From 43bca6fbee5f6b26ee02e8850bf7dace8d63336b Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 7 Feb 2011 00:49:40 +0200 Subject: [PATCH] frontend: key config: save it and make more intuitive --- frontend/common/input.c | 33 ++++++-- frontend/common/menu.c | 78 +++++++++-------- frontend/menu.c | 180 ++++++++++++++++++++++++++++++++++++++++ frontend/pandora.c | 12 +-- 4 files changed, 256 insertions(+), 47 deletions(-) diff --git a/frontend/common/input.c b/frontend/common/input.c index 7bbb39c1..52505355 100644 --- a/frontend/common/input.c +++ b/frontend/common/input.c @@ -677,22 +677,39 @@ int in_bind_key(int dev_id, int keycode, int mask, int bind_type, int force_unbi return 0; } -void in_unbind_all(int dev_id, int act_mask, int bind_type) +/* + * Unbind act_mask on binds with type bind_type + * - if dev_id_ < 0, affects all devices + * else only affects dev_id_ + * - if act_mask == -1, unbind all keys + * else only actions in mask + */ +void in_unbind_all(int dev_id_, int act_mask, int bind_type) { + int dev_id = 0, dev_last = IN_MAX_DEVS - 1; int i, count; in_dev_t *dev; - if (dev_id < 0 || dev_id >= IN_MAX_DEVS || bind_type >= IN_BINDTYPE_COUNT) + if (dev_id_ >= 0) + dev_id = dev_last = dev_id_; + + if (bind_type >= IN_BINDTYPE_COUNT) return; - dev = &in_devices[dev_id]; - count = dev->key_count; + for (; dev_id <= dev_last; dev_id++) { + dev = &in_devices[dev_id]; + count = dev->key_count; - if (dev->binds == NULL) - return; + if (dev->binds == NULL) + continue; - for (i = 0; i < count; i++) - dev->binds[IN_BIND_OFFS(i, bind_type)] &= ~act_mask; + if (act_mask != -1) { + for (i = 0; i < count; i++) + dev->binds[IN_BIND_OFFS(i, bind_type)] &= ~act_mask; + } + else + memset(dev->binds, 0, sizeof(dev->binds[0]) * count * IN_BINDTYPE_COUNT); + } } /* returns device id, or -1 on error */ diff --git a/frontend/common/menu.c b/frontend/common/menu.c index aa76e431..31522f7e 100644 --- a/frontend/common/menu.c +++ b/frontend/common/menu.c @@ -1039,18 +1039,11 @@ static int menu_loop_savestate(int is_loading) static char *action_binds(int player_idx, int action_mask, int dev_id) { - int k, count = 0, can_combo = 0, type; - const int *binds; + int dev = 0, dev_last = IN_MAX_DEVS - 1; + int can_combo = 1, type; static_buff[0] = 0; - binds = in_get_dev_binds(dev_id); - if (binds == NULL) - return static_buff; - - in_get_config(dev_id, IN_CFG_BIND_COUNT, &count); - in_get_config(dev_id, IN_CFG_DOES_COMBOS, &can_combo); - type = IN_BINDTYPE_EMU; if (player_idx >= 0) { can_combo = 0; @@ -1059,22 +1052,37 @@ static char *action_binds(int player_idx, int action_mask, int dev_id) if (player_idx == 1) action_mask <<= 16; - for (k = 0; k < count; k++) - { - const char *xname; - int len; + if (dev_id >= 0) + dev = dev_last = dev_id; + + for (; dev <= dev_last; dev++) { + int k, count = 0, combo = 0; + const int *binds; - if (!(binds[IN_BIND_OFFS(k, type)] & action_mask)) + binds = in_get_dev_binds(dev); + if (binds == NULL) continue; - xname = in_get_key_name(dev_id, k); - len = strlen(static_buff); - if (len) { - strncat(static_buff, can_combo ? " + " : ", ", - sizeof(static_buff) - len - 1); - len += can_combo ? 3 : 2; + in_get_config(dev, IN_CFG_BIND_COUNT, &count); + in_get_config(dev, IN_CFG_DOES_COMBOS, &combo); + combo = combo && can_combo; + + for (k = 0; k < count; k++) { + const char *xname; + int len; + + if (!(binds[IN_BIND_OFFS(k, type)] & action_mask)) + continue; + + xname = in_get_key_name(dev, k); + len = strlen(static_buff); + if (len) { + strncat(static_buff, combo ? " + " : ", ", + sizeof(static_buff) - len - 1); + len += combo ? 3 : 2; + } + strncat(static_buff, xname, sizeof(static_buff) - len - 1); } - strncat(static_buff, xname, sizeof(static_buff) - len - 1); } return static_buff; @@ -1126,7 +1134,10 @@ static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_ text_out16(x, y, "%s : %s", opts[i].name, action_binds(player_idx, opts[i].mask, dev_id)); - dev_name = in_get_dev_name(dev_id, 1, 1); + if (dev_id < 0) + dev_name = "(all devices)"; + else + dev_name = in_get_dev_name(dev_id, 1, 1); w = strlen(dev_name) * me_mfont_w; if (w < 30 * me_mfont_w) w = 30 * me_mfont_w; @@ -1155,7 +1166,7 @@ static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_idx) { int i, sel = 0, menu_sel_max = opt_cnt - 1, does_combos = 0; - int dev_id, dev_count, kc, is_down, mkey; + int dev_id, bind_dev_id, dev_count, kc, is_down, mkey; int unbind, bindtype, mask_shift; for (i = 0, dev_id = -1, dev_count = 0; i < IN_MAX_DEVS; i++) { @@ -1171,6 +1182,7 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ return; } + dev_id = -1; // show all mask_shift = 0; if (player_idx == 1) mask_shift = 16; @@ -1184,18 +1196,18 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ case PBTN_UP: sel--; if (sel < 0) sel = menu_sel_max; continue; case PBTN_DOWN: sel++; if (sel > menu_sel_max) sel = 0; continue; case PBTN_LEFT: - for (i = 0, dev_id--; i < IN_MAX_DEVS; i++, dev_id--) { - if (dev_id < 0) + for (i = 0, dev_id--; i < IN_MAX_DEVS + 1; i++, dev_id--) { + if (dev_id < -1) dev_id = IN_MAX_DEVS - 1; - if (in_get_dev_name(dev_id, 1, 0) != NULL) + if (dev_id == -1 || in_get_dev_name(dev_id, 1, 0) != NULL) break; } continue; case PBTN_RIGHT: for (i = 0, dev_id++; i < IN_MAX_DEVS; i++, dev_id++) { if (dev_id >= IN_MAX_DEVS) - dev_id = 0; - if (in_get_dev_name(dev_id, 1, 0) != NULL) + dev_id = -1; + if (dev_id == -1 || in_get_dev_name(dev_id, 1, 0) != NULL) break; } continue; @@ -1217,20 +1229,20 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ /* wait for some up event */ for (is_down = 1; is_down; ) - kc = in_update_keycode(&dev_id, &is_down, -1); + kc = in_update_keycode(&bind_dev_id, &is_down, -1); - i = count_bound_keys(dev_id, opts[sel].mask << mask_shift, bindtype); + i = count_bound_keys(bind_dev_id, opts[sel].mask << mask_shift, bindtype); unbind = (i > 0); /* allow combos if device supports them */ - in_get_config(dev_id, IN_CFG_DOES_COMBOS, &does_combos); + in_get_config(bind_dev_id, IN_CFG_DOES_COMBOS, &does_combos); if (i == 1 && bindtype == IN_BINDTYPE_EMU && does_combos) unbind = 0; if (unbind) - in_unbind_all(dev_id, opts[sel].mask << mask_shift, bindtype); + in_unbind_all(bind_dev_id, opts[sel].mask << mask_shift, bindtype); - in_bind_key(dev_id, kc, opts[sel].mask << mask_shift, bindtype, 0); + in_bind_key(bind_dev_id, kc, opts[sel].mask << mask_shift, bindtype, 0); } } diff --git a/frontend/menu.c b/frontend/menu.c index 0a4c271e..e7d20ffe 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -251,6 +251,8 @@ static void make_cfg_fname(char *buf, size_t size, int is_game) snprintf(buf, size, "." PCSX_DOT_DIR "%s", cfgfile_basename); } +static void keys_write_all(FILE *f); + static int menu_write_config(int is_game) { char cfgfile[MAXPATHLEN]; @@ -289,7 +291,9 @@ static int menu_write_config(int is_game) if (!is_game) fprintf(f, "lastcdimg = %s\n", last_selected_fname); + keys_write_all(f); fclose(f); + return 0; } @@ -305,6 +309,8 @@ static void parse_str_val(char *cval, const char *src) *tmp = 0; } +static void keys_load_all(const char *cfg); + static int menu_load_config(int is_game) { char cfgfile[MAXPATHLEN]; @@ -400,6 +406,7 @@ static int menu_load_config(int is_game) if (strcmp(Config.Spu, spu_plugins[i]) == 0) { spu_plugsel = i; break; } + keys_load_all(cfg); ret = 0; fail_read: free(cfg); @@ -647,6 +654,8 @@ me_bind_action me_ctrl_actions[] = { "R1 ", 1 << DKEY_R1 }, { "L2 ", 1 << DKEY_L2 }, { "R2 ", 1 << DKEY_R2 }, + { "L3 ", 1 << DKEY_L3 }, + { "R3 ", 1 << DKEY_R3 }, { "START ", 1 << DKEY_START }, { "SELECT ", 1 << DKEY_SELECT }, { NULL, 0 } @@ -664,6 +673,177 @@ me_bind_action emuctrl_actions[] = { NULL, 0 } }; +static char *mystrip(char *str) +{ + int i, len; + + len = strlen(str); + for (i = 0; i < len; i++) + if (str[i] != ' ') break; + if (i > 0) memmove(str, str + i, len - i + 1); + + len = strlen(str); + for (i = len - 1; i >= 0; i--) + if (str[i] != ' ') break; + str[i+1] = 0; + + return str; +} + +static void get_line(char *d, size_t size, const char *s) +{ + const char *pe; + size_t len; + + for (pe = s; *pe != '\r' && *pe != '\n' && *pe != 0; pe++) + ; + len = pe - s; + if (len > size - 1) + len = size - 1; + strncpy(d, s, len); + d[len] = 0; + + mystrip(d); +} + +static void keys_write_all(FILE *f) +{ + int d; + + for (d = 0; d < IN_MAX_DEVS; d++) + { + const int *binds = in_get_dev_binds(d); + const char *name = in_get_dev_name(d, 0, 0); + int k, count = 0; + + if (binds == NULL || name == NULL) + continue; + + fprintf(f, "binddev = %s\n", name); + in_get_config(d, IN_CFG_BIND_COUNT, &count); + + for (k = 0; k < count; k++) + { + int i, kbinds, mask; + char act[32]; + + act[0] = act[31] = 0; + name = in_get_key_name(d, k); + + kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER12)]; + for (i = 0; kbinds && i < ARRAY_SIZE(me_ctrl_actions) - 1; i++) { + mask = me_ctrl_actions[i].mask; + if (mask & kbinds) { + strncpy(act, me_ctrl_actions[i].name, 31); + fprintf(f, "bind %s = player1 %s\n", name, mystrip(act)); + kbinds &= ~mask; + } + mask = me_ctrl_actions[i].mask << 16; + if (mask & kbinds) { + strncpy(act, me_ctrl_actions[i].name, 31); + fprintf(f, "bind %s = player2 %s\n", name, mystrip(act)); + kbinds &= ~mask; + } + } + + kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_EMU)]; + for (i = 0; kbinds && i < ARRAY_SIZE(emuctrl_actions) - 1; i++) { + mask = emuctrl_actions[i].mask; + if (mask & kbinds) { + strncpy(act, emuctrl_actions[i].name, 31); + fprintf(f, "bind %s = %s\n", name, mystrip(act)); + kbinds &= ~mask; + } + } + } + } +} + +static int parse_bind_val(const char *val, int *type) +{ + int i; + + *type = IN_BINDTYPE_NONE; + if (val[0] == 0) + return 0; + + if (strncasecmp(val, "player", 6) == 0) + { + int player, shift = 0; + player = atoi(val + 6) - 1; + + if ((unsigned int)player > 1) + return -1; + if (player == 1) + shift = 16; + + *type = IN_BINDTYPE_PLAYER12; + for (i = 0; me_ctrl_actions[i].name != NULL; i++) { + if (strncasecmp(me_ctrl_actions[i].name, val + 8, strlen(val + 8)) == 0) + return me_ctrl_actions[i].mask << shift; + } + } + for (i = 0; emuctrl_actions[i].name != NULL; i++) { + if (strncasecmp(emuctrl_actions[i].name, val, strlen(val)) == 0) { + *type = IN_BINDTYPE_EMU; + return emuctrl_actions[i].mask; + } + } + + return -1; +} + +static void keys_load_all(const char *cfg) +{ + char dev[256], key[128], *act; + const char *p; + int bind, bindtype; + int dev_id; + + p = cfg; + while (p != NULL && (p = strstr(p, "binddev = ")) != NULL) { + p += 10; + + get_line(dev, sizeof(dev), p); + dev_id = in_config_parse_dev(dev); + if (dev_id < 0) { + printf("input: can't handle dev: %s\n", dev); + continue; + } + + in_unbind_all(dev_id, -1, -1); + while ((p = strstr(p, "bind"))) { + if (strncmp(p, "binddev = ", 10) == 0) + break; + + p += 4; + if (*p != ' ') { + printf("input: parse error: %16s..\n", p); + continue; + } + + get_line(key, sizeof(key), p); + act = strchr(key, '='); + if (act == NULL) { + printf("parse failed: %16s..\n", p); + continue; + } + *act = 0; + act++; + mystrip(key); + mystrip(act); + + bind = parse_bind_val(act, &bindtype); + if (bind != -1 && bind != 0) { + printf("bind #%d '%s' %08x (%s)\n", dev_id, key, bind, act); + in_config_bind_key(dev_id, key, bind, bindtype); + } + else + lprintf("config: unhandled action \"%s\"\n", act); + } + } +} + static int key_config_loop_wrap(int id, int keys) { switch (id) { diff --git a/frontend/pandora.c b/frontend/pandora.c index 8eacabb6..cd50728e 100644 --- a/frontend/pandora.c +++ b/frontend/pandora.c @@ -27,12 +27,12 @@ static const char * const pandora_gpio_keys[KEY_MAX + 1] = { [KEY_LEFT] = "Left", [KEY_RIGHT] = "Right", [KEY_DOWN] = "Down", - [KEY_HOME] = "A", - [KEY_PAGEDOWN] = "X", - [KEY_END] = "B", - [KEY_PAGEUP] = "Y", - [KEY_RIGHTSHIFT]= "L", - [KEY_RIGHTCTRL] = "R", + [KEY_HOME] = "(A)", + [KEY_PAGEDOWN] = "(X)", + [KEY_END] = "(B)", + [KEY_PAGEUP] = "(Y)", + [KEY_RIGHTSHIFT]= "(L)", + [KEY_RIGHTCTRL] = "(R)", [KEY_LEFTALT] = "Start", [KEY_LEFTCTRL] = "Select", [KEY_MENU] = "Pandora", -- 2.39.2