• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Forum moderator applications are now open! Click here for details.
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Research: FireRed Pokédex Hacking

Full Metal

C(++) Developer.
810
Posts
16
Years
In all honesty, it would probably be easier to just modify the routine that loads it.
Getting rid of it would be a pain in the arse.
0300500C is pointing to the second of three savegame blocks that change position to avoid overusing certain parts of the memory. The data in it is tightly packed.

08104AB0 uses 08104AFE or 08104B14 depending on whether R1 is 0 or 1.

Code:
R1=0 loc_08104AFE:
LDR     R0, =saveblock2
LDR     R0, [R0]
ADDS    R0, #0x5C @ Start of second flagdata
ADDS    R0, R0, R4 @ R4 contains flag-nr (=pokemon-nr minus 1) divided by 8
LDRB    R1, [R0]
ANDS    R1, R6 @ R6 has only one of the first 8 bits set
CMP     R1, #0
BEQ     loc_08104BB0

R1=1 loc_08104B14:
LDR     R0, =saveblock2
LDR     R2, [R0]
MOVS    R0, R2
ADDS    R0, #0x28 @ Start of first flagdata
ADDS    R0, R0, R4 @ R4 like above
LDRB    R1, [R0]
ANDS    R1, R6 @ R6 like above
CMP     R1, #0
BEQ     loc_08104BB0

Because the first data starts at 0x28 and ends at 0x5C you only have enough place for (0x5C-0x28)*8 pokemon. (=416) Unless you know how to repoint in savegames you have these size constraints.

Think you could point us to the routine that saves the seen/caught flag data? :)
 
Last edited:

Jambo51

Glory To Arstotzka
736
Posts
14
Years
  • Seen Jan 28, 2018
Progress is fun!

http://www.youtube.com/watch?v=ze0vPh63mEM
Sorry, I have no idea how to actually embed it in the post, so have a link instead!

Here we have video evidence of 649 Pokémon appearing in FireRed's Pokédex. As things stand, I haven't inserted the sprites or cries, or most of their stats, but NONE of what I just mentioned is routine related. Most of them (the ones with stats) are valid battlers too, so I think I can honestly say I'll have this finished within the next couple of days if I find the time.

Also shown in this video is the Kanto dex, reorganised into a regional dex. The length and order of this dex is entirely up to the hacker, but being based on LC and all, I decided to give it an appropriate pokédex order, and made the Kanto dex into the New Pokédex from GSC.
 
Last edited:

Full Metal

C(++) Developer.
810
Posts
16
Years
Please do share how you accomplished this!
I would gladly dedicate my next (programming) project to this. :)
 

Gamer2020

Accept no Imitations!
1,062
Posts
15
Years
http://www.youtube.com/watch?v=ze0vPh63mEM
Sorry, I have no idea how to actually embed it in the post, so have a link instead!

Here we have video evidence of 649 Pokémon appearing in FireRed's Pokédex. As things stand, I haven't inserted the sprites or cries, or most of their stats, but NONE of what I just mentioned is routine related. Most of them (the ones with stats) are valid battlers too, so I think I can honestly say I'll have this finished within the next couple of days if I find the time.

Also shown in this video is the Kanto dex, reorganised into a regional dex. The length and order of this dex is entirely up to the hacker, but being based on LC and all, I decided to give it an appropriate pokédex order, and made the Kanto dex into the New Pokédex from GSC.

Not bad, I did that months ago. You figure out how to expand the seen/caught in the RAM yet? Cause that is the hard part...
 

Jambo51

Glory To Arstotzka
736
Posts
14
Years
  • Seen Jan 28, 2018
Not bad, I did that months ago. You figure out how to expand the seen/caught in the RAM yet? Cause that is the hard part...

Yeah, that was the first thing I did because I figured that the rest of it wouldn't work without that first.

@Full Metal
I'm still ironing out some bugs related to the hack, but when I make it bug free, I'll release the information.
I'm relatively happy to allow people to use it once it's bug free!
 
Last edited:

Gamer2020

Accept no Imitations!
1,062
Posts
15
Years
Yeah, that was the first thing I did because I figured that the rest of it wouldn't work without that first.

@Full Metal
I'm still ironing out some bugs related to the hack, but when I make it bug free, I'll release the information.
I'm relatively happy to allow people to use it once it's bug free!

