Novedades en AL3D

Estos días he estado incorporando una serie de novedades al motor de rendrizado 3D AL3D

Principalmente han sido 2 funcionalidades nuevas, además de corrección de una serie de fallos y mejora del rendimiento.

La primera novedad es la posibilidad de añadir mapas normales y mapas especulares, mientras que la segunda novedad se centra fundamentalmente en un nuevo sistema que permite el post procesado de los renders y volverlos a mostrar por pantalla, una persona como yo, interesada en el procesamiento de imágenes, estaba obligado a meter esta funcionalidad cuanto antes.

Un ejemplo de como crear una malla con mapas normales y especulares es el siguiente:

A continuación se muestra un ejemplo de post procesamiento

También he subido todo el código a github: https://github.com/RdlP/AL3D

Y aquí puede observarse un ejemplo en vivo http://angelluispg.es/AL3D/examples/Postprocessing/

Aunque en el Readme del gthub se pueden ver más ejemplos.

glwp2 glwp3 glwp4glwp5

Hacking Pokemon

Como he comentado en un artículo anterior los pokemons que aparecen en la zona de hierba se almacenan en la posición de la RAM 0xD887 y estos datos ocupan 21 bytes, 1 para la frecuencia de combate y otros 20 bytes para los pokemons que pueden aparecer y sus respectivos niveles. Ocurre lo mismo con los pokemons que aparecen en las zonas de agua, solo que esta información está almacenada en la dirección de la RAM 0xD8A4.

Vamos a probar a modificar estos datos, vamos a establecer que aparezca el pokemon con índice interno 0x15 y con nivel 100 (0x64).

n007

El pokemon con índice interno 0x15 es Mew.

n008

Vamos a cambiar ahora el nombre de nuestro jugador en tiempo de ejecución. Como he dicho en otro artículo el nombre del personaje se almacena en la dirección de la RAM 0xD158

c001

Ahora vamos a cambiar el nombre de ASH por ANGEL LUIS, según el artículo sobre códificación de cadena de textos, la cadena ANGEL LUIS se codifica como 0x80 0x8D 0x86 0x84 0x8B 0x7F 0x8B 0x94 0x88 0x92

n009

Podemos ver como se ha cambiado, estableciendo una longitud en principio no válida por el juego ya que no cabe dentro del menú.

Por último vamos a cambiar el nombre de algún pokemon para ponerle lo que queramos. El nombre de los pokemons está almacenado en la ROM y empieza en la dirección 0x1c21e y respetan el orden según el indice interno de pokemon, es decir, el pokemon que aparece en la primera posición no es bulbasaur sino Rhydorn.

Cada una de estos nombres tiene una longitud de 10 bytes, vamos a cambiar el nombre a Mew que como hemos visto tiene el índice interno 0x15, por tanto desde la dirección 0x1C21E tenemos que contar 0x14 * 0xA = 0xC8 (es 0x14 porque Mew es el numero 0x15 contando desde 0x01, pero aquí estamos considerando que el pokemon con indice 0x01 va a aparecer en el offset 0x00 desde la dirección 0x1C21E, por tanto Mew estará en la posición 0x15-0x01 = 0x14), por tanto el nombre de Mew debe comenzar en la dirección 0x1c2E6

n010

Si lo cambiamos ahora por mi nombre codificado en su sistema, quedará:

n011

Si ahora guardamos la rom y la ejecutamos con el emulador podremos ver lo siguiente:

n012n013

Sistema de codificación de la Primera Generación de Pokemon

En un artículo anterior he mencionado que Pokemon usa una codificación diferente a la ascii estándar para las cadenas de texto, esta codificación es una codificación propietaria. Cada carácter ocupa 1 byte y la codificación depende de la región del juego, por ejemplo, no es lo mismo el juego de caracteres que posee la versión japonesa que el juego de caracteres que posee la versión europea.

Por encontrarnos en Europa, voy a detallar el juego de caracteres de la versión europea.

  • El byte 0x00 es el carácter nulo
  • Del byte 0x01 al 0x47, ambos inclusive. son datos no usados en la versión europea.
  • Del byte 0x48 al 0x5F, ambos inclusive, son usados como caracteres de control.
  • Del byte 0x60 al 0x7E, ambos inclusive, son datos no usados en la versión europea.
  • Del byte 0x80 al 0xBF, ambos inclusibe, son caracteres imprimibles y que se detallaran a continuación.
  • Del byte 0xC0 al 0xDF, ambos inclusive, son datos no usados en la versión europea.
  • Del byte 0xE0 al al 0xFF, ambos inclusive, son caracteres especiales y números imprimibles (a excepción 0xE9, 0xEA y 0xEB).

 

n14

Veamos un ejemplo, el nombre de nuestro usuario se guarda en RAM en la dirección 0xD158 como se muestra a continuación

c001

Como se puede ver en la dirección de memoria mencionada podemos ver 0x80 0x80 0x87 0x50 que si miramos en la tabla superior damos cuenta que corresponde a ASH y que 0x50 es un carácter de control, generalmente para delimitar cadenas.