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

110 lines
2.9 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_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_EXIT, .sdl_key = SDLK_ESCAPE},
{.key = KEYBOARD_KEY_F11, .sdl_key = SDLK_F11},
{.key = KEYBOARD_KEY_W, .sdl_key = SDLK_w},
{.key = KEYBOARD_KEY_A, .sdl_key = SDLK_a},
{.key = KEYBOARD_KEY_S, .sdl_key = SDLK_s},
{.key = KEYBOARD_KEY_D, .sdl_key = SDLK_d}
};
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;
}
}