• 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

LCCoolJ95

Limited Capacity
638
Posts
14
Years
SBird, I heard about your method. I saw that Emerald had a malloc system as well. I didn't have the proper tools to look further into it however (I'm not too sure on how to add ASM code yet, and I can't find HackMew's compiler anywhere). It's cool that you looked into it. So, it is possible to extend it, but way more complex than Fire Red's process?
 

Tlachtli

Crit happens.
267
Posts
12
Years
Tlachi, could you share your code that puts the Physical/Special/Status symbols on the summary and move learning screens? (Also, the small glimpses of your ROM that you're leaking through your sig look amazing. Great work!)

I'll be happy to, once I'm totally satisfied with how it works anyways. Right now it's appearing about 1-2 frames too early, which I know sounds unimportant but it's one of those things you can't un-see once you notice it. I'm still working on that at the moment.

ASM is not answer for everything. I wait for day when you all understand that.

As far as GBA hacking is concerned, it actually kinda is. ASM (assembly language) is as close to the actual machine code as you can get, and is the basis for just about everything that happens while a ROM operates.
 

AtecainCorp.

Rejishan awake...
1,377
Posts
15
Years
So. Is ASM is really handy? Why when I asking a lot of times do not get POINTER ADRESS for Pokemon Ruby Cries Table? I start do my own researches avoiding ASM by this fact. NO ONE GIVE ME THAT DAMIT POINTER WHICH I NEED. Only telling that ASM is EASY TO LEARN. Lying! Is not easy. When it was easy I've do not must found method which avoid ASM code.
 
91
Posts
14
Years
  • Seen Feb 22, 2023
So. Is ASM is really handy? Why when I asking a lot of times do not get POINTER ADRESS for Pokemon Ruby Cries Table? I start do my own researches avoiding ASM by this fact. NO ONE GIVE ME THAT DAMIT POINTER WHICH I NEED. Only telling that ASM is EASY TO LEARN. Lying! Is not easy. When it was easy I've do not must found method which avoid ASM code.
No offense, but what you are speaking is not even english, and that comes from a person who is not even a native lol...
However, I do not want to discuss this any further, if you want to use your method go ahead.
@LCCoolJ95: Yeah, you pretty much nailed it.

~SBird
 

AtecainCorp.

Rejishan awake...
1,377
Posts
15
Years
Ok. Do what you want. Blindly follow Karatekid522 and Jambo51 do not listen new and fresh methods which is easier and working. I don't care now.

And for all who said that I crush rom. I use my Method for remake of Pokemon Ruby. All works ideal without any failure.
 

LCCoolJ95

Limited Capacity
638
Posts
14
Years
@LCCoolJ95: Yeah, you pretty much nailed it.

~SBird
Oh my, that's incredible! You know, I always thought that it was. I'm not going to bug you over and over again about it because I don't want you to feel pressured on doing it. Take your time with it, I feel that waiting for expanding the amount of Pokémon in a game that I always hack is so worth it. Just one thing:

I looked at the tutorial on how to expand it in Fire Red, and it states that a patch called "JPAN's save block hack." Emerald doesn't have a patch like that, so how did you look into it?
 
252
Posts
10
Years
  • Age 27
  • Seen Jul 6, 2019
"JPAN's save block hack." - Is normaly SRAM patch. So every SRAM patcher and you can do it...
Emerald uses more memory then Firered, which means that JPAN's save block hack wouldn't work normally. You'd have to port it and make it suitable to Emerald.
 
91
Posts
14
Years
  • Seen Feb 22, 2023
As for the save hack take a look at this thread: http://www.pokecommunity.com/showthread.php?t=306202 The last snippet is working as stated and you just have to port it to your english version.

Also: I think I kind of did it for Emerald, however, I'm a german hacker and it was a pain in the ass to do this, therefore I won't port it to an english version because I'm sorry to say but I won't ever take advantage of it. You can have my notes on the german version, it's a bit cramped, but maybe you'll get the hang of how it is supposed to work:

Spoiler:


The last part is all memory, global vars and stuff like that, you'll just have to deal with it I guess...

~SBird
 

LCCoolJ95

Limited Capacity
638
Posts
14
Years
Well, I've thought about it for a little while now, and I've decided to do one thing...I'm going to take what SBird has found about expanding the amount of Pokémon and Pokédex entries in a german Emerald ROM, and port it to an English Emerald ROM. Emerald is my favorite game to hack, and I would love to see what has happened in Fire Red be incorporated in Emerald. Will it be hard? Of course, but I'm very patient. I also hope anyone wanting this will be as well.
 

Tlachtli

Crit happens.
267
Posts
12
Years
Protean.gif


I think I've finally worked the bugs out of Protean, and I'm 96% sure it'll work with no problem now. As promised here's the (Emerald BPEE) ASM for it, so hold on to your butts:

Code:
.align 2
.thumb

GetPokeTypes:
    push {r0-r5}
    ldr r1, .BattleData
    ldr r0, .CurPokeIndex
    ldrb r0, [r0]
    mov r2, #0x58
    mul r2, r0
    add r1, #0x21
    add r1, r2
    ldrh r0, [r1]
    mov r2, r0
    lsr r0, #2
    lsl r2, #24
    lsr r2, #24

GetMoveType:
    ldr r3, .CurMoveIndex
    ldrh r3, [r3]
    ldr r4, .MoveData
    mov r5, #0xC
    mul r5, r3
    add r4, r5
    add r4, #0x2
    ldrb r4, [r4]

ChangePokeType:
    cmp r0, r4
    beq End
    cmp r2, r4
    beq End
    lsl r4, #2
    ldr r5, .TypeList1
    add r5, r4
    mov r0, r5
    mov r2, #0x2
    sub r1, #0x1
    swi #0x0B
    ldr r0, .TypeList1
    ldr r1, .CheckForChange
    mov r2, #0x1
    swi #0x0B
    ldr r0, .TypeList2
    add r0, r4
    ldr r1, .TypeBuffer
    mov r2, #0x2
    swi #0x0B

End:
    pop {r0-r5}
    bx lr

.align 2
.BattleData:        .word 0x02024084
.CurPokeIndex:        .word 0x0202420B
.CurMoveIndex:        .word 0x020241EA
.MoveData:        .word 0x08E3E680
.CheckForChange:    .word 0x02024200
.TypeBuffer:        .word 0x02022F58
.TypeList1:        .word 0x[address1]
.TypeList2:        .word 0x[address2]
For TypeList1, copy this hex somewhere and use its start as address1:
Code:
6A 00 00 00 6A 01 01 00 6A 02 02 00 6A 03 03 00 6A 04 04 00 6A 05 05 00  6A 06 06 00 6A 07 07 00 6A 08 08 00 6A 09 09 00 6A 0A 0A 00 6A 0B 0B 00  6A 0C 0C 00 6A 0D 0D 00 6A 0E 0E 00 6A 0F 0F 00 6A 10 10 00 6A 11 11 00
For TypeList2, copy this hex somewhere and use its start as address2
Code:
FD 03 00 FF FD 03 01 FF FD 03 02 FF FD 03 03 FF FD 03 04 FF FD 03 05 FF  FD 03 06 FF FD 03 07 FF FD 03 08 FF FD 03 09 FF FD 03 0A FF FD 03 0B FF  FD 03 0C FF FD 03 0D FF FD 03 0E FF FD 03 0F FF FD 03 10 FF FD 03 11 FF
Now actually implementing it is the tricky part, it won't be a simple copy/paste job; you'll need some insight on what the battle scripts for different moves are actually doing to decide the appropriate place(s) to put ability checks. For any move you want to be affected by Protean you'll need to add a check for it somewhere in the battle script before calculatedamage. In order for a notification string to print out correctly callasm must be before printstring 0x49, and the printstring must be before attackcanceller. You should add a check to see if the user's ability is Protean, if so execute the ASM and optionally print a message if the type is changed, then jump back to the right point in the script. A potential script segment would look something like:

Code:
... (move script stuff is here) ...
jumpifability BANK_USER ABILITY_PROTEAN @Protean        /Note 1
goto 0x082D8A26                                         /Note 2

#org @Protean
callasm [address of Protean asm, plus 0x1]
jumpifbyte B_!= 0x02024200 0x0 @Change                  /Note 3
jumpifbyte B_= 0x02024200 0x0 @AttackCanceller

#org @Change
setbyte 0x02024200 0x0
printstring 0x49                                        /Note 4
waitmessage 0x40
goto @AttackCanceller

#org @AttackCanceller
attackcanceler
accuracycheck 0x82D8A5E 0x0
attackstring
ppreduce
calculatedamage
goto 0x82D8A34
Note 1: You'll either need to define ABILITY_PROTEAN in BSP's abilities.bsh, or just use the hex for the ability here instead.
Note 2: A goto jump to an address somewhere in the area of 0x082D8A26 usually signifies the end of a moves' unique scripting, as that jumps to a segment of script shared by nearly all damaging moves. In damaging moves I'd suggest putting the check for Protean before that jump. In status moves the jump may be different.
Note 3: The ASM for Protean does the following: gets the type of the move being used, checks it against the user's type(s), and if necessary changes type to match the move. If there is a type change it will always result in a monotype, if one is not needed though the Poke can retain a dual typing. If a type change is done the byte at 0x02024200 is set to a non-zero garbage byte (in this case 0x6A). This can be used to decide whether or not to display a message, and should be reset to 0x0 somewhere in the battle script.
Note 4: String 0x49 is "[User] transformed into the [Type] type!". This is the string used in Gen 6 games.

As a demo, here's the script I used while testing it. It changes Psybeam, Feint Attack, and Slash (all moves known by the Kecleon I was testing with). After compiling the test script change Psybeam's move effect (effect 76) pointer to match @Psybeam, and change Slash and Feint Attack (effects 43 and 17) to both match @Slash. You'll also need Jambo's callasm for BSP and to define Protean in abilities.bsh.
Spoiler:

Even though it seems complicated and may not be the most concise or elegant way to add Protean, it does indeed work. The only known issue is that when using Hidden Power it will change to Normal instead of the hidden type, but honestly it seems like a small issue and writing more asm to fix that is fairly low on my priority list.
 
1,323
Posts
16
Years
  • Seen Dec 9, 2023
One thing I feel that makes Ruby/Sapphire feel more "old" compared to FR/LG and Emerald is due to the way Ruby/Sapphire handles menu boxes.

In the Japanese Ruby/Sapphire, the menu box choice indicator was a black arrow, just like in FR/LG and Emerald. But in localized releases of Ruby/Sapphire, they changed the black arrow to a red box, which later came to bug me after FR/LG and Emerald. FR/LG and Emerald retained the black arrow from their respective Japanese versions, and simply got around any space problems by using one of the smaller fonts, such as the one used in the Pokémon's HP boxes in-battle. (The Japanese FR/LG and Emerald doesn't HP box font in those places, it was a localization change to make the names fit).

