mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
PSP boot: Move more of the startup process into the loading thread. Simplifies the code a bit.
This commit is contained in:
parent
19c7d795a7
commit
ee90d2acc1
10 changed files with 92 additions and 164 deletions
|
@ -14,4 +14,6 @@
|
|||
typedef bool (*BadAccessHandler)(uintptr_t address, void *context);
|
||||
|
||||
void InstallExceptionHandler(BadAccessHandler accessHandler);
|
||||
|
||||
// Implementation note: This must be a no-op if InstallExceptionHandler hasn't been called.
|
||||
void UninstallExceptionHandler();
|
||||
|
|
|
@ -434,7 +434,7 @@ void __KernelMemoryInit()
|
|||
kernelMemory.Init(PSP_GetKernelMemoryBase(), PSP_GetKernelMemoryEnd() - PSP_GetKernelMemoryBase(), false);
|
||||
userMemory.Init(PSP_GetUserMemoryBase(), PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase(), false);
|
||||
volatileMemory.Init(PSP_GetVolatileMemoryStart(), PSP_GetVolatileMemoryEnd() - PSP_GetVolatileMemoryStart(), false);
|
||||
ParallelMemset(&g_threadManager, Memory::GetPointerWrite(PSP_GetKernelMemoryBase()), 0, PSP_GetUserMemoryEnd() - PSP_GetKernelMemoryBase(), TaskPriority::HIGH);
|
||||
Memory::Memset(PSP_GetKernelMemoryBase(), 0, PSP_GetUserMemoryEnd() - PSP_GetKernelMemoryBase());
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, PSP_GetKernelMemoryBase(), PSP_GetUserMemoryEnd() - PSP_GetKernelMemoryBase(), "MemInit");
|
||||
INFO_LOG(Log::sceKernel, "Kernel and user memory pools initialized");
|
||||
|
||||
|
|
|
@ -15,10 +15,7 @@
|
|||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "Core/Core.h"
|
||||
#include "Common/Thread/ThreadUtil.h"
|
||||
#include "Common/System/Request.h"
|
||||
|
||||
#include "Common/File/AndroidContentURI.h"
|
||||
|
@ -49,8 +46,6 @@
|
|||
#include "Core/PSPLoaders.h"
|
||||
#include "Core/HLE/sceKernelModule.h"
|
||||
|
||||
static std::thread g_loadingThread;
|
||||
|
||||
static void UseLargeMem(int memsize) {
|
||||
if (memsize != 1) {
|
||||
// Nothing requested.
|
||||
|
@ -252,7 +247,6 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) {
|
|||
} else {
|
||||
*error_string = "A PSP game couldn't be found on the disc.";
|
||||
}
|
||||
coreState = CORE_BOOT_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -270,38 +264,11 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) {
|
|||
g_Config.loadGameConfig(id, g_paramSFO.GetValueString("TITLE"));
|
||||
System_PostUIMessage(UIMessage::CONFIG_LOADED);
|
||||
INFO_LOG(Log::Loader, "Loading %s...", bootpath.c_str());
|
||||
|
||||
PSPLoaders_Shutdown();
|
||||
// Note: this thread reads the game binary, loads caches, and links HLE while UI spins.
|
||||
// To do something deterministically when the game starts, disabling this thread won't be enough.
|
||||
// Instead: Use Core_ListenLifecycle() or watch coreState.
|
||||
g_loadingThread = std::thread([bootpath] {
|
||||
SetCurrentThreadName("ExecLoader");
|
||||
PSP_LoadingLock guard;
|
||||
if (coreState != CORE_POWERUP)
|
||||
return;
|
||||
|
||||
AndroidJNIThreadContext jniContext;
|
||||
|
||||
INFO_LOG(Log::System, "Loading executable...");
|
||||
// TODO: We can't use the initial error_string pointer.
|
||||
bool success = __KernelLoadExec(bootpath.c_str(), 0, &PSP_CoreParameter().errorString);
|
||||
if (success && coreState == CORE_POWERUP) {
|
||||
if (PSP_CoreParameter().startBreak) {
|
||||
coreState = CORE_STEPPING_CPU;
|
||||
System_Notify(SystemNotification::DEBUG_MODE_CHANGE);
|
||||
} else {
|
||||
coreState = CORE_RUNNING_CPU;
|
||||
}
|
||||
} else {
|
||||
coreState = CORE_BOOT_ERROR;
|
||||
// TODO: This is a crummy way to communicate the error...
|
||||
PSP_CoreParameter().fileToStart.clear();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
// TODO: We can't use the initial error_string pointer.
|
||||
return __KernelLoadExec(bootpath.c_str(), 0, &PSP_CoreParameter().errorString);
|
||||
}
|
||||
|
||||
// TODO: Move this to common. Merge with ResolvePath?
|
||||
static Path NormalizePath(const Path &path) {
|
||||
if (path.Type() != PathType::NATIVE) {
|
||||
// Nothing to do - these can't be non-normalized.
|
||||
|
@ -375,7 +342,6 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) {
|
|||
// If root is not a subpath of path, we can't boot the game.
|
||||
if (!pathNorm.StartsWith(rootNorm)) {
|
||||
*error_string = "Cannot boot ELF located outside mountRoot.";
|
||||
coreState = CORE_BOOT_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -438,65 +404,12 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) {
|
|||
File::Rename(oldNamePrefix.WithExtraExtension(".jpg"), newPrefix.WithExtraExtension(".jpg"));
|
||||
}
|
||||
|
||||
PSPLoaders_Shutdown();
|
||||
// Note: See Load_PSP_ISO for notes about this thread.
|
||||
g_loadingThread = std::thread([finalName] {
|
||||
SetCurrentThreadName("ExecLoader");
|
||||
PSP_LoadingLock guard;
|
||||
if (coreState != CORE_POWERUP)
|
||||
return;
|
||||
|
||||
AndroidJNIThreadContext jniContext;
|
||||
|
||||
bool success = __KernelLoadExec(finalName.c_str(), 0, &PSP_CoreParameter().errorString);
|
||||
if (success && coreState == CORE_POWERUP) {
|
||||
if (PSP_CoreParameter().startBreak) {
|
||||
coreState = CORE_STEPPING_CPU;
|
||||
System_Notify(SystemNotification::DEBUG_MODE_CHANGE);
|
||||
} else {
|
||||
coreState = CORE_RUNNING_CPU;
|
||||
}
|
||||
} else {
|
||||
coreState = CORE_BOOT_ERROR;
|
||||
// TODO: This is a crummy way to communicate the error...
|
||||
PSP_CoreParameter().fileToStart.clear();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
return __KernelLoadExec(finalName.c_str(), 0, error_string);
|
||||
}
|
||||
|
||||
bool Load_PSP_GE_Dump(FileLoader *fileLoader, std::string *error_string) {
|
||||
auto umd = std::make_shared<BlobFileSystem>(&pspFileSystem, fileLoader, "data.ppdmp");
|
||||
pspFileSystem.Mount("disc0:", umd);
|
||||
|
||||
PSPLoaders_Shutdown();
|
||||
// Note: See Load_PSP_ISO for notes about this thread.
|
||||
g_loadingThread = std::thread([] {
|
||||
SetCurrentThreadName("ExecLoader");
|
||||
PSP_LoadingLock guard;
|
||||
if (coreState != CORE_POWERUP)
|
||||
return;
|
||||
|
||||
AndroidJNIThreadContext jniContext;
|
||||
|
||||
bool success = __KernelLoadGEDump("disc0:/data.ppdmp", &PSP_CoreParameter().errorString);
|
||||
if (success && coreState == CORE_POWERUP) {
|
||||
if (PSP_CoreParameter().startBreak) {
|
||||
coreState = CORE_STEPPING_CPU;
|
||||
System_Notify(SystemNotification::DEBUG_MODE_CHANGE);
|
||||
} else {
|
||||
coreState = CORE_RUNNING_CPU;
|
||||
}
|
||||
} else {
|
||||
coreState = CORE_BOOT_ERROR;
|
||||
// TODO: This is a crummy way to communicate the error...
|
||||
PSP_CoreParameter().fileToStart.clear();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
void PSPLoaders_Shutdown() {
|
||||
if (g_loadingThread.joinable())
|
||||
g_loadingThread.join();
|
||||
return __KernelLoadGEDump("disc0:/data.ppdmp", &PSP_CoreParameter().errorString);
|
||||
}
|
||||
|
|
|
@ -966,10 +966,6 @@ void identify_and_load_callback(int result, const char *error_message, rc_client
|
|||
g_isIdentifying = false;
|
||||
}
|
||||
|
||||
bool IsReadyToStart() {
|
||||
return !g_isLoggingIn;
|
||||
}
|
||||
|
||||
void SetGame(const Path &path, IdentifiedFileType fileType, FileLoader *fileLoader) {
|
||||
bool homebrew = false;
|
||||
switch (fileType) {
|
||||
|
|
|
@ -96,7 +96,6 @@ bool HasAchievementsOrLeaderboards();
|
|||
bool LoginAsync(const char *username, const char *password);
|
||||
void Logout();
|
||||
|
||||
bool IsReadyToStart();
|
||||
void SetGame(const Path &path, IdentifiedFileType fileType, FileLoader *fileLoader);
|
||||
void ChangeUMD(const Path &path, FileLoader *fileLoader); // for in-game UMD change
|
||||
void UnloadGame(); // Call when leaving a game.
|
||||
|
|
126
Core/System.cpp
126
Core/System.cpp
|
@ -40,6 +40,7 @@
|
|||
#include "Common/File/DirListing.h"
|
||||
#include "Common/File/AndroidContentURI.h"
|
||||
#include "Common/TimeUtil.h"
|
||||
#include "Common/Thread/ThreadUtil.h"
|
||||
#include "Common/GraphicsContext.h"
|
||||
#include "Core/RetroAchievements.h"
|
||||
#include "Core/MemFault.h"
|
||||
|
@ -83,6 +84,7 @@ CoreParameter g_CoreParameter;
|
|||
static FileLoader *g_loadedFile;
|
||||
// For background loading thread.
|
||||
static std::mutex loadingLock;
|
||||
static std::thread g_loadingThread;
|
||||
|
||||
bool coreCollectDebugStats = false;
|
||||
static int coreCollectDebugStatsCounter = 0;
|
||||
|
@ -218,7 +220,7 @@ static void GetBootError(IdentifiedFileType type, std::string *errorString) {
|
|||
#ifdef WIN32
|
||||
*errorString = "RAR file detected (Require WINRAR)";
|
||||
#else
|
||||
*error_string = "RAR file detected (Require UnRAR)";
|
||||
*errorString = "RAR file detected (Require UnRAR)";
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -226,7 +228,7 @@ static void GetBootError(IdentifiedFileType type, std::string *errorString) {
|
|||
#ifdef WIN32
|
||||
*errorString = "ZIP file detected (Require WINRAR)";
|
||||
#else
|
||||
*error_string = "ZIP file detected (Require UnRAR)";
|
||||
*errorString = "ZIP file detected (Require UnRAR)";
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -249,8 +251,6 @@ static void GetBootError(IdentifiedFileType type, std::string *errorString) {
|
|||
|
||||
// NOTE: The loader has already been fully resolved (ResolveFileLoaderTarget) and identified here.
|
||||
static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::string *errorString) {
|
||||
coreState = CORE_POWERUP;
|
||||
|
||||
// Default memory settings
|
||||
// Seems to be the safest place currently..
|
||||
Memory::g_MemorySize = Memory::RAM_NORMAL_SIZE; // 32 MB of ram by default
|
||||
|
@ -416,10 +416,6 @@ PSP_LoadingLock::~PSP_LoadingLock() {
|
|||
void CPU_Shutdown() {
|
||||
UninstallExceptionHandler();
|
||||
|
||||
// Since we load on a background thread, wait for startup to complete.
|
||||
PSP_LoadingLock lock;
|
||||
PSPLoaders_Shutdown();
|
||||
|
||||
GPURecord::Replay_Unload();
|
||||
|
||||
if (g_Config.bAutoSaveSymbolMap) {
|
||||
|
@ -441,15 +437,14 @@ void CPU_Shutdown() {
|
|||
g_loadedFile = nullptr;
|
||||
|
||||
delete g_CoreParameter.mountIsoLoader;
|
||||
g_CoreParameter.mountIsoLoader = nullptr;
|
||||
delete g_symbolMap;
|
||||
g_symbolMap = nullptr;
|
||||
|
||||
g_lua.Shutdown();
|
||||
|
||||
g_CoreParameter.mountIsoLoader = nullptr;
|
||||
}
|
||||
|
||||
// TODO: Maybe loadedFile doesn't even belong here...
|
||||
// Used for UMD switching only.
|
||||
void UpdateLoadedFile(FileLoader *fileLoader) {
|
||||
delete g_loadedFile;
|
||||
g_loadedFile = fileLoader;
|
||||
|
@ -477,20 +472,14 @@ void PSP_ForceDebugStats(bool enable) {
|
|||
_assert_(coreCollectDebugStatsCounter >= 0);
|
||||
}
|
||||
|
||||
bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) {
|
||||
bool PSP_InitStart(const CoreParameter &coreParam) {
|
||||
if (pspIsIniting || pspIsQuitting) {
|
||||
ERROR_LOG(Log::System, "Can't start loader thread - initing or quitting");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Achievements::IsReadyToStart()) {
|
||||
return false;
|
||||
}
|
||||
coreState = CORE_POWERUP;
|
||||
|
||||
// TODO: Move almost all of this into the thread.
|
||||
|
||||
NOTICE_LOG(Log::Boot, "PPSSPP %s", PPSSPP_GIT_VERSION);
|
||||
|
||||
Core_NotifyLifecycle(CoreLifecycle::STARTING);
|
||||
GraphicsContext *temp = g_CoreParameter.graphicsContext;
|
||||
g_CoreParameter = coreParam;
|
||||
if (g_CoreParameter.graphicsContext == nullptr) {
|
||||
|
@ -499,47 +488,69 @@ bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) {
|
|||
g_CoreParameter.errorString.clear();
|
||||
pspIsIniting = true;
|
||||
|
||||
Path filename = g_CoreParameter.fileToStart;
|
||||
FileLoader *loadedFile = ResolveFileLoaderTarget(ConstructFileLoader(filename));
|
||||
std::string *error_string = &g_CoreParameter.errorString;
|
||||
|
||||
IdentifiedFileType type = Identify_File(loadedFile, &g_CoreParameter.errorString);
|
||||
g_CoreParameter.fileType = type;
|
||||
INFO_LOG(Log::System, "Starting loader thread...");
|
||||
|
||||
if (System_GetPropertyBool(SYSPROP_ENOUGH_RAM_FOR_FULL_ISO)) {
|
||||
if (g_Config.bCacheFullIsoInRam) {
|
||||
switch (g_CoreParameter.fileType) {
|
||||
case IdentifiedFileType::PSP_ISO:
|
||||
case IdentifiedFileType::PSP_ISO_NP:
|
||||
loadedFile = new RamCachingFileLoader(loadedFile);
|
||||
break;
|
||||
default:
|
||||
INFO_LOG(Log::System, "RAM caching is on, but file is not an ISO, so ignoring");
|
||||
break;
|
||||
g_loadingThread = std::thread([error_string]() {
|
||||
SetCurrentThreadName("ExecLoader");
|
||||
PSP_LoadingLock guard;
|
||||
if (coreState != CORE_POWERUP)
|
||||
return;
|
||||
|
||||
AndroidJNIThreadContext jniContext;
|
||||
|
||||
NOTICE_LOG(Log::Boot, "PPSSPP %s", PPSSPP_GIT_VERSION);
|
||||
|
||||
Core_NotifyLifecycle(CoreLifecycle::STARTING);
|
||||
|
||||
Path filename = g_CoreParameter.fileToStart;
|
||||
FileLoader *loadedFile = ResolveFileLoaderTarget(ConstructFileLoader(filename));
|
||||
|
||||
IdentifiedFileType type = Identify_File(loadedFile, &g_CoreParameter.errorString);
|
||||
g_CoreParameter.fileType = type;
|
||||
|
||||
if (System_GetPropertyBool(SYSPROP_ENOUGH_RAM_FOR_FULL_ISO)) {
|
||||
if (g_Config.bCacheFullIsoInRam) {
|
||||
switch (g_CoreParameter.fileType) {
|
||||
case IdentifiedFileType::PSP_ISO:
|
||||
case IdentifiedFileType::PSP_ISO_NP:
|
||||
loadedFile = new RamCachingFileLoader(loadedFile);
|
||||
break;
|
||||
default:
|
||||
INFO_LOG(Log::System, "RAM caching is on, but file is not an ISO, so ignoring");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Config.bAchievementsEnable) {
|
||||
// Need to re-identify after ResolveFileLoaderTarget - although in practice probably not,
|
||||
// but also, re-using the identification would require some plumbing, to be done later.
|
||||
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)) {
|
||||
CPU_Shutdown();
|
||||
*error_string = g_CoreParameter.errorString;
|
||||
if (error_string->empty()) {
|
||||
*error_string = "Failed initializing CPU/Memory";
|
||||
if (g_Config.bAchievementsEnable) {
|
||||
std::string errorString;
|
||||
Achievements::SetGame(filename, type, loadedFile);
|
||||
}
|
||||
pspIsIniting = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// After CPU_Init returns, the loader thread will keep working for a bit, while we exit here and come back later through
|
||||
// PSP_InitUpdate.
|
||||
// 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();
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
||||
if (PSP_CoreParameter().startBreak) {
|
||||
coreState = CORE_STEPPING_CPU;
|
||||
System_Notify(SystemNotification::DEBUG_MODE_CHANGE);
|
||||
} else {
|
||||
coreState = CORE_RUNNING_CPU;
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -557,6 +568,10 @@ bool PSP_InitUpdate(std::string *error_string) {
|
|||
*error_string = g_CoreParameter.errorString;
|
||||
}
|
||||
|
||||
// Since we load on a background thread, wait for startup to complete.
|
||||
_dbg_assert_(g_loadingThread.joinable());
|
||||
g_loadingThread.join();
|
||||
|
||||
if (success && gpu == nullptr) {
|
||||
INFO_LOG(Log::System, "Starting graphics...");
|
||||
Draw::DrawContext *draw = g_CoreParameter.graphicsContext ? g_CoreParameter.graphicsContext->GetDrawContext() : nullptr;
|
||||
|
@ -591,7 +606,8 @@ bool PSP_InitUpdate(std::string *error_string) {
|
|||
// 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) {
|
||||
if (!PSP_InitStart(coreParam, error_string))
|
||||
// InitStart doesn't really fail anymore.
|
||||
if (!PSP_InitStart(coreParam))
|
||||
return false;
|
||||
|
||||
while (!PSP_InitUpdate(error_string))
|
||||
|
|
|
@ -72,7 +72,7 @@ GPUBackend GetGPUBackend();
|
|||
std::string GetGPUBackendDevice();
|
||||
|
||||
bool PSP_Init(const CoreParameter &coreParam, std::string *error_string);
|
||||
bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string);
|
||||
bool PSP_InitStart(const CoreParameter &coreParam);
|
||||
bool PSP_InitUpdate(std::string *error_string);
|
||||
bool PSP_IsIniting();
|
||||
bool PSP_IsInited();
|
||||
|
|
|
@ -251,6 +251,8 @@ void __PPGeInit() {
|
|||
int height[12]{};
|
||||
int flags = 0;
|
||||
|
||||
// TODO: Load the atlas on a thread!
|
||||
|
||||
bool loadedZIM = !skipZIM && LoadZIM("ppge_atlas.zim", width, height, &flags, imageData);
|
||||
if (!skipZIM && !loadedZIM) {
|
||||
ERROR_LOG(Log::sceGe, "Failed to load ppge_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory.\n\nPPGe stuff will not be drawn.");
|
||||
|
|
|
@ -355,10 +355,9 @@ void EmuScreen::bootGame(const Path &filename) {
|
|||
coreParam.pixelWidth = g_display.pixel_xres;
|
||||
coreParam.pixelHeight = g_display.pixel_yres;
|
||||
|
||||
std::string error_string;
|
||||
if (!PSP_InitStart(coreParam, &error_string)) {
|
||||
// PSP_InitStart can't really fail anymore, unless it's called at the wrong time. It just starts the loader thread.
|
||||
if (!PSP_InitStart(coreParam)) {
|
||||
bootPending_ = false;
|
||||
errorMessage_ = error_string;
|
||||
ERROR_LOG(Log::Boot, "InitStart bootGame error: %s", errorMessage_.c_str());
|
||||
}
|
||||
|
||||
|
@ -552,10 +551,8 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) {
|
|||
PSP_Shutdown();
|
||||
bootPending_ = true;
|
||||
System_Notify(SystemNotification::DISASSEMBLY);
|
||||
|
||||
std::string resetError;
|
||||
if (!PSP_InitStart(PSP_CoreParameter(), &resetError)) {
|
||||
ERROR_LOG(Log::Loader, "Error resetting: %s", resetError.c_str());
|
||||
if (!PSP_InitStart(PSP_CoreParameter())) {
|
||||
ERROR_LOG(Log::Loader, "Error resetting");
|
||||
stopRender_ = true;
|
||||
screenManager()->switchScreen(new MainScreen());
|
||||
return;
|
||||
|
|
|
@ -184,9 +184,9 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, const
|
|||
if (opt.compare || opt.bench)
|
||||
coreParameter.collectDebugOutput = &output;
|
||||
|
||||
std::string error_string;
|
||||
if (!PSP_InitStart(coreParameter, &error_string)) {
|
||||
fprintf(stderr, "Failed to start '%s'. Error: %s\n", coreParameter.fileToStart.c_str(), error_string.c_str());
|
||||
if (!PSP_InitStart(coreParameter)) {
|
||||
// Shouldn't really happen anymore, the errors happen later in PSP_InitUpdate.
|
||||
fprintf(stderr, "Failed to start '%s'.\n", coreParameter.fileToStart.c_str());
|
||||
printf("TESTERROR\n");
|
||||
TeamCityPrint("testIgnored name='%s' message='PRX/ELF missing'", currentTestName.c_str());
|
||||
GitHubActionsPrint("error", "PRX/ELF missing for %s", currentTestName.c_str());
|
||||
|
@ -198,9 +198,12 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, const
|
|||
if (opt.compare)
|
||||
headlessHost->SetComparisonScreenshot(ExpectedScreenshotFromFilename(coreParameter.fileToStart), opt.maxScreenshotError);
|
||||
|
||||
std::string error_string;
|
||||
while (!PSP_InitUpdate(&error_string))
|
||||
sleep_ms(1, "auto-test");
|
||||
|
||||
if (!PSP_IsInited()) {
|
||||
TeamCityPrint("%s", error_string.c_str());
|
||||
TeamCityPrint("testFailed name='%s' message='Startup failed'", currentTestName.c_str());
|
||||
TeamCityPrint("testFinished name='%s'", currentTestName.c_str());
|
||||
GitHubActionsPrint("error", "Test init failed for %s", currentTestName.c_str());
|
||||
|
|
Loading…
Add table
Reference in a new issue