aboutsummaryrefslogtreecommitdiff
path: root/src
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
commit45337576dff70a3b5991b79d0fe13420110b3594 (patch)
treed3f18d3d92a9da8c7d2dd9e596b44eb579cf368c /src
parent82c61e3d1d97c6e829bfbe0e35539abfe75d1380 (diff)
downloadrts-45337576dff70a3b5991b79d0fe13420110b3594.tar.gz
Implement touch controls
Diffstat (limited to 'src')
-rw-r--r--src/camera/CMakeLists.txt2
-rw-r--r--src/camera/inc/camera.h1
-rw-r--r--src/camera/src/touch.c57
-rw-r--r--src/game/src/game.c5
-rw-r--r--src/mouse/inc/mouse.h3
-rw-r--r--src/mouse/sdl-1.2/src/mouse.c4
-rw-r--r--src/mouse/src/mouse.c5
-rw-r--r--src/player/inc/human_player.h5
-rw-r--r--src/player/src/human_player.c113
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);