Code ASM Resource Thread Page 29

Started by esperance September 19th, 2014 3:13 PM
  • 437395 views
  • 1599 replies

chrunch

Male
Seen December 10th, 2021
Posted February 24th, 2021
1,343 posts
12.7 Years
You probably messed up pointers. Try doing it again and make sure all your pointers are correct.



It seems that TMs are still consumable if taught to a pokemon without animation, i.e. if it only knows 2 moves.
There's already a fix for this here.
Male
Seen July 29th, 2018
Posted December 5th, 2016
39 posts
7 Years
Hello, since the EXP. Gain canceller had been effin'ly implemented, it's good to have MONEY gain and reduce canceller so that we can make a Battle frontier-like event.
Request
Temporarily disabling prize money from battle

(Only works in FireRed)

Here is a routine that will prevent you from getting money after you won a battle against a trainer. Good for tournament-style battles, where it makes no sense that you get or lose money.

How to insert:

Compile and insert this routine anywhere into free space:
Spoiler:
.text
.align 2
.thumb
.thumb_func

main:
    push {r0-r3}
    mov r0, #0xFF
    lsl r0, r0, #0x1
    add r0, r0, #0x5
    ldr r2, =(0x806E6D0 +1)
    bl linker
    cmp r0, #0x1
    beq skip
    pop {r0-r3}
    mov r0, #0x0
    mov r1, r8
    ldr r0, [r1]
    mov r1, #0xa4
    lsl r1, r1, #0x2
    add r0, r0, r1
    add r1, r4, #0x0
    ldr r2, =(0x809FDA0 +1)
    bl linker
    ldr r1, =(0x8025A00 +1)
    bx r1
    
skip:
    pop {r0-r3}
    mov r0, #0x0
    mov r1, r8
    ldr r0, [r1]
    mov r1, #0xa4
    lsl r1, r1, #0x2
    add r0, r0, r1
    add r1, r4, #0x0
    ldr r1, =(0x8025A00 +1)
    bx r1
    
linker:
    bx r2
    
.align 2
(not really space saving, i know...)

Compiled:
0F B4 FF 20 40 00 05 30 0E 4A 00 F0 19 F8 01 28 0C D0 0F BC 00 20 41 46 08 68 A4 21 89 00 40 18 21 1C 09 4A 00 F0 0C F8 08 49 08 47 0F BC 00 20 41 46 08 68 A4 21 89 00 40 18 21 1C 03 49 08 47 10 47 C0 46 D1 E6 06 08 A1 FD 09 08 01 5A 02 08

Now navigate to 0x0259E8 and insert following bytes:
00 48 00 47 XX XX XX 08
Where XX XX XX is the location of the routine you inserted + 1.


Next compile and insert this routine into free space:
Spoiler:
.text
.align 2
.thumb
.thumb_func

main:
    mov r0, #0xFF
    lsl r0, r0, #0x1
    add r0, r0, #0x5
    ldr r2, =(0x806E6D0 +1)
    bl linker
    cmp r0, #0x1
    beq skip
    add r0, r4, #0x0
    ldr r2, =(0x809fdd8 +1)
    bl linker
    
skip:
    ldr r2, =(0x80a0058 +1)
    bl linker
    ldr r2, =(0x8054BEA +1)
    
linker:
    bx r2
    
.align 2
Compiled:
FF 20 40 00 05 30 07 4A 00 F0 0A F8 01 28 03 D0 20 1C 05 4A 00 F0 04 F8 04 4A 00 F0 01 F8 04 4A 10 47 C0 46 D1 E6 06 08 D9 FD 09 08 59 00 0A 08 EB 4B 05 08

Finally navigate to 0x054BE0 and insert following bytes where XX XX XX is the location of the second routine +1:
00 48 00 47 XX XX XX 08
This thing requires two routines, that's because the money gets reduced when you black out while the prize money is gained after the message appears. These are two different places so there have to be two different functions :P


At last you should also want to remove the text that appears after winning/losing that informs you about the money you gained/lost. You need another routine for that. Compile and insert into free space:
Spoiler:

.text
.align 2
.thumb
.thumb_func

main:
    ldr r0, =(0x83fb432)
    cmp r2, r0
    beq checkflag
    ldr r0, =(0x83fb4f6)
    cmp r2, r0
    beq checkflag
    b noskip

checkflag:
    mov r0, #0xFF
    lsl r0, r0, #0x1
    add r0, r0, #0x5
    ldr r3, =(0x806E6D0 +1)
    bl linker
    cmp r0, #0x1
    beq skip

noskip:
    ldr r0, =(0x202298C)
    mov r1, #0x0
    ldr r3, =(0x80D87BC +1)
    bl linker
    
skip:
    ldr r0, =(0x8032B4C +1)
    bx r0
    
linker:
    bx r3

.align 2
Compiled:
0B 48 82 42 03 D0 0B 48 82 42 00 D0 07 E0 FF 20 40 00 05 30 08 4B 00 F0 09 F8 01 28 04 D0 07 48 00 21 07 4B 00 F0 02 F8 06 48 00 47 18 47 C0 46 32 B4 3F 08 F6 B4 3F 08 D1 E6 06 08 8C 29 02 02 BD 87 0D 08 4D 2B 03 08

Now change the bytes at 0x032B44 to following (XX XX XX) is the location of this last routine:
00 48 00 47 XX XX XX 08
How to use:

In order to disable prize money you have to set the flag 0x203.
If you want to reenable it just clear the flag and you will get money again.
I should type my signature now but lazy people nev

Joexv

ManMadeOfGouda
joexv.github.io

Age 24
Male
Oregon
Seen 2 Days Ago
Posted April 8th, 2022
1,034 posts
9.7 Years
Temporarily disabling prize money from battle


Here is a routine that will prevent you from getting money after you won a battle against a trainer. Note that the message telling you about your prize money still shows up, iI am working on that. I'll update the post later with the final version because I don't have much time today. EDIT: I just realized ita lso doesn't work when you lose, so just wait a bit and dont insert it yet...


How to insert:

Compile and insert this routine anywhere into free space:
Spoiler:
.text
.align 2
.thumb
.thumb_func

main:
    push {r0-r3}
    mov r0, #0xFF
    lsl r0, r0, #0x1
    add r0, r0, #0x5
    ldr r2, =(0x806E6D0 +1)
    bl linker
    cmp r0, #0x1
    beq skip
    pop {r0-r3}
    mov r0, #0x0
    mov r1, r8
    ldr r0, [r1]
    mov r1, #0xa4
    lsl r1, r1, #0x2
    add r0, r0, r1
    add r1, r4, #0x0
    ldr r2, =(0x809FDA0 +1)
    bl linker
    ldr r1, =(0x8025A00 +1)
    bx r1
    
