Es recomendable la lectura de los artÃculos anteriores para comprender mejor el actual:
En este artÃculo veremos algunas caracterÃsticas de la GameBoy relacionadas con la VRAM y la pantalla, de este modo comprenderemos mejor su funcionamiento y que se puede llegar a hacer con ella.
Primero aclaremos que la pantalla de la GameBoy está compuesta de 3 capas:
- Background: Fondo de los niveles del juego. - Sprites: Elementos móviles como personajes o enemigos. - Window: Parte donde se muestra nformación como la puntuación, vidas y demás elementos informativos. |
NOTA: La VRAM está dividida en dos regiones, una para los sprites y otra compartida entre el fondo y el window. Por este motivo cuando debugeamos con bgb la VRAM del background/window aparece en una pestaña distinta a la de tiles.
El segundo aspecto a tener en cuenta es la limitada cantidad de VRAM de la que dispone la GameBoy, sabiendo que la pantalla tiene una resolución de 160x144 pixels nos dá un total de 23040 pixels, si la GameBoy utilizase un sistema tipo framebuffer , es decir cada punto de la pantalla es mapeado a una posición de la memoria necesitarÃa 23040 bytes -> 22KB
Entonces como es posible mostrar una pantalla que precisa de 22KB de VRAM tan solo con 8KB?
La respuesta es un ingenioso sistema de reutilización de tiles, como los niveles suelen repetir tiles se cargan estos en VRAM para luego crear sprites/backgrounds/screen indicando la posición de la VRAM a utilizar, de este modo varios sprites hacen referencia a las mismas posiciones de la VRAM, disminuyendo considerablemente la cantidad de RAM necesaria.
Este sistema ya lo habiamos utilizado de forma transparente en los artÃculos anteriores donde cargábamos los tiles a VRAM mediante la función set_sprite_data y mediante la función set_sprite_tile indicábamos la posición en VRAM del tile a asignar al sprite en ese momento.
Los backgrounds de la GameBoy permiten realizar scroll sobre ellos, estos es gracias a que en VRAM se mapea el background entero aunque la pantalla solo esté mostrando parte de este, para que se entienda aclaremos algunos puntos:
- Cada tile es de 8×8 pixels. - La pantalla es de 160x144 pixels -> 20x18 tiles. |
|
- En VRAM hay 32x32 tiles permitiéndonos cargar en una instrucción un background y hacer scroll sobre él. |
Para explicar como funcionan los fondos en la GameBoy con estos datos tenemos mas que suficiente pero dejo algunos videos y enlaces muy interesantes sobre el hardware y funcionamiento de la GameBoy:
- https://www.youtube.com/watch?v=RZUDEaLa5Nw
- https://www.youtube.com/watch?v=t0V-D2YMhrs
- https://www.youtube.com/watch?v=ecTQVa42sJc
- http://hisimon.dk/misc/pandocs/
- https://www.copetti.org/writings/consoles/game-boy/
Para crear nuestro fondo utilizaremos la herramienta gbtd(GameBoy Tile Designer), donde crearemos nuestros tiles con los que confeccionaremos nuestro mapa:
Creamos unos tiles con diferentes patrones, en este caso son muy básicos ya que tan solo nos van a servir como ejemplo.
Transparente | Suelo | Negro |
---|---|---|
Guardamos el pack de tiles para que el Map Builder pueda cargarlos:
File -> Save As: BackgroundTiles.gbr
También exportamos los tiles como vimos en artÃculos anteriores:
File -> Export to
Para diseñar el mapa cargaremos los tiles en gbmb(GameBoy Map Builder):
cd ~/GBDEV/gbmb
wget http://www.devrs.com/gb/hmgd/gbmb18.zip
unzip /gbmb18.zip
wine GBMB.EXE
Creamos el mapa y cargamos los tiles:
File -> Map Properties:
Size: Definimos el tamaño del fondo: 32x18 tiles
Browse: Z:\home\kr0m\GBDEV\code\BackgroundTiles.gbr
Recordemos que la pantalla de la GameBoy es de 160x144 pixels -> 20x18 tiles pero como queremos hacer scroll horizontal el mapa debe ser mayor(32x18) con un máximo impuesto por la VRAM de 32x32 tiles.
Creamos nuestro mapa seleccionando los tiles a utilizar y dibujando en el mapa con el botón derecho:
Exportamos el mapa:
File -> Export
En el código debemos cargar los tiles en VRAM, desde la posición 0 hasta un total de 3 tiles:
set_bkg_data(0, 3, BackgroundTiles);
Y cargar el background desde las coordenadas 0,0, un tamaño de 32x18 leyendo los datos del array BackgroundMap que actúa a modo de Ãndice indicando que tile debe cargarse en cada posición del fondo:
set_bkg_tiles(0, 0, 32, 18, BackgroundMap);
El código serÃa el siguiente:
#include <gb/gb.h>
#include "BackgroundTiles.c"
#include "BackgroundMap.c"
void main(){
set_bkg_data(0, 3, BackgroundTiles);
set_bkg_tiles(0, 0, 32, 18, BackgroundMap);
SHOW_BKG;
DISPLAY_ON;
while(1){
scroll_bkg(2,0);
delay(100);
}
}
Compilamos:
Cargamos el juego en el emulador y podemos ver como el portview se desplaza por la VRAM mientras muestra por pantalla el contenido:
En este video se puede apreciar como el VRAM viewer de bgb tiene las dos pestañas comentadas al principio del artÃculo, una para visualizar la parte de la VRAM del background y otra para los tiles/screen.