Trainer
From PHWiki
Trainers for handheld games are usually supplied as an IPS patch which when applied to the correct ROM make the game easier by, for example, providing infinite lives or other benefits. When a trainer is released it's directory name and NFO file provide information on the number of cheats provided:
For Example, Maya_The_Bee_And_Her_Friends_Plus2_Trainer-CPL
The 'Plus2' indicates that this trainer provides two cheat options.
Early handheld trainers (for the original Gameboy, trainer releases started in the mid 1990's) were unselectable. The release archive would contain a different .ips patch for each cheat. Once a patch had been applied it could not be disabled without reverting to the original ROM image. Later trainers became selectable. A selectable trainer includes an intro where each option can be enabled or disabled each time the game is executed. Many people now consider an unselectable trainer to be a 'hack' rather than a trainer, although historically they were considered trainers at the time of release.
Early trainers often included just a small number of options, but as group members compete to demonstrate their skill at 'training' a game, the number of options has increased dramatically. Typically GB trainers had just one or two options. GBC trainers often had four or more and it is not uncommon for a GBA trainer to have in excess of 6 selectable options (and in one case eighteen options!). Later trainers also included in-game buttons, where pressing a particular combination of buttons during the game would activate a specific cheat. Occasionally a trainer enhances the game in some non-cheating way, such as saving high scores to SRAM.
Notable groups for trainer releases are Asgard (original GB), Capital (GB and GBC), Eurasia (GB, GBC and GBA), LightForce (GBC and GBA), Dual Crew Shining (GBC and GBA), Venom (GBA) and Rising Sun (GBA), although many have also been released by other groups and individuals.
Trainers: A technical standpoint (Or, The inner workings of a GB/C trainer)
The first thing a trainer needs to do is to load its menu. Execution of a GB/C ROM begins at location $0100; this is usually a jump to $0150 (ie. past the header) but instead we patch it to jump to an empty area (usually within the first 256 bytes of the ROM) where we can execute a bank switching command then jump to the entry point of the trainer menu.
At this point the GB/C's RAM will probably be full of garbage so we initially clear the memory. Then we display our menu and allow the end user to select the options they want. These options are written to an area of RAM that we know is not used by the game (some trainers will write each option's status to an individual byte whereas more efficient trainers will write up to 8 options' status into a single byte, ie. one bit per option).
On exiting the menu we jump back to where we came in (ie. the jump we replaced, so usually $0150). We then need to patch the game's own "clear memory" routine to clear less of the memory than originally specified, otherwise our options' status will be overwritten.
The next thing to do is to patch the game. For example, say we are coding an "infinite time" option; once we have identified the part of the code that decrements the counter, we patch it to jump to our own routine (which is placed either in the same bank or in bank $00, depending on how much space there is). Our routine then checks the value of the "infinite time" option and acts accordingly, before jumping back to the original code. This is of course massively simplified, and the individual steps would actually look like this:
- Load the value of the memory location that holds our option status into the af register
- Check af to see whether bit 1 is switched on
- If it isn't then infinite time isn't selected, so we jump on a few steps
- Load the timer value's into af
- Increment af by 1
- Load af into the timer value's memory location
- (This is where we jumped to from a few steps ago) Jump back to the "decrement timer" routine; if the cheat is on then we just increased the timer by 1, thus cancelling out the subsequent timer decrease.
Ingame keys are a little more complicated, but not terribly so; we need to locate the main loop of the game (ie. a central "core" of instructions which are continually executed during play, which usually takes the form of a series of calls to other routines) and patch it so that at some point we execute our own code, which checks to see whether a particular button is being held down (some games which use all buttons during play can be patched so that the button only works while the game is paused, or while an unlikely combination of buttons is held, or whatever) and if it is we do something (eg. say for example memory location $C100 is usually $00 but is set as $01 when a level has been completed; we would create an ingame key that writes $01 to $C100 if Select is pressed. The next time the game goes through the main loop it will see that $C100 is $01, assume that this is because the level has been complete and move to the next one).
Another method of training a game is to patch the vertical blank interrupt (VBlank), but this is not recommended as executing too much code in the vertical blank can cause problems (eg. graphics corruption) and should therefore only be used as a last resort.
Making a trainer is generally an exercise in patience, as a game should be played to completion to ensure that all eventualities are covered (eg. a game could contain 10 different ways of dying and a different "lose a life" subroutine for each one). Of course, there's also the fact that other groups could be racing to release a trainer so the need for testing should be balanced against the need to release your trainer first.
