Skip to content

Commit

Permalink
Add a button to quickly swap between Memory<->Rumble Paks
Browse files Browse the repository at this point in the history
  • Loading branch information
bslenul committed Dec 14, 2023
1 parent f1ad37c commit 7917e39
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ static void inputGetKeys_default_descriptor(void)
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "C-Up" },\
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Z Trigger" },\
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R Shoulder" },\
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "Memory/Rumble Pak Swap" },\
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "L Shoulder" },\
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },\
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },\
Expand Down Expand Up @@ -117,6 +118,7 @@ static void inputGetKeys_default_descriptor(void)
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Z Trigger" },\
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R Shoulder" },\
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L Shoulder" },\
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Memory/Rumble Pak Swap" },\
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },\
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },\
{ PAD, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },\
Expand Down
132 changes: 129 additions & 3 deletions libretro/libretro.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ int d_cbutton;
int u_cbutton;
bool alternate_mapping;

static bool swap_pak_enabled[4] = {false};
static int swap_pak_hold[4] = {0};
static int swap_pak_delay = 0;

static uint8_t* game_data = NULL;
static uint32_t game_size = 0;

Expand Down Expand Up @@ -764,6 +768,25 @@ void update_controllers()
else if (!strcmp(pk1var.value, "transfer"))
p1_pak = PLUGIN_TRANSFER_PAK;

// This is for the 'Memory/Rumble Pak Swap' button that lets you swap
// between Memory and Rumble Pak on-the-fly.
// Initialize to Memory Pak, then it's handled by pak_swapping().
// As long as swap_pak_enabled is true we just keep the current value
// from controller[port].control->Plugin, or else the Pak would be
// reinitialized to Memory Pak every time core options are refreshed.
if (!strcmp(pk1var.value, "memory/rumble (swappable)"))
{
if (swap_pak_enabled[0])
p1_pak = controller[0].control->Plugin;
else
{
swap_pak_enabled[0] = true;
p1_pak = PLUGIN_MEMPAK;
}
}
else
swap_pak_enabled[0] = false;

// If controller struct is not initialised yet, set pad_pak_types instead
// which will be looked at when initialising the controllers.
if (controller[0].control)
Expand All @@ -783,6 +806,19 @@ void update_controllers()
else if (!strcmp(pk2var.value, "transfer"))
p2_pak = PLUGIN_TRANSFER_PAK;

if (!strcmp(pk2var.value, "memory/rumble (swappable)"))
{
if (swap_pak_enabled[1])
p2_pak = controller[1].control->Plugin;
else
{
swap_pak_enabled[1] = true;
p2_pak = PLUGIN_MEMPAK;
}
}
else
swap_pak_enabled[1] = false;

if (controller[1].control)
controller[1].control->Plugin = p2_pak;
else
Expand All @@ -800,6 +836,19 @@ void update_controllers()
else if (!strcmp(pk3var.value, "transfer"))
p3_pak = PLUGIN_TRANSFER_PAK;

if (!strcmp(pk3var.value, "memory/rumble (swappable)"))
{
if (swap_pak_enabled[2])
p3_pak = controller[2].control->Plugin;
else
{
swap_pak_enabled[2] = true;
p3_pak = PLUGIN_MEMPAK;
}
}
else
swap_pak_enabled[2] = false;

if (controller[2].control)
controller[2].control->Plugin = p3_pak;
else
Expand All @@ -817,13 +866,76 @@ void update_controllers()
else if (!strcmp(pk4var.value, "transfer"))
p4_pak = PLUGIN_TRANSFER_PAK;

if (!strcmp(pk4var.value, "memory/rumble (swappable)"))
{
if (swap_pak_enabled[3])
p4_pak = controller[3].control->Plugin;
else
{
swap_pak_enabled[3] = true;
p4_pak = PLUGIN_MEMPAK;
}
}
else
swap_pak_enabled[3] = false;

if (controller[3].control)
controller[3].control->Plugin = p4_pak;
else
pad_pak_types[3] = p4_pak;
}
}

