Split peripheral-related logic into its own component

This has several advantages:

- `camera` no longer needs to define public functions for each
peripheral type.
- Peripheral-related is now no longer tighly coupled to human_player,
so peripheral logic can be reused elsewhere e.g.: on menus.
- Makes camera_update_touch consistent compared to equivalent functions,
since now `pan` has now been moved to `camera` (as it should be).
This commit is contained in:
Xavier Del Campo Romero 2022-06-12 22:34:23 +02:00
parent 5794dbf403
commit 0f9e2d8958
13 changed files with 165 additions and 78 deletions

View File

@ -55,6 +55,7 @@ set(components
keyboard
mouse
pad
peripheral
player
resource
sfx

View File

@ -1,3 +1,3 @@
add_library(camera "src/camera.c" "src/pad.c" "src/mouse.c" "src/touch.c")
target_include_directories(camera PUBLIC "inc" PRIVATE "privinc")
target_link_libraries(camera PUBLIC container mouse pad terrain util PRIVATE gfx)
target_link_libraries(camera PUBLIC container mouse pad peripheral terrain util PRIVATE gfx)

View File

@ -3,6 +3,7 @@
#include <mouse.h>
#include <pad.h>
#include <peripheral.h>
#include <util.h>
#include <stdbool.h>
@ -15,6 +16,7 @@ struct camera
{
int x, y, x_speed, y_speed;
unsigned int xt, yt;
bool pan;
struct cursor
{
@ -33,9 +35,7 @@ struct camera
extern struct sprite cursor_sprite;
void camera_update_pad(struct camera *cam, const struct pad *p);
void camera_update_mouse(struct camera *cam, const struct mouse *m);
bool camera_update_touch(struct camera *cam, const struct mouse *m);
void camera_update(struct camera *cam, const union peripheral *p);
bool camera_translate(const struct camera *cam, const struct util_rect *dim, short *x, short *y);
void cursor_init(struct cursor *c);
bool cursor_collision(const struct camera *cam, const struct util_rect *d);

View File

@ -15,6 +15,9 @@ enum
};
void camera_update_pos(struct camera *cam);
void camera_update_pad(struct camera *cam, const struct pad *p);
void camera_update_mouse(struct camera *cam, const struct mouse *m);
void camera_update_touch(struct camera *cam, const struct mouse *m);
#ifdef __cplusplus
}

View File

@ -103,3 +103,21 @@ bool camera_translate(const struct camera *const cam, const struct util_rect *co
*y = ty;
return true;
}
void camera_update(struct camera *const cam, const union peripheral *const p)
{
switch (p->common.type)
{
case PERIPHERAL_TYPE_PAD:
camera_update_pad(cam, &p->pad.pad);
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);
break;
}
}

View File

@ -2,6 +2,7 @@
#include <camera_private.h>
#include <pad.h>
#include <terrain.h>
#include <peripheral.h>
#include <util.h>
#include <stdbool.h>

View File

@ -13,9 +13,8 @@ static void cursor_update(struct cursor *const c, const struct mouse *const m)
c->y = m->y;
}
static bool update_speed(struct camera *const cam, const struct mouse *const m)
static void update_speed(struct camera *const cam, const struct mouse *const m)
{
bool ret = false;
int *const sx = &cam->x_speed, *const sy = &cam->y_speed;
if (mouse_pressed(m, MOUSE_BUTTON_LEFT))
@ -23,7 +22,7 @@ static bool update_speed(struct camera *const cam, const struct mouse *const m)
*sx = m->dx;
*sy = m->dy;
ret = *sx || *sy;
cam->pan = *sx || *sy;
}
else if (*sx || *sy)
{
@ -41,17 +40,11 @@ static bool update_speed(struct camera *const cam, const struct mouse *const m)
else
*sy = 0;
}
return ret;
}
bool camera_update_touch(struct camera *const cam, const struct mouse *const m)
void camera_update_touch(struct camera *const cam, const struct mouse *const m)
{
bool ret;
cursor_update(&cam->cursor, m);
ret = update_speed(cam, m);
update_speed(cam, m);
camera_update_pos(cam);
return ret;
}

