jtmm2/src/camera.c

59 lines
2.0 KiB
C

#include <gint/display.h>
#include "camera.h"
#include "conf.h"
#include "vec.h"
#include "player.h"
#include "level.h"
void camera_step(Camera *camera)
{
/* lerp towards target */
vec_lerp(&camera->pos, *camera->target, camera->speed);
/* put the camera in the right place */
vec_clamp(&camera->pos, camera->min, camera->max);
/* calculate pixel offset */
Vec * const offset = &camera->offset; /* DRY */
vec_cpy(offset, camera->pos);
vec_div(offset, VEC_PRECISION);
vec_sub(offset, VEC_SCALED_DCENTER);
}
void camera_init(Camera *camera, Player *player, const Level *level)
{
/* NOTE: This system doesn't totally works, but it's good enough for now. */
/* 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);
}
vec_clamp(&camera->pos, camera->min, camera->max);
}
void camera_draw_debug(Camera *camera)
{
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);
}