Jambo51
Glory To Arstotzka
- 736
- Posts
- 14
- Years
- Seen Jan 28, 2018
As you will all know by now, certain trainers in FireRed have a pre-battle mugshot which is displayed as the music starts to play. What I want to do is have the game apply this pre-battle mugshot to any given trainer with any given picture.
AS ALWAYS, THESE ROUTINES ARE ONLY FOR BPRE 1.0!
The following routines give us full control over whether or not the battle will have a mugshot and indeed what pallet the game will load. This does require you to create a custom table with custom pallets for proper full customisation, but is fully compatible with the game's original pallets.
First thing's first, the game is quite clever with these pallets. It only uses the first 10 colours (including the transparent one) from the rom, and overwrites the rest with gender appropriate background colours for the player. It does this while the pallet is stored in a temporary location. This location is dynamic, so I haven't quite nailed down how it's obtained yet, but it's not important.
First, the part which allows it to be activated:
This first routine checks the trainerbattle's script for a byte which is otherwise unused (only the case in FireRed!). If this byte is 0x0, then it'll skip the new procedure and continue to load as normal (ie, it will still have mugshots for the elite 4 and the champion). If it is not 0x0, it will "pretend" to be champion class and load as if it was a champion battle. Works under the circumstances.
This routine changes the sprite which is loaded to the sprite which is used in the actual trainerbattle. You CANNOT use the player's sprites as opponents using their standard slots, as if it was possible, it would interfere with the loading of the player's sprite in the mugshot sequence. But every other sprite is useable here. Note that it has support for extended trainerbattle tables too, as it stands. No need to worry about changing pointers in this routine!
This final routine allows the hacker to change the background pallet of the mugshot. It uses the same byte as the activation to determine which pallet it should load, and it will load the same slot from table2. Ie, if you set the byte as 0x1, it will load the first slot on the table. Table2 does not exist within the rom, but it is simply a table of pointers to the pallets to use. So nothing horrendously complicated. Create your table, with pointers to valid pallets, and change the 0x08FFFFFF pointer to your new table.
These routines insert locations are as follows:
Musghot Hack One:
Insert at 0x0807FF90:
004A1047XXXXXX08
Mugshot Hack Two:
Insert at 0x08083862:
014C20470000XXXXXX08
Mugshot Pallet Hack:
Insert at 0x080D28C6:
014908470000XXXXXX08
As always, the XXXXXX08s represent your pointer to the routine's insert location plus 1 for thumb mode.
Finally, change the byte at 0x080801F5 to 0x78.
Now, once these routines are all present and correct, and you have some pallets set up, all you need to do is change how you write a script which requires a mugshot trainerbattle. This is NOT complicated compared to the set up, so here's hoping you'll be able to use it well.
What that means, if it's unclear, is that for pallet 1, you'd set the middle h-word as 0x100, pallet 2, 0x200 etc. This does NOT use any extra space, as the 0x0 (of the original trainerbattle) always stands for a half-word.
The game "Frankensteins" the pallets, glueing the chosen pallet for the battle with the relevant gender pallet for the player, then stores it to the actual pallet slot at 0x050001E0.
This covers just about everything related to the hack, except the pallet editing. Please note, these pallets are purely for the background of the mugshot. The overlayed sprites' pallets are loaded separately.
The pallets (for the in game mugshots) are at:
0x3FA660 (Agatha)
0x3FA680 (Bruno)
0x3FA6A0 (Lorelei)
0x3FA6C0 (Lance)
0x3FA6E0 (Gary Champion)
0x3FA700 (Male Player BG)
0x3FA720 (Female Player BG)
To replicate these pallets, and make them work, I recommend looking at them in APE, and messing around with them until you get the desired pallet.
AS ALWAYS, THESE ROUTINES ARE ONLY FOR BPRE 1.0!
The following routines give us full control over whether or not the battle will have a mugshot and indeed what pallet the game will load. This does require you to create a custom table with custom pallets for proper full customisation, but is fully compatible with the game's original pallets.
First thing's first, the game is quite clever with these pallets. It only uses the first 10 colours (including the transparent one) from the rom, and overwrites the rest with gender appropriate background colours for the player. It does this while the pallet is stored in a temporary location. This location is dynamic, so I haven't quite nailed down how it's obtained yet, but it's not important.
First, the part which allows it to be activated:
Code:
.text
.align 2
.thumb
.thumb_func
.global mugshothackone
main:
ldrb r5, [r4, #0x3]
lsl r5, r5, #0x18
lsr r5, r5, #0x18
cmp r5, #0x0
beq normalchecks
mov r1, #0x5A
ldr r5, returnone
bx r5
normalchecks: cmp r1, #0x57
bne later
add r1, r2, #0x0
mov r0, #0xCD
ldr r5, returntwo
bx r5
later: ldr r5, returnone
bx r5
.align
returntwo: .word 0x0807FFA5
returnone: .word 0x08080009
This first routine checks the trainerbattle's script for a byte which is otherwise unused (only the case in FireRed!). If this byte is 0x0, then it'll skip the new procedure and continue to load as normal (ie, it will still have mugshots for the elite 4 and the champion). If it is not 0x0, it will "pretend" to be champion class and load as if it was a champion battle. Works under the circumstances.
Code:
.text
.align 2
.thumb
.thumb_func
.global mugshothacktwo
main:
cmp r0, #0x87
beq there
cmp r0, #0x88
beq there
ldr r4, ramoffset
ldrh r4, [r4, #0x0]
lsl r5, r4, #0x2
add r5, r4, r5
lsl r4, r5, #0x3
ldr r5, place
ldr r5, [r5, #0x0]
add r0, r4, r5
ldrb r0, [r0, #0x3]
there: add r4, r0, #0x0
add r5, r1, #0x0
add r6, r2, #0x0
mov r9, r3
ldr r7, [sp, #0x34]
ldr r0, return
bx r0
.align
place: .word 0x08044028
ramoffset: .word 0x020386AE
return: .word 0x0808386D
This routine changes the sprite which is loaded to the sprite which is used in the actual trainerbattle. You CANNOT use the player's sprites as opponents using their standard slots, as if it was possible, it would interfere with the loading of the player's sprite in the mugshot sequence. But every other sprite is useable here. Note that it has support for extended trainerbattle tables too, as it stands. No need to worry about changing pointers in this routine!
Code:
.text
.align 2
.thumb
.thumb_func
.global mugshotpallethack
main:
ldr r1, ramoffset
ldrh r1, [r1, #0x0]
lsl r0, r1, #0x2
add r0, r0, r1
lsl r1, r0, #0x3
ldr r0, trainertable
ldr r0, [r0, #0x0]
add r1, r0, r1
ldrb r1, [r1, #0x1]
cmp r1, #0x5A
beq oldway
cmp r1, #0x57
beq oldway
ldr r1, ramoffset
ldrb r1, [r1, #0x3]
sub r1, #0x1
lsl r1, r1, #0x2
ldr r0, table2
add r1, r1, r0
ldr r0, [r1, #0x0]
b back
oldway: ldr r1, table
mov r2, r8
mov r3, #0x26
ldrh r0, [r2, r3]
lsl r0, r0, #0x2
add r0, r0, r1
ldr r0, [r0, #0x0]
back: ldr r1, return
bx r1
.align
ramoffset: .word 0x020386AE
trainertable: .word 0x08044028
table: .word 0x083FA740
table2: .word 0x08FFFFFF
return: .word 0x080D28D5
This final routine allows the hacker to change the background pallet of the mugshot. It uses the same byte as the activation to determine which pallet it should load, and it will load the same slot from table2. Ie, if you set the byte as 0x1, it will load the first slot on the table. Table2 does not exist within the rom, but it is simply a table of pointers to the pallets to use. So nothing horrendously complicated. Create your table, with pointers to valid pallets, and change the 0x08FFFFFF pointer to your new table.
These routines insert locations are as follows:
Musghot Hack One:
Insert at 0x0807FF90:
004A1047XXXXXX08
Mugshot Hack Two:
Insert at 0x08083862:
014C20470000XXXXXX08
Mugshot Pallet Hack:
Insert at 0x080D28C6:
014908470000XXXXXX08
As always, the XXXXXX08s represent your pointer to the routine's insert location plus 1 for thumb mode.
Finally, change the byte at 0x080801F5 to 0x78.
Now, once these routines are all present and correct, and you have some pallets set up, all you need to do is change how you write a script which requires a mugshot trainerbattle. This is NOT complicated compared to the set up, so here's hoping you'll be able to use it well.
Code:
trainerbattle [TYPE - BYTE] [TRAINER ID - HALF WORD] [MUGSHOT PALLET - BYTE AND 0x0 - BYTE] [MESSAGES]
What that means, if it's unclear, is that for pallet 1, you'd set the middle h-word as 0x100, pallet 2, 0x200 etc. This does NOT use any extra space, as the 0x0 (of the original trainerbattle) always stands for a half-word.
The game "Frankensteins" the pallets, glueing the chosen pallet for the battle with the relevant gender pallet for the player, then stores it to the actual pallet slot at 0x050001E0.
This covers just about everything related to the hack, except the pallet editing. Please note, these pallets are purely for the background of the mugshot. The overlayed sprites' pallets are loaded separately.
The pallets (for the in game mugshots) are at:
0x3FA660 (Agatha)
0x3FA680 (Bruno)
0x3FA6A0 (Lorelei)
0x3FA6C0 (Lance)
0x3FA6E0 (Gary Champion)
0x3FA700 (Male Player BG)
0x3FA720 (Female Player BG)
To replicate these pallets, and make them work, I recommend looking at them in APE, and messing around with them until you get the desired pallet.
Last edited: