From 938029cd6aeb677edf4f4f26b0461dc31a5b0506 Mon Sep 17 00:00:00 2001 From: Eloren1 Date: Sun, 31 May 2026 21:55:06 +0300 Subject: [PATCH] Add screenshots + extract LoadStateConfirmScreen --- UI/EmuScreen.cpp | 13 +++---------- UI/LoadStateConfirmScreen.cpp | 33 +++++++++++++++++++++++++++++++++ UI/LoadStateConfirmScreen.h | 22 ++++++++++++++++++++++ UI/PauseScreen.cpp | 11 ++++------- UI/UI.vcxproj | 2 ++ 5 files changed, 64 insertions(+), 17 deletions(-) create mode 100644 UI/LoadStateConfirmScreen.cpp create mode 100644 UI/LoadStateConfirmScreen.h diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index bce8eff595..8cab0ee3d5 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -76,10 +76,10 @@ using namespace std::placeholders; #include "Core/HLE/__sceAudio.h" #include "Core/HW/Display.h" -#include "Common/UI/PopupScreens.h" #include "UI/BackgroundAudio.h" #include "UI/GamepadEmu.h" #include "UI/PauseScreen.h" +#include "UI/LoadStateConfirmScreen.h" #include "UI/MainScreen.h" #include "UI/Background.h" #include "UI/EmuScreen.h" @@ -509,7 +509,7 @@ EmuScreen::~EmuScreen() { void EmuScreen::dialogFinished(const Screen *dialog, DialogResult result) { std::string_view tag = dialog->tag(); - if (tag == "TextEditPopup") { + if (tag == "TextEditPopup" || tag == "LoadStateConfirm") { // Chat message finished. return; } @@ -1058,16 +1058,9 @@ void EmuScreen::ProcessVKey(VirtKey virtKey) { case VIRTKEY_LOAD_STATE: if (!Achievements::WarnUserIfHardcoreModeActive(false) && !NetworkWarnUserIfOnlineAndCantSavestate() && !bootPending_) { if (g_Config.bConfirmLoadState) { - auto pa = GetI18NCategory(I18NCat::PAUSE); - auto di = GetI18NCategory(I18NCat::DIALOG); std::string prefix = SaveState::GetGamePrefix(g_paramSFO); int slot = g_Config.iCurrentStateSlot; - std::string message(di->T("ConfirmLoadState")); - std::string dateStr = SaveState::GetSlotDateAsString(prefix, slot); - if (!dateStr.empty()) { - message += "\n\n" + dateStr; - } - screenManager()->push(new UI::MessagePopupScreen(pa->T("Load State"), message, pa->T("Load State"), di->T("Cancel"), [prefix, slot](bool result) { + screenManager()->push(new LoadStateConfirmScreen(prefix, slot, [prefix, slot](bool result) { if (result) { SaveState::LoadSlot(prefix, slot, &ShowMessageAfterSaveStateAction); } diff --git a/UI/LoadStateConfirmScreen.cpp b/UI/LoadStateConfirmScreen.cpp new file mode 100644 index 0000000000..d8ea3ada1f --- /dev/null +++ b/UI/LoadStateConfirmScreen.cpp @@ -0,0 +1,33 @@ +#include "UI/LoadStateConfirmScreen.h" + +#include "Common/UI/AsyncImageFileView.h" +#include "Common/UI/ViewGroup.h" +#include "Common/Data/Text/I18n.h" +#include "Core/SaveState.h" + +LoadStateConfirmScreen::LoadStateConfirmScreen(std::string_view saveStatePrefix, int slot, std::function callback) + : UI::PopupScreen(GetI18NCategory(I18NCat::PAUSE)->T("Load State"), + GetI18NCategory(I18NCat::PAUSE)->T("Load State"), + GetI18NCategory(I18NCat::DIALOG)->T("Cancel")), + saveStatePrefix_(saveStatePrefix), slot_(slot), callback_(callback) { + screenshotFilename_ = SaveState::GenerateSaveSlotPath(saveStatePrefix_, slot_, SaveState::SCREENSHOT_EXTENSION); +} + +void LoadStateConfirmScreen::CreatePopupContents(UI::ViewGroup *parent) { + using namespace UI; + auto di = GetI18NCategory(I18NCat::DIALOG); + // 480:272 PSP ratio; at default popup width 550, effective area ~510 → height ~289 + parent->Add(new AsyncImageFileView(screenshotFilename_, IS_KEEP_ASPECT, + new LinearLayoutParams(FILL_PARENT, 289.0f))); + std::string dateStr = SaveState::GetSlotDateAsString(saveStatePrefix_, slot_); + if (!dateStr.empty()) { + parent->Add(new TextView(dateStr, ALIGN_HCENTER, false, + new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, Margins(0, 4)))); + } + parent->Add(new TextView(di->T("ConfirmLoadState"), ALIGN_HCENTER | FLAG_WRAP_TEXT, false, + new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, Margins(0, 8)))); +} + +void LoadStateConfirmScreen::OnCompleted(DialogResult result) { + if (callback_) callback_(result == DR_OK); +} diff --git a/UI/LoadStateConfirmScreen.h b/UI/LoadStateConfirmScreen.h new file mode 100644 index 0000000000..9491998b2c --- /dev/null +++ b/UI/LoadStateConfirmScreen.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include + +#include "Common/File/Path.h" +#include "Common/UI/PopupScreens.h" + +class LoadStateConfirmScreen : public UI::PopupScreen { +public: + LoadStateConfirmScreen(std::string_view saveStatePrefix, int slot, std::function callback); + const char *tag() const override { return "LoadStateConfirm"; } + void CreatePopupContents(UI::ViewGroup *parent) override; +protected: + void OnCompleted(DialogResult result) override; +private: + std::string saveStatePrefix_; + int slot_; + Path screenshotFilename_; + std::function callback_; +}; diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 8d1bb5a597..f32673aea0 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -57,6 +57,7 @@ #include "UI/EmuScreen.h" #include "UI/PauseScreen.h" +#include "UI/LoadStateConfirmScreen.h" #include "UI/GameSettingsScreen.h" #include "UI/ReportScreen.h" #include "UI/CwCheatScreen.h" @@ -162,9 +163,7 @@ void ScreenshotViewScreen::OnLoadState(UI::EventParams &e) { if (!NetworkWarnUserIfOnlineAndCantSavestate()) { g_Config.iCurrentStateSlot = slot_; 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) { + screenManager()->push(new LoadStateConfirmScreen(saveStatePrefix_, slot_, [this](bool result) { if (result) { SaveState::LoadSlot(saveStatePrefix_, slot_, &ShowMessageAfterSaveStateAction); TriggerFinish(DR_OK); @@ -414,9 +413,7 @@ void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems, finishNextFrameResult_ = 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) { + screenManager()->push(new LoadStateConfirmScreen(saveStatePrefix_, slotNum, [doLoad](bool result) { if (result) doLoad(); })); } else { @@ -832,7 +829,7 @@ void GamePauseScreen::dialogFinished(const Screen *dialog, DialogResult dr) { } else { if (tag == "Game") { g_BackgroundAudio.SetGame(Path()); - } else if (tag != "MessagePopupScreen" && tag != "Prompt" && tag != "ContextMenuPopup" && tag != "ContextMenuCallbackPopup" && tag != "Report" && tag != "listpopup") { + } else if (tag != "MessagePopupScreen" && tag != "Prompt" && tag != "ContextMenuPopup" && tag != "ContextMenuCallbackPopup" && tag != "Report" && tag != "listpopup" && tag != "LoadStateConfirm") { // Maybe should invert the logic here, so many cases.. // There may have been changes to our savestates, so let's recreate. SaveState::Rescan(saveStatePrefix_); diff --git a/UI/UI.vcxproj b/UI/UI.vcxproj index 2af2cbc0ff..e998fe5a5d 100644 --- a/UI/UI.vcxproj +++ b/UI/UI.vcxproj @@ -58,6 +58,7 @@ + @@ -117,6 +118,7 @@ +