From 23aef44ae17f33bff0a6a6db760459faf7521580 Mon Sep 17 00:00:00 2001 From: Eloren1 Date: Sun, 31 May 2026 19:15:31 +0300 Subject: [PATCH] UI: Add load state confirmation option --- Core/Config.cpp | 1 + Core/Config.h | 1 + UI/GameSettingsScreen.cpp | 1 + UI/PauseScreen.cpp | 36 ++++++++++++++++++++++++++++++++---- assets/lang/en_US.ini | 2 ++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 81304f6b0a..9b126f78bb 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -267,6 +267,7 @@ static const ConfigSetting generalSettings[] = { ConfigSetting("SaveLoadResetsAVdumping", SETTING(g_Config, bSaveLoadResetsAVdumping), false, CfgFlag::DEFAULT), ConfigSetting("StateSlot", SETTING(g_Config, iCurrentStateSlot), 0, CfgFlag::PER_GAME), ConfigSetting("EnableStateUndo", SETTING(g_Config, bEnableStateUndo), &DefaultEnableStateUndo, CfgFlag::PER_GAME), + ConfigSetting("ConfirmLoadState", SETTING(g_Config, bConfirmLoadState), false, CfgFlag::DEFAULT), ConfigSetting("StateLoadUndoGame", SETTING(g_Config, sStateLoadUndoGame), "NA", CfgFlag::DEFAULT), ConfigSetting("StateUndoLastSaveGame", SETTING(g_Config, sStateUndoLastSaveGame), "NA", CfgFlag::DEFAULT), ConfigSetting("StateUndoLastSaveSlot", SETTING(g_Config, iStateUndoLastSaveSlot), -5, CfgFlag::DEFAULT), // Start with an "invalid" value diff --git a/Core/Config.h b/Core/Config.h index 38a1b25472..100bcbd37d 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -346,6 +346,7 @@ public: int iRewindSnapshotInterval; bool bUISound; bool bEnableStateUndo; + bool bConfirmLoadState; std::string sStateLoadUndoGame; std::string sStateUndoLastSaveGame; int iStateUndoLastSaveSlot; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index c789a09a55..d184d83c69 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -1390,6 +1390,7 @@ void GameSettingsScreen::CreateSystemSettings(UI::ViewGroup *systemSettings) { systemSettings->Add(new ItemHeader(sa->T("Save states"))); // Borrow this string from the savedata manager systemSettings->Add(new CheckBox(&g_Config.bEnableStateUndo, sy->T("Savestate slot backups"))); + systemSettings->Add(new CheckBox(&g_Config.bConfirmLoadState, sy->T("Ask to confirm on load"))); PopupSliderChoice* savestateSlotCount = systemSettings->Add(new PopupSliderChoice(&g_Config.iSaveStateSlotCount, 1, 30, 5, sy->T("Savestate slot count"), screenManager())); savestateSlotCount->OnChange.Add([](UI::EventParams &e) { diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 802145d6c2..7b14b083d5 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -161,8 +161,19 @@ void ScreenshotViewScreen::OnSaveState(UI::EventParams &e) { void ScreenshotViewScreen::OnLoadState(UI::EventParams &e) { if (!NetworkWarnUserIfOnlineAndCantSavestate()) { g_Config.iCurrentStateSlot = slot_; - SaveState::LoadSlot(saveStatePrefix_, slot_, &ShowMessageAfterSaveStateAction); - TriggerFinish(DR_OK); + if (g_Config.bConfirmLoadState) { + auto pa = GetI18NCategory(I18NCat::PAUSE); + auto di = GetI18NCategory(I18NCat::DIALOG); + screenManager()->push(new UI::MessagePopupScreen(pa->T("Load State"), di->T("ConfirmLoadState"), pa->T("Load State"), di->T("Cancel"), [this](bool result) { + if (result) { + SaveState::LoadSlot(saveStatePrefix_, slot_, &ShowMessageAfterSaveStateAction); + TriggerFinish(DR_OK); + } + })); + } else { + SaveState::LoadSlot(saveStatePrefix_, slot_, &ShowMessageAfterSaveStateAction); + TriggerFinish(DR_OK); + } } } @@ -218,6 +229,7 @@ public: UI::Event OnStateSaved; UI::Event OnScreenshotClicked; UI::Event OnSelected; + UI::Event OnLoadRequested; private: void OnSaveState(UI::EventParams &e); @@ -303,10 +315,9 @@ void SaveSlotView::Draw(UIContext &dc) { void SaveSlotView::OnLoadState(UI::EventParams &e) { if (!NetworkWarnUserIfOnlineAndCantSavestate()) { g_Config.iCurrentStateSlot = slot_; - SaveState::LoadSlot(saveStatePrefix_, slot_, &ShowMessageAfterSaveStateAction); UI::EventParams e2{}; e2.v = this; - OnStateLoaded.Trigger(e2); + OnLoadRequested.Trigger(e2); } } @@ -394,6 +405,23 @@ void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems, SaveSlotView *slot = leftColumnItems->Add(new SaveSlotView(saveStatePrefix_, i, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, Gravity::G_HCENTER, Margins(0,0,0,0)))); slot->OnStateLoaded.Handle(this, &GamePauseScreen::OnState); slot->OnStateSaved.Handle(this, &GamePauseScreen::OnState); + slot->OnLoadRequested.Add([this](UI::EventParams &e) { + SaveSlotView *v = static_cast(e.v); + int slotNum = v->GetSlot(); + auto doLoad = [this, slotNum]() { + SaveState::LoadSlot(saveStatePrefix_, slotNum, &ShowMessageAfterSaveStateAction); + TriggerFinish(DR_CANCEL); + }; + if (g_Config.bConfirmLoadState) { + auto pa = GetI18NCategory(I18NCat::PAUSE); + auto di = GetI18NCategory(I18NCat::DIALOG); + screenManager()->push(new UI::MessagePopupScreen(pa->T("Load State"), di->T("ConfirmLoadState"), pa->T("Load State"), di->T("Cancel"), [doLoad](bool result) { + if (result) doLoad(); + })); + } else { + doLoad(); + } + }); slot->OnScreenshotClicked.Add([this](UI::EventParams &e) { SaveSlotView *v = static_cast(e.v); int slot = v->GetSlot(); diff --git a/assets/lang/en_US.ini b/assets/lang/en_US.ini index a2c2c53ee6..7115a86890 100644 --- a/assets/lang/en_US.ini +++ b/assets/lang/en_US.ini @@ -457,6 +457,7 @@ DeleteConfirmAll = Do you really want to delete all your save data for this game DeleteConfirmGame = Do you really want to delete this game from your device? You can't undo this. DeleteConfirmGameConfig = Do you really want to delete the settings for this game? DeleteConfirmSaveState = Are you sure you want to permanently delete this save state? +ConfirmLoadState = Are you sure you want to load this save state? DeleteFailed = Unable to delete data. Deleting = Deleting\nPlease wait... Details = Details @@ -1502,6 +1503,7 @@ Restore Default Settings = Restore PPSSPP's settings to default RetroAchievements = RetroAchievements Rewind Snapshot Interval = Rewind Snapshot Interval (mem hog) Savestate Slot = Savestate slot +Ask to confirm on load = Ask to confirm on load Savestate slot backups = Savestate slot backups Savestate slot count = Savestate slot count Screenshot mode = Screenshot mode