aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornotaz2011-02-07 00:49:40 +0200
committernotaz2011-02-10 02:07:54 +0200
commit43bca6fbee5f6b26ee02e8850bf7dace8d63336b (patch)
tree15cc9a17cf6b3b4df8a552f006ea38ecb524fecb
parent54b4a001cf0b0f165a59b727c4b201226eda014c (diff)
downloadpcsx_rearmed-43bca6fbee5f6b26ee02e8850bf7dace8d63336b.tar.gz
pcsx_rearmed-43bca6fbee5f6b26ee02e8850bf7dace8d63336b.tar.bz2
pcsx_rearmed-43bca6fbee5f6b26ee02e8850bf7dace8d63336b.zip
frontend: key config: save it and make more intuitive
-rw-r--r--frontend/common/input.c33
-rw-r--r--frontend/common/menu.c78
-rw-r--r--frontend/menu.c180
-rw-r--r--frontend/pandora.c12
4 files changed, 256 insertions, 47 deletions
diff --git a/frontend/common/input.c b/frontend/common/input.c
index 7bbb39c..5250535 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 aa76e43..31522f7 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 0a4c271..e7d20ff 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 8eacabb..cd50728 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",