PDA

View Full Version : Research: Pre-Battle Mugshots in FireRed


Jambo51
January 2nd, 2011, 02:49 PM
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:
.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.

.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!

.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.

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.

Teh Blazer
July 24th, 2011, 07:30 PM
I probably sound really stupid right now because the answer could be so simple, but how could we load the sprite so that it looks like the more recent ones with the faces (ex: http://www.pokestadium.com/pokemon/sprites/trainers/blackwhite/mugshot2.png)
but not replace the actual trainer sprites (ex: http://archives.bulbagarden.net/media/upload/8/80/Spr_BW_Cheren.png?

TheDarkShark
July 25th, 2011, 04:06 AM
When I'm on my own PC again, I'm gonna take a look into porting this over to BPRD (Firered German). But for now I only gotta say 'Awesome work, dude! I'm sure gonna use this!'

Jambo51
July 25th, 2011, 11:28 AM
I probably sound really stupid right now because the answer could be so simple, but how could we load the sprite so that it looks like the more recent ones with the faces (ex: http://www.pokestadium.com/pokemon/sprites/trainers/blackwhite/mugshot2.png)
but not replace the actual trainer sprites (ex: http://archives.bulbagarden.net/media/upload/8/80/Spr_BW_Cheren.png?

As of right now, no. We don't understand the code well enough to do it yet. However, if I can find the part of the code which scales up the sprite, and make it so that it's selectively called, (or not called at all) we could simply replace the sprite table pointer with a new table which has the mugshots on it.

When I'm on my own PC again, I'm gonna take a look into porting this over to BPRD (Firered German). But for now I only gotta say 'Awesome work, dude! I'm sure gonna use this!'

So long as you credit me with the original routines, feel free to do so!

Chaos Rush
July 25th, 2011, 06:34 PM
I'm just curious, but what parts of the ASM code needs to be changed in order for it to work with Pokemon Ruby?

DuoRyan
July 25th, 2011, 07:24 PM
What do you mean when we can't used the player sprite as a opponent?

Jambo51
July 26th, 2011, 04:53 AM
I'm just curious, but what parts of the ASM code needs to be changed in order for it to work with Pokemon Ruby?

Probably very little of it. You would need to find the parts of Ruby's code which are the equivalents of the parts I mentioned to hack in FR, change registers to work, and pointers. That's dependant on the actual mugshot code being in Ruby, which I think it is, IIRC.

What do you mean when we can't used the player sprite as a opponent?

The mugshot won't work with either of the player sprites, because if I had left that option open, then the game would have overwritten the player's sprite in the mugshot. I could probably do a minor rewrite to let the game support them though.

HackChu
August 25th, 2011, 01:41 PM
Be nice to do this to the gym leaders and boss rocket.

shinyabsol1
September 30th, 2011, 03:55 PM
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.

I've got this all working except for this part, because I don't understand what I am supposed to do. Specifically, the part in bold. Can someone please help me get this right?

I've learned a lot of things since I started rom hacking, but creating a new table is not one of them...

Full Metal
September 30th, 2011, 04:55 PM
A table with pointers is simply a sequence of pointers.
Eg:
080102030801030408010405
^ And so forth( Of course, fill in with actual pointers. That tends to work better )
You can put it anywhere you want, and whatever the 0x08FFFFFF pointer is, change that to repoint to your table. ( I would elaborate more, but I haven't actually red this tutorial )

shinyabsol1
September 30th, 2011, 07:47 PM
A table with pointers is simply a sequence of pointers.
Eg:
080102030801030408010405
^ And so forth( Of course, fill in with actual pointers. That tends to work better )
You can put it anywhere you want, and whatever the 0x08FFFFFF pointer is, change that to repoint to your table. ( I would elaborate more, but I haven't actually red this tutorial )

Thanks for helping out. Now I understand how pointer tables work, but I'm still having a problem. It did work once, but the game crashed the next time I tried to load the save file. I think that what I'm doing wrong has to do with the 0x8FFFFFF pointer. When the tut says to "change the 0x08FFFFFF pointer to your new table" does that mean to change it in the ASM code

Here:

...
table2: .word 0x08FFFFFF
...


or in the ROM itself? Also, what is the difference between the 08 being at the beginning of a pointer rather than the end?

Thanks again.

Jambo51
October 1st, 2011, 01:39 AM
Hello, my friend. A table (in Pokemon ROM hacking) is a list of data stored in the rom in a consistent format, usually used when there are multiple possible items which can use a piece of data.

In this case, you want to point the 0x08FFFFFF (either in the ASM file or in the ROM, just remember that doing it in the ROM means you need to reverse hex the pointer, while if you do it in the ASM file, it will be done automatically by the compiler) to some aligned free space (that is, the pointer ends with a 0, 4, 8 or C) and fill in the entries of the table with little endian pointers to the pallets which are to be used in the background of the mugshot.

Little Endian = Reverse Hex.

That should help you!

shinyabsol1
October 1st, 2011, 02:05 PM
Hello, my friend. A table (in Pokemon ROM hacking) is a list of data stored in the rom in a consistent format, usually used when there are multiple possible items which can use a piece of data.

In this case, you want to point the 0x08FFFFFF (either in the ASM file or in the ROM, just remember that doing it in the ROM means you need to reverse hex the pointer, while if you do it in the ASM file, it will be done automatically by the compiler) to some aligned free space (that is, the pointer ends with a 0, 4, 8 or C) and fill in the entries of the table with little endian pointers to the pallets which are to be used in the background of the mugshot.

Little Endian = Reverse Hex.

That should help you!

Thanks Jambo51. Now I understand what I was doing wrong and it works. Nice work figuring out how to do this, by the way. :)

Hackrex
December 11th, 2011, 05:58 AM
well what should I say....
In the firered english rom it works without any problems. In the german rom it doesn´t work. Of course I have researched and changed (in the scripts) the offsets in/for the german rom. I am really sure that this are the right offsets. But it doesn´t work. I think there is a small different between the german and the english rom. Can you please try it on a german rom and say what should I change? I can give you the researched offsets. I am sure that they are right. But it doesn´t work. Maybe the could be wrong....

Well I currently don´t know where I have my document. If you want the offsets and test (maybe make it work) for the german rom please PM me (or send me a PM, I don´t know how I have to write it in english).

Haru~
May 13th, 2012, 12:37 AM
I noticed that this doesn't seem to work when the trainerbattle type is 0x9 (the one with Prof. Oak's speech in-battle) even if the half-word is 0x100 and above.

Edit: Nevermind. I just made the routine make a flag check and so on and so forth...
This hack is really amazing, I love it! :)

LugiaMZ
September 2nd, 2012, 03:55 AM
Hello everyone, I have a question for this theard. Routine of this theard is for add a VS screen to any trainer?

Thanks.

LugiaMZ
September 4th, 2012, 07:10 AM
Yes.

------------------------

For now I don't know how to make a script to call mugshot, I already inserted routine, can you write a example script to me and explain the command? Another question, the 3rd background pallet routine I changed the 0x08FFFFFF to 0x08800000, so I need to write a pointer table? If that how to write the table to load my pallet? Or can directly change 0x08FFFFFF to my pallet offset?

Thanks.

shinyabsol1
September 12th, 2012, 04:50 PM
For now I don't know how to make a script to call mugshot, I already inserted routine, can you write a example script to me and explain the command?

Thanks.

All you have to do is change one thing in the trainerbattle command:

trainerbattle 0x 0x[Trainer ID] [B]0x0 [pointers to messages]

That's the part in bold. Instead of that byte being 0x0 as it usually is, change it to 0x100, 0x200, 0x300, etc... depending on the slot of the palette you want to use in your table. So 0x100 would be the first palette...and so on.

Another question, the 3rd background pallet routine I changed the 0x08FFFFFF to 0x08800000, so I need to write a pointer table? If that how to write the table to load my pallet? Or can directly change 0x08FFFFFF to my pallet offset?

If you have put 800000 in place of the Fs, then the ASM will think that your table is at 0x800000. So starting at that offset, put the pointers to your palettes.

LugiaMZ
September 15th, 2012, 01:51 AM
All you have to do is change one thing in the trainerbattle command:

trainerbattle 0x 0x[Trainer ID] [B]0x0 [pointers to messages]

That's the part in bold. Instead of that byte being 0x0 as it usually is, change it to 0x100, 0x200, 0x300, etc... depending on the slot of the palette you want to use in your table. So 0x100 would be the first palette...and so on.



If you have put 800000 in place of the Fs, then the ASM will think that your table is at 0x800000. So starting at that offset, put the pointers to your palettes.


Thanks for your help! Now I can add mugshot to my gym leader or some important character, thanks you very much.

tajaros
October 6th, 2012, 03:55 AM
How can you make sprites appear in the mugshots, do they have to be included in the table as well? :/ Repoint something? And can you make custom sprites appear?

Well, I'm gonna try this and see what happens... :)

Jambo51
October 6th, 2012, 04:09 AM
How can you make sprites appear in the mugshots, do they have to be included in the table as well? :/ Repoint something? And can you make custom sprites appear?

Well, I'm gonna try this and see what happens... :)

It automatically uses the sprite assigned to the trainer you are battling. So if you're battling Misty, it'll display Misty's sprite in the mugshot. The exception to that is when the trainer uses the hero/heroine sprite, if it uses either of those sprites, it loads Gary's sprite.

tajaros
October 6th, 2012, 04:11 AM
It automatically uses the sprite assigned to the trainer you are battling. So if you're barreling Misty, it'll display Misty's sprite in the mugshot.


Ohhh, but what about the palletes? :/

Jambo51
October 6th, 2012, 04:21 AM
Ohhh, but what about the palletes? :/

Read this very helpful post by shinyabsol1, it explains it rather well. :)

All you have to do is change one thing in the trainerbattle command:

trainerbattle 0x 0x[Trainer ID] [B]0x0 [pointers to messages]

That's the part in bold. Instead of that byte being 0x0 as it usually is, change it to 0x100, 0x200, 0x300, etc... depending on the slot of the palette you want to use in your table. So 0x100 would be the first palette...and so on.



If you have put 800000 in place of the Fs, then the ASM will think that your table is at 0x800000. So starting at that offset, put the pointers to your palettes.

tajaros
October 8th, 2012, 11:33 PM
Read this very helpful post by shinyabsol1, it explains it rather well. :)

OMG, I just made this work thanks for this Jambo51! :)

