Registrarse

Investigación | En Progreso | TLoZ Minish Cap.

Estado
Cerrado para nuevas respuestas.

Cheve

MoonLover~
Miembro de honor
Investigación: The Legend Of Zelda, Minish Cap





Datos:


  • Titulo de Descarga: The Legend of Zelda - The Minish Cap (U)(DCS)
  • Código interno del Rom: GBAZELDA MC.
  • Idioma: USA
  • Version: 01

(La versión en español es sólo la multi-idioma, teniendo muchisimo menos espacio en la Rom y demasiados punteros)


Lista de cosas a Investigar:


  • Tabla de textos
  • Compresión o no de graficos
  • Estructura de Mapas
  • Scripts - Eventos
  • Tablas de Enemigos
  • Rutinas de utilidad
  • Rutinas generales

Herramientas usadas:

  • VBA & VBA-M & VBA-SDL-H
  • Translhextion
  • HxD
  • NLZ - GBA Advance
  • IDA Pro 1.6


Datos Especiales:

- Existen "Offsets Especiales", que por lo general empiezan en 0x80xxyyzz que son calculados mediante una fórmula matemática:

f(x) = x + 0x80000000 - 0x08324ae4​


Offsets Encontrados:

Textos.​

0x089CD731 Inicio texto de introducción.

Gráficos.​

0x0836E448 - "Tileset 1"

0x08370C18 - "Tileset 2"

0x083734f0 - "Tileset 3"

Tablas.
0x08052E74 : Offset de tabla: 0x0810246C ??

0x08052E78 : Offset de Tabla: 0x08107988 ??

0x08052E7C : Offset de Tabla: 0x0810309C Aparentemente contiene los bloques de cada mapa/tileset

0x08052E80 : Offset de tabla: 0x080B755 ??

0x08052E84 : Offset de tabla: 0x0813A7F0 ??

0x08052E88 : Offset de tabla: 0x080D50FC ??

Roms Rotas: 6
_____________________________

Éste tema se planea que será como un "Diario" donde iré poniendo las cosas que vaya investigando, pero si alguien quiere aportar en el camino, bienvenido sea xD
_____________________________

#Día 1​

- Rom Descargada.

- Post creado.

- Búsqueda en internet de posibles datos ya investigados.
(La búsqueda parece no dar resultados, DataCristal está caido, RomHacking.net también)​


- Empezando por el texto, hasta ahora es solo ASCII, no está comprimido ni cifrado.

- El espacio vacío parece empezar en 0xDE7DC0 aprox

- Los punteros parecen funcionar distinto que en las roms de Pokémon.

- +1 Rom Rota.

- El texto se puede escribir encima sin ningun problema, solo con HxD en Ascci


- Parece que el texto está todo junto.


# Día 1 - Inciso 2

# Kaiser el puto amo - 1

# Día 2

# Día 2 - Inciso 2

# Día 3

# Kaiser el puto amo - 2
 
Última edición:

Kaiser de Emperana

Called in hand
Genial. Si en en algun momento me libero un poco veo si te puedo ayudar aportando algo.
Siempre es bueno ver que se comienzan nuevas investigaciones.

¡Suerte con los graficos! Ojala sean comprimidos y no encriptados, asi te ahorras unas cuantas horas de debugueo... xD
 

TrAiNeRjAc

Uno mas entre miles
Hola, de todas las investigaciones esta es la que mas me ha llamado la atencion ya que involucra el zelda un juego q marco mi infacia igual q pokemon pero a diferencia este era pa cuando me aburria de pokemon. Haci q por lo viejos tiempos tratare de ayudarte con lo que este en mis manos. saludos y suerte!
 

Cheve

MoonLover~
Miembro de honor
#Día 1 - Inciso 2

Llueve, hace frío, tengo mate con café y no trabajo. Estoy inspirado y seguiré mirando un poco.

________________________________________

- NLZ parece leer todos los tilesets y algunos gráficos extra.

- El primer mapa parece estar compuesto de tres tilesets:

"Tileset 1" 0x36E448

