Initiating ACE during game startup in Pokemon Crystal
Posted by: Npo
Date: 2018-05-16 14:06:13
Editing the player name to have the char 50 00 in it can be done using a different ACE method, and by writing directly to SRAM instead of wram we won't have to worry about trying to save the game afterword, as doing so would cause the game to read the player name and thus cause the game to start running code from ram.
The first problem is trying to get the byte $c9 written to $cd52 before the game reads the $15 00 sequence. My solution to this is to make the player's name so long that as the game reads the name it will overwrite that part of memory with the char $c9. When the game starts reading the player name it stores the location of where to print the name in memory in hl which at the start of the name hl=$c574, we need to get hl up to $cd52. I found while looking into the unused mobile char functions, that the char sequence
$15 04 – – xx 50 where '–' is just any char, and 'xx' is some byte.
will cause the game to 'skip' xx spaces in it's output, effectively adding 'xx' to hl. However, I want to keep the player name short enough to fit in the 10 char limit so that the entire name is loaded when the game resets. To do this i will use char that refence other 'names' in the game.
The game actually has memory stored for Mom's name, Red's name and Green's name. It seems that the developers once intented the player to be able to change these NPC's names, but since that was never implemented the names stored in RAM are never refrenced in normal play. This means if we edit those names in ram, we can refrence them in the player name using the chars $49, $39, $38 for Mom's, Green's and Red's names respectivly.
Finaly we have what we need to set up the exploit. Here are the names we need for each character for the exploit to work.
Mom's name: 15 04 00 00 ff 50 50 (skip 255 char)
Red's name: 15 04 00 00 f2 50 50 (skip 242 char)
Green's name: 49 49 49 38 50 ( skip 255 + 255 + 255 +242 = 1007 char)
Your name: 39 39 c9 15 00 c3 0e da 50 (skip 1,007*2=2,014 char then write c9…)
the player name when read will then cause the game to jump to $da0e which then should contain code to fix the player name so that once it is read again it will be as normal, and also initiate an HRAM hook allowing for pretty much anything.
It's important to note that the game actually reads the player name once before it actually prints it anywhere on screen after picking continue, this means that (assuming the code at $da0e will fix the player name) the game should appear to run normaly.
I will attach a link to a save file / save-state for bgb which is set up to run a "Rainbow Pallet" payload where the players pallet is randomly changed every frame as an example of how this would work.
https://drive.google.com/drive/folders/13Lwo0_5bhnaZCFnNf_B12oGJA26XHF3-?usp=sharing
———————
That was a pretty dense look at what I have been doing, but basically I made a way to have ACE on startup, my next goal is to write a method that will run with the HRAM hook and will detect when the player saves to fix the player name in SRAM so that when the game resets after a save the exploit will still work. If I can get that to work then this would open up the possibility of a functional "mod" to the gen 2 pokemon games. I will update this post in the future with the asm code for fixing the player name and implementing the HRAM hook.