Registrarse

[Otros] FR | Menú debug v1.0

Gold

Porrero a tiempo parcial
Miembro insignia
Muchas veces hemos insertado nuevos Pokémon, items, canciones, etc, y para probar que todo funciona bien in game usamos métodos distintos, ¿Y como lo hacemos? Pues al menos yo todos estos años hago un script de prueba para interactuar con el y probarlo. Pero, ¿No les parece algo tedioso hacer eso? Al menos a mí si. En sus juegos Game Freak decidió crear algo llamado Menú debug, con lo cual ellos pueden testear cada cosa sin necesidad de estar haciendo los eventos de prueba que los romhackers hacemos.

Aquí unos videos de los distintos menú debug que Game freak ha hecho:

Entonces nosotros vamos a hacer un menú debug medio rudimentario, pero funcional. Para ello debemos de tirar de ASM y un poco de manipulación de RAM. Las rutinas necesarias para este menú son:

Rutina de Multichoices desplazables de FBI (No es necesaria para esto, también una multichoice común vale, pero esta queda más profesional)
Rutina de Caja numérica de JPAN

Para este menú requeriremos una multichoice con 7 opciones para las funciones que hasta el momento están implementadas. Pueden ponerle el nombre que más concuerde con lo que hace.

Ya con esas rutinas podemos proceder con el menú. Para explicar un poco las rutinas de arriba, la rutina para digitar números funciona seleccionando manualmente con la cruceta el número deseado y este se almacena en las variables 0x8008 y 0x8009. Como la rutina tiene 9 dígitos no usaremos ambas variables y usaremos solamente la variable 0x8008 (Donde se guardan los primeros dígitos).

La rutina original (No funcional) Tenía las funciones de Dar un Pokémon, un objeto, ir a X mapa, reproducir una canción. cambiar clima, y generar batalla contra Pokémon salvaje y entrenador. Esta es la primer rutina (no la usen, explicaré porqué no sirve)

Código:
#dynamic 0xC00000
//---------------
#org @start
lockall
setvar 0x8008 0x0
setvar 0x8009 0x0
msgbox @string1 MSG_KEEPOPEN //"Pokémon GS Chronicles Beta 2.5\nDe..."
setvar 0x8000 0x0
setvar 0x8001 0x7
setvar 0x8004 0x0
special 0x158
waitstate
compare LASTRESULT 0x0
if 0x1 goto @snippet1
compare LASTRESULT 0x1
if 0x1 goto @snippet2
compare LASTRESULT 0x2
if 0x1 goto @snippet3
compare LASTRESULT 0x3
if 0x1 goto @snippet4
compare LASTRESULT 0x4
if 0x1 goto @snippet5
compare LASTRESULT 0x5
if 0x1 goto @snippet6
compare LASTRESULT 0x6
if 0x1 goto @snippet7
releaseall
end

//---------------
#org @snippet1
msgbox @string2 MSG_KEEPOPEN //"Select valid species (1-412)"
special 0x154
waitstate
compare 0x8008 0xC9FF
if 0x1 goto @snippet8
givepokemon 0x8008 0x32 0x0 0x0 0x0 0x0
msgbox @string3 MSG_NORMAL //"Pokémon species were added."
goto @start

//---------------
#org @snippet2
msgbox @string4 MSG_KEEPOPEN //"Select a valid item (1-410)"
special 0x154
waitstate
compare 0x8008 0xC9FF
if 0x1 goto @snippet8
additem 0x8008 0x64
msgbox @string5 MSG_NORMAL //"Item was added."
goto @start

//---------------
#org @snippet3
msgbox @string6 MSG_KEEPOPEN //"Not functional option."
closeonkeypress
goto @start

//---------------
#org @snippet4
msgbox @string7 MSG_KEEPOPEN //"Select a song to play (256-372)"
special 0x154
waitstate
compare 0x8008 0xC9FF
if 0x1 goto @snippet8
playsong2 0x8008
closeonkeypress
goto @start

//---------------
#org @snippet5
msgbox @string8 MSG_KEEPOPEN //"Select valid Weather (1-15)"
special 0x154
waitstate
compare 0x8008 0xC9FF
if 0x1 goto @snippet8
setweather 0x8008
doweather
closeonkeypress
goto @start

//---------------
#org @snippet6
msgbox @string2 MSG_KEEPOPEN //"Select valid species (1-412)"
special 0x154
waitstate
closeonkeypress
compare 0x8008 0xC9FF
if 0x1 goto @snippet8
wildbattle 0x8008 0x5 0x0
goto @start

