From dac8ccff1db4e8809ee5cf6d864cac820da39c7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 23 Feb 2026 11:48:34 +0100 Subject: [PATCH] Gamescreen: Reload savedataSize on open --- UI/GameInfoCache.cpp | 29 +++++++++++++++++++++-------- UI/GameInfoCache.h | 3 ++- UI/GameScreen.cpp | 10 ++++++++-- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index ec9620a9e3..6b55006961 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -907,24 +907,30 @@ handleELF: u64 saveDataSize = 0; u64 installDataSize = 0; + std::lock_guard lock(info_->lock); + info_->gameSizeOnDisk = gameSizeOnDisk; + info_->saveDataSize = saveDataSize; + info_->installDataSize = installDataSize; + } + + if (flags_ & GameInfoFlags::SAVEDATA_SIZE) { switch (info_->fileType) { case IdentifiedFileType::PSP_ISO: case IdentifiedFileType::PSP_ISO_NP: case IdentifiedFileType::PSP_DISC_DIRECTORY: case IdentifiedFileType::PSP_PBP: case IdentifiedFileType::PSP_PBP_DIRECTORY: - saveDataSize = info_->GetGameSavedataSizeInBytes(); - installDataSize = info_->GetInstallDataSizeInBytes(); + { + std::lock_guard lock(info_->lock); + info_->saveDataSize = info_->GetGameSavedataSizeInBytes(); + info_->installDataSize = info_->GetInstallDataSizeInBytes(); break; + } default: break; } - - std::lock_guard lock(info_->lock); - info_->gameSizeOnDisk = gameSizeOnDisk; - info_->saveDataSize = saveDataSize; - info_->installDataSize = installDataSize; } + if (flags_ & GameInfoFlags::UNCOMPRESSED_SIZE) { info_->gameSizeUncompressed = info_->GetSizeUncompressedInBytes(); } @@ -1038,12 +1044,13 @@ void GameInfoCache::PurgeType(IdentifiedFileType fileType) { // Call on the main thread ONLY - that is from stuff called from NativeFrame. // Can also be called from the audio thread for menu background music, but that cannot request images! -std::shared_ptr GameInfoCache::GetInfo(Draw::DrawContext *draw, const Path &gamePath, GameInfoFlags wantFlags, GameInfoFlags *outHasFlags) { +std::shared_ptr GameInfoCache::GetInfo(Draw::DrawContext *draw, const Path &gamePath, GameInfoFlags wantFlags, GameInfoFlags *outHasFlags, GameInfoFlags refetchFlags) { const std::string &pathStr = gamePath.ToString(); // _dbg_assert_(gamePath != GetSysDirectory(DIRECTORY_SAVEDATA)); // This is always needed to determine the method to get the other info, so make sure it's computed first. + wantFlags |= GameInfoFlags::FILE_TYPE; mapLock_.lock(); @@ -1056,10 +1063,15 @@ std::shared_ptr GameInfoCache::GetInfo(Draw::DrawContext *draw, const info->FinishPendingTextureLoads(draw); info->lastAccessedTime = time_now_d(); + GameInfoFlags wanted = (GameInfoFlags)0; { // Careful now! std::unique_lock lock(info->lock); + if (refetchFlags != GameInfoFlags::EMPTY) { + // Forget some flags! + info->hasFlags &= ~refetchFlags; + } GameInfoFlags willHaveFlags = info->hasFlags | info->pendingFlags; // We don't want to re-fetch data that we have, so or in pendingFlags. wanted = (GameInfoFlags)((int)wantFlags & ~(int)willHaveFlags); // & is reserved for testing so we have to cast to int. ugh. info->pendingFlags |= wanted; @@ -1067,6 +1079,7 @@ std::shared_ptr GameInfoCache::GetInfo(Draw::DrawContext *draw, const *outHasFlags = info->hasFlags; } } + if (wanted != (GameInfoFlags)0) { // We're missing info that we want. Go get it! GameInfoWorkItem *item = new GameInfoWorkItem(gamePath, info, wanted); diff --git a/UI/GameInfoCache.h b/UI/GameInfoCache.h index 09bfb7ffb2..362ecfd1e8 100644 --- a/UI/GameInfoCache.h +++ b/UI/GameInfoCache.h @@ -48,6 +48,7 @@ enum class GameInfoFlags { SND = 0x20, SIZE = 0x40, UNCOMPRESSED_SIZE = 0x80, + SAVEDATA_SIZE = 0x100, }; ENUM_CLASS_BITOPS(GameInfoFlags); @@ -200,7 +201,7 @@ public: // because they're big. bgTextures and sound may be discarded over time as well. // NOTE: This never returns null, so you don't need to check for that. Do check Ready() flags though. // It's OK to pass in nullptr for draw if you don't need the actual texture right now. - std::shared_ptr GetInfo(Draw::DrawContext *draw, const Path &gamePath, GameInfoFlags wantFlags, GameInfoFlags *outHasFlags = nullptr); + std::shared_ptr GetInfo(Draw::DrawContext *draw, const Path &gamePath, GameInfoFlags wantFlags, GameInfoFlags *outHasFlags = nullptr, GameInfoFlags refetchFlags = GameInfoFlags::EMPTY); void FlushBGs(); // Gets rid of all BG textures. Also gets rid of bg sounds. void CancelAll(); diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index f9199644e6..76e620b1d8 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -56,13 +56,16 @@ #include "UI/SavedataScreen.h" #include "UI/MiscViews.h" -constexpr GameInfoFlags g_desiredFlags = GameInfoFlags::PARAM_SFO | GameInfoFlags::ICON | GameInfoFlags::PIC0 | GameInfoFlags::PIC1 | GameInfoFlags::UNCOMPRESSED_SIZE | GameInfoFlags::SIZE; +constexpr GameInfoFlags g_desiredFlags = GameInfoFlags::PARAM_SFO | GameInfoFlags::ICON | GameInfoFlags::PIC0 | GameInfoFlags::PIC1 | GameInfoFlags::UNCOMPRESSED_SIZE | GameInfoFlags::SIZE | GameInfoFlags::SAVEDATA_SIZE; GameScreen::GameScreen(const Path &gamePath, bool inGame) : UITwoPaneBaseDialogScreen(gamePath, TwoPaneFlags::SettingsToTheRight | TwoPaneFlags::CustomContextMenu), inGame_(inGame) { g_BackgroundAudio.SetGame(gamePath); System_PostUIMessage(UIMessage::GAME_SELECTED, gamePath.ToString()); - info_ = g_gameInfoCache->GetInfo(NULL, gamePath_, g_desiredFlags, &knownFlags_); + // We want to re-fetch savedata size when opening this screen. + constexpr GameInfoFlags refetchFlags = GameInfoFlags::SAVEDATA_SIZE; + + info_ = g_gameInfoCache->GetInfo(NULL, gamePath_, g_desiredFlags, &knownFlags_, refetchFlags); } GameScreen::~GameScreen() { @@ -252,7 +255,10 @@ void GameScreen::CreateContentViews(UI::ViewGroup *parent) { } TextView *tvGameSize = mainGameInfo->Add(new TextView(temp, ALIGN_LEFT, true, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); tvGameSize->SetShadow(true); + } + if ((knownFlags_ & GameInfoFlags::SAVEDATA_SIZE)) { + char temp[256]; if (info_->saveDataSize > 0) { snprintf(temp, sizeof(temp), "%s: %s", ga->T_cstr("SaveData"), NiceSizeFormat(info_->saveDataSize).c_str()); TextView *tvSaveDataSize = infoLayout->Add(new TextView(temp, ALIGN_LEFT, true, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));