mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Cleanup a lot of the bootup state management.
This commit is contained in:
parent
e6ea158dcc
commit
088a02bfdb
30 changed files with 239 additions and 257 deletions
|
@ -1700,7 +1700,7 @@ Path Config::getGameConfigFile(const std::string &pGameId, bool *exists) {
|
|||
return iniFileNameFull;
|
||||
}
|
||||
|
||||
bool Config::saveGameConfig(const std::string &pGameId, const std::string &title) {
|
||||
bool Config::saveGameConfig(const std::string &pGameId, const std::string &titleForComment) {
|
||||
if (pGameId.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1711,7 +1711,7 @@ bool Config::saveGameConfig(const std::string &pGameId, const std::string &title
|
|||
IniFile iniFile;
|
||||
|
||||
Section *top = iniFile.GetOrCreateSection("");
|
||||
top->AddComment(StringFromFormat("Game config for %s - %s", pGameId.c_str(), title.c_str()));
|
||||
top->AddComment(StringFromFormat("Game config for %s - %s", pGameId.c_str(), titleForComment.c_str()));
|
||||
|
||||
PreSaveCleanup(true);
|
||||
|
||||
|
|
|
@ -196,7 +196,7 @@ void DisassemblyManager::analyze(u32 address, u32 size = 1024)
|
|||
|
||||
while (address < end && start <= address)
|
||||
{
|
||||
if (!PSP_IsInited())
|
||||
if (PSP_GetBootState() != BootState::Complete)
|
||||
return;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(entriesLock_);
|
||||
|
@ -406,7 +406,7 @@ void DisassemblyManager::clear()
|
|||
|
||||
DisassemblyFunction::DisassemblyFunction(u32 _address, u32 _size): address(_address), size(_size)
|
||||
{
|
||||
if (!PSP_IsInited())
|
||||
if (PSP_GetBootState() != BootState::Complete)
|
||||
return;
|
||||
|
||||
hash = computeHash(address,size);
|
||||
|
@ -419,7 +419,7 @@ DisassemblyFunction::~DisassemblyFunction() {
|
|||
|
||||
void DisassemblyFunction::recheck()
|
||||
{
|
||||
if (!PSP_IsInited())
|
||||
if (PSP_GetBootState() != BootState::Complete)
|
||||
return;
|
||||
|
||||
HashType newHash = computeHash(address,size);
|
||||
|
@ -872,14 +872,14 @@ bool DisassemblyMacro::disassemble(u32 address, DisassemblyLineInfo &dest, bool
|
|||
|
||||
DisassemblyData::DisassemblyData(u32 _address, u32 _size, DataType _type): address(_address), size(_size), type(_type)
|
||||
{
|
||||
_dbg_assert_(PSP_IsInited());
|
||||
_dbg_assert_(PSP_GetBootState() == BootState::Complete);
|
||||
hash = computeHash(address,size);
|
||||
createLines();
|
||||
}
|
||||
|
||||
void DisassemblyData::recheck()
|
||||
{
|
||||
if (!PSP_IsInited())
|
||||
if (PSP_GetBootState() != BootState::Complete)
|
||||
return;
|
||||
|
||||
HashType newHash = computeHash(address,size);
|
||||
|
|
|
@ -99,10 +99,6 @@ static void UpdateConnected(int delta) {
|
|||
}
|
||||
|
||||
static void WebSocketNotifyLifecycle(CoreLifecycle stage) {
|
||||
// We'll likely already be locked during the reboot.
|
||||
if (PSP_IsRebooting())
|
||||
return;
|
||||
|
||||
switch (stage) {
|
||||
case CoreLifecycle::STARTING:
|
||||
case CoreLifecycle::STOPPING:
|
||||
|
|
|
@ -107,12 +107,15 @@ void WebSocketCPUResume(DebuggerRequest &req) {
|
|||
// - ticks: number of CPU cycles into emulation.
|
||||
void WebSocketCPUStatus(DebuggerRequest &req) {
|
||||
JsonWriter &json = req.Respond();
|
||||
json.writeBool("stepping", PSP_IsInited() && Core_IsStepping() && coreState != CORE_POWERDOWN);
|
||||
|
||||
const bool pspInited = PSP_GetBootState() == BootState::Complete;
|
||||
|
||||
json.writeBool("stepping", pspInited && Core_IsStepping() && coreState != CORE_POWERDOWN);
|
||||
json.writeBool("paused", GetUIState() != UISTATE_INGAME);
|
||||
// Avoid NULL deference.
|
||||
json.writeUint("pc", PSP_IsInited() ? currentMIPS->pc : 0);
|
||||
json.writeUint("pc", pspInited ? currentMIPS->pc : 0);
|
||||
// A double ought to be good enough for a 156 day debug session.
|
||||
json.writeFloat("ticks", PSP_IsInited() ? CoreTiming::GetTicks() : 0);
|
||||
json.writeFloat("ticks", pspInited ? CoreTiming::GetTicks() : 0);
|
||||
}
|
||||
|
||||
// Retrieve all regs and their values (cpu.getAllRegs)
|
||||
|
|
|
@ -58,7 +58,7 @@ WebSocketGPURecordState::~WebSocketGPURecordState() {
|
|||
//
|
||||
// Note: recording may take a moment.
|
||||
void WebSocketGPURecordState::Dump(DebuggerRequest &req) {
|
||||
if (!PSP_IsInited()) {
|
||||
if (PSP_GetBootState() != BootState::Complete) {
|
||||
return req.Fail("CPU not started");
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ void WebSocketGPUStatsState::FlipListener() {
|
|||
// Note: stats are returned after the next flip completes (paused if CPU or GPU in break.)
|
||||
// Note: info and timing may not be accurate if certain settings are disabled.
|
||||
void WebSocketGPUStatsState::Get(DebuggerRequest &req) {
|
||||
if (!PSP_IsInited())
|
||||
if (PSP_GetBootState() != BootState::Complete)
|
||||
return req.Fail("CPU not started");
|
||||
|
||||
std::lock_guard<std::mutex> guard(pendingLock_);
|
||||
|
@ -169,7 +169,7 @@ void WebSocketGPUStatsState::Get(DebuggerRequest &req) {
|
|||
//
|
||||
// Note: info and timing will be accurate after the first frame.
|
||||
void WebSocketGPUStatsState::Feed(DebuggerRequest &req) {
|
||||
if (!PSP_IsInited())
|
||||
if (PSP_GetBootState() != BootState::Complete)
|
||||
return req.Fail("CPU not started");
|
||||
bool enable = true;
|
||||
if (!req.ParamBool("enable", &enable, DebuggerParamType::OPTIONAL))
|
||||
|
|
|
@ -27,7 +27,7 @@ struct GameStatusEvent {
|
|||
JsonWriter j;
|
||||
j.begin();
|
||||
j.writeString("event", ev);
|
||||
if (PSP_IsInited()) {
|
||||
if (PSP_GetBootState() == BootState::Complete) {
|
||||
j.pushDict("game");
|
||||
j.writeString("id", g_paramSFO.GetDiscID());
|
||||
j.writeString("version", g_paramSFO.GetValueString("DISC_VERSION"));
|
||||
|
@ -83,10 +83,10 @@ void GameBroadcaster::Broadcast(net::WebSocketServer *ws) {
|
|||
} else if (state == UISTATE_INGAME && prevState_ == UISTATE_PAUSEMENU) {
|
||||
ws->Send(GameStatusEvent{"game.resume"});
|
||||
prevState_ = state;
|
||||
} else if (state == UISTATE_INGAME && PSP_IsInited()) {
|
||||
} else if (state == UISTATE_INGAME && PSP_GetBootState() == BootState::Complete) {
|
||||
ws->Send(GameStatusEvent{"game.start"});
|
||||
prevState_ = state;
|
||||
} else if (state == UISTATE_MENU && !PSP_IsInited() && !PSP_IsQuitting() && !PSP_IsRebooting()) {
|
||||
} else if (state == UISTATE_MENU && PSP_GetBootState() != BootState::Complete) {
|
||||
ws->Send(GameStatusEvent{"game.quit"});
|
||||
prevState_ = state;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ DebuggerSubscriber *WebSocketGameInit(DebuggerEventHandlerMap &map) {
|
|||
//
|
||||
// Response (same event name) with no extra data or error.
|
||||
void WebSocketGameReset(DebuggerRequest &req) {
|
||||
if (!PSP_IsInited())
|
||||
if (PSP_GetBootState() != BootState::Complete)
|
||||
return req.Fail("Game not running");
|
||||
|
||||
bool needBreak = false;
|
||||
|
@ -50,7 +50,7 @@ void WebSocketGameReset(DebuggerRequest &req) {
|
|||
PSP_CoreParameter().startBreak = true;
|
||||
|
||||
std::string resetError;
|
||||
if (!PSP_Reboot(&resetError)) {
|
||||
if (PSP_Reboot(&resetError) != BootState::Complete) {
|
||||
ERROR_LOG(Log::Boot, "Error resetting: %s", resetError.c_str());
|
||||
return req.Fail("Could not reset");
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ void WebSocketGameReset(DebuggerRequest &req) {
|
|||
// - paused: boolean, true when gameplay is paused (not the same as stepping.)
|
||||
void WebSocketGameStatus(DebuggerRequest &req) {
|
||||
JsonWriter &json = req.Respond();
|
||||
if (PSP_IsInited()) {
|
||||
if (PSP_GetBootState() == BootState::Complete) {
|
||||
json.pushDict("game");
|
||||
json.writeString("id", g_paramSFO.GetDiscID());
|
||||
json.writeString("version", g_paramSFO.GetValueString("DISC_VERSION"));
|
||||
|
|
|
@ -101,7 +101,7 @@ void WebSocketHLEThreadList(DebuggerRequest &req) {
|
|||
}
|
||||
|
||||
static bool ThreadInfoForStatus(DebuggerRequest &req, DebugThreadInfo *result) {
|
||||
if (!PSP_IsInited()) {
|
||||
if (PSP_GetBootState() != BootState::Complete) {
|
||||
req.Fail("CPU not active");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ void WebSocketReplayAbort(DebuggerRequest &req) {
|
|||
// - version: unsigned integer, version number of data.
|
||||
// - base64: base64 encode of binary data.
|
||||
void WebSocketReplayFlush(DebuggerRequest &req) {
|
||||
if (!PSP_IsInited())
|
||||
if (PSP_GetBootState() != BootState::Complete)
|
||||
return req.Fail("Game not running");
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
|
@ -90,7 +90,7 @@ void WebSocketReplayFlush(DebuggerRequest &req) {
|
|||
//
|
||||
// Response (same event name) with no extra data.
|
||||
void WebSocketReplayExecute(DebuggerRequest &req) {
|
||||
if (!PSP_IsInited())
|
||||
if (PSP_GetBootState() != BootState::Complete)
|
||||
return req.Fail("Game not running");
|
||||
|
||||
uint32_t version = -1;
|
||||
|
@ -130,7 +130,7 @@ void WebSocketReplayStatus(DebuggerRequest &req) {
|
|||
// Response (same event name):
|
||||
// - value: unsigned integer, may have more than 32 integer bits.
|
||||
void WebSocketReplayTimeGet(DebuggerRequest &req) {
|
||||
if (!PSP_IsInited())
|
||||
if (PSP_GetBootState() != BootState::Complete)
|
||||
return req.Fail("Game not running");
|
||||
|
||||
JsonWriter &json = req.Respond();
|
||||
|
@ -144,7 +144,7 @@ void WebSocketReplayTimeGet(DebuggerRequest &req) {
|
|||
//
|
||||
// Response (same event name) with no extra data.
|
||||
void WebSocketReplayTimeSet(DebuggerRequest &req) {
|
||||
if (!PSP_IsInited())
|
||||
if (PSP_GetBootState() != BootState::Complete)
|
||||
return req.Fail("Game not running");
|
||||
|
||||
uint32_t value;
|
||||
|
|
|
@ -57,7 +57,7 @@ private:
|
|||
//
|
||||
// Sent unexpectedly with no other properties.
|
||||
void SteppingBroadcaster::Broadcast(net::WebSocketServer *ws) {
|
||||
if (PSP_IsInited()) {
|
||||
if (PSP_GetBootState() == BootState::Complete) {
|
||||
int steppingCounter = Core_GetSteppingCounter();
|
||||
// We ignore CORE_POWERDOWN as a stepping state.
|
||||
if (coreState == CORE_STEPPING_CPU && steppingCounter != lastCounter_) {
|
||||
|
|
|
@ -326,9 +326,7 @@ std::string __KernelStateSummary() {
|
|||
return __KernelThreadingSummary();
|
||||
}
|
||||
|
||||
|
||||
void sceKernelExitGame()
|
||||
{
|
||||
void sceKernelExitGame() {
|
||||
INFO_LOG(Log::sceKernel, "sceKernelExitGame");
|
||||
__KernelSwitchOffThread("game exited");
|
||||
Core_Stop();
|
||||
|
|
|
@ -210,7 +210,7 @@ unsigned int MIPSDebugInterface::readMemory(unsigned int address) {
|
|||
|
||||
bool MIPSDebugInterface::isAlive()
|
||||
{
|
||||
return PSP_IsInited() && coreState != CORE_BOOT_ERROR && coreState != CORE_RUNTIME_ERROR && coreState != CORE_POWERDOWN;
|
||||
return PSP_GetBootState() == BootState::Complete && coreState != CORE_BOOT_ERROR && coreState != CORE_RUNTIME_ERROR && coreState != CORE_POWERDOWN;
|
||||
}
|
||||
|
||||
bool MIPSDebugInterface::isBreakpoint(unsigned int address)
|
||||
|
|
|
@ -313,7 +313,7 @@ bool Init() {
|
|||
}
|
||||
|
||||
void Reinit() {
|
||||
_assert_msg_(PSP_IsInited(), "Cannot reinit during startup/shutdown");
|
||||
_assert_msg_(PSP_GetBootState() == BootState::Complete, "Cannot reinit during startup/shutdown");
|
||||
Core_NotifyLifecycle(CoreLifecycle::MEMORY_REINITING);
|
||||
Shutdown();
|
||||
Init();
|
||||
|
|
|
@ -250,16 +250,6 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// OK, pretty confident we have a PSP game.
|
||||
if (g_paramSFO.IsValid()) {
|
||||
std::string title = StringFromFormat("%s : %s", g_paramSFO.GetValueString("DISC_ID").c_str(), g_paramSFO.GetValueString("TITLE").c_str());
|
||||
INFO_LOG(Log::Loader, "%s", title.c_str());
|
||||
System_SetWindowTitle(title);
|
||||
} else {
|
||||
// Should have been loaded earlier in the process.
|
||||
_dbg_assert_(false);
|
||||
}
|
||||
|
||||
//in case we didn't go through EmuScreen::boot
|
||||
g_Config.loadGameConfig(id, g_paramSFO.GetValueString("TITLE"));
|
||||
System_PostUIMessage(UIMessage::CONFIG_LOADED);
|
||||
|
@ -375,17 +365,10 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) {
|
|||
homebrewName = homebrewName.substr(lslash + 1);
|
||||
if (rslash != homebrewName.npos)
|
||||
homebrewName = homebrewName.substr(rslash + 1);
|
||||
std::string homebrewTitle = g_paramSFO.GetValueString("TITLE");
|
||||
if (homebrewTitle.empty())
|
||||
homebrewTitle = homebrewName;
|
||||
std::string discID = g_paramSFO.GetDiscID();
|
||||
std::string discVersion = g_paramSFO.GetValueString("DISC_VERSION");
|
||||
std::string madeUpID = g_paramSFO.GenerateFakeID(Path());
|
||||
|
||||
std::string title = StringFromFormat("%s : %s", discID.c_str(), homebrewTitle.c_str());
|
||||
INFO_LOG(Log::Loader, "%s", title.c_str());
|
||||
System_SetWindowTitle(title);
|
||||
|
||||
// Migrate old save states from old versions of fake game IDs.
|
||||
// Ugh, this might actually be slow on Android.
|
||||
const Path savestateDir = GetSysDirectory(DIRECTORY_SAVESTATE);
|
||||
|
|
|
@ -381,7 +381,7 @@ namespace Reporting
|
|||
|
||||
void UpdateConfig() {
|
||||
currentSupported = IsSupported();
|
||||
if (!currentSupported && PSP_IsInited())
|
||||
if (!currentSupported && PSP_GetBootState() == BootState::Complete)
|
||||
everUnsupported = true;
|
||||
}
|
||||
|
||||
|
@ -438,7 +438,7 @@ namespace Reporting
|
|||
void AddGameplayInfo(UrlEncoder &postdata)
|
||||
{
|
||||
// Just to get an idea of how long they played.
|
||||
if (PSP_IsInited())
|
||||
if (PSP_GetBootState() == BootState::Complete)
|
||||
postdata.Add("ticks", (const uint64_t)CoreTiming::GetTicks());
|
||||
|
||||
float vps, fps;
|
||||
|
@ -536,7 +536,7 @@ namespace Reporting
|
|||
// Don't report from games without a version ID (i.e. random hashed homebrew IDs.)
|
||||
// The problem is, these aren't useful because the hashes end up different for different people.
|
||||
// TODO: Should really hash the ELF instead of the path, but then that affects savestates/cheats.
|
||||
if (PSP_IsInited() && g_paramSFO.GetValueString("DISC_VERSION").empty())
|
||||
if (PSP_GetBootState() == BootState::Complete && g_paramSFO.GetValueString("DISC_VERSION").empty())
|
||||
return false;
|
||||
|
||||
// Some users run the exe from a zip or something, and don't have fonts.
|
||||
|
@ -555,7 +555,7 @@ namespace Reporting
|
|||
|
||||
bool IsEnabled()
|
||||
{
|
||||
if (g_Config.sReportHost.empty() || (!currentSupported && PSP_IsInited()))
|
||||
if (g_Config.sReportHost.empty() || (!currentSupported && PSP_GetBootState() == BootState::Complete))
|
||||
return false;
|
||||
// Disabled by default for now.
|
||||
if (g_Config.sReportHost.compare("default") == 0)
|
||||
|
|
|
@ -1147,15 +1147,10 @@ double g_lastSaveTime = -1.0;
|
|||
}
|
||||
|
||||
void Cleanup() {
|
||||
// TODO: Handle this better.
|
||||
if (needsRestart) {
|
||||
PSP_Shutdown();
|
||||
std::string resetError;
|
||||
if (!PSP_Init(PSP_CoreParameter(), &resetError)) {
|
||||
ERROR_LOG(Log::Boot, "Error resetting: %s", resetError.c_str());
|
||||
// TODO: This probably doesn't clean up well enough.
|
||||
Core_Stop();
|
||||
return;
|
||||
}
|
||||
std::string error_string;
|
||||
PSP_Reboot(&error_string);
|
||||
System_Notify(SystemNotification::BOOT_DONE);
|
||||
System_Notify(SystemNotification::DISASSEMBLY);
|
||||
needsRestart = false;
|
||||
|
|
241
Core/System.cpp
241
Core/System.cpp
|
@ -71,6 +71,7 @@
|
|||
#include "GPU/GPUCommon.h"
|
||||
#include "GPU/Debugger/Playback.h"
|
||||
#include "GPU/Debugger/RecordFormat.h"
|
||||
#include "UI/DiscordIntegration.h"
|
||||
|
||||
enum CPUThreadState {
|
||||
CPU_THREAD_NOT_RUNNING,
|
||||
|
@ -94,11 +95,11 @@ static volatile CPUThreadState cpuThreadState = CPU_THREAD_NOT_RUNNING;
|
|||
static GPUBackend gpuBackend;
|
||||
static std::string gpuBackendDevice;
|
||||
|
||||
// Ugly!
|
||||
static volatile bool pspIsInited = false;
|
||||
static volatile bool pspIsIniting = false;
|
||||
static volatile bool pspIsQuitting = false;
|
||||
static volatile bool pspIsRebooting = false;
|
||||
static BootState g_bootState = BootState::Off;
|
||||
|
||||
BootState PSP_GetBootState() {
|
||||
return g_bootState;
|
||||
}
|
||||
|
||||
void ResetUIState() {
|
||||
globalUIState = UISTATE_MENU;
|
||||
|
@ -131,21 +132,7 @@ std::string GetGPUBackendDevice() {
|
|||
return gpuBackendDevice;
|
||||
}
|
||||
|
||||
bool CPU_IsReady() {
|
||||
if (coreState == CORE_POWERUP)
|
||||
return false;
|
||||
return cpuThreadState == CPU_THREAD_RUNNING || cpuThreadState == CPU_THREAD_NOT_RUNNING;
|
||||
}
|
||||
|
||||
bool CPU_IsShutdown() {
|
||||
return cpuThreadState == CPU_THREAD_NOT_RUNNING;
|
||||
}
|
||||
|
||||
bool CPU_HasPendingAction() {
|
||||
return cpuThreadState != CPU_THREAD_RUNNING;
|
||||
}
|
||||
|
||||
void CPU_Shutdown();
|
||||
void CPU_Shutdown(bool success);
|
||||
|
||||
static Path SymbolMapFilename(const Path ¤tFilename, const char *ext) {
|
||||
File::FileInfo info{};
|
||||
|
@ -249,6 +236,24 @@ static void GetBootError(IdentifiedFileType type, std::string *errorString) {
|
|||
}
|
||||
}
|
||||
|
||||
static void ShowCompatWarnings(const Compatibility &compat) {
|
||||
// UI changes are best done after PSP_InitStart.
|
||||
if (compat.flags().RequireBufferedRendering && g_Config.bSkipBufferEffects && !g_Config.bSoftwareRendering) {
|
||||
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, gr->T("BufferedRenderingRequired", "Warning: This game requires Rendering Mode to be set to Buffered."), 10.0f);
|
||||
}
|
||||
|
||||
if (compat.flags().RequireBlockTransfer && g_Config.iSkipGPUReadbackMode != (int)SkipGPUReadbackMode::NO_SKIP && !PSP_CoreParameter().compat.flags().ForceEnableGPUReadback) {
|
||||
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, gr->T("BlockTransferRequired", "Warning: This game requires Skip GPU Readbacks be set to No."), 10.0f);
|
||||
}
|
||||
|
||||
if (compat.flags().RequireDefaultCPUClock && g_Config.iLockedCPUSpeed != 0) {
|
||||
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, gr->T("DefaultCPUClockRequired", "Warning: This game requires the CPU clock to be set to default."), 10.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: The loader has already been fully resolved (ResolveFileLoaderTarget) and identified here.
|
||||
static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::string *errorString) {
|
||||
// Default memory settings
|
||||
|
@ -263,6 +268,8 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
|
|||
|
||||
std::string geDumpDiscID;
|
||||
|
||||
std::string gameTitle = "Unidentified PSP title";
|
||||
|
||||
switch (type) {
|
||||
case IdentifiedFileType::PSP_ISO:
|
||||
case IdentifiedFileType::PSP_ISO_NP:
|
||||
|
@ -294,6 +301,7 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
|
|||
if (DiscIDFromGEDumpPath(g_CoreParameter.fileToStart, fileLoader, &geDumpDiscID)) {
|
||||
// Store in SFO, otherwise it'll generate a fake disc ID.
|
||||
g_paramSFO.SetValue("DISC_ID", geDumpDiscID, 16);
|
||||
gameTitle = g_CoreParameter.fileToStart.GetFilename();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -306,6 +314,15 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
|
|||
}
|
||||
}
|
||||
|
||||
// OK, pretty confident we have a PSP game.
|
||||
if (g_paramSFO.IsValid()) {
|
||||
gameTitle = SanitizeString(g_paramSFO.GetValueString("TITLE"), StringRestriction::NoLineBreaksOrSpecials);
|
||||
}
|
||||
|
||||
std::string title = StringFromFormat("%s : %s", g_paramSFO.GetValueString("DISC_ID").c_str(), gameTitle.c_str());
|
||||
INFO_LOG(Log::Loader, "%s", title.c_str());
|
||||
System_SetWindowTitle(title);
|
||||
|
||||
currentMIPS = &mipsr4k;
|
||||
|
||||
g_symbolMap = new SymbolMap();
|
||||
|
@ -319,6 +336,7 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
|
|||
// 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.
|
||||
g_CoreParameter.compat.Load(g_paramSFO.GetDiscID());
|
||||
ShowCompatWarnings(g_CoreParameter.compat);
|
||||
|
||||
// Compat settings can override the software renderer, take care of that here.
|
||||
if (g_Config.bSoftwareRendering || PSP_CoreParameter().compat.flags().ForceSoftwareRenderer) {
|
||||
|
@ -329,7 +347,6 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
|
|||
if (!Memory::Init()) {
|
||||
// We're screwed.
|
||||
*errorString = "Memory init failed";
|
||||
CPU_Shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -370,7 +387,10 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
|
|||
dir = ResolvePBPDirectory(Path(dir)).ToString();
|
||||
pspFileSystem.SetStartingDirectory("ms0:/" + dir.substr(pos));
|
||||
}
|
||||
return Load_PSP_ELF_PBP(fileLoader, errorString);
|
||||
if (!Load_PSP_ELF_PBP(fileLoader, errorString)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Looks like a wrong fall through but is not, both paths are handled above.
|
||||
|
||||
|
@ -378,17 +398,26 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
|
|||
case IdentifiedFileType::PSP_ELF:
|
||||
{
|
||||
INFO_LOG(Log::Loader, "File is an ELF or loose PBP! %s", fileLoader->GetPath().c_str());
|
||||
return Load_PSP_ELF_PBP(fileLoader, errorString);
|
||||
if (!Load_PSP_ELF_PBP(fileLoader, errorString)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IdentifiedFileType::PSP_ISO:
|
||||
case IdentifiedFileType::PSP_ISO_NP:
|
||||
case IdentifiedFileType::PSP_DISC_DIRECTORY: // behaves the same as the mounting is already done by now
|
||||
pspFileSystem.SetStartingDirectory("disc0:/PSP_GAME/USRDIR");
|
||||
return Load_PSP_ISO(fileLoader, errorString);
|
||||
if (!Load_PSP_ISO(fileLoader, errorString)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case IdentifiedFileType::PPSSPP_GE_DUMP:
|
||||
return Load_PSP_GE_Dump(fileLoader, errorString);
|
||||
if (!Load_PSP_GE_Dump(fileLoader, errorString)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
GetBootError(type, errorString);
|
||||
|
@ -405,20 +434,12 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
|
|||
return true;
|
||||
}
|
||||
|
||||
PSP_LoadingLock::PSP_LoadingLock() {
|
||||
loadingLock.lock();
|
||||
}
|
||||
|
||||
PSP_LoadingLock::~PSP_LoadingLock() {
|
||||
loadingLock.unlock();
|
||||
}
|
||||
|
||||
void CPU_Shutdown() {
|
||||
void CPU_Shutdown(bool success) {
|
||||
UninstallExceptionHandler();
|
||||
|
||||
GPURecord::Replay_Unload();
|
||||
|
||||
if (g_Config.bAutoSaveSymbolMap) {
|
||||
if (g_Config.bAutoSaveSymbolMap && success) {
|
||||
SaveSymbolMapIfSupported();
|
||||
}
|
||||
|
||||
|
@ -473,30 +494,32 @@ void PSP_ForceDebugStats(bool enable) {
|
|||
}
|
||||
|
||||
bool PSP_InitStart(const CoreParameter &coreParam) {
|
||||
if (pspIsIniting || pspIsQuitting) {
|
||||
ERROR_LOG(Log::System, "Can't start loader thread - initing or quitting");
|
||||
if (g_bootState != BootState::Off) {
|
||||
ERROR_LOG(Log::System, "Can't start loader thread - already on.");
|
||||
return false;
|
||||
}
|
||||
|
||||
_dbg_assert_(coreState != CORE_POWERUP);
|
||||
|
||||
coreState = CORE_POWERUP;
|
||||
|
||||
g_bootState = BootState::Booting;
|
||||
|
||||
GraphicsContext *temp = g_CoreParameter.graphicsContext;
|
||||
g_CoreParameter = coreParam;
|
||||
if (g_CoreParameter.graphicsContext == nullptr) {
|
||||
g_CoreParameter.graphicsContext = temp;
|
||||
}
|
||||
g_CoreParameter.errorString.clear();
|
||||
pspIsIniting = true;
|
||||
|
||||
std::string *error_string = &g_CoreParameter.errorString;
|
||||
|
||||
INFO_LOG(Log::System, "Starting loader thread...");
|
||||
|
||||
_dbg_assert_(!g_loadingThread.joinable());
|
||||
|
||||
g_loadingThread = std::thread([error_string]() {
|
||||
SetCurrentThreadName("ExecLoader");
|
||||
PSP_LoadingLock guard;
|
||||
if (coreState != CORE_POWERUP)
|
||||
return;
|
||||
|
||||
AndroidJNIThreadContext jniContext;
|
||||
|
||||
|
@ -532,14 +555,14 @@ bool PSP_InitStart(const CoreParameter &coreParam) {
|
|||
// 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)) {
|
||||
CPU_Shutdown();
|
||||
CPU_Shutdown(false);
|
||||
coreState = CORE_BOOT_ERROR;
|
||||
g_CoreParameter.fileToStart.clear();
|
||||
*error_string = g_CoreParameter.errorString;
|
||||
if (error_string->empty()) {
|
||||
*error_string = "Failed initializing CPU/Memory";
|
||||
}
|
||||
pspIsIniting = false;
|
||||
g_bootState = BootState::Failed;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -549,101 +572,84 @@ bool PSP_InitStart(const CoreParameter &coreParam) {
|
|||
} else {
|
||||
coreState = CORE_RUNNING_CPU;
|
||||
}
|
||||
|
||||
g_bootState = BootState::Complete;
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PSP_InitUpdate(std::string *error_string) {
|
||||
if (pspIsInited || !pspIsIniting) {
|
||||
return true;
|
||||
BootState PSP_InitUpdate(std::string *error_string) {
|
||||
if (g_bootState == BootState::Booting || g_bootState == BootState::Off) {
|
||||
// We're done already.
|
||||
return g_bootState;
|
||||
}
|
||||
|
||||
if (!CPU_IsReady()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = !g_CoreParameter.fileToStart.empty();
|
||||
if (!g_CoreParameter.errorString.empty()) {
|
||||
*error_string = g_CoreParameter.errorString;
|
||||
}
|
||||
_dbg_assert_(g_bootState == BootState::Complete || g_bootState == BootState::Failed);
|
||||
|
||||
// Since we load on a background thread, wait for startup to complete.
|
||||
_dbg_assert_(g_loadingThread.joinable());
|
||||
g_loadingThread.join();
|
||||
|
||||
if (success && gpu == nullptr) {
|
||||
if (g_bootState == BootState::Failed) {
|
||||
// Failed! (Note: PSP_Shutdown was already called on the loader thread).
|
||||
Core_NotifyLifecycle(CoreLifecycle::START_COMPLETE);
|
||||
*error_string = g_CoreParameter.errorString;
|
||||
return g_bootState;
|
||||
}
|
||||
|
||||
// Ok, async boot completed, let's finish up things on the main thread.
|
||||
|
||||
if (!gpu) { // should be!
|
||||
INFO_LOG(Log::System, "Starting graphics...");
|
||||
Draw::DrawContext *draw = g_CoreParameter.graphicsContext ? g_CoreParameter.graphicsContext->GetDrawContext() : nullptr;
|
||||
success = GPU_Init(g_CoreParameter.graphicsContext, draw);
|
||||
bool success = GPU_Init(g_CoreParameter.graphicsContext, draw);
|
||||
if (!success) {
|
||||
*error_string = "Unable to initialize rendering engine.";
|
||||
PSP_Shutdown(false);
|
||||
g_bootState = BootState::Failed;
|
||||
return g_bootState;
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
pspIsRebooting = false;
|
||||
PSP_Shutdown();
|
||||
return true;
|
||||
|
||||
// TODO: This should all be checked during GPU_Init.
|
||||
if (!GPU_IsStarted()) {
|
||||
*error_string = "Unable to initialize rendering engine.";
|
||||
PSP_Shutdown(false);
|
||||
g_bootState = BootState::Failed;
|
||||
}
|
||||
|
||||
pspIsInited = GPU_IsReady();
|
||||
pspIsIniting = !pspIsInited;
|
||||
if (pspIsInited) {
|
||||
Core_NotifyLifecycle(CoreLifecycle::START_COMPLETE);
|
||||
pspIsRebooting = false;
|
||||
|
||||
// If GPU init failed during IsReady checks, bail.
|
||||
if (!GPU_IsStarted()) {
|
||||
*error_string = "Unable to initialize rendering engine.";
|
||||
pspIsRebooting = false;
|
||||
PSP_Shutdown();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return pspIsInited;
|
||||
Core_NotifyLifecycle(CoreLifecycle::START_COMPLETE);
|
||||
return g_bootState;
|
||||
}
|
||||
|
||||
// Most platforms should not use this one, they should call PSP_InitStart and then do their thing
|
||||
// while repeatedly calling PSP_InitUpdate. This is basically just for libretro convenience.
|
||||
bool PSP_Init(const CoreParameter &coreParam, std::string *error_string) {
|
||||
BootState PSP_Init(const CoreParameter &coreParam, std::string *error_string) {
|
||||
// InitStart doesn't really fail anymore.
|
||||
if (!PSP_InitStart(coreParam))
|
||||
return false;
|
||||
return BootState::Failed;
|
||||
|
||||
while (!PSP_InitUpdate(error_string))
|
||||
sleep_ms(10, "psp-init-poll");
|
||||
return pspIsInited;
|
||||
while (true) {
|
||||
BootState state = PSP_InitUpdate(error_string);
|
||||
if (state != BootState::Booting) {
|
||||
return state;
|
||||
}
|
||||
sleep_ms(5, "psp-init-poll");
|
||||
}
|
||||
}
|
||||
|
||||
bool PSP_IsIniting() {
|
||||
return pspIsIniting;
|
||||
}
|
||||
|
||||
bool PSP_IsInited() {
|
||||
return pspIsInited && !pspIsQuitting && !pspIsRebooting;
|
||||
}
|
||||
|
||||
bool PSP_IsRebooting() {
|
||||
return pspIsRebooting;
|
||||
}
|
||||
|
||||
bool PSP_IsQuitting() {
|
||||
return pspIsQuitting;
|
||||
}
|
||||
|
||||
void PSP_Shutdown() {
|
||||
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 (!pspIsInited && !pspIsIniting && !pspIsQuitting) {
|
||||
if (g_bootState == BootState::Off) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure things know right away that PSP memory, etc. is going away.
|
||||
pspIsQuitting = !pspIsRebooting;
|
||||
if (coreState == CORE_RUNNING_CPU)
|
||||
Core_Stop();
|
||||
|
||||
|
@ -651,29 +657,42 @@ void PSP_Shutdown() {
|
|||
MIPSAnalyst::StoreHashMap();
|
||||
}
|
||||
|
||||
if (pspIsIniting)
|
||||
if (g_bootState == BootState::Booting) {
|
||||
// This should only happen during failures.
|
||||
Core_NotifyLifecycle(CoreLifecycle::START_COMPLETE);
|
||||
}
|
||||
Core_NotifyLifecycle(CoreLifecycle::STOPPING);
|
||||
CPU_Shutdown();
|
||||
|
||||
CPU_Shutdown(success);
|
||||
GPU_Shutdown();
|
||||
g_paramSFO.Clear();
|
||||
System_SetWindowTitle("");
|
||||
currentMIPS = 0;
|
||||
pspIsInited = false;
|
||||
pspIsIniting = false;
|
||||
pspIsQuitting = false;
|
||||
|
||||
currentMIPS = nullptr;
|
||||
|
||||
g_Config.unloadGameConfig();
|
||||
|
||||
Core_NotifyLifecycle(CoreLifecycle::STOPPED);
|
||||
|
||||
if (success) {
|
||||
g_bootState = BootState::Off;
|
||||
}
|
||||
}
|
||||
|
||||
bool PSP_Reboot(std::string *error_string) {
|
||||
if (!pspIsInited || pspIsQuitting)
|
||||
return false;
|
||||
// Call this after handling BootState::Failed.
|
||||
void PSP_CancelBoot() {
|
||||
_dbg_assert_(g_bootState == BootState::Failed);
|
||||
g_bootState = BootState::Off;
|
||||
}
|
||||
|
||||
BootState PSP_Reboot(std::string *error_string) {
|
||||
if (g_bootState != BootState::Complete) {
|
||||
return g_bootState;
|
||||
}
|
||||
|
||||
pspIsRebooting = true;
|
||||
Core_Stop();
|
||||
Core_WaitInactive();
|
||||
PSP_Shutdown();
|
||||
PSP_Shutdown(true);
|
||||
std::string resetError;
|
||||
return PSP_Init(PSP_CoreParameter(), error_string);
|
||||
}
|
||||
|
|
|
@ -71,27 +71,41 @@ void SetGPUBackend(GPUBackend type, const std::string &device = "");
|
|||
GPUBackend GetGPUBackend();
|
||||
std::string GetGPUBackendDevice();
|
||||
|
||||
bool PSP_Init(const CoreParameter &coreParam, std::string *error_string);
|
||||
enum class BootState {
|
||||
Off,
|
||||
Booting,
|
||||
Complete,
|
||||
Failed,
|
||||
};
|
||||
|
||||
BootState PSP_GetBootState();
|
||||
inline bool PSP_IsInited() {
|
||||
return PSP_GetBootState() == BootState::Complete;
|
||||
}
|
||||
|
||||
// Call this once, then call PSP_InitUpdate repeatedly to monitor progress.
|
||||
bool PSP_InitStart(const CoreParameter &coreParam);
|
||||
bool PSP_InitUpdate(std::string *error_string);
|
||||
bool PSP_IsIniting();
|
||||
bool PSP_IsInited();
|
||||
bool PSP_IsRebooting();
|
||||
bool PSP_IsQuitting();
|
||||
void PSP_Shutdown();
|
||||
bool PSP_Reboot(std::string *error_string);
|
||||
|
||||
// Check the return value of this - if Booting, keep calling.
|
||||
// If Complete or Failed, handle as appropriate, and stop calling.
|
||||
BootState PSP_InitUpdate(std::string *error_string);
|
||||
|
||||
// Blocking wrapper around the two above functions, used for convenience in a couple of places.
|
||||
// Should be avoided/removed eventually.
|
||||
// Returns either BootState::Complete or BootState::Failed.
|
||||
BootState PSP_Init(const CoreParameter &coreParam, std::string *error_string);
|
||||
// Call this after handling BootState::Failed from PSP_Init.
|
||||
void PSP_CancelBoot();
|
||||
|
||||
void PSP_Shutdown(bool success);
|
||||
BootState PSP_Reboot(std::string *error_string);
|
||||
|
||||
|
||||
void PSP_BeginHostFrame();
|
||||
void PSP_EndHostFrame();
|
||||
void PSP_RunLoopWhileState();
|
||||
void PSP_RunLoopFor(int cycles);
|
||||
|
||||
// Used to wait for background loading thread.
|
||||
struct PSP_LoadingLock {
|
||||
PSP_LoadingLock();
|
||||
~PSP_LoadingLock();
|
||||
};
|
||||
|
||||
// Call before PSP_BeginHostFrame() in order to not miss any GPU stats.
|
||||
void PSP_UpdateDebugStats(bool collectStats);
|
||||
// Increments or decrements an internal counter. Intended to be used by debuggers.
|
||||
|
|
|
@ -563,7 +563,7 @@ static void FormatVertColRawType(char *dest, size_t destSize, const void *data,
|
|||
static void FormatVertColRawColor(char *dest, size_t destSize, const void *data, int type);
|
||||
|
||||
void FormatVertColRaw(VertexDecoder *decoder, char *dest, size_t destSize, int row, int col) {
|
||||
if (!PSP_IsInited()) {
|
||||
if (PSP_GetBootState() != BootState::Complete) {
|
||||
truncate_cpy(dest, destSize, "Invalid");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -53,10 +53,6 @@ static void SetGPU(T *obj) {
|
|||
#undef new
|
||||
#endif
|
||||
|
||||
bool GPU_IsReady() {
|
||||
return gpu != nullptr;
|
||||
}
|
||||
|
||||
bool GPU_IsStarted() {
|
||||
if (gpu)
|
||||
return gpu->IsStarted();
|
||||
|
|
|
@ -182,7 +182,6 @@ namespace Draw {
|
|||
}
|
||||
|
||||
bool GPU_Init(GraphicsContext *ctx, Draw::DrawContext *draw);
|
||||
bool GPU_IsReady();
|
||||
bool GPU_IsStarted();
|
||||
void GPU_Shutdown();
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "ppsspp_config.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Core/Config.h"
|
||||
#include "DiscordIntegration.h"
|
||||
#include "UI/DiscordIntegration.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
|
||||
#if (PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(LINUX)) && !PPSSPP_PLATFORM(ANDROID) && !PPSSPP_PLATFORM(UWP)
|
||||
|
|
|
@ -120,7 +120,7 @@ private:
|
|||
DisplayLayoutScreen::DisplayLayoutScreen(const Path &filename) : UIDialogScreenWithGameBackground(filename) {}
|
||||
|
||||
void DisplayLayoutScreen::DrawBackground(UIContext &dc) {
|
||||
if (PSP_IsInited() && !g_Config.bSkipBufferEffects) {
|
||||
if (PSP_GetBootState() == BootState::Complete && !g_Config.bSkipBufferEffects) {
|
||||
// We normally rely on the PSP screen showing through.
|
||||
} else {
|
||||
// But if it's not present (we're not in game, or skip buffer effects is used),
|
||||
|
|
|
@ -229,7 +229,6 @@ bool EmuScreen::bootAllowStorage(const Path &filename) {
|
|||
return false;
|
||||
|
||||
case PERMISSION_STATUS_DENIED:
|
||||
stopRender_ = true;
|
||||
screenManager()->switchScreen(new MainScreen());
|
||||
return false;
|
||||
|
||||
|
@ -251,37 +250,42 @@ void EmuScreen::bootGame(const Path &filename) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (PSP_IsRebooting())
|
||||
std::string error_string = "(unknown error)";
|
||||
BootState state = PSP_InitUpdate(&error_string);
|
||||
|
||||
switch (state) {
|
||||
case BootState::Booting:
|
||||
// Keep trying.
|
||||
return;
|
||||
if (PSP_IsInited()) {
|
||||
case BootState::Failed:
|
||||
// Failure.
|
||||
PSP_CancelBoot();
|
||||
_dbg_assert_(!error_string.empty());
|
||||
g_BackgroundAudio.SetGame(Path());
|
||||
bootPending_ = false;
|
||||
errorMessage_ = error_string;
|
||||
ERROR_LOG(Log::Boot, "Boot failed: %s", errorMessage_.c_str());
|
||||
return;
|
||||
case BootState::Complete:
|
||||
// Done booting!
|
||||
g_BackgroundAudio.SetGame(Path());
|
||||
bootPending_ = false;
|
||||
errorMessage_.clear();
|
||||
bootComplete();
|
||||
// Reset views in case controls are in a different place.
|
||||
RecreateViews();
|
||||
return;
|
||||
case BootState::Off:
|
||||
// Gotta start the boot process! Continue below.
|
||||
break;
|
||||
}
|
||||
|
||||
if (PSP_IsIniting()) {
|
||||
std::string error_string = "(unknown error)";
|
||||
|
||||
bootPending_ = !PSP_InitUpdate(&error_string);
|
||||
|
||||
if (!bootPending_) {
|
||||
if (!PSP_IsInited()) {
|
||||
errorMessage_ = error_string;
|
||||
ERROR_LOG(Log::Boot, "isIniting bootGame error: %s", errorMessage_.c_str());
|
||||
return;
|
||||
}
|
||||
bootComplete();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
g_BackgroundAudio.SetGame(Path());
|
||||
|
||||
// Check permission status first, in case we came from a shortcut.
|
||||
if (!bootAllowStorage(filename))
|
||||
return;
|
||||
|
||||
// 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.
|
||||
std::shared_ptr<GameInfo> info = g_gameInfoCache->GetInfo(nullptr, filename, GameInfoFlags::PARAM_SFO);
|
||||
if (!info->Ready(GameInfoFlags::PARAM_SFO)) {
|
||||
return;
|
||||
|
@ -303,10 +307,6 @@ void EmuScreen::bootGame(const Path &filename) {
|
|||
SetAssertCancelCallback(&AssertCancelCallback, this);
|
||||
|
||||
if (!info->id.empty()) {
|
||||
g_Config.loadGameConfig(info->id, info->GetTitle());
|
||||
// Reset views in case controls are in a different place.
|
||||
RecreateViews();
|
||||
|
||||
g_Discord.SetPresenceGame(info->GetTitle());
|
||||
} else {
|
||||
g_Discord.SetPresenceGame(sc->T("Untitled PSP game"));
|
||||
|
@ -359,21 +359,7 @@ void EmuScreen::bootGame(const Path &filename) {
|
|||
if (!PSP_InitStart(coreParam)) {
|
||||
bootPending_ = false;
|
||||
ERROR_LOG(Log::Boot, "InitStart bootGame error: %s", errorMessage_.c_str());
|
||||
}
|
||||
|
||||
if (PSP_CoreParameter().compat.flags().RequireBufferedRendering && g_Config.bSkipBufferEffects && !g_Config.bSoftwareRendering) {
|
||||
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, gr->T("BufferedRenderingRequired", "Warning: This game requires Rendering Mode to be set to Buffered."), 10.0f);
|
||||
}
|
||||
|
||||
if (PSP_CoreParameter().compat.flags().RequireBlockTransfer && g_Config.iSkipGPUReadbackMode != (int)SkipGPUReadbackMode::NO_SKIP && !PSP_CoreParameter().compat.flags().ForceEnableGPUReadback) {
|
||||
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, gr->T("BlockTransferRequired", "Warning: This game requires Skip GPU Readbacks be set to No."), 10.0f);
|
||||
}
|
||||
|
||||
if (PSP_CoreParameter().compat.flags().RequireDefaultCPUClock && g_Config.iLockedCPUSpeed != 0) {
|
||||
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, gr->T("DefaultCPUClockRequired", "Warning: This game requires the CPU clock to be set to default."), 10.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
loadingViewColor_->Divert(0xFFFFFFFF, 0.75f);
|
||||
|
@ -386,6 +372,7 @@ void EmuScreen::bootGame(const Path &filename) {
|
|||
}
|
||||
}
|
||||
|
||||
// Only call this on successful boot.
|
||||
void EmuScreen::bootComplete() {
|
||||
UpdateUIState(UISTATE_INGAME);
|
||||
System_Notify(SystemNotification::BOOT_DONE);
|
||||
|
@ -456,9 +443,8 @@ EmuScreen::~EmuScreen() {
|
|||
std::string gameID = g_paramSFO.GetValueString("DISC_ID");
|
||||
g_Config.TimeTracker().Stop(gameID);
|
||||
|
||||
// If we were invalid, it would already be shutdown.
|
||||
if (!bootPending_) {
|
||||
PSP_Shutdown();
|
||||
PSP_Shutdown(true);
|
||||
}
|
||||
|
||||
System_PostUIMessage(UIMessage::GAME_SELECTED, "");
|
||||
|
@ -543,17 +529,15 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) {
|
|||
screenManager()->push(new GamePauseScreen(gamePath_));
|
||||
} else if (message == UIMessage::REQUEST_GAME_STOP) {
|
||||
// We will push MainScreen in update().
|
||||
PSP_Shutdown();
|
||||
PSP_Shutdown(true);
|
||||
bootPending_ = false;
|
||||
stopRender_ = true;
|
||||
System_Notify(SystemNotification::DISASSEMBLY);
|
||||
} else if (message == UIMessage::REQUEST_GAME_RESET) {
|
||||
PSP_Shutdown();
|
||||
PSP_Shutdown(true);
|
||||
bootPending_ = true;
|
||||
System_Notify(SystemNotification::DISASSEMBLY);
|
||||
if (!PSP_InitStart(PSP_CoreParameter())) {
|
||||
ERROR_LOG(Log::Loader, "Error resetting");
|
||||
stopRender_ = true;
|
||||
screenManager()->switchScreen(new MainScreen());
|
||||
return;
|
||||
}
|
||||
|
@ -567,7 +551,7 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) {
|
|||
if (ext != nullptr && !strcmp(ext, ".ppst")) {
|
||||
SaveState::Load(Path(value), -1, &AfterStateBoot);
|
||||
} else {
|
||||
PSP_Shutdown();
|
||||
PSP_Shutdown(true);
|
||||
bootPending_ = true;
|
||||
gamePath_ = Path(value);
|
||||
// Don't leave it on CORE_POWERDOWN, we'll sometimes aggressively bail.
|
||||
|
@ -1433,14 +1417,11 @@ void EmuScreen::update() {
|
|||
}
|
||||
|
||||
bool EmuScreen::checkPowerDown() {
|
||||
if (PSP_IsRebooting()) {
|
||||
bootPending_ = true;
|
||||
}
|
||||
|
||||
if (coreState == CORE_POWERDOWN && !PSP_IsIniting() && !PSP_IsRebooting()) {
|
||||
// This is for handling things like sceKernelExitGame().
|
||||
if (coreState == CORE_POWERDOWN && PSP_GetBootState() == BootState::Complete) {
|
||||
bool shutdown = false;
|
||||
if (PSP_IsInited()) {
|
||||
PSP_Shutdown();
|
||||
PSP_Shutdown(true);
|
||||
shutdown = true;
|
||||
}
|
||||
INFO_LOG(Log::System, "SELF-POWERDOWN!");
|
||||
|
|
|
@ -101,7 +101,6 @@ private:
|
|||
Path gamePath_;
|
||||
|
||||
bool quit_ = false;
|
||||
bool stopRender_ = false;
|
||||
std::string errorMessage_;
|
||||
|
||||
// If set, pauses at the end of the frame.
|
||||
|
|
|
@ -50,7 +50,7 @@ static ImColor scaleColor(ImColor color, float factor) {
|
|||
}
|
||||
|
||||
bool ImDisasmView::getDisasmAddressText(u32 address, char* dest, bool abbreviateLabels, bool showData) {
|
||||
if (!PSP_IsInited())
|
||||
if (PSP_GetBootState() != BootState::Complete)
|
||||
return false;
|
||||
|
||||
return GetDisasmAddressText(address, dest, abbreviateLabels, showData, displaySymbols_);
|
||||
|
|
|
@ -483,8 +483,7 @@ void GamePauseScreen::CreateViews() {
|
|||
|
||||
rightColumnItems->Add(new Spacer(20.0));
|
||||
|
||||
std::string gameId = g_paramSFO.GetDiscID();
|
||||
if (g_Config.hasGameConfig(gameId)) {
|
||||
if (g_paramSFO.IsValid() && g_Config.hasGameConfig(g_paramSFO.GetDiscID())) {
|
||||
rightColumnItems->Add(new Choice(pa->T("Game Settings")))->OnClick.Handle(this, &GamePauseScreen::OnGameSettings);
|
||||
rightColumnItems->Add(new Choice(pa->T("Delete Game Config")))->OnClick.Handle(this, &GamePauseScreen::OnDeleteConfig);
|
||||
} else {
|
||||
|
|
|
@ -120,7 +120,7 @@ bool RunTests() {
|
|||
INFO_LOG(Log::System, "Preparing to execute '%s'", testName.c_str());
|
||||
std::string error_string;
|
||||
output.clear();
|
||||
if (!PSP_Init(coreParam, &error_string)) {
|
||||
if (BootState::Complete != PSP_Init(coreParam, &error_string)) {
|
||||
ERROR_LOG(Log::System, "Failed to init unittest %s : %s", testsToRun[i], error_string.c_str());
|
||||
PSP_CoreParameter().pixelWidth = g_display.pixel_xres;
|
||||
PSP_CoreParameter().pixelHeight = g_display.pixel_yres;
|
||||
|
@ -177,7 +177,7 @@ bool RunTests() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
PSP_Shutdown();
|
||||
PSP_Shutdown(true);
|
||||
}
|
||||
PSP_CoreParameter().pixelWidth = g_display.pixel_xres;
|
||||
PSP_CoreParameter().pixelHeight = g_display.pixel_yres;
|
||||
|
|
|
@ -199,7 +199,7 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, const
|
|||
headlessHost->SetComparisonScreenshot(ExpectedScreenshotFromFilename(coreParameter.fileToStart), opt.maxScreenshotError);
|
||||
|
||||
std::string error_string;
|
||||
while (!PSP_InitUpdate(&error_string))
|
||||
while (PSP_InitUpdate(&error_string) == BootState::Booting)
|
||||
sleep_ms(1, "auto-test");
|
||||
|
||||
if (!PSP_IsInited()) {
|
||||
|
@ -265,7 +265,7 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, const
|
|||
draw->EndFrame();
|
||||
}
|
||||
|
||||
PSP_Shutdown();
|
||||
PSP_Shutdown(true);
|
||||
|
||||
if (!opt.bench)
|
||||
headlessHost->FlushDebugOutput();
|
||||
|
|
Loading…
Add table
Reference in a new issue