core, linux+libretro, multiplayer adaptor support

This commit is contained in:
kub 2022-01-26 19:34:13 +00:00
parent a833e78c98
commit 1d5885dd84
9 changed files with 104 additions and 49 deletions

View file

@ -262,43 +262,29 @@ static u32 read_pad_team(int i, u32 out_bits)
int phase = Pico.m.padTHPhase[i];
u32 value;
if (phase == 0) {
switch (phase) {
case 0:
value = 0x03;
goto out;
}
if (phase == 1) {
break;
case 1:
value = 0x0f;
goto out;
}
pad = ~PicoIn.padInt[0]; // Get inverse of pad MXYZ SACB RLDU
if (phase == 8) {
break;
case 4: case 5: case 6: case 7: // controller IDs, all 3 btn for now
value = 0x00;
break;
case 8: case 10: case 12: case 14:
pad = ~PicoIn.padInt[(phase-8) >> 1];
value = pad & 0x0f; // ?x?x RLDU
goto out;
}
else if(phase == 9) {
break;
case 9: case 11: case 13: case 15:
pad = ~PicoIn.padInt[(phase-8) >> 1];
value = (pad & 0xf0) >> 4; // ?x?x SACB
goto out;
break;
default:
value = 0;
break;
}
pad = ~PicoIn.padInt[1]; // Get inverse of pad MXYZ SACB RLDU
if (phase == 12) {
value = pad & 0x0f; // ?x?x RLDU
goto out;
}
else if(phase == 13) {
value = (pad & 0xf0) >> 4; // ?x?x SACB
goto out;
}
if (phase >= 8 && pad < 16) {
value = 0x0f;
goto out;
}
value = 0;
out:
value |= (out_bits & 0x40) | ((out_bits & 0x20)>>1);
return value;
}
@ -308,8 +294,8 @@ static u32 read_pad_4way(int i, u32 out_bits)
u32 pad = (PicoMem.ioports[2] & 0x70) >> 4;
u32 value = 0;
if (i == 0 && !(pad & 1))
value = read_pad_3btn(pad >> 1, out_bits);
if (i == 0 && pad <= 3)
value = read_pad_3btn(pad, out_bits);
value |= (out_bits & 0x40);
return value;
@ -357,7 +343,10 @@ void PicoSetInputDevice(int port, enum input_device device)
if (port < 0 || port > 2)
return;
switch (device) {
if (port == 1 && port_readers[0] == read_pad_team)
func = read_nothing;
else switch (device) {
case PICO_INPUT_PAD_3BTN:
func = read_pad_3btn;
break;
@ -409,7 +398,7 @@ NOINLINE void io_ports_write(u32 a, u32 d)
Pico.m.padTHPhase[a - 1] = 0;
else if ((d^PicoMem.ioports[a]) & 0x60)
Pico.m.padTHPhase[a - 1]++;
} else if (port_readers[a - 1] == read_pad_4way) {
} else if (port_readers[0] == read_pad_4way) {
if (a == 2 && ((PicoMem.ioports[a] ^ d) & 0x70))
Pico.m.padTHPhase[0] = 0;
if (a == 1 && !(PicoMem.ioports[a] & 0x40) && (d & 0x40))

View file

@ -95,8 +95,8 @@ typedef struct PicoInterface
{
unsigned int opt; // POPT_* bitfield
unsigned short pad[2]; // Joypads, format is MXYZ SACB RLDU
unsigned short padInt[2]; // internal copy
unsigned short pad[4]; // Joypads, format is MXYZ SACB RLDU
unsigned short padInt[4]; // internal copy
unsigned short AHW; // active addon hardware: PAHW_* bitfield
unsigned short skipFrame; // skip rendering frame, but still do sound (if enabled) and emulation stuff

View file

@ -85,6 +85,19 @@ static void keys_write(FILE *fn, int dev_id, const int *binds)
}
}
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)]) {
@ -371,12 +384,12 @@ static int parse_bind_val(const char *val, int *type)
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;

View file

@ -1180,21 +1180,29 @@ void emu_update_input(void)
{
static int prev_events = 0;
int actions[IN_BINDTYPE_COUNT] = { 0, };
int pl_actions[2];
int pl_actions[4];
int events;
in_update(actions);
pl_actions[0] = actions[IN_BINDTYPE_PLAYER12];
pl_actions[1] = actions[IN_BINDTYPE_PLAYER12] >> 16;
pl_actions[2] = actions[IN_BINDTYPE_PLAYER34];
pl_actions[3] = actions[IN_BINDTYPE_PLAYER34] >> 16;
PicoIn.pad[0] = pl_actions[0] & 0xfff;
PicoIn.pad[1] = pl_actions[1] & 0xfff;
PicoIn.pad[2] = pl_actions[2] & 0xfff;
PicoIn.pad[3] = pl_actions[3] & 0xfff;
if (pl_actions[0] & 0x7000)
do_turbo(&PicoIn.pad[0], pl_actions[0]);
if (pl_actions[1] & 0x7000)
do_turbo(&PicoIn.pad[1], pl_actions[1]);
if (pl_actions[2] & 0x7000)
do_turbo(&PicoIn.pad[2], pl_actions[2]);
if (pl_actions[3] & 0x7000)
do_turbo(&PicoIn.pad[3], pl_actions[3]);
events = actions[IN_BINDTYPE_EMU] & PEV_MASK;

View file

@ -366,6 +366,12 @@ static int key_config_loop_wrap(int id, int keys)
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;
@ -396,15 +402,18 @@ static const char *mgn_dev_name(int id, int *offs)
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),

View file

@ -93,6 +93,8 @@ typedef enum
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,

@ -1 +1 @@
Subproject commit d57c9992201e065f8caf6ce68247195ff98e8420
Subproject commit 25cfdf0a342a64a01710c1b6fbe3b1b04f28975e

View file

@ -1235,6 +1235,34 @@ bool retro_load_game(const struct retro_game_info *info)
{ 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 },
};
@ -1442,6 +1470,10 @@ static enum input_device input_name_to_val(const char *name)
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;
@ -1719,8 +1751,8 @@ void retro_run(void)
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++)

View file

@ -294,12 +294,14 @@ struct retro_core_option_v2_definition option_defs_us[] = {
"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 },
},
@ -309,7 +311,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
"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",
{