Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a button to quickly swap between Memory<->Rumble Paks #509

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
134 changes: 131 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 the Memory Pak and the 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)
{
int 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,18 @@ 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 startup is true then ROM infos aren't ready yet and we don't know
// the region of the game yet, so we just keep the seconds for now
// and we'll calculate in frames a bit later in retro_load_game()
swap_pak_delay = atoi(var.value);
if (!startup)
swap_pak_delay *= retro_get_region() == RETRO_REGION_PAL ? 50 : 60;
}

update_controllers();

// Hide irrelevant options
Expand Down Expand Up @@ -1931,6 +2055,10 @@ bool retro_load_game(const struct retro_game_info *game)
if(current_rdp_type == RDP_PLUGIN_GLIDEN64 || current_rdp_type == RDP_PLUGIN_PARALLEL)
{
first_context_reset = true;

// Now that we know the region, we can calculate the seconds in frames
// for the 'Memory/Rumble Pak Swap' button hold delay
swap_pak_delay *= retro_get_region() == RETRO_REGION_PAL ? 50 : 60;
}
else
{
Expand Down Expand Up @@ -1985,10 +2113,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 +2164,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 Hold Delay",
NULL,
"Select how long you have to hold the 'Memory/Rumble Pak Swap' button to perform the swap between the Memory Pak and the Rumble Pak. NOTE: only works if the player's Pak is set to 'memory/rumble (swappable)'",
NULL,
"input",
{
{"0", "0 second"},
{"1", "1 second"},
{"2", "2 seconds"},
{"3", "3 seconds"},
{ NULL, NULL },
},
"0"
},
{ NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL },
};

Expand Down