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 | |
| parent | 1950fe7b0679c6b6486cc7b25bef813db2b1bb4e (diff) | |
| download | jancity-ce8b1c43caf9e97fe0e93a51d6ca6b82460305d7.tar.gz | |
Implement touch controls
Diffstat (limited to 'src')
| -rw-r--r-- | src/camera/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/camera/inc/camera.h | 1 | ||||
| -rw-r--r-- | src/camera/src/touch.c | 57 | ||||
| -rw-r--r-- | src/game/src/game.c | 5 | ||||
| -rw-r--r-- | src/mouse/inc/mouse.h | 3 | ||||
| -rw-r--r-- | src/mouse/sdl-1.2/src/mouse.c | 4 | ||||
| -rw-r--r-- | src/mouse/src/mouse.c | 5 | ||||
| -rw-r--r-- | src/player/inc/human_player.h | 5 | ||||
| -rw-r--r-- | src/player/src/human_player.c | 113 |
9 files changed, 177 insertions, 18 deletions
diff --git a/src/camera/CMakeLists.txt b/src/camera/CMakeLists.txt index 3d9d113..f234098 100644 --- a/src/camera/CMakeLists.txt +++ b/src/camera/CMakeLists.txt @@ -1,3 +1,3 @@ -add_library(camera "src/camera.c" "src/pad.c" "src/mouse.c") +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) diff --git a/src/camera/inc/camera.h b/src/camera/inc/camera.h index ec2739b..93ad740 100644 --- a/src/camera/inc/camera.h +++ b/src/camera/inc/camera.h @@ -35,6 +35,7 @@ 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); 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); diff --git a/src/camera/src/touch.c b/src/camera/src/touch.c new file mode 100644 index 0000000..475b308 --- /dev/null +++ b/src/camera/src/touch.c @@ -0,0 +1,57 @@ +#include <camera.h> +#include <mouse.h> +#include <camera_private.h> +#include <gfx.h> + +static void cursor_update(struct cursor *const c, const struct mouse *const m) +{ + if (c->screen.last_w != screen_w + || c->screen.last_h != screen_h) + cursor_init(c); + + c->x = m->x; + c->y = m->y; +} + +static bool 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)) + { + *sx = m->dx; + *sy = m->dy; + + ret = *sx || *sy; + } + else if (*sx || *sy) + { + const int qx = *sx / 4; + + if (qx) + *sx -= qx; + else + *sx = 0; + + const int qy = *sy / 4; + + if (qy) + *sy -= qy; + else + *sy = 0; + } + + return ret; +} + +bool camera_update_touch(struct camera *const cam, const struct mouse *const m) +{ + bool ret; + + cursor_update(&cam->cursor, m); + ret = update_speed(cam, m); + camera_update_pos(cam); + + return ret; +} diff --git a/src/game/src/game.c b/src/game/src/game.c index b583c5c..e1a316e 100644 --- a/src/game/src/game.c +++ b/src/game/src/game.c @@ -26,7 +26,7 @@ int game(void) { const struct human_player_cfg cfg = { - .sel_periph = HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE, + .sel_periph = HUMAN_PLAYER_PERIPH_TOUCH, .padn = i, .pl = { @@ -86,8 +86,7 @@ int game(void) terrain_update(&map); if (terrain_render(&map, &h->cam) - || human_player_render(h, &o) - || cursor_render(&h->cam.cursor)) + || human_player_render(h, &o)) goto end; /* TODO: render AI players. */ diff --git a/src/mouse/inc/mouse.h b/src/mouse/inc/mouse.h index a4b4044..60b63d3 100644 --- a/src/mouse/inc/mouse.h +++ b/src/mouse/inc/mouse.h @@ -16,12 +16,13 @@ enum mouse_button struct mouse { - short x, y; + short x, y, dx, dy; int mask, oldmask; }; void mouse_init(struct mouse *m); void mouse_update(struct mouse *m); +bool mouse_pressed(const struct mouse *m, enum mouse_button b); bool mouse_justpressed(const struct mouse *m, enum mouse_button b); bool mouse_justreleased(const struct mouse *m, enum mouse_button b); diff --git a/src/mouse/sdl-1.2/src/mouse.c b/src/mouse/sdl-1.2/src/mouse.c index a0a6d90..cee4549 100644 --- a/src/mouse/sdl-1.2/src/mouse.c +++ b/src/mouse/sdl-1.2/src/mouse.c @@ -39,6 +39,7 @@ static void mouse_event(const SDL_MouseMotionEvent *const ev, void mouse_update(struct mouse *const m) { + const short x = m->x, y = m->y; SDL_Event ev; int n; @@ -71,6 +72,9 @@ void mouse_update(struct mouse *const m) } } + m->dx = m->x - x; + m->dy = m->y - y; + end: if (n < 0) diff --git a/src/mouse/src/mouse.c b/src/mouse/src/mouse.c index 5f5c059..bec978d 100644 --- a/src/mouse/src/mouse.c +++ b/src/mouse/src/mouse.c @@ -1,6 +1,11 @@ #include <mouse.h> #include <stdbool.h> +bool mouse_pressed(const struct mouse *const m, const enum mouse_button b) +{ + return m->mask & (1 << b); +} + bool mouse_justpressed(const struct mouse *const m, const enum mouse_button b) { 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); |
