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 */
\r
static char *action_binds(int player_idx, int action_mask, int dev_id)\r
{\r
- int k, count = 0, can_combo = 0, type;\r
- const int *binds;\r
+ int dev = 0, dev_last = IN_MAX_DEVS - 1;\r
+ int can_combo = 1, type;\r
\r
static_buff[0] = 0;\r
\r
- binds = in_get_dev_binds(dev_id);\r
- if (binds == NULL)\r
- return static_buff;\r
-\r
- in_get_config(dev_id, IN_CFG_BIND_COUNT, &count);\r
- in_get_config(dev_id, IN_CFG_DOES_COMBOS, &can_combo);\r
-\r
type = IN_BINDTYPE_EMU;\r
if (player_idx >= 0) {\r
can_combo = 0;\r
if (player_idx == 1)\r
action_mask <<= 16;\r
\r
- for (k = 0; k < count; k++)\r
- {\r
- const char *xname;\r
- int len;\r
+ if (dev_id >= 0)\r
+ dev = dev_last = dev_id;\r
+\r
+ for (; dev <= dev_last; dev++) {\r
+ int k, count = 0, combo = 0;\r
+ const int *binds;\r
\r
- if (!(binds[IN_BIND_OFFS(k, type)] & action_mask))\r
+ binds = in_get_dev_binds(dev);\r
+ if (binds == NULL)\r
continue;\r
\r
- xname = in_get_key_name(dev_id, k);\r
- len = strlen(static_buff);\r
- if (len) {\r
- strncat(static_buff, can_combo ? " + " : ", ",\r
- sizeof(static_buff) - len - 1);\r
- len += can_combo ? 3 : 2;\r
+ in_get_config(dev, IN_CFG_BIND_COUNT, &count);\r
+ in_get_config(dev, IN_CFG_DOES_COMBOS, &combo);\r
+ combo = combo && can_combo;\r
+\r
+ for (k = 0; k < count; k++) {\r
+ const char *xname;\r
+ int len;\r
+\r
+ if (!(binds[IN_BIND_OFFS(k, type)] & action_mask))\r
+ continue;\r
+\r
+ xname = in_get_key_name(dev, k);\r
+ len = strlen(static_buff);\r
+ if (len) {\r
+ strncat(static_buff, combo ? " + " : ", ",\r
+ sizeof(static_buff) - len - 1);\r
+ len += combo ? 3 : 2;\r
+ }\r
+ strncat(static_buff, xname, sizeof(static_buff) - len - 1);\r
}\r
- strncat(static_buff, xname, sizeof(static_buff) - len - 1);\r
}\r
\r
return static_buff;\r
text_out16(x, y, "%s : %s", opts[i].name,\r
action_binds(player_idx, opts[i].mask, dev_id));\r
\r
- dev_name = in_get_dev_name(dev_id, 1, 1);\r
+ if (dev_id < 0)\r
+ dev_name = "(all devices)";\r
+ else\r
+ dev_name = in_get_dev_name(dev_id, 1, 1);\r
w = strlen(dev_name) * me_mfont_w;\r
if (w < 30 * me_mfont_w)\r
w = 30 * me_mfont_w;\r
static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_idx)\r
{\r
int i, sel = 0, menu_sel_max = opt_cnt - 1, does_combos = 0;\r
- int dev_id, dev_count, kc, is_down, mkey;\r
+ int dev_id, bind_dev_id, dev_count, kc, is_down, mkey;\r
int unbind, bindtype, mask_shift;\r
\r
for (i = 0, dev_id = -1, dev_count = 0; i < IN_MAX_DEVS; i++) {\r
return;\r
}\r
\r
+ dev_id = -1; // show all\r
mask_shift = 0;\r
if (player_idx == 1)\r
mask_shift = 16;\r
case PBTN_UP: sel--; if (sel < 0) sel = menu_sel_max; continue;\r
case PBTN_DOWN: sel++; if (sel > menu_sel_max) sel = 0; continue;\r
case PBTN_LEFT:\r
- for (i = 0, dev_id--; i < IN_MAX_DEVS; i++, dev_id--) {\r
- if (dev_id < 0)\r
+ for (i = 0, dev_id--; i < IN_MAX_DEVS + 1; i++, dev_id--) {\r
+ if (dev_id < -1)\r
dev_id = IN_MAX_DEVS - 1;\r
- if (in_get_dev_name(dev_id, 1, 0) != NULL)\r
+ if (dev_id == -1 || in_get_dev_name(dev_id, 1, 0) != NULL)\r
break;\r
}\r
continue;\r
case PBTN_RIGHT:\r
for (i = 0, dev_id++; i < IN_MAX_DEVS; i++, dev_id++) {\r
if (dev_id >= IN_MAX_DEVS)\r
- dev_id = 0;\r
- if (in_get_dev_name(dev_id, 1, 0) != NULL)\r
+ dev_id = -1;\r
+ if (dev_id == -1 || in_get_dev_name(dev_id, 1, 0) != NULL)\r
break;\r
}\r
continue;\r
\r
/* wait for some up event */\r
for (is_down = 1; is_down; )\r
- kc = in_update_keycode(&dev_id, &is_down, -1);\r
+ kc = in_update_keycode(&bind_dev_id, &is_down, -1);\r
\r
- i = count_bound_keys(dev_id, opts[sel].mask << mask_shift, bindtype);\r
+ i = count_bound_keys(bind_dev_id, opts[sel].mask << mask_shift, bindtype);\r
unbind = (i > 0);\r
\r
/* allow combos if device supports them */\r
- in_get_config(dev_id, IN_CFG_DOES_COMBOS, &does_combos);\r
+ in_get_config(bind_dev_id, IN_CFG_DOES_COMBOS, &does_combos);\r
if (i == 1 && bindtype == IN_BINDTYPE_EMU && does_combos)\r
unbind = 0;\r
\r
if (unbind)\r
- in_unbind_all(dev_id, opts[sel].mask << mask_shift, bindtype);\r
+ in_unbind_all(bind_dev_id, opts[sel].mask << mask_shift, bindtype);\r
\r
- in_bind_key(dev_id, kc, opts[sel].mask << mask_shift, bindtype, 0);\r
+ in_bind_key(bind_dev_id, kc, opts[sel].mask << mask_shift, bindtype, 0);\r
}\r
}\r
\r
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];
if (!is_game)
fprintf(f, "lastcdimg = %s\n", last_selected_fname);
+ keys_write_all(f);
fclose(f);
+
return 0;
}
*tmp = 0;
}
+static void keys_load_all(const char *cfg);
+
static int menu_load_config(int is_game)
{
char cfgfile[MAXPATHLEN];
if (strcmp(Config.Spu, spu_plugins[i]) == 0)
{ spu_plugsel = i; break; }
+ keys_load_all(cfg);
ret = 0;
fail_read:
free(cfg);
{ "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 }
{ 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) {
[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",