19 septiembre 2005

Sprites. Introducción

Una de las ventajas que tiene programar para la Gameboy Advance es que incorpora control de sprites por hardware. Este hecho simplificará sobremanera nuestras rutinas, ya que únicamente tenemos que indicarle a la consola cómo dibujar nuestro sprite y cuáles son sus coordenadas, y ella se encargará de todo. Además, también nos permite aplicar transformaciones afines sobre los mismos, pero eso lo veremos más adelante.

Para empezar vamos a ver cómo se almacenan los sprites en la memoria y cómo podemos manejarlos.

Los sprites en la GBA pueden ser de tamaño 8x8 hasta 64x64 pixeles, y se pueden manejar hasta 128 de ellos. Cada sprite estará formado por bloques o tiles de 8x8. Los datos de los 128 sprites se almacenan en una zona de memoria llamada OAM (Object Attribute Memory o Memoria de Atributos de Objetos). La OAM consta de 1KB, donde se encuadran las 128 entradas de atributos de los sprites intercaladas con las 32 entradas disponibles para transformaciones afines.

En lenguaje C podríamos definir ambas estructuras de la siguiente forma:

typedef struct tipo_OAM_ENTRY
{
u16 attr0;
u16 attr1;
u16 attr2;
s16 fill;
} OAM_ENTRY;

typedef struct tipo_OAM_AFF_ENTRY
{
u16 fill0[3];
s16 pa;
u16 fill1[3];
s16 pb;
u16 fill2[3];
s16 pc;
u16 fill3[3];
s16 pd;
} OAM_AFF_ENTRY;

de forma que se entrelazarían de la siguiente manera:

mem (u16)03478BCF
OAM_ENTRY 0 1 2 0 1 2 0 1 2 0 1 2
OAM_AFF_ENTRY pa pb pc pd

Cada entrada de la OAM consta de 3 atributos de 16 bits, en los que se almacena la siguiente información:

ATRIBUTO 0

bits 0..7: Coordenada Y de la esquina superior izquierda del sprite.
bits 8..9: usados para configurar las transformaciones afines u ocultar el sprite.

00 - dibujado normal
01 - el sprite se dibuja según la transformación afin descrita por el atributo 1, bits 9..13
10 - desactiva el dibujado (oculta el sprite)
11 - transformación afín usando el doble del área de dibujado (lo veremos más adelante)

bits 10..11: modo gráfico (efectos especiales)

00 - dibujado normal
01 - habilita el canal alpha
10 - el sprite hace de máscara
11 - prohibido

bit 12: habilita/deshabilita el efecto mosaico
bit 13: modo de color, 16 colores por pixel si vale 0 y 256 si vale 1
bits 14..15: forma del sprite, junto con el tamaño del sprite (atributo 1, bits 14..15) conforma el tamaño real del mismo

ATRIBUTO 1

bits 0..8: coordenada X de la esquina superior izquierda del sprite.
bits 9..13: índice de la transformación afín, sólo se usa si el bit 8 del atributo 0 vale 1
bit 12: volteado horizontal, sólo si el bit 8 del atributo 0 vale 0
bit 13: volteado vertical, sólo si el bit 8 del atributo 0 vale 1
bits 14..15: tamaño, junto con la forma indicada en el atributo 0 conforma el tamaño real del sprite, según la siguiente tabla:

forma\tamaño 00 01 10 11
00 8x 8 16x16 32x32 64x64
0116x 8 32x 8 32x16 64x32
108 x16 8x32 16x32 32x64
Tamaño del sprite.

ATRIBUTO 2

bits 0..9: índice del primer bloque de los que componen el sprite. Si estamos trabajando en modo bitmap, el índice debe valer 512 o más
bits 10..11: indican la prioridad, cuanto más alta, se dibuja primero (y quedará por debajo si luego se dibujan más sprites). Un sprite se dibuja por encima de un fondo de la misma prioridad y, por otro lado, para dos sprites de la misma prioridad, se dibuja primero aquél que tenga la entrada en la tabla OAM con el índice más alto.
bits 12..15: subpaleta que se usará para el sprite cuando estemos trabajando en el modo de 16 colores, sólo si el bit 12 del atributo 0 vale 1

No hay un cuarto atributo, pero para completar el alineamiento en memoria a una doble palabra de 32 bits se suele declarar un relleno (que se usa en las tablas de transformaciones afines, que estudiaremos más adelante).


DOBLE BÚFER

Cuando trabajemos con sprites, se suele usar con la OAM una técnica de doble búfer. Esto es, trabajamos sobre una copia de la OAM y cuando se produzca el retrazado vertical en el redibujado de la pantalla aprovechamos para volcar la copia en la OAM real. De esta forma evitaremos modificar los valores de los sprites justo mientras están siendo dibujados por el hardware de la Gameboy Advance.

En la próxima entrega veremos un ejemplo práctico. Vamos a crear dos sprites de 256 colores (por tanto, compartirán paleta) y podremos moverlos con el keypad y ver cómo se superpone el uno sobre el otro.