//---------------
#org @snippet7
msgbox @string9 MSG_KEEPOPEN //"Select a valid trainer battle\n(1-..."
special 0x154
waitstate
closeonkeypress
compare 0x8008 0xC9FF
if 0x1 goto @snippet8
trainerbattle 0x3 0x8008 0x0 @string10
goto @start

//---------------
#org @snippet8
releaseall
end


//---------
// Strings
//---------
#org @string1
= Pokémon GS Chronicles Beta 2.5\nDebug Menu.

#org @string2
= Select valid species (1-412)

#org @string3
= Pokémon species were added.

#org @string4
= Select a valid item (1-410)

#org @string5
= Item was added.

#org @string6
= Not functional option.

#org @string7
= Select a song to play (256-372)

#org @string8
= Select valid Weather (1-15)

#org @string9
= Select a valid trainer battle\n(1-742)

#org @string10
= ............ ............

A simple vista el script funciona, pero hay un problema con tres comandos. Playsong, trainerbattle y Wildbattle fueron codificados de manera que no funcionan con variables como valor principal, provocando que al ejecutarse crasheen el juego o no hagan nada.

¿Como solucionarlo? Pues pedí ayuda en Pokeco y como todo un capo el usuario DrFuji encontró justo lo que necesitaba. El usuario DavidJJcob/Missingyep hace casi 9 años encontró un método funcional de hacer que scripts que normalmente no aceptan variables como valor puedan funcionar, haciendo que nuestro script debug funcione como esperábamos. Para ello ejecutaremos los scripts mediante ejecución de la RAM.

Para no hacerlo más largo, dejo aquí la versión v1.0 de mi script debug explicado.

Código:
#dynamic 0xC00000

//---------------
#org @start
lockall
setvar 0x8008 0x0 //"Es obligatorio poner estos setvars para el correcto funcionamiento de las rutinas"
setvar 0x8009 0x0
msgbox @string1 MSG_KEEPOPEN //"Cualquier texto vale"
setvar 0x8000 0x0 //"Estos setvars y el special 0x158 son la multichoice desplazable"
setvar 0x8001 0x7
setvar 0x8004 0x0
special 0x158
waitstate //"Desde el setvar 0x8000 hasta aquí se puede reemplazar por el comando multichoice"
compare LASTRESULT 0x0
if 0x1 goto @snippet1 //"obtener un Pokémon"
compare LASTRESULT 0x1
if 0x1 goto @snippet2 //"Obtener objeto"
compare LASTRESULT 0x2
if 0x1 goto @snippet3 //"Ir a un mapa"
compare LASTRESULT 0x3
if 0x1 goto @snippet4 //"Reproducir una canción"
compare LASTRESULT 0x4
if 0x1 goto @snippet5 //"Cambiar clima"
compare LASTRESULT 0x5
if 0x1 goto @snippet6 //"Batalla con Pokémon Salvaje"
compare LASTRESULT 0x6
if 0x1 goto @snippet7 //"Batalla con entrenador"
releaseall
end

//---------------
#org @snippet1
msgbox @string2 MSG_KEEPOPEN
special 0x154 //"Eso lo sustituyen con un callasm a la rutina de digitación numérica de JPAN"
waitstate
compare 0x8008 0xC9FF
if 0x1 goto @snippet8 //"Si no se selecciona un número no se ejecutará comando alguno"
givepokemon 0x8008 0x32 0x0 0x0 0x0 0x0 //"El script fue hecho para que el nivel sea 50 por defecto, cambiar a su gusto"
msgbox @string3 MSG_NORMAL //"Pokémon species were added."
goto @start

//---------------
#org @snippet2
msgbox @string4 MSG_KEEPOPEN
special 0x154
waitstate
compare 0x8008 0xC9FF
if 0x1 goto @snippet8
additem 0x8008 0x64 //"También lo pueden cambiar por un giveitem
msgbox @string5 MSG_NORMAL //"Item was added."
goto @start

//---------------
#org @snippet3
msgbox @string6 MSG_KEEPOPEN //"Aún no lo hago funcionar xD"
closeonkeypress
goto @start

//---------------
#org @snippet4
msgbox @string7 MSG_KEEPOPEN
special 0x154
waitstate
compare 0x8008 0xC9FF
if 0x1 goto @snippet8
setvar 0x8007 0x3300 //"Aquí empezamos a usar Eval. El 0x33 corresponde al comando playsong en hex mas el 00 obligatorio"
setvar 0x8009 0x0 //"Aquí es el segundo valor desconocido del comando playsong.
setvar 0x800A 0x3 //"Regreso al comando"
call 0x20370C6 //"Llamada a la variable 0x8007 que nos ejecutará el comando normalmente y usando la variable 0x8008 como valor principal"
closeonkeypress
goto @start