skip:
    pop {r0-r3}
    mov r0, #0x0
    mov r1, r8
    ldr r0, [r1]
    mov r1, #0xa4
    lsl r1, r1, #0x2
    add r0, r0, r1
    add r1, r4, #0x0
    ldr r1, =(0x8025A00 +1)
    bx r1
    
linker:
    bx r2
    
.align 2
(not really space saving, i know...)

Compiled:
0F B4 FF 20 40 00 05 30 0E 4A 00 F0 19 F8 01 28 0C D0 0F BC 00 20 41 46 08 68 A4 21 89 00 40 18 21 1C 09 4A 00 F0 0C F8 08 49 08 47 0F BC 00 20 41 46 08 68 A4 21 89 00 40 18 21 1C 03 49 08 47 10 47 C0 46 D1 E6 06 08 A1 FD 09 08 01 5A 02 08


Now navigate to 0x0259E8 and insert following bytes:
00 48 00 47 XX XX XX 08
Where XX XX XX is the location of the routine you inserted + 1.


How to use:

In order to disable prize money you have to set the flag 0x203.
If you want to reenable it just clear the flag and you will get money again.
The location of the text is 0x3FB41A, there seem to be only one pointer to it, its setup in a table along with various other winning/losing messages which appears to start at 0x3FDF3C. Hope this helps.
New living flesh vessel who dis?
Male
california
Seen May 19th, 2022
Posted May 7th, 2021
277 posts
7.4 Years
You probably messed up pointers. Try doing it again and make sure all your pointers are correct.



It seems that TMs are still consumable if taught to a pokemon without animation, i.e. if it only knows 2 moves.
Where XX XX XX is the location of the routine you inserted + 1.
I don't really get what the "+1" means. That's probably where I messed up.

Deokishisu

Mr. Magius

Male
If I'm online, it's a safe bet I'm at a computer.
Seen 43 Minutes Ago
Posted 21 Hours Ago
948 posts
16.4 Years
I don't really get what the "+1" means. That's probably where I messed up.
If you put the routine at 0x800000, your pointer would NOT be 00 00 80 08, it would be 01 00 80 08, as if the location was 0x800001. It's a THUMB quirk, I think.
Seen January 7th, 2017
Posted August 6th, 2016
58 posts
6.8 Years
I would like to make a request: wild double battle in Pkmn FR version
Based on JPAN's document on battle scripts, we can change a word in the EWRAM to change the battle type. However, simply putting a hook at the function storing type to that location is obviously with several bugs so I hope that someone will get the full source code and share it, thanks!

esperance

Age 25
Male
OH
Seen 3 Weeks Ago
Posted January 11th, 2022
3,831 posts
12.3 Years

Day/Night Switching of Textbox Palettes (FireRed)