Using the following routine, I was able to repoint and extend the seen and caught flags for Pokémon to a free RAM location. The new routine has support for 656 caught flags, and 656 seen flags (as close to 649 as I could get using the 8 bits to a byte system, obviously aiming for the gen 5 total here!). Bear in mind however, that the routine is only limited by how much free space you allocate it. If we were to use a full save block to store caught and seen flags (which is possible using JPAN's save block hack!), we would be limited to a maximum of 10,240 pokémon. This is clearly more than enough XD.

The routine actually simplifies on the original greatly and as such, it's more open to bugs and oddities. Instead of having 3 separate sets of caught and seen flags, I reduced it to 1 longer set, pointed to a different RAM location. The only issue I have with the routine is that the new block of ram is NOT saved when saving the game.

Code:
.text
.align 2
.thumb
.thumb_func
.global seencaughtflagsrepoint
main:
 add r3, r0, #0x0
 add r5, r1, #0x0
 lsl r2, r2, #0x18
 sub r0, r3, #0x1
 lsl r0, r0, #0x10
 lsr r3, r0, #0x10
 lsr r4, r0, #0x13
 mov r0, #0x7
 and r3, r0
 mov r0, #0x80
 lsl r0, r0, #0x11
 lsl r0, r3
 lsr r6, r0, #0x18
 mov r0, #0x0
 mov r12, r0
 cmp r5, #0x1
 beq caughtcheck
 cmp r5, #0x2
 beq setseen
 cmp r5, #0x3
 beq setcaught
 cmp r5, #0x0
 beq seencheck
 b end
seencheck: ldr r0, newblock
there: add r0, r0, r4
 ldrb r1, [r0, #0x0]
 and r1, r6
 cmp r1, #0x0
 beq end
 mov r0, #0x1
 mov r12, r0
 b end
caughtcheck: ldr r0, newblock
 add r0, #0x52
 b there
setseen: ldr r1, newblock
there2: add r1, r1, r4
 ldrb r2, [r1, #0x0]
 add r0, r6, #0x0
 orr r0, r2
 strb r0, [r1, #0x0]
 b end
setcaught: ldr r1, newblock
 add r1, #0x52
 b there2
end: mov r0, r12
 pop {r4-r7}
 pop {r1}
 bx r1
.align
newblock: .word 0x0203E400
This routine could theoretically be inserted directly over the original routine as it is smaller than it. If you wish to do so, paste my routine into the rom starting at 0x104AB2. However, it is substantially safer to insert it with a ldr bx combo. Up to you I guess. If you want to use a ldr bx combo, use Register 3.

As you can see, it sets up the new caught/seen flags at 0x0203E400 (seen) and 0x0203E452 (caught). That's 82 (0x52) bytes for each set, which equates to 656 caught and seen flags.

It uses a total of 164 bytes to safely store all the relevant bits. This is (again) actually smaller than what the original rom uses just to store 416 bits worth of flags. However, because all the data isn't concurrent, we can't use that for our new data.

The routine is pretty much self explanatory, and isn't complicated to the point of being unintelligible. This solves our first BIG problem related to the expansion of the Pokédex. Now if I could just get the block to save using jpan's hack, i'd be sorted. :)

Oh is that what that is? I really didn't notice that as I scrolled down. I'll take a better look at it tomorrow when I wake up. I want to compare it to the original routine and stuff.
I'm actually working on doing this to Emerald for my hack. I already have been able to add more Pokemon but the seen/caught is everybody's biggest problem I think.
 

Jambo51

Glory To Arstotzka
736
Posts
14
Years
  • Seen Jan 28, 2018
I actually managed to get it all working, and then somehow completely mucked it up while (I believe) trying to insert a cry. Trying to replicate it on a clean rom now, but having issues with the Pokédex screen not working. I have noted down as many definite limiters as I can find, but I basically have to start over. I hate the cries! XD
 

Gamer2020

Accept no Imitations!
1,062
Posts
15
Years
I actually managed to get it all working, and then somehow completely mucked it up while (I believe) trying to insert a cry. Trying to replicate it on a clean rom now, but having issues with the Pokédex screen not working. I have noted down as many definite limiters as I can find, but I basically have to start over. I hate the cries! XD

Just make constant back ups and stuff. I made a tool to do all the repointing and expanding for me. All I need is to solve the Pokedex problem.

Did you properly repoint everything? Keep in mind you still need to put the egg and unowns after the Pokemon that includes the icons.
 
Last edited:

Full Metal

C(++) Developer.
810
Posts
16
Years
Just wondering...why don't we use the games own 'malloc' ?
( and of course, save a pointer to it, and such ) ?
 

Jambo51

Glory To Arstotzka
736
Posts
14
Years
  • Seen Jan 28, 2018
For those who've been asking, I will probably release this publically as a patch when I've finished inserting all the data. This will mean it can't be used on a hack which is in progress. I'll most likely highlight the significant data in the patch so that people can copy it over to their roms if they want to use it on an already started hack. Of course, the patch will only be for BPRE as I simply don't have the time to sit and translate all the data and limiters over to another rom.

Current Patch Progress:
Limiters (100%)
Names (100%)
Front Sprites (100%)
Back Sprites (42% - Up to and including Servine in - No shiny pallets though)
Pokémon Data (100%)
Pokédex Entries (90% - Need to edit scale for comparison for nearly all, but everything else is in)
Movesets (0%)
TM/HM Compatibilities (5%)
Evolution Data (100%)
Evolution Types Added (100%)
Icons (60%)
Cries (100%)
Footprints (0%)
Pokédex Habitat Data (100%)

As you can see, there is a LOT of stuff to be done before I can truly call it complete. The routines work, yes, but that's about it.
 
Last edited:

Full Metal

C(++) Developer.
810
Posts
16
Years
Will you also document it and release the info? ( I'm genuinely curious about it X) )
And also, this weekend after I update Bytes And Bits. I would gladly help out in any way I can! :)
 

Jambo51

Glory To Arstotzka
736
Posts
14
Years
  • Seen Jan 28, 2018
Will you also document it and release the info? ( I'm genuinely curious about it X) )
And also, this weekend after I update Bytes And Bits. I would gladly help out in any way I can! :)

Yeah, of course i'll release documentation to go with it. It'd be a bit daft to release the patch, and then have people try to work it all out for themselves.

Most of the hard work has been completed, with all but one routine working from what I can see, and that shouldn't be too hard to fix. Interestingly, as a side effect of fixing the Unown sprites, I came across how the game generates the Unown, and could theoretically hack that to produce controllable Unown encounters.

What I mean by that is, the hacker can set what Unown s/he wants to appear on a certain map, or even control it with variables/flags. We can FINALLY have proper GSC style Unown controlled by completing those puzzles!
 

Full Metal

C(++) Developer.
810
Posts
16
Years
That would seem to be more or less a waste of space -- having a separate stat listing for every possible unknown. :\
 

Meta Paradox

Researching FireRed...
56
Posts
12
Years
  • Seen Jul 18, 2011
Hmm... you guys could edit and control the Unown that can appear on each map now, right? So if you're adding the Sinnoh and Unova listings, why not try to edit some more for the controlled changing of formes for some Pokemon? Lie Cherrim's Overcast Forme appearing only in sunlight, or when giving a certain item to Giratina or Shaymin (possibly a Griseous Orb or Gracidea) that will change their formes. This is especially neccesary for Arceus, with seventeen Plates that can change its forme AND type. So, how about it? :D
 

Jambo51

Glory To Arstotzka
736
Posts
14
Years
  • Seen Jan 28, 2018
Hmm... you guys could edit and control the Unown that can appear on each map now, right? So if you're adding the Sinnoh and Unova listings, why not try to edit some more for the controlled changing of formes for some Pokemon? Lie Cherrim's Overcast Forme appearing only in sunlight, or when giving a certain item to Giratina or Shaymin (possibly a Griseous Orb or Gracidea) that will change their formes. This is especially neccesary for Arceus, with seventeen Plates that can change its forme AND type. So, how about it? :D

And what if I told you i've already started doing some of the basic work needed for that...? I can already switch sprites around based on forme checks, although, I still haven't worked out a way to do type changes.

EDIT: I think that type isn't actually stored in the Pokémon's data. I think the game automatically reads the actual data table stored in the rom to determine type. In order to get TYPE changing formes, I was thinking of have the game run a set of extra checks, firstly checking the pokémon against a list of Pokémon which have formes and which type of forme (male/female sprite (Pikachu), simple sprite switch (Shellos and Gastrodon), sprite and type switch (Arceus)), and then, if it has a forme, run the appropriate check to see if the sprite needs switching. For the type, i'll need to run a LOT of extra checks. Basically, any read of the type of any given Pokémon (whether in Battle, or in status screen - Note that the Pokédex could support it too, but it's better not to really), will need to have those extra checks running and modifying the type behaviours for each given Pokémon individually.

In other words, we have forme 1 Burmy and forme 2 Burmy in our party. The check will get run for BOTH Burmys as it will match one of the forme checks, the first one will return Bug/Grass Type and Sprite number 1 (because of location or whatever it is that changes a Burmy's forme), while the second will return Bug/Steel Type and Sprite number 2. Does that make sense?

How I would go about doing it, would be to have a 650 byte long table (an entry for each Pokémon species) with the following key:
0 - No Forme
1 - Simple Sprite Switch (Including Male/Female Formes)
2 - Sprite and Type Switch

0 Speaks for itself. 1 would run appropriate checks for the species you pass it (if you pass it 0x19, it will check the Pokémon's gender, and then load the appropriate sprite, if you pass it 0x1A6 it will check where the Pokémon was caught, and load the appropriate sprite).
2 is more difficult. It would run a similar check to 1, but it would also have to force the game to bypass reading the normal Pokémon Stats Data, and make it read a separate set of data with a separate set of types.
 
Last edited:
4
Posts
15
Years
  • Seen Sep 9, 2011
Would it be possible to consider two different Pokemon to be the same Pokemon? That way we could have 28 Unowns that are created the same as other Unowns, 2/3 pikachus that are treated the same, and 7 or so of the one legendary. That would mean less hardcoded checks, but still wouldn't cover, say, cast-form.

Of course, I'm reverting to my Yuri's Revenge sensibilities, when this is more Tiberian Dawn style ASM.
 
Back
Top