Game Boy Advance es una consola portátil de juegos creada por Nintendo. Fue lanzada en Japón en 2001 y fue la sucesora de Game Boy Color. Tenía un procesador ARM7TDMI con una velocidad de reloj de 16,78 MHz, 32 kb de RAM interna, 256 kb de RAM externa y 96 kb de VRAM. No es la máquina más potente, pero hay muchos juegos para la consola portátil que muchos guardan en su memoria. Sin embargo, un juego que nunca vio la luz para el dispositivo fue un prototipo de Quake, un juego desarrollado por id Software que ayudó a definir el género de disparos en primera persona que conocemos hoy.

Quake es un juego increíblemente detallado con una banda sonora fantástica y una jugabilidad adictiva, y al igual que DOOM, ha sido adaptado a prácticamente todos los dispositivos que puedas imaginar. Su adaptación a Game Boy Advance es particularmente increíble, ya que no es compatible de forma nativa con gráficos 3D, y Nintendo comercializó específicamente la consola portátil como una experiencia de juego bidimensional. Sin embargo, eso no impidió que Randy Linden desarrollara su propia adaptación.

Consola de bolsillo analógica Quake Game Boy Advance

Si no conoces a Linden, es más conocido por ser el desarrollador de bleem! (un emulador de PlayStation) y del port de DOOM para SNES, un logro que John Romero, cofundador de id Software, dijo una vez en una entrevista conShacknewsque no creía que fuera posible. La habilidad de Linden para el desarrollo demostró que si alguien iba a ser capaz de hacer realidad Quake para Game Boy Advance, probablemente ese era él.

Este port ha salido a la luz gracias al lanzamiento del propio Linden a través del proyecto Forest of Illusion. Forest of Illusion es un proyecto cuyo objetivo es preservar la historia de los juegos de Nintendo, y Linden se puso en contacto para distribuir la copia del port de Quake que encontró en una tarjeta flash de 256 MB que tenía en su poder.

Nos gustaría agradecer a Randy Linden por dedicar tiempo a responder nuestras preguntas y garantizar la precisión técnica de este artículo. También nos gustaría agradecer aModern Vintage Gamerpor permitirnos usar las imágenes fijas de su video que necesitábamos. Este port no tiene relación oficial con id Software o ZeniMax y fue desarrollado como un proyecto individual por Linden.

El puerto de Quake para Game Boy Advance

Técnicamente hablando, es una maravilla que Quake pueda funcionar al nivel que lo hace en Game Boy Advance. Funciona a una buena velocidad de cuadros y mantiene la iluminación y la paleta de colores correctas del juego Quake original. Todo es 3D, incluidas las armas y los monstruos. Los juegos de Game Boy Advance conseguían gráficos 3D normalmente a través de sprites, pero este era el verdadero. No hace uso de la proyección de rayos de la forma en que lo hacían otros juegos 3D en la consola portátil, e incluso consigue efectos de iluminación puntual en objetos pre-renderizados a través de un truco de cambio de paleta para lograr una ilusión de iluminación dinámica.

Para ser claros, este port no es el juego completo, y es un prototipo que Linden tenía la intención de llevar a id Software una vez que estuviera terminado para que lo hicieran para su lanzamiento. Sin embargo, la popularidad de Game Boy Advance comenzó a decaer y, en su lugar, el motor personalizado escrito por Linden se convirtió más tarde en el motor de otro juego desarrollado completamente por Linden: Cyboid. Linden nos dice que una "gran parte del código" sigue siendo el código ARM original de la versión de Game Boy Advance. Si quieres probar Cyboid, hay una versión anterior disponible en Google Play Store, pero el APK oficial ahora se distribuye enAmazon App Store,ya que el juego tiene mucho código de 32 bits de bajo nivel.

CiboideDesarrollador:R and R Digital, LLC.
Precio: Gratis
3.3
Descargar

Linden también compartió con nosotros un vídeo de su código ejecutándose en el iPod Video, que sirvió como una de las primeras versiones de Cyboid. Se creó con el mismo código de motor que se utilizó para su adaptación de Quake a Game Boy Advance.

El puerto de Quake para Game Boy Advance no contiene ninguno de los recursos oficiales del juego, ya que Linden no se ha comunicado con id Software ni con ZeniMax para distribuir la versión E1M1 que contiene los recursos oficiales de Quake.

El juego que se distribuye actualmente también es una versión de depuración. Si se mantiene presionada la tecla R al iniciar el juego, el jugador accederá directamente al segundo mapa del juego, y si se mantiene presionada la tecla izquierda del pad direccional, accederá al tercero. También se puede acceder al cambio de mapa cuando el jugador muere, y los monstruos no atacarán al jugador hasta que este les dispare primero.