Omega Zero
January 14th, 2013, 07:56 PM
Hey, how do i get this to work with the Prof.oak dialogue version, the first battle with Blue?
0x9 0x? 0x100 doesn't work :|

interdpth
January 26th, 2013, 08:35 AM
If you still haven't figured out how the game loads the palettes, I don't mind helping as this is really interesting. Hit me up on AIM or something :)

HackChu
October 6th, 2013, 11:43 AM
What address do I insert these routines?

Hound of Justice
November 14th, 2013, 05:57 AM
What about trainers saying something to the player inside a battle when they have a last pokemon left or when they are ready to use a rare strong pokemon

I think this was in Diamond id like to see this in gba too

What about trainers saying something to the player inside a battle when they have a last pokemon left or when they are ready to use a rare strong pokemon

I think this was in Diamond id like to see this in gba too

designmadman
February 19th, 2014, 10:20 PM
Mmmph...for the last routine I inserted my table location but I'm not 100% sure how to put the pointers to the games existing palettes...I know dumb but inexperienced simple problem

Code:
... table2: .word 0x08800790 ...

I always get the picture of the sprites hand starting to show in the far left hand corner but then the screen freezes at this point with the music continuing to play...

pengoy
April 17th, 2014, 09:52 AM
im having troubles putting this in a rom, i followed the steps... but i always got an error upon activating the battle with a trainer and resets the game.

