camera: implement fixed cursor movement
On platforms with PERIPHERAL_TYPE_PAD, navigating through menus and options can be cumbersome if moving the cursor freely around the screen. Therefore, this commit instead defines a list of (X, Y) coordinates that the cursor can jump to. The implementation also attempts to guess which direction the cursor should jump to for the previous/next point, and hence determine which button should be pressed by the user.
This commit is contained in:
parent
8ddea5eef5
commit
9da37c198e
|
@ -35,6 +35,16 @@ struct camera
|
|||
{
|
||||
int last_w, last_h;
|
||||
} screen;
|
||||
|
||||
struct cursor_pos_rt
|
||||
{
|
||||
const struct cursor_pos
|
||||
{
|
||||
unsigned x, y;
|
||||
} *list;
|
||||
|
||||
size_t i, n;
|
||||
} rt;
|
||||
} cursor;
|
||||
};
|
||||
|
||||
|
@ -45,6 +55,7 @@ bool camera_translate(const struct camera *cam, const struct util_rect *dim, sho
|
|||
void cursor_init(struct cursor *c);
|
||||
bool cursor_collision(const struct camera *cam, const struct util_rect *d);
|
||||
void cursor_pos(const struct camera *cam, unsigned long *x, unsigned long *y);
|
||||
void cursor_set_pos_list(struct cursor *c, const struct cursor_pos *pos, size_t n);
|
||||
int cursor_render(const struct cursor *c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -114,6 +114,16 @@ bool camera_translate(const struct camera *const cam, const struct util_rect *co
|
|||
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)
|
||||
{
|
||||
switch (p->common.type)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#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)
|
||||
{
|
||||
|
@ -99,9 +100,61 @@ static void update_speed(struct camera *const cam, const struct pad *const p)
|
|||
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)
|
||||
{
|
||||
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 (pad_justpressed(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 (pad_justpressed(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)
|
||||
{
|
||||
cursor_update(cam, p);
|
||||
update_speed(cam, p);
|
||||
camera_update_pos(cam);
|
||||
if (cam->cursor.rt.list)
|
||||
cursor_update_fixed(cam, p);
|
||||
else
|
||||
{
|
||||
cursor_update(cam, p);
|
||||
update_speed(cam, p);
|
||||
camera_update_pos(cam);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue