• 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?".
  • 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: Exploring Ruby and Emerald

91
Posts
14
Years
  • Seen Feb 22, 2023
I can't really contribute anything to the following topic (for now) but has anyone ever researched the catch areas(As seen in the pokédex)? I know there is a huge document on it for FR by M_X but I was'nt able to figure it out in emerald yet.

~SBird
 

LCCoolJ95

Limited Capacity
638
Posts
14
Years
Well, I did find one handy piece of information by Chaos Rush that is very useful for anyone who does not like the animations in Emerald :)

Spoiler:

I have tested it personally and it worked very well so...here you go guys :)
 

Le pug

Creator of Pokémon: Discovery / Fat Kid
870
Posts
10
Years
I appreciate this thread very much : ]

I don't know if the port from FR to EM that shinyquagsire is the one I was trying to get him to do, but even though it's already an existing thread I feel it's being looked over yet if it was recognized, it could prove to be helpful for different things.

It's a port of a second message box on the screen. Two different types of the asm, one where the box size is re-sizable and one where it is not. Here is the original thread for FR: LINK

You could put a small box above the original textbox simply with the name of the person who is speaking or you could pull it up like how I plan to use it where it's mixed with other features for your game. Where the player chooses to either do a good or bad choice and whichever you choose affects your player score which you will be able to view before you make your decision. (Your level determines different events in the game, prices on items, etc)

And according to shinyquagsire, most of the work is already complete just some functions are harder to find. Here is the work thus far:

Spoiler:
 
180
Posts
10
Years
  • Age 34
  • Seen Jan 10, 2017
Copy 1 or 2 lines of bytes from the Fire Red pointer, and then search for that in Emerald. This almost always works, unless the function has been optimised so that the bytes aren't identical anymore, in which case you can continue searching for parts of it. Also, if you're searching for parts of a function, it is best to leave out BL bytes as those are always different between games.

While I've managed to do this with some simple features (merely just for testing it out), I can't seem to port the B/W2 Repel system to Emerald using this method.

These are the Fire Red Offsets I'm trying to find in Emerald

Spoiler:


I can find a few of them by searching for similar bytes in Emerald using a HEX-Editor. However, some of the HEX-codes in Fire Red seems to be non-existent in Emerald (which did not happen when I translated stuff like move animations).

Is there anyway to do more accurate searches than just looking at connected bytes? Such as letting the search skip a byte or two.
 
1,323
Posts
16
Years
  • Seen Dec 9, 2023
Is there anyway to do more accurate searches than just looking at connected bytes? Such as letting the search skip a byte or two.
Try using GoldFinger. It's a rather old but perfectly usable and simple hex editor that lets you search hex strings with missing bytes.
 
89
Posts
10
Years
Thanks, Chaos Rush. By the way, how did you find these limiters? Because I've been trying to add new attack animation backgrounds, but I suspect there is a limiter preventing me from doing so.
For example, the table is at 37F374. When I repoint it, then insert my BG image pointer, followed by the palette and tileset pointers. What I get is a messed up bunch of tiles. But when I replace BG 0x1 (the extra Dark-type BG)'s pointers with my Waterfall BG pointers, it works. The problem with such a method is that other animations which use the BG I replace will get affected, and I am both too lazy to manually replace all instances of 14 01 17 afraid of accidentally messing up another unrelated 14 01 17 if I replace everything.
Also, some extra Ruby tables- the battle terrain table is at 1F95B8, but I don't know how to add a new terrain and use it. The table's structure is (image pointer)(tilemap pointer)(animation before the battle terrain shows).
 
1,323
Posts
16
Years
  • Seen Dec 9, 2023
I'm trying to expand the Pokédex on Emerald using SBird's German ROM notes. First off, here is the save block hack ported to an English Emerald ROM:
Code:
.align 2
.thumb


/*
Instructions for English Emerald:
At 0x152E98 change to 0x00 0x48 0x00 0x47 POINTER_TO_ROUTINE
At 0x15284E change to 0x38 0x47
At 0x15288C change to POINTER_TO_ROUTINE+0x61
*/



