#define KEYBITS_WORD_BITS (sizeof(keybits_t) * 8)
struct in_sdl_state {
+ const in_drv_t *drv;
SDL_Joystick *joy;
int joy_id;
int axis_keydown[2];
[SDLK_COMPOSE] = "compose",
};
-static void in_sdl_probe(void)
+static void in_sdl_probe(const in_drv_t *drv)
{
+ const struct in_pdata *pdata = drv->pdata;
+ const char * const * key_names = in_sdl_keys;
struct in_sdl_state *state;
SDL_Joystick *joy;
int i, joycount;
char name[256];
+ if (pdata->key_names)
+ key_names = pdata->key_names;
+
state = calloc(1, sizeof(*state));
if (state == NULL) {
fprintf(stderr, "in_sdl: OOM\n");
return;
}
+ state->drv = drv;
in_register(IN_SDL_PREFIX "keys", -1, state, SDLK_LAST,
- in_sdl_keys, 0);
+ key_names, 0);
/* joysticks go here too */
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
}
state->joy = joy;
state->joy_id = i;
+ state->drv = drv;
snprintf(name, sizeof(name), IN_SDL_PREFIX "%s", SDL_JoystickName(i));
- in_register(name, -1, state, SDLK_LAST, in_sdl_keys, 0);
+ in_register(name, -1, state, SDLK_LAST, key_names, 0);
}
if (joycount > 0)
}
static const char * const *
-in_sdl_get_key_names(int *count)
+in_sdl_get_key_names(const in_drv_t *drv, int *count)
{
+ const struct in_pdata *pdata = drv->pdata;
*count = SDLK_LAST;
+
+ if (pdata->key_names)
+ return pdata->key_names;
return in_sdl_keys;
}
{
int kc = -1, down = 0, ret = 0;
- /* FIXME: should ckeck .which */
/* TODO: remaining axis */
switch (event->type) {
case SDL_JOYAXISMOTION:
+ if (event->jaxis.which != state->joy_id)
+ return -2;
if (event->jaxis.axis > 1)
break;
if (-16384 <= event->jaxis.value && event->jaxis.value <= 16384) {
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
+ if (event->jbutton.which != state->joy_id)
+ return -2;
kc = (int)event->jbutton.button + SDLK_WORLD_0;
down = event->jbutton.state == SDL_PRESSED;
ret = 1;
Uint32 mask = state->joy ? JOY_EVENTS : (SDL_ALLEVENTS & ~JOY_EVENTS);
int count, maxcount;
int i, ret, retval = 0;
+ int num_events, num_peeped_events;
+ SDL_Event *event;
maxcount = (one_kc != NULL) ? 1 : sizeof(events) / sizeof(events[0]);
SDL_PumpEvents();
- while (1) {
+
+ num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, mask);
+
+ for (num_peeped_events = 0; num_peeped_events < num_events; num_peeped_events += count) {
count = SDL_PeepEvents(events, maxcount, SDL_GETEVENT, mask);
if (count <= 0)
break;
for (i = 0; i < count; i++) {
+ event = &events[i];
if (state->joy)
ret = handle_joy_event(state,
- &events[i], one_kc, one_down);
+ event, one_kc, one_down);
else
ret = handle_event(state,
- &events[i], one_kc, one_down);
- if (ret == -1) {
- if (ext_event_handler != NULL)
- ext_event_handler(&events[i]);
+ event, one_kc, one_down);
+ if (ret < 0) {
+ switch (ret) {
+ case -2:
+ SDL_PushEvent(event);
+ break;
+ default:
+ if (ext_event_handler != NULL)
+ ext_event_handler(event);
+ break;
+ }
continue;
}
retval |= ret;
if (one_kc != NULL && ret)
+ {
+ // don't lose events other devices might want to handle
+ for (i++; i < count; i++)
+ SDL_PushEvent(&events[i]);
goto out;
+ }
}
}
return ret_kc;
}
-struct menu_keymap {
- short key;
- short pbtn;
-};
-
-static const struct menu_keymap key_pbtn_map[] =
-{
- { SDLK_UP, PBTN_UP },
- { SDLK_DOWN, PBTN_DOWN },
- { SDLK_LEFT, PBTN_LEFT },
- { SDLK_RIGHT, PBTN_RIGHT },
- /* XXX: maybe better set this from it's plat code somehow */
- { SDLK_RETURN, PBTN_MOK },
- { SDLK_ESCAPE, PBTN_MBACK },
- { SDLK_SEMICOLON, PBTN_MA2 },
- { SDLK_QUOTE, PBTN_MA3 },
- { SDLK_BACKSLASH, PBTN_MENU },
- { SDLK_LEFTBRACKET, PBTN_L },
- { SDLK_RIGHTBRACKET, PBTN_R },
-};
-#define KEY_PBTN_MAP_SIZE (sizeof(key_pbtn_map) / sizeof(key_pbtn_map[0]))
-
-static const struct menu_keymap joybtn_pbtn_map[] =
-{
- { SDLK_UP, PBTN_UP },
- { SDLK_DOWN, PBTN_DOWN },
- { SDLK_LEFT, PBTN_LEFT },
- { SDLK_RIGHT, PBTN_RIGHT },
- /* joystick */
- { SDLK_WORLD_0, PBTN_MOK },
- { SDLK_WORLD_1, PBTN_MBACK },
- { SDLK_WORLD_2, PBTN_MA2 },
- { SDLK_WORLD_3, PBTN_MA3 },
-};
-#define JOYBTN_PBTN_MAP_SIZE (sizeof(joybtn_pbtn_map) / sizeof(joybtn_pbtn_map[0]))
-
static int in_sdl_menu_translate(void *drv_data, int keycode, char *charcode)
{
struct in_sdl_state *state = drv_data;
+ const struct in_pdata *pdata = state->drv->pdata;
+ const char * const * key_names = in_sdl_keys;
const struct menu_keymap *map;
int map_len;
int ret = 0;
int i;
- map = state->joy ? joybtn_pbtn_map : key_pbtn_map;
- map_len = state->joy ? JOYBTN_PBTN_MAP_SIZE : KEY_PBTN_MAP_SIZE;
+ if (pdata->key_names)
+ key_names = pdata->key_names;
+
+ if (state->joy) {
+ map = pdata->joy_map;
+ map_len = pdata->jmap_size;
+ } else {
+ map = pdata->key_map;
+ map_len = pdata->kmap_size;
+ }
if (keycode < 0)
{
}
if (charcode != NULL && (unsigned int)keycode < SDLK_LAST &&
- in_sdl_keys[keycode] != NULL && in_sdl_keys[keycode][1] == 0)
+ key_names[keycode] != NULL && key_names[keycode][1] == 0)
{
ret |= PBTN_CHAR;
- *charcode = in_sdl_keys[keycode][0];
+ *charcode = key_names[keycode][0];
}
}
.menu_translate = in_sdl_menu_translate,
};
-void in_sdl_init(const struct in_default_bind *defbinds,
- void (*handler)(void *event))
+int in_sdl_init(const struct in_pdata *pdata, void (*handler)(void *event))
{
- in_register_driver(&in_sdl_drv, defbinds);
+ if (!pdata) {
+ fprintf(stderr, "in_sdl: Missing input platform data\n");
+ return -1;
+ }
+
+ in_register_driver(&in_sdl_drv, pdata->defbinds, pdata);
ext_event_handler = handler;
+ return 0;
}