static void pak_swapping(void)
{
unsigned port;

for (port = 0; port < 4; port++)
{
if (swap_pak_enabled[port] && controller[port].control->Present)
{
bool pressed;

if (alternate_mapping)
pressed = input_cb(port, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3);
else
pressed = input_cb(port, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT);

if (pressed)
{
if (swap_pak_hold[port] >= swap_pak_delay)
{
struct retro_message msg;
char swap_msg[64];
const char *pak_name;

swap_pak_hold[port] = -1;

if (controller[port].control->Plugin == PLUGIN_MEMPAK)
{
controller[port].control->Plugin = PLUGIN_RAW;
pak_name = "Rumble";
}
else
{
controller[port].control->Plugin = PLUGIN_MEMPAK;
pak_name = "Memory";
}

snprintf(swap_msg, sizeof(swap_msg), "Player %d Controller Pak: %s Pak", port + 1, pak_name);
msg.msg = swap_msg;
msg.frames = 120;
environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg);
}
else if (swap_pak_hold[port] != -1)
swap_pak_hold[port]++;
}
else
swap_pak_hold[port] = 0;
}
}
}

static void update_variables(bool startup)
{
struct retro_variable var;
Expand Down Expand Up @@ -1731,6 +1843,20 @@ static void update_variables(bool startup)
}
#endif // HAVE_THR_AL

var.key = CORE_NAME "-pak-swap-delay";
var.value = NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
if (!strcmp(var.value, "no delay"))
swap_pak_delay = 0;
else if (!strcmp(var.value, "1s hold"))
swap_pak_delay = 60;
else if (!strcmp(var.value, "2s hold"))
swap_pak_delay = 120;
else if (!strcmp(var.value, "3s hold"))
swap_pak_delay = 180;
}

update_controllers();

// Hide irrelevant options
Expand Down Expand Up @@ -1985,10 +2111,8 @@ void retro_run (void)
libretro_swap_buffer = false;
static bool updated = false;

if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) {
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
update_variables(false);
update_controllers();
}

if(current_rdp_type == RDP_PLUGIN_GLIDEN64)
{
Expand Down Expand Up @@ -2038,6 +2162,8 @@ void retro_run (void)
// screen_pitch will be 0 for GLN
video_cb(NULL, retro_screen_width, retro_screen_height, screen_pitch);
}

pak_swapping();
}

void retro_reset (void)
Expand Down
20 changes: 20 additions & 0 deletions libretro/libretro_core_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -1656,6 +1656,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
{"memory", NULL},
{"rumble", NULL},
{"transfer", NULL},
{"memory/rumble (swappable)", NULL},
{ NULL, NULL },
},
"memory"
Expand All @@ -1672,6 +1673,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
{"memory", NULL},
{"rumble", NULL},
{"transfer", NULL},
{"memory/rumble (swappable)", NULL},
{ NULL, NULL },
},
"none"
Expand All @@ -1688,6 +1690,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
{"memory", NULL},
{"rumble", NULL},
{"transfer", NULL},
{"memory/rumble (swappable)", NULL},
{ NULL, NULL },
},
"none"
Expand All @@ -1704,10 +1707,27 @@ struct retro_core_option_v2_definition option_defs_us[] = {
{"memory", NULL},
{"rumble", NULL},
{"transfer", NULL},
{"memory/rumble (swappable)", NULL},
{ NULL, NULL },
},
"none"
},
{
CORE_NAME "-pak-swap-delay",
"Memory/Rumble Pak Swap Activation Delay",
NULL,
"Select if the 'Memory/Rumble Pak Swap' button should perform the swap on press or on hold. NOTE: only works if the player's Pak is set to 'memory/rumble (swappable)'",
NULL,
"input",
{
{"no delay", "Press to swap"},
{"1s hold", "Hold 1 second to swap"},
{"2s hold", "Hold 2 seconds to swap"},
{"3s hold", "Hold 3 seconds to swap"},
{ NULL, NULL },
},
"no delay"
},
{ NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL },
};

Expand Down

0 comments on commit 7917e39

Please sign in to comment.