Posiblemente no tienes mucha idea de que estamos haciendo en esta serie de posts. No te preocupes amigo/a/e que vamos a intentar explicarlo brevemente.
Vamos con ello:
驴Qu茅 es FCEUX?聽 – Se trata de algo m谩s que un emulador de la NES de Nintendo. Incorpora funcionalidades para poder grabar las partidas en formato fm2 (Tool-assisted game movies) y poder extender los juegos programando scripts en Lua.
驴Se pueden jugar juegos de NES con este emulador? Si dispones de la rom de un juego de NES podr谩s cargarlo y disfrutarlo.
驴Necesito tener FCEUX instalado para seguir estos posts?聽 – No pero es muy muy recomendable. La idea de estos posts es que quienes los sigan dispongan de FCEUX. Para saber como compilar la 煤ltima versi贸n en GNU+Linux puedes visitar el primer post: FCEUX – 0x00 – Compilar la 煤ltima versi贸n
驴Necesito saber Lua para programar scripts para FCEUX?聽 La verdad es que no. Lua es muy sencillo y los ejemplos de c贸digo que se ponen de ejemplo en estos posts son muy cortos.
Y bueno. Espero que eso ayude un poco a ponerse en situaci贸n a un posible lector para que sepa un poco de que va todo esto.
Descargar la ROM del Tetris
En esta ocasi贸n vamos a necesitar descargar la rom del Tetris.
Descargar rom: Tetris.zip
Esa rom la cargaremos en el emulador聽 para probar que funciona correctamente el juego. No es necesario descomprimir el zip.
Cargar la ROM del Tetris
Abres FCEUX y presionas Control + O . Seleccionas la rom y a disfrutar.
Otra opci贸n es cargar tambi茅n tanto la ROM como el script en LUA (Si es que quieres cargar uno) directamente as铆:
$ fceux --noframe --nogui --loadlua Tetris.lua Tetris.zip
Sacando la posici贸n y el tipo de piezas
Cargando este peque帽o script en LUA podemos determinar en que posici贸n andan las piezas.
while true do
x = memory.readbyte("0x0060"); -- Posici贸n x pieza actual
y = memory.readbyte("0x0061"); -- Posici贸n y pieza actual
p = memory.readbyte("0x0062"); -- id pieza actual
gui.text(10,10,"x: " .. x .. " y: " .. y .. " p: " .. p);
emu.frameadvance();
end
Esto permite por ejemplo conocer los tipos de piezas que vamos a tener en el tetris.聽 Son estos: imgs_tetris_nes_piezas.tar.gz
Podemos ir parando el juego (pulsando la tecla Pause de nuestro teclado) cada vez que sale una nueva ficha. Moverla con la tecla F para ver que la variable p va cambiando de n煤mero.
Esto al final nos permite sacar eso que he sacado yo. Y saber que en tetris disponemos de 7 tipos de piezas.
Lo que hace el juego es girar las piezas 90 grados. De esa forma en teor铆a todas las piezas tendr铆an que tener 4 posiciones pero si giras por el ejemplo la 10 cuatro veces en todas tendr谩s la misma forma.
Si giras la pieza 8,9 cuatro veces 90 grados tendr谩s solamente 2 formas.
聽聽聽聽
Es por esto que al final disponemos solamente de 7 tipos de piezas que suponen 18 formas.
Examinar zonas de la memoria
Para ver que valores cambian en memoria es interesante crear una funci贸n que nos permita justo eso. Podemos imprimir los resultados por consola para ir mirando si cambian.
Un c贸digo de ejemplo para hacer esto puede ser este:
function from_Hex(str)
local converted = string.format( "0X%4.4X", str )
return converted
end
function show_memory(from,to)
for position = from,to -- Desde 00 a FF por ejemplo
do
valor = string.format('%02d',memory.readbyte(from_Hex(position)));
io.write("[" .. from_Hex(position) .. " : " .. string.format('%X',valor) .. "]\n");
end
end
while true do
x = memory.readbyte("0x0060"); -- Posici贸n x pieza actual
y = memory.readbyte("0x0061"); -- Posici贸n y pieza actual
p = memory.readbyte("0x0062"); -- id pieza actual
gui.text(10,10,"x: " .. x .. " y: " .. y .. " p: " .. p);
show_memory(96,98)
emu.frameadvance();
end
Al cargarlo junto a la rom vamos a poder ir viendo en pantalla la zona que indiquemos. En este caso le he pasado que muestre desde la 96 a 98.
Le paso los valores en decimal.
Eso me permite monitorizar los valores desde la consola y por tanto buscar novedad en esas posiciones de memoria.
El valor de la siguiente pieza
Gracias a la funci贸n show_memory() que hemos creado antes podemos ir monitorizando zonas de memoria.
En este caso mientras juego voy monitorizando y viendo que cosas cambian. Se puede por ejemplo sacar la zona de memoria en la que se almacena la siguiente pieza.
Por ejemplo en la siguiente captura se ve que la pieza 芦NEXT禄 es la 2.
Y si miramos en la consola se ve que est谩 en la posici贸n 0x00BF
Cambiando la siguiente pieza por la que queramos
Ahora simplemente podemos crear una variable llamada 芦next禄 que contenga la zona de memoria en la que se almacena la siguiente pieza.
Luego cambiamos el valor por el de la pieza que queramos que salga.
function from_Hex(str)
local converted = string.format( "0X%4.4X", str )
return converted
end
function show_memory(from,to)
for position = from,to -- Desde 00 a FF por ejemplo
do
valor = string.format('%02d',memory.readbyte(from_Hex(position)));
io.write("[" .. from_Hex(position) .. " : " .. string.format('%X',valor) .. "]\n");
end
end
while true do
x = memory.readbyte("0x0060"); -- Posici贸n x pieza actual
y = memory.readbyte("0x0061"); -- Posici贸n y pieza actual
p = memory.readbyte("0x0062"); -- id pieza actual
gui.text(10,10,"x: " .. x .. " y: " .. y .. " p: " .. p);
next="0x00BF"
memory.writebyte(next, "10")
show_memory(190,192)
emu.frameadvance();
end
Se puede ver como siempre sale la pieza 10 (el cuadrado).聽 En la captura se ve que ha salido 43 veces seguidas :D.
Y bueno. M谩s o menos eso es todo por hoy.
Saludos cordiales.