mirror of
https://github.com/libretro/RetroArch
synced 2025-03-03 04:14:00 +00:00
Savestate auto indexing support.
This commit is contained in:
parent
d01a4fe61b
commit
bcae973d82
@ -216,6 +216,10 @@ static const bool netplay_client_swap_input = true;
|
|||||||
// This could potentially lead to buggy games.
|
// This could potentially lead to buggy games.
|
||||||
static const bool block_sram_overwrite = false;
|
static const bool block_sram_overwrite = false;
|
||||||
|
|
||||||
|
// When saving savestates, state index is automatically incremented before saving.
|
||||||
|
// When the ROM is loaded, state index will be set to the highest existing value.
|
||||||
|
static const bool savestate_auto_index = false;
|
||||||
|
|
||||||
|
|
||||||
////////////////////
|
////////////////////
|
||||||
// Keybinds, Joypad
|
// Keybinds, Joypad
|
||||||
|
8
file.c
8
file.c
@ -818,8 +818,12 @@ char** dir_list_new(const char *dir, const char *ext)
|
|||||||
goto error;
|
goto error;
|
||||||
if (strlcat(utf8_buf, "/*", sizeof(utf8_buf)) >= sizeof(utf8_buf))
|
if (strlcat(utf8_buf, "/*", sizeof(utf8_buf)) >= sizeof(utf8_buf))
|
||||||
goto error;
|
goto error;
|
||||||
if (strlcat(utf8_buf, ext, sizeof(utf8_buf)) >= sizeof(utf8_buf))
|
|
||||||
goto error;
|
if (ext)
|
||||||
|
{
|
||||||
|
if (strlcat(utf8_buf, ext, sizeof(utf8_buf)) >= sizeof(utf8_buf))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (MultiByteToWideChar(CP_UTF8, 0, utf8_buf, -1, wchar_buf, MAXPATHLEN) == 0)
|
if (MultiByteToWideChar(CP_UTF8, 0, utf8_buf, -1, wchar_buf, MAXPATHLEN) == 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
2
file.h
2
file.h
@ -37,6 +37,8 @@ void save_ram_file(const char *path, int type);
|
|||||||
bool init_rom_file(enum ssnes_game_type type);
|
bool init_rom_file(enum ssnes_game_type type);
|
||||||
|
|
||||||
// Returns a NULL-terminated list of files in a directory with full paths.
|
// Returns a NULL-terminated list of files in a directory with full paths.
|
||||||
|
// If ext is NULL, any file will be picked.
|
||||||
|
// If non-NULL, only files with extension ext are added.
|
||||||
char** dir_list_new(const char *dir, const char *ext);
|
char** dir_list_new(const char *dir, const char *ext);
|
||||||
void dir_list_free(char **dir_list);
|
void dir_list_free(char **dir_list);
|
||||||
|
|
||||||
|
@ -150,6 +150,7 @@ struct settings
|
|||||||
unsigned autosave_interval;
|
unsigned autosave_interval;
|
||||||
|
|
||||||
bool block_sram_overwrite;
|
bool block_sram_overwrite;
|
||||||
|
bool savestate_auto_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ssnes_game_type
|
enum ssnes_game_type
|
||||||
|
@ -172,6 +172,7 @@ static void set_defaults(void)
|
|||||||
g_settings.autosave_interval = autosave_interval;
|
g_settings.autosave_interval = autosave_interval;
|
||||||
|
|
||||||
g_settings.block_sram_overwrite = block_sram_overwrite;
|
g_settings.block_sram_overwrite = block_sram_overwrite;
|
||||||
|
g_settings.savestate_auto_index = savestate_auto_index;
|
||||||
|
|
||||||
assert(sizeof(g_settings.input.binds[0]) >= sizeof(snes_keybinds_1));
|
assert(sizeof(g_settings.input.binds[0]) >= sizeof(snes_keybinds_1));
|
||||||
assert(sizeof(g_settings.input.binds[1]) >= sizeof(snes_keybinds_rest));
|
assert(sizeof(g_settings.input.binds[1]) >= sizeof(snes_keybinds_rest));
|
||||||
@ -421,6 +422,7 @@ static void parse_config_file(void)
|
|||||||
CONFIG_GET_STRING(cheat_settings_path, "cheat_settings_path");
|
CONFIG_GET_STRING(cheat_settings_path, "cheat_settings_path");
|
||||||
|
|
||||||
CONFIG_GET_BOOL(block_sram_overwrite, "block_sram_overwrite");
|
CONFIG_GET_BOOL(block_sram_overwrite, "block_sram_overwrite");
|
||||||
|
CONFIG_GET_BOOL(savestate_auto_index, "savestate_auto_index");
|
||||||
|
|
||||||
if (!g_extern.has_set_save_path && config_get_array(conf, "savefile_directory", tmp_str, sizeof(tmp_str)))
|
if (!g_extern.has_set_save_path && config_get_array(conf, "savefile_directory", tmp_str, sizeof(tmp_str)))
|
||||||
{
|
{
|
||||||
|
56
ssnes.c
56
ssnes.c
@ -21,6 +21,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
@ -1070,6 +1071,53 @@ static void deinit_autosave(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_savestate_auto_index(void)
|
||||||
|
{
|
||||||
|
if (!g_settings.savestate_auto_index)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char state_path[MAXPATHLEN];
|
||||||
|
strlcpy(state_path, g_extern.savestate_name, sizeof(state_path));
|
||||||
|
|
||||||
|
char *split = strrchr(state_path, '/');
|
||||||
|
if (!split)
|
||||||
|
split = strrchr(state_path, '\\');
|
||||||
|
|
||||||
|
const char *base = state_path;
|
||||||
|
const char *dir = state_path;
|
||||||
|
if (split)
|
||||||
|
{
|
||||||
|
*split = '\0';
|
||||||
|
base = split + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned max_index = 0;
|
||||||
|
|
||||||
|
char **dir_list = dir_list_new(dir, NULL);
|
||||||
|
if (!dir_list)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned index = 0;
|
||||||
|
const char *dir_elem;
|
||||||
|
while ((dir_elem = dir_list[index++]))
|
||||||
|
{
|
||||||
|
if (!strstr(dir_elem, base))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const char *end = dir_elem + strlen(dir_elem);
|
||||||
|
while ((end != dir_elem) && isdigit(end[-1])) end--;
|
||||||
|
|
||||||
|
unsigned index = strtoul(end, NULL, 0);
|
||||||
|
if (index > max_index)
|
||||||
|
max_index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
dir_list_free(dir_list);
|
||||||
|
|
||||||
|
g_extern.state_slot = max_index;
|
||||||
|
SSNES_LOG("Found last state slot: #%u\n", g_extern.state_slot);
|
||||||
|
}
|
||||||
|
|
||||||
static void fill_pathnames(void)
|
static void fill_pathnames(void)
|
||||||
{
|
{
|
||||||
switch (g_extern.game_type)
|
switch (g_extern.game_type)
|
||||||
@ -1127,6 +1175,9 @@ static void check_savestates(void)
|
|||||||
bool should_savestate = driver.input->key_pressed(driver.input_data, SSNES_SAVE_STATE_KEY);
|
bool should_savestate = driver.input->key_pressed(driver.input_data, SSNES_SAVE_STATE_KEY);
|
||||||
if (should_savestate && !old_should_savestate)
|
if (should_savestate && !old_should_savestate)
|
||||||
{
|
{
|
||||||
|
if (g_settings.savestate_auto_index)
|
||||||
|
g_extern.state_slot++;
|
||||||
|
|
||||||
char save_path[MAXPATHLEN];
|
char save_path[MAXPATHLEN];
|
||||||
|
|
||||||
if (g_extern.state_slot > 0)
|
if (g_extern.state_slot > 0)
|
||||||
@ -1134,7 +1185,7 @@ static void check_savestates(void)
|
|||||||
else
|
else
|
||||||
snprintf(save_path, sizeof(save_path), "%s", g_extern.savestate_name);
|
snprintf(save_path, sizeof(save_path), "%s", g_extern.savestate_name);
|
||||||
|
|
||||||
if(!save_state(save_path))
|
if (!save_state(save_path))
|
||||||
{
|
{
|
||||||
msg_queue_clear(g_extern.msg_queue);
|
msg_queue_clear(g_extern.msg_queue);
|
||||||
char msg[512];
|
char msg[512];
|
||||||
@ -1160,7 +1211,7 @@ static void check_savestates(void)
|
|||||||
else
|
else
|
||||||
snprintf(load_path, sizeof(load_path), "%s", g_extern.savestate_name);
|
snprintf(load_path, sizeof(load_path), "%s", g_extern.savestate_name);
|
||||||
|
|
||||||
if(!load_state(load_path))
|
if (!load_state(load_path))
|
||||||
{
|
{
|
||||||
msg_queue_clear(g_extern.msg_queue);
|
msg_queue_clear(g_extern.msg_queue);
|
||||||
char msg[512];
|
char msg[512];
|
||||||
@ -1574,6 +1625,7 @@ int main(int argc, char *argv[])
|
|||||||
SSNES_LOG("Version of libsnes API: %u.%u\n", psnes_library_revision_major(), psnes_library_revision_minor());
|
SSNES_LOG("Version of libsnes API: %u.%u\n", psnes_library_revision_major(), psnes_library_revision_minor());
|
||||||
|
|
||||||
fill_pathnames();
|
fill_pathnames();
|
||||||
|
set_savestate_auto_index();
|
||||||
|
|
||||||
if (!init_rom_file(g_extern.game_type))
|
if (!init_rom_file(g_extern.game_type))
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -320,3 +320,10 @@
|
|||||||
# Block SRAM from being overwritten when loading save states.
|
# Block SRAM from being overwritten when loading save states.
|
||||||
# Might potentially lead to buggy games.
|
# Might potentially lead to buggy games.
|
||||||
# block_sram_overwrite = false
|
# block_sram_overwrite = false
|
||||||
|
|
||||||
|
# When saving a savestate, save state index is automatically increased before
|
||||||
|
# it is saved.
|
||||||
|
# Also, when loading a ROM, the index will be set to the highest existing index.
|
||||||
|
# There is no upper bound on the index.
|
||||||
|
# savestate_auto_index = false
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user