gp2x: pollux: various fixes
[libpicofe.git] / in_sdl.c
index ce57536..45a0276 100644 (file)
--- 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.
  */
 
@@ -25,6 +26,8 @@ struct in_sdl_state {
        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 +61,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 +123,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",
@@ -237,7 +239,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 +256,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 +290,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 +319,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;
+                       }
                }
        }
 
@@ -389,8 +420,8 @@ static const struct menu_keymap key_pbtn_map[] =
        /* 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_SEMICOLON,    PBTN_MA2 },
+       { SDLK_QUOTE,        PBTN_MA3 },
        { SDLK_BACKSLASH,    PBTN_MENU },
        { SDLK_LEFTBRACKET,  PBTN_L },
        { SDLK_RIGHTBRACKET, PBTN_R },
@@ -460,8 +491,9 @@ static const in_drv_t in_sdl_drv = {
        .menu_translate = in_sdl_menu_translate,
 };
 
-void in_sdl_init(const struct in_default_bind *defbinds)
+void in_sdl_init(const struct in_default_bind *defbinds,
+                void (*handler)(void *event))
 {
        in_register_driver(&in_sdl_drv, defbinds);
+       ext_event_handler = handler;
 }
-