From a4e6e84a0a7e8cb307b166900636f455d428b554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 9 Apr 2025 18:07:13 +0200 Subject: [PATCH] Move achievement handling to EmuScreen and the main thread. Fixes black screen. --- Core/RetroAchievements.cpp | 5 +++++ Core/System.cpp | 25 +++++++++++-------------- Core/System.h | 1 + UI/EmuScreen.cpp | 15 +++++++++++++-- UI/EmuScreen.h | 2 +- 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/Core/RetroAchievements.cpp b/Core/RetroAchievements.cpp index 3ad961b140..3f5eaf7c71 100644 --- a/Core/RetroAchievements.cpp +++ b/Core/RetroAchievements.cpp @@ -999,6 +999,11 @@ void SetGame(const Path &path, IdentifiedFileType fileType, FileLoader *fileLoad return; } + if (!fileLoader) { + ERROR_LOG(Log::Achievements, "File loader not initialized"); + return; + } + // The caller should hold off on executing game code until this turns false, checking with IsBlockingExecution() g_gamePath = path; g_isIdentifying = true; diff --git a/Core/System.cpp b/Core/System.cpp index 26d1315654..3d142aa9b9 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -42,7 +42,6 @@ #include "Common/TimeUtil.h" #include "Common/Thread/ThreadUtil.h" #include "Common/GraphicsContext.h" -#include "Core/RetroAchievements.h" #include "Core/MemFault.h" #include "Core/HDRemaster.h" #include "Core/MIPS/MIPS.h" @@ -101,6 +100,10 @@ BootState PSP_GetBootState() { return g_bootState; } +FileLoader *PSP_LoadedFile() { + return g_loadedFile; +} + void ResetUIState() { globalUIState = UISTATE_MENU; } @@ -276,6 +279,7 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin case IdentifiedFileType::PSP_ISO: case IdentifiedFileType::PSP_ISO_NP: case IdentifiedFileType::PSP_DISC_DIRECTORY: + // Doesn't seem to take ownership of fileLoader? if (!MountGameISO(fileLoader)) { *errorString = "Failed to mount ISO file - invalid format?"; return false; @@ -509,7 +513,7 @@ void PSP_ForceDebugStats(bool enable) { bool PSP_InitStart(const CoreParameter &coreParam) { if (g_bootState != BootState::Off) { - ERROR_LOG(Log::System, "Can't start loader thread - already on."); + ERROR_LOG(Log::Loader, "Can't start loader thread - already on."); return false; } @@ -524,7 +528,7 @@ bool PSP_InitStart(const CoreParameter &coreParam) { std::string *error_string = &g_CoreParameter.errorString; - INFO_LOG(Log::System, "Starting loader thread..."); + INFO_LOG(Log::Loader, "Starting loader thread..."); _dbg_assert_(!g_loadingThread.joinable()); @@ -551,17 +555,12 @@ bool PSP_InitStart(const CoreParameter &coreParam) { loadedFile = new RamCachingFileLoader(loadedFile); break; default: - INFO_LOG(Log::System, "RAM caching is on, but file is not an ISO, so ignoring"); + INFO_LOG(Log::Loader, "RAM caching is on, but file is not an ISO, so ignoring"); break; } } } - if (g_Config.bAchievementsEnable) { - std::string errorString; - Achievements::SetGame(filename, type, loadedFile); - } - // TODO: The reason we pass in g_CoreParameter.errorString here is that it's persistent - // it gets written to from the loader thread that gets spawned. if (!CPU_Init(loadedFile, type, &g_CoreParameter.errorString)) { @@ -602,7 +601,7 @@ BootState PSP_InitUpdate(std::string *error_string) { // Ok, async boot completed, let's finish up things on the main thread. if (!gpu) { // should be! - INFO_LOG(Log::System, "Starting graphics..."); + INFO_LOG(Log::Loader, "Starting graphics..."); Draw::DrawContext *draw = g_CoreParameter.graphicsContext ? g_CoreParameter.graphicsContext->GetDrawContext() : nullptr; // This set the `gpu` global. bool success = GPU_Init(g_CoreParameter.graphicsContext, draw); @@ -645,8 +644,6 @@ void PSP_Shutdown(bool success) { // Reduce the risk for weird races with the Windows GE debugger. gpuDebug = nullptr; - Achievements::UnloadGame(); - // Do nothing if we never inited. if (g_bootState == BootState::Off) { return; @@ -846,11 +843,11 @@ void DumpFileIfEnabled(const u8 *dataPtr, const u32 length, std::string_view nam return; } if (!dataPtr) { - ERROR_LOG(Log::System, "Error dumping %s: invalid pointer", DumpFileTypeToString(DumpFileType::EBOOT)); + ERROR_LOG(Log::Loader, "Error dumping %s: invalid pointer", DumpFileTypeToString(DumpFileType::EBOOT)); return; } if (length == 0) { - ERROR_LOG(Log::System, "Error dumping %s: invalid length", DumpFileTypeToString(DumpFileType::EBOOT)); + ERROR_LOG(Log::Loader, "Error dumping %s: invalid length", DumpFileTypeToString(DumpFileType::EBOOT)); return; } diff --git a/Core/System.h b/Core/System.h index 9f7bb84bb5..a3e9aa1178 100644 --- a/Core/System.h +++ b/Core/System.h @@ -102,6 +102,7 @@ void PSP_CancelBoot(); void PSP_Shutdown(bool success); BootState PSP_Reboot(std::string *error_string); +FileLoader *PSP_LoadedFile(); void PSP_BeginHostFrame(); void PSP_EndHostFrame(); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index e1cf4c0696..9f0b5153eb 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -357,6 +357,12 @@ void EmuScreen::ProcessGameBoot(const Path &filename) { // Only call this on successful boot. void EmuScreen::bootComplete() { + // Initialize retroachievements, now that we're on the right thread. + if (g_Config.bAchievementsEnable) { + std::string errorString; + Achievements::SetGame(PSP_CoreParameter().fileToStart, PSP_CoreParameter().fileType, PSP_LoadedFile()); + } + // We don't want to boot with the wrong game specific config, so wait until info is ready. // TODO: Actually, we read this info again during bootup, so this is not really necessary. auto sc = GetI18NCategory(I18NCat::SCREEN); @@ -382,7 +388,7 @@ void EmuScreen::bootComplete() { NOTICE_LOG(Log::Boot, "Booted %s...", PSP_CoreParameter().fileToStart.c_str()); if (!Achievements::HardcoreModeActive()) { // Don't auto-load savestates in hardcore mode. - autoLoad(); + AutoLoadSaveState(); } #ifndef MOBILE_DEVICE @@ -445,6 +451,7 @@ EmuScreen::~EmuScreen() { _dbg_assert_(!bootPending_); if (!bootPending_) { PSP_Shutdown(true); + Achievements::UnloadGame(); } _dbg_assert_(coreState == CORE_POWERDOWN); @@ -538,6 +545,7 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) { return; } PSP_Shutdown(true); + Achievements::UnloadGame(); bootPending_ = false; System_Notify(SystemNotification::DISASSEMBLY); } else if (message == UIMessage::REQUEST_GAME_RESET) { @@ -546,6 +554,7 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) { return; } PSP_Shutdown(true); + Achievements::UnloadGame(); bootPending_ = true; _dbg_assert_(coreState == CORE_POWERDOWN); if (!PSP_InitStart(PSP_CoreParameter())) { @@ -568,6 +577,7 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) { SaveState::Load(Path(value), -1, &AfterStateBoot); } else { PSP_Shutdown(true); + Achievements::UnloadGame(); bootPending_ = true; gamePath_ = Path(value); } @@ -1441,6 +1451,7 @@ bool EmuScreen::checkPowerDown() { bool shutdown = false; if (PSP_IsInited()) { PSP_Shutdown(true); + Achievements::UnloadGame(); shutdown = true; } INFO_LOG(Log::System, "SELF-POWERDOWN!"); @@ -1922,7 +1933,7 @@ void EmuScreen::renderUI() { ctx->Flush(); } -void EmuScreen::autoLoad() { +void EmuScreen::AutoLoadSaveState() { int autoSlot = -1; //check if save state has save, if so, load diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index b39a739891..a18d2866c6 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -89,7 +89,7 @@ private: void onVKey(VirtKey virtualKeyCode, bool down); void onVKeyAnalog(VirtKey virtualKeyCode, float value); - void autoLoad(); + void AutoLoadSaveState(); bool checkPowerDown(); void ProcessQueuedVKeys();