mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Headless: actually apply --state, and report the result
SaveState::Load only queues the operation - SaveState::Process() applies it, and headless never called that anywhere. So --state silently did nothing: the state was queued before boot and sat in the queue for the rest of the run. Call it at the top of the run loop, the same place in the cycle EmuScreen::render does. Also pass a callback so the outcome is visible, and make a failed load set a non-zero exit code. Without that, headless reported success for a state it never loaded - which is why it didn't catch the savestate regression this branch fixes. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01DCPmm7FoQUoqrbMdhfqhQ2
This commit is contained in:
1 parent
729653bf42
commit
8768c30b1d
1 file changed
+19
-1
+19
-1
@@ -82,6 +82,8 @@ static bool g_screenshotFailed = false;
|
||||
static std::string g_debugOutputBuffer;
|
||||
static bool g_writeFailureScreenshot = true;
|
||||
static bool g_writeDebugOutput = true;
|
||||
// Set from the savestate callback on the emu thread, read after it has been joined.
|
||||
static bool g_stateLoadFailed = false;
|
||||
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
JNIEnv *getEnv() {
|
||||
@@ -339,6 +341,10 @@ static bool RunAutoTest(GraphicsContext *graphicsContext, CoreParameter &corePar
|
||||
double deadline = time_now_d() + opt.timeout;
|
||||
coreState = coreParameter.startBreak ? CORE_STEPPING_CPU : CORE_RUNNING_CPU;
|
||||
while (coreState == CORE_RUNNING_CPU || coreState == CORE_STEPPING_CPU) {
|
||||
// Savestate loads/saves are queued and applied here, same as EmuScreen::render does in the
|
||||
// app. Without this, --state silently did nothing at all.
|
||||
SaveState::Process();
|
||||
|
||||
int blockTicks = (int)usToCycles(1000000 / 10);
|
||||
PSP_RunLoopFor(blockTicks);
|
||||
|
||||
@@ -873,7 +879,14 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
|
||||
if (stateToLoad) {
|
||||
SaveState::Load(Path(stateToLoad), -1);
|
||||
// Queued now, actually applied by SaveState::Process() once the game is up and running.
|
||||
SaveState::Load(Path(stateToLoad), -1, [](SaveState::Status status, std::string_view message, std::string_view) {
|
||||
// The message already reads as a full sentence, e.g. "Failed to load state: <reason>".
|
||||
fprintf(stderr, "%.*s\n", (int)message.size(), message.data());
|
||||
if (status == SaveState::Status::FAILURE) {
|
||||
g_stateLoadFailed = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
std::string errorMessage;
|
||||
@@ -893,6 +906,11 @@ int main(int argc, const char* argv[]) {
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
if (g_stateLoadFailed && retval == 0) {
|
||||
// Whatever the run itself reported, the state we were told to load never got applied.
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
graphicsContext->ShutdownAPI();
|
||||
|
||||
delete graphicsContext;
|
||||
|
||||
Reference in new issue
Block a user