Genesis-Plus-GX icon indicating copy to clipboard operation
Genesis-Plus-GX copied to clipboard

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

Open gplaysrv opened this issue 4 years ago • 7 comments

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:

  • Android 7 (32 bit Arm)
  • Android 10 (64 bit Arm)
  • Lakka linux (32 bit Arm / Raspberry Pi 3b)
  • Arch Linux (AMD64 / x64)

gplaysrv avatar Apr 23 '20 00:04 gplaysrv

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 ?

ekeeke avatar Apr 23 '20 07:04 ekeeke

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:

  • long int
  • unsigned long int
  • size_t
  • ptrdiff_t
  • intptr_t (optional data type)
  • uintptr_t (optional data type)
  • pointers

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

gplaysrv avatar Apr 23 '20 10:04 gplaysrv

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

ekeeke avatar Apr 24 '20 09:04 ekeeke

@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).

Chaos81 avatar Apr 26 '20 17:04 Chaos81

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.

ekeeke avatar Apr 27 '20 11:04 ekeeke

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.

Chaos81 avatar May 15 '20 22:05 Chaos81

@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

retropieuser avatar Oct 09 '23 06:10 retropieuser