diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2022-09-27 17:03:06 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2022-11-01 16:26:16 +0100 |
| commit | 980858186149651df5543b6fc99a4f7db0cdd089 (patch) | |
| tree | d347200b0a562d84df505097651ad0642f207fdd /src/keyboard | |
| parent | 39f50e601d395bbd2d78d0147ac530b756da2fff (diff) | |
| download | jancity-980858186149651df5543b6fc99a4f7db0cdd089.tar.gz | |
WIP
Diffstat (limited to 'src/keyboard')
| -rw-r--r-- | src/keyboard/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/keyboard/inc/keyboard.h | 27 | ||||
| -rw-r--r-- | src/keyboard/inc/keyboard/combo.h | 15 | ||||
| -rw-r--r-- | src/keyboard/inc/keyboard/key.h (renamed from src/keyboard/inc/keyboard_key.h) | 1 | ||||
| -rw-r--r-- | src/keyboard/ps1/inc/keyboard/port.h | 18 | ||||
| -rw-r--r-- | src/keyboard/ps1/src/keyboard.c | 5 | ||||
| -rw-r--r-- | src/keyboard/sdl-1.2/inc/keyboard/port.h | 21 | ||||
| -rw-r--r-- | src/keyboard/sdl-1.2/src/keyboard.c | 184 | ||||
| -rw-r--r-- | src/keyboard/src/keyboard.c | 112 |
9 files changed, 250 insertions, 135 deletions
diff --git a/src/keyboard/CMakeLists.txt b/src/keyboard/CMakeLists.txt index 5fa8892..2cdf85c 100644 --- a/src/keyboard/CMakeLists.txt +++ b/src/keyboard/CMakeLists.txt @@ -3,9 +3,11 @@ set(inc "inc") if(PS1_BUILD) set(src ${src} "ps1/src/keyboard.c") + set(inc ${inc} "ps1/inc") set(privdeps ${privdeps} PSXSDK::PSXSDK) elseif(SDL1_2_BUILD) set(src ${src} "sdl-1.2/src/keyboard.c") + set(inc ${inc} "sdl-1.2/inc") set(privdeps ${privdeps} SDL::SDL) endif() diff --git a/src/keyboard/inc/keyboard.h b/src/keyboard/inc/keyboard.h index 0fb0179..8bae4d3 100644 --- a/src/keyboard/inc/keyboard.h +++ b/src/keyboard/inc/keyboard.h @@ -1,7 +1,9 @@ #ifndef KEYBOARD_H #define KEYBOARD_H -#include <keyboard_key.h> +#include <keyboard/key.h> +#include <keyboard/combo.h> +#include <keyboard/port.h> #include <stdbool.h> #include <stddef.h> @@ -12,26 +14,33 @@ extern "C" #define KEYBOARD_COMBO(...) (const struct keyboard_combo){.keys = {__VA_ARGS__}} -enum {KEYBOARD_MAX_COMBO_KEYS = 3}; - struct keyboard { - struct keyboard_combo + struct keyboard_input { - enum keyboard_key keys[KEYBOARD_MAX_COMBO_KEYS]; - } combo, oldcombo; + struct keyboard_combo + { + enum keyboard_key keys[KEYBOARD_MAX_COMBO_KEYS]; + } combo; + + struct keyboard_chars + { + char c[KEYBOARD_MAX_COMBO_KEYS]; + } chars; + } input, oldinput; size_t i; + struct keyboard_port port; }; void keyboard_init(struct keyboard *k); void keyboard_update(struct keyboard *k); +bool keyboard_available(void); bool keyboard_justpressed(const struct keyboard *k, const struct keyboard_combo *c); bool keyboard_pressed(const struct keyboard *k, const struct keyboard_combo *c); bool keyboard_justreleased(const struct keyboard *k, const struct keyboard_combo *c); -bool keyboard_any_justpressed(const struct keyboard *k, struct keyboard_combo *c); -bool keyboard_any_pressed(const struct keyboard *k, struct keyboard_combo *c); -char keyboard_to_char(const struct keyboard *k, enum keyboard_key key); +bool keyboard_any_justpressed(const struct keyboard *k, struct keyboard_input *in); +bool keyboard_any_pressed(const struct keyboard *k, struct keyboard_input *in); const char *keyboard_key_str(enum keyboard_key k); #ifdef __cplusplus diff --git a/src/keyboard/inc/keyboard/combo.h b/src/keyboard/inc/keyboard/combo.h new file mode 100644 index 0000000..e0ef759 --- /dev/null +++ b/src/keyboard/inc/keyboard/combo.h @@ -0,0 +1,15 @@ +#ifndef KEYBOARD_COMBO_H +#define KEYBOARD_COMBO_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum {KEYBOARD_MAX_COMBO_KEYS = 3}; + +#ifdef __cplusplus +} +#endif + +#endif /* KEYBOARD_COMBO_H */ diff --git a/src/keyboard/inc/keyboard_key.h b/src/keyboard/inc/keyboard/key.h index 49c31d2..0a25a97 100644 --- a/src/keyboard/inc/keyboard_key.h +++ b/src/keyboard/inc/keyboard/key.h @@ -59,6 +59,7 @@ extern "C" X(KEYBOARD_KEY_SPACE) \ X(KEYBOARD_KEY_MINUS) \ X(KEYBOARD_KEY_DOT) \ + X(KEYBOARD_KEY_RETURN) \ X(KEYBOARD_KEY_SLASH) enum keyboard_key diff --git a/src/keyboard/ps1/inc/keyboard/port.h b/src/keyboard/ps1/inc/keyboard/port.h new file mode 100644 index 0000000..d0d5ffd --- /dev/null +++ b/src/keyboard/ps1/inc/keyboard/port.h @@ -0,0 +1,18 @@ +#ifndef KEYBOARD_PS1_H +#define KEYBOARD_PS1_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct keyboard_port +{ + int dummy; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* KEYBOARD_PS1_H */ diff --git a/src/keyboard/ps1/src/keyboard.c b/src/keyboard/ps1/src/keyboard.c index 69e7a90..ea31cd3 100644 --- a/src/keyboard/ps1/src/keyboard.c +++ b/src/keyboard/ps1/src/keyboard.c @@ -3,3 +3,8 @@ void keyboard_update(struct keyboard *const k) { } + +bool keyboard_available(void) +{ + return false; +} diff --git a/src/keyboard/sdl-1.2/inc/keyboard/port.h b/src/keyboard/sdl-1.2/inc/keyboard/port.h new file mode 100644 index 0000000..69628f1 --- /dev/null +++ b/src/keyboard/sdl-1.2/inc/keyboard/port.h @@ -0,0 +1,21 @@ +#ifndef KEYBOARD_SDL_1_2_H +#define KEYBOARD_SDL_1_2_H + +#include <keyboard.h> +#include <SDL_keyboard.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct keyboard_port +{ + Uint8 scancodes[KEYBOARD_MAX_COMBO_KEYS]; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* KEYBOARD_SDL_1_2_H */ diff --git a/src/keyboard/sdl-1.2/src/keyboard.c b/src/keyboard/sdl-1.2/src/keyboard.c index 78056e1..87ae808 100644 --- a/src/keyboard/sdl-1.2/src/keyboard.c +++ b/src/keyboard/sdl-1.2/src/keyboard.c @@ -1,38 +1,67 @@ #include <keyboard.h> -#include <keyboard_key.h> +#include <keyboard/port.h> +#include <keyboard/key.h> #include <SDL.h> +#include <ctype.h> +#include <stddef.h> #include <stdio.h> -static void append_key(const enum keyboard_key key, struct keyboard *const k) +static void append_key(const enum keyboard_key key, const char ch, + const Uint8 scancode, struct keyboard *const k) { - struct keyboard_combo *const c = &k->combo; + struct keyboard_combo *const c = &k->input.combo; for (size_t i = 0; i < sizeof c->keys / sizeof *c->keys; i++) { enum keyboard_key *const sel = &c->keys[i]; + char *const pch = &k->input.chars.c[i]; + Uint8 *const sc = &k->port.scancodes[i]; - if (*sel == KEYBOARD_KEY_NONE) + if (*sel == KEYBOARD_KEY_NONE && !*pch) { *sel = key; + *pch = ch; + *sc = scancode; break; } } } -static void remove_key(const enum keyboard_key key, struct keyboard *const k) +static enum keyboard_key char_to_key(const char ch) { - struct keyboard_combo *const c = &k->combo; - - for (size_t i = 0; i < sizeof c->keys / sizeof *c->keys; i++) + if (ch >= 'a' && ch <= 'b') + return KEYBOARD_KEY_A + (ch - 'a'); + else if (ch >= 'A' && ch <= 'Z') + return KEYBOARD_KEY_A + (ch - 'A'); + else if (ch >= '0' && ch <= '9') + return KEYBOARD_KEY_0 + (ch - '0'); + else { - enum keyboard_key *const sel = &c->keys[i]; + static const struct map + { + enum keyboard_key key; + char ch; + } map[] = + { + {.key = KEYBOARD_KEY_DOT, .ch = '.'}, + {.key = KEYBOARD_KEY_SPACE, .ch = ' '}, + {.key = KEYBOARD_KEY_MINUS, .ch = '-'}, + {.key = KEYBOARD_KEY_SLASH, .ch = '/'} + }; - if (*sel == key) - *sel = KEYBOARD_KEY_NONE; + for (size_t i = 0; i < sizeof map / sizeof *map; i++) + { + const struct map *const m = &map[i]; + + if (ch == m->ch) + return m->key; + } } + + return KEYBOARD_KEY_NONE; } -static void key_event(const SDL_KeyboardEvent *const ev, +static void on_pressed(const SDL_KeyboardEvent *const ev, struct keyboard *const k) { static const struct keymap @@ -46,86 +75,79 @@ static void key_event(const SDL_KeyboardEvent *const ev, {.key = KEYBOARD_KEY_RIGHT, .sdl_key = SDLK_RIGHT}, {.key = KEYBOARD_KEY_UP, .sdl_key = SDLK_UP}, {.key = KEYBOARD_KEY_DOWN, .sdl_key = SDLK_DOWN}, + {.key = KEYBOARD_KEY_ESC, .sdl_key = SDLK_ESCAPE}, + {.key = KEYBOARD_KEY_F11, .sdl_key = SDLK_F11}, {.key = KEYBOARD_KEY_LCTRL, .sdl_key = SDLK_LCTRL}, {.key = KEYBOARD_KEY_RCTRL, .sdl_key = SDLK_RCTRL}, {.key = KEYBOARD_KEY_LSHIFT, .sdl_key = SDLK_LSHIFT}, {.key = KEYBOARD_KEY_RSHIFT, .sdl_key = SDLK_RSHIFT}, - {.key = KEYBOARD_KEY_ESC, .sdl_key = SDLK_ESCAPE}, - {.key = KEYBOARD_KEY_F11, .sdl_key = SDLK_F11}, - {.key = KEYBOARD_KEY_SPACE, .sdl_key = SDLK_SPACE}, - {.key = KEYBOARD_KEY_MINUS, .sdl_key = SDLK_MINUS}, - {.key = KEYBOARD_KEY_SLASH, .sdl_key = SDLK_SLASH}, - {.key = KEYBOARD_KEY_SLASH, .sdl_key = SDLK_KP_DIVIDE}, - {.key = KEYBOARD_KEY_A, .sdl_key = SDLK_a}, - {.key = KEYBOARD_KEY_B, .sdl_key = SDLK_b}, - {.key = KEYBOARD_KEY_C, .sdl_key = SDLK_c}, - {.key = KEYBOARD_KEY_D, .sdl_key = SDLK_d}, - {.key = KEYBOARD_KEY_E, .sdl_key = SDLK_e}, - {.key = KEYBOARD_KEY_F, .sdl_key = SDLK_f}, - {.key = KEYBOARD_KEY_G, .sdl_key = SDLK_g}, - {.key = KEYBOARD_KEY_H, .sdl_key = SDLK_h}, - {.key = KEYBOARD_KEY_I, .sdl_key = SDLK_i}, - {.key = KEYBOARD_KEY_J, .sdl_key = SDLK_j}, - {.key = KEYBOARD_KEY_K, .sdl_key = SDLK_k}, - {.key = KEYBOARD_KEY_L, .sdl_key = SDLK_l}, - {.key = KEYBOARD_KEY_M, .sdl_key = SDLK_m}, - {.key = KEYBOARD_KEY_N, .sdl_key = SDLK_n}, - {.key = KEYBOARD_KEY_O, .sdl_key = SDLK_o}, - {.key = KEYBOARD_KEY_P, .sdl_key = SDLK_p}, - {.key = KEYBOARD_KEY_Q, .sdl_key = SDLK_q}, - {.key = KEYBOARD_KEY_R, .sdl_key = SDLK_r}, - {.key = KEYBOARD_KEY_S, .sdl_key = SDLK_s}, - {.key = KEYBOARD_KEY_T, .sdl_key = SDLK_t}, - {.key = KEYBOARD_KEY_U, .sdl_key = SDLK_u}, - {.key = KEYBOARD_KEY_V, .sdl_key = SDLK_v}, - {.key = KEYBOARD_KEY_W, .sdl_key = SDLK_w}, - {.key = KEYBOARD_KEY_X, .sdl_key = SDLK_x}, - {.key = KEYBOARD_KEY_Y, .sdl_key = SDLK_y}, - {.key = KEYBOARD_KEY_Z, .sdl_key = SDLK_z}, - {.key = KEYBOARD_KEY_0, .sdl_key = SDLK_0}, - {.key = KEYBOARD_KEY_1, .sdl_key = SDLK_1}, - {.key = KEYBOARD_KEY_2, .sdl_key = SDLK_2}, - {.key = KEYBOARD_KEY_3, .sdl_key = SDLK_3}, - {.key = KEYBOARD_KEY_4, .sdl_key = SDLK_4}, - {.key = KEYBOARD_KEY_5, .sdl_key = SDLK_5}, - {.key = KEYBOARD_KEY_6, .sdl_key = SDLK_6}, - {.key = KEYBOARD_KEY_7, .sdl_key = SDLK_7}, - {.key = KEYBOARD_KEY_8, .sdl_key = SDLK_8}, - {.key = KEYBOARD_KEY_9, .sdl_key = SDLK_9}, - {.key = KEYBOARD_KEY_0, .sdl_key = SDLK_KP0}, - {.key = KEYBOARD_KEY_1, .sdl_key = SDLK_KP1}, - {.key = KEYBOARD_KEY_2, .sdl_key = SDLK_KP2}, - {.key = KEYBOARD_KEY_3, .sdl_key = SDLK_KP3}, - {.key = KEYBOARD_KEY_4, .sdl_key = SDLK_KP4}, - {.key = KEYBOARD_KEY_5, .sdl_key = SDLK_KP5}, - {.key = KEYBOARD_KEY_6, .sdl_key = SDLK_KP6}, - {.key = KEYBOARD_KEY_7, .sdl_key = SDLK_KP7}, - {.key = KEYBOARD_KEY_8, .sdl_key = SDLK_KP8}, - {.key = KEYBOARD_KEY_9, .sdl_key = SDLK_KP9}, - {.key = KEYBOARD_KEY_DOT, .sdl_key = SDLK_PERIOD}, - {.key = KEYBOARD_KEY_DOT, .sdl_key = SDLK_KP_PERIOD} + {.key = KEYBOARD_KEY_RETURN, .sdl_key = SDLK_KP_ENTER}, + {.key = KEYBOARD_KEY_RETURN, .sdl_key = SDLK_RETURN} }; - for (size_t i = 0; i < sizeof keymap / sizeof *keymap; i++) + const char ch = ev->keysym.unicode; + + /* According to the man page for isprint(3): + * The standards require that the argument c for these functions is + * either EOF or a value that is representable in the type unsigned + * char. If the argument is of type char, it must be cast to + * unsigned char. */ + if (isprint((unsigned char)ch)) + append_key(char_to_key(ch), ch, ev->keysym.scancode, k); + else { - const struct keymap *const km = &keymap[i]; + for (size_t i = 0; i < sizeof keymap / sizeof *keymap; i++) + { + const struct keymap *const km = &keymap[i]; - if (ev->keysym.sym == km->sdl_key) + if (ev->keysym.sym == km->sdl_key) + { + append_key(km->key, '\0', ev->keysym.scancode, k); + break; + } + } + } +} + +static void remove_key(const Uint8 scancode, struct keyboard *const k) +{ + struct keyboard_port *const p = &k->port; + + for (size_t i = 0; i < sizeof p->scancodes / sizeof *p->scancodes; i++) + { + Uint8 *const sc = &p->scancodes[i]; + + if (*sc == scancode) { - if (ev->state == SDL_PRESSED) - append_key(km->key, k); - else - remove_key(km->key, k); + struct keyboard_combo *const c = &k->input.combo; + struct keyboard_chars *const ch = &k->input.chars; + + c->keys[i] = KEYBOARD_KEY_NONE; + ch->c[i] = '\0'; + *sc = 0; + break; } } } +static void key_event(const SDL_KeyboardEvent *const ev, + struct keyboard *const k) +{ + if (ev->state == SDL_PRESSED) + on_pressed(ev, k); + else + /* SDL allows reading Unicode only for pressed events. + * In order to know whether a Unicode was released, its + * corresponding scancode must be inspected. */ + remove_key(ev->keysym.scancode, k); +} + void keyboard_update(struct keyboard *const k) { SDL_Event ev; int n; - k->oldcombo = k->combo; + k->oldinput = k->input; while ((n = SDL_PeepEvents(&ev, 1, SDL_GETEVENT, SDL_KEYEVENTMASK | SDL_QUITMASK)) > 0) @@ -139,7 +161,7 @@ void keyboard_update(struct keyboard *const k) break; case SDL_QUIT: - append_key(KEYBOARD_KEY_EXIT, k); + append_key(KEYBOARD_KEY_EXIT, '\0', 0, k); break; default: @@ -150,9 +172,11 @@ void keyboard_update(struct keyboard *const k) } if (n < 0) - { - fprintf(stderr, "%s: SDL_PeepEvents: %s\n", - __func__, SDL_GetError()); - return; - } + fprintf(stderr, "%s: SDL_PeepEvents: %s\n", __func__, SDL_GetError()); +} + +bool keyboard_available(void) +{ + /* Keyboard availability is always assumed in SDL. */ + return true; } diff --git a/src/keyboard/src/keyboard.c b/src/keyboard/src/keyboard.c index 3d6f496..21d6898 100644 --- a/src/keyboard/src/keyboard.c +++ b/src/keyboard/src/keyboard.c @@ -1,24 +1,49 @@ #include <keyboard.h> -#include <keyboard_key.h> +#include <keyboard/key.h> #include <stdbool.h> #include <stddef.h> #include <string.h> -bool keyboard_any_justpressed(const struct keyboard *const k, +static bool chars_justpressed(const struct keyboard *const k, + struct keyboard_chars *const c) +{ + bool ret = false; + const struct keyboard_chars *const ref = &k->input.chars; + + for (size_t i = 0; i < sizeof c->c / sizeof *c->c; i++) + c->c[i] = '\0'; + + for (size_t i = 0, j = 0; i < sizeof ref->c / sizeof *ref->c; i++) + { + const char ch = ref->c[i]; + + if (ch && k->oldinput.chars.c[i] != ch) + { + c->c[j++] = ch; + ret = true; + } + } + + return ret; +} + +static bool keys_justpressed(const struct keyboard *const k, struct keyboard_combo *const c) { bool ret = false; - for (size_t i = 0; i < sizeof c->keys / sizeof c->keys; i++) + for (size_t i = 0; i < sizeof c->keys / sizeof *c->keys; i++) c->keys[i] = KEYBOARD_KEY_NONE; + const struct keyboard_combo *const ref = &k->input.combo; + for (size_t i = 0, j = 0; - i < sizeof k->combo.keys / sizeof *k->combo.keys; i++) + i < sizeof ref->keys / sizeof *ref->keys; i++) { - const enum keyboard_key key = k->combo.keys[i]; + const enum keyboard_key key = ref->keys[i]; if (key != KEYBOARD_KEY_NONE - && k->oldcombo.keys[i] == KEYBOARD_KEY_NONE) + && k->oldinput.combo.keys[i] != key) { c->keys[j++] = key; ret = true; @@ -28,16 +53,24 @@ bool keyboard_any_justpressed(const struct keyboard *const k, return ret; } -bool keyboard_any_pressed(const struct keyboard *const k, +bool keyboard_any_justpressed(const struct keyboard *const k, + struct keyboard_input *const in) +{ + /* Use bitwise OR since both functions must be always executed. */ + return keys_justpressed(k, &in->combo) + | chars_justpressed(k, &in->chars); +} + +static bool keys_pressed(const struct keyboard *const k, struct keyboard_combo *const c) { - for (size_t i = 0; i < sizeof k->combo.keys / sizeof *k->combo.keys; i++) - { - const enum keyboard_key key = k->combo.keys[i]; + const struct keyboard_combo *const ref = &k->input.combo; - if (key != KEYBOARD_KEY_NONE) + for (size_t i = 0; i < sizeof ref->keys / sizeof *ref->keys; i++) + { + if (ref->keys[i] != KEYBOARD_KEY_NONE) { - *c = k->combo; + *c = *ref; return true; } } @@ -45,43 +78,28 @@ bool keyboard_any_pressed(const struct keyboard *const k, return false; } -char keyboard_to_char(const struct keyboard *const k, - const enum keyboard_key key) +static bool chars_pressed(const struct keyboard *const k, + struct keyboard_chars *const ch) { - if (key >= KEYBOARD_KEY_0 && key <= KEYBOARD_KEY_9) - return '0' + key - KEYBOARD_KEY_0; - else if (key >= KEYBOARD_KEY_A && key <= KEYBOARD_KEY_Z) - { - if (keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_LSHIFT)) - || keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_RSHIFT))) - return 'A' + key - KEYBOARD_KEY_A; - else - return 'a' + key - KEYBOARD_KEY_A; - } - else - { - static const struct map - { - enum keyboard_key key; - char ch; - } map[] = - { - {.key = KEYBOARD_KEY_DOT, .ch = '.'}, - {.key = KEYBOARD_KEY_SPACE, .ch = ' '}, - {.key = KEYBOARD_KEY_MINUS, .ch = '-'}, - {.key = KEYBOARD_KEY_SLASH, .ch = '/'} - }; + const struct keyboard_chars *const ref = &k->input.chars; - for (size_t i = 0; i < sizeof map / sizeof *map; i++) + for (size_t i = 0; i < sizeof ref->c / sizeof *ref->c; i++) + { + if (ref->c[i]) { - const struct map *const m = &map[i]; - - if (key == m->key) - return m->ch; + *ch = *ref; + return true; } } - return -1; + return false; +} + +bool keyboard_any_pressed(const struct keyboard *const k, + struct keyboard_input *const in) +{ + /* Use bitwise OR since both functions must be always executed. */ + return keys_pressed(k, &in->combo) | chars_pressed(k, &in->chars); } static bool combo_pressed(const struct keyboard_combo *const ref, @@ -117,19 +135,21 @@ static bool combo_pressed(const struct keyboard_combo *const ref, bool keyboard_pressed(const struct keyboard *const k, const struct keyboard_combo *const c) { - return combo_pressed(&k->combo, c); + return combo_pressed(&k->input.combo, c); } bool keyboard_justreleased(const struct keyboard *const k, const struct keyboard_combo *const c) { - return !combo_pressed(&k->combo, c) && combo_pressed(&k->oldcombo, c); + return !combo_pressed(&k->input.combo, c) + && combo_pressed(&k->oldinput.combo, c); } bool keyboard_justpressed(const struct keyboard *const k, const struct keyboard_combo *const c) { - return combo_pressed(&k->combo, c) && !combo_pressed(&k->oldcombo, c); + return combo_pressed(&k->input.combo, c) + && !combo_pressed(&k->oldinput.combo, c); } void keyboard_init(struct keyboard *const k) |