So this is one of my few successful ASM hacks. What it does is swap the palettes used by the textbox depending on whether it is day or night (based on Prime Dialga's D/N system). Some of you older users may remember such a feature being implemented by Shiny Quagsire for Pokémon Grey (iirc).

So the first thing you need to do is go to 0x471DEC and copy 0xA0 bytes there, and then paste them into freespace somewhere. Be sure to note the offset. These are the five palettes used by the textboxes. You can use this copy as the base for your new night palettes.

Next, assemble and insert the following routine into freespace, once again noting the offset. Be sure to replace the ZZZZZZ with the offset of your new night palettes.
.text
.align 2
.thumb
.thumb_func

main:
  @ get the time
  ldr r1, =(0x300553C) @ if your RTC uses a different location for the time, change this
  ldrb r1, [r1, #0x6]

  @ check the time
  @ if <= 6 AM or >= 6 PM
  @   load night palette
  @ else
  @   load day palette
  cmp r1, #0x6 @ 6 AM
  ble set_night
  cmp r1, #0x12 @ 6 PM
  bge set_night

set_day:
  ldr r1, day_palette
  b return

set_night:
  ldr r1, night_palette

return:
  @ this uses the end of the original function
  @ so there should be no problems
  add r0, r0, r1
  pop {r1}
  bx r1

.align 2

day_palette:
  .word 0x08471DEC

night_palette:
  .word 0x08ZZZZZZ @ change this to your night palette
Now finally, navigate to 0x150448 and place this (the hook):
00 49 08 47 XX XX XX 08 00 00 00 00
Where XX XX XX 08 is the pointer to the location you inserted the ASM + 1.

I know it's a bit of a silly hack, but I hope someone makes use of it! :)
What are you so afraid of?
Male
california
Seen May 19th, 2022
Posted May 7th, 2021
277 posts
7.4 Years
If you put the routine at 0x800000, your pointer would NOT be 00 00 80 08, it would be 01 00 80 08, as if the location was 0x800001. It's a THUMB quirk, I think.
So it's just +1 for the first byte? Also, for every asm pointer, do I always have to add +1?
Seen January 7th, 2017
Posted August 6th, 2016
58 posts
6.8 Years
for every asm pointer, do I always have to add +1?
No, that depends on the way to jump to the code.
If you use bx (or callasm in script, which also use bx to jump to the code), you should add 1 if the code is in thumb mode as is always the case.
If you use another way to branch, such as
ldr r0, .addr
mov pc, r0
.align 2
.addr: [offset of your code]
This kind of code don't need to add 1 to the pointer of the code it jumps to.
But most people use bx to jump, so adding 1 is often required.
Male
Seen November 12th, 2021
Posted April 30th, 2020
218 posts
8.9 Years
I know there's several routines like this one, but I didn't found them practical.

Check a specific pokémon with a specific slot through the use of Special 0xA2, for Emerald :
Spoiler:

.thumb

Start:
	push {r0-r7, lr}
	ldr r6, var8005
	ldr r0, party_amount
	ldrb r4, [r0]
	cmp r4, #0x0
	beq End
	ldrh r3, [r6]
	cmp r3, #0x0
	beq End
Check:
	add r0, #3
	mov r1, #0x64
	ldr r7, var8004
	ldrb r6, [r7]
	mul r1, r6
	add r0, r0, r1
	push {r0-r7}
	mov r1, #0xB
	ldr r2, decrypt_poke
	bl Jump
	mov r9, r0
	pop {r0-r7}
	cmp r9, r3
	bne NoSuccess
	mov r6, #1
	b Success
NoSuccess:
	mov r6, #0
Success:
	ldr r7, var8005
	strh r6, [r7]

End:
	pop {r0-r7, pc}
Jump:
mov pc, r2
	
.align 2
party_amount:	.word 0x020244E9
var8004:		.word 0x020275D8 + (0x8004*2)
var8005:		.word 0x020275D8 + (0x8005*2)
decrypt_poke:	.word 0x0806A519

/*var 0x8005, species you want to check*/
Basically, when you use special 0xA2, the party screen open and you can select a poke, the slot of the poke is stored in var 0x8004, so the routine check this slot.
If it is the the same species than 0x8005, then 0x8005 is set to 1, otherwise to 0

Le pug

Creator of Pokémon: Discovery / Fat Kid

Age 29
Male
Le bed
Seen November 18th, 2021
Posted February 18th, 2021
874 posts
8.9 Years
Spoiler:
Temporarily disabling prize money from battle


Here is a routine that will prevent you from getting money after you won a battle against a trainer. Good for tournament-style battles, where it makes no sense that you get or lose money.

How to insert:

Compile and insert this routine anywhere into free space:
Spoiler:
.text
.align 2
.thumb
.thumb_func

main:
    push {r0-r3}
    mov r0, #0xFF
    lsl r0, r0, #0x1
    add r0, r0, #0x5
    ldr r2, =(0x806E6D0 +1)
    bl linker
    cmp r0, #0x1
    beq skip
    pop {r0-r3}
    mov r0, #0x0
    mov r1, r8
    ldr r0, [r1]
    mov r1, #0xa4
    lsl r1, r1, #0x2
    add r0, r0, r1
    add r1, r4, #0x0
    ldr r2, =(0x809FDA0 +1)
    bl linker
    ldr r1, =(0x8025A00 +1)
    bx r1
    
skip:
    pop {r0-r3}
    mov r0, #0x0
    mov r1, r8
    ldr r0, [r1]
    mov r1, #0xa4
    lsl r1, r1, #0x2
    add r0, r0, r1
    add r1, r4, #0x0
    ldr r1, =(0x8025A00 +1)
    bx r1
    
linker:
    bx r2
    
.align 2
(not really space saving, i know...)

Compiled:
0F B4 FF 20 40 00 05 30 0E 4A 00 F0 19 F8 01 28 0C D0 0F BC 00 20 41 46 08 68 A4 21 89 00 40 18 21 1C 09 4A 00 F0 0C F8 08 49 08 47 0F BC 00 20 41 46 08 68 A4 21 89 00 40 18 21 1C 03 49 08 47 10 47 C0 46 D1 E6 06 08 A1 FD 09 08 01 5A 02 08

Now navigate to 0x0259E8 and insert following bytes:
00 48 00 47 XX XX XX 08
Where XX XX XX is the location of the routine you inserted + 1.


Next compile and insert this routine into free space:
Spoiler:
.text
.align 2
.thumb
.thumb_func

main:
    mov r0, #0xFF
    lsl r0, r0, #0x1
    add r0, r0, #0x5
    ldr r2, =(0x806E6D0 +1)
    bl linker
    cmp r0, #0x1
    beq skip
    add r0, r4, #0x0
    ldr r2, =(0x809fdd8 +1)
    bl linker
    
skip:
    ldr r2, =(0x80a0058 +1)
    bl linker
    ldr r2, =(0x8054BEA +1)
    
linker:
    bx r2
    
.align 2
Compiled:
FF 20 40 00 05 30 07 4A 00 F0 0A F8 01 28 03 D0 20 1C 05 4A 00 F0 04 F8 04 4A 00 F0 01 F8 04 4A 10 47 C0 46 D1 E6 06 08 D9 FD 09 08 59 00 0A 08 EB 4B 05 08

Finally navigate to 0x054BE0 and insert following bytes where XX XX XX is the location of the second routine +1:
00 48 00 47 XX XX XX 08
This thing requires two routines, that's because the money gets reduced when you black out while the prize money is gained after the message appears. These are two different places so there have to be two different functions :P


At last you should also want to remove the text that appears after winning/losing that informs you about the money you gained/lost. You need another routine for that. Compile and insert into free space:
Spoiler:

.text
.align 2
.thumb
.thumb_func

main:
    ldr r0, =(0x83fb432)
    cmp r2, r0
    beq checkflag
    ldr r0, =(0x83fb4f6)
    cmp r2, r0
    beq checkflag
    b noskip

checkflag:
    mov r0, #0xFF
    lsl r0, r0, #0x1
    add r0, r0, #0x5
    ldr r3, =(0x806E6D0 +1)
    bl linker
    cmp r0, #0x1
    beq skip

noskip:
    ldr r0, =(0x202298C)
    mov r1, #0x0
    ldr r3, =(0x80D87BC +1)
    bl linker
    
skip:
    ldr r0, =(0x8032B4C +1)
    bx r0
    
linker:
    bx r3

.align 2
Compiled:
0B 48 82 42 03 D0 0B 48 82 42 00 D0 07 E0 FF 20 40 00 05 30 08 4B 00 F0 09 F8 01 28 04 D0 07 48 00 21 07 4B 00 F0 02 F8 06 48 00 47 18 47 C0 46 32 B4 3F 08 F6 B4 3F 08 D1 E6 06 08 8C 29 02 02 BD 87 0D 08 4D 2B 03 08

Now change the bytes at 0x032B44 to following (XX XX XX) is the location of this last routine:
00 48 00 47 XX XX XX 08
How to use:

In order to disable prize money you have to set the flag 0x203.
If you want to reenable it just clear the flag and you will get money again.
Requesting this in Emerald. Great resource and besides tournaments, it can be used for trainer-battle styled wild pokemon battles (obviously they dont give you $)
Retired. Thank you guys for a wonderful five years.

Ephraim225

Freaky Frillish Guy

Male
In America
Seen December 2nd, 2020
Posted December 3rd, 2019
161 posts
9 Years
Checking HM Compatibility
Hey guys, I've got a fun one for you. If you're like me and hate wasting move slots on HMs, this hack will make that a thing of the past. This hack checks whether the player's team contains a Pokemon that can learn an HM you specify. It doesn't check if they actually HAVE it, only whether they CAN learn it. Used correctly, the player can simply walk up to a tree and cut it immediately if they have a Pokémon that can cut. This is for Fire Red but porting it should be simple if you know the equivalent offsets in Emerald (and I don't, if someone does, let me know and I'll update this post)

Compile and insert to free space:
Spoiler:
.align 2
.thumb

start:
push {r0-r5, lr}
mov r5, #0x0

loopback:
ldr r0, =(0x2024284) /* Player's party in RAM */
mov r2, #0x64
mov r1, r5
mul r1, r1, r2
add r0, r0, r1
mov r1, #0xB
ldr r3, =(0x803FBE8 +1) /* Pokemon decrypter */
bl linker

ldr r3, =(0x8252BD0) /* TM Compatibility table */
lsl r0, r0, #0x3
add r3, r0, r3
add r3, r3, #0x6
ldrb r2, [r3]
ldr r1, =(0x20370D0) /* Var 0x800D in RAM */
ldrb r0, [r1]
mov r3, r0
and r3, r2, r3
cmp r0, r3
beq end

ldr r3, =(0x2024029) /* Player's team size */
ldrb r3, [r3]
add r5, r5, #0x1
cmp r5, r3
beq endfail
b loopback

end:
strb r5, [r1]
pop {r0-r5, pc}

endfail:
mov r5, #0x6
strb r5, [r1]
pop {r0-r5, pc}

linker:
bx r3


NOTE: Before you compile, direct your attention to the line highlighted in blue. The offset here is the offset of the table that determines TM/HM compatibility. If you have expanded the number of Pokémon in your hack, be sure to change this offset to whatever the new offset is.

Now, using this ASM is simple. In whatever script you're writing, first set variable 0x800D (aka LASTRESULT) to one of the following values based on the HM you are checking:

Spoiler:
0x4 - Cut
0x8 - Fly
0x10 - Surf
0x20 - Strength
0x40 - Flash
0x80 - Rock Smash


Then, call the ASM using Callasm. After the ASM runs, variable 0x800D will be set to the party slot containing the Pokémon who can learn whatever move you checked for, or 0x6 if no Pokémon was found.

The only issue is, Fly and Flash aren't used in scripts by the game, and Dive and Waterfall can't be checked. Making items that perform the same functions using other methods, however, is a working substitute.

Here's an example script. Let's say I'm editing the cut tree script. (If you remove the badge check and attack check as I have you can actually overwrite the original script with this, as there's enough space for it)
Spoiler:
#org 0x81BDF13
'-----------------------------------
special INIT_STEPCOUNT
compare LASTRESULT 0x2
if == jump 0x81A7AE0 ' Equal To
lockall
setvar LASTRESULT 0x4
callasm 0x8XXXXXX ' This should be changed to wherever you put the ASM in your ROM

compare LASTRESULT 0x6
if == jump 0x81BDF87 ' This skips the rest of the script if 0x6 is returned
setanimation 0x0 0x800D
storepartypokemon 0x0 0x800D
storeattack 0x1 0xF
msgbox 0x81BDF94 ' This tree looks like...
callstd MSG_YESNO ' Yes/No message
compare LASTRESULT NO
if == jump 0x81BDF91 ' Equal To
msgbox 0x81BDFD7 ' \v\h02 used \v\h03!
callstd MSG_NOCLOSE ' Non-closing message
closemsg
doanimation 0x2
waitspecial
jump 0x81BDF76


Anyways, that's that. I'll be using this in the future, but I do hope others can make use of it too.

FBI

Free supporter

Male
Unknown Island
Seen 11 Hours Ago
Posted 2 Weeks Ago
1,925 posts
9.4 Years
Checking HM Compatibility
Hey guys, I've got a fun one for you. If you're like me and hate wasting move slots on HMs, this hack will make that a thing of the past. This hack checks whether the player's team contains a Pokemon that can learn an HM you specify. It doesn't check if they actually HAVE it, only whether they CAN learn it. Used correctly, the player can simply walk up to a tree and cut it immediately if they have a Pokémon that can cut. This is for Fire Red but porting it should be simple if you know the equivalent offsets in Emerald (and I don't, if someone does, let me know and I'll update this post)

Compile and insert to free space:
Spoiler:
.align 2
.thumb

start:
push {r0-r5, lr}
mov r5, #0x0

loopback:
ldr r0, =(0x2024284) /* Player's party in RAM */
mov r2, #0x64
mov r1, r5
mul r1, r1, r2
add r0, r0, r1
mov r1, #0xB
ldr r3, =(0x803FBE8 +1) /* Pokemon decrypter */
bl linker

ldr r3, =(0x8252BD0) /* TM Compatibility table */
lsl r0, r0, #0x3
add r3, r0, r3
add r3, r3, #0x6
ldrb r2, [r3]
ldr r1, =(0x20370D0) /* Var 0x800D in RAM */
ldrb r0, [r1]
mov r3, r0
and r3, r2, r3
cmp r0, r3
beq end

ldr r3, =(0x2024029) /* Player's team size */
ldrb r3, [r3]
add r5, r5, #0x1
cmp r5, r3
beq endfail
b loopback

end:
strb r5, [r1]
pop {r0-r5, pc}

endfail:
mov r5, #0x6
strb r5, [r1]
pop {r0-r5, pc}

linker:
bx r3


NOTE: Before you compile, direct your attention to the line highlighted in blue. The offset here is the offset of the table that determines TM/HM compatibility. If you have expanded the number of Pokémon in your hack, be sure to change this offset to whatever the new offset is.

Now, using this ASM is simple. In whatever script you're writing, first set variable 0x800D (aka LASTRESULT) to one of the following values based on the HM you are checking:

Spoiler:
0x4 - Cut
0x8 - Fly
0x10 - Surf
0x20 - Strength
0x40 - Flash
0x80 - Rock Smash


Then, call the ASM using Callasm. After the ASM runs, variable 0x800D will be set to the party slot containing the Pokémon who can learn whatever move you checked for, or 0x6 if no Pokémon was found.

The only issue is, Fly and Flash aren't used in scripts by the game, and Dive and Waterfall can't be checked. Making items that perform the same functions using other methods, however, is a working substitute.

Here's an example script. Let's say I'm editing the cut tree script. (If you remove the badge check and attack check as I have you can actually overwrite the original script with this, as there's enough space for it)
Spoiler:
#org 0x81BDF13
'-----------------------------------
special INIT_STEPCOUNT
compare LASTRESULT 0x2
if == jump 0x81A7AE0 ' Equal To
lockall
setvar LASTRESULT 0x4
callasm 0x8XXXXXX ' This should be changed to wherever you put the ASM in your ROM

