jancity/src/camera/src/camera.c

157 lines
3.2 KiB
C

#include <camera.h>
#include <camera_private.h>
#include <gfx.h>
#include <mouse.h>
#include <pad.h>
#include <util.h>
#include <limits.h>
#include <stdbool.h>
struct sprite cursor_sprite;
bool cursor_collision(const struct camera *const cam, const struct util_rect *const d)
{
unsigned long x, y;
cursor_pos(cam, &x, &y);
const struct util_rect cd =
{
.x = x,
.y = y,
.w = CAMERA_CURSOR_WIDTH / 4,
.h = CAMERA_CURSOR_HEIGHT / 4
};
return util_collision(d, &cd);
}
void cursor_pos(const struct camera *const cam, unsigned long *const x,
unsigned long *const y)
{
const struct cursor *const c = &cam->cursor;
*x = c->x - cam->x;
*y = c->y - cam->y;
}
int cursor_render(const struct cursor *const c)
{
sprite_get_or_ret(s, -1);
if (sprite_clone(&cursor_sprite, s))
{
fprintf(stderr, "%s: sprite_clone failed\n", __func__);
return -1;
}
s->x = c->x;
s->y = c->y;
s->w = CAMERA_CURSOR_WIDTH;
s->h = CAMERA_CURSOR_HEIGHT;
switch (c->state)
{
case CURSOR_STATE_IDLE:
break;
case CURSOR_STATE_HOVERING:
s->u += CAMERA_CURSOR_WIDTH;
break;
case CURSOR_STATE_PRESSED:
s->u += CAMERA_CURSOR_WIDTH * 2;
break;
}
const int ret = sprite_sort(s);
if (ret)
fprintf(stderr, "%s: sprite_sort failed\n", __func__);
return ret;
}
void cursor_init(struct cursor *const c)
{
const unsigned x = (screen_w / 2) - CAMERA_CURSOR_WIDTH,
y = (screen_h / 2) - CAMERA_CURSOR_HEIGHT;
*c = (const struct cursor)
{
.x = x,
.x_init = x,
.y = y,
.y_init = y,
.screen =
{
.last_w = screen_w,
.last_h = screen_h
}
};
}
void camera_update_pos(struct camera *const cam)
{
const struct camera_dim *const d = &cam->dim;
if (!d->w || !d->h)
return;
cam->x += cam->x_speed;
if (cam->x > 0)
cam->x = 0;
else if (cam->x < -d->w + screen_w)
cam->x = -d->w + screen_w;
cam->y += cam->y_speed;
if (cam->y > 0)
cam->y = 0;
else if (cam->y < -d->h + screen_h)
cam->y = -d->h + screen_h;
}
bool camera_translate(const struct camera *const cam, const struct util_rect *const dim,
short *const x, short *const y)
{
const long tx = dim->x + cam->x, ty = dim->y + cam->y;
if (!gfx_inside_drawenv(tx, ty, dim->w, dim->h))
return false;
*x = tx;
*y = ty;
return true;
}
void cursor_set_pos_list(struct cursor *const c,
const struct cursor_pos *const pos, const size_t n)
{
c->rt = (const struct cursor_pos_rt)
{
.list = pos,
.n = n
};
}
void camera_update(struct camera *const cam,
const union peripheral *const p, const struct input *const in)
{
switch (p->common.type)
{
case PERIPHERAL_TYPE_PAD:
camera_update_pad(cam, &p->pad.pad, in);
break;
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
camera_update_mouse(cam, &p->kbm.mouse);
break;
case PERIPHERAL_TYPE_TOUCH:
camera_update_touch(cam, &p->kbm.mouse, in);
break;
}
}