En cuanto a la música, la demostración utiliza archivos públicos .S3M y el mezclador de sonido maneja tanto música estéreo como efectos de sonido.

Límites técnicos

Hubo una serie de limitaciones en lo que respecta a Game Boy Advance que hicieron que esta adaptación fuera difícil. Algunos de los mayores obstáculos fueron la baja velocidad de reloj, la falta de capacidades gráficas 3D de la consola portátil y la falta de una unidad de punto flotante (FPU). Hubo muchos otros a lo largo del camino, pero estos fueron puntos problemáticos que Linden me describió como problemáticos. Antes de profundizar en el tema, es importante comprender el diseño de Game Boy Advance.

Disposición de Game Boy Advance

El Game Boy Advance tiene tres conjuntos de RAM: uno es la RAM de trabajo interna (IWRAM), otro es la RAM de trabajo externa (EWRAM) y el tercero es la RAM de video (VRAM). Los 32 kb de IWRAM se utilizan para almacenar instrucciones ARM para una ejecución rápida, mientras que los 256 kb de EWRAM son óptimos para almacenar instrucciones de solo Thumb y fragmentos de datos más pequeños. Comoseñala Rodrigo Copetti, el acceso a la EWRAM puede ser hasta seis veces más lento que el de la IWRAM. La mayoría de la memoria en forma de EWRAM solo es accesible a través de un bus de 16 bits, a pesar de que el Game Boy Advance se comercializa como una consola portátil de 32 bits. Se podía acceder a la IWRAM a través de un bus de 32 bits. La VRAM en el Game Boy Advance tiene 96 kb y, si bien es principalmente para almacenar datos gráficos, se encuentra en el mapa de memoria de la CPU y también se puede usar como almacenamiento de memoria normal.

Las instrucciones Thumb son un subconjunto de las instrucciones ARM de 32 bits y son un conjunto de instrucciones codificadas en palabras de 16 bits. Tienen todos los beneficios de las instrucciones de 32 bits sin ocupar tanto espacio, lo que las hace eficientes para un desarrollo optimizado. Esto significa que, si bien el acceso a la EWRAM es más lento, las instrucciones Thumb, al ser eficientes, a menudo pueden terminar siendo tan rápidas como las instrucciones ARM almacenadas en IWRAM, aunque la desventaja de las instrucciones Thumb es que, a veces, no existe un equivalente Thumb de una instrucción ARM que desee ejecutar. La EWRAM se utilizó para almacenar la salida de la lógica de transformación matemática 3D, que era básicamente la lista de bordes de polígonos que luego se trazaban línea por línea de escaneo mediante el código de rasterización.

Como me cuenta Linden, la parte más compleja y difícil de todo el port fue el renderizador de líneas de escaneo. Consiste en más de 10.000 líneas de código ensamblador ARM altamente optimizado que está diseñado para dibujar un conjunto de píxeles en la VRAM. El renderizador de líneas de escaneo utilizó la mayor parte de la IWRAM de 32 kb. Los bordes más cercanos a la cámara están activos y renderizados, y es esencialmente un gran árbol de Partición de Espacio Binario (BSP). La VRAM se utilizó para almacenar los resultados de la salida de la transformación poligonal en tablas de bordes porque no había suficiente IWRAM, pero la VRAM en Game Boy Advance sigue siendo más rápida que la EWRAM. Los gráficos también se almacenaron y mostraron aquí.

Pasó mucho tiempo centrándose en las optimizaciones para garantizar que pudiera obtener el tiempo de ejecución más rápido posible. Tres cosas que hizo para acelerar ese tiempo de ejecución incluyeron lo siguiente:

  • Automodifiqué el código antes de ejecutarlo, por lo que se necesitaron menos instrucciones
  • Se utilizó una serie de tablas de búsqueda para cosas como recíproco, seno, coseno, tangente, etc.
  • Cambió el "modo" de la CPU para obtener acceso a registros adicionales (que son como "variables") sin tener que guardar y restaurar los valores de los registros.

Cambiar los modos de la CPU para obtener registros adicionales es una maniobra increíblemente inteligente que permite un acceso rápido a valores cercanos a la CPU para que puedan recuperarse en un solo ciclo de reloj. Como me cuenta Linden, era posible cambiar de registro y recuperar un valor en un solo ciclo de reloj, en lugar de almacenar un valor en la RAM de Game Boy Advance, que lleva más tiempo. La CPU en sí es un procesador de 16,78 MHz, lo que significa que puede completar 16780000 ciclos por segundo. Eso parece mucho, pero cuando necesitas calcular y dibujar cada píxel en la pantalla, eso se suma rápidamente y se vuelve importante eliminar tantas operaciones como sea posible.

Registros del ARM7TDMI

