miércoles, 28 de septiembre de 2016

Games aside #0: Ensamblador en Game Boy, ¿es necesario?


Izquierda: prototipo presentado aquí; derecha: nuevo prototipo en ensamblador.

Recientemente he terminado de portar todo el código del prototipo de Last Crown Warriors mostrado en este blog a ensamblador. Sentía que el programa original, realizado con una combinación de C y ASM, no garantizaba un rendimiento óptimo, y que no sería la mejor base sobre la que fundamentar el resto del programa: tarde o temprano iba a terminar recurriendo a las virtudes de la programación de bajo nivel, y las herramientas que estaba usando, a pesar de ofrecer la posibilidad de añadir rutinas en ensamblador al programa, no presentaban las mismas ventajas que ofrece un programa realizado íntegramente en lenguaje ensamblador.

Por eso, aprovechando la ocasión de tener dos programas de resultado casi idéntico (uno en ASM, otro en C+ASM) para Game Boy, me he decidido a realizar una sencilla comparativa de rendimiento en ambos.

No es mi objetivo hacer un análisis en profundidad y concienzudo, ni mucho menos, pero sí sacar a la luz cuál es el resultado real que se obtiene cuando se desarrolla haciendo uso de las principales herramientas de las que la escena de Game Boy actualmente dispone.

C+ASM versus ASM

Antes de comenzar, creo conveniente aclarar por qué en este caso no se encuentra representada la opción de sólo C. Sencillamente, la desestimé. El deseo de tener un gran número de enemigos en pantalla con un rendimiento óptimo se contradecía con mi experiencia previa en desarrollos basados únicamente en C y orientados al sistema de marras.

Para empezar, toca concretar qué herramientas se han usado para la elaboración de la ROM en cada uno de los casos: Para el programa de C y ensamblador usé GBDK (Game Boy Development Kit), una versión modificada del SDCC (Small Device C Compiler) orientada a la Game Boy con librerías dedicadas y ejemplos. Decir que lleva sin actualizarse desde mediados de 2002.

En este programa el código en C, si bien no busca la optimización más absoluta, si se encuentra realizado siguiendo las directrices recomendadas por la herramienta. Se delegan además la operaciones matemáticas complejas y las funciones grandes recurrentes o relativamente simples a rutinas en ASM. Concretamente en este lenguaje de bajo nivel se cumplen los siguientes procesos:
  • actualización y posprocesado de sprites;
  • inteligencia artificial de los enemigos;
  • detección de entorno y procesado de hierba;
  • multiplicaciones y divisiones con resto;
  • generación de números aleatorios;
  • actualización gráfica durante el VBLANK.
Por lo tanto queda en manos de C el control del héroe, su sistema de colisión avanzada, la actualización de la interfaz de usuario, la animación del fondo, y el control general del programa.

Cabe destacar que el rendimiento de las rutinas mencionadas en el programa basado en C es menor que el de sus homónimas en el programa completamente en ensamblador. La razón es simple, en bajo nivel cuando queremos acceder a un dato lo hacemos directamente a través de su dirección, en C la memoria se maneja de manera dinámica y por lo tanto no es viable acceder a un dato de esta forma. A menos, claro está, que también decidamos controlar las direcciones de cada una de las variables, perdiendo así una de las ventajas que C nos ofrece. En el caso del prototipo se pasan todos los parámetros en forma de variables a través de una pila, apilando todos los datos de referencia que necesitamos primero para luego desapilarlos en la rutina de ASM antes de gestionarlos. Este proceso adicional perjudica ligeramente a la rapidez de dichas rutinas.

Resultado, hasta cinco enemigos moviéndose simultáneamente en pantalla sin ralentizaciones de ningún tipo. La barra verde a la derecha de la imágen indica la carga del procesador, si el verde claro sobrepasase el alto de la barra significaría que existe una carga de trabajo por frame mayor a la que el procesador puede hacer frente y surgirían ralentizaciones.


Programa en C+ASM.

Y aquí tenemos ese mismo resultado con el programa elaborado enteramente en ASM con RGBDS (Rednex Game Boy Development System), un ensamblador que hoy día sigue recibiendo actualizaciones. En este programa se ha realizado una transición de la lógica original a este lenguaje, priorizando en todo momento la optimización de recursos y procesamiento.

 Programa en ASM puro.

Como se puede observar la carga del procesador es notablemente menor. Y aquí tenemos el programa de nuevo esta vez con nueve enemigos en movimiento, algo inviable en el prototipo anterior, llegando así a cubrir el número máximo de sprites en pantalla a nivel de hardware (si contamos los sprites de hierba asociados a cada personaje).

 Programa en ASM puro, con número de enemigos máximizado.

Así que, ensamblador en Game Boy, ¿es necesario? Creo que depende del proyecto que se quiera desarrollar. Para Last Crown Warriors, un juego que pretende mostrar de manera simultánea el mayor número posible de personajes distintos en movimiento, definitivamente sí.

lunes, 5 de septiembre de 2016

Last Crown Warriors #0: Acción táctica en Game Boy

Last Crown Warriors en un nuevo proyecto paralelo para Game Boy. Su nombre proviene del juego que presenté en la BitBit Jam 2015.

Izquierda: Last Crown (BitBit Jam 2015); Derecha: Last Crown Warriors (en desarrollo)

El juego en cuestión ha sido replanteado y reprogramado con una mezcla de C y ensamblador, dando prioridad a conseguir procesar un gran número de enemigos.

La idea inicial de este nuevo proyecto se resume en conseguir aunar las mecánicas de control de los Zelda de Game Boy con la acción táctica característica de la serie de videojuegos Warriors (o Musou).

Dynasty Warriors 2 (2000), PS2
The Legend of Zelda Link's Awakening (1993), Game Boy
 
Existen algunos títulos que también han intentado juntar acción clásica con estrategia, como el reciente Gotta Protectors de la saga Protect Me Knight.

Gotta Protectors (2016), 3DS
El equipo del proyecto será el mismo que el de Rocket Man, con Seiyouh a cargo de la elaboración de gráficos, NAP.VGM haciendo músicas y efectos de sonido y yo (Imanolea) como responsable del diseño y la programación.

En este vídeo puede verse una primera demostración técnica del programa, con cinco enemigos simultáneos en pantalla.