diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2022-02-24 17:55:57 +0100 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2022-03-30 08:20:21 +0200 |
| commit | 9eee43d3bb24000077602a62dfdfeee2606f1589 (patch) | |
| tree | 0e5f8efef62b068e252fe9c98c14fec723e0a7a3 /src/player | |
| parent | 18717569acda82b26099c62410df3b398d596ba1 (diff) | |
| download | rts-9eee43d3bb24000077602a62dfdfeee2606f1589.tar.gz | |
Add support for keyboard and mouse
Diffstat (limited to 'src/player')
| -rw-r--r-- | src/player/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/player/inc/human_player.h | 33 | ||||
| -rw-r--r-- | src/player/src/human_player.c | 211 |
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); |
