aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorneonloop2023-01-14 07:08:49 +0000
committerneonloop2023-01-14 07:08:49 +0000
commit56b37f20f5fb5e9b16acf0f8fbe2a5f878f0b944 (patch)
tree206bb7430a0466f84cbd8543ddb1ff0ae7bf389e
parent13447e236c51cd48372355e5c4d5e5379d39b892 (diff)
downloadpicoarch-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.patch199
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);
+