/*cc left in first block
70 +70+70+108 = 258 in people block
8*70 + 820 = BA0 from box block
grand total of EC4 wasted space (9/10 of block wasted)
saved c000 to c0cc at first block (0x0)
saved c0cc to c324 at fifth block (0x4)
saved c324 to cec4 at 14th block (0xd)*/


/*at 080DA284, in the save routine, place a branch to this (in r0)*/
/*in pre-patched Fire Red, d9ef0*/
load_hijack:    ldr r1, [r4]
        mov r3, #0xff 
        lsl r3, r3, #0x4
        add r3, r3, r1
        ldrh r0, [r3, #0x4]
        cmp r0, #0x0
        beq first_cc_load
        cmp r0, #0x4
        beq middle_load
        cmp r0, #0xd
        beq last_load


load_ender:    cmp r5, #0xd
        ble next_loop_iter
        
        mov r0, #0x1
        pop {r3}
        mov r8, r3
        pop {r4-r7, pc}        

first_cc_load:    mov r1, #0xc4
        ldr r2, c0c8_addr
        b load_loop    
    
middle_load:    mov r1, #0x1d
        lsl r1, r1, #0x3
        ldr r2, c320_addr
        b load_loop

last_load:    mov r1, #0x41
        lsl r1, r1, #0x5
        ldr r2, cec0_addr
                

load_loop:    sub r3, #0x4
        ldr r0, [r3]
        str r0, [r2]
        sub r2, #0x4    
        sub r1, #0x4
        cmp r1, #0x0
        bne load_loop
        b load_ender
.hword 0x0000
c0c8_addr:    .word 0x0203c0c0
c320_addr:    .word 0x0203c1A8
cec0_addr:    .word 0x0203c9C8

next_loop_iter:    ldr r0, game_load_ret_addr
        bx r0
game_load_ret_addr:    .word 0x08152E2D
/*d9e85 for pre-patched*/


.word 0xffffffff
/*for the Save routine, we hijack before the save on Flash routine
that is located at 080D9CC6. Change there for bx r7, and at 080D9D04
place pointer to this*/
/*in pre-patched version is d9932 and d9970*/

store_hijack:    mov r7, #0xff
        lsl r7, r7, #0x4
        add r7, r1, r7
        strh r0, [r7,#0x6]
        ldrh r6, [r7, #0x4]
        cmp r6, #0x0
        beq first_store
        cmp r6, #0x4
        beq middle_store
        cmp r6, #0xd
        beq last_store

.hword 0x0000
store_ender:    ldr r0, game_store_ret_addr
        bx r0
game_store_ret_addr:    .word 0x08152853
/*in pre-patched return is d9937*/


first_store:    mov r3, #0xc4
        ldr r2, c0c8_addr_2
        b store_loop    
    
middle_store:    mov r3, #0x1D
        lsl r3, r3, #0x3
        ldr r2, c320_addr_2
        b store_loop

last_store:    mov r3, #0x41
        lsl r3, r3, #0x5
        ldr r2, cec0_addr_2

store_loop:    sub r7, #0x4
        ldr r0, [r2]
        str r0, [r7]
        sub r2, #0x4
        sub r3, #0x4
        cmp r3, #0x0
        bne store_loop
        b store_ender

c0c8_addr_2:    .word 0x0203c0c0
c320_addr_2:    .word 0x0203c1A8
cec0_addr_2:    .word 0x0203c9C8
I'm 90% sure I changed all the offsets correctly. To implement the save block hack, insert the above routine somewhere, and then:
152E98: 00 48 00 47 [XX XX XX 08]
15284E: 38 47
15288C: [YY YY YY 08]

0D9CC6: 38 47
0D9D04: [YY YY YY 08]
0DA284: 00 48 00 47 [XX XX XX 08]

XX XX XX 08 = offset of routine + 0x1
YY YY YY 08 = offset of routine + 0x61


As for finding the English ROM offsets from SBird's German ROM notes:
Spoiler:

Unfortunately this isn't enough to get everything working. I haven't added 0x700 to all 0x000006XX pointers yet though, as there's a crapload of them. Another problem is, I'm not sure how to repoint the Seen/Caught flags, because I'm not sure where they even are to begin with lol. So far I've got this:
OcFcDZZ.png

But there's tons of problems, such as the Seen/Caught indicator not showing up, the scrolling being glitchy (idk how to explain it), and sometimes just freezing for no reason lol. But hey, it's a start.

EDIT:
Ok, so from 0xBB6AC to 0xC21AC I replaced every instance of 0x000006XX to 0x00000DXX and the Pokédex, and it fixed a TON of glitches I was experiencing:
93IMIWJ.png

Now all I need help with is repointing the seen/caught flags. There's also this glitch where if you scroll up, the slots become blank (it can be fixed either just by scrolling down or using the left/right button to skip a few entries).
 
Last edited:
91
Posts
14
Years
  • Seen Feb 22, 2023
As for your seen caught flags there is a routine at 0x080C06FC that reads the caught flags, at 0x080C06AA reading the seen flags, at 0x080C07D8 writing the caught flags and at 0x080C079C writing the seen flags, they are loaded with some DMA adds and some other dohickies, your best bet is probably to just choose a static adress in a ram area that belongs to your newly obtained save area, which I by the way recommend you to use space from 0x0203D000 on, not 0x0203C000, I can't remember exactly why I made this decision, there where issues of course. Those rom adresses I did research are for BPEE already by the way, so no worries.

As for your glitchy scrolling: I probably forgot some of the global vars / they are different in the english version. What I did is set a break point (on read) on the Pokédex RAM which gets memallocated to about 0x02000010 + 0x600 something. This is where the original global vars begin. When you start scrolling you should break and with some research you can find a structure like mov rX, #V -> lsl rX, #V1 -> add rY, rX. This is calculating the global vars, I memalloced enough bytes(0x2000) to just add 1 to the lsl operation(I calculated it with the re-ejected reference and a calculator, but you are welcome to use an assembler)

I am glad someone tries to port this over to emerald english and would also welcome some sort of credits if anyone uses my notes(And chaos rush, because I know this transcribing can be a pain in the ass as well), because it literally took me hours to research all those manual calculated offsets(It's one of this works compared to copying values in and out of excel tables for the whole day, definitely not very funny :D)

Hope you manage to do it for the english version as well, I did not find any issues in the german one by now.

~SBird
 
1,323
Posts
16
Years
  • Seen Dec 9, 2023
As for your seen caught flags there is a routine at 0x080C06FC that reads the caught flags, at 0x080C06AA reading the seen flags, at 0x080C07D8 writing the caught flags and at 0x080C079C writing the seen flags, they are loaded with some DMA adds and some other dohickies, your best bet is probably to just choose a static adress in a ram area that belongs to your newly obtained save area, which I by the way recommend you to use space from 0x0203D000 on, not 0x0203C000, I can't remember exactly why I made this decision, there where issues of course. Those rom adresses I did research are for BPEE already by the way, so no worries.

As for your glitchy scrolling: I probably forgot some of the global vars / they are different in the english version. What I did is set a break point (on read) on the Pokédex RAM which gets memallocated to about 0x02000010 + 0x600 something. This is where the original global vars begin. When you start scrolling you should break and with some research you can find a structure like mov rX, #V -> lsl rX, #V1 -> add rY, rX. This is calculating the global vars, I memalloced enough bytes(0x2000) to just add 1 to the lsl operation(I calculated it with the re-ejected reference and a calculator, but you are welcome to use an assembler)

I am glad someone tries to port this over to emerald english and would also welcome some sort of credits if anyone uses my notes(And chaos rush, because I know this transcribing can be a pain in the ass as well), because it literally took me hours to research all those manual calculated offsets(It's one of this works compared to copying values in and out of excel tables for the whole day, definitely not very funny :D)

Hope you manage to do it for the english version as well, I did not find any issues in the german one by now.

~SBird
Actually when I repointed the Seen/Caught flags, the glitchy scrolling problem went away It seems that the glitchy scrolling problem only happens if I have gaps in the Pokédex. Right now it seemingly works perfectly except for the following problems:
*The flags aren't appearing to be writing to 0x0203D000 even though I made sure they're pointed to
*Scrolling in the dex around 490~ish freezes the game (99% sure it's flag-related)
*When pressing START while in the dex, if you press B without selecting a different dex mode, then the Pokédex list will be blank
*If you scroll up while there are gaps in the Pokédex, it will get a little glitchy

My guess as to what's wrong is that either I did the save block hack wrong, or I just need to pick a different offset for the seen/caught flags.

EDIT: and yes, once this is fully working and documented, of course you'll be credited :)

EDIT: I got the new flags working properly. Now the only problem I have is the glitchy scrolling when scrolling up through blank entries, and the issue where the list appears blank if you press START in the dex but don't change modes.
 
Last edited:

Le pug

Creator of Pokémon: Discovery / Fat Kid
870
Posts
10
Years
Anyone know if it's possible to increase the number of palettes and OWs as well as edit them for Emerald? I can see at this thread (LINK) that it is possible in FireRed using JPANs engine ... what I'm trying to figure out is did he change it around at all or did he just repoint a table to a new location to allow for more palette insertions?
 
91
Posts
14
Years
  • Seen Feb 22, 2023
Actually when I repointed the Seen/Caught flags, the glitchy scrolling problem went away It seems that the glitchy scrolling problem only happens if I have gaps in the Pokédex. Right now it seemingly works perfectly except for the following problems:
*The flags aren't appearing to be writing to 0x0203D000 even though I made sure they're pointed to
*Scrolling in the dex around 490~ish freezes the game (99% sure it's flag-related)
*When pressing START while in the dex, if you press B without selecting a different dex mode, then the Pokédex list will be blank
*If you scroll up while there are gaps in the Pokédex, it will get a little glitchy

My guess as to what's wrong is that either I did the save block hack wrong, or I just need to pick a different offset for the seen/caught flags.

EDIT: and yes, once this is fully working and documented, of course you'll be credited :)

EDIT: I got the new flags working properly. Now the only problem I have is the glitchy scrolling when scrolling up through blank entries, and the issue where the list appears blank if you press START in the dex but don't change modes.

Try finding the global vars via a debugger as I said above. I am quite sure the english version of emerald contains some differences to the german one. I had those glitches as well but as soon as I fixed all of the global vars (just by adding one to the value of any lsl opcodes that are responsible for the global var offsets) those glitches were fixed and the dex kept working.

I think I also have some german offsets I did not put into the post above, just because I researched them after posting, those should be:

@0x080be8c2: Manual calculus of offset (0x660) -> 09 01
@0x080bd05a: Manual calculus of offset (0x640) -> 12 01
@0x080bd074: Manual calculus of offset (0x640) -> 09 01
@0x080bd08e: Manual calculus of offset (0x640) -> 09 01

I never experieced the bug with the dex menu though. If it persits after you change those values there are definitely differences between the languages(Which I guess is because the C compiler operates differently after all the translations were done in both texts and images)

~SBird
 
1,323
Posts
16
Years
  • Seen Dec 9, 2023
Try finding the global vars via a debugger as I said above. I am quite sure the english version of emerald contains some differences to the german one. I had those glitches as well but as soon as I fixed all of the global vars (just by adding one to the value of any lsl opcodes that are responsible for the global var offsets) those glitches were fixed and the dex kept working.

I think I also have some german offsets I did not put into the post above, just because I researched them after posting, those should be:

@0x080be8c2: Manual calculus of offset (0x660) -> 09 01
@0x080bd05a: Manual calculus of offset (0x640) -> 12 01
@0x080bd074: Manual calculus of offset (0x640) -> 09 01
@0x080bd08e: Manual calculus of offset (0x640) -> 09 01

I never experieced the bug with the dex menu though. If it persits after you change those values there are definitely differences between the languages(Which I guess is because the C compiler operates differently after all the translations were done in both texts and images)

~SBird
Alright, so right now everything is working perfectly EXCEPT the problem that happens with the dex appearing blank when you enter and exit the mode change menu without doing anything. And yes, I found the routines that load the global variables, starting at around 080BB3C2 (although with inferences to your notes, the first variable to change is at BB6B8), but my question is: Did you actually write down every single offset of the variable? Because there's well over 100 of them! At first I just used a hex editor search and replace function to replace any instance of [__ 06 00 00] to [__ 0D 00 00] within the offsets 0xBB6AC-0xC217C (these are the english ROM offsets). But after several tests, I can confirm that something that I changed here is what's causing the blank list to appear, since I redid everything on a separate ROM and can confirm for sure that that's whats causing it. So then I resorted to looking through the routine and writing down every global variable offset, but I stopped after writing down nearly 50 of them, because from what it looks like there's at least 100+ or even 200+ of them. Did you use a search function, or did you actually painstakingly go through the routine and right down every one? If so, major respect to you, my friend.

(In case I didn't make sense, what I need to do is add 0x700 to every 0x000006XX, which is what I've done, but my method of doing it isn't 100% accurate and is causing the blank list glitch, even though I made sure I'm only overwriting offsets that are 4-byte aligned)
 
Last edited:
91
Posts
14
Years
  • Seen Feb 22, 2023
No I didn't go and record every single one I replaced, even though I made sure that the majority is in fact correct and used to define a global var in the pokedex script via the VBA disassembler. I actually wrote a script that goes through the routine and does what I need to do. It also checks if the offset is 4-aligned.

~SBird
 
1,323
Posts
16
Years
  • Seen Dec 9, 2023
Hey guys guess what ;)

Turns out there were a couple extra lsl rX, rX, #0x3 operations that weren't in SBird's notes so I went through parts of the routines and added 1 to them to see what works, and voila, this is now working.

I will post a tutorial soon :)
 
1,323
Posts
16
Years
  • Seen Dec 9, 2023
Hey Chaos Rush, that's fantastic! But, how many Pokémon can be added? Is it like in Fire Red, where it goes up to 1020, or is it less than that?
I'm not 100% sure, but I know that it can support at least 744, as when my flags weren't working properly, it would scroll that high when reading from an FFFFFFFFFFFFFFFFF area for the seen/caught flags.
 

LCCoolJ95

Limited Capacity
638
Posts
14
Years
I'm not 100% sure, but I know that it can support at least 744, as when my flags weren't working properly, it would scroll that high when reading from an FFFFFFFFFFFFFFFFF area for the seen/caught flags.
Whoa, that's good. I don't know why anyone would want that many in their game, but I won't question it hahaha
 
173
Posts
11
Years
  • Seen Jan 2, 2015
Whoa, that's good. I don't know why anyone would want that many in their game, but I won't question it hahaha

744 would be alright, if you wanted EVERY single pokemon from X/Y, and a bit more! But then... THAT would be a big hack... with that many pokemon... But... If someone DID achieve that, especially in an emerald rom, you can bet I'd play it... providing it uses good sprites, as in Chaos Rush's thread, and Mr. Dollsteak's thread! And I wonder how the battle frontier would go with that?
 
252
Posts
10
Years
  • Age 27
  • Seen Jul 6, 2019
So since this is the "Exploring R/S/E" thread, I think this might be a good place to re-post my reply to Artemis64 in the battle backgrounds tutorial. Hopefully someone can make heads and tails of what I've looked into. (I can't really hack as of now)
I think you meant 0x31ABA8. And it seems like Emerald's table format is a bit different from Firered's, so it looks like we'll need a custom routine.
I might as well contribute what I've discovered so far:
0x31ABA8 - 0x31AC6F: Contains 10 battle backgrounds, the outside battle backgrounds and 2 indoor battle backgrounds, I think.
D8 CC D7 08: A pointer to an indoor battle background. This battle background has tiles on it, and its used for places like the Aqua Hideout and the Elite Four. There's probably a separate loading routine, but I haven't looked into this yet.
0x35838: Has a pointer to the Rayquaza battle background (the one with the clouds). This is the only pointer in the rom that points to the Rayquaza battle background. I haven't looked into this either.

I don't have time to look into this, but I guess someone could look into this? Idk hope this helps somewhat.
 
Last edited:

xGal

Mhm
241
Posts
12
Years
LCCoolJ95 said:
expanding the amount of songs
I once made a tutorial on it. You do not need an ASM code for that, you can do it by moving the table to another location and adding this:
Code:
XX XX XX 08 00 YY 00 00
XX XX XX is replaced by the pointer and YY is replaced by 00. It can be replaced with 02 or 03 too, but it's more complicated.
 
Back
Top