"Tileset 2" 0x370C18

"Tileset 3" 0x3734f0



- Por motivos de investigación llamaré al mapa de fuera de la casa de Link mapa 0

- No existe ningun puntero al offset 0x36E448

- En 0x080B14D8 el juego descomprime el Tileset 1

- Ésto se ejecuta dos veces antes de cargar el mapa

- Rom Cargada en IDA Pro (Gracias @Sonicarvalho, tu Tutorial siempre me ayuda)

- Parece ser que 0x080B14D8 es el offset a una funcion que llama al SWI 0x12 y retorna ya que lo usar siempre para descomprimir imágenes (En vez de llamar directamente al SWI, malditos HDP, como si eso les ahorrara taaantas lineas lptm xD) (Anotado en el IDA)

- 30 minutos intentando trackear la parte en la que selecciona el tileset a cargar, una tabla de mapas, de tilesets, o de lo que sea relacionado, sin resultados.

- Se me acabó el primer termo de agua, a cargar otro.

Aquí lo dejo por hoy.
 

H.B.P

Emperador Kaktiácero
Miembro de honor
¡Hey, una buena investigación la que elegiste, sí señor! Creo que rom hackear usando esta rom base podría traer mucha frescura y la dinámica de juego digamos que es más directa que la de Pokémon. Una pregunta, ¿has probado hacer un edit en plan "kamikaze"? Me explico, hacer parches trastocando ciertas partes del rom y probar más o menos si ahí van cosas importantes. De todas formas, con una herramienta para debuggear la RAM se va por un camino un poco más selectivo.

De momento llegaste a hacer lo básico, cambiar textos, pero tiene buena pinta, ¡vamos a ver qué más nos traes!
 

Kaiser de Emperana

Called in hand
Creo que encontre como funcionan los punteros de los tilesets.

Partiendo de un offset "común", como los que usamos en los roms de pokemon, digamos el offset del tileset 1: 0x36E448

Aplicando la función:
f(x) = x + 0x80000000 - 0x08324ae4

Nos da: 0x800fe38c. Que permutado es 8C E3 0F 80. Remplazando todas las coincidencias del rom por el resultado de aplicar la función a otro tileset, conseguí exitosamente hace b*sta el mapa :D

No lo probé mucho y me quedé sin tiempo, por lo que lo dejo acá. Pero con eso, en teoría (a no ser que haya factores que no esté evaluando), se tendría que poder repuntear el tileset por otra imagen comprimida en Lz77.
 
Última edición:

Miguelife

PRINCIPIANTE/NOOB
Muy guapa la investigación,espero que averigües como hacer buenos hacks de Zelda,
Suerte!!!!


Enviado desde mi iPad utilizando Tapatalk
 

Cheve

MoonLover~
Miembro de honor
Creo que encontre como funcionan los punteros de los tilesets.

Partiendo de un offset "común", como los que usamos en los roms de pokemon, digamos el offset del tileset 1: 0x36E448

Aplicando la función:
f(x) = x + 0x80000000 - 0x08324ae4

Nos da: 0x800fe38c. Que permutado es 8C E3 0F 80. Remplazando todas las coincidencias del rom por el resultado de aplicar la función a otro tileset, conseguí exitosamente hace b*sta el mapa :D

No lo probé mucho y me quedé sin tiempo, por lo que lo dejo acá. Pero con eso, en teoría (a no ser que haya factores que no esté evaluando), se tendría que poder repuntear el tileset por otra imagen comprimida en Lz77.
Luego de 30 minutos de no llegar al mismo resultado, me di cuenta que usaste un Tileset diferente al que mencionas xD
Pero si, funciona :D Me gustaría saber cómo llegaste a esos valores ¿:.

____________________________________

#Día 2​

- +5 Roms rotas por lo de arriba.

- 0x80000000 - 0x08324ae4 siempre es +0x77CDB51C El "Numero de Oro"

- 0x0836E448 + 0x77CDB51C = 0x80049964 (Tileset 1 /exterior/)

- Permutado: 64 99 04 80

