aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2018-10-21 03:16:41 +0200
committerStapleButter <thetotalworm@gmail.com>2018-10-21 03:16:41 +0200
commitd191af86904acb407c7c05a5a971652027d5de64 (patch)
tree4fd5738b978c418303455190ff861fe52799f8c4
parentcbcecc8cdb39048732941a64f8c6e5f11e124bbf (diff)
rewrite how structures are stored to savestates (store individual fields, to avoid compatibility issues)
also fixes stability issues when 3D is involved. turns out we were storing raw pointers to vertices. figures more crapo code to get around that, but atleast it works without asploding now.
-rw-r--r--src/GPU3D.cpp79
-rw-r--r--src/NDS.cpp10
2 files changed, 83 insertions, 6 deletions
diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp
index 1f3a64e..d094537 100644
--- a/src/GPU3D.cpp
+++ b/src/GPU3D.cpp
@@ -150,10 +150,14 @@ const s32 CmdNumCycles[256] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
-typedef struct
+typedef union
{
- u8 Command;
- u32 Param;
+ u64 _contents;
+ struct
+ {
+ u32 Param;
+ u8 Command;
+ };
} CmdFIFOEntry;
@@ -410,8 +414,73 @@ void DoSavestate(Savestate* file)
file->Var32(&FlushRequest);
file->Var32(&FlushAttributes);
- file->VarArray(VertexRAM, sizeof(Vertex)*6144*2);
- file->VarArray(PolygonRAM, sizeof(Polygon)*2048*2);
+ for (int i = 0; i < 6144*2; i++)
+ {
+ Vertex* vtx = &VertexRAM[i];
+
+ file->VarArray(vtx->Position, sizeof(s32)*4);
+ file->VarArray(vtx->Color, sizeof(s32)*3);
+ file->VarArray(vtx->TexCoords, sizeof(s16)*2);
+
+ file->Var32((u32*)&vtx->Clipped);
+
+ file->VarArray(vtx->FinalPosition, sizeof(s32)*2);
+ file->VarArray(vtx->FinalColor, sizeof(s32)*3);
+ }
+
+ for(int i = 0; i < 2048*2; i++)
+ {
+ Polygon* poly = &PolygonRAM[i];
+
+ // this is a bit ugly, but eh
+ // we can't save the pointers as-is, that's a bad idea
+ if (file->Saving)
+ {
+ for (int j = 0; j < 10; j++)
+ {
+ Vertex* ptr = poly->Vertices[j];
+ u32 id;
+ if (ptr) id = (u32)((ptr - (&VertexRAM[0])) / sizeof(Vertex));
+ else id = -1;
+ file->Var32(&id);
+ }
+ }
+ else
+ {
+ for (int j = 0; j < 10; j++)
+ {
+ u32 id = -1;
+ file->Var32(&id);
+ if (id == -1) poly->Vertices[j] = NULL;
+ else poly->Vertices[j] = &VertexRAM[id];
+ }
+ }
+
+ file->Var32(&poly->NumVertices);
+
+ file->VarArray(poly->FinalZ, sizeof(s32)*10);
+ file->VarArray(poly->FinalW, sizeof(s32)*10);
+ file->Var32((u32*)&poly->WBuffer);
+
+ file->Var32(&poly->Attr);
+ file->Var32(&poly->TexParam);
+ file->Var32(&poly->TexPalette);
+
+ file->Var32((u32*)&poly->FacingView);
+ file->Var32((u32*)&poly->Translucent);
+
+ file->Var32((u32*)&poly->IsShadowMask);
+ file->Var32((u32*)&poly->IsShadow);
+
+ file->Var32(&poly->VTop);
+ file->Var32(&poly->VBottom);
+ file->Var32((u32*)&poly->YTop);
+ file->Var32((u32*)&poly->YBottom);
+ file->Var32((u32*)&poly->XTop);
+ file->Var32((u32*)&poly->XBottom);
+
+ file->Var32(&poly->SortKey);
+ }
// probably not worth storing the vblank-latched Renderxxxxxx variables
diff --git a/src/NDS.cpp b/src/NDS.cpp
index 33b1a79..042b625 100644
--- a/src/NDS.cpp
+++ b/src/NDS.cpp
@@ -487,7 +487,15 @@ bool DoSavestate(Savestate* file)
file->Var32(&CPUStop);
- file->VarArray(Timers, 8*sizeof(Timer));
+ for (int i = 0; i < 8; i++)
+ {
+ Timer* timer = &Timers[i];
+
+ file->Var16(&timer->Reload);
+ file->Var16(&timer->Cnt);
+ file->Var32(&timer->Counter);
+ file->Var32(&timer->CycleShift);
+ }
file->VarArray(TimerCheckMask, 2*sizeof(u8));
file->VarArray(DMA9Fill, 4*sizeof(u32));