• 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
    • 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
    12
    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
    11
    Years
    • 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