diff --git a/src/duckstation-qt/advancedsettingswidget.cpp b/src/duckstation-qt/advancedsettingswidget.cpp index 7eb30652c..cd1cc383f 100644 --- a/src/duckstation-qt/advancedsettingswidget.cpp +++ b/src/duckstation-qt/advancedsettingswidget.cpp @@ -198,6 +198,9 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(QtHostInterface* host_interface, addBooleanTweakOption(m_host_interface, m_ui.tweakOptionTable, tr("Allow Booting Without SBI File"), "CDROM", "AllowBootingWithoutSBIFile", false); + addBooleanTweakOption(m_host_interface, m_ui.tweakOptionTable, tr("Create Save State Backups"), "General", + "CreateSaveStateBackups", false); + dialog->registerWidgetHelp(m_ui.logLevel, tr("Log Level"), tr("Information"), tr("Sets the verbosity of messages logged. Higher levels will log more messages.")); dialog->registerWidgetHelp(m_ui.logToConsole, tr("Log To System Console"), tr("User Preference"), @@ -238,4 +241,5 @@ void AdvancedSettingsWidget::onResetToDefaultClicked() setBooleanTweakOption(m_ui.tweakOptionTable, 19, false); setBooleanTweakOption(m_ui.tweakOptionTable, 20, true); setBooleanTweakOption(m_ui.tweakOptionTable, 21, false); + setBooleanTweakOption(m_ui.tweakOptionTable, 22, false); } diff --git a/src/frontend-common/common_host_interface.cpp b/src/frontend-common/common_host_interface.cpp index bec087387..b13996480 100644 --- a/src/frontend-common/common_host_interface.cpp +++ b/src/frontend-common/common_host_interface.cpp @@ -789,6 +789,7 @@ bool CommonHostInterface::SaveState(bool global, s32 slot) } std::string save_path = global ? GetGlobalSaveStateFileName(slot) : GetGameSaveStateFileName(code.c_str(), slot); + RenameCurrentSaveStateToBackup(save_path.c_str()); if (!SaveState(save_path.c_str())) return false; @@ -2745,6 +2746,24 @@ std::string CommonHostInterface::GetGlobalSaveStateFileName(s32 slot) const return GetUserDirectoryRelativePath("savestates" FS_OSPATH_SEPARATOR_STR "savestate_%d.sav", slot); } +void CommonHostInterface::RenameCurrentSaveStateToBackup(const char* filename) +{ + if (!GetBoolSettingValue("General", "CreateSaveStateBackups", false)) + return; + + if (!FileSystem::FileExists(filename)) + return; + + const std::string backup_filename(FileSystem::ReplaceExtension(filename, "bak")); + if (!FileSystem::RenamePath(filename, backup_filename.c_str())) + { + Log_ErrorPrintf("Failed to rename save state backup '%s'", backup_filename.c_str()); + return; + } + + Log_InfoPrintf("Renamed save state '%s' to '%s'", filename, backup_filename.c_str()); +} + std::vector CommonHostInterface::GetAvailableSaveStates(const char* game_code) const { std::vector si; diff --git a/src/frontend-common/common_host_interface.h b/src/frontend-common/common_host_interface.h index 3daf1864f..73a44d15d 100644 --- a/src/frontend-common/common_host_interface.h +++ b/src/frontend-common/common_host_interface.h @@ -404,6 +404,9 @@ protected: /// Returns the path to a save state file. Specifying an index of -1 is the "resume" save state. std::string GetGlobalSaveStateFileName(s32 slot) const; + /// Moves the current save state file to a backup name, if it exists. + void RenameCurrentSaveStateToBackup(const char* filename); + /// Sets the base path for the user directory. Can be overridden by platform/frontend/command line. virtual void SetUserDirectory(); diff --git a/src/frontend-common/fullscreen_ui.cpp b/src/frontend-common/fullscreen_ui.cpp index 7ca956074..a56c99c9b 100644 --- a/src/frontend-common/fullscreen_ui.cpp +++ b/src/frontend-common/fullscreen_ui.cpp @@ -2526,6 +2526,14 @@ void DrawSettingsWindow() &s_settings_copy.increase_timer_resolution); #endif + settings_changed |= ToggleButtonForNonSetting("Allow Booting Without SBI File", + "Allows loading protected games without subchannel information.", + "CDROM", "AllowBootingWithoutSBIFile", false); + + settings_changed |= ToggleButtonForNonSetting("Create Save State Backups", + "Renames existing save states when saving to a backup file.", + "General", "CreateSaveStateBackups", false); + MenuHeading("Display Settings"); settings_changed |= ToggleButtonForNonSetting("Show Status Indicators", "Shows persistent icons when turbo is active or when paused.",