1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
There are a lot of popular cheat codes in Pokémon games: walk through walls, get Rare Candies and Master Balls, find wild shiny Pokémon, get all the Badges... Different physical cheat devices exist, like [GameShark](https://en.wikipedia.org/wiki/GameShark), [Game Genie](https://en.wikipedia.org/wiki/Game_Genie), [Action Replay](https://en.wikipedia.org/wiki/Action_Replay), and even Pokémon-specific ones like [Monster Brain](https://bulbapedia.bulbagarden.net/wiki/Monster_Brain). Game Boy emulators tend to support GameShark-style cheat codes because they're popular and straightforward.
A GameShark cheat code looks like this: `ttvvllhh`
- `tt` is the code type. `01` is typical. `9x` will switch to WRAM bank `x`. `8x` will switch to SRAM bank `x`.
- `vv` is the value to write into RAM. It's a [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) byte from $00 to $FF.
- `hhll` is the RAM address to write to. Note that it's [little-endian](https://en.wikipedia.org/wiki/Endianness) in the code, low byte first.
We can reverse-engineer the meaning of particular codes, and discover our own new codes, with the [**symbol files**](https://github.com/pret/pokecrystal/tree/symbols). When we run `make` to build the ROM, along with the .gbc file it creates a .sym file. This file lists all the labels from the source code with their corresponding banks and addresses in the ROM.
For example, the code `010730D2` writes `07` to `01:D230`. We can look up this address in [pokecrystal.sym](https://raw.githubusercontent.com/pret/pokecrystal/symbols/pokecrystal.sym): it's `wBattleType`, from [wram.asm](../blob/master/wram.asm). Its appropriate values are the `BATTLETYPE_*` constants, from [constants/battle_constants.asm](../blob/master/constants/battle_constants.asm), of which #7 (remember, `const_def` counts up from 0) is `BATTLETYPE_SHINY`. So this looks like a cheat to force shiny battles like Red Gyarados. And sure enough, in [Matthew Robinson's Pokemon Crystal Gameshark Code Archive](https://www.ocf.berkeley.edu/~jdonald/pokemon/pokemonccodes.txt), that code appears as "Fight Shiney Pokemon".
We can design new codes this way. If your pokecrystal-based hack project ended up shifting the location of `wBattleType`, or changed the value of `BATTLETYPE_SHINY`, then the code `010730D2` would affect something else, and might do nothing, cause glitches, or crash the game. But you can just find the new address of `wBattleType` in your own .sym file and edit the code to use that.
Note that not every address has its own label. For example, [Matthew Robinson](https://www.ocf.berkeley.edu/~jdonald/pokemon/pokemonccodes.txt) lists these four codes as "skill modifiers":
```
Skill 1 Modifier 01??E1DC
Skill 2 Modifier 01??E2DC
Skill 3 Modifier 01??E3DC
Skill 4 Modifier 01??E4DC
```
But only one of those four addresses has a label in [pokecrystal.sym](https://raw.githubusercontent.com/pret/pokecrystal/symbols/pokecrystal.sym):
```
01:dce1 wPartyMon1Moves
```
Nor is there any `wPartyMon1Moves` label in [wram.asm](../blob/master/wram.asm). However, there is this:
```
wPartyMon1:: party_struct wPartyMon1
```
And [macros/wram.asm](../blob/master/macros/wram.asm) defines the `party_struct` macro:
```
party_struct: MACRO
box_struct \1
\1Status:: db
...
\1StructEnd::
ENDM
```
```
box_struct: MACRO
\1Species:: db
\1Item:: db
\1Moves:: ds NUM_MOVES
...
\1BoxEnd::
ENDM
```
That `ds NUM_MOVES` means that the label `wPartyMon1Moves` covers four bytes, not one (since `NUM_MOVES EQU 4` in [constants/battle_constants.asm](../blob/master/constants/battle_constants.asm)). Cheat codes can affect any of the four move bytes, but only one label exists.
|