void CPU_RunLoop() { setCurrentThreadName("CPU"); FPU_SetFastMode(); if (CPU_NextState(CPU_THREAD_PENDING, CPU_THREAD_STARTING)) { CPU_Init(); CPU_NextState(CPU_THREAD_STARTING, CPU_THREAD_RUNNING); } else if (!CPU_NextState(CPU_THREAD_RESUME, CPU_THREAD_RUNNING)) { ERROR_LOG(CPU, "CPU thread in unexpected state: %d", cpuThreadState); return; } while (cpuThreadState != CPU_THREAD_SHUTDOWN) { CPU_WaitStatus(cpuThreadCond, &CPU_HasPendingAction); switch (cpuThreadState) { case CPU_THREAD_EXECUTE: mipsr4k.RunLoopUntil(cpuThreadUntil); gpu->FinishEventLoop(); CPU_NextState(CPU_THREAD_EXECUTE, CPU_THREAD_RUNNING); break; // These are fine, just keep looping. case CPU_THREAD_RUNNING: case CPU_THREAD_SHUTDOWN: break; case CPU_THREAD_QUIT: // Just leave the thread, CPU is switching off thread. CPU_SetState(CPU_THREAD_NOT_RUNNING); return; default: ERROR_LOG(CPU, "CPU thread in unexpected state: %d", cpuThreadState); // Begin shutdown, otherwise we'd just spin on this bad state. CPU_SetState(CPU_THREAD_SHUTDOWN); break; } } if (coreState != CORE_ERROR) { coreState = CORE_POWERDOWN; } // Let's make sure the gpu has already cleaned up before we start freeing memory. if (gpu) { gpu->FinishEventLoop(); gpu->SyncThread(true); } CPU_Shutdown(); CPU_SetState(CPU_THREAD_NOT_RUNNING); }
void PSP_RunLoopUntil(u64 globalticks) { SaveState::Process(); if (coreState == CORE_POWERDOWN || coreState == CORE_ERROR) { return; } // Switch the CPU thread on or off, as the case may be. bool useCPUThread = g_Config.bSeparateCPUThread; if (useCPUThread && cpuThread == nullptr) { // Need to start the cpu thread. Core_ListenShutdown(System_Wake); CPU_SetState(CPU_THREAD_RESUME); cpuThread = new std::thread(&CPU_RunLoop); cpuThreadID = cpuThread->get_id(); cpuThread->detach(); if (gpu) { gpu->SetThreadEnabled(true); } CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsReady); } else if (!useCPUThread && cpuThread != nullptr) { CPU_SetState(CPU_THREAD_QUIT); CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsShutdown); delete cpuThread; cpuThread = nullptr; cpuThreadID = std::thread::id(); if (gpu) { gpu->SetThreadEnabled(false); } } if (cpuThread != nullptr) { // Tell the gpu a new frame is about to begin, before we start the CPU. gpu->SyncBeginFrame(); cpuThreadUntil = globalticks; if (CPU_NextState(CPU_THREAD_RUNNING, CPU_THREAD_EXECUTE)) { // The CPU doesn't actually respect cpuThreadUntil well, especially when skipping frames. // TODO: Something smarter? Or force CPU to bail periodically? while (!CPU_IsReady()) { gpu->RunEventsUntil(CoreTiming::GetTicks() + msToCycles(1000)); if (coreState != CORE_RUNNING) { CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsReady); } } } else { ERROR_LOG(CPU, "Unable to execute CPU run loop, unexpected state: %d", cpuThreadState); } } else { mipsr4k.RunLoopUntil(globalticks); } gpu->CleanupBeforeUI(); }
bool PSP_Init(const CoreParameter &coreParam, std::string *error_string) { INFO_LOG(BOOT, "PPSSPP %s", PPSSPP_GIT_VERSION); coreParameter = coreParam; coreParameter.errorString = ""; 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(); } bool success = coreParameter.fileToStart != ""; *error_string = coreParameter.errorString; if (success) { success = GPU_Init(); if (!success) { PSP_Shutdown(); *error_string = "Unable to initialize rendering engine."; } } return success; }
bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) { if (pspIsIniting) { return false; } #if defined(_WIN32) && defined(_M_X64) INFO_LOG(BOOT, "PPSSPP %s Windows 64 bit", PPSSPP_GIT_VERSION); #elif defined(_WIN32) && !defined(_M_X64) INFO_LOG(BOOT, "PPSSPP %s Windows 32 bit", PPSSPP_GIT_VERSION); #else INFO_LOG(BOOT, "PPSSPP %s", PPSSPP_GIT_VERSION); #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(); } else { CPU_Init(); } *error_string = coreParameter.errorString; return coreParameter.fileToStart != ""; }
void CPU_Init() { coreState = CORE_POWERUP; currentCPU = &mipsr4k; numCPUs = 1; // Default memory settings // Seems to be the safest place currently.. if (g_Config.iPSPModel == PSP_MODEL_FAT) Memory::g_MemorySize = Memory::RAM_NORMAL_SIZE; // 32 MB of ram by default else Memory::g_MemorySize = Memory::RAM_DOUBLE_SIZE; g_RemasterMode = false; g_DoubleTextureCoordinates = false; Memory::g_PSPModel = g_Config.iPSPModel; std::string filename = coreParameter.fileToStart; IdentifiedFileType type = Identify_File(filename); switch (type) { case FILETYPE_PSP_ISO: case FILETYPE_PSP_ISO_NP: case FILETYPE_PSP_DISC_DIRECTORY: InitMemoryForGameISO(filename); break; default: break; } Memory::Init(); mipsr4k.Reset(); host->AttemptLoadSymbolMap(); if (coreParameter.enableSound) { Audio_Init(); } CoreTiming::Init(); // Init all the HLE modules HLEInit(); // TODO: Check Game INI here for settings, patches and cheats, and modify coreParameter accordingly // Why did we check for CORE_POWERDOWN here? if (!LoadFile(filename, &coreParameter.errorString)) { CPU_Shutdown(); coreParameter.fileToStart = ""; CPU_SetState(CPU_THREAD_NOT_RUNNING); return; } if (coreParameter.updateRecent) { g_Config.AddRecent(filename); } coreState = coreParameter.startPaused ? CORE_STEPPING : CORE_RUNNING; }
void CPU_Init() { currentCPU = &mipsr4k; numCPUs = 1; // Default memory settings // Seems to be the safest place currently.. Memory::g_MemorySize = 0x2000000; // 32 MB of ram by default g_RemasterMode = false; g_DoubleTextureCoordinates = false; std::string filename = coreParameter.fileToStart; IdentifiedFileType type = Identify_File(filename); switch (type) { case FILETYPE_PSP_ISO: case FILETYPE_PSP_ISO_NP: case FILETYPE_PSP_DISC_DIRECTORY: InitMemoryForGameISO(filename); break; default: break; } Memory::Init(); mipsr4k.Reset(); mipsr4k.pc = 0; host->AttemptLoadSymbolMap(); if (coreParameter.enableSound) { mixer = new PSPMixer(); host->InitSound(mixer); } if (coreParameter.disableG3Dlog) { LogManager::GetInstance()->SetEnable(LogTypes::G3D, false); } CoreTiming::Init(); // Init all the HLE modules HLEInit(); // TODO: Check Game INI here for settings, patches and cheats, and modify coreParameter accordingly // Why did we check for CORE_POWERDOWN here? if (!LoadFile(filename, &coreParameter.errorString)) { CPU_Shutdown(); coreParameter.fileToStart = ""; CPU_SetState(CPU_THREAD_NOT_RUNNING); return; } if (coreParameter.updateRecent) { g_Config.AddRecent(filename); } coreState = coreParameter.startPaused ? CORE_STEPPING : CORE_RUNNING; }
bool CPU_NextStateNot(CPUThreadState from, CPUThreadState to) { lock_guard guard(cpuThreadLock); if (cpuThreadState != from) { CPU_SetState(to); return true; } else { return false; } }
void CPU_RunLoop() { Common::SetCurrentThreadName("CPUThread"); if (!CPU_NextState(CPU_THREAD_PENDING, CPU_THREAD_STARTING)) { ERROR_LOG(CPU, "CPU thread in unexpected state: %d", cpuThreadState); return; } CPU_Init(); CPU_NextState(CPU_THREAD_STARTING, CPU_THREAD_RUNNING); while (cpuThreadState != CPU_THREAD_SHUTDOWN) { CPU_WaitStatus(&CPU_HasPendingAction); switch (cpuThreadState) { case CPU_THREAD_EXECUTE: mipsr4k.RunLoopUntil(cpuThreadUntil); gpu->FinishEventLoop(); CPU_NextState(CPU_THREAD_EXECUTE, CPU_THREAD_RUNNING); break; // These are fine, just keep looping. case CPU_THREAD_RUNNING: case CPU_THREAD_SHUTDOWN: break; default: ERROR_LOG(CPU, "CPU thread in unexpected state: %d", cpuThreadState); // Begin shutdown, otherwise we'd just spin on this bad state. CPU_SetState(CPU_THREAD_SHUTDOWN); break; } } if (coreState != CORE_ERROR) { coreState = CORE_POWERDOWN; } CPU_Shutdown(); CPU_SetState(CPU_THREAD_NOT_RUNNING); }
void PSP_Shutdown() { if (coreState == CORE_RUNNING) coreState = CORE_ERROR; if (cpuThread != NULL) { CPU_SetState(CPU_THREAD_SHUTDOWN); CPU_WaitStatus(&CPU_IsShutdown); delete cpuThread; cpuThread = 0; } else { CPU_Shutdown(); } GPU_Shutdown(); }
void PSP_Shutdown() { if (coreState == CORE_RUNNING) Core_UpdateState(CORE_ERROR); if (cpuThread != NULL) { CPU_SetState(CPU_THREAD_SHUTDOWN); CPU_WaitStatus(&CPU_IsShutdown); delete cpuThread; cpuThread = 0; } else { CPU_Shutdown(); } GPU_Shutdown(); host->SetWindowTitle(0); }
bool PSP_Init(const CoreParameter &coreParam, std::string *error_string) { INFO_LOG(HLE, "PPSSPP %s", PPSSPP_GIT_VERSION); coreParameter = coreParam; coreParameter.errorString = ""; if (g_Config.bSeparateCPUThread) { CPU_SetState(CPU_THREAD_PENDING); cpuThread = new std::thread(&CPU_RunLoop); CPU_WaitStatus(&CPU_IsReady); } else { CPU_Init(); } bool success = coreParameter.fileToStart != ""; *error_string = coreParameter.errorString; if (success) { GPU_Init(); } return success; }
bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) { if (pspIsIniting || pspIsQuiting) { return false; } #if defined(_WIN32) && defined(_M_X64) INFO_LOG(BOOT, "PPSSPP %s Windows 64 bit", PPSSPP_GIT_VERSION); #elif defined(_WIN32) && !defined(_M_X64) INFO_LOG(BOOT, "PPSSPP %s Windows 32 bit", PPSSPP_GIT_VERSION); #else INFO_LOG(BOOT, "PPSSPP %s", PPSSPP_GIT_VERSION); #endif GraphicsContext *temp = coreParameter.graphicsContext; coreParameter = coreParam; if (coreParameter.graphicsContext == nullptr) { coreParameter.graphicsContext = temp; } coreParameter.errorString = ""; pspIsIniting = true; if (g_Config.bSeparateCPUThread) { Core_ListenShutdown(System_Wake); CPU_SetState(CPU_THREAD_PENDING); cpuThread = new std::thread(&CPU_RunLoop); cpuThreadID = cpuThread->get_id(); cpuThread->detach(); } else { CPU_Init(); } *error_string = coreParameter.errorString; bool success = coreParameter.fileToStart != ""; if (!success) { pspIsIniting = false; } return success; }
bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) { if (pspIsIniting) { return false; } #if defined(_WIN32) && defined(_M_X64) INFO_LOG(BOOT, "PPSSPP %s Windows 64 bit", PPSSPP_GIT_VERSION); #elif defined(_WIN32) && !defined(_M_X64) INFO_LOG(BOOT, "PPSSPP %s Windows 32 bit", PPSSPP_GIT_VERSION); #else INFO_LOG(BOOT, "PPSSPP %s", PPSSPP_GIT_VERSION); #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); #ifdef _XBOX SuspendThread(cpuThread->native_handle()); XSetThreadProcessor(cpuThread->native_handle(), 2); ResumeThread(cpuThread->native_handle()); #endif cpuThreadID = cpuThread->get_id(); cpuThread->detach(); } else { CPU_Init(); } *error_string = coreParameter.errorString; bool success = coreParameter.fileToStart != ""; if (!success) { pspIsIniting = false; } return success; }
void CPU_Init() { coreState = CORE_POWERUP; currentMIPS = &mipsr4k; g_symbolMap = new SymbolMap(); // Default memory settings // Seems to be the safest place currently.. Memory::g_MemorySize = Memory::RAM_NORMAL_SIZE; // 32 MB of ram by default g_RemasterMode = false; g_DoubleTextureCoordinates = false; Memory::g_PSPModel = g_Config.iPSPModel; std::string filename = coreParameter.fileToStart; loadedFile = ResolveFileLoaderTarget(ConstructFileLoader(filename)); #ifdef _M_X64 if (g_Config.bCacheFullIsoInRam) { loadedFile = new RamCachingFileLoader(loadedFile); } #endif IdentifiedFileType type = Identify_File(loadedFile); // TODO: Put this somewhere better? if (coreParameter.mountIso != "") { coreParameter.mountIsoLoader = ConstructFileLoader(coreParameter.mountIso); } MIPSAnalyst::Reset(); Replacement_Init(); switch (type) { case FILETYPE_PSP_ISO: case FILETYPE_PSP_ISO_NP: case FILETYPE_PSP_DISC_DIRECTORY: InitMemoryForGameISO(loadedFile); break; case FILETYPE_PSP_PBP: InitMemoryForGamePBP(loadedFile); break; case FILETYPE_PSP_PBP_DIRECTORY: // This is normal for homebrew. // ERROR_LOG(LOADER, "PBP directory resolution failed."); break; default: break; } // Here we have read the PARAM.SFO, let's see if we need any compatibility overrides. // Homebrew usually has an empty discID, and even if they do have a disc id, it's not // likely to collide with any commercial ones. std::string discID = g_paramSFO.GetValueString("DISC_ID"); if (!discID.empty()) { coreParameter.compat.Load(discID); } Memory::Init(); mipsr4k.Reset(); host->AttemptLoadSymbolMap(); if (coreParameter.enableSound) { Audio_Init(); } CoreTiming::Init(); // Init all the HLE modules HLEInit(); // TODO: Check Game INI here for settings, patches and cheats, and modify coreParameter accordingly // Why did we check for CORE_POWERDOWN here? if (!LoadFile(&loadedFile, &coreParameter.errorString)) { CPU_Shutdown(); coreParameter.fileToStart = ""; CPU_SetState(CPU_THREAD_NOT_RUNNING); return; } if (coreParameter.updateRecent) { g_Config.AddRecent(filename); } coreState = coreParameter.startPaused ? CORE_STEPPING : CORE_RUNNING; }