1
0
mirror of https://github.com/libretro/RetroArch synced 2024-07-05 17:58:41 +00:00

Merge pull request #11600 from davidgfnet/master

Adding savestate garbage collector for autoincrement stavestates
This commit is contained in:
Autechre 2020-11-22 17:11:08 +01:00 committed by GitHub
commit 06279b68f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 233 additions and 62 deletions

View File

@ -1020,6 +1020,15 @@ static const unsigned netplay_share_analog = RARCH_NETPLAY_SHARE_ANALOG_NO_PREFE
* to the highest existing value. */
static const bool savestate_auto_index = false;
/* Specifies the maximum number of savestates to keep
* when savestate auto index is enabled
* > When limit is exceeded, savestate with the lowest
* index will be deleted automatically when creating
* a new savestate
* > Setting value to zero disables the limit (no
* savestates will be deleted in this case) */
#define DEFAULT_SAVESTATE_MAX_KEEP 0
/* Automatically saves a savestate at the end of RetroArch's lifetime.
* The path is $SRAM_PATH.auto.
* RetroArch will automatically load any savestate with this path on

View File

@ -1878,6 +1878,7 @@ static struct config_uint_setting *populate_settings_uint(
SETTING_UINT("rewind_granularity", &settings->uints.rewind_granularity, true, DEFAULT_REWIND_GRANULARITY, false);
SETTING_UINT("rewind_buffer_size_step", &settings->uints.rewind_buffer_size_step, true, DEFAULT_REWIND_BUFFER_SIZE_STEP, false);
SETTING_UINT("autosave_interval", &settings->uints.autosave_interval, true, DEFAULT_AUTOSAVE_INTERVAL, false);
SETTING_UINT("savestate_max_keep", &settings->uints.savestate_max_keep, true, DEFAULT_SAVESTATE_MAX_KEEP, false);
SETTING_UINT("frontend_log_level", &settings->uints.frontend_log_level, true, DEFAULT_FRONTEND_LOG_LEVEL, false);
SETTING_UINT("libretro_log_level", &settings->uints.libretro_log_level, true, DEFAULT_LIBRETRO_LOG_LEVEL, false);
SETTING_UINT("keyboard_gamepad_mapping_type",&settings->uints.input_keyboard_gamepad_mapping_type, true, 1, false);

View File

@ -170,6 +170,7 @@ typedef struct settings
unsigned rewind_granularity;
unsigned rewind_buffer_size_step;
unsigned autosave_interval;
unsigned savestate_max_keep;
unsigned network_cmd_port;
unsigned network_remote_base_port;
unsigned keymapper_port;

View File

@ -2586,6 +2586,10 @@ MSG_HASH(
MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE,
"savestate_auto_save"
)
MSG_HASH(
MENU_ENUM_LABEL_SAVESTATE_MAX_KEEP,
"savestate_max_keep"
)
MSG_HASH(
MENU_ENUM_LABEL_SAVESTATE_DIRECTORY,
"savestate_directory"

View File

@ -2962,6 +2962,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX,
"Before making a save state, the save state index is automatically increased. When loading content, the index will be set to the highest existing index."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_SAVESTATE_MAX_KEEP,
"Maximum Auto-Increment Save States to Keep"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_SAVESTATE_MAX_KEEP,
"Limits the number of save states that will be created when 'Increment Save State Index Automatically' is enabled. If limit is exceeded when saving a new state, the existing state with the lowest index will be deleted. A value of '0' means unlimited states will be recorded."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE,
"Auto Save State"

View File

@ -491,6 +491,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_savestate_auto_load, MENU_
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_savestate_thumbnail_enable, MENU_ENUM_SUBLABEL_SAVESTATE_THUMBNAIL_ENABLE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_save_file_compression, MENU_ENUM_SUBLABEL_SAVE_FILE_COMPRESSION)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_savestate_file_compression, MENU_ENUM_SUBLABEL_SAVESTATE_FILE_COMPRESSION)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_savestate_max_keep, MENU_ENUM_SUBLABEL_SAVESTATE_MAX_KEEP)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_autosave_interval, MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_remap_binds_enable, MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_autodetect_enable, MENU_ENUM_SUBLABEL_INPUT_AUTODETECT_ENABLE)
@ -2876,6 +2877,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_AUTOSAVE_INTERVAL:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_autosave_interval);
break;
case MENU_ENUM_LABEL_SAVESTATE_MAX_KEEP:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_savestate_max_keep);
break;
case MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_savestate_thumbnail_enable);
break;

View File

@ -8052,31 +8052,48 @@ unsigned menu_displaylist_build_list(
break;
case DISPLAYLIST_SAVING_SETTINGS_LIST:
{
menu_displaylist_build_info_t build_list[] = {
{MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SORT_SAVESTATES_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SORT_SAVEFILES_BY_CONTENT_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SORT_SAVESTATES_BY_CONTENT_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_AUTOSAVE_INTERVAL, PARSE_ONLY_UINT},
{MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SAVE_FILE_COMPRESSION, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SAVESTATE_FILE_COMPRESSION, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SORT_SCREENSHOTS_BY_CONTENT_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SAVESTATES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SYSTEMFILES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SCREENSHOTS_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG_AGGREGATE, PARSE_ONLY_BOOL},
settings_t *settings = config_get_ptr();
bool savestate_auto_index = settings->bools.savestate_auto_index;
menu_displaylist_build_info_selective_t build_list[] = {
{MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SORT_SAVESTATES_ENABLE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SORT_SAVEFILES_BY_CONTENT_ENABLE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SORT_SAVESTATES_BY_CONTENT_ENABLE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_AUTOSAVE_INTERVAL, PARSE_ONLY_UINT, true},
{MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SAVESTATE_MAX_KEEP, PARSE_ONLY_UINT, false},
{MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SAVE_FILE_COMPRESSION, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SAVESTATE_FILE_COMPRESSION, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SORT_SCREENSHOTS_BY_CONTENT_ENABLE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SAVESTATES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SYSTEMFILES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SCREENSHOTS_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG_AGGREGATE, PARSE_ONLY_BOOL, true},
};
for (i = 0; i < ARRAY_SIZE(build_list); i++)
{
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
switch (build_list[i].enum_idx)
{
case MENU_ENUM_LABEL_SAVESTATE_MAX_KEEP:
build_list[i].checked = savestate_auto_index;
break;
default:
break;
}
}
for (i = 0; i < ARRAY_SIZE(build_list); i++)
{
if (build_list[i].checked &&
MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
build_list[i].enum_idx, build_list[i].parse_type,
false) == 0)
count++;

View File

@ -9317,7 +9317,7 @@ static bool setting_append_list(
case SETTINGS_LIST_SAVING:
{
uint8_t i;
struct bool_entry bool_entries[14];
struct bool_entry bool_entries[13];
START_GROUP(list, list_info, &group_info, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS), parent_group);
parent_group = msg_hash_to_str(MENU_ENUM_LABEL_SAVING_SETTINGS);
@ -9361,54 +9361,48 @@ static bool setting_append_list(
bool_entries[5].default_value = DEFAULT_BLOCK_SRAM_OVERWRITE;
bool_entries[5].flags = SD_FLAG_NONE;
bool_entries[6].target = &settings->bools.savestate_auto_index;
bool_entries[6].name_enum_idx = MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX;
bool_entries[6].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX;
bool_entries[6].default_value = savestate_auto_index;
bool_entries[6].target = &settings->bools.savestate_auto_save;
bool_entries[6].name_enum_idx = MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE;
bool_entries[6].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE;
bool_entries[6].default_value = savestate_auto_save;
bool_entries[6].flags = SD_FLAG_NONE;
bool_entries[7].target = &settings->bools.savestate_auto_save;
bool_entries[7].name_enum_idx = MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE;
bool_entries[7].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE;
bool_entries[7].default_value = savestate_auto_save;
bool_entries[7].target = &settings->bools.savestate_auto_load;
bool_entries[7].name_enum_idx = MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD;
bool_entries[7].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD;
bool_entries[7].default_value = savestate_auto_load;
bool_entries[7].flags = SD_FLAG_NONE;
bool_entries[8].target = &settings->bools.savestate_auto_load;
bool_entries[8].name_enum_idx = MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD;
bool_entries[8].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD;
bool_entries[8].default_value = savestate_auto_load;
bool_entries[8].flags = SD_FLAG_NONE;
bool_entries[8].target = &settings->bools.savestate_thumbnail_enable;
bool_entries[8].name_enum_idx = MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE;
bool_entries[8].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE;
bool_entries[8].default_value = savestate_thumbnail_enable;
bool_entries[8].flags = SD_FLAG_ADVANCED;
bool_entries[9].target = &settings->bools.savestate_thumbnail_enable;
bool_entries[9].name_enum_idx = MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE;
bool_entries[9].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE;
bool_entries[9].default_value = savestate_thumbnail_enable;
bool_entries[9].target = &settings->bools.savefiles_in_content_dir;
bool_entries[9].name_enum_idx = MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE;
bool_entries[9].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SAVEFILES_IN_CONTENT_DIR_ENABLE;
bool_entries[9].default_value = default_savefiles_in_content_dir;
bool_entries[9].flags = SD_FLAG_ADVANCED;
bool_entries[10].target = &settings->bools.savefiles_in_content_dir;
bool_entries[10].name_enum_idx = MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE;
bool_entries[10].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SAVEFILES_IN_CONTENT_DIR_ENABLE;
bool_entries[10].default_value = default_savefiles_in_content_dir;
bool_entries[10].target = &settings->bools.savestates_in_content_dir;
bool_entries[10].name_enum_idx = MENU_ENUM_LABEL_SAVESTATES_IN_CONTENT_DIR_ENABLE;
bool_entries[10].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SAVESTATES_IN_CONTENT_DIR_ENABLE;
bool_entries[10].default_value = default_savestates_in_content_dir;
bool_entries[10].flags = SD_FLAG_ADVANCED;
bool_entries[11].target = &settings->bools.savestates_in_content_dir;
bool_entries[11].name_enum_idx = MENU_ENUM_LABEL_SAVESTATES_IN_CONTENT_DIR_ENABLE;
bool_entries[11].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SAVESTATES_IN_CONTENT_DIR_ENABLE;
bool_entries[11].default_value = default_savestates_in_content_dir;
bool_entries[11].target = &settings->bools.systemfiles_in_content_dir;
bool_entries[11].name_enum_idx = MENU_ENUM_LABEL_SYSTEMFILES_IN_CONTENT_DIR_ENABLE;
bool_entries[11].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SYSTEMFILES_IN_CONTENT_DIR_ENABLE;
bool_entries[11].default_value = default_systemfiles_in_content_dir;
bool_entries[11].flags = SD_FLAG_ADVANCED;
bool_entries[12].target = &settings->bools.systemfiles_in_content_dir;
bool_entries[12].name_enum_idx = MENU_ENUM_LABEL_SYSTEMFILES_IN_CONTENT_DIR_ENABLE;
bool_entries[12].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SYSTEMFILES_IN_CONTENT_DIR_ENABLE;
bool_entries[12].default_value = default_systemfiles_in_content_dir;
bool_entries[12].target = &settings->bools.screenshots_in_content_dir;
bool_entries[12].name_enum_idx = MENU_ENUM_LABEL_SCREENSHOTS_IN_CONTENT_DIR_ENABLE;
bool_entries[12].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SCREENSHOTS_IN_CONTENT_DIR_ENABLE;
bool_entries[12].default_value = default_screenshots_in_content_dir;
bool_entries[12].flags = SD_FLAG_ADVANCED;
bool_entries[13].target = &settings->bools.screenshots_in_content_dir;
bool_entries[13].name_enum_idx = MENU_ENUM_LABEL_SCREENSHOTS_IN_CONTENT_DIR_ENABLE;
bool_entries[13].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_SCREENSHOTS_IN_CONTENT_DIR_ENABLE;
bool_entries[13].default_value = default_screenshots_in_content_dir;
bool_entries[13].flags = SD_FLAG_ADVANCED;
for (i = 0; i < ARRAY_SIZE(bool_entries); i++)
{
CONFIG_BOOL(
@ -9446,6 +9440,37 @@ static bool setting_append_list(
(*list)[list_info->index - 1].get_string_representation =
&setting_get_string_representation_uint_autosave_interval;
#endif
CONFIG_BOOL(
list, list_info,
&settings->bools.savestate_auto_index,
MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX,
MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX,
savestate_auto_index,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
(*list)[list_info->index - 1].action_ok = &setting_bool_action_left_with_refresh;
(*list)[list_info->index - 1].action_left = &setting_bool_action_left_with_refresh;
(*list)[list_info->index - 1].action_right = &setting_bool_action_right_with_refresh;
CONFIG_UINT(
list, list_info,
&settings->uints.savestate_max_keep,
MENU_ENUM_LABEL_SAVESTATE_MAX_KEEP,
MENU_ENUM_LABEL_VALUE_SAVESTATE_MAX_KEEP,
DEFAULT_SAVESTATE_MAX_KEEP,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
menu_settings_list_current_add_range(list, list_info, 0, 999, 1, true, true);
CONFIG_BOOL(
list, list_info,

View File

@ -1736,6 +1736,7 @@ enum msg_hash_enums
MENU_LABEL(CHEAT_DELETE_MATCH),
MENU_LABEL(SCREEN_RESOLUTION),
MENU_LABEL(SAVESTATE_AUTO_INDEX),
MENU_LABEL(SAVESTATE_MAX_KEEP),
MENU_LABEL(SAVESTATE_AUTO_SAVE),
MENU_LABEL(SAVESTATE_AUTO_LOAD),
MENU_LABEL(SAVESTATE_THUMBNAIL_ENABLE),

View File

@ -11982,7 +11982,7 @@ static void command_event_load_auto_state(
static void command_event_set_savestate_auto_index(
settings_t *settings,
global_t *global,
const global_t *global,
struct rarch_state *p_rarch)
{
size_t i;
@ -12047,6 +12047,96 @@ static void command_event_set_savestate_auto_index(
max_idx);
}
static void command_event_set_savestate_garbage_collect(
settings_t *settings,
const global_t *global,
struct rarch_state *p_rarch)
{
size_t i, cnt = 0;
char state_dir[PATH_MAX_LENGTH];
char state_base[PATH_MAX_LENGTH];
struct string_list *dir_list = NULL;
unsigned min_idx = UINT_MAX;
const char *oldest_save = NULL;
unsigned max_to_keep = settings->uints.savestate_max_keep;
bool show_hidden_files = settings->bools.show_hidden_files;
if (!global || (max_to_keep == 0))
return;
state_dir[0] = '\0';
state_base[0] = '\0';
/* Similar to command_event_set_savestate_auto_index(),
* this will find the lowest numbered save-state */
fill_pathname_basedir(state_dir, global->name.savestate,
sizeof(state_dir));
dir_list = dir_list_new_special(state_dir, DIR_LIST_PLAIN, NULL,
show_hidden_files);
if (!dir_list)
return;
fill_pathname_base(state_base, global->name.savestate,
sizeof(state_base));
for (i = 0; i < dir_list->size; i++)
{
unsigned idx;
char elem_base[128];
const char *end = NULL;
const char *dir_elem = dir_list->elems[i].data;
const char *ext = NULL;
elem_base[0] = '\0';
if (string_is_empty(dir_elem))
continue;
fill_pathname_base(elem_base, dir_elem, sizeof(elem_base));
/* Only consider files with a '.state' extension
* > i.e. Ignore '.state.auto', '.state.bak', etc. */
ext = path_get_extension(elem_base);
if (string_is_empty(ext) ||
!string_starts_with_size(ext, "state", STRLEN_CONST("state")))
continue;
/* Check whether this file is associated with
* the current content */
if (!string_starts_with(elem_base, state_base))
continue;
/* This looks like a valid save */
cnt++;
/* > Get index */
end = dir_elem + strlen(dir_elem);
while ((end > dir_elem) && ISDIGIT((int)end[-1]))
end--;
idx = string_to_unsigned(end);
/* > Check if this is the lowest index so far */
if (idx < min_idx)
{
min_idx = idx;
oldest_save = dir_elem;
}
}
/* Only delete one save state per save action
* > Conservative behaviour, designed to minimise
* the risk of deleting multiple incorrect files
* in case of accident */
if (!string_is_empty(oldest_save) && (cnt > max_to_keep))
filestream_delete(oldest_save);
dir_list_free(dir_list);
}
static bool event_init_content(
settings_t *settings,
struct rarch_state *p_rarch)
@ -12655,15 +12745,26 @@ static bool command_event_main_state(
switch (cmd)
{
case CMD_EVENT_SAVE_STATE:
content_save_state(state_path, true, false);
{
bool savestate_auto_index =
settings->bools.savestate_auto_index;
unsigned savestate_max_keep =
settings->uints.savestate_max_keep;
bool frame_time_counter_reset_after_save_state =
settings->bools.frame_time_counter_reset_after_save_state;
settings->bools.frame_time_counter_reset_after_save_state;
content_save_state(state_path, true, false);
/* Clean up excess savestates if necessary */
if (savestate_auto_index && (savestate_max_keep > 0))
command_event_set_savestate_garbage_collect(settings, global, p_rarch);
if (frame_time_counter_reset_after_save_state)
p_rarch->video_driver_frame_time_count = 0;
ret = true;
push_msg = false;
}
ret = true;
push_msg = false;
break;
case CMD_EVENT_LOAD_STATE:
if (content_load_state(state_path, false, false))