View File

@ -26,7 +26,7 @@ int game(void)
{
const struct human_player_cfg cfg =
{
.sel_periph = HUMAN_PLAYER_PERIPH_TOUCH,
.sel_periph = PERIPHERAL_TYPE_KEYBOARD_MOUSE,
.padn = i,
.pl =
{

View File

@ -0,0 +1,3 @@
add_library(peripheral "src/peripheral.c")
target_include_directories(peripheral PUBLIC "inc")
target_link_libraries(peripheral PUBLIC pad mouse keyboard util)

View File

@ -0,0 +1,64 @@
#ifndef PERIPHERAL_H
#define PERIPHERAL_H
#include <pad.h>
#include <keyboard.h>
#include <mouse.h>
#include <util.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C"
{
#endif
enum peripheral_type
{
PERIPHERAL_TYPE_PAD,
PERIPHERAL_TYPE_TOUCH,
PERIPHERAL_TYPE_KEYBOARD_MOUSE
};
union peripheral
{
struct peripheral_common
{
enum peripheral_type type;
} common;
struct peripheral_pad
{
struct peripheral_common common;
struct pad pad;
} pad;
struct peripheral_kbm
{
struct peripheral_common common;
struct mouse mouse;
struct keyboard keyboard;
bool long_press;
unsigned int lp_t;
} kbm;
};
struct peripheral_cfg
{
enum peripheral_type type;
int padn;
};
UTIL_STATIC_ASSERT(!offsetof(struct peripheral_pad, common),
"unexpected offsetof for struct peripheral_pad");
UTIL_STATIC_ASSERT(!offsetof(struct peripheral_kbm, common),
"unexpected offsetof for struct peripheral_kbm");
void peripheral_init(const struct peripheral_cfg *cfg, union peripheral *p);
void peripheral_update(union peripheral *p);
#ifdef __cplusplus
}
#endif
#endif /* PERIPHERAL_H */

View File

@ -0,0 +1,41 @@
#include <peripheral.h>
#include <keyboard.h>
#include <mouse.h>
#include <pad.h>
void peripheral_update(union peripheral *const p)
{
switch (p->common.type)
{
case PERIPHERAL_TYPE_TOUCH:
/* Fall through. */
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
mouse_update(&p->kbm.mouse);
keyboard_update(&p->kbm.keyboard);
break;
case PERIPHERAL_TYPE_PAD:
pad_update(&p->pad.pad);
break;
}
}
void peripheral_init(const struct peripheral_cfg *const cfg,
union peripheral *const p)
{
*p = (const union peripheral){0};
switch (p->common.type = cfg->type)
{
case PERIPHERAL_TYPE_TOUCH:
/* Fall through. */
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
mouse_init(&p->kbm.mouse);
keyboard_init(&p->kbm.keyboard);
break;
case PERIPHERAL_TYPE_PAD:
pad_init(cfg->padn, &p->pad.pad);
break;
}
}

View File

@ -6,6 +6,7 @@
#include <instance.h>
#include <mouse.h>
#include <pad.h>
#include <peripheral.h>
#include <player.h>
#include <stdbool.h>
#include <stddef.h>
@ -19,35 +20,17 @@ enum {MAX_SELECTED_INSTANCES = 4};
struct human_player_cfg
{
enum human_player_periph
{
HUMAN_PLAYER_PERIPH_PAD,
HUMAN_PLAYER_PERIPH_TOUCH,
HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE
} sel_periph;
enum peripheral_type sel_periph;
struct player_cfg pl;
int padn;
struct camera_dim dim;
};
struct human_player
{
struct player pl;
struct camera cam;
enum human_player_periph sel_periph;
union
{
struct pad pad;
struct human_player_kbm
{
struct mouse mouse;
struct keyboard keyboard;
bool long_press, pan;
unsigned int lp_t;
} kbm;
} periph;
union peripheral periph;
struct sel_instance
{

View File

@ -528,9 +528,7 @@ static bool update_from_pad(struct human_player *const h,
struct player_others *const o)
{
bool ret = false;
struct pad *const p = &h->periph.pad;
pad_update(p);
struct pad *const p = &h->periph.pad.pad;
if (pad_justpressed(p, PAD_KEY_OPTIONS)
|| pad_justpressed(p, PAD_KEY_EXIT))
@ -565,13 +563,10 @@ static bool update_from_touch(struct human_player *const h,
{
struct mouse *const m = &h->periph.kbm.mouse;
struct keyboard *const k = &h->periph.kbm.keyboard;
struct peripheral_kbm *const kbm = &h->periph.kbm;
bool *const pan = &h->cam.pan;
mouse_update(m);
keyboard_update(k);
struct human_player_kbm *const kbm = &h->periph.kbm;
if (mouse_pressed(m, MOUSE_BUTTON_LEFT) && !kbm->pan)
if (mouse_pressed(m, MOUSE_BUTTON_LEFT) && !*pan)
{
enum {LONG_PRESS_THRESHOLD = 30};
@ -585,10 +580,10 @@ static bool update_from_touch(struct human_player *const h,
}
else if (mouse_justreleased(m, MOUSE_BUTTON_LEFT))
{
if (!kbm->pan && !select_instances(h, o, false, true))
if (!*pan && !select_instances(h, o, false, true))
move_units(h, o);
kbm->pan = false;
*pan = false;
kbm->long_press = false;
kbm->lp_t = 0;
}
@ -602,9 +597,6 @@ static bool update_from_keyboard_mouse(struct human_player *const h,
struct mouse *const m = &h->periph.kbm.mouse;
struct keyboard *const k = &h->periph.kbm.keyboard;
mouse_update(m);
keyboard_update(k);
if (mouse_justreleased(m, MOUSE_BUTTON_LEFT))
{
const bool shift_pressed =
@ -631,29 +623,24 @@ bool human_player_update(struct human_player *const h,
gui_update(h);
update_selected(h);
update_target(h);
peripheral_update(&h->periph);
switch (h->sel_periph)
switch (h->periph.common.type)
{
case HUMAN_PLAYER_PERIPH_PAD:
case PERIPHERAL_TYPE_PAD:
ret = update_from_pad(h, o);
camera_update_pad(&h->cam, &h->periph.pad);
break;
case HUMAN_PLAYER_PERIPH_TOUCH:
{
struct human_player_kbm *const kbm = &h->periph.kbm;
case PERIPHERAL_TYPE_TOUCH:
ret = update_from_touch(h, o);
kbm->pan |= camera_update_touch(&h->cam, &kbm->mouse);
}
break;
case HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE:
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
ret = update_from_keyboard_mouse(h, o);
camera_update_mouse(&h->cam, &h->periph.kbm.mouse);
break;
}
camera_update(&h->cam, &h->periph);
player_update(p);
}
@ -730,15 +717,15 @@ int human_player_render(const struct human_player *const h,
|| gui_render(h))
return -1;
switch (h->sel_periph)
switch (h->periph.common.type)
{
case HUMAN_PLAYER_PERIPH_PAD:
case PERIPHERAL_TYPE_PAD:
/* Fall through. */
case HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE:
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
cursor_render(&h->cam.cursor);
break;
case HUMAN_PLAYER_PERIPH_TOUCH:
case PERIPHERAL_TYPE_TOUCH:
break;
default:
@ -756,20 +743,13 @@ int human_player_init(const struct human_player_cfg *const cfg,
if (player_init(&cfg->pl, &h->pl))
return -1;
switch (h->sel_periph = cfg->sel_periph)
const struct peripheral_cfg p_cfg =
{
case HUMAN_PLAYER_PERIPH_TOUCH:
/* Fall through. */
case HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE:
mouse_init(&h->periph.kbm.mouse);
keyboard_init(&h->periph.kbm.keyboard);
break;
case HUMAN_PLAYER_PERIPH_PAD:
pad_init(cfg->padn, &h->periph.pad);
break;
}
.type = cfg->sel_periph,
.padn = cfg->padn
};
peripheral_init(&p_cfg, &h->periph);
cursor_init(&h->cam.cursor);
h->top_gui = true;
memmove(h->gui_res, h->pl.resources, sizeof h->gui_res);