compare LASTRESULT 0x6
if == jump 0x81BDF87 ' This skips the rest of the script if 0x6 is returned
setanimation 0x0 0x800D
storepartypokemon 0x0 0x800D
storeattack 0x1 0xF
msgbox 0x81BDF94 ' This tree looks like...
callstd MSG_YESNO ' Yes/No message
compare LASTRESULT NO
if == jump 0x81BDF91 ' Equal To
msgbox 0x81BDFD7 ' \v\h02 used \v\h03!
callstd MSG_NOCLOSE ' Non-closing message
closemsg
doanimation 0x2
waitspecial
jump 0x81BDF76


Anyways, that's that. I'll be using this in the future, but I do hope others can make use of it too.
First of all, good job! As for the issues with Surf, Waterfall and Fly, I think these links would help you a good amount:
http://www.pokecommunity.com/showthread.php?t=338513
http://www.pokecommunity.com/showpost.php?p=8676227&postcount=530

Lastly, just a small tip.
cmp r5, r3
beq endfail
b loopback
When you have two branches in a row (and one or both aren't "bl") it can be reduced to a single branch. Here bne loopback would do the same as these two branches if you move endfail as the next line in sequence :)
...
Seen January 7th, 2017
Posted August 6th, 2016
58 posts
6.8 Years
I don't know where it is either. Perhaps you can ask daniilS via VM or something.




1) For forced evolution, I don't know what you're really talking about. You mean just make a Pokemon evolve without giving the player time to hit the "b" button? I'll look into Pokemon evolution sure.

