From a73b15b9630266376b90984fd531a45a381dfd0d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 19 Jan 2014 14:17:34 -0800 Subject: [PATCH] In multithreadead, load the game async. This way if it takes time to load, things aren't frozen while it's doing that. This allows us to show any sort of loading animation or etc. we want. Before, it might show a odd looking game select screen while loading, and then finally go to black. Now it immediately goes to black. Fixes #2030. --- Core/System.cpp | 40 +++++++++++++++++++++++++++++++++++++--- Core/System.h | 3 +++ UI/EmuScreen.cpp | 30 +++++++++++++++++++++++------- UI/EmuScreen.h | 1 + 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/Core/System.cpp b/Core/System.cpp index 2ef66066b4..b2355d4ff9 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -301,8 +301,13 @@ void System_Wake() { } static bool pspIsInited = false; +static bool pspIsIniting = false; + +bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) { + if (pspIsIniting) { + return false; + } -bool PSP_Init(const CoreParameter &coreParam, std::string *error_string) { #if defined(_WIN32) && defined(_M_X64) INFO_LOG(BOOT, "PPSSPP %s Windows 64 bit", PPSSPP_GIT_VERSION); #elif defined(_WIN32) && !defined(_M_X64) @@ -312,17 +317,30 @@ bool PSP_Init(const CoreParameter &coreParam, std::string *error_string) { #endif coreParameter = coreParam; coreParameter.errorString = ""; + pspIsIniting = true; if (g_Config.bSeparateCPUThread) { Core_ListenShutdown(System_Wake); CPU_SetState(CPU_THREAD_PENDING); cpuThread = new std::thread(&CPU_RunLoop); cpuThread->detach(); - CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsReady); } else { CPU_Init(); } + *error_string = coreParameter.errorString; + return coreParameter.fileToStart != ""; +} + +bool PSP_InitUpdate(std::string *error_string) { + if (pspIsInited || !pspIsIniting) { + return true; + } + + if (g_Config.bSeparateCPUThread && !CPU_IsReady()) { + return false; + } + bool success = coreParameter.fileToStart != ""; *error_string = coreParameter.errorString; if (success) { @@ -333,7 +351,22 @@ bool PSP_Init(const CoreParameter &coreParam, std::string *error_string) { } } pspIsInited = success; - return success; + pspIsIniting = false; + return true; +} + +bool PSP_Init(const CoreParameter &coreParam, std::string *error_string) { + PSP_InitStart(coreParam, error_string); + + if (g_Config.bSeparateCPUThread) { + CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsReady); + } + + return PSP_InitUpdate(error_string); +} + +bool PSP_IsIniting() { + return pspIsIniting; } bool PSP_IsInited() { @@ -362,6 +395,7 @@ void PSP_Shutdown() { host->SetWindowTitle(0); currentMIPS = 0; pspIsInited = false; + pspIsIniting = false; } void PSP_RunLoopUntil(u64 globalticks) { diff --git a/Core/System.h b/Core/System.h index c9010eb5ec..71a8b7a569 100644 --- a/Core/System.h +++ b/Core/System.h @@ -49,6 +49,9 @@ extern GlobalUIState globalUIState; void UpdateUIState(GlobalUIState newState); bool PSP_Init(const CoreParameter &coreParam, std::string *error_string); +bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string); +bool PSP_InitUpdate(std::string *error_string); +bool PSP_IsIniting(); bool PSP_IsInited(); void PSP_Shutdown(); void PSP_RunLoopUntil(u64 globalticks); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 40c421ed69..1d0d3feef3 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -63,14 +63,29 @@ EmuScreen::EmuScreen(const std::string &filename) } void EmuScreen::bootGame(const std::string &filename) { - booted_ = true; - std::string fileToStart = filename; + if (PSP_IsIniting()) { + std::string error_string; + booted_ = PSP_InitUpdate(&error_string); + if (booted_) { + invalid_ = !PSP_IsInited(); + if (invalid_) { + errorMessage_ = error_string; + ERROR_LOG(BOOT, "%s", errorMessage_.c_str()); + System_SendMessage("event", "failstartgame"); + return; + } + bootComplete(); + } + return; + } + + invalid_ = true; CoreParameter coreParam; coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER; coreParam.gpuCore = g_Config.bSoftwareRendering ? GPU_SOFTWARE : GPU_GLES; coreParam.enableSound = g_Config.bEnableSound; - coreParam.fileToStart = fileToStart; + coreParam.fileToStart = filename; coreParam.mountIso = ""; coreParam.startPaused = false; coreParam.printfEmuLog = false; @@ -92,23 +107,24 @@ void EmuScreen::bootGame(const std::string &filename) { coreParam.pixelHeight = pixel_yres; std::string error_string; - if (PSP_Init(coreParam, &error_string)) { - invalid_ = false; - } else { + if (!PSP_InitStart(coreParam, &error_string)) { + booted_ = true; invalid_ = true; errorMessage_ = error_string; ERROR_LOG(BOOT, "%s", errorMessage_.c_str()); System_SendMessage("event", "failstartgame"); return; } +} +void EmuScreen::bootComplete() { globalUIState = UISTATE_INGAME; host->BootDone(); host->UpdateDisassembly(); g_gameInfoCache.FlushBGs(); - NOTICE_LOG(BOOT, "Loading %s...", fileToStart.c_str()); + NOTICE_LOG(BOOT, "Loading %s...", PSP_CoreParameter().fileToStart.c_str()); autoLoad(); I18NCategory *s = GetI18NCategory("Screen"); diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 5fe07f38d8..a90b0f45b4 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -48,6 +48,7 @@ protected: private: void bootGame(const std::string &filename); + void bootComplete(); void processAxis(const AxisInput &axis, int direction); void pspKey(int pspKeyCode, int flags);