Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.
Posted by: Stackout
Date: 2016-06-06 16:41:19
Remember that animation opcode 0x03 creates a new task: it happens to call the address you give it as well.
It also increases a counter, named [tt]move_anim_active_task_count[/tt] in the FireRed IDB.
Animation opcode 0x08 is essentially a no-op if [tt]move_anim_active_task_count[/tt] >= 0.
So, you need to remove the task (otherwise, the game will keep calling the payload over and over, and will freeze as the animation will never end).
(How the game continued in FR/LG/Emerald remains a mystery to me.)
You do this by calling a function named [tt]move_anim_task_del()[/tt] in the FireRed IDB. Its location is 0x8072760 in FireRed US, 0x8075928 in Ruby US v1.2.
As for how to find it in other games, search for [tt]08 78 01 38 08 70 01 BC 00 47[/tt]; the function entry point should be the [tt]00 B5[/tt] 12 bytes before. There are two matches very close to each other: the first match is what you're looking for (the functions are identical apart from the RAM address whose value gets decremented)
Anyway, [tt]move_anim_task_del()[/tt] takes one argument: the task index to delete. Thing is, we don't know the task index, at least initially. However, the second time the payload gets called, the task index is in r0.
So, how to detect that?
It's really quite easy: the first time the payload gets called, r1 points to ROM; otherwise, it points to RAM. So, a payload like this could be used:
[tt]; fasmarm syntax
processor cpu32_v4t ; ARMv4t (GBA cpu)
thumb ; we don't want an ARM-mode payload
; code starts below
push {r0-r1, lr} ; save r0, r1, lr to stack
; is this our first time? if so, run the payload
lsrs r1,24
cmp r1,8
beq run_payload
; we're being called a second time, just remove the task
ldr r1, [move_anim_task_del]
bl _call_via_r1
pop {r0-r1, pc}
run_payload:
; actual payload here
ldr r1, [script_run]
ldr r0, [script_vmip]
bl _call_via_r1
pop {r0-r1, pc}
_call_via_r1:
bx r1
; hey, perfectly aligned now!
move_anim_task_del:
dw 0x08075929
script_run:
dw 0x080655D9
script_vmip:
dw 0x02025be4[/tt]
Hex representation:
[tt]03 B5 09 0E 08 29 03 D0 04 49 00 F0 06 F8 03 BD 03 49 04 48 00 F0 01 F8 03 BD 08 47 29 59 07 08 D9 55 06 08 E4 5B 02 02[/tt]
Remember to change the last three 32-bit integers for your game/version/language.