In the past few days, I have been working on a side project to make Ruby feel a bit less dated. Here is what I've done. On the left is vanilla Ruby, on the right is my modifications:
2yzd7k8.png


This wasn't a simple graphics change. For the START menu alone, what I had to do was:
1) insert Emerald's black arrow selector in some free space in a Ruby ROM
2) repoint one of the red box pointers to the black arrow
3) change a RAM pointer to a ROM offset in order to get the black arrow's palette to load correctly
4) extend the width of the START menu
5) reposition the text

(unrelated but I also took the screenshots on the right using an old font patch of mine that changes Ruby's font to Emerald)

Changing the graphics alone won't magically update all of your menu boxes, as the black arrow would overlap the text. What you have to do for every single menu box is to extend the width and reposition the text.

Here are my horribly disorganized notes that I've taken during this process. Please be aware that these notes are incomplete, as there a few more menu boxes that I haven't found the positioning for.
Spoiler:


I apologize for how horribly disorganized these notes are. Once I find all of the positioning stuff for every menu box, then I will explain these in detail and make a tutorial/patch or something.

Again, these notes are incomplete, and I'm only posting them so you guys can experiment. There are still many menu box position stuff that I have yet to find, such as in-battle move selection, the party screen, etc. By changing the red box to an arrow, it doesn't automatically fix all the menus, you have to reposition the text in every single menu box AND extend the width of almost every single menu box in order to get this to work.

EDIT: On Ruby, the bytes at 0802E16E and 0802E174 controls the positioning of the attack names during battle. I moved them one tile to the right to make room for my black arrow hack, and it still works fine. I even tested with attacks that have the max character limit and the black arrow doesn't overlap! This screenshot is proof that FR/LG and Emerald using a smaller font for attack selection is redundant. I actually think it looks a lot better with the main font.
087c7bdc97ece26105d13ff2c9de4318_500.png
 
Last edited:
89
Posts
10
Years
I've probably posted this elsewhere, but still.....

(refer to Chaos Rush's thread for the backgrounds)

To do a Attack Background, use 14 XX 17 (XX refers to a Background)

To do an Animated BG use 14 XX 17 03 59 3A 0E 08 05 04 00 FY 00 ZZ 00 00 00 FF FF

XX referring to a background, Y referring to the speed of the horizontal scrolling and ZZ referring to the speed of the vertical scrolling.

To clear such BGs, put 0E F3 61 1D 08 before the 08 at the end.

To color a background(e.g. Giga Drain) use 02 C4 B3 3D 08 02 05 01 00 XX 00 00 00 II 00 CC CC 05

To clear the color use 02 C4 B3 3D 08 02 05 01 00 SS 00 YY 00 00 00 CC CC 05 0B 03 0D

In this case SS referring to the speed of the transition, II the intensity of the color (0C for Giga Drain, 10 completely replaces the background with that color) and CC referring to the color.

Hope this helps with creating new animations for Pokémon Ruby.

Also I've found the Attack BG table, but there seems to be limiter bytes that stop me from adding more than 0x1A or 26 Backgrounds....
There also seems to be a limiter byte preventing Pokémon Ruby from loading more than 413 Pokémon, can anyone figure out where is it?

Edit: The Psychic BG command is 0E E7 61 1D 08.
I'm also making a list of particle pointers (e.g. the rotating fire before Dragon Claw) for Ruby, once I'm done will post them.
 
Last edited:
252
Posts
10
Years
  • Age 27
  • Seen Jul 6, 2019
I'm happy to say I can finally contribute something to Emerald hacking!

PokemonEmerald_01_zps28774f11.png


The battle background table starts at 0x525D54 and ends at 0x525E97, and the structure is the same as FireRed's.
Also, here are some of my notes on Emerald animations: (although I think people might already know this)

To do a scrolling background: 14 WW 17 03 61 76 11 08 05 04 00 XX 00 YY 00 00 FF FF
WW refers to the image of the background, XX and YY refer to the speed of the horizontal and vertical scrolling respectively.
To display a background: 14 WW 17
To clear a background: 0E DD 7C 2D 08

If I find any more commands, I will update this post.
 
1,323
Posts
16
Years
  • Seen Dec 9, 2023
Some of you may have noticed that in all of my Ruby-hacking related stuff, it has a hacked font. Some time ago I made a patch to change Ruby's font to Emerald, but I have yet to release it. Yesterday I finally found where Ruby's font width table is and finally perfected the patch, so here it is.

This patch is for Ruby. It does this:
*Changes the font to the one used in Emerald
*Changes the font width table to be identical to Emerald
*Changes the byte at 0x08056D62 to 0xE0 to enable Palette 12 to be used in tilesets (credit to colcolstyles)
 
Last edited:
89
Posts
10
Years
The attack BG table appears to be at 0x37F374 and ends at 0x37F4AB, but as I mentioned above, there appears to be a limiter byte that prevents loading more than 0x1A backgrounds.
For example, using the Waterfall BG, if I use it to overwrite BG 0x1 (the extra Dark-type BG) I can load it. However, if I place its Image/Tileset/Pallette pointers at the end it doesn't work and gives me a messed up screen.....
Edit: Forgot to mention, this is for Ruby.
 
89
Posts
10
Years
This is not really a contribution to Ruby & Emerald hacking per se, but rather a contribution to hacking in general.
I used Gen 4 fire sprites and modified them to be used in GBA. It's in the attachment.
 
Last edited:
89
Posts
10
Years
LCCoolJ95, could you pleaseprovide me with the patch for your Light Platinum fixes? I'm playing Light Platinum, and would really love not hearing Unown's cry every time I send out my Empoleon....
Also, do y'all still remember MrDollSteak's tutorial on adding new particles into FireRed? I have the table offsets for R/S/E handy here, but I can't seem to find the loader pointers he had at 728B7. For Ruby, while I think those are at 374B20 (since 369A48 roughly points to the same bytes as 399388), but I'm not sure. Can someone check this out?
The table offsets (ifI find the loader pointers I'll post them):
Ruby : 37E164
Sapphire : 37E0F4
Emerald : 524B44
Also, I've been trying to add new Pokémon to Ruby. However, I can't seem to find the limiter Chaos Rush/Jambo51 disabled to get the Pokémon working. If anyone knows this limiter,can they post it or PM it to me? Thanks.(And screw Pokédex expansion for now)
 
1,323
Posts
16
Years
  • Seen Dec 9, 2023
Also, I've been trying to add new Pokémon to Ruby. However, I can't seem to find the limiter Chaos Rush/Jambo51 disabled to get the Pokémon working. If anyone knows this limiter, can they post it or PM it to me? Thanks.(And screw Pokédex expansion for now)
Digging up some old notes, here's every instance of the bytes "CE 20 40 00" in a Ruby ROM:

[x]D310 <---makes sprites work during evolution
[x]D3EC <---makes sprites work
[ ]E9FA
[ ]10454
[ ]13B38 <---DO NOT CHANGE
[ ]2898E
[ ]2AFD4
[x]3DDAA <---Names
[ ]3FD42
[x]4038A <---Palettes
[x]405A4 <---Palettes
[x]40946 <---Palettes
[x]418CC <---Palettes
[x]77CEC <---Position
[x]77DB4 <---Position
[x]77E20 <---Position
[x]7A18C
[x]7A250
[x]7A328
[ ]81F12
[x]9D34E <---Icons
[x]9D45E <---Icons
[x]9D546 <---Icons
[x]9D5DE <---Icons
[ ]C5694
[ ]12663C
[ ]1266A2
[ ]13522C
[ ]143148

Change to "80 20 C0 00".

But don't change all of them, as the ones I've labeled are the ones I know for sure. The ones that are marked with [x] means it is confirmed that you have to change that limiter to get something working. The ones that are [ ] means it could possibly be a limiter, but I don't know what it does.
 

Shiny Quagsire

I'm Still Alive, Elsewhere
697
Posts
14
Years
I guess I'll throw in my two cents on the topic. As much as I love Ruby as a game, it's codebase is absolutely horrible. Now, we all know that GameFreak programmed these games in C, so this is in no way their fault but in fact a slight defect from using some of the first compilers released by Nintendo when the GBA was released. So is it workable? Maybe. There are still a few actual elements of the engine that are a bit of a mess so I will personally continue to use only Fire Red and Emerald.

As for Emerald, it is ridiculously easy to port ASM from Emerald to Fire Red and vice versa. I've done this countless times and only failed once. Heck, I ported an entire intro to Emerald once, and the Ruins of Alph. My point being, that in terms of Emerald support I am 100% in. It's a great engine and it's literally loaded with features. No issues there.

For those curious on how to find pieces of code between engines, I will say this (and you might think it to be a bit obvious, but it isn't always): 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.
 
Last edited:
Back
Top