La lista anterior es la de los registros generales del chipset ARM7TDMI que se encuentra dentro de Game Boy Advance. Normalmente, los desarrolladores solo acceden a los registros dentro del modo "Sistema y Usuario" y recurren al uso de variables normales fuera de este. Sin embargo, él hizo uso de registros en los siete modos del chipset, y lo mejor de todo es que al cambiar de modo se conservan los valores en los registros de los otros modos, por lo que puede cambiar entre ellos.

Curiosamente, Linden también mencionó cómo su método de cambio de banco desenterró un error en el emulador Nanoboy Advance. Resultó que ese emulador no admitía el uso de otros modos de la CPU para guardar en registros y cambiar, y su demo de Quake fue el primer juego conocido que lo hizo.

Linden compartió con nosotros una foto de algunas de las notas que creó y explicó cómo optimizó sus cálculos de punto flotante en ausencia de una FPU adecuada.

Notas del puerto de terremotos de Randy Linden

La imagen de arriba es una que Linden compartió con nosotros a partir de sus notas, y lo que es particularmente interesante es el "recuento de instrucciones de ciclo ARM misceláneo". Ideó una forma de optimizar los ciclos para los cálculos de modo que pudiera reducir la cantidad de ciclos de reloj para un cálculo. Como me lo describió, un número de 8 bits se podía multiplicar en un ciclo de reloj, un número de 16 bits en dos ciclos de reloj, un número de 32 bits en tres ciclos de reloj y un número de 64 bits en cuatro ciclos de reloj.

"Había dos o tres etapas de ejecución [en el procesador ARM]. Digamos, por ejemplo, que multiplico el registro uno por el registro dos y pongo el resultado en el registro tres. Si supiera que el registro dos es un número de 16 bits, en lugar de decir multiplicar el registro uno por el registro dos, lo invertiría y diría multiplicar el registro dos por el registro uno porque eso me ahorraría un ciclo de reloj".

Me dijo que el motivo de su decisión era exprimir al máximo el rendimiento de la Game Boy Advance, ya que un ciclo de reloj ahorrado aquí y allá realmente suma cuando se realizan muchos cálculos. En cuanto al código automodificable, le pedí a Linden que me lo explicara.

"El programa viene de [la memoria], transfiere un gran bloque del programa a la RAM interna para su ejecución porque es más rápido. Cada acceso a la RAM es mucho, mucho más lento, así que hago un DMA [Acceso directo a memoria] de un gran bloque de la ROM a la RAM, y luego cambio el código real del programa. Por ejemplo, ARM tiene la capacidad de desplazar operandos a la izquierda o a la derecha o puede enmascarar ciertos bits como parte del conjunto de instrucciones. La instrucción especifica qué bits vas a enmascarar o cuántos bits vas a desplazar. Entonces, generaría código que modificaría lo que estaba a punto de ejecutarse en función de cuántos bits necesitaba desplazar. Otro ejemplo es con respecto a la multiplicación de matrices 3D. Hay un montón de multiplicaciones involucradas allí. Generaría las instrucciones reales que realizan las multiplicaciones en la RAM interna y luego las ejecutaría de modo que el código, de alguna manera, crearía partes de sí mismo mientras se ejecutaba".

El código automodificable tiene sus desventajas, en particular cuando se trata de depuración. También elimina la necesidad de instrucciones de bifurcación, donde el código saltaría a otra secuencia de ejecución y puede privar al hilo principal de un valioso tiempo de cálculo. Linden también nos dijo que las tablas de búsqueda están perfectamente alineadas en la ROM, de modo que son un múltiplo perfecto de un valor de ocho bits desplazado a la izquierda. El tamaño de la tabla de búsqueda es inmenso y no cabe en la RAM, y la alineación también evita la necesidad de una instrucción de carga adicional para obtener la dirección base de la tabla.

En total, el prototipo final se desarrolló durante casi dos años.

El futuro del puerto de Quake de Randy Linden

Le pregunté a Linden qué pasaría con el futuro del port de Quake y me dijo que estaba considerando pedirle a ZeniMax e id Software que lanzaran la versión con los recursos oficiales de Quake. También me dijo que en algún momento lanzaría el código fuente, pero que actualmente no se puede compilar porque requiere una computadora más vieja.

Configuración de Game Boy Advance de Randy Linden que Randy Linden utilizó para conectarlo

Le pregunté a Linden por qué había elegido Quake y me dijo que le encantaba el juego y que le encantaba el desafío de que fuera un "proyecto imposible", ya que era el resultado de su port de DOOM para SNES. También mencionó que, si bien no cree que se hubiera podido portar todo el juego debido a las limitaciones de espacio, la gran mayoría del juego podría haber estado en el mismo motor.

Si estás interesado en probar Quake para Game Boy Advance, asegúrate de ver su lanzamiento en Forest of Illusion, que puedes ver a continuación.


Descargar desde Bosque de Ilusión