aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-06-24 17:45:50 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-06-24 17:45:50 +0200
commit9da37c198e88ebade4a176bc1d7c9a9ebd388862 (patch)
treeec32c55d29ce066cd37c4c76738de6afbe6b2f48
parent8ddea5eef59dbc124f914560af61b78867671482 (diff)
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.
-rw-r--r--src/camera/inc/camera.h11
-rw-r--r--src/camera/src/camera.c10
-rw-r--r--src/camera/src/pad.c59
3 files changed, 77 insertions, 3 deletions
diff --git a/src/camera/inc/camera.h b/src/camera/inc/camera.h
index 98cb240..9841315 100644
--- a/src/camera/inc/camera.h
+++ b/src/camera/inc/camera.h
@@ -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
diff --git a/src/camera/src/camera.c b/src/camera/src/camera.c
index 0c4ffd1..6d114c5 100644
--- a/src/camera/src/camera.c
+++ b/src/camera/src/camera.c
@@ -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)
diff --git a/src/camera/src/pad.c b/src/camera/src/pad.c
index f123980..317616f 100644
--- a/src/camera/src/pad.c
+++ b/src/camera/src/pad.c
@@ -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);
+ }
}