- Luego de buscar e ir reemplazando las coincidencias, la primera es el tileset del primer mapa (0x08 100E88, 88 0E 10 08)


- Al costado del offset donde se escribe el offset del tileset 1 se vé lo que parece un puntero normal

- "54 0E 10 08"

- En el offset 10 0e 54 encontramos "2C D0 03 80" lo que parece un offset sacado con el número de oro.

- Restado con el numero, queda 08 36 1B 10. Estoy más convencido de que es un offset a un dato y que lo que le sigue en el offset 100E58 son datos de como usar "eso" que está allí guardado.

- "Eso" resultó ser un tileSet pero que no se usa en el primer mapa. ¿Encontraré un puntero al puntero que tiene el offset del TileSet 1?

- Encontrado en 0x08 100F3C

- Estimando Estructura de Mapa:

De 0x08 100F31 a 0x08 100F6B

00 00 00 00 00 00 00 00 00 00 00 88 0E 10 08 C4 0E 10 08 00 0F 10 08 28 6C 06 80 00 00 00 06 00 40 00 80 D8 8A 06 80 00 40 00 06 00 40 00 80 C0 A7 06 80 00 80 00 06 00 40 00 80

Naranja: Puntero al offset + Numero de oro del TileSet1

Azul: Puntero al Offset + Numero de oro de algún TileSet Primario

Rojo: Puntero al Offset + Numero de oro de algún TileSet Primario

Amarillo: Offset + Numero de oro de algún TileSet Secundario o Terciario

Magenta: Desconocido. (¿Dimensiones de mapa?)

Purpura: Offset + Numero de oro de algún TileSet Secundario o Terciario

Cyan: Offset + Numero de oro de algún TileSet Secundario o Terciario


- Busqué un puntero al offset 0x08 100F3C (donde está el puntero naranja) y me encontré con una tabla que empieza en 0x08 102468

- Parece ser una tabla de TileSets

- Buscando 08102468 permutado me arroja a otra tabla.

- Tengo que cocinar, lo dejo por ahora.
 

Kaiser de Emperana

Called in hand
Luego de 30 minutos de no llegar al mismo resultado, me di cuenta que usaste un Tileset diferente al que mencionas xD
Pero si, funciona :D Me gustaría saber cómo llegaste a esos valores ¿:.
Lol, puse el resultado por el que cambie el valor original xD. Sorry estaba apurado.

No hice nada muy raro la verdad. Debuguee un poco empezando de la funcion que llama al swi (la que encontraste vos). Fui poniendo breakpoints y mirando los registros para ver si ya tenia el valor real del tileset, si no lo tenia miraba el lr y subia una rutina mas.
Asi hasta que llegue a una rutina que recibia como parametro un puntero y que al terminar de ejecutarse tenia el puntero real... xD

Y resumiendo lo importante. El puntero resulto apuntar a un numero raro que se veia como 0x80YYYYYY, luego le hacia un and logico con 0x7FFFFFFF (de ahi el +0x80000000, que en realidad no es correcto, pero para nuestra suerte los desarrolladores parece que lo usan siempre asi). Quedando asi en un registro una de las partes del puntero real.
Y por otro lado la rutina lo que hacia era cargar en un registro otro numero raro y sumar los dos valores. Aca medio que me desilucione, porque si lo que hacia era sumar dos numeros cualquiera encontrar los punteros iba a ser un viaje cada vez que quisieramos hacerlo, pero .mirando bien me di cuenta que lo que cargaba en el registro era una constante (siempre cargaba el valor de la misma direccion de la rom), por lo que pude sacar esa funcion matematica.
 

Cheve

MoonLover~
Miembro de honor
#Día 3


- Empecé haciendo un poco de Debugging a la tabla, para saber cómo es leída:


BPR 0x08102468 0xF4

- Break en 0x08052E2E

- Parece ser que la rutina inicia en 0x08052E10 (Gracias IDA <3 )

- Dicha rutina parece ser un "Refresco" de Mapa.

