Sega Saturn has a particular issue where memory appears to be byteswapped, and pointers are 4-bytes large, resulting in difficulties for creating achievements.
This is rooted in a core issue of libretro memory handling, which cheevo sets ends up expecting. libretro will just obtain pointers to core memory. Memory will proceed to be read, byte by byte, to construct memory values.
In theory, this all should work ok. In practice, some cores utilize a trick known as swizzling. This is so an emulated system with an endianess opposite of the host system can directly do common read/writes (assuming the width for common read/writes is greater than 1 byte) under the host system's endianess. When it comes time to do a 1 byte read, the address will be xored with a constant before being used to index a memory buffer (for 2 byte swizzling, this constant is 1, for 4 byte swizzling, this constant is 3).
This knowledge is even worse when you consider this is only going to possibly occur when the host system's endianess is opposite of the emulate system's endianess. If you change the host system so something which matches the emulated system's endianess, you will now read memory "correctly" as it's no longer being swizzled. Of course, this ends up resulting in a mismatch compared to the swizzled memory, and sets would only be made one way or the other.
In practice of course, this trick is limited to emulated big endian systems, as most host systems will be little endian. Not all emulated big endian systems will utilize this trick anyways, some like the Jaguar and GameCube/Wii have big endian memory, but emulators for those systems do not swizzle memory.
The selection of consoles which this trick actually occurs is also very limited. Sega Mega Drive / CD / 32X all utilize this (and of course those are more or less all under the same emulators), Sega Saturn also utilizes this. N64 utilizes this, but instead of simple byteswapping, it does the swizzling by 4 bytes (so ^ 3 instead of ^ 1 for 1 byte reads). (There could be some other systems I'm missing here)
Also in practice, the issues of a big endian host system typically won't actually occur. This will mean the user is running RetroArch on a Wii, Wii U, or old PowerPC Mac, and achievement hunting, and probably doing so with the Genesis Plus GX core. A combination of factors so unlikely it apparently has never actually resulted in some ticket being filed, as I'm told.
As far as I can tell, the libretro API does not offer any way to know if memory is being swizzled or not. It seems to have some kind of flags for retro_memory_map's, so perhaps it'd need a flag added?
Even if this is "fixed" you may still end up needing to fix a ton of existing sets, which all rely on the existing memory behavior, and users will be forced to update their cores / clients, which would create a ton of updating pain.
BizHawk actually normally fixes swizzling for its memory APIs, but for cheevo purposes it has to swizzle it back, due to the mentioned existing sets relying on memory swizzling.
Sega Saturn has a particular issue where memory appears to be byteswapped, and pointers are 4-bytes large, resulting in difficulties for creating achievements.
This is rooted in a core issue of libretro memory handling, which cheevo sets ends up expecting. libretro will just obtain pointers to core memory. Memory will proceed to be read, byte by byte, to construct memory values.
In theory, this all should work ok. In practice, some cores utilize a trick known as swizzling. This is so an emulated system with an endianess opposite of the host system can directly do common read/writes (assuming the width for common read/writes is greater than 1 byte) under the host system's endianess. When it comes time to do a 1 byte read, the address will be xored with a constant before being used to index a memory buffer (for 2 byte swizzling, this constant is 1, for 4 byte swizzling, this constant is 3).
This knowledge is even worse when you consider this is only going to possibly occur when the host system's endianess is opposite of the emulate system's endianess. If you change the host system so something which matches the emulated system's endianess, you will now read memory "correctly" as it's no longer being swizzled. Of course, this ends up resulting in a mismatch compared to the swizzled memory, and sets would only be made one way or the other.
In practice of course, this trick is limited to emulated big endian systems, as most host systems will be little endian. Not all emulated big endian systems will utilize this trick anyways, some like the Jaguar and GameCube/Wii have big endian memory, but emulators for those systems do not swizzle memory.
The selection of consoles which this trick actually occurs is also very limited. Sega Mega Drive / CD / 32X all utilize this (and of course those are more or less all under the same emulators), Sega Saturn also utilizes this. N64 utilizes this, but instead of simple byteswapping, it does the swizzling by 4 bytes (so ^ 3 instead of ^ 1 for 1 byte reads). (There could be some other systems I'm missing here)
Also in practice, the issues of a big endian host system typically won't actually occur. This will mean the user is running RetroArch on a Wii, Wii U, or old PowerPC Mac, and achievement hunting, and probably doing so with the Genesis Plus GX core. A combination of factors so unlikely it apparently has never actually resulted in some ticket being filed, as I'm told.
As far as I can tell, the libretro API does not offer any way to know if memory is being swizzled or not. It seems to have some kind of flags for retro_memory_map's, so perhaps it'd need a flag added?
Even if this is "fixed" you may still end up needing to fix a ton of existing sets, which all rely on the existing memory behavior, and users will be forced to update their cores / clients, which would create a ton of updating pain.
BizHawk actually normally fixes swizzling for its memory APIs, but for cheevo purposes it has to swizzle it back, due to the mentioned existing sets relying on memory swizzling.