mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
headless: add --save-state, the counterpart to --state
--state could load a savestate but nothing could produce one without a GUI, so savestate bugs couldn't be reproduced or regression-tested from a script. This saves one partway through the run, once the game is actually up. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01JvJR8oJNSCimCM9KXVLjfq
This commit is contained in:
1 parent
5a84f287c4
commit
2389b8ce96
3 files changed
+21
-1
No files matched your search
+19
-1
@@ -84,6 +84,9 @@ 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;
|
||||
// Set by --save-state. Saving needs the game to actually be running, so it happens from the run
|
||||
// loop rather than up front like a load does.
|
||||
static std::string g_stateToSave;
|
||||
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
JNIEnv *getEnv() {
|
||||
@@ -338,13 +341,24 @@ static bool RunAutoTest(GraphicsContext *graphicsContext, CoreParameter &corePar
|
||||
}
|
||||
|
||||
bool passed = true;
|
||||
double deadline = time_now_d() + opt.timeout;
|
||||
const double startTime = time_now_d();
|
||||
double deadline = startTime + opt.timeout;
|
||||
// Late enough that the game is past booting, early enough to leave the run some time after.
|
||||
double saveStateAt = startTime + opt.timeout * 0.7;
|
||||
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();
|
||||
|
||||
if (!g_stateToSave.empty() && time_now_d() > saveStateAt) {
|
||||
const std::string filename = g_stateToSave;
|
||||
g_stateToSave.clear();
|
||||
SaveState::Save(Path(filename), -1, [](SaveState::Status status, std::string_view message, std::string_view) {
|
||||
fprintf(stderr, "%.*s\n", (int)message.size(), message.data());
|
||||
});
|
||||
}
|
||||
|
||||
int blockTicks = (int)usToCycles(1000000 / 10);
|
||||
PSP_RunLoopFor(blockTicks);
|
||||
|
||||
@@ -878,6 +892,10 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
if (cmdLineOptions.stateToSave.has_value()) {
|
||||
g_stateToSave = cmdLineOptions.stateToSave.value();
|
||||
}
|
||||
|
||||
if (stateToLoad) {
|
||||
// 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) {
|
||||
|
||||
Reference in new issue
Block a user