2020-09-14 14:37:46 +02:00
|
|
|
#include <gint/display.h>
|
|
|
|
|
2020-09-11 18:07:53 +02:00
|
|
|
#include "camera.h"
|
2020-09-19 14:00:46 +02:00
|
|
|
#include "conf.h"
|
2020-09-14 10:33:01 +02:00
|
|
|
#include "vec.h"
|
2020-09-23 12:19:40 +02:00
|
|
|
#include "player.h"
|
|
|
|
#include "level.h"
|
2020-09-11 18:07:53 +02:00
|
|
|
|
|
|
|
void camera_step(Camera *camera)
|
|
|
|
{
|
2020-09-21 14:52:28 +02:00
|
|
|
/* lerp towards target */
|
2020-09-14 14:37:46 +02:00
|
|
|
vec_lerp(&camera->pos, *camera->target, camera->speed);
|
2020-09-23 12:19:40 +02:00
|
|
|
/* put the camera in the right place */
|
|
|
|
vec_clamp(&camera->pos, camera->min, camera->max);
|
2020-09-21 14:52:28 +02:00
|
|
|
/* calculate pixel offset */
|
|
|
|
Vec * const offset = &camera->offset; /* DRY */
|
|
|
|
vec_cpy(offset, camera->pos);
|
|
|
|
vec_div(offset, VEC_PRECISION);
|
2020-09-23 12:19:40 +02:00
|
|
|
vec_sub(offset, VEC_SCALED_DCENTER);
|
|
|
|
}
|
|
|
|
|
|
|
|
void camera_init(Camera *camera, Player *player, const Level *level)
|
|
|
|
{
|
2020-09-23 15:59:31 +02:00
|
|
|
/* NOTE: This system doesn't totally works, but it's good enough for now. */
|
2020-09-23 15:56:49 +02:00
|
|
|
/* check level size */
|
|
|
|
const Vec level_dim = {level->width * (TILE_SIZE / VEC_PRECISION * SCALE),
|
|
|
|
level->height * (TILE_SIZE / VEC_PRECISION * SCALE)};
|
|
|
|
if (level_dim.x > DWIDTH || level_dim.y > DHEIGHT)
|
|
|
|
{
|
|
|
|
/* level cannot be displayed on a single screen */
|
|
|
|
/* calculate min and max */
|
|
|
|
vec_cpy(&camera->min, VEC_SCALED_DCENTER);
|
|
|
|
vec_mul(&camera->min, VEC_PRECISION);
|
|
|
|
vec_cpy(&camera->max, (Vec){0, 0});
|
|
|
|
vec_sub(&camera->max, VEC_SCALED_DCENTER);
|
|
|
|
vec_mul(&camera->max, VEC_PRECISION);
|
|
|
|
vec_add(&camera->max, (Vec){TILE_SIZE * level->width, TILE_SIZE * level->height});
|
|
|
|
vec_cpy(&camera->pos, player->pos);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* level is single screen */
|
|
|
|
/* We calculate the offset and setup the camera to center everything. */
|
|
|
|
const Vec screen_center_precise = {level->width * TILE_SIZE / (2 * SCALE),
|
|
|
|
level->height * TILE_SIZE / (2 * SCALE)};
|
|
|
|
vec_cpy(&camera->min, screen_center_precise);
|
|
|
|
vec_cpy(&camera->max, screen_center_precise);
|
|
|
|
}
|
2020-09-23 12:19:40 +02:00
|
|
|
vec_clamp(&camera->pos, camera->min, camera->max);
|
2020-09-14 14:37:46 +02:00
|
|
|
}
|
|
|
|
|
2020-09-18 11:12:34 +02:00
|
|
|
void camera_draw_debug(Camera *camera)
|
2020-09-14 14:37:46 +02:00
|
|
|
{
|
2020-09-23 12:19:40 +02:00
|
|
|
dprint(0, 0, C_BLACK, "-x: %d, -y: %d", camera->min.x, camera->min.y);
|
|
|
|
dprint(0, 10, C_BLACK, "+x: %d, +y: %d", camera->max.x, camera->max.y);
|
|
|
|
dprint(0, 20, C_BLACK, "cx: %d, cy: %d", camera->pos.x, camera->pos.y);
|
|
|
|
dprint(0, 30, C_BLACK, "px: %d, py: %d", camera->offset.x, camera->offset.y);
|
2020-09-11 18:07:53 +02:00
|
|
|
}
|