rileytestut / Delta

Delta is an all-in-one classic video game emulator for non-jailbroken iOS devices.
4.46k stars 327 forks source link

Feature Request: Add Support for Unencrypted GBA GameShark/Action Replay Cheat Codes #347

Open beta382 opened 3 weeks ago

beta382 commented 3 weeks ago

My ask is for Delta to support unencrypted cheat codes for GBA GameShark and Action Replay, perhaps via a separate cheat type selection, or an "Unencrypted" toggle when entering cheats of these types (perhaps with an info blurb about "For advanced users; if you found the code online, it's probably encrypted and you want this off"). Maybe an "encrypt/decrypt code" button that does the conversion on the device for the user.

On real hardware (and in Delta), GameShark and Action Replay devices for the GBA expect the codes you use for them to be encrypted. Most codes you'll find in the wild for these devices are the encrypted versions, however, for someone creating their own cheat codes, it is a right pain to need to re-encrypt the code and re-enter the wildly changed code for every minor change you make (and need to be near a PC, which has the convenient encryption tool).

As an example, I wrote a DMA-respecting FireRed "make the PC item box have the item you want in slot 1" Action Replay cheat after seeing that all the codes online permanently corrupt your PC item box (because they don't respect DMA, they just choose an address that is always somewhere in the PC item box RAM block, causing bugs in the very high chance it makes the list disjoint). It's quite reusable:

Raw code format:

42305008 014CXXXX
42305008 014DYYYY

XXXX: Item index
YYYY: Item quantity

Encrypted "999 Master Balls":

F7056CA0 E3B265B6
E19D9DB9 68502457

Encrypted "1 Metal Coat" (Just one, nothing crazy, want both evos for my dex but don't want to go through the hassle of obtaining the second one in the Trainer Tower):

839FE8ED 723982BE
F88C6064 14E0AA91

As is obvious, it's tedious to reuse this code since what are ostensibly minor changes require running the raw code through the encryption scheme, and the result is wildly different. It's not something I could just change directly on my phone by e.g. looking up the item index on Bulbapedia and swapping out the 2 bytes.


Technical Details

From what I can tell, the VBA-m core Delta uses only accepts encrypted codes. This would mean Delta would need to implement the encryption scheme before submitting the code to VBA-m. The encryption scheme is Tiny Encryption Algorithm, with default keys 0x09F4FBBD, 0x9681884A, 0x352027E9, 0xF3DEE5A7 for GameShark (v1) and 0x7AA9648F, 0x7FAE6994, 0xC0EFAAD5, 0x42712C57 for Action Replay (v3). 0xDEADFACE 0x0000XXXX codes throw in a wrinkle by which the encryption keys are shuffled for subsequently interpreted codes, though I'm not sure if there's ever a reason to use them aside from needless obfuscation (so maybe they don't need to be supported; the implementation is pretty trivial though from a glance at the VBA-m source, as well as the original, very concise source VBA-m got their impl from). AR Crypt is an existing program that can be used to validate the implementation (it uses the aforementioned GSAcrypt library).

Related, looking at the GBADeltaCore code, am I seeing right that GameShark and Action Replay codes are both being submitted to VBA-m with v3 set to true? That doesn't seem right. GameShark (v1) and Action Replay (v3) have incompatible opcodes, with the latter having a greatly expanded feature set. As mentioned earlier, they also have different keys for their encryption schemes. In practice (I just tried it), it looks like codes input into Delta as either GameShark or Action Replay are interpreted and executed as Action Replay (v3), which would be a bug (GameShark codes should be submitted to VBA-m with cheatsAddGSACode(_, _, false)).