Sé que según el antiguo reglamento no debería comentar este tema a no ser de aportar algo a la investigación, pero ya que las cosas han cambiado, he de decir que me parece una pasada. Ya era hora de que se investiguen otras ROMs y quizás otras plataformas para hacerle honor al nombre del foro, que casi en su totalidad se ha estado centrando solo en Pokémon.
En fin, paso de enrollarme más y os deseo lo mejor con esta investigación, he estado atento desde que CheveX abrió el tema y [aunque no tenga puta idea] siento bastante admiración.
Ya casi está lista la carga de mapas (es más pensé que ya estaba, pero me acabo de dar cuenta que hay algunos bloques rotos aún).
El header de mapas que descubrí hace unos días y que luego me entró la duda si lo era o no , resultó ser el header en serio Así que ya se como tenemos la relación de todas las características de los mapeado en base a los números de índice y subíndice de mapa.
Capa1: Capa 2:
--------------------------
Capa1: Capa 2:
--------------------------
Capa1: Capa 2:
--------------------------
Capa1: Capa 2:
--------------------------
Capa1: Capa 2:
--------------------------
Capa1: Capa 2:
El problema, que de momento la carga de mapas está en alrededor de 4 segundos...
Así que me toca optimizar un poco... Igual hay cosas que me di cuenta que estaban mal a medida que fui avanzando (de ahí es donde creo que provienen los errores que hay en el mapa), así que supongo que no va a ser tan dificil bajar ese tiempo.
Hace mucho no actualizo con nada, pero estuvo todos los días varias horas mirando cosillas.
Le dí muchas vueltas al asunto de los textos, y llegué a éstas conclusiones: (Nota, un "?" es "Poco comprobado" )
Si 0x020227A0 = 01 --> Está mostrando texto.
0x020227A0 = Ultima letra cargada (?)
0x020227B0 = Puntero próximo texto a cargar
La rutina 0x805EED6 es la encargada de calcular el offset del texto.
Los textos parecen relacionarse de la siguiente manera:
A 0x805EED6 llega el R3 cargado con una H-Word: XX YY
XX es el número de "Tabla" de mensajes, mientras que YY es "El mensaje en esa tabla"
El offset de las tablas están cargadas tal que: XX XX XX 00 + 089B1D90 = YY YY YY YY dónde XX XX XX 00 es el valor que contiene la tabla ubicada en 0x089B1D8C
"Teoría: En un evento simplemente habremos de escribir "msg 1060" para que nos muestre el mensaje 60 de la tabla 0x10, el juego irá a (0x089B1D8C + 0x10*4), sacará ese valor, le sumará 0x089B1D90 y obtendrá el offset de la tabla de textos (TblTxt). Luego hará TblTxt+(60*4), sacará la D-Word y se la sumará a TblTxt para dar con los datos de escritura. " (?)
Si, hace 3 días que vengo con dolor de cabeza por la mañana xD
Descubrí un par de cosas interesantes sobre los mapas.
Cuando termine la funcionalidad de editar mapas de MQEQ, me puse a probar un poco y descubrí que a diferencia de los roms de pokemon, los mapas no tienen permisos de movimiento. Simplemente borrando unas cajas de un lugar me volví capaz de caminar por ese lugar.
De ahí saqué dos teorías. O los permisos de movimientos dependían de los tileset o de los bloques. Así que me puse a trabajar en el editor de bloques.
Hace unos momentos lo terminé y puedo confirmar que los permisos dependen de los bloques. Entre las capaz y esto el Zelda se parece cada vez más al RPG maker lol.
De momento no tengo ni idea de donde puede estar guardada esa información
En cuanto compruebe que MQEQ no tenga muchos errores en este momento, actualizo el post para que la gente pueda probar.
Como voy a andar un tiempo sin hacer nada, posteo la tontería que descubrí.
No se como está relacionado con los bloques, no encontré ninguna tabla ni patrón que tuviera sentido, pero se que el juego chequea los permisos de los bloques con esta zona de la rom.
Si uno remplaza por muchos 0's la información de 0xb402b, empieza a ser capaz de caminar por las paredes de los mapas de interiores. Pero por alguna razón tambien se pueden atravesar algunos bloques de tilesets exteriores. Parece ser que los permisos de bloques son definidos para todos los tilesets diferentes.
No tengo idea del como funcionan en realidad, pero como dije, voy a andar un poco alejado de la investigación. Así que por si alguien la quiere continuar mientras yo no lo hago, quise postear esto.
Es increíble el trabajo que puede llegar a hacer alguien con experiencia en el ROM hacking.
Simplemente me gusta la idea aunque creó que esto ya dejo de avanzar
Un cordial saludo.
Después de 8 meses sin tocar nada de esto, hace unas semanas me puse a ver un poco lo que tenía hecho en MQEQ. Tras darme cuenta que ni yo me entendía, me puse a refactorizar el código, ahora, creo que está ¿mejor?
Pero bueno, voy a dejar un poco más en claro todo lo que descubrí:
Todos los mapas depender de un índice y un subíndice, con los cueles se llegan a diferenes entradas de estas tablas.
Cada mapa tiene un header. Para llegar al mismo, se debe ver la tabla mencionada arriba.
Esta tabla es una tabla de punteros a otra tabla. El indice del mapa se usa para conseguir el puntero a la segunda, la cual ya si es una tabla de headers. El subindice se usa para obtener el header en sí.
El header consta de 5 halfwords.
- Las dos primeras, no se paraque sirven.
- La tercera es el ancho del mapa en tiles, multiplicado por 16.
- La cuarta es el alto del mapa en tiles, multiplicado por 16.
- La quinta es un índice de tileset. El cual por lo general parece ser siempre igual a 0.
Las tablas de los datos del mapa, los bloques, y los tileset, tienen como entradas finales lo que parece ser un header genérico. El cual consta de 3 words:
- La primera es el puntero a la información (tileset/bloques/etc.), oculto con la función que está posteada en el post principal.
- La segunda, es la dirección de memoria donde se descomprimirán los datos. Los tileset tienen un puntero a la vram, los bloques a la ewram. (Ultra eficiente... guardar el puntero por CADA entrada de la tabla...)
- La tercera es el tamaño de los datos descomprimidos. (Ultra relevante, siendo que los datos se extraen con la función de la bios...)
Las distintas tablas, apuntan a vectores quee tienen una cantidad indefinida de estos headers. Por lo que el juego comienza a cargar los datos indicados en estos headers hasta llegar a uno en el cual el resultado de hacer un and logico entre la primera word y 0x80000000, de 0. Es la bandera que indica que el vector terminó.
Las paletas tambien tienen este header, pero su comportamiento es un poco diferente.
- La primera word es un indice para el segundo header de paleta.
- Las otras dos word son iguales a 0.
Esto es una tabla que apunta a tablas de los headers genericos. Usando el índice y subindice de mapa se llega a sus entradas. Y comienza a descomprimir los datos de los mismos en la ewram.
Los capas son simplementes un montón de halfwords que indican que tiles hay en cada posición.
Esto es una tabla que apunta a tablas de los headers genericos. Usando el índice y subindice de tileset (que está en el header del mapa) se llega a sus entradas. Y comienza a descomprimir los datos de los mismos en la ewram.
Estas entradas apuntan a imágenes...
La ultima entrada de esta tabla es header genérico de las paletas que se van a utilizar.
Las paletas tienen dos headers. El primero es el encontrado en la tabla de tilesets. Cuyo índicce se usa para buscar el segundo header de la paleta, en la tabla correspondiente.
El header 2 consta de dos halfwords:
- La primera es el índice de paleta.
- La segunda, no se que es.
La tabla de paletas, es una tabla donde cada entrada es una paleta. Con el índice del header 2, el juego va a la entrada correspondiente, y copia las 13 paletas que haya desde ese punto en adelante.
Las otras 3 paletas son independientes del mapa.
Mientras estaba arreglando el código, encontré los comportamientos de los bloques. La verdad es que era muy obvio...
La tabla de bloques es una tabla con punteros a vectores de headers genericos. Los bloques dependen únicamente del índice de mapa.
Dependiendo de la dirección de ewram donde se descompriman los datos, los mismos son:
- 0x202ceb4: datos de las imágenes de los bloques de la capa 1 del mapa
- 0x2012654: datos de las imágenes de los bloques de la capa 2 del mapa
- 0x202aeb4: datos de los comportamientos de los bloques de la capa 1 del mapa
- 0x2010654: datos de los comportamientos de los bloques de la capa 2 del mapa
Los datos de la imagen, tienen el formato de la VRAM, (com los bloques de las rom de pokemon).
Por cada bloque, hay una halfword con un valor que indica su comportamiento. No tengo ni la menor idea de si es valor cumple con algún patrón o que. Pero vamos, si copiamos el comportamiento de los bloques que ya están el juego, anda.
Por ejemplo, si le ponemos los siguientes comportamientos a los bloques:
- 0x1ab: el bloque no se puede atravezar.
- 0x465: se puede caminar por la mitad izquierda del bloque.
- 0x464: se puede caminar por la mitad derecha del bloque.
- 0xb: se puede caminar por encima del bloque.
- 0x3f: el bloque se puede levantar y lanzar.
- etc.
Bueno y eso es lo que hay por ahora. En MQEQ, ejecutando desde el código fuente, se pueden modificar todos los datos mencionados acá.
Cuando tenga tiempo para programar la interfaz de cambio de tiles y paletas, saco un ejecutable para los vagos de windows.
Pero bueno, todo lo que es el aspecto gráfico de los mapas, se podría decir que está listo. Salvo que vayamos descubriendo cosas nuevas.
~No caí en cuenta de que use la Rom Multi Idioma, luego paso los offsets de la Rom USA~
He decidido aportar mi granito de arena investigando sobre los offsets y paletas del "Hero's Sprite", después de un rato jodiendo gráficos logre encontrar lo que estaba buscando más un extra, con esto me refiero a las paletas de los Zumos que cambian el color de la Túnica:
Código:
Sprite de Link: 13A500
Paleta: 5A2590
~Paletas de Zumos~
Rojo: 5A25B0
Azul: 5A25D0
Morado: 5A25F0
Por desgracia el overworld no esta tan ordenado como en las roms de Pokemon pero es posible editarlo, valientes los que se atrevan a insertar un personaje cambiando todos los frames:
Si acomodas bien primeros frames se verán tal cual ingame, pero luego van a notar algunas partes desordenadas hasta llegar a esto:
También he encontrado las imágenes de los items del menú, por falta de tiempo solo he encontrado las paletas de la primer espada (Smith), prometo traerles el resto en cuanto me desocupe:
Código:
Items: 2E5FE0
~Paletas~
Espada: 5A2450
Y bueno, les dejo una muestra de como he cambiado las paletas de Link, he usado los zumos para tener variedad de "Trajes":
@Ωmega, si cambiás el ancho de la imagen a 2 tiles se podrían editar fácilmente los frames de 16x32 y si lo cambiás a 4 tiles se podrían editar fácilmente los frames de 32x32.
---------------------------
Esta vez traje unas cuantas cosas distintas, todas a medias.
La tabla de warps dlos mapas es la tabla de 0x13a7f0.
Cada mapa tiene una entrada a la misma. La que se consigue con el indice y el subindice del mapa.
Y termina en un vector de tamaño indeterminado cuyas entradas consisten en 20 bytes:
Código:
XX XX XX XX XX XX [COLOR="Red"]XX XX[/COLOR] [COLOR="Blue"]XX XX[/COLOR] XX [COLOR="SeaGreen"]XX[/COLOR] [COLOR="DarkOrange"]XX[/COLOR] XX XX XX XX XX XX XX
- coordenada X de destino
- coordenada Y de destino
- índice de mapa destino
- subíndice de mapa destino
De los bytes del final, no tengo idea.
De los del principio, CREO que el primero es un "tipo de warp" y los siguientes son parámetros que se usan según el tipo del warp.
El vector indefinido termina cuando se encuentra un:
Código:
FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00
La tabla de 0xd50fc, es la que tiene todos los eventos de cada mapa. Se llega a las entradas de la misma con el índice y subíndice del mapa.
Sus entradas consisten en:
- Un puntero a algo que no se lo que es...
- Un puntero a las decoraciones de mapa.
- Un puntero a los enemigos del mapa.
- Un puntero a los scripts de loot (cofres).
- Una word que por que he visto siempre está en 0.
- Otra word que por lo que he visto está siempre en 0.
- Un puntero a una función que parece ser un callback llamado en cada frame.
- Un puntero a la función de carga de scripts de personas.
- Un vector indefinido de bytes, que creo que está relacionado con el loot del mapa. Este vector se deja de leer cuando encuentra los bytes "FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00".
Se usan para cargar algunos tiles que estén por encima del jugador. Consiste en un conjunto de 16 bytes:
Código:
XX XX [COLOR="DarkOrange"]XX XX[/COLOR] XX XX XX [COLOR="Red"]XX XX[/COLOR] [COLOR="Blue"]XX XX[/COLOR] XX XX XX XX XX
- número de decoración (debe haber alguna tabla por algún lado)
- coordenada X
- coordenada Y
No se nada del resto
Sus entradas ocupan 16 bytes.
Código:
XX XX [COLOR="DarkOrange"]XX[/COLOR] XX XX XX XX [COLOR="Red"]XX XX[/COLOR] [COLOR="Blue"]XX XX[/COLOR] XX XX XX XX XX
- número de enemigo
- coordenada X
- coordenada Y
La tabla de datos de enemigo, está en 0xd2c58. Sus entradas ocupan 16 bytes. No miré más.
La tabla de las funciones de IA de los enemigo está en 0xd3bf8.
Y encontre un vector de halfwords que no se lo que es pero parece estár relacionada de alguna forma... Está en 0xd3d94.
Ocupa 16 bytes.
Código:
XX XX [COLOR="DarkOrange"]XX XX[/COLOR] [COLOR="Magenta"]XX XX[/COLOR] XX XX XX XX XX XX XX XX XX XX
- item a dar
- posición de script (este no parece funcionar por coordenadas)
Esto no me gustó mucho, porque va a ser dificil armar un prgrama que lo comprenda... Pero los scripts son cargados por una función. Que según los valores de algunas variables carga o una tabla de scripts u otra.
Si uno desensambla la función a la que apunta este puntero, va a ver que esta tiene una (o más) llamada(s) a la función en 0x0804addc, la que recibe el puntero de la tabla de scripts de persona del mapa, por r0.
Si uno se dirige en el editor hexadecimal a la dirección de esta tabla, va a encontrar una serie de entradas de 16 bytes.
Código:
XX XX [COLOR="DarkOrange"]XX XX[/COLOR] XX XX XX XX [COLOR="Red"]XX XX[/COLOR] [COLOR="Blue"]XX XX[/COLOR] [COLOR="Magenta"]XX XX XX XX[/COLOR]
- número de sprite
- coordenada X
- coordenada Y
- puntero al script asignado
Un script es un conjunto de halfwords seguidos uno después del otro.
Lo que hace el ejecutador de scripts es leer la halfword, hacerle un and lógico con la halfword 0x3ff (por lo que toma los 10 bits menores) y buscar su entrada en la tabla de funciones de script. Obviamente, luego la ejecuta...
La tabla de funciones de scripts está en 0x11e524
Cada función es recibe como parámetro un puntero a la ram, que guarda el puntero a la dirección en la rom del script que se está ejecuntando. Cada función es encargada de actualizar la dirección de la misma para que luego se ejecute la siguiente instrucción.
El script termina cuando se lee 0xFFFF.
Cada una de las tablas que mencioné acá, son de tamaño indefinido y terminan cuando se encuentran los siguientes bytes:
Código:
FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
No miré nada de las cosas que no menciono.
Y bueno, eso sería todo. Ya llegamos al punto donde cualquiera puede aportar, simplemente cambiando bytes desde el editor hexadecimal y diciendo qu es lo que pasa.
Ej: "si escribo 0x2FE en un script, me dan un objeto"
Si nos ayudan con los scripts, nos vendría genial...
Bueno. Miré un poco más de los scripts. No encontre mucho, pero hice algunas cosas.
Como dije antes, lo scripts son vectores de numeros de 2 bytes (16 bits). Los 10 bits menos significativos indican el comando a ejecutar. Y los 6 bits más significativos indican la cantidad de parámetos del comando más 1 (es la cantidad de halfwords que debe avanzar el script una vez termina, por eso cuenta también cuenta la halfword del comando en sí).
Los scripts en este juego parecen estar constantemente en ejecución. Por lo que hay algunos comandos que ejecutan acciones directamente, algunos que configuran aspectos del evento y otros que simplemente son un "esperar hasta que pase algo".
Los comandos que se lo que hacen al 100% son... digamos pocos.
nop:
bytes: 0x0400
parámetros: ninguno
descripción: no hace nada
branch:
bytes: 0x0803
parámetros:
- desplazamiento (2 bytes) (con signo)
(auque actualmente hice un especie de truco para que sea más sencillo compilarlo y recibe dos paŕametros. Mirar los ejemplos del repositorio para ver como funciona)
descripción: es el "goto" de este juego, pero funciona diferente. Este no recibe un puntero, sino un valor que indica la cantidad de bytes que se va a desplazar con respecto a la posición actual, menos dos (no me pregunten a mí...).
call_function:
bytes: 0x0C0B
parámetros:
- puntero a la función (4 bytes)
descripción: ejecuta la función pasada. Es el "callasm" de este juego, pero a diferencia de los juegos de pokemon, acá se usa MUCHO.
Hay algunos comandos que estimo lo que hace según lo que pasa si los uso o no:
cmd_50: recibe un parámetro, y cambia la animación del sprite.
cmd_51: detiene la ejecución del script hasta que ocurra algo.
cmd_5d: es un msgbox simple. Recibe dos parámetros, un id de mensaje, y un número que no se lo que hace (en los casos que vi estuvo siempre en 0)
cmd_79: recibe un parámetro y hace que el sprite deje de ser traspasable
Haciendo un "call_function 0x8066289" parece hacer que el cmd_51 se quede esperando hasta que el personaje hable con el evento, caso en el cual continuará con la siguiente instrucción del script.
Para compilar esto necesitan: cygwin, armips y devkitarm. Luego tienen que poner un rom de BZME en la carpeta del repositorio. Y por último ejecutar make.
El repositorio contiene:
- un repunteo de la tabla de comandos de scripts (archivos "asm/patches/script_table_ptr.sinc", "src/script_table.c", "include/scripts.h", "BZME.ld")
- un nuevo comando de script, para mostrar mensajes sencillamente (que hice antes de descubrir el cmd_5d) (archivos: "src/script_table.c", "src/custom_script_cmds.c", "BZME.ld")
- definición de comandos de scripts (archivo "asm/macros/script_cmds.inc")
- unos scripts (archivo "asm/testscripts.s")
- asignación de uno de los scripts anteriores al abuelo de Link, en el momento en que Link debe llevar a Zelda al festival (archivo "asm/patches/blacksmith_script_ptr.sinc")
(Con asginación, me refiero a simplemente cambiar el puntero...)
En la carpeta tools, también está el engendro del demonio que estoy usando actualmente para decompilar los scripts. Para usarlo, simplemente ejecuten:
Donde nombre del rom es el path a su rom. Y offset del script el offset donde comienza el script.
Probablemente la próxima versión de MQEQ funcione con este repositorio, más al estilo proyecto que modificando directamente la rom.
De momento el repositorio es cualquier cosa. Es para ir probando lo que se me ocurra de forma fácil. Espero cualquier consejo de como mejorarlo o de como hacer para que funcione en Windows sin la necesidad de cygwin, sin hacer mucho trabajo.
Saludos.
PD: si alguien puede ir haciendo los macros de los comandos que vaya encontrando y falten en el archivo "asm/macros/script_cmds.inc", ayudaría mucho.
PD2: cualquier duda de como usar el repositorio no duden en preguntarme
Como Cheve posteó unos mensajes atrás, el juego tiene una tabla de textos, donde están absolutamente todos los textos... Probablemente lo hicieron así pensando en la versión multiidioma, porque hay 7 punteros apuntando a la misma tabla, uno al lado del otro xD
Agregué un par de scripts al repositorio:
- Uno para extraer los textos de la rom. Los deja en unos archivos con syntaxis de asm. Para compilar el repositrio ahora son necesarias las tools de pokeruby, las que deben estar en el directorio "tools/pokeruby" (por ahora uso nomás el preproc, para los textos).
- Otro para generar una tabla con el formato que usa el juego en base a los textos que se indiquen.
En mi repositorio ya están, probablemente mal, porque hay caracteres que reciben parámetros y puede que se me haya pasado alguno que casualmente reciba el fin de línea. Pero por ahora sirve.
Si compilan el repositorio van a poder ver lo mismo del gif.
El repunteo de la tabla de textos está en el archivo "text_table_repoint.sinc".
La pricipal es generada automáticamente a la hora de compilación. Las tablas de textos están en el directorio "data/texts" y su orden está en el archivo "data/texts/table_order.cfg".
Ya se lo que hacen unos cuantos comandos más:
enterquick:
parámetros: ninguno
descripción: entra a un "modo de ejecución rápida", ejecuta los comandos seguidamente hasta que llegue a un exitquick.
exitquick:
parámetros: ninguno
descripción: termina el "modo de ejecución rápida" iniciado por enterquick
branch_ifzero:
parámetros: dirección a saltar
descripción: hace un branch si el ultimo resultado dio 0 branch_ifnotzero:
parámetros: dirección a saltar
descripción: hace un branch si el ultimo resultado no dio 0
checkflag:
parámetros: dirección a saltar
descripción: se fija si la flag está activada (usar antes de branch_ifzero o branch_ifnotzero).
checknewactions:
parámetros: ninguno
descripcion: controla si ocurrió alguna action especial (ej: alguien habló con el evento).
(CREO)
sendsignal:
parámetros: banderas (4 bytes)
descripcion: envía una señal que pueden leer todos los ecentos del mapa
setflag:
parámetros: numero de flag
descripcion: activa la flag
clearflag:
parámetros: numero de flag
descripcion: desactiva la flag
waitframes:
parámetros: cantidad N de frames
descripción: espera N frames
waitsignal:
parámetros: banderas
descripción: si el resultado de hacer un AND lógico entre el parametro recibido y el último valor setteado con sendsignal es distinto de 0, continúa con el script. Caso contrario se queda esperando.
lock:
lock2:
parámetros: ninguno
descripción: el personaje ya no se puede mover libremente. No se cual es la diferencia entre los dos, no me fijé.
release:
parámetros: ninguno
descripción: el personaje se puede mover libremente
setplayerscript:
parámetros: puntero a un script
descripción: asigna un script al jugador. Si no se desasigna, el jugador no se podrá mover al final.
set_unk_important_flags_zero
set_unk_important_flags_two
set_unk_important_flags_four
set_unk_important_flags_eigth
parámetros: ninguno
descripción: cambian el valor de la misma flag a valores específicos. Ni idea de para que sirve. Comentarlo no parace afectar en nada...
addaction_talk:
parámetros: ninguno
descripción: el evento ahora chequeará cuando le hablen.
waitmsg:
parámetros: ninguno
descripción: espera a que el jugador pase el mensaje para continuar el script.
msgbox:
msgbox2:
msgbox3:
parámetros: numero de mensaje, y los msgbox2 y 3 reciben otro número que no se en qué afecta (siempre que lo vi estaba en 0)
face:
parámetros: dirección
descripción: cambia la dirección en la que mira el evento
faceplayer:
parámetros: ninguno
descripción: hace que el evento mire hacia el jugador.
faceme:
parámetros: ninguno
descripción: hace que el jugador mire hacia el evento.
setmovementspeed:
parámetros: velocidad
descripción: cambia la velocidad con la que se mueve el evento. Por defecto es 0, es decir, no se puede mover.
move:
parámetros: coorddenada x, coordenada y
descripción: el evento se mueve a las coordenadas especificadas
setbehaviourflag:
parámetros: numero de bandera
descripción: activa ciertas banderas de comportamiento.
- 0x0 pare ser estar quieto
- 0x1 animación de caminando,
- 0x4 mostrar un globo con un signo de exclamación
- 0xa hace que el evento sea sólido
giveitem:
parámetros: numero de item
descripción: da el objeto al jugador. Parece desasignar el script asignado al jugador.
La verdad que con esto ya se pueden hacer algunas cosas. Así eran los scripts originales de la escena del gif:
Casi que se lo que hace todo en el script. Salvo los callfunction y algún que otro comando, que no parece ser indispensable.
Y este es el script por los que remplacé los anteriores:
Código:
.include "asm/macros/script_cmds.inc"
.equ LINK_DONE, 0x1
.equ BLACKSMITH_DONE, 0x2
.equ ZELDA_DONE, 0x4
.global ScriptZelda
ScriptZelda:
enterquick
face 0x4
setmovementspeed 0xc0
exitquick
move 0x58 0x50
face 0x4
setbehaviourflag 0x0
waitsignal BLACKSMITH_DONE
move 0x70 0x68
face 0x4
msgbox2 0x5002 0x0
waitmsg
move 0x58 0x50
face 0x4
setbehaviourflag 0x0
sendsignal ZELDA_DONE
end
.global ScriptBlacksmith
ScriptBlacksmith:
enterquick
face 0x4
setmovementspeed 0xc0
exitquick
lock
setplayerscript ScriptLink
move 0x88 0x50
face 0x4
setbehaviourflag 0x0
waitsignal LINK_DONE
move 0x70 0x68
face 0x4
msgbox2 0x5001 0x0
waitmsg
move 0x88 0x50
face 0x4
setbehaviourflag 0x0
sendsignal BLACKSMITH_DONE
waitsignal ZELDA_DONE
giveitem 0x0
waitframes 120
msgbox2 0x5003 0x0
waitmsg
release
end
ScriptLink:
enterquick
setmovementspeed 0xc0
exitquick
move 0x70 0x68
face 0x4
msgbox2 0x5000 0x0
waitmsg
move 0x70 0x50
face 0x4
setbehaviourflag 0x0
sendsignal LINK_DONE
end
Y mi nueva tabla de textos:
Código:
text_5000:
.string "Bueno...{END}"
text_5001:
.string "Como podran observar...{END}"
text_5002:
.string "Esta vez avance un poco mas.{END}"
text_5003:
.string "Aunque todavia no se poner acentos...{END}"
Después de meses de trabajo, finalmente terminé de traducir los textos del juego. ¡Fue muy duro pero valió la pena!
LOL
Me di cuenta de algo. El rom usa un tabla de textos.... Por que está pensado para ser un rom multi idioma... La versión multiidioma del rom tiene la opción en español... O sea que hay una versión de la tabla de textos en español....