2) I haven't seen it so VMing me it would be nice. Anyways this is rather easy, I've done it before. I'll post the results at the bottom of this post.

3) Skipping the introduction was already done by Knizz. There's a post in the research and development section's quick research thread.


Preventing TMs from being consumed on use



Quick research:
TMs are deleted in two places. The first place is in their own function. When called from the bag, after use the TM has it's own deletion mechanism. The second way is from the bag, after you use a TM the bag attempts to delete it as well. Well, the solution is quite simple. There's two ways to do this, either go to 0809A1D8 call your own function there which checks if the item is a TM, and if it is, just jump to the end. Or much more simply you just remove the parts from the bag and tm function that deletes the TM (Which is what I did). The former way is a way you can make another item you have unconsumable.

To insert:
Do the byte changes below
0x124F78: 00 00 00 00
0x125C80: 00 00 00 00

Make it Ungivable:
insert that at 0x1326B8: 00 00 17 E0

Make it consumable after animation:
Insert: 00 00 00 00 at 0x124F78

To remove the quantities showing up in the bag:

Compile and insert into free space:
Spoiler:

.text
.align 2
.thumb
.thumb_func

main:
	cmp r5, #0x0
	bne end
	ldr r3, =(0x8131EFE +1)
	bx r3

end:
	mov r0, r7
	mov r1, #0x8
	mov r2, r4
	ldr r6, =(0x81335B0 +1)
	bl link
	ldr r3, =(0x8131EFE +1)
	bx r3

link:
	bx r6

.align 2


Here's a compiled version:
00 2D 01 D1 05 4B 18 47 38 1C 08 21 22 1C 04 4E 00 F0 02 F8 01 4B 18 47 30 47 C0 46 FF 1E 13 08 B1 35 13 08
Now navigate to 0x131EF4 and insert:
00 48 00 47 XX XX XX 08
Where XX XX XX is the pointer to where you assembled the routine +1

Now navigate to 0x131EA5 and change the byte to E0

Unsellable:
Basically for the TMs, you can still sell them to vendors. To change this, you need to modify each TM individually. It's unfortunate, but the game checks if an item can be sold my comparing it's market price to zero. If it's strictly greater than zero, then you can sell it to a vendor, seems to be the rule. So to make TMs unsellable you need to set their market prices individually to zero.
I can't use my own checks to disguise the TMs as unique because the sell routine in shops are used for ALL items including potions, berries, TMs, and other items like nuggets.


Present :3
I've found a way to make TMs unsellable:
0x132924 - 00 00 00 00
In addition, the quantity in bag when you buy TMs in the game should be hided, and here is a quick way to remove the box which shows the quantity for all items:
0x9BCC2 - 00 00 00 00
So here's the full code, no extra routines needed

Reusable TMs


0x1326BA - 17 E0 //can't hold as item
0x124F78 - 00 00 00 00 //can't delete
0x125C80 - 00 00 00 00 //can't delete
0x124EAC - 00 00 00 00 //can't delete
0x131EA6 - 2A E0 //fix the graphic
0x132924 - 00 00 00 00 //can't sell
0x9BCC2 - 00 00 00 00 //hide the box showing quantity
My contribution:

Forcing the text speed to "fast"


It is done by neglecting the speed set by the player:
0xF78D0 - 01 20
Then everything is done automatically.
Age 24
Male
Seen 2 Weeks Ago
Posted September 2nd, 2020
546 posts
9.8 Years
I've found a way to make TMs unsellable:
0x132924 - 00 00 00 00
In addition, the quantity in bag when you buy TMs in the game should be hided, and here is a quick way to remove the box which shows the quantity for all items:
0x9BCC2 - 00 00 00 00
So here's the full code, no extra routines needed

Reusable TMs


0x1326BA - 17 E0 //can't hold as item
0x124F78 - 00 00 00 00 //can't delete
0x125C80 - 00 00 00 00 //can't delete
0x124EAC - 00 00 00 00 //can't delete
0x131EA6 - 2A E0 //fix the graphic
0x132924 - 00 00 00 00 //can't sell
0x9BCC2 - 00 00 00 00 //hide the box showing quantity
My contribution:

Forcing the text speed to "fast"


It is done by neglecting the speed set by the player:
0xF78D0 - 01 20
Then everything is done automatically.
Umm... Hi. I believe I don't understand the implication of your comment "//can't delete". Does this mean I can't delete the attack I taught using a TM?
Seen January 7th, 2017
Posted August 6th, 2016
58 posts
6.8 Years
Umm... Hi. I believe I don't understand the implication of your comment "//can't delete". Does this mean I can't delete the attack I taught using a TM?
It means that it won't be deleted even it's used so that's just part of this hack. (It is from FBI's hack so please don't worry about it)

jiangzhengwenjzw

now working on kirby & the amazing mirror decomp (jiangzhengwenjz/katam)

Male
Seen 1 Hour Ago
Posted December 19th, 2019
175 posts
9.8 Years

The implementation of ROCK CLIMB in BPRE


This post will only deal with the "rock climb" selected by the player in the pokemon selection scene, so please do the script on your own if you want to use rock climb by talking to a rock.
This hack can judge the "playerfacing" and the number of the blocks you will climb.
1. Firstly we will repoint and expand the RAM location for TMs: (found from Development: More TMs/HMs - The PokéCommunity Forums Credit goes to Taの境界)
at 0x99E6A:
01 48 00 47 00 00 FF FF FF 08
FF FF FF 08 is the pointer to ram.asm (thumb mode +1):
ram.asm:
.text
.align 2
.thumb
.thumb_func
.global tm_slots_hack

