X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=in_sdl.c;h=046f92dcd32623341b09ef88068966f0da675c97;hb=8b4363e302e6bbcf41321ec70f8c033efed5840d;hp=ce5753656d10557198e41e17ac74b92af8863aeb;hpb=a86e9a3e58f55bf49d99dfd5e5d6413e17149593;p=libpicofe.git diff --git a/in_sdl.c b/in_sdl.c index ce57536..046f92d 100644 --- a/in_sdl.c +++ b/in_sdl.c @@ -5,6 +5,7 @@ * (at your option): * - GNU GPL, version 2 or later. * - GNU LGPL, version 2.1 or later. + * - MAME license. * See the COPYING file in the top-level directory. */ @@ -19,12 +20,15 @@ typedef unsigned long keybits_t; #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]; keybits_t keystate[SDLK_LAST / KEYBITS_WORD_BITS + 1]; }; +static void (*ext_event_handler)(void *event); + static const char * const in_sdl_keys[SDLK_LAST] = { [SDLK_BACKSPACE] = "backspace", [SDLK_TAB] = "tab", @@ -58,7 +62,7 @@ static const char * const in_sdl_keys[SDLK_LAST] = { [SDLK_8] = "8", [SDLK_9] = "9", [SDLK_COLON] = ":", - [SDLK_SEMICOLON] = ",", + [SDLK_SEMICOLON] = ";", [SDLK_LESS] = "<", [SDLK_EQUALS] = "=", [SDLK_GREATER] = ">", @@ -120,7 +124,6 @@ static const char * const in_sdl_keys[SDLK_LAST] = { [SDLK_DOWN] = "down", [SDLK_RIGHT] = "right", [SDLK_LEFT] = "left", - [SDLK_DOWN] = "down", [SDLK_INSERT] = "insert", [SDLK_HOME] = "home", [SDLK_END] = "end", @@ -160,21 +163,27 @@ static const char * const in_sdl_keys[SDLK_LAST] = { [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); @@ -192,9 +201,10 @@ static void in_sdl_probe(void) } 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) @@ -213,9 +223,13 @@ static void in_sdl_free(void *drv_data) } 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; } @@ -237,7 +251,7 @@ static int handle_event(struct in_sdl_state *state, SDL_Event *event, int *kc_out, int *down_out) { if (event->type != SDL_KEYDOWN && event->type != SDL_KEYUP) - return 0; + return -1; update_keystate(state->keystate, event->key.keysym.sym, event->type == SDL_KEYDOWN); @@ -254,10 +268,11 @@ static int handle_joy_event(struct in_sdl_state *state, SDL_Event *event, { 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) { @@ -287,10 +302,14 @@ static int handle_joy_event(struct in_sdl_state *state, SDL_Event *event, 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; break; + default: + return -1; } if (ret) @@ -312,24 +331,48 @@ static int collect_events(struct in_sdl_state *state, int *one_kc, int *one_down 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); + 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; + } } } @@ -375,52 +418,26 @@ static int in_sdl_update_keycode(void *drv_data, int *is_down) 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_a, PBTN_MA2 }, - { SDLK_s, 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) { @@ -440,10 +457,10 @@ static int in_sdl_menu_translate(void *drv_data, int keycode, char *charcode) } 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]; } } @@ -460,8 +477,14 @@ static const in_drv_t in_sdl_drv = { .menu_translate = in_sdl_menu_translate, }; -void in_sdl_init(const struct in_default_bind *defbinds) +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; +}