if this would help, i did this stuff...

1. changed the 0x8FFFFFF to 0x8800000 then point an existing palette with 3fa6a0 > a0 a6 3f 08
2. i put the hex codes of the .bins at 750001, 750041, 750071. ( should i put it in 750000~ etc. )

what am i doing wrong?

EDIT: I did manage to put it in the rom, the problem was the hex codes were in the "01" bytes... i put it to the '00" and it worked! YAY!


but there's only one sprite shown in the mugshots(both shows the same)... its the twins Tate & Liza... i tried to change the byte on the 2nd .bin, particularly the "1C" since 1C = 28, and the twin's sprite number is 28. i changed it and the sprite changes too, i thought it was supposed to show the trainer sprite im battling with? it shows a certain sprite no matter who i battle with.

http://i60.tinypic.com/ra56pe.png

RaileysXerilyasRX
June 8th, 2014, 04:09 AM
Nice job! This is the one I've been looking for! :D I've tried this on FireRed and it works well. :) So then, how to do this on Emerald?

Derlo
October 4th, 2014, 09:35 AM
Some questions:
1 - There's a strange problem when I use the sprite 106 (1st rival sprite)
the pallets crash and the rom freeze..
2 - We can not use the battle in which Prof. OAK gives us tips (Type: 0x09, 1st battle against rival), the value that decides if the comments will be or not shown, is where we put the palette. the value is 0x03, but if we put the value 0x1 to load the first palette and then 0x03 = 0x103, the musgshot animations isn't loaded...

