mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Merge pull request #8301 from unknownbrackets/savestates
Fix iOS savestate compatibility issue
This commit is contained in:
commit
b278299324
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user