mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Savestate: Fix action and exit callback handling on load
Delete the old HLE mips call actions instead of leaking them or keeping stale ones, fail the load on an unknown action type instead of crashing, and derive the exit-callback-pending flag from the loaded state. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
06e11fb176
commit
490f08d220
2 files changed
+34
-3
No files matched your search
+17
-3
@@ -486,16 +486,30 @@ void HLEDoState(PointerWrap &p) {
|
||||
if (s >= 2) {
|
||||
int actions = (int)mipsCallActions.size();
|
||||
Do(p, actions);
|
||||
if (actions != (int)mipsCallActions.size()) {
|
||||
mipsCallActions.resize(actions);
|
||||
if (p.mode == p.MODE_READ) {
|
||||
for (PSPAction *action : mipsCallActions) {
|
||||
delete action;
|
||||
}
|
||||
mipsCallActions.clear();
|
||||
if (actions < 0) {
|
||||
p.SetError(p.ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
mipsCallActions.resize(actions, nullptr);
|
||||
}
|
||||
|
||||
for (auto &action : mipsCallActions) {
|
||||
int actionTypeID = action != nullptr ? action->actionTypeID : -1;
|
||||
Do(p, actionTypeID);
|
||||
if (actionTypeID != -1) {
|
||||
if (p.mode == p.MODE_READ)
|
||||
if (p.mode == p.MODE_READ) {
|
||||
action = __KernelCreateAction(actionTypeID);
|
||||
if (!action) {
|
||||
ERROR_LOG(Log::SaveState, "Unable to load state: unknown action type %d", actionTypeID);
|
||||
p.SetError(p.ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
action->DoState(p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,6 +223,10 @@ public:
|
||||
{
|
||||
if (p.mode == p.MODE_READ)
|
||||
chainedAction = __KernelCreateAction(chainedActionType);
|
||||
if (!chainedAction) {
|
||||
p.SetError(p.ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
chainedAction->DoState(p);
|
||||
}
|
||||
}
|
||||
@@ -286,6 +290,10 @@ public:
|
||||
auto s = p.Section("ActionAfterExitCallback", 1);
|
||||
if (!s)
|
||||
return;
|
||||
if (p.mode == p.MODE_READ) {
|
||||
// The dispatch is still in flight in the loaded state (see __KernelThreadingDoState.)
|
||||
g_exitCallbackPending = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -570,6 +578,10 @@ void MipsCall::DoState(PointerWrap &p)
|
||||
{
|
||||
if (p.mode == p.MODE_READ)
|
||||
doAfter = __KernelCreateAction(actionTypeID);
|
||||
if (!doAfter) {
|
||||
p.SetError(p.ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
doAfter->DoState(p);
|
||||
}
|
||||
}
|
||||
@@ -810,6 +822,11 @@ void __KernelThreadingInit() {
|
||||
|
||||
void __KernelThreadingDoState(PointerWrap &p)
|
||||
{
|
||||
if (p.mode == p.MODE_READ) {
|
||||
// Set again if an ActionAfterExitCallback is loaded (with the mips calls, later.)
|
||||
g_exitCallbackPending = false;
|
||||
}
|
||||
|
||||
auto s = p.Section("sceKernelThread", 1, 5);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user