someone know how to fix?

EDIT:
After a little research I could fix the "commented Battle against rival".
The problem is that the kind of battle 0x09, record the information in a different place of RAM, so the routine does not read it.
I made some changes in MugshotHackOne and MugshotPallet Hack routines:
/*In Bold... my changes. (I don't know ASM correctly .. so ... that was what I got. xD)
/* I use Goldroad to assemble it.
Musghot Hack One:

@define returntwo = 0x0807FFA5
@define returnone = 0x08080009
@define RAM = 0x020386ac


@thumb
thumb_code
main:
ldrb r5, [r4, #0x3]
lsl r5, r5, #0x18
lsr r5, r5, #0x18
ldr r3, RAM
ldrb r3, [r3]
cmp r3, #0x09
beq vs_oak_teach
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

vs_oak_teach:
mov r1, #0x5A
ldr r5, returnone
bx r5

Mugshot Pallet Hack

@define ramoffset = 0x020386AE
@define ramoffset2 = 0x020386ca
@define trainertable = 0x08044028
@define table = 0x083FA740
@define table2 = 0x08F00d70
@define return = 0x080D28D5

@thumb
thumb_code
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
r1, [r1, #0x1]
cmp r1, #0x5A
beq oldway
cmp r1, #0x57
beq oldway
ldr r1, ramoffset
ldr r3, RAM_color_cola
ldrb r3, [r3]
cmp r3, #0x00
beq write_PALSLOT
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

write_PALSLOT:
ldr r1, ramoffset2
ldrb r1, [r1, #0x3]
sub r1, #0x1
lsl r1, r1, #0x2
ldr r0, table2
add r1, r1, r0
ldr r0, [r1, #0x0]
b back



Just put them in their proper places and the battle will load the mugshot smoothly ...

Lance32497
October 18th, 2014, 11:20 PM
Create your table, with pointers to valid pallets, and change the 0x08FFFFFF pointer to your new table.

I dont get that part

so the table you are saying

TRAINER SPRITE POINTER TRAINER PALETTE POITER

or

00 00 08 08 1C 00 80 08 2C 00 80 08 3C 00 80 08 .....

Where:
00 00 80 08 is the trainer sprite #1 Pointer
1C 00 80 08 is the trainer palette #1 Pointer
2C 00 80 08 is the trainer sprite #2 Pointer
3C 00 80 08 is the trainer palette #3 Pointer

Am I right? Is that the table?

Lance32497
October 19th, 2014, 03:40 AM
Oh! by just reading comments made me understood how your tutorial works in a Firered rom..

The table is all about palette haha, no sprites, but last question.....

Can I use all palettes of all the trainers?

From Ordinary lass to Champion?
In the table, What is the limitation numbers of palette to be used?

Is it possible in 0x100, 0x200, 0x300 and so on and so forth to reach upto 0x2000?

Shiny Quagsire
October 19th, 2014, 01:30 PM
Oh! by just reading comments made me understood how your tutorial works in a Firered rom..

The table is all about palette haha, no sprites, but last question.....

Can I use all palettes of all the trainers?

From Ordinary lass to Champion?
In the table, What is the limitation numbers of palette to be used?

Is it possible in 0x100, 0x200, 0x300 and so on and so forth to reach upto 0x2000?
The palettes actually are referring to the palletes used behind the trainer, not the trainers themselves. So in terms of the trainer sprite, there are no limitations. However, for the background colors, that's where you need to set up those different palettes for each person you want to have this particular animation for.

Lance32497
October 19th, 2014, 04:42 PM
https://z-1-scontent-b.xx.fbcdn.net/hphotos-xfp1/v/t1.0-9/10704168_731301686937890_2389528263157514880_n.jpg?oh=ce60791331453c8745a8e6f020614df9&oe=54BD3899
https://z-n.ak.fbcdn.net/sphotos-f.ak/hphotos-ak-xpf1/v/t1.0-9/10639646_731301733604552_5621918755349453756_n.jpg?oh=26fc1cf8ad2b94f3129d065d479219b0&oe=54F0DB55&__gda__=1424638527_b58bab0ad180ab07398ce1803f46eae6
https://z-n.ak.fbcdn.net/sphotos-c.ak/hphotos-ak-xpf1/v/t1.0-9/10474732_731302746937784_6705316779450511358_n.jpg?oh=cd36c0ae32cdbdf1e12312140ac632a6&oe=54BA479E&__gda__=1421086452_48e8ca81b29c526055034d6831e7100a

I made it hehe