aboutsummaryrefslogtreecommitdiff
path: root/src/player
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-02-24 17:55:57 +0100
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-03-30 08:20:21 +0200
commit9eee43d3bb24000077602a62dfdfeee2606f1589 (patch)
tree0e5f8efef62b068e252fe9c98c14fec723e0a7a3 /src/player
parent18717569acda82b26099c62410df3b398d596ba1 (diff)
downloadrts-9eee43d3bb24000077602a62dfdfeee2606f1589.tar.gz
Add support for keyboard and mouse
Diffstat (limited to 'src/player')
-rw-r--r--src/player/CMakeLists.txt2
-rw-r--r--src/player/inc/human_player.h33
-rw-r--r--src/player/src/human_player.c211
3 files changed, 193 insertions, 53 deletions
diff --git a/src/player/CMakeLists.txt b/src/player/CMakeLists.txt
index d7a275d..6d692fe 100644
--- a/src/player/CMakeLists.txt
+++ b/src/player/CMakeLists.txt
@@ -5,7 +5,9 @@ target_link_libraries(player
building
camera
gfx
+ keyboard
instance
+ mouse
pad
resource
tech
diff --git a/src/player/inc/human_player.h b/src/player/inc/human_player.h
index 6d97cf7..b2a07ee 100644
--- a/src/player/inc/human_player.h
+++ b/src/player/inc/human_player.h
@@ -2,7 +2,9 @@
#define HUMAN_PLAYER_H
#include <camera.h>
+#include <keyboard.h>
#include <instance.h>
+#include <mouse.h>
#include <pad.h>
#include <player.h>
#include <stdbool.h>
@@ -15,11 +17,34 @@ extern "C"
enum {MAX_SELECTED_INSTANCES = 4};
+struct human_player_cfg
+{
+ enum human_player_periph
+ {
+ HUMAN_PLAYER_PERIPH_PAD,
+ HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE
+ } sel_periph;
+
+ struct player_cfg pl;
+ int padn;
+};
+
struct human_player
{
struct player pl;
struct camera cam;
- struct pad pad;
+ enum human_player_periph sel_periph;
+
+ union
+ {
+ struct pad pad;
+
+ struct
+ {
+ struct mouse mouse;
+ struct keyboard keyboard;
+ } kbm;
+ } periph;
struct sel_instance
{
@@ -52,12 +77,6 @@ struct human_player
unsigned long gui_res[MAX_RESOURCE_TYPES];
};
-struct human_player_cfg
-{
- struct player_cfg pl;
- int padn;
-};
-
int human_player_init(const struct human_player_cfg *cfg, struct human_player *h);
bool human_player_update(struct human_player *h, struct player_others *o);
int human_player_render(const struct human_player *h, const struct player_others *o);
diff --git a/src/player/src/human_player.c b/src/player/src/human_player.c
index 7fd558a..b45e24f 100644
--- a/src/player/src/human_player.c
+++ b/src/player/src/human_player.c
@@ -2,8 +2,10 @@
#include <player.h>
#include <building.h>
#include <camera.h>
+#include <gfx.h>
#include <gui.h>
#include <instance.h>
+#include <keyboard.h>
#include <pad.h>
#include <resource.h>
#include <unit.h>
@@ -29,7 +31,7 @@ static bool instance_selected(const struct human_player *const h,
}
static bool select_units(struct human_player *const h, const short x,
- const short y)
+ const short y, const bool excl)
{
struct player *const pl = &h->pl;
@@ -50,19 +52,37 @@ static bool select_units(struct human_player *const h, const short x,
&& cursor_collision(&h->cam, &in->r)
&& h->n_sel < sizeof h->sel / sizeof *h->sel)
{
- for (size_t i = 0; i < sizeof h->sel / sizeof *h->sel; i++)
- {
- struct sel_instance *const sel = &h->sel[i];
+ struct sel_instance *sel = NULL;
- if (!sel->d.u)
+ if (excl)
+ {
+ sel = h->sel;
+ h->n_sel = 1;
+ }
+ else
+ {
+ for (size_t i = 0; i < sizeof h->sel / sizeof *h->sel; i++)
{
- sel->type = INSTANCE_TYPE_UNIT;
- sel->d.u = u;
- h->n_sel++;
- sfx_play(&unit_sounds[UNIT_SOUND_SELECTED]);
- return true;
+ struct sel_instance *const s = &h->sel[i];
+
+ if (!s->d.u)
+ {
+ sel = s;
+ h->n_sel++;
+ break;
+ }
}
}
+
+ if (sel)
+ {
+ sel->type = INSTANCE_TYPE_UNIT;
+ sel->d.u = u;
+ sfx_play(&unit_sounds[UNIT_SOUND_SELECTED]);
+ return true;
+ }
+
+ return false;
}
}
break;
@@ -79,7 +99,7 @@ static bool select_units(struct human_player *const h, const short x,
}
static bool select_buildings(struct human_player *const h, const short x,
- const short y)
+ const short y, const bool excl)
{
struct player *const pl = &h->pl;
@@ -96,18 +116,36 @@ static bool select_buildings(struct human_player *const h, const short x,
&& cursor_collision(&h->cam, &in->r)
&& h->n_sel < sizeof h->sel / sizeof *h->sel)
{
- for (size_t i = 0; i < sizeof h->sel / sizeof *h->sel; i++)
- {
- struct sel_instance *const sel = &h->sel[i];
+ struct sel_instance *sel = NULL;
- if (!sel->d.b)
+ if (excl)
+ {
+ sel = h->sel;
+ h->n_sel = 1;
+ }
+ else
+ {
+ for (size_t i = 0; i < sizeof h->sel / sizeof *h->sel; i++)
{
- sel->type = INSTANCE_TYPE_BUILDING;
- sel->d.b = b;
- h->n_sel++;
- return true;
+ struct sel_instance *const s = &h->sel[i];
+
+ if (!s->d.b)
+ {
+ sel = s;
+ h->n_sel++;
+ break;
+ }
}
}
+
+ if (sel)
+ {
+ sel->type = INSTANCE_TYPE_BUILDING;
+ sel->d.b = b;
+ return true;
+ }
+
+ return false;
}
}
}
@@ -116,7 +154,7 @@ static bool select_buildings(struct human_player *const h, const short x,
}
static bool select_resources(struct human_player *const h, const short x,
- const short y, const struct player_others *const o)
+ const short y, const struct player_others *const o, const bool excl)
{
for (size_t i = 0; i < o->n_res; i++)
{
@@ -131,18 +169,36 @@ static bool select_resources(struct human_player *const h, const short x,
&& cursor_collision(&h->cam, &in->r)
&& h->n_sel < sizeof h->sel / sizeof *h->sel)
{
- for (size_t i = 0; i < sizeof h->sel / sizeof *h->sel; i++)
- {
- struct sel_instance *const sel = &h->sel[i];
+ struct sel_instance *sel = NULL;
- if (!sel->d.r)
+ if (excl)
+ {
+ sel = h->sel;
+ h->n_sel = 1;
+ }
+ else
+ {
+ for (size_t i = 0; i < sizeof h->sel / sizeof *h->sel; i++)
{
- sel->type = INSTANCE_TYPE_RESOURCE;
- sel->d.r = r;
- h->n_sel++;
- return true;
+ struct sel_instance *const s = &h->sel[i];
+
+ if (!s->d.r)
+ {
+ sel = s;
+ h->n_sel++;
+ break;
+ }
}
}
+
+ if (sel)
+ {
+ sel->type = INSTANCE_TYPE_RESOURCE;
+ sel->d.r = r;
+ return true;
+ }
+
+ return false;
}
}
}
@@ -150,16 +206,16 @@ static bool select_resources(struct human_player *const h, const short x,
return false;
}
-static void select_instances(struct human_player *const h,
- const struct player_others *const o)
+static bool select_instances(struct human_player *const h,
+ const struct player_others *const o, const bool excl)
{
unsigned long x, y;
cursor_pos(&h->cam, &x, &y);
- if (!select_buildings(h, x, y)
- && !select_units(h, x, y))
- select_resources(h, x, y, o);
+ return select_buildings(h, x, y, excl)
+ || select_units(h, x, y, excl)
+ || select_resources(h, x, y, o, excl);
}
static bool instance_collision(const struct camera *const cam,
@@ -450,6 +506,58 @@ static void update_target(struct human_player *const h)
}
}
+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);
+
+ if (pad_justpressed(p, PAD_KEY_OPTIONS)
+ || pad_justpressed(p, PAD_KEY_EXIT))
+ ret = true;
+ else if (pad_justpressed(p, PAD_KEY_A))
+ select_instances(h, o, false);
+ else if (pad_justpressed(p, PAD_KEY_B))
+ move_units(h, o);
+ else if (pad_justpressed(p, PAD_KEY_C))
+ deselect_instances(h);
+ else if (pad_justpressed(p, PAD_KEY_E))
+ h->top_gui ^= true;
+
+ return ret;
+}
+
+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;
+
+ mouse_update(m);
+ keyboard_update(k);
+
+ if (mouse_justreleased(m, MOUSE_BUTTON_LEFT))
+ {
+ const bool shift_pressed =
+ keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_LSHIFT))
+ || keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_RSHIFT));
+
+ if (!select_instances(h, o, !shift_pressed))
+ 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;
+}
+
bool human_player_update(struct human_player *const h,
struct player_others *const o)
{
@@ -459,22 +567,22 @@ bool human_player_update(struct human_player *const h,
if (p->alive)
{
gui_update(h);
- pad_update(&h->pad);
update_selected(h);
update_target(h);
- if (pad_justpressed(&h->pad, PAD_KEY_OPTIONS))
- ret = true;
- else if (pad_justpressed(&h->pad, PAD_KEY_A))
- select_instances(h, o);
- else if (pad_justpressed(&h->pad, PAD_KEY_B))
- move_units(h, o);
- else if (pad_justpressed(&h->pad, PAD_KEY_C))
- deselect_instances(h);
- else if (pad_justpressed(&h->pad, PAD_KEY_E))
- h->top_gui ^= true;
+ switch (h->sel_periph)
+ {
+ case HUMAN_PLAYER_PERIPH_PAD:
+ ret = update_from_pad(h, o);
+ camera_update_pad(&h->cam, &h->periph.pad);
+ break;
+
+ case HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE:
+ ret = update_from_keyboard_mouse(h, o);
+ camera_update_mouse(&h->cam, &h->periph.kbm.mouse);
+ break;
+ }
- camera_update(&h->cam, &h->pad);
player_update(p);
}
@@ -562,7 +670,18 @@ int human_player_init(const struct human_player_cfg *const cfg,
if (player_init(&cfg->pl, &h->pl))
return -1;
- pad_init(cfg->padn, &h->pad);
+ switch (h->sel_periph = cfg->sel_periph)
+ {
+ 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;
+ }
+
cursor_init(&h->cam.cursor);
h->top_gui = true;
memmove(h->gui_res, h->pl.resources, sizeof h->gui_res);