diff --git a/GPU/Debugger/Record.cpp b/GPU/Debugger/Record.cpp index b0ab2efd1e..a2c42e6bbc 100644 --- a/GPU/Debugger/Record.cpp +++ b/GPU/Debugger/Record.cpp @@ -695,6 +695,22 @@ bool Recorder::RecordNextFrame(const std::function callback) return true; } +void Recorder::RestartAfterLoad() { + if (!active) { + return; + } + NOTICE_LOG(Log::System, "Savestate loaded, restarting the recording"); + commands.clear(); + pushbuf.clear(); + lastVRAM.clear(); + lastEdramTrans = 0x400; + flipLastAction = gpuStats.totals.numFlips; + flipFinishAt = -1; + std::lock_guard guard(callbackLock_); + active = false; + nextFrame = true; +} + void Recorder::FinishRecording() { // We're done - this was just to write the result out. if (!active) { diff --git a/GPU/Debugger/Record.h b/GPU/Debugger/Record.h index 78964859b0..ea911be628 100644 --- a/GPU/Debugger/Record.h +++ b/GPU/Debugger/Record.h @@ -50,6 +50,9 @@ public: return nextFrame || active; } bool RecordNextFrame(const std::function callback); + // A savestate load replaced everything a recording in progress started from. It starts over + // from the loaded state, at the next frame. + void RestartAfterLoad(); void ClearCallback() { std::lock_guard guard(callbackLock_); writeCallback = nullptr; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 7372fc989d..913ada9910 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1953,7 +1953,7 @@ struct DisplayList_v2 { }; void GPUCommon::DoState(PointerWrap &p) { - auto s = p.Section("GPUCommon", 1, 7); + auto s = p.Section("GPUCommon", 1, 8); if (!s) return; @@ -2056,9 +2056,26 @@ void GPUCommon::DoState(PointerWrap &p) { if (s >= 5) { Do(p, matrixVisible.all); + } else if (p.mode == PointerWrap::MODE_READ) { + ResetMatrices(); } if (s >= 6) { Do(p, edramTranslation_); + } else if (p.mode == PointerWrap::MODE_READ) { + edramTranslation_ = 0x400; + } + // Which slot (and so which id) the next list gets. Older states start over at 0, rather than + // carry on from the session before the load. + if (s >= 8) { + Do(p, nextListID); + } else { + nextListID = 0; + } + if (p.mode == PointerWrap::MODE_READ) { + if (nextListID < 0 || nextListID > DisplayListMaxCount) { + nextListID = 0; + } + recorder_.RestartAfterLoad(); } }