main:
ldr r0, ram
str r0, [r1, #0x18]
mov r0, #0x3B
strb r0, [r1, #0x1c]
ldr r0, return
bx r0

.align
ram:.word 0x0203c000
return:.word 0x08099e74+1
0x203c000 is the free ram location.

2. Use JPAN's save_block_hack to save properly.
link: The PokéCommunity Forums - View Single Post - Research: FireRed Pokédex Hacking
Or use the patch instead: JPAN's Save Block Patch for FR » Romhack.me - ROM Hacking Community

3. tables and codes
1)repoint the table at 0x45A76E, replace 0c 00 with the move id of rock climb (swapped), and put 0c 00 after it as the end. (special move table)
2)repoint the table at 0x45A80C, add the move id (swapped). (TM table)
3)repoint the table at 0x45A37C and add an pointer to the description text. Please make it short like other texts in this table. (description text pointer table)
4)repoint the table at 0x45A618 and add [pointer to move name] A5 45 12 08 at the end of the table. (name_table)
5)copy these data to 0x3D4D6C as item picture and palette data.
C8 1C E9 08 64 1E E9 08
(in item picture & palette table)
6)copy these data to 0x3DEBCC as item data. (in item table)
C2 C7 A1 AA FF 00 00 00 00 00 00 00 00 00 5B 01 00 00 00 00 E5 75 48 08 01 00 04 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Please edit the description pointer to your new description!
7)edit the table at 0x252BC8 to enable some pokemon to learn the HM. This table is made up with bitfield, which means that you should convert it into binary to see the real data. 1 = learnable 0 = can't learn(TM learnable table)
For example, data for bulbasaur is "20 07 35 84 08 1E E4 00"
We divide it into 2 parts: "20 07 35 84" and "08 1E E4 00"
Then swap them, so we get "84350720" and "00E41E08"
Convert them into binary: "10000100001101010000011100100000" and "111001000001111000001000"
get them together in the reversed order:
"11100100000111100000100010000100001101010000011100100000"
It's in the order of "HM08, HM07,.........,TM01"
So if we want bulbusaur to learn HM09 we edit the higher part "111001000001111000001000"
We change it into "100111001000001111000001000"
Then we convert it into hexadecimal: "4E41E08"
swap it to get "08 1E E4 04" and we absolutely use it to replace "08 1E E4 00".
So you can see that we will always only deal with the higher part, I convert the lower part to just make things clearer

8)repoint the table at 0x45A788 and add [XX XX XX 08 0D 00 00 00] to the end of it. (function table)
XX XX XX 08 is the pointer to the following function: (thumb mode +1)
check.asm: (main ROCK CLIMB function)
.thumb
.align 2
push {r4, lr}
sub sp, sp, #4
mov r4, sp
add r4, #2
mov r0, sp
mov r1, r4
ldr r3, =0x0805C4F5
bl call_via_r3
mov r0, sp
mov r1, #0
ldrsh r0, [r0, r1]
mov r2, #0
ldrsh r1, [r4, r2]
ldr r2, =0x08058F79
bl call_via_r2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
cmp r0, #0x80 @behavior_byte
bne back
ldr r1, =0x03005024
ldr r0, =0x081248B1
str r0, [r1]
ldr r1, =0x0203B0C4
ldr r0, =0x08RRRRRR
str r0, [r1]
mov r0, #1
b real_back

back:
mov r0, #0

real_back:
add sp, sp, #4
pop {r4}
pop {r1}
bx r1

call_via_r3:
bx r3

