diff options
author | neonloop | 2023-01-14 07:08:49 +0000 |
---|---|---|
committer | neonloop | 2023-01-14 07:08:49 +0000 |
commit | 56b37f20f5fb5e9b16acf0f8fbe2a5f878f0b944 (patch) | |
tree | 206bb7430a0466f84cbd8543ddb1ff0ae7bf389e | |
parent | 13447e236c51cd48372355e5c4d5e5379d39b892 (diff) | |
download | picoarch-56b37f20f5fb5e9b16acf0f8fbe2a5f878f0b944.tar.gz picoarch-56b37f20f5fb5e9b16acf0f8fbe2a5f878f0b944.tar.bz2 picoarch-56b37f20f5fb5e9b16acf0f8fbe2a5f878f0b944.zip |
Updates libpicofe key combo handling
Does not prevent buttons when no combo is bound, delays keyup of mod
key to allow normal handling, ignores combo key handling when no combo
keys are bound
-rw-r--r-- | patches/libpicofe/0001-key-combos.patch | 199 |
1 files changed, 187 insertions, 12 deletions
diff --git a/patches/libpicofe/0001-key-combos.patch b/patches/libpicofe/0001-key-combos.patch index 7105fc3..b2e0819 100644 --- a/patches/libpicofe/0001-key-combos.patch +++ b/patches/libpicofe/0001-key-combos.patch @@ -1,8 +1,8 @@ diff --git a/in_sdl.c b/in_sdl.c -index a84c781..bab649a 100644 +index a84c781..bc0e79b 100644 --- a/in_sdl.c +++ b/in_sdl.c -@@ -19,11 +19,18 @@ +@@ -19,14 +19,24 @@ typedef unsigned long keybits_t; #define KEYBITS_WORD_BITS (sizeof(keybits_t) * 8) @@ -18,10 +18,40 @@ index a84c781..bab649a 100644 int joy_id; int axis_keydown[2]; + enum mod_state mod_state; ++ int allow_unbound_mods; ++ char *mods_bound; 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]; -@@ -259,6 +266,139 @@ static int get_keystate(keybits_t *keystate, int sym) ++ short delayed_key; + }; + + static void (*ext_event_handler)(void *event); +@@ -184,6 +194,11 @@ static void in_sdl_probe(const in_drv_t *drv) + } + + state->drv = drv; ++ ++ if (pdata->mod_key) { ++ state->mods_bound = calloc(pdata->modmap_size, sizeof(char)); ++ } ++ + in_register(IN_SDL_PREFIX "keys", -1, state, SDLK_LAST, + key_names, 0); + +@@ -220,6 +235,11 @@ static void in_sdl_free(void *drv_data) + if (state != NULL) { + if (state->joy != NULL) + SDL_JoystickClose(state->joy); ++ ++ if (state->mods_bound != NULL) { ++ free(state->mods_bound); ++ } ++ + free(state); + } + } +@@ -259,6 +279,169 @@ static int get_keystate(keybits_t *keystate, int sym) return !!(*ks_word & mask); } @@ -73,7 +103,9 @@ index a84c781..bab649a 100644 + for (i = 0; i < pdata->modmap_size; i++) { + map = &pdata->mod_keymap[i]; + -+ if (get_keystate(keystate, map->inkey)) { ++ if (get_keystate(keystate, map->inkey) && ++ (state->allow_unbound_mods || ++ (state->mods_bound && state->mods_bound[i]))) { + state->mod_state = MOD_YES; + switch_key(event, keystate, map->inkey, map->outkey); + } @@ -93,9 +125,8 @@ index a84c781..bab649a 100644 + event->key.state = SDL_PRESSED; + SDL_PushEvent(event); + -+ event->type = SDL_KEYUP; -+ event->key.state = SDL_RELEASED; -+ SDL_PushEvent(event); ++ /* Delay keyup to force handling */ ++ state->delayed_key = event->key.keysym.sym; + } + break; + case MOD_YES: @@ -119,17 +150,24 @@ index a84c781..bab649a 100644 + break; + } + } else { ++ int found = 0; + for (i = 0; i < pdata->modmap_size; i++) { + map = &pdata->mod_keymap[i]; + -+ if (map->inkey == key) { ++ if (map->inkey == key && ++ (state->allow_unbound_mods || ++ (state->mods_bound && state->mods_bound[i]))) { + state->mod_state = MOD_YES; + + event->key.keysym.sym = map->outkey; + update_keystate(keystate, map->outkey, event->type == SDL_KEYDOWN); + SDL_PushEvent(event); ++ found = 1; + } + } ++ ++ if (!found) ++ SDL_PushEvent(event); + } +} + @@ -137,6 +175,7 @@ index a84c781..bab649a 100644 +{ + const struct in_pdata *pdata = state->drv->pdata; + SDL_Event events[10]; /* Must be bigger than events size in collect_events */ ++ SDL_Event delayed_event = {0}; + keybits_t keystate[SDLK_LAST / KEYBITS_WORD_BITS + 1]; + int count; + int has_events; @@ -145,6 +184,18 @@ index a84c781..bab649a 100644 + if (!pdata->mod_key) + return; + ++ if (!state->allow_unbound_mods && state->mods_bound) { ++ int bound = 0; ++ for (i = 0; i < pdata->modmap_size; i++) { ++ bound = state->mods_bound[i]; ++ if (bound) ++ break; ++ } ++ ++ if (!bound) ++ return; ++ } ++ + has_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, mask); + + if (!has_events) @@ -153,6 +204,15 @@ index a84c781..bab649a 100644 + memcpy(keystate, state->keystate, sizeof(keystate)); + + count = SDL_PeepEvents(events, (sizeof(events) / sizeof(events[0])), SDL_GETEVENT, mask); ++ ++ if (state->delayed_key != 0) { ++ delayed_event.type = SDL_KEYUP; ++ delayed_event.key.state = SDL_PRESSED; ++ delayed_event.key.keysym.sym = state->delayed_key; ++ SDL_PushEvent(&delayed_event); ++ state->delayed_key = 0; ++ } ++ + for (i = 0; i < count; i++) { + translate_combo_event(state, &events[i], keystate); + } @@ -161,7 +221,7 @@ index a84c781..bab649a 100644 static int handle_event(struct in_sdl_state *state, SDL_Event *event, int *kc_out, int *down_out, int *emu_out) { -@@ -363,6 +503,9 @@ static int collect_events(struct in_sdl_state *state, int *one_kc, int *one_down +@@ -363,6 +546,9 @@ static int collect_events(struct in_sdl_state *state, int *one_kc, int *one_down SDL_PumpEvents(); @@ -171,11 +231,99 @@ index a84c781..bab649a 100644 num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, mask); for (num_peeped_events = 0; num_peeped_events < num_events; num_peeped_events += count) { +@@ -406,12 +592,34 @@ out: + return retval; + } + ++static void update_modifier_binds(struct in_sdl_state *state, const int *binds) ++{ ++ int i, b; ++ const struct in_pdata *pdata = state->drv->pdata; ++ const struct mod_keymap *map; ++ ++ for (i = 0; i < pdata->modmap_size; i++) { ++ map = &pdata->mod_keymap[i]; ++ ++ for (b = 0; b < IN_BINDTYPE_COUNT; b++) { ++ state->mods_bound[i] = 0; ++ if (binds[IN_BIND_OFFS(map->outkey, b)]) { ++ state->mods_bound[i] = 1; ++ break; ++ } ++ } ++ } ++} ++ + static int in_sdl_update(void *drv_data, const int *binds, int *result) + { + struct in_sdl_state *state = drv_data; + keybits_t mask; + int i, sym, bit, b; + ++ if (state->mods_bound) ++ update_modifier_binds(state, binds); ++ + collect_events(state, NULL, NULL); + + for (i = 0; i < SDLK_LAST / KEYBITS_WORD_BITS + 1; i++) { +@@ -510,6 +718,35 @@ static int in_sdl_clean_binds(void *drv_data, int *binds, int *def_finds) + return cnt; + } + ++static int in_sdl_get_config(void *drv_data, int what, int *val) ++{ ++ struct in_sdl_state *state = drv_data; ++ ++ switch (what) { ++ case IN_CFG_ALLOW_UNBOUND_MOD_KEYS: ++ *val = state->allow_unbound_mods; ++ break; ++ default: ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int in_sdl_set_config(void *drv_data, int what, int val) ++{ ++ struct in_sdl_state *state = drv_data; ++ ++ switch (what) { ++ case IN_CFG_ALLOW_UNBOUND_MOD_KEYS: ++ state->allow_unbound_mods = val; ++ default: ++ return -1; ++ } ++ ++ return 0; ++} ++ + static const in_drv_t in_sdl_drv = { + .prefix = IN_SDL_PREFIX, + .probe = in_sdl_probe, +@@ -519,6 +756,8 @@ static const in_drv_t in_sdl_drv = { + .update_keycode = in_sdl_update_keycode, + .menu_translate = in_sdl_menu_translate, + .clean_binds = in_sdl_clean_binds, ++ .get_config = in_sdl_get_config, ++ .set_config = in_sdl_set_config, + }; + + int in_sdl_init(const struct in_pdata *pdata, void (*handler)(void *event)) diff --git a/input.h b/input.h -index 360b65b..895ad61 100644 +index 360b65b..f95ddf0 100644 --- a/input.h +++ b/input.h -@@ -110,6 +110,11 @@ struct menu_keymap { +@@ -59,6 +59,7 @@ + enum { + IN_CFG_BIND_COUNT = 0, + IN_CFG_DOES_COMBOS, ++ IN_CFG_ALLOW_UNBOUND_MOD_KEYS, + IN_CFG_BLOCKING, + IN_CFG_KEY_NAMES, + IN_CFG_ABS_DEAD_ZONE, /* dead zone for analog-digital mapping */ +@@ -110,6 +111,11 @@ struct menu_keymap { short pbtn; }; @@ -187,7 +335,7 @@ index 360b65b..895ad61 100644 struct in_pdata { const struct in_default_bind *defbinds; const struct menu_keymap *key_map; -@@ -117,6 +122,9 @@ struct in_pdata { +@@ -117,6 +123,9 @@ struct in_pdata { const struct menu_keymap *joy_map; size_t jmap_size; const char * const *key_names; @@ -197,3 +345,30 @@ index 360b65b..895ad61 100644 }; /* to be called by drivers */ +diff --git a/menu.c b/menu.c +index e91f84a..616daac 100644 +--- a/menu.c ++++ b/menu.c +@@ -1455,6 +1455,7 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ + int i, sel = 0, menu_sel_max = opt_cnt - 1, does_combos = 0;
+ int dev_id, bind_dev_id, dev_count, kc, is_down, mkey;
+ int unbind, bindtype, mask_shift;
++ int allow_unbound_mods = 0;
+
+ for (i = 0, dev_id = -1, dev_count = 0; i < IN_MAX_DEVS; i++) {
+ if (in_get_dev_name(i, 1, 0) != NULL) {
+@@ -1515,10 +1516,14 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ +
+ draw_key_config(opts, opt_cnt, player_idx, sel, dev_id, dev_count, 1);
+
++ in_get_config(bind_dev_id, IN_CFG_ALLOW_UNBOUND_MOD_KEYS, &allow_unbound_mods);
++ in_set_config_int(bind_dev_id, IN_CFG_ALLOW_UNBOUND_MOD_KEYS, 1);
+ /* wait for some up event */
+ for (is_down = 1; is_down; )
+ kc = in_update_keycode(&bind_dev_id, &is_down, NULL, -1);
+
++ in_set_config_int(bind_dev_id, IN_CFG_ALLOW_UNBOUND_MOD_KEYS, allow_unbound_mods);
++
+ i = count_bound_keys(bind_dev_id, opts[sel].mask << mask_shift, bindtype);
+ unbind = (i > 0);
+
|