aboutsummaryrefslogtreecommitdiff
path: root/src/player
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-03-30 08:36:16 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-03-31 06:50:33 +0200
commitce8b1c43caf9e97fe0e93a51d6ca6b82460305d7 (patch)
tree462ed058f56f76bff22ed55da34a36dc348a04dc /src/player
parent1950fe7b0679c6b6486cc7b25bef813db2b1bb4e (diff)
downloadjancity-ce8b1c43caf9e97fe0e93a51d6ca6b82460305d7.tar.gz
Implement touch controls
Diffstat (limited to 'src/player')
-rw-r--r--src/player/inc/human_player.h5
-rw-r--r--src/player/src/human_player.c113
2 files changed, 105 insertions, 13 deletions
diff --git a/src/player/inc/human_player.h b/src/player/inc/human_player.h
index b2a07ee..08f47d9 100644
--- a/src/player/inc/human_player.h
+++ b/src/player/inc/human_player.h
@@ -22,6 +22,7 @@ struct human_player_cfg
enum human_player_periph
{
HUMAN_PLAYER_PERIPH_PAD,
+ HUMAN_PLAYER_PERIPH_TOUCH,
HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE
} sel_periph;
@@ -39,10 +40,12 @@ struct human_player
{
struct pad pad;
- struct
+ struct human_player_kbm
{
struct mouse mouse;
struct keyboard keyboard;
+ bool long_press, pan;
+ unsigned int lp_t;
} kbm;
} periph;
diff --git a/src/player/src/human_player.c b/src/player/src/human_player.c
index b45e24f..e4e16b2 100644
--- a/src/player/src/human_player.c
+++ b/src/player/src/human_player.c
@@ -207,15 +207,33 @@ static bool select_resources(struct human_player *const h, const short x,
}
static bool select_instances(struct human_player *const h,
- const struct player_others *const o, const bool excl)
+ const struct player_others *const o, const bool excl,
+ const bool same_type)
{
unsigned long x, y;
cursor_pos(&h->cam, &x, &y);
- return select_buildings(h, x, y, excl)
- || select_units(h, x, y, excl)
- || select_resources(h, x, y, o, excl);
+ if (!same_type || !h->n_sel)
+ return select_buildings(h, x, y, excl)
+ || select_units(h, x, y, excl)
+ || select_resources(h, x, y, o, excl);
+ else
+ {
+ switch (h->sel->type)
+ {
+ case INSTANCE_TYPE_UNIT:
+ return select_units(h, x, y, excl);
+
+ case INSTANCE_TYPE_BUILDING:
+ return select_buildings(h, x, y, excl);
+
+ case INSTANCE_TYPE_RESOURCE:
+ select_resources(h, x, y, o, excl);
+ }
+ }
+
+ return false;
}
static bool instance_collision(const struct camera *const cam,
@@ -518,7 +536,7 @@ static bool update_from_pad(struct human_player *const h,
|| pad_justpressed(p, PAD_KEY_EXIT))
ret = true;
else if (pad_justpressed(p, PAD_KEY_A))
- select_instances(h, o, false);
+ select_instances(h, o, false, false);
else if (pad_justpressed(p, PAD_KEY_B))
move_units(h, o);
else if (pad_justpressed(p, PAD_KEY_C))
@@ -529,10 +547,59 @@ static bool update_from_pad(struct human_player *const h,
return ret;
}
+static bool update_keyboard_mouse_common(const struct mouse *const m,
+ const struct keyboard *const k)
+{
+ bool ret = false;
+
+ if (keyboard_justreleased(k, &KEYBOARD_COMBO(KEYBOARD_KEY_EXIT)))
+ ret = true;
+ else if (keyboard_justreleased(k, &KEYBOARD_COMBO(KEYBOARD_KEY_F11)))
+ gfx_toggle_fullscreen();
+
+ return ret;
+}
+
+static bool update_from_touch(struct human_player *const h,
+ struct player_others *const o)
+{
+ struct mouse *const m = &h->periph.kbm.mouse;
+ struct keyboard *const k = &h->periph.kbm.keyboard;
+
+ mouse_update(m);
+ keyboard_update(k);
+
+ enum {DEAD_ZONE = 5};
+ struct human_player_kbm *const kbm = &h->periph.kbm;
+
+ if (mouse_pressed(m, MOUSE_BUTTON_LEFT) && !kbm->pan)
+ {
+ enum {LONG_PRESS_THRESHOLD = 30};
+
+ if (kbm->lp_t < LONG_PRESS_THRESHOLD)
+ kbm->lp_t++;
+ else if (!kbm->long_press)
+ {
+ kbm->long_press = true;
+ deselect_instances(h);
+ }
+ }
+ else if (mouse_justreleased(m, MOUSE_BUTTON_LEFT))
+ {
+ if (!kbm->pan && !select_instances(h, o, false, true))
+ move_units(h, o);
+
+ kbm->pan = false;
+ kbm->long_press = false;
+ kbm->lp_t = 0;
+ }
+
+ return update_keyboard_mouse_common(m, k);
+}
+
static bool update_from_keyboard_mouse(struct human_player *const h,
struct player_others *const o)
{
- bool ret = false;
struct mouse *const m = &h->periph.kbm.mouse;
struct keyboard *const k = &h->periph.kbm.keyboard;
@@ -545,17 +612,13 @@ static bool update_from_keyboard_mouse(struct human_player *const h,
keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_LSHIFT))
|| keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_RSHIFT));
- if (!select_instances(h, o, !shift_pressed))
+ if (!select_instances(h, o, !shift_pressed, false))
deselect_instances(h);
}
else if (mouse_justreleased(m, MOUSE_BUTTON_RIGHT))
move_units(h, o);
- else if (keyboard_justreleased(k, &KEYBOARD_COMBO(KEYBOARD_KEY_EXIT)))
- ret = true;
- else if (keyboard_justreleased(k, &KEYBOARD_COMBO(KEYBOARD_KEY_F11)))
- gfx_toggle_fullscreen();
- return ret;
+ return update_keyboard_mouse_common(m, k);
}
bool human_player_update(struct human_player *const h,
@@ -577,6 +640,15 @@ bool human_player_update(struct human_player *const h,
camera_update_pad(&h->cam, &h->periph.pad);
break;
+ case HUMAN_PLAYER_PERIPH_TOUCH:
+ {
+ struct human_player_kbm *const kbm = &h->periph.kbm;
+
+ ret = update_from_touch(h, o);
+ kbm->pan |= camera_update_touch(&h->cam, &kbm->mouse);
+ }
+ break;
+
case HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE:
ret = update_from_keyboard_mouse(h, o);
camera_update_mouse(&h->cam, &h->periph.kbm.mouse);
@@ -659,6 +731,21 @@ int human_player_render(const struct human_player *const h,
|| gui_render(h))
return -1;
+ switch (h->sel_periph)
+ {
+ case HUMAN_PLAYER_PERIPH_PAD:
+ /* Fall through. */
+ case HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE:
+ cursor_render(&h->cam.cursor);
+ break;
+
+ case HUMAN_PLAYER_PERIPH_TOUCH:
+ break;
+
+ default:
+ return -1;
+ }
+
return 0;
}
@@ -672,6 +759,8 @@ int human_player_init(const struct human_player_cfg *const cfg,
switch (h->sel_periph = cfg->sel_periph)
{
+ 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);