Gráficos en Consolas Antiguas. Temp 2 (II): Game Boy Advance

La siguiente consola que voy a tocar en esta serie de entradas no es una consola pensada para el 3D a tiempo real pero si que apareció cronológicamente en la misma generación que PS2, GCN y Xbox.

Obviamente me estoy refiriendo a la segunda generación de portátiles de Nintendo, la Game Boy Advance.

Game-Boy-Advance-GBA-SP-and-GB-Micro-size-comparisonTransparent-Background

CPU y Work RAM

La CPU de GBA es un ARM7TDMI, se trata de la segunda CPU con set de instrucciones ARM aparecida en la historia de las consolas después de 3DO. Funciona a una frecuencia de 16.78 MHz en cuanto a velocidad de reloj y su potencia es de unos 15 MIPS aproximadamente que es una cifra muy superior a la de SNES/SFC y Mega Drive/Genesis. La potencia de dicha CPU le permite a GBA no solo generar las Name Tables para generar la escena a una velocidad mucho más rápida de lo normal sino poder realizar transformaciones afines sobre los patrones/sprites que no son posibles en las consolas de sobremesa de 16 bits.

Una de las particularidades y esto es important en el caso de GBA es el hecho que aparte de set de instrucciones ARM de 32 bits tiene otro que es gemelo llamado THUMB pero con instrucciones de 16 bits. Esto es importante porque hay partes del hardware de GBA que tienen un bus no de 32 bits sino de 16 bits y por tanto tardan dos ciclos de reloj en escribir en memoria una instrucción, en esos casos se recomienda el uso de instrucciones THUMB con tal de minimizar el número de ciclos de reloj que se pueden utilizar.

¿Por qué  es importante esto?

gbain5_lGBA tiene un pozo con dos memorias principales distintas.

La primera se encuentra dentro del chip y es la llamada Internal Work RAM, tiene la misma velocidad que la CPU y un puerto de 32 bits. ¿El handicap? Dispone solo de 32KB de densidad pero es la memoria más rápida del sistema desde el momento en que no añade latencia de ningún tipo al acceso de la misma.

La segunda es la External Work RAM, su densidad es de 256KB y en modo ARM añade unos 6 ciclos de reloj para el acceso por el hecho de que tiene un puerto de 16 bits, en modo THUMB le permite realizar instrucciones que en la IWRAM se harían en un ciclo hacerlas en cuatro ciclos. ¿Entonces cual es la utilidad de dicha memoria? Pues para programas que superan el tamaño de 32KB de la IWRAM y por tanto no pueden ser contenidos dentro de esta.

Lo ideal obviamente en cuanto a rendimiento hubiese sido una GBA con una IWRAM que tuviese la densidad de la EWRAM p

CPU y el acceso a otras memorias.

GBA tiene una unidad DMA con cuatro canales, el de más privilegio es el DMA0 que es el canal que tiene preferencia de acceso por encima de los otros tres canales.

El DMA0 permite copiar datos entre la EWRAM a la IWRAM. Es utilizado además en modo lectura y junto al modo escritura del DMA3 para copiar los datos del cartucho a las memorias del sistema. Pero sobretodo es útil para darle acceso al ARM7 a la VRAM  y a la OAM durante el periodo HBlank cuando se renderiza en modo patrón, para enviar las Name Tables en modo patrón a la VRAM y para tener acceso completo a la VRAM durante el modo bitmap.

El DMA 1 y el DMA2 se utilizan para el sonido por lo que no los voy a tocar en esta entrada.

Cartuchos.

GBA utiliza cartuchos que pueden llegar a tener una densidad de hasta 32MB, aunque el ARM7 puede llegar a direccionar hasts 4GB por temas de costes de producción el tamaño máximo de los cartuchos que puede alcanzar GBA es de 32MB.

DSCN7707El puerto de cartuchos es de 16 bits y su velocidad de reloj es de 4.195 MHz, es decir tiene la misma velocidad de acceso que la RAM principal aunque solo se pueden leer datos y es necesario tener otra memoria en la que escribir. Curiosamente también se puede acceder en modo lectura+escritura pero en este caso el ancho de banda es de 8 bits por sentido y no es recomendable de cara al rendimiento por lo que este acceso al cartucho solo se utiliza para salvar partidas.

La pantalla de GBA y la PPU del sistema.

Antes de irnos directamente a los modos gráficos de GBA toca hablar de la pantalla del dispositivo, así como el procesador gráfico en su interior ya que ambos elementos están relacionados.

gba_drawGBA puede renderizar una escena de tres formas distintas:

  1. Modo Patrón Regular (heredado de SNES).
  2. Modo Patrón Afín (propio de GBA)
  3. Modo Bitmap (propio de GBA).

Los dos primeros modos son combinables entre si, la consola puede generar varios fondos distintos aparte de la capa principal de gráficos y dejar que la CPU los pueda manipular, tenemos unos tres tipos de planos distintos:

  • Texto: El cual no puede ser manipulado por la CPU, los patrones son sacados de una memoria interna de la consola que almacena los símbolo alfanuméricos.
  • Fondo Estático: No puede ser manipulado por la CPU tampoco.
  • Fondo Áfín: Se pueden realizar operaciones afines como rotación y desplazamiento por parte de la CPU.

