- 24
- Posts
- 16
- Years
- Seen Nov 26, 2023
Hi!
When researching for my tool called PokéDAN, I found a routine, that is used to get the address to the wildpokémon data. It's called everytime you encouter a wild battle. I've hacked this routine to create day / night specific encounters. I think, that some pretty cool stuff can be done hacking these routines.. It can be found (gamecode specific) at the following adresses.
BPRD: 0x82a50
BPRE: 0x82aec
BPGD: 0x82a24
BPGE: 0x82ac0
Parameters (that I found so far):
r0 = contains the address minus four of the pointer (to the wildpokémon data).
r1 = battle type ( 0 = grass, idk the others..)
Hacking this routine is very easy, once you know what parameters it takes.
But for I'll give you an example, of how it can be do. The following code was adapted from my day / night encounter routine..
If we take a look at the routine, we find code that looks like this:
Because there is no address specific code in this part, we can replace it with some code that jumps to our own routine. But make sure to NOT replace the first command ("push {r4-r7, lr}")!! This is important because we want to get the link register properly saved! In our custom routine we will then execute the code we've overwritten.
Place this hook @ address of the routine
Then we'll write our custom routine.
That's it ! I'm already working on a bigger project than my day / night encounter, that will allow you to change the wildpokémon data using XSE scripting. this will make my system very dynamic.
Please excuse any grammer mistakes! I'm german and trying my best to master your language.
Greetz hack!osa
When researching for my tool called PokéDAN, I found a routine, that is used to get the address to the wildpokémon data. It's called everytime you encouter a wild battle. I've hacked this routine to create day / night specific encounters. I think, that some pretty cool stuff can be done hacking these routines.. It can be found (gamecode specific) at the following adresses.
BPRD: 0x82a50
BPRE: 0x82aec
BPGD: 0x82a24
BPGE: 0x82ac0
Parameters (that I found so far):
r0 = contains the address minus four of the pointer (to the wildpokémon data).
r1 = battle type ( 0 = grass, idk the others..)
Hacking this routine is very easy, once you know what parameters it takes.
But for I'll give you an example, of how it can be do. The following code was adapted from my day / night encounter routine..
If we take a look at the routine, we find code that looks like this:
Code:
push {r4-r7, lr} @ save registers r4 .. r7 and lr
mov r7, r8 @ r7 == r8
push {r7} @ save r7
mov r7, r0 @ r7 == r0 NOTE: r7 now contains the first parameter
lsl r1, r1, #0x18 @ this code basically..
lsr r1, r1, #0x18 @ .. ensures that r1 is not bigger than 255 (one byte)
mov r0, r1 @ r0 == r1 NOTE: r0 cannot be used anymore to read or modify the first parameter! USE r7!
lsl r2, r2, #0x18
Because there is no address specific code in this part, we can replace it with some code that jumps to our own routine. But make sure to NOT replace the first command ("push {r4-r7, lr}")!! This is important because we want to get the link register properly saved! In our custom routine we will then execute the code we've overwritten.
Place this hook @ address of the routine
Code:
.align 2
.thumb
.global main
main:
push {r4-r7, lr} @ this is basically the first command, we don't want to get overwritten ;)
push {r0} @save r0
ldr r0, .pointer @ r0 == address of custom routine
bx r0 @ jump to r0
pop {r0} @ restore r0
b .exit_hook @ resume execution of the routine
.align 2
.pointer:
.word 0x08802001 @ address of our custom routine + 1. replace if you put it at any other location
.exit_hook:
Then we'll write our custom routine.
Code:
.align 2
.thumb
entry:
pop {r0} @ restore r0
original: @ this is the code we replaced .. look above for an explanation..
mov r7, r8
push {r7}
mov r7, r0
lsl r1, r1, #0x18
lsr r1, r1, #0x18
mov r0, r1
lsl r2, r2, #0x18
main:
push {r0-r6} @ save r0 .. r6
@ inside here we can put our custom code
@ we can change r7 to make the game loading the wildpokémon address from some other pointer.
@ but keep in mind, that the pointer must be substracted by 4. Why?
@ because the routine is loading the address from r7 + 4!
pop {r0-r6} @ restore r0 .. r6
push {r0} @ save r0
ldr r0, .return @ r0 = return address
bx r0 @ jump to r0
.align 2
.return:
.word 0x08082A59 @ this is the return address. It must be adjusted to the address of the original routine + 9.
That's it ! I'm already working on a bigger project than my day / night encounter, that will allow you to change the wildpokémon data using XSE scripting. this will make my system very dynamic.
Please excuse any grammer mistakes! I'm german and trying my best to master your language.
Greetz hack!osa