Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
gplaysrv opened this issue Apr 23, 2020 · 7 comments

Comments

@gplaysrv
Copy link

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)
@ekeeke
Copy link
Owner

ekeeke commented Apr 23, 2020

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
Copy link
Author

gplaysrv commented Apr 23, 2020

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

@ekeeke
Copy link
Owner

ekeeke commented Apr 24, 2020

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
Copy link

Chaos81 commented Apr 26, 2020

@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
Copy link
Owner

ekeeke commented Apr 27, 2020

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
Copy link

Chaos81 commented May 15, 2020

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
Copy link

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants