Hey there, I'm relatively new to this forum, but i've been kicking about on PC for a while and have built up a considerable list of useful ASM routines, mostly for FireRed (US) 1.0. I wanted to share these routines with other hackers, but always got the impression that the people (mods) over at PC didn't like me very much because I sided with Gamer2020 in his war of words with them.
Anyway, I decided to put this post up.
Stuff Needed:
Basic Hex Editing Knowledge
A Brain
A THUMB compiler - HackMew's is the best i've found so far
A Hex Editor - I use Hex Workshop
If you use these, you should credit me. If I credit anyone else in here, you should credit them too.
Each piece of ASM will be presented like this:
CODE - The actual ASM code
INSERTION LOCATION - Where to put the link to the new routine, and what hex bytes you will need to do it.
EXPLANATION - A short explanation of what the code does.
Without further ado, I present to you the ASM itself:
Trainer Encounter Music Hack:
Spoiler:
The code:
Code:
.text
.align 2
.thumb
.thumb_func
.global exclaimhack
main:
ldr r1, table
cmp r0, #0x14 /*This is the number of encounter music track you want
to have. If you use a value above this, it loads slot 3 of the table as a
failsafe*/
ble back
mov r0, #0x3
back: lsl r0, r0, #0x1
add r1, r0, r1
ldrh r0, [r1, #0x0]
ldr r1, place
bx r1
.align
place: .word 0x080806BB
table: .word 0xFFFFFFFF
Where to insert: In a hex editor, navigate to 0x80650, and overwrite the data there with this: 00 49 08 47 XX XX XX 08.
Where the XX's stand for the pointer to the new routine plus 1.
Explanation: All this does is reads the "music" byte which accompanies every trainer battle, and reads a newly created table. This table should have a half word for each entry. Which represent which music slot will be played for that music byte. Create your table wherever you like, then change the table: .word 0xFFFFFFFF to be a pointer to this new table.
Where to Insert: Navigate to 0x7F9F4 and change the bytes to 01 1C 00 00 00 48 00 47 XX XX XX 08.
Where the XX's stand for the pointer to the new routine plus 1.
Explanation: This routine reads what Pokémon species you are fighting, and searches a created table for that species. When it finds that species, it loads the associated music slot to modify what battle music you hear. If it doesn't find a matching species, it loads music slot 0x155 as standard.
The table should be set out as such:
Let's say you wanted Mewtwo to have slot 0x154, Mew to have slot 0x12B and Ho-oh to have slot 0x153. The table would be laid out like so:
9600 5401 9700 2B01 FA00 5301 FEFE 0000
In otherwords, you repeat this pattern until you want the table to end, which is were you put the "killing" half word. The number the routine looks for to mark the end of the table.
[Pokémon ID - Half word - in little endian (reverse hex)] [Music slot to load - Half word - little endian mode]
This table will only affect legendary battles which are run through special 0x138!
Where to insert: Anywhere! This routine is called from a script in the game, and as such, doesn't need to be carefully linked into existing routines. All you need to do is remember the rule of THUMB, add 1 to the offset when calling it!
Explanation: It's what it says on the tin, it lets you name your rival from the in game overworld, allowing for Silver like naming, or indeed, any other possibility you can come up with. The rivalname: .word 0x08FFFFFF is for if the player leaves the name box blank. It will fill it with a standard name instead. This standard name is up to you to create. Simply compile a name with XSE, and point that pointer to it.
You also need to put this routine in the game, or else it won't be able to load past the intro without naming the rival. All it does is temporarily write a holding name to the rival buffer so that the game doesn't crash.
Where to insert: Navigate to 0x54A6A, and change the following bytes to this:
01 49 08 47 00 00 XX XX XX 08.
Where the XX's stand for the pointer to the new routine plus 1.
Explanation: It simply writes a placeholder name into the [rival] buffer so the game doesn't crash. Obviously, you shouldn't be using the [rival] buffer until the player has named the rival, so it shouldn't be a problem.
To make this work, navigate to 0x130690, and change the pointer there to 0x1307D1.
Making Pre-Battle Mugshots available to all trainers:
Where to insert: Navigate to 0x83862, and replace the existing code with this:
01 4C 20 47 00 00 XX XX XX 08.
Where the XX's stand for the pointer to the new routine plus 1.
Explanation: This routine reads a what sprite the trainer you're about to battle has, and passes that index to the original routine, which then loads the appropriate sprite from there.
You will also need the following routine. This routine reads the trainerbattle script for a byte which tells it whether it should or should not load a mugshot.
Where to insert: Navigate to 0x7FF90, and replace the existing code with this:
00 4A 10 47 XX XX XX 08
Where the XX's stand for the pointer to the new routine plus 1.
Explanation: This code simply reads the trainerbattle script to judge whether or not it should load a mugshot. If the byte loaded is NOT 0, it will load a mugshot.
And the final piece of code, which allows us to control the background pallet of the mugshot, follows:
Where to insert: Navigate to 0xD28C6, and replace the existing code with this:
01 49 08 47 00 00 XX XX XX 08
Where the XX's stand for the pointer to the new routine plus 1.
Explanation: This routine reads the byte given by the trainerbattle script to determine which background pallet to load for the mugshot. The table2: .word 0x08FFFFFF is the location of a new table which contains pointers to the new pallets you can create for the mugshots. For an understanding of how these work, open 0x3FA6A0 in APE. This will show you how the pallets are constructed. You do NOT have to create 1 pallet for male and 1 for female, as the game actually works out which is needed, and sticks the relevant colours onto the end of the pallet you create. You also need to navigate to 0x801F5 and change the byte to 0x78.
How to use: Once the routines are present and correct, all you need to do to use the mugshots is write your trainerbattle like so:
Please note, the battle type makes no difference to the mugshots. It will work with any battle type.
Fixing the player not facing trainers:
Spoiler:
You need to call this routine from the edited script given at the end of this part.
The Code:
Code:
.text
.align 2
.thumb
.thumb_func
.global trainerface
main:
push {r0-r3,lr}
ldr r0, storeloc
ldrb r0, [r0, #0x0]
mov r1, #0x24
mul r0, r1
ldr r1, playerloc
add r0, r0, r1
ldrh r2, [r0, #0x10]
ldrh r3, [r1, #0x10]
cmp r2, r3
beq alternative
sub r2, r2, r3
cmp r2, #0x1
beq right
mov r0, #0x2
b end
right: mov r0, #0x3
b end
alternative: ldrh r2, [r0, #0x12]
ldrh r3, [r1, #0x12]
sub r2, r2, r3
cmp r2, #0x1
beq up
mov r0, #0x1
b end
up: mov r0, #0x0
end: ldr r1, lastresult
strh r0, [r1, #0x0]
pop {r0-r3,pc}
.align
storeloc: .word 0x03005074
playerloc: .word 0x02036E38
lastresult: .word 0x020370D0
Where to insert: Call from the script which follows.
Explanation: This simply reads the player's location against the trainer you're battling's location, and returns an assigned value which controls which way the player will look.
Where to insert: Compile this script wherever you like and note down it's location.
You must also change the pointer of the callasm to the location of the SECOND routine plus one. Then, navigate to 0x1A4EBD and 0x1A4F15, and change the pointers there to point to your new script.
Explanation: The actual script which makes the player turn and face opponents. You don't need to call it or anything, it's all done automatically in the background now.
These should all be completely bug free for the time being., but if anyone spots any bugs, hit me up and I'll try to get them fixed ASAP.
__________________
I have nothing interesting to add
Last edited by Jambo51; 25th October 2013 at 07:43 PM.
__________________
-Mewthree9000
We all fight a war within ourselves, a war of greatness, a war to become the best.
LIVE THE REVOLUTION, PHO!
Gotta Hack'em All!!