int phase = Pico.m.padTHPhase[i];\r
u32 value;\r
\r
- if (phase == 0) {\r
+ switch (phase) {\r
+ case 0:\r
value = 0x03;\r
- goto out;\r
- }\r
- if (phase == 1) {\r
+ break;\r
+ case 1:\r
value = 0x0f;\r
- goto out;\r
- }\r
-\r
- pad = ~PicoIn.padInt[0]; // Get inverse of pad MXYZ SACB RLDU\r
- if (phase == 8) {\r
- value = pad & 0x0f; // ?x?x RLDU\r
- goto out;\r
- }\r
- else if(phase == 9) {\r
- value = (pad & 0xf0) >> 4; // ?x?x SACB\r
- goto out;\r
- }\r
-\r
- pad = ~PicoIn.padInt[1]; // Get inverse of pad MXYZ SACB RLDU\r
- if (phase == 12) {\r
+ break;\r
+ case 4: case 5: case 6: case 7: // controller IDs, all 3 btn for now\r
+ value = 0x00;\r
+ break;\r
+ case 8: case 10: case 12: case 14:\r
+ pad = ~PicoIn.padInt[(phase-8) >> 1];\r
value = pad & 0x0f; // ?x?x RLDU\r
- goto out;\r
- }\r
- else if(phase == 13) {\r
+ break;\r
+ case 9: case 11: case 13: case 15:\r
+ pad = ~PicoIn.padInt[(phase-8) >> 1];\r
value = (pad & 0xf0) >> 4; // ?x?x SACB\r
- goto out;\r
- }\r
-\r
- if (phase >= 8 && pad < 16) {\r
- value = 0x0f;\r
- goto out;\r
+ break;\r
+ default:\r
+ value = 0;\r
+ break;\r
}\r
\r
- value = 0;\r
-\r
-out:\r
value |= (out_bits & 0x40) | ((out_bits & 0x20)>>1);\r
return value;\r
}\r
u32 pad = (PicoMem.ioports[2] & 0x70) >> 4;\r
u32 value = 0;\r
\r
- if (i == 0 && !(pad & 1))\r
- value = read_pad_3btn(pad >> 1, out_bits);\r
+ if (i == 0 && pad <= 3)\r
+ value = read_pad_3btn(pad, out_bits);\r
\r
value |= (out_bits & 0x40);\r
return value;\r
if (port < 0 || port > 2)\r
return;\r
\r
- switch (device) {\r
+ if (port == 1 && port_readers[0] == read_pad_team)\r
+ func = read_nothing;\r
+\r
+ else switch (device) {\r
case PICO_INPUT_PAD_3BTN:\r
func = read_pad_3btn;\r
break;\r
Pico.m.padTHPhase[a - 1] = 0;\r
else if ((d^PicoMem.ioports[a]) & 0x60)\r
Pico.m.padTHPhase[a - 1]++;\r
- } else if (port_readers[a - 1] == read_pad_4way) {\r
+ } else if (port_readers[0] == read_pad_4way) {\r
if (a == 2 && ((PicoMem.ioports[a] ^ d) & 0x70))\r
Pico.m.padTHPhase[0] = 0;\r
if (a == 1 && !(PicoMem.ioports[a] & 0x40) && (d & 0x40))\r
{\r
unsigned int opt; // POPT_* bitfield\r
\r
- unsigned short pad[2]; // Joypads, format is MXYZ SACB RLDU\r
- unsigned short padInt[2]; // internal copy\r
+ unsigned short pad[4]; // Joypads, format is MXYZ SACB RLDU\r
+ unsigned short padInt[4]; // internal copy\r
unsigned short AHW; // active addon hardware: PAHW_* bitfield\r
\r
unsigned short skipFrame; // skip rendering frame, but still do sound (if enabled) and emulation stuff\r
}
}
+ for (i = 0; me_ctrl_actions[i].name != NULL; i++) {
+ mask = me_ctrl_actions[i].mask;
+ if (mask & binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER34)]) {
+ strncpy(act, me_ctrl_actions[i].name, 31);
+ fprintf(fn, "bind %s = player3 %s" NL, name, mystrip(act));
+ }
+ mask = me_ctrl_actions[i].mask << 16;
+ if (mask & binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER34)]) {
+ strncpy(act, me_ctrl_actions[i].name, 31);
+ fprintf(fn, "bind %s = player4 %s" NL, name, mystrip(act));
+ }
+ }
+
for (i = 0; emuctrl_actions[i].name != NULL; i++) {
mask = emuctrl_actions[i].mask;
if (mask & binds[IN_BIND_OFFS(k, IN_BINDTYPE_EMU)]) {
int player, shift = 0;
player = atoi(val + 6) - 1;
- if (player > 1)
+ if (player > 3)
return -1;
- if (player == 1)
+ if (player & 1)
shift = 16;
- *type = IN_BINDTYPE_PLAYER12;
+ *type = IN_BINDTYPE_PLAYER12 + (player >> 1);
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;
{\r
static int prev_events = 0;\r
int actions[IN_BINDTYPE_COUNT] = { 0, };\r
- int pl_actions[2];\r
+ int pl_actions[4];\r
int events;\r
\r
in_update(actions);\r
\r
pl_actions[0] = actions[IN_BINDTYPE_PLAYER12];\r
pl_actions[1] = actions[IN_BINDTYPE_PLAYER12] >> 16;\r
+ pl_actions[2] = actions[IN_BINDTYPE_PLAYER34];\r
+ pl_actions[3] = actions[IN_BINDTYPE_PLAYER34] >> 16;\r
\r
PicoIn.pad[0] = pl_actions[0] & 0xfff;\r
PicoIn.pad[1] = pl_actions[1] & 0xfff;\r
+ PicoIn.pad[2] = pl_actions[2] & 0xfff;\r
+ PicoIn.pad[3] = pl_actions[3] & 0xfff;\r
\r
if (pl_actions[0] & 0x7000)\r
do_turbo(&PicoIn.pad[0], pl_actions[0]);\r
if (pl_actions[1] & 0x7000)\r
do_turbo(&PicoIn.pad[1], pl_actions[1]);\r
+ if (pl_actions[2] & 0x7000)\r
+ do_turbo(&PicoIn.pad[2], pl_actions[2]);\r
+ if (pl_actions[3] & 0x7000)\r
+ do_turbo(&PicoIn.pad[3], pl_actions[3]);\r
\r
events = actions[IN_BINDTYPE_EMU] & PEV_MASK;\r
\r
case MA_CTRL_PLAYER2:
key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 1);
break;
+ case MA_CTRL_PLAYER3:
+ key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 2);
+ break;
+ case MA_CTRL_PLAYER4:
+ key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 3);
+ break;
case MA_CTRL_EMU:
key_config_loop(emuctrl_actions, array_size(emuctrl_actions) - 1, -1);
break;
static int mh_saveloadcfg(int id, int keys);
static const char *mgn_saveloadcfg(int id, int *offs);
-const char *indev_names[] = { "none", "3 button pad", "6 button pad", NULL };
+const char *indev0_names[] = { "none", "3 button pad", "6 button pad", "Team player", "4 way play", NULL };
+const char *indev1_names[] = { "none", "3 button pad", "6 button pad", NULL };
static menu_entry e_menu_keyconfig[] =
{
mee_handler_id("Player 1", MA_CTRL_PLAYER1, key_config_loop_wrap),
mee_handler_id("Player 2", MA_CTRL_PLAYER2, key_config_loop_wrap),
+ mee_handler_id("Player 3", MA_CTRL_PLAYER3, key_config_loop_wrap),
+ mee_handler_id("Player 4", MA_CTRL_PLAYER4, key_config_loop_wrap),
mee_handler_id("Emulator controls", MA_CTRL_EMU, key_config_loop_wrap),
- mee_enum ("Input device 1", MA_OPT_INPUT_DEV0, currentConfig.input_dev0, indev_names),
- mee_enum ("Input device 2", MA_OPT_INPUT_DEV1, currentConfig.input_dev1, indev_names),
+ mee_enum ("Input device 1", MA_OPT_INPUT_DEV0, currentConfig.input_dev0, indev0_names),
+ mee_enum ("Input device 2", MA_OPT_INPUT_DEV1, currentConfig.input_dev1, indev1_names),
mee_range ("Turbo rate", MA_CTRL_TURBO_RATE, currentConfig.turbo_rate, 1, 30),
mee_range ("Analog deadzone", MA_CTRL_DEADZONE, currentConfig.analog_deadzone, 1, 99),
mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_saveloadcfg, mgn_saveloadcfg),
MA_SMSOPT_GHOSTING,
MA_CTRL_PLAYER1,
MA_CTRL_PLAYER2,
+ MA_CTRL_PLAYER3,
+ MA_CTRL_PLAYER4,
MA_CTRL_EMU,
MA_CTRL_TURBO_RATE,
MA_CTRL_DEADZONE,
-Subproject commit d57c9992201e065f8caf6ce68247195ff98e8420
+Subproject commit 25cfdf0a342a64a01710c1b6fbe3b1b04f28975e
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT,"Mode" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
+
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "C" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Y" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "A" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "X" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Z" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT,"Mode" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
+
+
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "C" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Y" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "A" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "X" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Z" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT,"Mode" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
+
{ 0 },
};
return PICO_INPUT_PAD_3BTN;
if (strcmp(name, "6 button pad") == 0)
return PICO_INPUT_PAD_6BTN;
+ if (strcmp(name, "team player") == 0)
+ return PICO_INPUT_PAD_TEAM;
+ if (strcmp(name, "4way play") == 0)
+ return PICO_INPUT_PAD_4WAY;
if (strcmp(name, "None") == 0)
return PICO_INPUT_NOTHING;
input_poll_cb();
- PicoIn.pad[0] = PicoIn.pad[1] = 0;
- for (pad = 0; pad < 2; pad++) {
+ PicoIn.pad[0] = PicoIn.pad[1] = PicoIn.pad[2] = PicoIn.pad[3] = 0;
+ for (pad = 0; pad < 4; pad++) {
if (libretro_supports_bitmasks) {
input = input_state_cb(pad, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
for (i = 0; i < RETRO_PICO_MAP_LEN; i++)
"picodrive_input1",
"Input Device 1",
NULL,
- "Choose which type of controller is plugged into slot 1.",
+ "Choose which type of controller is plugged into slot 1. Note that a multiplayer adaptor uses both slots.",
NULL,
"input",
{
{ "3 button pad", "3 Button Pad" },
{ "6 button pad", "6 Button Pad" },
+ { "team player", "Sega 4 Player Adaptor" },
+ { "4way play", "EA 4way Play Adaptor" },
{ "None", NULL },
{ NULL, NULL },
},
"picodrive_input2",
"Input Device 2",
NULL,
- "Choose which type of controller is plugged into slot 2.",
+ "Choose which type of controller is plugged into slot 2. This setting is ignored when a multiplayer adaptor is plugged into slot 1.",
NULL,
"input",
{