diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2022-03-30 08:36:16 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2022-03-31 06:50:33 +0200 |
| commit | ce8b1c43caf9e97fe0e93a51d6ca6b82460305d7 (patch) | |
| tree | 462ed058f56f76bff22ed55da34a36dc348a04dc /src/player | |
| parent | 1950fe7b0679c6b6486cc7b25bef813db2b1bb4e (diff) | |
| download | jancity-ce8b1c43caf9e97fe0e93a51d6ca6b82460305d7.tar.gz | |
Implement touch controls
Diffstat (limited to 'src/player')
| -rw-r--r-- | src/player/inc/human_player.h | 5 | ||||
| -rw-r--r-- | src/player/src/human_player.c | 113 |
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); |