- De analizar minuciosamente la rutina, parece que la Tabla en realidad empieza en 0x0810246C, y el offset que contiene su puntero está en 0x08052E74

- En la Ram @0x02033ACC se van cargando valores provenientes de (En el caso del mapa exterior) 0x0811CA26

- Luego de analizar la Rutina en 0x08052E10 llegué a éstas concluciones: (Todas a comprobar, pero seems legit)

  • Antes de llamar a la rutina, en R2 se especifíca el índice que se usará en las distintas tablas.
  • Antes de llamar a la rutina, en R1 se especifica el offset donde hay ciertos valores que se usa en la primer carga de datos.
  • Antes de llamar a la rutina, en R2 se especifíca el índice que se usará en una tabla también condicionada por R2 (Se usa una sola vez)
  • R5 tiene el valor 0x02033ACC siempre, y en esa dirección de la Ram se escriben todos los valores.
  • Los punteros a las tablas estan en:
    1. 0x08052E74 : Offset de tabla: 0x0810246C
    2. 0x08052E78 : Offset de Tabla: 0x08107988
    3. 0x08052E7C : Offset de Tabla: 0x0810309C
    4. 0x08052E80 : Offset de tabla: 0x080B755
    5. 0x08052E84 : Offset de tabla: 0x0813A7F0
    6. 0x08052E88 : Offset de tabla: 0x080D50FC


(Se puede decir que en 0x08052e74 es una tabla de tablas)

 

Kaiser de Emperana

Called in hand
Estuve viendo por otro lado y termine en la misma función que vos Cheve xD

Me enfoqué más en ver como era mapeado el mapeado. Y si bien no descubrí mucha cosa algo es algo.

Primero puedo casi que confirmar que la tabla en 0x0810309C es una tabla que contiene los bloques de cada mapa/tileset (a confirmar cual de los dos, por lo que vi es el mapa; hay varios punteros apuntando a la misma raw).

Es una tabla de punteros, que apunta a una estructura de este tipo:
(me voy a referir al tipo de punteros que descubrí hace unos días como punteros especiales)
[puntero especial a la raw de los bloques de tiles] [puntero normal a la dirección de ram donde se descomprime la raw] [aparente puntero especial que no es leido en ningún momento de la carga de mapas] ...
La estructura tiene un largo indefinido y puede repetirse todas la veces que se quiera. Termina cuando el primer puntero especial NO comienza con 80 (o sea, cuando en vez de ser XX XX XX 80, es XX XX XX 00).

La raw de los bloques no tiene gran dificultad, es como cualquier otra, una halfword:
4 bits: paleta
2 bits: flip
10 bits: tile

Tengo que investigar aún como funciona el tema de tiles que van encima de otros.

Pero ya nos vamos acercando al editor de mapas...

Una demostración de cambio de bloques (miren las cajas de la esquina):


Una de cambio de tiles (creo que no hace falta comparar...)

Ahora sólo queda hacerlo fácil xD
 

Kaiser de Emperana

Called in hand
Bueno no descubrí demasiado esta vez, pero algo hice.

Estuve viendo la función de la ultima vez (0x08052E10). Esta función recibe 4 parámetros:
- Una dirección de ram con una estructura que parece almacenar todos los datos del mapa (no me puse a analizarla porque al estar en la ram, no tiene gran importancia para lo que estamos haciendo ahora)
- Una dirección de la rom que parece ser como un header del mapa (aunque no estoy tan seguro de eso...)
- El número principal de carga de mapa (sería algo así como el banco en los roms de pokemon)
- El número secundario de carga de mapa (que me tiene bastante confundido...)

Esta función es la encargada de cargar todos los valores necesarios en la estructura de la ram, para luego dibujar el mapa en funciones posteriores (de la rama que vimos al principio, cuando se descomprime el tileset)

Analizando bien esta función y su llamadora (0x8052DA8), podríamos sacar las estructuras que estabamos necesitando.

