Merge pull request #8301 from unknownbrackets/savestates

Fix iOS savestate compatibility issue
This commit is contained in:
Henrik Rydgård 2015-12-26 10:42:52 +01:00
commit b278299324
2 changed files with 29 additions and 38 deletions

View File

@ -555,8 +555,10 @@ size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size, int &usec)
if (e.isRawSector) {
positionOnIso = e.sectorStart * 2048ULL + e.seekPos;
fileSize = (s64)e.openSize;
} else if (e.file == nullptr) {
ERROR_LOG(FILESYS, "File no longer exists (loaded savestate with different ISO?)");
return 0;
} else {
_dbg_assert_msg_(FILESYS, e.file != 0, "Expecting non-raw fd to have a tree entry.");
positionOnIso = e.file->startingPosition + e.seekPos;
fileSize = e.file->size;
}

View File

@ -1069,29 +1069,6 @@ struct DisplayList_v2 {
bool bboxResult;
};
struct DisplayList_v3_no_padding {
int id;
u32 startpc;
u32 pc;
u32 stall;
DisplayListState state;
SignalBehavior signal;
int subIntrBase;
u16 subIntrToken;
DisplayListStackEntry stack[32];
int stackptr;
bool interrupted;
u64 waitTicks;
bool interruptsEnabled;
bool pendingInterrupt;
bool started;
PSPPointer<u32_le> context;
u32 offsetAddr;
bool bboxResult;
u32 stackAddr;
// See the header
};
void GPUCommon::DoState(PointerWrap &p) {
easy_guard guard(listLock);
@ -1103,21 +1080,33 @@ void GPUCommon::DoState(PointerWrap &p) {
if (s >= 4) {
p.DoArray(dls, ARRAY_SIZE(dls));
} else if (s >= 3) {
#if defined(ANDROID) && defined(_M_IX86)
// If this starts failing, we'll need to put some alignment attributes on the Displaylist_v3_no_padding struct above.
static_assert(sizeof(DisplayList_v3_no_padding) == 452, "Not the old DisplayList size anymore, see comment");
for (size_t i = 0; i < ARRAY_SIZE(dls); ++i) {
DisplayList_v3_no_padding oldDL;
p.Do(oldDL);
// Copy over everything except the new padding bytes to make the struct size
// equal to other platforms.
memcpy(&dls[i], &oldDL, sizeof(DisplayList_v3_no_padding));
dls[i].padding = 0;
// This may have been saved with or without padding, depending on platform.
// We need to upconvert it to our consistently-padded struct.
static const size_t DisplayList_v3_size = 452;
static const size_t DisplayList_v4_size = 456;
static_assert(DisplayList_v4_size == sizeof(DisplayList), "Make sure to change here when updating DisplayList");
p.DoVoid(&dls[0], DisplayList_v3_size);
dls[0].padding = 0;
const u8 *savedPtr = *p.GetPPtr();
const u32 *savedPtr32 = (const u32 *)savedPtr;
// Here's the trick: the first member (id) is always the same as the index.
// The second member (startpc) is always an address, or 0, never 1. So we can see the padding.
const bool hasPadding = savedPtr32[1] == 1;
if (hasPadding) {
u32 padding;
p.Do(padding);
}
for (size_t i = 1; i < ARRAY_SIZE(dls); ++i) {
p.DoVoid(&dls[i], DisplayList_v3_size);
dls[i].padding = 0;
if (hasPadding) {
u32 padding;
p.Do(padding);
}
}
#else
// Android-x86 used to write badly padded data structures.
p.DoArray(dls, ARRAY_SIZE(dls));
#endif
} else if (s >= 2) {
for (size_t i = 0; i < ARRAY_SIZE(dls); ++i) {
DisplayList_v2 oldDL;