X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=in_sdl.c;h=d8f5ed5a71089fa8120f204be22c37cc606b4c10;hb=HEAD;hp=af8d636cd7cf55713eb473340c09a8ba2f2968ca;hpb=c19e28f62660cdaed26698234cff9c084517b34c;p=libpicofe.git diff --git a/in_sdl.c b/in_sdl.c index af8d636..d8f5ed5 100644 --- a/in_sdl.c +++ b/in_sdl.c @@ -24,7 +24,12 @@ struct in_sdl_state { SDL_Joystick *joy; int joy_id; int axis_keydown[2]; +#ifdef SDL_REDRAW_EVT + int rdraw; +#endif keybits_t keystate[SDLK_LAST / KEYBITS_WORD_BITS + 1]; + // emulator keys should always be processed immediately lest one is lost + keybits_t emu_keys[SDLK_LAST / KEYBITS_WORD_BITS + 1]; }; static void (*ext_event_handler)(void *event); @@ -165,11 +170,16 @@ static const char * const in_sdl_keys[SDLK_LAST] = { 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"); @@ -178,7 +188,7 @@ static void in_sdl_probe(const in_drv_t *drv) 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); @@ -199,7 +209,7 @@ static void in_sdl_probe(const in_drv_t *drv) 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) @@ -218,9 +228,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; } @@ -238,26 +252,41 @@ static void update_keystate(keybits_t *keystate, int sym, int is_down) *ks_word &= ~mask; } +static int get_keystate(keybits_t *keystate, int sym) +{ + keybits_t *ks_word, mask; + + mask = 1; + mask <<= sym & (KEYBITS_WORD_BITS - 1); + ks_word = keystate + sym / KEYBITS_WORD_BITS; + return !!(*ks_word & mask); +} + static int handle_event(struct in_sdl_state *state, SDL_Event *event, - int *kc_out, int *down_out) + int *kc_out, int *down_out, int *emu_out) { + int emu; + if (event->type != SDL_KEYDOWN && event->type != SDL_KEYUP) return -1; + emu = get_keystate(state->emu_keys, event->key.keysym.sym); update_keystate(state->keystate, event->key.keysym.sym, event->type == SDL_KEYDOWN); if (kc_out != NULL) *kc_out = event->key.keysym.sym; if (down_out != NULL) *down_out = event->type == SDL_KEYDOWN; + if (emu_out != NULL) + *emu_out = emu; return 1; } static int handle_joy_event(struct in_sdl_state *state, SDL_Event *event, - int *kc_out, int *down_out) + int *kc_out, int *down_out, int *emu_out) { - int kc = -1, down = 0, ret = 0; + int kc = -1, down = 0, emu = 0, ret = 0; /* TODO: remaining axis */ switch (event->type) { @@ -273,8 +302,10 @@ static int handle_joy_event(struct in_sdl_state *state, SDL_Event *event, } else if (event->jaxis.value < -16384) { kc = state->axis_keydown[event->jaxis.axis]; - if (kc) + if (kc) { + emu |= get_keystate(state->emu_keys, kc); update_keystate(state->keystate, kc, 0); + } kc = event->jaxis.axis ? SDLK_UP : SDLK_LEFT; state->axis_keydown[event->jaxis.axis] = kc; down = 1; @@ -282,8 +313,10 @@ static int handle_joy_event(struct in_sdl_state *state, SDL_Event *event, } else if (event->jaxis.value > 16384) { kc = state->axis_keydown[event->jaxis.axis]; - if (kc) + if (kc) { + emu |= get_keystate(state->emu_keys, kc); update_keystate(state->keystate, kc, 0); + } kc = event->jaxis.axis ? SDLK_DOWN : SDLK_RIGHT; state->axis_keydown[event->jaxis.axis] = kc; down = 1; @@ -303,12 +336,16 @@ static int handle_joy_event(struct in_sdl_state *state, SDL_Event *event, return -1; } - if (ret) + if (ret) { + emu |= get_keystate(state->emu_keys, kc); update_keystate(state->keystate, kc, down); + } if (kc_out != NULL) *kc_out = kc; if (down_out != NULL) *down_out = down; + if (emu_out != 0) + *emu_out = emu; return ret; } @@ -320,11 +357,21 @@ static int collect_events(struct in_sdl_state *state, int *one_kc, int *one_down { SDL_Event events[4]; Uint32 mask = state->joy ? JOY_EVENTS : (SDL_ALLEVENTS & ~JOY_EVENTS); - int count, maxcount; + int count, maxcount, is_emukey = 0; int i, ret, retval = 0; int num_events, num_peeped_events; SDL_Event *event; +#ifdef SDL_REDRAW_EVT + if (state->rdraw) { + if (one_kc != NULL) + *one_kc = SDLK_UNKNOWN; + if (one_down != NULL) + *one_down = 0; + state->rdraw = 0; + return 1; + } +#endif maxcount = (one_kc != NULL) ? 1 : sizeof(events) / sizeof(events[0]); SDL_PumpEvents(); @@ -337,12 +384,13 @@ static int collect_events(struct in_sdl_state *state, int *one_kc, int *one_down break; for (i = 0; i < count; i++) { event = &events[i]; - if (state->joy) + if (state->joy) { ret = handle_joy_event(state, - event, one_kc, one_down); - else + event, one_kc, one_down, &is_emukey); + } else { ret = handle_event(state, - event, one_kc, one_down); + event, one_kc, one_down, &is_emukey); + } if (ret < 0) { switch (ret) { case -2: @@ -353,15 +401,25 @@ static int collect_events(struct in_sdl_state *state, int *one_kc, int *one_down ext_event_handler(event); break; } - continue; +#ifdef SDL_REDRAW_EVT + if (ret != -2 && event->type == SDL_VIDEORESIZE) { + if (one_kc != NULL) + *one_kc = SDLK_UNKNOWN; + if (one_down != NULL) + *one_down = 1; + state->rdraw = 1; + is_emukey = 1, ret = 1; + } else + continue; +#endif } retval |= ret; - if (one_kc != NULL && ret) + if ((is_emukey || one_kc != NULL) && retval) { // don't lose events other devices might want to handle - for (i++; i < count; i++) - SDL_PushEvent(&events[i]); + if (++i < count) + SDL_PeepEvents(events+i, count-i, SDL_ADDEVENT, mask); goto out; } } @@ -413,11 +471,15 @@ 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; + if (pdata->key_names) + key_names = pdata->key_names; + if (state->joy) { map = pdata->joy_map; map_len = pdata->jmap_size; @@ -436,6 +498,11 @@ static int in_sdl_menu_translate(void *drv_data, int keycode, char *charcode) } else { +#ifdef SDL_REDRAW_EVT + if (keycode == SDLK_UNKNOWN) + ret = PBTN_RDRAW; + else +#endif for (i = 0; i < map_len; i++) { if (map[i].key == keycode) { ret = map[i].pbtn; @@ -444,16 +511,33 @@ 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]; } } return ret; } +static int in_sdl_clean_binds(void *drv_data, int *binds, int *def_finds) +{ + struct in_sdl_state *state = drv_data; + int i, t, cnt = 0; + + memset(state->emu_keys, 0, sizeof(state->emu_keys)); + for (t = 0; t < IN_BINDTYPE_COUNT; t++) + for (i = 0; i < SDLK_LAST; i++) + if (binds[IN_BIND_OFFS(i, t)]) { + if (t == IN_BINDTYPE_EMU) + update_keystate(state->emu_keys, i, 1); + cnt ++; + } + + return cnt; +} + static const in_drv_t in_sdl_drv = { .prefix = IN_SDL_PREFIX, .probe = in_sdl_probe, @@ -462,6 +546,7 @@ static const in_drv_t in_sdl_drv = { .update = in_sdl_update, .update_keycode = in_sdl_update_keycode, .menu_translate = in_sdl_menu_translate, + .clean_binds = in_sdl_clean_binds, }; int in_sdl_init(const struct in_pdata *pdata, void (*handler)(void *event))