Thread: Research: FireRed Pokédex Hacking
View Single Post
Old April 16th, 2011 (6:10 AM). Edited November 16th, 2011 by Jambo51.
Jambo51's Avatar
Jambo51 Jambo51 is offline
Glory To Arstotzka
Join Date: Jun 2009
Gender: Male
Nature: Quiet
Posts: 731
OK, this is an area that we seem to have very little knowledge in. No FireRed hacks have regional pokédexes (that i'm aware of), and almost all hacks get around the evolution problem (national dex pokémon not evolving without the national dex) simply by awarding the national dex at the start of the game. While this is alright, and it works, it doesn't look very professional.

We also (understandably, due to the large number of limiting bytes/words (trust me, it's both as i've done some research into it)) haven't ever really put any concerted effort into extending the pokédex.
What i'm proposing is that a few of us work together to actually work out how plausible it is, or indeed even if it is plausible.

I can also post some of my research into the Pokédex, but please note it's still fairly limited. All of the information below is for FireRed.

Kanto Dex Limiting Bytes:
(Bear in mind that it loops the compare + 1 times, as it also loops on 0)
0x10352C - mov r1, #0x97
0x1035F6 - cmp r0, #0x96

Evolutions work without National Dex:
At 0xCE91A change the next 4 bytes to 00 00 14 E0. This makes the previously conditional branch into an unconditional branch, which fixes the evolutions.

Seen/Caught Flags:
There are 3 (yes, 3) sets of seen flags. I don't know why this is, but this would surely be a problem for any extension hack, as these would all need repointed to support more pokémon. These are all DMA protected, so it's impossible to give exact locations, but I do know how the game gets them, so i'll post that.

In all 3 cases, the game reads the ram location 0x0300500C for a base location, adds a specific amount to that base location, then adds the appropriate number of bytes to that to find the actual flag, the finally runs a flag decryption, but does not use the known flag decrypter at 0x6E6D0.

For the caught checks, the game runs the same routine, but passes it a different index. This makes the game check the caught flag instead of the seen flag. There are only 1 set of caught flags that i'm aware of. Again, they're DMA protected.

In any case, the routine which handles this, as well as the actual caught check, is at 0x104AB0.

These are the ones i've figured out so far:
R0 = Pokémon Species in in game index numbering.
R1 = Check Seen = 0, Check Caught = 1, Set Seen = 2, Set Caught = 3

Pokédex Information Page:
This is the page which opens up when you select a Pokémon's name on the Pokédex, and shows pertinent information to that Pokémon's species.

The routine again checks the caught flag (you can't select a species name if you've not seen it, of course), and then proceed to load the information from the Pokédex information table. This is an interesting routine, in that it reads from a static ram location (the Pokédex's ram location after writing etc, is actually static). It reads which NUMBER you've pressed on, and then loads the Pokédex slot from the ram location which matches that slot. In other words, there are a set of converting (National -> Regional) routines used here which are largely (if not completely) useless.

Anyway, since the information loaded is already in National Dex numbering, it loads the data in order from the Information table, which starts at 0x44E850, including Missingno's slot 0. All the data except the species name (Pidgey, Rattata etc, not Tiny Bird, Mouse etc), sprite and cry is loaded using this routine. This routine is at 0x1058C4. The exceptions named above are just written directly from the original Pokédex data.

Known Locations related to this:
0x44E850 - Pokédex Information Table - 0x24 Bytes per entry, with 412 (386 + 25 + 1) entries.
0x02003400 - Pokédex Ram Location - 0x8 bytes per entry, with 386 entries (expandable in theory). Stores a pointer to the species name (if seen, else stores the pointer to the blank entry), the Pokémon species ID (H-Word), and the seen/caught status (H-Word).
0x020033B0 - Current Pokédex Page - Only used like this if on a species page. Copies the second word of the actual pokédex ram to here.
0x020033B4 - Current Pokédex Slot. Don't know an awful lot more than this.
0x020033C2 - Byte representing which mode the Pokédex is in. 0x0 = Regional, 0x5 = National.
0x020033C8 - H-Word - limit of the Pokédex.
0x020033CA - 3 bytes which change on changing page on the information screens. They change to 0xFF's when changing, then change to 0x2, 0x3 and 0x4 when on a page.
0x020033DA - H-Word - Species ID for cry to play.
0x020033E2 - H-Word - Offset from top of Pokédex. How many scrolls down you are from top of Pokédex. Hard to explain.

Main Pokédex Page (Listing):
This is where most of the grunt work of the Pokédex is executed. The main routine starts at 0x103518. It checks what dex mode you're in, and loads the appropriate routine from a table, then mov PC, R0. It loads the Pokédex order from a table at 0x251FEE.

The rom then proceeds to check the caught/seen status of the first unchecked Pokémon in the dex, starting with Bulbasaur. If seen, it adds [Pokémon Species ID]*10 to the names array (0x08245EE0), and then stores the pointer at 0x02003400 + [Check Number*8]. It then writes the species ID as a halfword to 0x02003404 + [Check Number]*8. Then it finally writes the status of that slot's check into the following halfword.

Then it repeats until the check number becomes equal to the number of checks to be run. For the Kanto (Regional) Dex, that number is 0x96. For the National Dex, it's 0x181. We already have 411 Pokémon in the game (technically), so a good place to start would be getting the rom to show those extra 25 Pokémon on the dex.

The game limits the length the dex to the last SEEN pokémon by copying the ID of the current Pokémon being checked, IF it has been seen, to R10.

649 Patch Alpha 2 Available Here:
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Reply With Quote