08-Tiles a partir de imágenes

Aventuras en Megadrive: Tiles a partir de imágenes

Es difícil hacer un juego creando los tiles “a mano”, desde el código es realmente incómodo. El SGDK permite usar imágenes para crear tiles, siempre que respetemos  estas normas:

  • El tamaño de la imagen debe ser divisible por 8 (p.e. 64×32 está bien, 67×31 no).
  • La profundidad de color, por tile, debe ser máximo de 4bpp (16 colores).
  • El número de colores máximo debe ser 64 colores.
  • Debemos indicar cada imagen en el archivo RES correspondiente.
  • Debemos llevar la cuenta de cuantos tiles hemos cargado en VRAM para no machacar una imagen con otra.

 

Lo vemos con un ejemplo, vamos a cargar una imagen en memoria, el SGDK descompondrá la imagen en tiles, crearemos una paleta de colores a partir de la imagen y la mostraremos.

Captura

Empecemos. Crea un proyecto nuevo. Copia esto en el main.c

#include <genesis.h>
#include "resources.h"

int main()
{
//para llevar la cuenta de tiles en VRAM
u16 ind; 
// crea una paleta de colores a partir de la imagen y la
// asigna a la primera paleta de la MD (PAL0)
VDP_setPalette(PAL0, moon.palette->data);

// carga la imagen en VRAM y la dibuja en pantalla en la posición (3,3)
ind = TILE_USERINDEX;
VDP_drawImageEx(PLAN_A, &moon, TILE_ATTR_FULL(PAL0, 0, 0, 0, ind), 3, 3, 0, CPU);
ind += moon.tileset->numTile;

   while(1)
   {
   VDP_waitVSync();
   }

return 0;
}

 

No compiles todavía. Ahora crea una carpeta llamada res que cuelgue de la carpeta del proyecto actual. Descarga esta imagen en esa carpeta. Llámala moon.png

moon

Ahora hemos de preparar el archivo RES. En la carpeta res, crea un archivo de texto llamado ‘resources.res’. Abre el archivo y escribe:

IMAGE moon "moon.png" 0
  • Esto define la variable moon, que es usada en el main.c para referirse al recurso. Podemos llamarla como queramos, no hace falta que se parezca al nombre del archivo aunque sí recomendable.
  • Además le decimos al SGDK cual es el recurso y dónde está (en este caso “moon.png” en la propia carpeta res. Opcional: podemos crear subcarpetas y poner la ruta hasta el archivo para tenerlo todo mejor organizado.
  • Finalmente el cero significa que no usamos compresión de datos. No tocaremos este tema por ahora.

Graba los cambios. Ahora compila el proyecto (MAY+F9). Si todo va bien:

  • Aparecerá un archivo ‘resources.h’ en la carpeta RES.
  • En la carpeta OUT, que se creará al compilar el proyecto, además de la ROM, tendremos a su vez otra carpeta RES. Dentro encontraremos un archivo ‘resources.o’, que es el bitmap procesado por el SGDK.
  • Por supuesto carguemos la rom en un emulador para ver que carga la imagen y la muestra correctamente.

Ahora veamos un poco más el código:

#include "resources.h"

Fuerza al SGDK busca el archivo .res y genera el archivo .h correspondiente (si no existe). El SGDK procesará la imagen para crear tiles a partir de ella. Si has elegido otro nombre para el archivo RES, deberás cambiar el .H también.

u16 ind;

Crea una variable llamada ‘ind’ (índice, index). Esta variable llevará la cuenta de cual es la primera tile libre en VRAM. Cada vez que cargamos una imagen, el SGDK utiliza ‘x’ tiles, le sumaremos ‘x’ a ‘ind’. A su vez, cada vez que cargamos una imagen, le indicamos al SGDK que ponga las tiles a partir de la tile ‘ind’.

‘ind’ inicialmente es 0 (siguiendo la norma de C). Pero el tile 0 por defecto se usa para rellenar el fondo (normalmente se pone un tile plano con el color que nos interese, negro por ejemplo). Para evitar problemas utilizamos

ind = TILE_USERINDEX;

Esto reserva los primeros 16 tiles, planos y además les asigna uno a uno los colores de la primera paleta. De esta forma como normalmente el primer color de la paleta es negro evitamos el problema del fondo, además tenemos tiles planos para utilizar si es necesario.

VDP_drawImageEx(PLAN_A, &moon, TILE_ATTR_FULL(PAL0, 0, 0, 0, ind), 3, 3, 0, CPU);
ind += moon.tileset->numTile;

Cargamos la imagen en VRAM y la mostramos en pantalla:

  • En el plano A.
  • Con la paleta 0 (la primera).
  • Sin invertir ni en plano horizontal ni vertical.
  • En la posición (3,3). recordemos que hablamos en tiles, no en píxels.
  • Incrementamos ‘ind’ tanto tiles como tiles ha generado el SGDK al cargar la luna

Tras esto podemos cargar otra imagen, y sus tiles irán en memoria a continuación. Lo veremos en la siguiente entrada.

Ten en cuenta que no estas obligado a reservar los primeros 16 tiles de VRAM, si los necesitas cambia

ind = TILE_USERINDEX;

por

ind = 0;

o bien

ind = 1;

Si deseas reservar el primer tile (el tile 0) para el fondo, comenzando a usar las tiles para imágenes en el segundo tile (tile 1).

Anuncios