GBA puede trabajar con un plano principal y 5 planos de fondo, el plano principal es por donde se mueve el personaje principal y los enemigos, es donde ocurre toda la acción en lo que a detección de colisiones de los diferentes elementos se refiere y es por tanto la Name Table que generará la CPU en modo patrón marcando los cambios en la escena siendo dicha Name Table de 32×20, dicha Name Table lo que hace es almacenar referencias a la OAM (Object Attribute Memory) que es otra memoria interna que contiene una serie de datos sobre los patrones/sprites a dibujar pero no los propios patrones/sprites.

Sobre la memoria OAM/SAT ya había hablado con anterioridad en el resto de consolas basadas en el modo patrón y durante la primera temporada de entradas. En el caso de GBA tiene un tamaño de 1KB y almacena datos de hasta 128 patrones/sprites en pantalla pero como he dicho antes no los patrones sino información de como tiene que dibujar la PPU la imagen, es decir… la Name Table en combinación con la OAM son la lista de pantalla.

Los patrones/sprites se encuentran almacenados en la VRAM de la consola que es 96KB y se encuentran en el mismo chip de la consola, la CPU puede acceder a la VRAM cuando quiera pero con un ciclo de latencia en dicha operación. La PPU no tiene acceso al cartucho ni a la Work RAM por lo que tienen que ser volcados en dicha memoria para el modo patrón/sprites.

Dibujado de la escena en modo patrón/sprites

En primer lugar GBA puede dibujar hasta cinco planos distintos.

Parallax-scroll-example-2En el primer plano es donde ocurre la acción del juego y siempre tendrá preferencia de dibujado sobre el resto, el de menos preferencia es el cuarto fondo que es el que se dibujará en el caso de que en ese espacio no se encuentren los otros planos compitiendo por ser dibujados por lo que en caso de conflicto la jerarquía de más a menos va desde el primer plano hasta el último. Todos los patrones/sprites como ocurre en sistemas similares tienen un color invisible que significaque tienen que dibujar el patrón/sprite que se encuentra en el fondo posterior.

Ahora bien, GBA dibuja la escena de forma distinta si se trata del fondo o se trata de la acción principal por el hecho que las Name Table del fondo ya se encuentran generadas en memoria. ¿El motivo? El hecho de poder generar el scroll de pantalla de forma más fácil, esto es algo que ya se encontraba en la NES peor no va mal recordarlo. Por ejemplo esto es la escena de un fondo:

brin3-full.png

Obviamente esto son varias pantallas distintas, pero el fondo se va desplazando a medida que nos movemos por el nivel utilizando un registro del procesador que marca el desplazamiento del mismo.

brin3-ofs-2x

La PPU dibuja la escena según le marca la Name Table, pero en el caso de que no haya un patrón/sprite en esa posición en el primer plano/plano de acción lo que hace es dibujar el correspondiente a esa parte del nivel. Los mapas del fondo pueden tener un tamaño desde 32×32 patrones hasta 64×64 patrones distintos en el caso de que los fondos sean regulares y por tanto estáticos. En el caso de que sean afines pueden ir de los 16×16 patrones hasta los 128×128 patrones.

En el modo patrón hay tres modos de funcionamiento gráfico de cara a los fondos:

  • Modo 0: Cuatro fondos regulares.
  • Modo 1: Dos fondos regulares y uno afín.
  • Modo 2: Dos fondos afínes.

En modo regular la PPU de GBA funciona de la misma manera que la de SNES realizando unas cuatro operaciones por pixel. Esto significa que contando los tiempos del HBlank y el VBlank también  la PPU de GBA funciona en dicho modo a 16.78 MHz por lo que es más lenta en modo patrón/sprite que la de SNES.

En modo afín lo que hace es reducir el número de patrones/sprites de 128 a unos 32 en total. El motivo de ello es que el modo patrón el tiempo es limitado ya que depende de la velocidad en la que se dibuja la escena en pantalla y el hecho de manipular los patrones/sprites son una serie de operaciones adicionales y de ahí la limitación en 32 patrones/sprites.

CPU y acceso a la VRAM y a la OAM

Debido a que la CPU puede acceder a la VRAM y a la OAM en cualquier momento se pueden realizar acciones de manipulación de escena al vuelo. No es algo que hagan muchos juego realmente y es difícil de realizar por lo que la mayoría de desarrolladores lo que hacen es utilizar el modo Bitmap para estas tareas.

El modo bitmap.

En modo bitmap la VRAM es utilizada como un búfer de imagen completo ya que:

240*160 pixeles*16 bits por pixel= 76.8 KB

El modo bitmap permite dos modos, uno con un solo búfer y 16 bits por pixel y otro con doblé búfer y 8 bits por pixel. En el modo bitmap el dibujado de la escena es independiente a la velocidad en la que se dibuja la pantalla y utiliza el mismo modo de dibujado que sistemas más avanzados que SNES/SFC y Genesis/Mega Drive. La mayoría de juegos que no son ports de SNES y son exclusivos de GBA utilizan este modo para realizar sus gráficos.

Creo que con esto queda perfectamente explicado como funciona GBA.

 

 

 

Anuncios