jancity/src/camera/src/pad.c

166 lines
4.2 KiB
C

#include <camera.h>
#include <camera_private.h>
#include <input.h>
#include <pad.h>
#include <peripheral.h>
#include <gfx.h>
#include <util.h>
#include <stdbool.h>
#include <stdlib.h>
static void cursor_update(struct camera *const cam,
const struct pad *const p, const struct input *const in)
{
struct cursor *const c = &cam->cursor;
enum {STEP = 4};
if (c->screen.last_w != screen_w
|| c->screen.last_h != screen_h)
cursor_init(c);
if (input_pad_pressed(in, p, PAD_KEY_LEFT)
&& (c->x - STEP)
&& (!cam->x || c->x != c->x_init))
c->x -= STEP;
else if (input_pad_pressed(in, p, PAD_KEY_RIGHT)
&& (c->x + STEP < screen_w)
&& (c->x != c->x_init || cam->x <= -cam->dim.w))
c->x += STEP;
if (input_pad_pressed(in, p, PAD_KEY_UP)
&& (c->y - STEP)
&& (c->y != c->y_init || !cam->y))
c->y -= STEP;
else if (input_pad_pressed(in, p, PAD_KEY_DOWN)
&& (c->y + STEP < screen_h)
&& (c->y != c->y_init || cam->y <= -cam->dim.h))
c->y += STEP;
c->state = pad_pressed(p, PAD_KEY_A) ||
pad_pressed(p, PAD_KEY_B) ?
CURSOR_STATE_PRESSED: CURSOR_STATE_IDLE;
}
static void update_speed(struct camera *const cam,
const struct pad *const p, const struct input *const in)
{
enum
{
MAX_SPEED = 10,
STEP = 1,
T_STEP = 2
};
const struct cursor *const c = &cam->cursor;
if (c->x == c->x_init
&& (!cam->x_speed || ++cam->xt >= T_STEP))
{
if (input_pad_pressed(in, p, PAD_KEY_RIGHT))
{
if (cam->x_speed > 0)
cam->x_speed = -STEP;
else if (cam->x_speed - STEP >= -MAX_SPEED)
cam->x_speed -= STEP;
}
else if (input_pad_pressed(in, p, PAD_KEY_LEFT))
{
if (cam->x_speed < 0)
cam->x_speed = STEP;
else if (cam->x_speed + STEP <= MAX_SPEED)
cam->x_speed += STEP;
}
else
cam->x_speed = 0;
cam->xt = 0;
}
else if (c->x != c->x_init)
cam->x_speed = 0;
if (c->y == c->y_init
&& (!cam->y_speed || ++cam->yt >= T_STEP))
{
if (input_pad_pressed(in, p, PAD_KEY_DOWN))
{
if (cam->y_speed > 0)
cam->y_speed = STEP;
else if (cam->y_speed - STEP >= -MAX_SPEED)
cam->y_speed -= STEP;
}
else if (input_pad_pressed(in, p, PAD_KEY_UP))
{
if (cam->y_speed < 0)
cam->y_speed = -STEP;
else if (cam->y_speed + STEP <= MAX_SPEED)
cam->y_speed += STEP;
}
else
cam->y_speed = 0;
cam->yt = 0;
}
else if (c->y != c->y_init)
cam->y_speed = 0;
}
static enum pad_key get_ref_key(struct cursor_pos_rt *const rt,
const size_t ref)
{
enum pad_key key;
const struct cursor_pos *const cur = &rt->list[rt->i],
*const next = &rt->list[ref];
const short nx = next->x - cur->x,
ny = next->y - cur->y;
if (abs(nx) > abs(ny))
key = nx > 0 ? PAD_KEY_RIGHT : PAD_KEY_LEFT;
else
key = ny > 0 ? PAD_KEY_DOWN : PAD_KEY_UP;
return key;
}
static void cursor_update_fixed(struct camera *const cam,
const struct pad *const p, const struct input *const in)
{
struct cursor *const c = &cam->cursor;
struct cursor_pos_rt *const rt = &c->rt;
const size_t next = rt->i + 1;
if (next < rt->n)
{
const enum pad_key key = get_ref_key(rt, next);
if (input_pad_justpressed(in, p, key))
rt->i = next;
}
else if (rt->i)
{
const size_t prev = rt->i - 1;
const enum pad_key key = get_ref_key(rt, prev);
if (input_pad_justpressed(in, p, key))
rt->i = prev;
}
const struct cursor_pos *const cur = &rt->list[rt->i];
c->x = cur->x;
c->y = cur->y;
}
void camera_update_pad(struct camera *const cam, const struct pad *const p,
const struct input *const in)
{
if (cam->cursor.rt.list)
cursor_update_fixed(cam, p, in);
else
{
cursor_update(cam, p, in);
update_speed(cam, p, in);
camera_update_pos(cam);
}
}