ekeeke / Genesis-Plus-GX

An enhanced port of Genesis Plus - accurate & portable Sega 8/16 bit emulator
Other
698 stars 199 forks source link

Incompatibility of savestate between cores 32 bit and 64 bit (same version number) #311

Open gplaysrv opened 4 years ago

gplaysrv commented 4 years ago

Savestates generated on Genesis-Plus-GX (Retroarch) 32 bit core are incompatible with Genesis-Plus-GX (Retroarch) core in its variant 64 bit (same version number) and the other way around.

Version of Genesis-Plus-GX: 1.7.4-5055106

Platforms tested:

ekeeke commented 4 years ago

It shouldn't be the case unless the default 'int' type has different size with some 64-bit compilers.

Also make sure the two cores are configured the same (the selected YM2612/YM3438 core in particular changes the savestate content).

Could you upload savestate files from 32-bit and 64-bit versions, using obviously the exact same game and taken at exact same spot (game paused) for comparison ?

gplaysrv commented 4 years ago

The savestates are generated on Retroarch cores (v. 1.7.4-5055106). Both cores used with default parameters / options. Retroarch downloaded from Google Playstore.

Android is LP64 for 64-bit architectures. So, if the error depends on mismatch of integer sizes, it could be bound to writing (to the savefile) these data types:

I have uploaded 2 savestates for "Sonic The Hedgehog 2 (World).md" (sha1. 14dd06fc3aa19a59a818ea1f6de150c9061b14d4 / md5. 8e2c29a1e65111fe2078359e685e7943)

savestates_genesis_plus_gx_1.7.4-5055106.zip

ekeeke commented 4 years ago

Indeed, I looked a bit more into saved state and it appears there are memory pointers actually being saved, which results in some offsets between 32-bit and 64-bit savestates (pointers being 4-bytes long in one case and 8-bytes long in the other).

For reference, these are part of MAME's YM2612 core context: https://github.com/ekeeke/Genesis-Plus-GX/blob/master/core/sound/ym2612.c#L496 https://github.com/ekeeke/Genesis-Plus-GX/blob/master/core/sound/ym2612.c#L543 https://github.com/ekeeke/Genesis-Plus-GX/blob/master/core/sound/ym2612.c#L615

Those pointers are not used when loading state as they are recalculated using other saved parameters but it was easier back then to save the whole structure instead of cherry-picking what was needed.

Unfortunately, this is a chicken/egg like situation where I cannot fix that without breaking savestate support for user's existing saves on either 32-bit or 64-bit platforms (or both if we remove those unneeded pointers completely) so I'm afraid this will remain like that for the time being. Next time savestate format needs to be changed because we have no other choices (for adding a new feature or improving emulation accuracy/compatibility), I guess we could as well fix this.

EDIT: looks like there are also pointers being saved (although unused as well) in Z80 context so this cannot be possibly bypassed by doing savestates with the other YM2612 core. https://github.com/ekeeke/Genesis-Plus-GX/blob/master/core/z80/z80.h#L47

Chaos81 commented 4 years ago

@ekeeke would this be the main reason why netplay between architectures (Windows vs. Mac) wouldn't work (esp. using a 32-bit Windows core)? If so, I would like to try and fix this, maybe make a variant of the core to allow netplay. The netplay with your core works really well otherwise. It's strange, because I remember being able to load a save state from 32-bit Windows on a 64-bit Mac with no problems maybe about a year ago (was using RA version 1.7.5, don't remember what version GPGX core, it was around Oct. 2018).

ekeeke commented 4 years ago

If netplay relies on exchanging savestates, which I think it does, yes, definitively.

Those pointers have always been there so it's unlikely savestates were ever compatible between 32-bit and 64-bit versions.

Chaos81 commented 4 years ago

If netplay relies on exchanging savestates, which I think it does, yes, definitively.

Those pointers have always been there so it's unlikely savestates were ever compatible between 32-bit and 64-bit versions.

Yeah, I must have been testing between 64-bit versions on Mac and PC.

retropieuser commented 12 months ago

@ekeeke would this be the main reason why netplay between architectures (Windows vs. Mac) wouldn't work (esp. using a 32-bit Windows core)? If so, I would like to try and fix this, maybe make a variant of the core to allow netplay. The netplay with your core works really well otherwise. It's strange, because I remember being able to load a save state from 32-bit Windows on a 64-bit Mac with no problems maybe about a year ago (was using RA version 1.7.5, don't remember what version GPGX core, it was around Oct. 2018).

Just to confirm I've come across this issue and I could work netplay between an android smartphone (64bit) and my Mac (arm64) but neither of these devices would connect to my raspberry pi/Retropie (32bit).

So it definitely breaks netplay moving between 32bit and 64bit architecture