Checktype
Hoy os traigo otra pequeña rutina que de seguro para más de uno le es útil. Ni más ni menos que analizar si un determinado Pokémon de nuestro equipo es de un tipo que nosotros escojamos.
Esta rutina comprueba tanto el primer tipo como el segundo.
La rutina para Fire Red:
Código:
.text
.align 2
.thumb
main:
push {r0-r2, lr}
mov r1, #0x64
ldr r0, var_8004
ldrh r0, [r0]
mul r0, r0, r1
ldr r1, pokemondata
add r0, r0, r1 ;aquí está el offset de la RAM de los datos del Pokemon que hayamos escogido
mov r1, #0xB
ldr r2, pokedecrypt
bl linker ;tenemos la especie del Pokemon para poder buscarlo en la tabla
mov r1, #0x1C
mul r0, r0, r1
ldr r1, tablestart
sub r1, r1, #0x1C
add r0, r0, r1 ;offset del primer tipo del Pokemon que hemos elegido
mov r2, r0
ldrb r0, [r0]
ldr r1, var_8005
ldrh r1, [r1]
cmp r0, r1 ;compara el primer tipo con el tipo que hemos definido en la variable 8005
beq label
mov r0, r2
add r0, r0, #0x1
ldrb r0, [r0]
ldr r1, var_8005 ;ahora compara el segundo tipo
ldrh r1, [r1]
cmp r0, r1
beq label
mov r0, #0x0
ldr r1, var_8005
strh r0, [r1] ;si el Tipo no coincide guardamos en la variable 8005 un 0
b end
label:
mov r0, #0x1
ldr r1, var_8005
strh r0, [r1] ;de lo contrario guardamos un 1
b end
linker:
bx r2
end:
pop {r0-r2, pc}
.align 2
var_8004: .word 0x020370C0
var_8005: .word 0x020370C2
tablestart: .word 0x082547A6
pokemondata: .word 0x02024284
pokedecrypt: .word 0x0803FBE9
Voy a explicar los offsets que he usado para que aquel que entienda un mínimo de ASM pueda sustituir los offsets y hacer la rutina para otras ROM bases.
La rutina compilada para Fire Red:var_8004: es simplemente la variable que he usado para especificar la posición del Pokemon a analizar.
var_8005: sirve para especificar el tipo a checkear y te devuelve el resultado.
pokemondata: es el offset de la RAM de los datos del primer Pokemon de tu equipo, ahí está su PID, sus HP...
pokedecrypt: es una función, os recomiendo el post de @EnamoratDeKatie para encontrar el offset para otras ROMs. https://whackahack.com/foro/t-57964/e-fr-recopilacion-offsets-frecuentes-en-rutinas-asm
tablestart: es el offset de la ROM de los datos referentes a los tipos de Bulbasaur, ocupando cada tipo un byte (en total un half word). No entraré más en detalle. Pero sabed que aquí va el offset del primer pokemon de todos, de su primer tipo más bien.
Código:
07 B5 64 21 12 48 00 88 48 43 14 49 40 18 0B 21 13 4A 00 F0 1A F8 1C 21 48 43 0F 49 1C 39 40 18 02 1C 00 78 0B 49 09 88 88 42 0A D0 10 1C 01 30 00 78 08 49 09 88 88 42 03 D0 00 20 05 49 08 80 04 E0 01 20 03 49 08 80 00 E0 10 47 07 BD C0 46 C0 70 03 02 C2 70 03 02 A6 47 25 08 84 42 02 02 E9 FB 03 08
Parámetros de entrada
Variable 0x8004: Posición de Pokémon a analizar (nótese que el primero es 0)
Variable 0x8005: Tipo Pokemon
Parámetros de salida
Variable 0x8005: 0 si el Pokemon no es de ese tipo, 1 si lo es
NORMAL 0x0
FIGHT 0x1
FLYING 0x2
POISON 0x3
GROUND 0x4
ROCK 0x5
BUG 0x6
GHOST 0x7
STEEL 0x8
??? 0x9
FIRE 0xA
WATER 0xB
GRASS 0xC
ELECTR 0xD
PSYCHC 0xE
ICE 0xF
DRAGON 0x10
DARK 0x11
FIGHT 0x1
FLYING 0x2
POISON 0x3
GROUND 0x4
ROCK 0x5
BUG 0x6
GHOST 0x7
STEEL 0x8
??? 0x9
FIRE 0xA
WATER 0xB
GRASS 0xC
ELECTR 0xD
PSYCHC 0xE
ICE 0xF
DRAGON 0x10
DARK 0x11
Código:
#dynamic 0x800000
#org @start
setvar 0x8004 5 'Quiero saber si el último poke de mi equipo...
setvar 0x8005 0xC '... es de tipo planta
callasm 0x08800001 'Aquí pongo el offset en que inserté la rutina, sumándole 1
compare 0x8005 1
if 5 goto @noestipoplanta
msgbox @mensajetipoplanta 6 'Esto se ejecuta si es tipo planta
end
#org @noestipoplanta
msgbox @mensajenotipoplanta 6 'Esto se ejecuta si no es tipo planta
end
#org @mensajetipoplanta
= Es tipo planta.
#org @mensajenotipoplanta
= No es tipo planta.
Código:
#dyn 0x800000
#org @main
setvar 0x8004 0 'Reviso si el primer poke de mi equipo...
setvar 0x8005 0 '... es de tipo normal
callasm 0x800001 'Este es el offset en el que inserté la rutina, sumándole 1
if (0x8005==1) {
loadptr @mensajetiponormal 'Esto se ejecuta si el poke es de tipo normal
callstd 6
end
}
else {
loadptr @mensajenotiponormal 'Esto se ejecuta si el poke no es de tipo normal
callstd 6
end
}
#org @mensajetiponormal
= Es tipo normal.$$
#org @mensajenotiponormal
= Tu pokémon no es de\n
= tipo
= normal.$$
Esto es todo por hoy. Espero que os sirva
Última edición: