From 5fa1dd73419aff7b0398926b18b0542a0607f122 Mon Sep 17 00:00:00 2001 From: hunterk Date: Sat, 25 Apr 2026 16:30:17 -0500 Subject: [PATCH 1/5] add autosavestate task --- config.def.h | 10 ++++++++ configuration.c | 1 + configuration.h | 1 + content.h | 3 +++ intl/msg_hash_lbl.h | 4 ++++ intl/msg_hash_us.h | 12 ++++++++++ menu/cbs/menu_cbs_sublabel.c | 4 ++++ menu/menu_displaylist.c | 1 + menu/menu_setting.c | 17 ++++++++++++++ msg_hash_lbl_str.h | 1 + runloop.c | 3 +++ tasks/task_save.c | 45 ++++++++++++++++++++++++++++++++++++ 12 files changed, 102 insertions(+) diff --git a/config.def.h b/config.def.h index 4446b93ad6fc..038ab6438813 100644 --- a/config.def.h +++ b/config.def.h @@ -1436,6 +1436,16 @@ #define DEFAULT_SAVESTATE_AUTO_SAVE false #define DEFAULT_SAVESTATE_AUTO_LOAD false +/* Automatically saves a savestate at a regular interval. + * It is measured in seconds. A value of 0 disables automatic savestate saving. */ +#if defined(__i386__) || defined(__i486__) || defined(__i686__) || defined(__x86_64__) || defined(_M_X64) || defined(_WIN32) || defined(OSX) || defined(ANDROID) || defined(IOS) || defined(DINGUX) +/* Disabled by default but can be enabled by user */ +#define DEFAULT_AUTOMATIC_SAVESTATE_INTERVAL 0 +#else +/* Default to disabled on I/O-constrained platforms */ +#define DEFAULT_AUTOMATIC_SAVESTATE_INTERVAL 0 +#endif + /* Take screenshots for save states */ #if defined(__x86_64__) || defined(_M_X64) #define DEFAULT_SAVESTATE_THUMBNAIL_ENABLE true diff --git a/configuration.c b/configuration.c index dd9082bf9343..930c54df7af2 100644 --- a/configuration.c +++ b/configuration.c @@ -2461,6 +2461,7 @@ static struct config_uint_setting *populate_settings_uint( SETTING_UINT("memory_update_interval", &settings->uints.memory_update_interval, true, DEFAULT_MEMORY_UPDATE_INTERVAL, false); SETTING_UINT("core_updater_auto_backup_history_size", &settings->uints.core_updater_auto_backup_history_size, true, DEFAULT_CORE_UPDATER_AUTO_BACKUP_HISTORY_SIZE, false); SETTING_UINT("autosave_interval", &settings->uints.autosave_interval, true, DEFAULT_AUTOSAVE_INTERVAL, false); + SETTING_UINT("automatic_savestate_interval", &settings->uints.automatic_savestate_interval, true, DEFAULT_AUTOMATIC_SAVESTATE_INTERVAL, false); 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("run_ahead_frames", &settings->uints.run_ahead_frames, true, 1, false); diff --git a/configuration.h b/configuration.h index 71d02a785954..4b98d0d78194 100644 --- a/configuration.h +++ b/configuration.h @@ -242,6 +242,7 @@ typedef struct settings unsigned rewind_granularity; unsigned rewind_buffer_size_step; unsigned autosave_interval; + unsigned automatic_savestate_interval; unsigned replay_checkpoint_interval; unsigned replay_max_keep; unsigned savestate_max_keep; diff --git a/content.h b/content.h index 16ff6f89d0ea..9aa4861573b3 100644 --- a/content.h +++ b/content.h @@ -54,6 +54,9 @@ bool content_load_state(const char* path, bool load_to_backup_buffer, bool autol /* Save a state from memory to disk. */ bool content_save_state(const char *path, bool save_to_disk); +/* Automatically save a state if the interval has elapsed. */ +bool content_save_state_automatic(void); + /* Save an automatic savestate to disk. */ bool content_auto_save_state(const char *path); diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index a4419efd1869..2ac2f488aafc 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -392,6 +392,10 @@ MSG_HASH( MENU_ENUM_LABEL_AUTOSAVE_INTERVAL, MENU_ENUM_LABEL_AUTOSAVE_INTERVAL_STR ) +MSG_HASH( + MENU_ENUM_LABEL_AUTOMATIC_SAVESTATE_INTERVAL, + MENU_ENUM_LABEL_AUTOMATIC_SAVESTATE_INTERVAL_STR + ) MSG_HASH( MENU_ENUM_LABEL_REPLAY_CHECKPOINT_INTERVAL, MENU_ENUM_LABEL_REPLAY_CHECKPOINT_INTERVAL_STR diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 239be309ed8c..6cf00e9b066a 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -4779,6 +4779,18 @@ MSG_HASH( MENU_ENUM_LABEL_HELP_AUTOSAVE_INTERVAL, "Autosaves the non-volatile SRAM at a regular interval. This is disabled by default unless set otherwise. The interval is measured in seconds. A value of 0 disables autosave." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTOMATIC_SAVESTATE_INTERVAL, + "Automatic Savestate Interval" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUTOMATIC_SAVESTATE_INTERVAL, + "Automatically save a savestate at a regular interval (in seconds). Set to 0 to disable." + ) +MSG_HASH( + MENU_ENUM_LABEL_HELP_AUTOMATIC_SAVESTATE_INTERVAL, + "Automatically saves a savestate at regular intervals. This is useful for creating periodic backups of your game progress. The interval is measured in seconds. A value of 0 disables automatic savestate saving." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_REPLAY_CHECKPOINT_INTERVAL, "Replay: Checkpoint Interval" diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index de8c0eec36b6..05883751cb45 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -825,6 +825,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_save_file_compression, MENU_ 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_automatic_savestate_interval, MENU_ENUM_SUBLABEL_AUTOMATIC_SAVESTATE_INTERVAL) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_replay_max_keep, MENU_ENUM_SUBLABEL_REPLAY_MAX_KEEP) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_replay_checkpoint_interval, MENU_ENUM_SUBLABEL_REPLAY_CHECKPOINT_INTERVAL) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_replay_checkpoint_deserialize, MENU_ENUM_SUBLABEL_REPLAY_CHECKPOINT_DESERIALIZE) @@ -4107,6 +4108,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_AUTOMATIC_SAVESTATE_INTERVAL: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_automatic_savestate_interval); + break; case MENU_ENUM_LABEL_REPLAY_CHECKPOINT_INTERVAL: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_replay_checkpoint_interval); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 78c185b58b3e..bf2f682af8d6 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -11138,6 +11138,7 @@ unsigned menu_displaylist_build_list( {MENU_ENUM_LABEL_SORT_SAVEFILES_BY_CONTENT_ENABLE, PARSE_ONLY_BOOL, true}, {MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL, true}, {MENU_ENUM_LABEL_AUTOSAVE_INTERVAL, PARSE_ONLY_UINT, true}, + {MENU_ENUM_LABEL_AUTOMATIC_SAVESTATE_INTERVAL, PARSE_ONLY_UINT, true}, {MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE, PARSE_ONLY_BOOL, true}, #if defined(HAVE_ZLIB) {MENU_ENUM_LABEL_SAVE_FILE_COMPRESSION, PARSE_ONLY_BOOL, true}, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 1fc6a6401d8e..2ae1e31fe1ca 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -12006,6 +12006,23 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_autosave_interval; #endif + CONFIG_UINT( + list, list_info, + &settings->uints.automatic_savestate_interval, + MENU_ENUM_LABEL_AUTOMATIC_SAVESTATE_INTERVAL, + MENU_ENUM_LABEL_VALUE_AUTOMATIC_SAVESTATE_INTERVAL, + DEFAULT_AUTOMATIC_SAVESTATE_INTERVAL, + &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, 0, 1, true, false); + SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_CMD_APPLY_AUTO); + (*list)[list_info->index - 1].get_string_representation = + &setting_get_string_representation_uint_autosave_interval; + CONFIG_BOOL( list, list_info, &settings->bools.savestate_auto_index, diff --git a/msg_hash_lbl_str.h b/msg_hash_lbl_str.h index 304770c572b8..11cce45f22ca 100644 --- a/msg_hash_lbl_str.h +++ b/msg_hash_lbl_str.h @@ -107,6 +107,7 @@ #define MENU_ENUM_LABEL_MICROPHONE_WASAPI_SH_BUFFER_LENGTH_STR "microphone_wasapi_sh_buffer_length" #define MENU_ENUM_LABEL_MICROPHONE_RESAMPLER_QUALITY_STR "microphone_resampler_quality" #define MENU_ENUM_LABEL_AUTOSAVE_INTERVAL_STR "autosave_interval" +#define MENU_ENUM_LABEL_AUTOMATIC_SAVESTATE_INTERVAL_STR "automatic_savestate_interval" #define MENU_ENUM_LABEL_REPLAY_CHECKPOINT_INTERVAL_STR "replay_checkpoint_interval" #define MENU_ENUM_LABEL_REPLAY_CHECKPOINT_DESERIALIZE_STR "replay_checkpoint_deserialize" #define MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE_STR "auto_overrides_enable" diff --git a/runloop.c b/runloop.c index 034214ee68ad..dc0c07de5fe7 100644 --- a/runloop.c +++ b/runloop.c @@ -7476,6 +7476,9 @@ int runloop_iterate(void) autosave_unlock(); #endif + /* Check if we should save state automatically */ + content_save_state_automatic(); + end: if (vrr_runloop_enable) { diff --git a/tasks/task_save.c b/tasks/task_save.c index 03ff21eb15f1..231c29fec3be 100644 --- a/tasks/task_save.c +++ b/tasks/task_save.c @@ -135,6 +135,9 @@ static struct ram_save_state_buf ram_buf; static bool save_state_in_background = false; static bool save_state_disable_undo = false; +/* Time tracking for automatic savestate interval */ +static time_t last_automatic_savestate_time = 0; + typedef struct rastate_size_info { size_t total_size; @@ -1882,3 +1885,45 @@ void set_save_state_disable_undo(bool disable) { save_state_disable_undo = disable; } + +bool content_save_state_automatic(void) +{ + time_t current_time; + char savestate_path[PATH_MAX_LENGTH]; + settings_t *settings = config_get_ptr(); + unsigned automatic_savestate_interval = + settings->uints.automatic_savestate_interval; + + /* Return early if automatic savestate is disabled, + no content is loaded, or core doesn't support savestates */ + if (automatic_savestate_interval == 0 + || !content_is_inited() + || !core_info_current_supports_savestate()) + return false; + + current_time = time(NULL); + + /* Check how long since last autosavestate */ + if ((current_time - last_automatic_savestate_time) < + (time_t)automatic_savestate_interval) + return false; + + /* Generate the savestate path */ + if (!runloop_get_current_savestate_path(savestate_path, + sizeof(savestate_path))) + { + RARCH_WARN("[State] %s\n", + msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE)); + return false; + } + + /* Trigger the savestate */ + RARCH_LOG("[State] %s (automatic) to \"%s\".\n", + msg_hash_to_str(MSG_SAVING_STATE), + savestate_path); + + /* Update the last savestate time, rinse/repeat */ + last_automatic_savestate_time = current_time; + + return content_save_state(savestate_path, true); +} From b8d799535af2474ca202412775a91597c0567ae9 Mon Sep 17 00:00:00 2001 From: hunterk Date: Sat, 25 Apr 2026 17:30:21 -0500 Subject: [PATCH 2/5] use auto slot for autosavestate, fix message hash --- msg_hash.h | 1 + tasks/task_save.c | 14 ++++++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/msg_hash.h b/msg_hash.h index 1bfe9e830f03..b5ab3c57f728 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -2546,6 +2546,7 @@ enum msg_hash_enums MENU_LABEL(FRONTEND_LOG_LEVEL), MENU_LBL_H(LIBRETRO_LOG_LEVEL), MENU_LBL_H(AUTOSAVE_INTERVAL), + MENU_LBL_H(AUTOMATIC_SAVESTATE_INTERVAL), MENU_LBL_H(REPLAY_CHECKPOINT_INTERVAL), MENU_LBL_H(REPLAY_CHECKPOINT_DESERIALIZE), MENU_LBL_H(CONFIG_SAVE_ON_EXIT), diff --git a/tasks/task_save.c b/tasks/task_save.c index 231c29fec3be..0a5bb810f5df 100644 --- a/tasks/task_save.c +++ b/tasks/task_save.c @@ -1895,10 +1895,8 @@ bool content_save_state_automatic(void) settings->uints.automatic_savestate_interval; /* Return early if automatic savestate is disabled, - no content is loaded, or core doesn't support savestates */ - if (automatic_savestate_interval == 0 - || !content_is_inited() - || !core_info_current_supports_savestate()) + safety checks already happen in content_save_state() */ + if (automatic_savestate_interval == 0) return false; current_time = time(NULL); @@ -1909,11 +1907,11 @@ bool content_save_state_automatic(void) return false; /* Generate the savestate path */ - if (!runloop_get_current_savestate_path(savestate_path, - sizeof(savestate_path))) + if (!runloop_get_savestate_path(savestate_path, + sizeof(savestate_path), -1)) { RARCH_WARN("[State] %s\n", - msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE)); + msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO)); return false; } @@ -1925,5 +1923,5 @@ bool content_save_state_automatic(void) /* Update the last savestate time, rinse/repeat */ last_automatic_savestate_time = current_time; - return content_save_state(savestate_path, true); + return content_auto_save_state(savestate_path); } From 5d843940ded3a9ccf1d40fdb5913fa3cecaa1aba Mon Sep 17 00:00:00 2001 From: hunterk Date: Sat, 25 Apr 2026 18:34:31 -0500 Subject: [PATCH 3/5] buildfix for platforms without thread support --- menu/menu_setting.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 2ae1e31fe1ca..34f69c037b18 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -12006,6 +12006,8 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_autosave_interval; #endif + +#ifdef HAVE_THREADS CONFIG_UINT( list, list_info, &settings->uints.automatic_savestate_interval, @@ -12022,6 +12024,7 @@ static bool setting_append_list( SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_CMD_APPLY_AUTO); (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_autosave_interval; +#endif CONFIG_BOOL( list, list_info, From 8511b53e91e59968f600a0376ec47962a9311de2 Mon Sep 17 00:00:00 2001 From: hunterk Date: Sun, 26 Apr 2026 10:37:58 -0500 Subject: [PATCH 4/5] fix compiler warning with slang cache while I'm at it --- gfx/drivers_shader/slang_cache.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gfx/drivers_shader/slang_cache.cpp b/gfx/drivers_shader/slang_cache.cpp index 79aa5c257f42..f0036430f80d 100644 --- a/gfx/drivers_shader/slang_cache.cpp +++ b/gfx/drivers_shader/slang_cache.cpp @@ -64,13 +64,18 @@ static bool spirv_cache_get_filename(const char *hash, char *cache_file_out, size_t cache_file_out_len) { char cache_dir[PATH_MAX_LENGTH]; + int ret; if (!spirv_cache_get_dir(cache_dir, sizeof(cache_dir))) return false; - snprintf(cache_file_out, cache_file_out_len, "%s/%s.spirv", + ret = snprintf(cache_file_out, cache_file_out_len, "%s/%s.spirv", cache_dir, hash); + /* Check if snprintf truncated the output */ + if (ret < 0 || (size_t)ret >= cache_file_out_len) + return false; + return true; } From c32eac45bb0379c015f0c6c47eeaa91c46b35306 Mon Sep 17 00:00:00 2001 From: hunterk Date: Fri, 1 May 2026 21:32:00 -0500 Subject: [PATCH 5/5] follow menu wording conventions and improve help text --- config.def.h | 4 ++-- configuration.c | 2 +- configuration.h | 2 +- intl/msg_hash_lbl.h | 4 ++-- intl/msg_hash_us.h | 12 ++++++------ menu/cbs/menu_cbs_sublabel.c | 6 +++--- menu/menu_displaylist.c | 2 +- menu/menu_setting.c | 8 ++++---- msg_hash.h | 2 +- msg_hash_lbl_str.h | 2 +- tasks/task_save.c | 16 ++++++++-------- 11 files changed, 30 insertions(+), 30 deletions(-) diff --git a/config.def.h b/config.def.h index 038ab6438813..4ea28df30394 100644 --- a/config.def.h +++ b/config.def.h @@ -1440,10 +1440,10 @@ * It is measured in seconds. A value of 0 disables automatic savestate saving. */ #if defined(__i386__) || defined(__i486__) || defined(__i686__) || defined(__x86_64__) || defined(_M_X64) || defined(_WIN32) || defined(OSX) || defined(ANDROID) || defined(IOS) || defined(DINGUX) /* Disabled by default but can be enabled by user */ -#define DEFAULT_AUTOMATIC_SAVESTATE_INTERVAL 0 +#define DEFAULT_SAVESTATE_AUTOMATIC_INTERVAL 0 #else /* Default to disabled on I/O-constrained platforms */ -#define DEFAULT_AUTOMATIC_SAVESTATE_INTERVAL 0 +#define DEFAULT_SAVESTATE_AUTOMATIC_INTERVAL 0 #endif /* Take screenshots for save states */ diff --git a/configuration.c b/configuration.c index 930c54df7af2..6bd776eb4e33 100644 --- a/configuration.c +++ b/configuration.c @@ -2461,7 +2461,7 @@ static struct config_uint_setting *populate_settings_uint( SETTING_UINT("memory_update_interval", &settings->uints.memory_update_interval, true, DEFAULT_MEMORY_UPDATE_INTERVAL, false); SETTING_UINT("core_updater_auto_backup_history_size", &settings->uints.core_updater_auto_backup_history_size, true, DEFAULT_CORE_UPDATER_AUTO_BACKUP_HISTORY_SIZE, false); SETTING_UINT("autosave_interval", &settings->uints.autosave_interval, true, DEFAULT_AUTOSAVE_INTERVAL, false); - SETTING_UINT("automatic_savestate_interval", &settings->uints.automatic_savestate_interval, true, DEFAULT_AUTOMATIC_SAVESTATE_INTERVAL, false); + SETTING_UINT("savestate_automatic_interval", &settings->uints.savestate_automatic_interval, true, DEFAULT_SAVESTATE_AUTOMATIC_INTERVAL, false); 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("run_ahead_frames", &settings->uints.run_ahead_frames, true, 1, false); diff --git a/configuration.h b/configuration.h index 4b98d0d78194..f234bc0f6ec5 100644 --- a/configuration.h +++ b/configuration.h @@ -242,7 +242,7 @@ typedef struct settings unsigned rewind_granularity; unsigned rewind_buffer_size_step; unsigned autosave_interval; - unsigned automatic_savestate_interval; + unsigned savestate_automatic_interval; unsigned replay_checkpoint_interval; unsigned replay_max_keep; unsigned savestate_max_keep; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 2ac2f488aafc..5eaea0551feb 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -393,8 +393,8 @@ MSG_HASH( MENU_ENUM_LABEL_AUTOSAVE_INTERVAL_STR ) MSG_HASH( - MENU_ENUM_LABEL_AUTOMATIC_SAVESTATE_INTERVAL, - MENU_ENUM_LABEL_AUTOMATIC_SAVESTATE_INTERVAL_STR + MENU_ENUM_LABEL_SAVESTATE_AUTOMATIC_INTERVAL, + MENU_ENUM_LABEL_SAVESTATE_AUTOMATIC_INTERVAL_STR ) MSG_HASH( MENU_ENUM_LABEL_REPLAY_CHECKPOINT_INTERVAL, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 6cf00e9b066a..aa296c00feab 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -4780,16 +4780,16 @@ MSG_HASH( "Autosaves the non-volatile SRAM at a regular interval. This is disabled by default unless set otherwise. The interval is measured in seconds. A value of 0 disables autosave." ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTOMATIC_SAVESTATE_INTERVAL, - "Automatic Savestate Interval" + MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTOMATIC_INTERVAL, + "Save State: Automatic Interval" ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUTOMATIC_SAVESTATE_INTERVAL, - "Automatically save a savestate at a regular interval (in seconds). Set to 0 to disable." + MENU_ENUM_SUBLABEL_SAVESTATE_AUTOMATIC_INTERVAL, + "Automatically save a state at a regular interval (in seconds). Set to 0 to disable." ) MSG_HASH( - MENU_ENUM_LABEL_HELP_AUTOMATIC_SAVESTATE_INTERVAL, - "Automatically saves a savestate at regular intervals. This is useful for creating periodic backups of your game progress. The interval is measured in seconds. A value of 0 disables automatic savestate saving." + MENU_ENUM_LABEL_HELP_SAVESTATE_AUTOMATIC_INTERVAL, + "Automatically saves a state at a regular interval, measured in seconds. This is useful for creating periodic backups of your game progress, especially on devices that may close unexpectedly due to battery or other issues. A value of 0 disables this feature." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_REPLAY_CHECKPOINT_INTERVAL, diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 05883751cb45..c1aad757caf7 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -825,7 +825,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_save_file_compression, MENU_ 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_automatic_savestate_interval, MENU_ENUM_SUBLABEL_AUTOMATIC_SAVESTATE_INTERVAL) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_savestate_automatic_interval, MENU_ENUM_SUBLABEL_SAVESTATE_AUTOMATIC_INTERVAL) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_replay_max_keep, MENU_ENUM_SUBLABEL_REPLAY_MAX_KEEP) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_replay_checkpoint_interval, MENU_ENUM_SUBLABEL_REPLAY_CHECKPOINT_INTERVAL) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_replay_checkpoint_deserialize, MENU_ENUM_SUBLABEL_REPLAY_CHECKPOINT_DESERIALIZE) @@ -4108,8 +4108,8 @@ 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_AUTOMATIC_SAVESTATE_INTERVAL: - BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_automatic_savestate_interval); + case MENU_ENUM_LABEL_SAVESTATE_AUTOMATIC_INTERVAL: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_savestate_automatic_interval); break; case MENU_ENUM_LABEL_REPLAY_CHECKPOINT_INTERVAL: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_replay_checkpoint_interval); diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index bf2f682af8d6..544921d4ff77 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -11138,7 +11138,7 @@ unsigned menu_displaylist_build_list( {MENU_ENUM_LABEL_SORT_SAVEFILES_BY_CONTENT_ENABLE, PARSE_ONLY_BOOL, true}, {MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL, true}, {MENU_ENUM_LABEL_AUTOSAVE_INTERVAL, PARSE_ONLY_UINT, true}, - {MENU_ENUM_LABEL_AUTOMATIC_SAVESTATE_INTERVAL, PARSE_ONLY_UINT, true}, + {MENU_ENUM_LABEL_SAVESTATE_AUTOMATIC_INTERVAL, PARSE_ONLY_UINT, true}, {MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE, PARSE_ONLY_BOOL, true}, #if defined(HAVE_ZLIB) {MENU_ENUM_LABEL_SAVE_FILE_COMPRESSION, PARSE_ONLY_BOOL, true}, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 34f69c037b18..14e8a7d1560b 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -12010,10 +12010,10 @@ static bool setting_append_list( #ifdef HAVE_THREADS CONFIG_UINT( list, list_info, - &settings->uints.automatic_savestate_interval, - MENU_ENUM_LABEL_AUTOMATIC_SAVESTATE_INTERVAL, - MENU_ENUM_LABEL_VALUE_AUTOMATIC_SAVESTATE_INTERVAL, - DEFAULT_AUTOMATIC_SAVESTATE_INTERVAL, + &settings->uints.savestate_automatic_interval, + MENU_ENUM_LABEL_SAVESTATE_AUTOMATIC_INTERVAL, + MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTOMATIC_INTERVAL, + DEFAULT_SAVESTATE_AUTOMATIC_INTERVAL, &group_info, &subgroup_info, parent_group, diff --git a/msg_hash.h b/msg_hash.h index b5ab3c57f728..c35cf1e7393b 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -2546,7 +2546,7 @@ enum msg_hash_enums MENU_LABEL(FRONTEND_LOG_LEVEL), MENU_LBL_H(LIBRETRO_LOG_LEVEL), MENU_LBL_H(AUTOSAVE_INTERVAL), - MENU_LBL_H(AUTOMATIC_SAVESTATE_INTERVAL), + MENU_LBL_H(SAVESTATE_AUTOMATIC_INTERVAL), MENU_LBL_H(REPLAY_CHECKPOINT_INTERVAL), MENU_LBL_H(REPLAY_CHECKPOINT_DESERIALIZE), MENU_LBL_H(CONFIG_SAVE_ON_EXIT), diff --git a/msg_hash_lbl_str.h b/msg_hash_lbl_str.h index 11cce45f22ca..d0ceefd13b86 100644 --- a/msg_hash_lbl_str.h +++ b/msg_hash_lbl_str.h @@ -107,7 +107,7 @@ #define MENU_ENUM_LABEL_MICROPHONE_WASAPI_SH_BUFFER_LENGTH_STR "microphone_wasapi_sh_buffer_length" #define MENU_ENUM_LABEL_MICROPHONE_RESAMPLER_QUALITY_STR "microphone_resampler_quality" #define MENU_ENUM_LABEL_AUTOSAVE_INTERVAL_STR "autosave_interval" -#define MENU_ENUM_LABEL_AUTOMATIC_SAVESTATE_INTERVAL_STR "automatic_savestate_interval" +#define MENU_ENUM_LABEL_SAVESTATE_AUTOMATIC_INTERVAL_STR "savestate_automatic_interval" #define MENU_ENUM_LABEL_REPLAY_CHECKPOINT_INTERVAL_STR "replay_checkpoint_interval" #define MENU_ENUM_LABEL_REPLAY_CHECKPOINT_DESERIALIZE_STR "replay_checkpoint_deserialize" #define MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE_STR "auto_overrides_enable" diff --git a/tasks/task_save.c b/tasks/task_save.c index 0a5bb810f5df..1aeec1c77174 100644 --- a/tasks/task_save.c +++ b/tasks/task_save.c @@ -136,7 +136,7 @@ static bool save_state_in_background = false; static bool save_state_disable_undo = false; /* Time tracking for automatic savestate interval */ -static time_t last_automatic_savestate_time = 0; +static time_t last_savestate_automatic_time = 0; typedef struct rastate_size_info { @@ -1891,19 +1891,19 @@ bool content_save_state_automatic(void) time_t current_time; char savestate_path[PATH_MAX_LENGTH]; settings_t *settings = config_get_ptr(); - unsigned automatic_savestate_interval = - settings->uints.automatic_savestate_interval; + unsigned savestate_automatic_interval = + settings->uints.savestate_automatic_interval; /* Return early if automatic savestate is disabled, - safety checks already happen in content_save_state() */ - if (automatic_savestate_interval == 0) + safety checks already happen in content_auto_save_state() */ + if (savestate_automatic_interval == 0) return false; current_time = time(NULL); /* Check how long since last autosavestate */ - if ((current_time - last_automatic_savestate_time) < - (time_t)automatic_savestate_interval) + if ((current_time - last_savestate_automatic_time) < + (time_t)savestate_automatic_interval) return false; /* Generate the savestate path */ @@ -1921,7 +1921,7 @@ bool content_save_state_automatic(void) savestate_path); /* Update the last savestate time, rinse/repeat */ - last_automatic_savestate_time = current_time; + last_savestate_automatic_time = current_time; return content_auto_save_state(savestate_path); }