//---------------
#org @snippet5
msgbox @string8 MSG_KEEPOPEN
special 0x154
waitstate
compare 0x8008 0xC9FF
if 0x1 goto @snippet8
setweather 0x8008
doweather
closeonkeypress
goto @start

//---------------
#org @snippet6
msgbox @string2 MSG_KEEPOPEN
special 0x154
waitstate
closeonkeypress
compare 0x8008 0xC9FF
if 0x1 goto @snippet8
setvar 0x8007 0xB600 //"B6 corresponde al comando setwildbattle más 00"
setvar 0x8009 0x0005 //"Nivel del Pokémon salvaje. mas primer byte del valor del objeto equipado"
setvar 0x800A 0xB700 //"Segundo byte del objeto equipado más B7 correspondiente al comando dowildbattle"
setvar 0x800B 0x3 //"Regreso al comando"
call 0x20370C6 //"Ejecutar variable 0x8007 y el comando especificado con 0x8008 como valor principal"
goto @start

//---------------
#org @snippet7
msgbox @string9 MSG_KEEPOPEN
special 0x154
waitstate
closeonkeypress
compare 0x8008 0xC9FF
if 0x1 goto @snippet8
setvar 0x8006 0x035C //"Corresponde al comando trainerbattle (0x5C) y el tipo de batalla (03)"
copyvar 0x8007 0x8008 //"Tiraremos de esta var ya que no podemos usar 0x800C, así que pondemos el número de entrenador en 0x8007"
setvar 0x8008 0x00000 //"Bytes que Trainerbattle no usa (O que uses si es una trainerbattle 0x9 o tienes la rutina de Vs Bars)"
setvar 0x8009 0xYYZZ
setvar 0x800A 0x08XX //"Estas vars actúan como puntero al texto de batalla al perder. Pon una offset con espacio libre para el texto"
setvar 0x800B 0x3
call 0x20370C4
goto @start

//---------------
#org @snippet8
releaseall
end


//---------
// Strings
//---------
#org @string1
= Debug Menu v1.0

#org @string2
= Select valid species (1-412)

#org @string3
= Pokémon species were added.

#org @string4
= Select a valid item (1-374)

#org @string5
= Item was added.

#org @string6
= Not functional option.

#org @string7
= Select a song to play (256-346)

#org @string8
= Select valid Weather (1-15)

#org @string9
= Select a valid trainer battle\n(1-742)

#org 0xXXYYZZ
= (aquí va el texto genérico del entrenador al perder)
Compilando y configurando el script anterior el resultado es este:


Cualquier sugerencia sobre qué podría agregarse será bienvenida. Igual el código no está muy pulido que digamos, pero funciona para lo que necesitemos.
 

darkeon75

ROM Hacker
No me funciona, cuando se supone que tiene que aparecer la caja con los números se resetea el juego y eso que he insertado la rutina.
 

Edo

You've met with a terrible fate, haven't you?
Miembro de honor
Interesantísimo. Y una herramienta muy práctica, sin dudas.

Genial aporte, amigo, ¡como siempre!
 

GazelMc

Usuario de oro
No Puedo Compilar El Script En La Variable 800A Y el Offset Del Dialogo De Perdida Me dice Lo Siguiente...
1652897525212.png


Como Lo Compilo Gracias...
 

Versekr Dark

Usuario mítico
Alguien sabe compilarlo? lo hemos compilado y al abrir cualquier opcion crashea el juego
Compilar que?, esto no se compila, es una rutina y ya junto con un script muy sencillo, date el tiempo de leerlo correctamente y puedes hasta usar las mismas multichoice del juego si no quieres instarlar la rutina de las multichoice, date un tiempo de leerlo y lo entenderas.
 

KiddKey

Fuck off!
Compilar que?, esto no se compila, es una rutina y ya junto con un script muy sencillo, date el tiempo de leerlo correctamente y puedes hasta usar las mismas multichoice del juego si no quieres instarlar la rutina de las multichoice, date un tiempo de leerlo y lo entenderas.
el problema se nos da con la numeric box si solo usamos el multichoice de CFRU, porque al compilar el script nos da errores de overflow en la linea 111
 
Arriba