rts/src/keyboard/sdl-1.2/src/keyboard.c

157 lines
5.3 KiB
C

#include <keyboard.h>
#include <keyboard_key.h>
#include <SDL.h>
#include <stdio.h>
static void append_key(const enum keyboard_key key, struct keyboard *const k)
{
struct keyboard_combo *const c = &k->combo;
for (size_t i = 0; i < sizeof c->keys / sizeof *c->keys; i++)
{
enum keyboard_key *const sel = &c->keys[i];
if (*sel == KEYBOARD_KEY_NONE)
{
*sel = key;
break;
}
}
}
static void remove_key(const enum keyboard_key key, struct keyboard *const k)
{
struct keyboard_combo *const c = &k->combo;
for (size_t i = 0; i < sizeof c->keys / sizeof *c->keys; i++)
{
enum keyboard_key *const sel = &c->keys[i];
if (*sel == key)
*sel = KEYBOARD_KEY_NONE;
}
}
static void key_event(const SDL_KeyboardEvent *const ev,
struct keyboard *const k)
{
static const struct keymap
{
enum keyboard_key key;
SDLKey sdl_key;
} keymap[] =
{
{.key = KEYBOARD_KEY_BACKSPACE, .sdl_key = SDLK_BACKSPACE},
{.key = KEYBOARD_KEY_LEFT, .sdl_key = SDLK_LEFT},
{.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_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_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}
};
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->state == SDL_PRESSED)
append_key(km->key, k);
else
remove_key(km->key, k);
}
}
}
void keyboard_update(struct keyboard *const k)
{
SDL_Event ev;
int n;
k->oldcombo = k->combo;
while ((n = SDL_PeepEvents(&ev, 1, SDL_GETEVENT,
SDL_KEYEVENTMASK | SDL_QUITMASK)) > 0)
{
switch (ev.type)
{
case SDL_KEYDOWN:
/* Fall through. */
case SDL_KEYUP:
key_event(&ev.key, k);
break;
case SDL_QUIT:
append_key(KEYBOARD_KEY_EXIT, k);
break;
default:
fprintf(stderr, "%s: unexpected SDL_Event %d\n",
__func__, ev.type);
break;
}
}
if (n < 0)
{
fprintf(stderr, "%s: SDL_PeepEvents: %s\n",
__func__, SDL_GetError());
return;
}
}