aboutsummaryrefslogtreecommitdiff
path: root/patches/libpicofe/0001-key-combos.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/libpicofe/0001-key-combos.patch')
-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);
+