call_via_r2:
bx r2
change 0x8RRRRRR to the offset+1 of the following function:(script_run function)
.thumb
.align 2
run_scr:
push {lr}
ldr r0, =0x0203B0A0
ldrb r0, [r0, #9]
ldr r1, =0x020386E0
lsl r0, r0, #0x18
lsr r0, r0, #0x18
str r0, [r1]
ldr r0, =0x08SSSSSS
ldr r1, =0x08069AE5
bl call_via_r1
pop {r0}
bx r0


call_via_r1:
bx r1
change 0x8SSSSSS to the offset of the following script:(ROCK CLIMB script)
#org @start
lockall
doanimation 0x25
waitstate
callasm 0x8kkkkkk //offset of code1+1
compare 0x800c 1
if1 1 @down
compare 0x800c 2
if1 1 @up
compare 0x800c 3
if1 1 @left
goto @right

#org @down
applymovement 0xff @movedown
waitmovement 0xff
callasm 0x8jjjjjj //offset of code2+1
compare 0x8004 0
if1 1 @downeventual
goto @down

#org @up
applymovement 0xff @moveup
waitmovement 0xff
callasm 0x8jjjjjj //offset of code2+1
compare 0x8004 0
if1 1 @upeventual
goto @up

#org @left
applymovement 0xff @moveleft
waitmovement 0xff
callasm 0x8jjjjjj //offset of code2+1
compare 0x8004 0
if1 1 @lefteventual
goto @left

#org @right
applymovement 0xff @moveright
waitmovement 0xff
callasm 0x8jjjjjj //offset of code2+1
compare 0x8004 0
if1 1 @righteventual
goto @right

#org @downeventual
applymovement 0xff @movedown
waitmovement 0xff
releaseall
end

#org @upeventual
applymovement 0xff @moveup
waitmovement 0xff
releaseall
end

#org @lefteventual
applymovement 0xff @moveleft
waitmovement 0xff
releaseall
end

#org @righteventual
applymovement 0xff @moveright
waitmovement 0xff
releaseall
end

#org @movedown
#raw 0x1D 0xfe

#org @moveup
#raw 0x1e 0xfe

#org @moveleft
#raw 0x1f 0xfe

#org @moveright
#raw 0x20 0xfe
change the 0x8kkkkkk & 0x8jjjjjj to the offset+1 of the following routines.

code1:(get "playerfacing" in var_0x800C)
.thumb
.align 2
push {lr}
ldr r0, =0x0805C6C5
bl linker
ldr r1, =0x020370D4
strh r0, [r1]
pop {pc}

linker:
bx r0
code2:(get the tile behavior byte)
.thumb
.align 2
push {r4, lr}
sub sp, sp, #4
mov r4, sp
add r4, #2
mov r0, sp
mov r1, r4
ldr r3, =0x0805C4F5
bl call_via_r3
mov r0, sp
mov r1, #0
ldrsh r0, [r0, r1]
mov r2, #0
ldrsh r1, [r4, r2]
ldr r2, =0x08058F79
bl call_via_r2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
ldr r1, =0x020370C0
cmp r0, #0x80 @behavior_byte
bne back
mov r0, #1
b realback

back:
mov r0, #0

realback:
strh r0, [r1]
add sp, sp, #4
pop {r4, pc}

call_via_r2:
bx r2


call_via_r3:
bx r3
change the "0x80" in code2 and check.asm to the behavior byte you selected for the "rock climb" tile block.

4. fix the badge check routine so that it will check the 8th badge for the HM09 you added: (untested)
place this at 0x12461C:
00 48 00 47 MM MM MM 08
MM MM MM 08 is the pointer to the following routine: (thumb mode +1)
.thumb
.align 2
add r0, r4, #0
cmp r4, #7
blt checkbadge
mov r0, #7
cmp r4, #0xc
beq checkbadge
ldr r1, =0x8124627
add r1, #0x32
bx r1

checkbadge:
mov r1, #0x82
lsl r1, r1, #0x4
add r0, r0, r1
ldr r1, =0x8124627
bx r1
5. An example: (Haven't edited the text and name yet)


At last, I have to say that i haven't tried to teach the HM to a pokemon, so if there's any problem, simply follow a reply in Development: More TMs/HMs - The PokéCommunity Forums to delete the animation of learning TMs, but I think there's no problem)

As you can see, I have done the main part, but I can't ensure there's no glitch in this hack. So please contribute to it! I'm so tired with it so i won't touch it recently...

Edit: Here is a simple looping script to get all of the TMs and HMs as the cheats for the game won't work:
#org @start
lock
faceplayer
setvar 0x8004 0x121
goto @snippet2

//---------------
#org @snippet1
release
end

//---------------
#org @snippet2
additem 0x8004 0x1
addvar 0x8004 0x1
compare 0x8004 0x15C
if 0x1 goto @snippet1
goto @snippet2
Edit2: Source codes and binary files uploaded.

Edit3: Corrected a slight typo. Codes reuploaded.
But please pay attention that "8RRRRRR" & "8SSSSSS" are not in the attachment and they're shown as "8CCCCCC" & "8DDDDDD" in the files in the .zip archive so that they can be compiled successfully. If you don't understand, please simply follow the post and neglect the attachment. So is the offsets included in the script file (scr.rbc) because they use the offset in my test ROM XD

Edit4: added explanation to bitfield.
Male
Antarctica
Seen April 1st, 2020
Posted September 26th, 2017
326 posts
8.2 Years

Events that happen daily:




First of all, this uses the Day/Night System's clock, or you can use ShinyQuagsire's RTC, which I'm fairly sure are one and the same anyway. Either way, you have to have that in the game or this won't work for obvious reasons.


Insert this into free space.
.thumb
start:
 push {r0-r7, lr}
 ldr r0, =(0x20370D0)
 ldrh r1, [r0]
 mov r2, #0x4
 mul r1, r1, r2
 ldr r0, =(0x3005546)
 add r0, r0, r1
 mov r1, r0
 mov r2, r0
 add r0, #0x1
 add r1, #0x2
 add r2, #0x3
 ldrh r3, [r0]
 ldrb r4, [r1]
 ldrb r5, [r2]
 ldr r6, =(0x300553C)
 ldrh r7, [r6]
 cmp r3, r7
 bcc x800D_1
 strh r7, [r0]
 ldr r6, =(0x300553F)
 ldrb r7, [r6]
 cmp r4, r7
 bcc x800D_1
 strb r7, [r1]
 ldr r6, =(0x3005540)
 ldrb r7, [r6]
 cmp r5, r7
 bcc x800D_1
 strb r7, [r2]
 ldr r0, =(0x20370D0)
 mov r1, #0x0
 strh r1, [r0]
 pop {r0-r7, pc}
x800D_1:
 ldr r6, =(0x300553C)
 ldrh r7, [r6]
 strh r7, [r0]
 ldr r6, =(0x300553F)
 ldrb r7, [r6]
 strh r7, [r1]
 ldr r6, =(0x3005540)
 ldrb r7, [r6]
 strb r7, [r2]
 ldr r0, =(0x20370D0)
 mov r1, #0x1
 strh r1, [r0]
 pop {r0-r7, pc}
This hack uses variable x800D for almost everything. So each event that happens daily is supposed to have a number attached to it using x800D, like so.
#dynamic 0x______
 
#org @start
setvar 0x800D 0x_ (set 800D to the table entry.)
callasm 0x8(offset where you put my the previous ASM +1)
compare 0x800D 0x0
if 0x1 goto @1 (if x800D is the value of 0, then the event has already happened today)
compare 0x800D 0x1
if 0x1 goto @2 (if x800D is the value of 1, then the event has not happened that day)
Please credit if you use this, and report any bugs here or by PM/VM, thanks.


~EDIT~ It was pointed out to me that this doesn't work over save data outside of save states, that was an oversight. I'll fix it as soon as I can.

jiangzhengwenjzw

now working on kirby & the amazing mirror decomp (jiangzhengwenjz/katam)

Male
Seen 1 Hour Ago
Posted December 19th, 2019
175 posts
9.8 Years

Pre-battle Mugshot Hack in BPEE


I don't hack Emerald but my friend jirachiwishmaker requested the code, so I will share it.
This is a port of Jambo51's codes in this thread to Emerald Version
If you still don't know what it is, please take a look at this picture:

1. Make these byte changes:
0x147C6A - 00 00 00 00 (disable the palette mixing)
0xB13FD - 78 (for safety's sake)
0x5C8F90 - CD 6A 0F 73 51 7B 93 7F D5 7F FF 7F (filling the palette...)
0x5C8F70 - CD 6A 0F 73 51 7B 93 7F D5 7F FF 7F
0x5C8F50 - CD 6A 0F 73 51 7B 93 7F D5 7F FF 7F
2. Insert these 3 ASM codes in free space and change bytes accordingly:
insert 00 48 00 47 AA AA AA 08 at 0xB0F44, in which AA AA AA 08 is the pointer to the following routine (thumb mode +1)
.thumb
.align 2
ldrb r2, [r4, #7]
cmp r2, #0
beq normal
ldr r0, =0x80B0F5D
bx r0

normal:
ldrh r2, [r4]
lsl r0, r2, #2
add r0, r0, r2
lsl r0, r0, #3
add r0, r0, r1
ldr r1, =0x80B0F4F
bx r1
insert 00 48 00 47 BB BB BB 08 at 0xB5E78, BB BB BB 08 = pointer to the following code (thumb mode +1)
.thumb
.align 2
cmp r4, #0x47
beq normal
cmp r4, #0x48
beq normal
ldr r0, =0x2038BCA
ldrh r0, [r0]
lsl r5, r0, #2
add r5, r0, r5
lsl r0, r5, #3
ldr r5, =0x806E4C4
ldr r5, [r5]
add r0, r0, r5
ldrb r4, [r0, #3]

normal: 
add r5, r1, #0
add r6, r2, #0
mov r9, r3
ldr r7, [sp, #0x34]
ldr r0, =0x80B5E81
bx r0
insert 01 49 08 47 00 00 CC CC CC 08 at 0x147C42, CC CC CC 08 = pointer to the following code (thumb mode +1)
change 0x8FFFFFF to the palette table in your ROM and it can have 255 custom palettes.
The table's structure is [pointer1][pointer2]........................
Every pointer will point to a 16-color uncompressed palette (32 bytes)
.thumb
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, #0x1f
 beq oldway
 cmp r1, #0x26
 beq oldway
 ldr r1, ramoffset
 ldrb r1, [r1, #0x7]
 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 2
ramoffset: .word 0x02038BCA
trainertable: .word 0x0806E4C4
table:  .word 0x085C8FDC
table2:  .word 0x08FFFFFF
return:  .word 0x08147C51
To activate it in a script, you can use this format:
trainerbattle 0(type, you can change it to fit your script) 0x50(your chosen trainer's ID) 0x0100 @pointertomsg1 @pointertomsg2
0x0100 means the first palette in your custom table at 0x8FFFFFF, and 0x0200 means the second, ...... 0xff00 means the 255th palette.

Some sample palettes in the original game: (If you don't change the tiles and tileset, please build your palette in this format using APE)
D5 18 CE 39 52 4A D6 5A 5A 6B 17 5C 59 64 9B 6C DD 74 1F 7D CD 6A 0F 73 51 7B 93 7F D5 7F FF 7F
D5 18 CE 39 52 4A D6 5A 5A 6B 41 07 A4 13 C6 1B E9 27 EF 3F FC 45 3E 4E 7F 56 BF 5E FF 66 FC 45
Give credit to Jambo51 (for the routines for BPRE) and jirachiwishmaker (for finding some offsets) if you use this hack. I only adjusted the routines so that it will be compatible with Emerald's RAM structure and fixed a small glitch in Jambo51's code1. So no credit needed for me, if you don't want to make your credit list long.
Female
Seen March 5th, 2022
Posted September 27th, 2017
27 posts
6.9 Years

Pre-battle Mugshot Hack in BPEE


I don't hack Emerald but my friend jirachiwishmaker requested the code, so I will share it.
This is a port of Jambo51's codes in this thread to Emerald Version
If you still don't know what it is, please take a look at this picture:

1. Make these byte changes:
0x147C6A - 00 00 00 00 (disable the palette mixing)
0xB13FD - 78 (for safety's sake)
0x5C8F90 - CD 6A 0F 73 51 7B 93 7F D5 7F FF 7F (filling the palette...)
0x5C8F70 - CD 6A 0F 73 51 7B 93 7F D5 7F FF 7F
0x5C8F50 - CD 6A 0F 73 51 7B 93 7F D5 7F FF 7F
2. Insert these 3 ASM codes in free space and change bytes accordingly:
insert 00 48 00 47 AA AA AA 08 at 0xB0F44, in which AA AA AA 08 is the pointer to the following routine (thumb mode +1)
.thumb
.align 2
ldrb r2, [r4, #6]
cmp r2, #0
beq normal
ldr r0, =0x80B0F5D
bx r0

normal:
ldrh r2, [r4]
lsl r0, r2, #2
add r0, r0, r2
lsl r0, r0, #3
add r0, r0, r1
ldr r1, =0x80B0F4F
bx r1
insert 00 48 00 47 BB BB BB 08 at 0xB5E78, BB BB BB 08 = pointer to the following code (thumb mode +1)
.thumb
.align 2
cmp r4, #0x47
beq normal
cmp r4, #0x48
beq normal
ldr r0, =0x2038BCA
ldrh r0, [r0]
lsl r5, r0, #2
add r5, r0, r5
lsl r0, r5, #3
ldr r5, =0x806E4C4
ldr r5, [r5]
add r0, r0, r5
ldrb r4, [r0, #3]

normal: 
add r5, r1, #0
add r6, r2, #0
mov r9, r3
ldr r7, [sp, #0x34]
ldr r0, =0x80B5E81
bx r0
insert 01 49 08 47 00 00 CC CC CC 08 at 0x147C42, CC CC CC 08 = pointer to the following code (thumb mode +1)
change 0x8FFFFFF to the palette table in your ROM and it can have 255 custom palettes.
The table's structure is [pointer1][pointer2]........................
Every pointer will point to a 16-color uncompressed palette (32 bytes)
.thumb
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, #0x1f
 beq oldway
 cmp r1, #0x26
 beq oldway
 ldr r1, ramoffset
 ldrb r1, [r1, #0x6]
 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 2
ramoffset: .word 0x02038BCA
trainertable: .word 0x0806E4C4
table:  .word 0x085C8FDC
table2:  .word 0x08FFFFFF
return:  .word 0x08147C51
To activate it in a script, you can use this format:
trainerbattle 0(type, you can change it to fit your script) 0x50(your chosen trainer's ID) 0x0100 @pointertomsg1 @pointertomsg2
0x0100 means the first palette in your custom table at 0x8FFFFFF, and 0x0200 means the second, ...... 0xff00 means the 255th palette.

Some sample palettes in the original game: (If you don't change the tiles and tileset, please build your palette in this format using APE)
D5 18 CE 39 52 4A D6 5A 5A 6B 17 5C 59 64 9B 6C DD 74 1F 7D CD 6A 0F 73 51 7B 93 7F D5 7F FF 7F
D5 18 CE 39 52 4A D6 5A 5A 6B 41 07 A4 13 C6 1B E9 27 EF 3F FC 45 3E 4E 7F 56 BF 5E FF 66 FC 45
Give credit to Jambo51 (for the routines for BPRE) and jirachiwishmaker (for finding some offsets). I only adjusted the routines so that it will be compatible with Emerald's RAM structure and fixed a small glitch in Jambo51's code1. So no credit needed for me, if you don't want to make your credit list long.
Worship

Xencleamas

Suddenly lurking in the shadows...

Male
Asgard
Seen August 8th, 2020
Posted August 7th, 2018
458 posts
8.4 Years

Pre-battle Mugshot Hack in BPEE

Still don't get the mugshot. I have inserted the routines and done the byte changes correctly but still the mugshot do not appear. Assuming I have modified the script too.

EDIT: It works fine when I use 0x0001, 0x0002, and so on. 0x0100, 0x0200, and so on which are standards to be used for mugshots do not activate well unless you have a palette on that 0x100 slot.

Xencleamas Untitled Pokémon Fan Game (Coming Soon!) Untitled Region (Coming Soon!)