in cores/snes/controls.cpp [1242:1666]
s9xcommand_t S9xGetCommandT (const char *name)
{
s9xcommand_t cmd;
int i, j;
const char *s;
memset(&cmd, 0, sizeof(cmd));
cmd.type = S9xBadMapping;
cmd.multi_press = 0;
cmd.button_norpt = 0;
if (!strcmp(name, "None"))
cmd.type = S9xNoMapping;
else
if (!strncmp(name, "Joypad", 6))
{
if (name[6] < '1' || name[6] > '8' || name[7] != ' ')
return (cmd);
if (!strncmp(name + 8, "Axis ", 5))
{
cmd.axis.joypad.idx = name[6] - '1';
s = name + 13;
if (!strncmp(s, "Left/Right ", 11)) { j = 0; i = 0; s += 11; }
else
if (!strncmp(s, "Right/Left ", 11)) { j = 0; i = 1; s += 11; }
else
if (!strncmp(s, "Up/Down ", 8)) { j = 1; i = 0; s += 8; }
else
if (!strncmp(s, "Down/Up ", 8)) { j = 1; i = 1; s += 8; }
else
if (!strncmp(s, "Y/A ", 4)) { j = 2; i = 0; s += 4; }
else
if (!strncmp(s, "A/Y ", 4)) { j = 2; i = 1; s += 4; }
else
if (!strncmp(s, "X/B ", 4)) { j = 3; i = 0; s += 4; }
else
if (!strncmp(s, "B/X ", 4)) { j = 3; i = 1; s += 4; }
else
if (!strncmp(s, "L/R ", 4)) { j = 4; i = 0; s += 4; }
else
if (!strncmp(s, "R/L ", 4)) { j = 4; i = 1; s += 4; }
else
return (cmd);
cmd.axis.joypad.axis = j;
cmd.axis.joypad.invert = i;
i = get_threshold(&s);
if (i < 0)
return (cmd);
cmd.axis.joypad.threshold = (i - 1) * 256 / 1000;
cmd.type = S9xAxisJoypad;
}
else
{
cmd.button.joypad.idx = name[6] - '1';
s = name + 8;
i = 0;
if ((cmd.button.joypad.toggle = strncmp(s, "Toggle", 6) ? 0 : 1)) s += i = 6;
if ((cmd.button.joypad.sticky = strncmp(s, "Sticky", 6) ? 0 : 1)) s += i = 6;
if ((cmd.button.joypad.turbo = strncmp(s, "Turbo", 5) ? 0 : 1)) s += i = 5;
if (cmd.button.joypad.toggle && !(cmd.button.joypad.sticky || cmd.button.joypad.turbo))
return (cmd);
if (i)
{
if (*s != ' ')
return (cmd);
s++;
}
i = 0;
if (!strncmp(s, "Up", 2)) { i |= SNES_UP_MASK; s += 2; if (*s == '+') s++; }
if (!strncmp(s, "Down", 4)) { i |= SNES_DOWN_MASK; s += 4; if (*s == '+') s++; }
if (!strncmp(s, "Left", 4)) { i |= SNES_LEFT_MASK; s += 4; if (*s == '+') s++; }
if (!strncmp(s, "Right", 5)) { i |= SNES_RIGHT_MASK; s += 5; if (*s == '+') s++; }
if (*s == 'A') { i |= SNES_A_MASK; s++; if (*s == '+') s++; }
if (*s == 'B') { i |= SNES_B_MASK; s++; if (*s == '+') s++; }
if (*s == 'X') { i |= SNES_X_MASK; s++; if (*s == '+') s++; }
if (*s == 'Y') { i |= SNES_Y_MASK; s++; if (*s == '+') s++; }
if (*s == 'L') { i |= SNES_TL_MASK; s++; if (*s == '+') s++; }
if (*s == 'R') { i |= SNES_TR_MASK; s++; if (*s == '+') s++; }
if (!strncmp(s, "Start", 5)) { i |= SNES_START_MASK; s += 5; if (*s == '+') s++; }
if (!strncmp(s, "Select", 6)) { i |= SNES_SELECT_MASK; s += 6; }
if (i == 0 || *s != 0 || *(s - 1) == '+')
return (cmd);
cmd.button.joypad.buttons = i;
cmd.type = S9xButtonJoypad;
}
}
else
if (!strncmp(name, "Mouse", 5))
{
if (name[5] < '1' || name[5] > '2' || name[6] != ' ')
return (cmd);
cmd.button.mouse.idx = name[5] - '1';
s = name + 7;
i = 0;
if ((cmd.button.mouse.left = (*s == 'L'))) s += i = 1;
if ((cmd.button.mouse.right = (*s == 'R'))) s += i = 1;
if (i == 0 || *s != 0)
return (cmd);
cmd.type = S9xButtonMouse;
}
else
if (!strncmp(name, "Superscope ", 11))
{
s = name + 11;
i = 0;
if ((cmd.button.scope.aim_offscreen = strncmp(s, "AimOffscreen", 12) ? 0 : 1)) { s += i = 12; if (*s == ' ') s++; else if (*s != 0) return (cmd); }
if ((cmd.button.scope.fire = strncmp(s, "Fire", 4) ? 0 : 1)) { s += i = 4; if (*s == '+') s++; }
if ((cmd.button.scope.cursor = strncmp(s, "Cursor", 6) ? 0 : 1)) { s += i = 6; if (*s == '+') s++; }
if ((cmd.button.scope.turbo = strncmp(s, "ToggleTurbo", 11) ? 0 : 1)) { s += i = 11; if (*s == '+') s++; }
if ((cmd.button.scope.pause = strncmp(s, "Pause", 5) ? 0 : 1)) { s += i = 5; }
if (i == 0 || *s != 0 || *(s - 1) == '+')
return (cmd);
cmd.type = S9xButtonSuperscope;
}
else
if (!strncmp(name, "Justifier", 9))
{
if (name[9] < '1' || name[9] > '2' || name[10] != ' ')
return (cmd);
cmd.button.justifier.idx = name[9] - '1';
s = name + 11;
i = 0;
if ((cmd.button.justifier.aim_offscreen = strncmp(s, "AimOffscreen", 12) ? 0 : 1)) { s += i = 12; if (*s == ' ') s++; else if (*s != 0) return (cmd); }
if ((cmd.button.justifier.trigger = strncmp(s, "Trigger", 7) ? 0 : 1)) { s += i = 7; if (*s == '+') s++; }
if ((cmd.button.justifier.start = strncmp(s, "Start", 5) ? 0 : 1)) { s += i = 5; }
if (i == 0 || *s != 0 || *(s - 1) == '+')
return (cmd);
cmd.type = S9xButtonJustifier;
}
else
if (!strncmp(name, "Pointer ", 8))
{
s = name + 8;
i = 0;
if ((cmd.pointer.aim_mouse0 = strncmp(s, "Mouse1", 6) ? 0 : 1)) { s += i = 6; if (*s == '+') s++; }
if ((cmd.pointer.aim_mouse1 = strncmp(s, "Mouse2", 6) ? 0 : 1)) { s += i = 6; if (*s == '+') s++; }
if ((cmd.pointer.aim_scope = strncmp(s, "Superscope", 10) ? 0 : 1)) { s += i = 10; if (*s == '+') s++; }
if ((cmd.pointer.aim_justifier0 = strncmp(s, "Justifier1", 10) ? 0 : 1)) { s += i = 10; if (*s == '+') s++; }
if ((cmd.pointer.aim_justifier1 = strncmp(s, "Justifier2", 10) ? 0 : 1)) { s += i = 10; }
if (i == 0 || *s != 0 || *(s - 1) == '+')
return (cmd);
cmd.type = S9xPointer;
}
else
if (!strncmp(name, "ButtonToPointer ", 16))
{
if (name[16] < '1' || name[16] > '8')
return (cmd);
cmd.button.pointer.idx = name[16] - '1';
s = name + 17;
i = 0;
if ((cmd.button.pointer.UD = (*s == 'u' ? -1 : (*s == 'd' ? 1 : 0)))) s += i = 1;
if ((cmd.button.pointer.LR = (*s == 'l' ? -1 : (*s == 'r' ? 1 : 0)))) s += i = 1;
if (i == 0 || *(s++) != ' ')
return (cmd);
for (i = 0; i < 4; i++)
if (!strcmp(s, speed_names[i]))
break;
if (i > 3)
return (cmd);
cmd.button.pointer.speed_type = i;
cmd.type = S9xButtonPseudopointer;
}
else
if (!strncmp(name, "AxisToPointer ", 14))
{
if (name[14] < '1' || name[14] > '8')
return (cmd);
cmd.axis.pointer.idx = name[14] - '1';
s= name + 15;
i = 0;
if (*s == 'h')
cmd.axis.pointer.HV = 0;
else
if (*s == 'v')
cmd.axis.pointer.HV = 1;
else
return (cmd);
if (s[1] != ' ')
return (cmd);
s += 2;
if ((cmd.axis.pointer.invert = *s == '-'))
s++;
for (i = 0; i < 4; i++)
if (!strcmp(s, speed_names[i]))
break;
if (i > 3)
return (cmd);
cmd.axis.pointer.speed_type = i;
cmd.type = S9xAxisPseudopointer;
}
else
if (!strncmp(name, "AxisToButtons ", 14))
{
s = name + 14;
if (s[0] == '0')
{
if (s[1] != '/')
return (cmd);
cmd.axis.button.negbutton = 0;
s += 2;
}
else
{
i = 0;
do
{
if (*s < '0' || *s > '9')
return (cmd);
i = i * 10 + *s - '0';
if (i > 255)
return (cmd);
}
while (*++s != '/');
cmd.axis.button.negbutton = i;
s++;
}
if (s[0] == '0')
{
if (s[1] != ' ')
return (cmd);
cmd.axis.button.posbutton = 0;
s += 2;
}
else
{
i = 0;
do
{
if (*s < '0' || *s > '9')
return (cmd);
i = i * 10 + *s - '0';
if (i > 255)
return (cmd);
}
while (*++s != ' ');
cmd.axis.button.posbutton = i;
s++;
}
i = get_threshold(&s);
if (i < 0)
return (cmd);
cmd.axis.button.threshold = (i - 1) * 256 / 1000;
cmd.type = S9xAxisPseudobuttons;
}
else
if (!strncmp(name, "MULTI#", 6))
{
i = strtol(name + 6, (char **) &s, 10);
if (s != NULL && *s != '\0')
return (cmd);
if (i >= (int) multis.size())
return (cmd);
cmd.button.multi_idx = i;
cmd.type = S9xButtonMulti;
}
else
if (((name[0] == '+' && name[1] == '{') || name[0] == '{') && name[strlen(name) - 1] == '}')
{
if (multis.size() > 2147483640)
{
fprintf(stderr, "Too many multis!");
return (cmd);
}
string x;
int n;
j = 2;
for (i = (name[0] == '+') ? 2 : 1; name[i] != '\0'; i++)
{
if (name[i] == ',' || name[i] == ';')
{
if (name[i] == ';')
j++;
if (++j > 2147483640)
{
fprintf(stderr, "Multi too long!");
return (cmd);
}
}
if (name[i] == '{')
return (cmd);
}
s9xcommand_t *c = (s9xcommand_t *) calloc(j, sizeof(s9xcommand_t));
if (c == NULL)
{
perror("malloc error while parsing multi");
return (cmd);
}
n = 0;
i = (name[0] == '+') ? 2 : 1;
do
{
if (name[i] == ';')
{
c[n].type = S9xNoMapping;
c[n].multi_press = 0;
c[n].button_norpt = 0;
j = i;
}
else
if (name[i] == ',')
{
free(c);
return (cmd);
}
else
{
uint8 press = 0;
if (name[0] == '+')
{
if (name[i] == '+')
press = 1;
else
if (name[i] == '-')
press = 2;
else
{
free(c);
return (cmd);
}
i++;
}
for (j = i; name[j] != ';' && name[j] != ',' && name[j] != '}'; j++) ;
x.assign(name + i, j - i);
c[n] = S9xGetCommandT(x.c_str());
c[n].multi_press = press;
if (maptype(c[n].type) != MAP_BUTTON)
{
free(c);
return (cmd);
}
if (name[j] == ';')
j--;
}
i = j + 1;
n++;
}
while (name[i] != '\0');
c[n].type = S9xNoMapping;
c[n].multi_press = 3;
multis.push_back(c);
cmd.button.multi_idx = multis.size() - 1;
cmd.type = S9xButtonMulti;
}
else
{
i = findstr(name, command_names, LAST_COMMAND);
if (i < 0)
return (cmd);
cmd.type = S9xButtonCommand;
cmd.button.command = i;
}
return (cmd);
}