diff --git a/GPU/Debugger/Playback.cpp b/GPU/Debugger/Playback.cpp index 81b0d96cee..9c636d5063 100644 --- a/GPU/Debugger/Playback.cpp +++ b/GPU/Debugger/Playback.cpp @@ -610,7 +610,18 @@ void DumpExecute::SubmitListEnd() { } void DumpExecute::Init(u32 ptr, u32 sz) { - gstate.Restore((u32_le *)(pushbuf_.data() + ptr)); + // Dumps from before savedContextVersion 1 hold PPSSPP's old context layout, with the matrices as raw + // floats; the new one ends its commands with an END. Restoring an old one as new turned its matrices + // into garbage and the scene disappeared (4140). The PSP replayer tells them apart the same way. + const u32_le *context = (const u32_le *)(pushbuf_.data() + ptr); + bool oldLayout = true; + for (int i = 17; i < 512; ++i) { + if (context[i] == GE_CMD_END << 24) { + oldLayout = false; + break; + } + } + gstate.Restore(context, oldLayout); ExecuteOnMain(Operation{ OpType::ReapplyGfxState }); fbPtr_ = gstate.fbptr & 0x00FFFFFF; fbWidth_ = gstate.fbwidth & 0x00FFFFFF; diff --git a/GPU/GPUState.cpp b/GPU/GPUState.cpp index 8b7de27977..c384df55df 100644 --- a/GPU/GPUState.cpp +++ b/GPU/GPUState.cpp @@ -205,6 +205,10 @@ void GEState::FastLoadBoneMatrix(u32 addr) { } void GEState::Restore(const u32_le *ptr) { + Restore(ptr, savedContextVersion == 0); +} + +void GEState::Restore(const u32_le *ptr, bool oldLayout) { // Not sure what the first 10 values are, exactly, but these seem right. gstate_c.vertexAddr = ptr[5]; gstate_c.indexAddr = ptr[6]; @@ -218,7 +222,7 @@ void GEState::Restore(const u32_le *ptr) { } } - if (savedContextVersion == 0) { + if (oldLayout) { if (Memory::IsValidAddress(getClutAddress())) loadclut = *cmds++; boneMatrixNumber = *cmds++; diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 0422d67d89..7fe8bd8238 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -439,6 +439,8 @@ struct GEState { static void Reset(); void Save(u32_le *ptr); void Restore(const u32_le *ptr); + // oldLayout: PPSSPP's layout before savedContextVersion 1, with the matrices as raw floats. + void Restore(const u32_le *ptr, bool oldLayout); }; bool vertTypeIsSkinningEnabled(u32 vertType);