Pero como ya había empezado a investigar los bloques (y medio que me aburrí de debuguear y ver tantos números xD), me puse a programar el editor de mapas, que de momento no hace nada. Pero con lo que fuimos descubriendo ya puedo ir procesando un poco las imágenes, y va a ser más facil de entender los bloques si vemos los tiles a si vemos un montón de halfwords...
De momento ando algo perdido con el tema de las alturas, no encontré nada sobre como los tiles se superponen. No se si es que ando distraído o que.

Pero bueno, haciendo un bosquejo de los bloques del mapa de la casa de link (o eso al menos creo que leí...). Conseguí esta paleta de bloques:
Si alguién ve algo que yo no vea, que lo comente. Porque yo me esperaba algo como, "Ah esta segunda mitad de la paleta tiene los tiles superiores", y no lo estaría viendo... Debe haber otra raw para los mismos... (Ah, el color negro puro es el trasnparente)

Si a alguien le interesa, en el repositorio de github pueden ver de forma un poco más ordenada lo que hice. (Todo está en game_utils y map_utils, lo otro son cosas que todavía no sirven de nada o que son irrelevantes.)

Gracias a cosarara y a Nintenlord, que saqué un par de cosas de bluespider y de NLZ-Advance :)
 

Noctul~

Usuario de Platino
Que buen juego, uno de los favoritos de mi infancia. Seguire tu investigacion hasta el final, suerte en la investigacion
 

Kaiser de Emperana

Called in hand
Como evidentemente soy incapaz de entender los bloques en escala de grises, me puse a ver las paletas.

De momento descubrí unas cuantas de cosas:
- Antes de ser gradualmente escritas en la Palette RAM, las paletas son escritas en la WRAM en la dirección 0x20176A0.
- Las paletas parecen no estar ni comprimidas, ni encriptadas (por lo menos la que estuve viendo, pero otra cosa que descubrí me hace asumir que son todas). Están el mismo formato que la Palette RAM.
- Existe una tabla ubicada en 0x85A2E80, que tiene las paletas seguidas una después de otra (no se si son todas las paletas del juego o sólo la de los tilesets)
- Existe otra tabla ubicada en 0x80FF850, con punteros a unos header de paletas, con el siguiente formato:
[halfword: numero de paleta (haciendo referencia a la tabla anterior)][byte: número raro que me canse de investigar para que sirve, es usado en algún especie de control antes de copiar la paleta a la RAM vía DMA3][byte: número de paleta en la Palette RAM + 1 (*)]

(*) Está limitado de una forma rara, primero realiza un and lógico entre el byte y 0xF (para eliminar la segunda mitad del byte) y si queda igual a 0 lo transforma a 0x10 (o sea, 16).

Bueno, básicamente ya sabemos todo el final del proceso, ahora habría que ver como se llega a ese punto desde el número de mapa...

PD: Todo esto son conclusiones sacadas de la rutina 0x801D714

-----------------------------

EDIT: Me acabo de dar cuenta que casualmente el número de índice a la tabla de headers de paletas es el mismo número que esta 12 bytes más adelante de los tileset del mapa que estaba viendo... Será que... ;)

EDIT2: Sí era eso. Hubiera mirado 5 minutos más y me daba cuenta LOL. Ahora a programar.
 
Última edición:

H.B.P

Emperador Kaktiácero
Miembro de honor
Vaya, parece bastante interesante. Entonces a ver si lo he entendido, si las paletas no están comprimidas, ¿eso significa que hackear TLoZ es mucho más sencillo que hackear las ediciones Pokémon de GBA a las que estamos acostumbrados? Trataré de seguir el tema de cerca, pues veo que la investigación avanza y se está llegando a un nivel bastante acelerado. Finalmente, mi enorme agradecimiento también a Kaiser de Emperana, vamos a ver hasta dónde llegáis.
 

Cheve

MoonLover~
Miembro de honor
Ya que Kaiser le está dando duro a los mapas, me he puesto a mirar un poco sobre los textos en los scripts.

- En el puntero 0x089CDAF4 está el primer carácter del texto "Good Morning..."



- La rutina que lee el byte lo hace en la línea 0x0805EFA8

- Dicha rutina parece empezar en 0x0805EF8C

- Parece ser que la rutina es la que se encarga de escribir las letras del texto en la Ram

- Es llamada por muchas rutinas externas.

- Una de ellas (0x805EFEC) es muy... hum, llamativa:


Por ahora me iré a hacer la comida.
 

Kaiser de Emperana

Called in hand
.:Helix Boo♪:.;377464 dijo:
Vaya, parece bastante interesante. Entonces a ver si lo he entendido, si las paletas no están comprimidas, ¿eso significa que hackear TLoZ es mucho más sencillo que hackear las ediciones Pokémon de GBA a las que estamos acostumbrados? Trataré de seguir el tema de cerca, pues veo que la investigación avanza y se está llegando a un nivel bastante acelerado. Finalmente, mi enorme agradecimiento también a Kaiser de Emperana, vamos a ver hasta dónde llegáis.
Yo no diría eso. O sea, el que los datos estén comprimidos termina siendo lo mismo si uno sabe el método de encripción (que es LZ77, el mismo de los roms de pokemon). Además, lo que sabemos que no está comprimido son las paletas de los TILESETS (las demás puede que tampoco, pero al menos yo no me puse a verlo); y los roms de pokemon tampoco comprimen estas xD
O sea, si hacemos una comparación entre los dos roms:
- Los de pokemon comprimen: imágenes de tilesets.
- El zelda comprime: imágenes de tilesets, raws de bloques y raws del mapa.
Por lo que, en todo caso sería más dificil según tu análisis. Pero como digo, sabiendo el método de compresión y las tablas que apuntan a todos los valores. Sólo se va a demorar un poquito más en leer el mapa, pero la dificultad es casi igual. Además el que los datos usen el método LZ77, puede hasta hacer más fácil encontrarlos (Cheve tiene un tutorial de cḿo encontrar imágenes comprimidas).

-----------------------------------------------

Este era el mensaje que iba a postear ayer, pero no lo hice para que los mensajes no se combinen por doblepost:

Bueno, terminé la lectura de paletas. Ahora todo se ve mucho mas lindo. Aunque evidentemente mis ideas de como se leían los bloques no eran correctas... Por alguna razón puedo cargar perfectamente la primera raw, pero las demás no. Cosa que no me explico porque estoy cargando las raws correctas y usando los mismos tiles y paletas que para la primera...
O sea... Si no andara ninguna bueno, pero ¿qué carajos?

Igual ya esta cerca de terminado :)
Aca unas muestras de algunos bloques de mapas (como dije los primeros están bien, los demás no tanto):

Para el que quiera probar un poco les dejo de vuelta mi repositorio del editor de mapas.
Solo tiene que crear una carpeta llamada testing y poner una copia del rom con el nombre "bzme.gba". Después ejecutando map_utils.py van a poder ir generando los bloques de los mapas (para elegir el mapa cambien el valor de map_index).
Van a necesitar python 3 y pillow.

-------------------------------------------

Y para no tener el mismo problema que ayer, una mini actu:

Estuve viendo las raw de los mapas y puedo confirmar:
- La tabla de las mismas es la tabla de 0x08107988, que encontramos hace un tiempo.
- Es una tabla que apunta a subtablas que apunta a una estructura como la de los tilesets o los bloques.
- Los mapas a diferencia de los roms de pokemon no tienen bloques con dos alturas. Sino que son mas parecidos al RPGM, tienen dos capas (posiblemente expandibles a tres). Ambas son un montón de halfwords que representan un bloque cada una.
- Está comprimidas en LZ77.

Ya puede realizar las primeras imágenes del mapa con el editor:

Capa 1:


Capa2:

(Está mal porque aún no arregle la carga de bloques que menciono antes)

Ahora solo queda:
- Encontrar dónde está el ancho de mapa.
- Arreglar los bloques

Y ya saco la primera versión de "editor" de mapas. (Va a ser más en visualizador que un editor en este punto...)

Saludos
 
Estado
Cerrado para nuevas respuestas.
Arriba