L'histoire du portage impossible: comment Quake a été porté sur Game Boy Advance

Porter Quake sur Game Boy Advance aurait semblé impossible, mais Randy Linden a réussi à y parvenir. Voici comment.

La Game Boy Advance est une console de jeux portable créée par Nintendo. Il est sorti au Japon en 2001 et a succédé à la Game Boy Color. Il avait un ARM7TDMI cadencé à 16,78 MHz, 32 Ko de RAM de travail interne, 256 Ko de RAM externe et 96 Ko de VRAM. Ce n’est pas la machine la plus puissante, mais il existe de nombreux jeux pour ordinateur de poche que beaucoup gardent en mémoire. Un jeu qui n'a jamais vu le jour pour l'appareil était un prototype de portage de Quake, un jeu développé par id Software qui a contribué à définir le genre de jeu de tir à la première personne que nous connaissons aujourd'hui.

Quake est un jeu incroyablement détaillé avec une bande-son fantastique et un gameplay addictif, et tout comme DOOM, il a été porté sur pratiquement tous les appareils auxquels vous pouvez penser. Son portage sur Game Boy Advance est particulièrement incroyable car il ne prend pas en charge nativement les graphiques 3D, et Nintendo a spécifiquement commercialisé l'ordinateur de poche comme étant une expérience de jeu en deux dimensions. Cela n'a pas empêché Randy Linden de développer son propre port.

Photo du port Quake joué sur un Analog Pocket utilisé avec la permission de Modern Vintage Gamer

Si vous n'êtes pas familier avec Linden, il est surtout connu pour être le développeur des deux bleem! (un émulateur PlayStation) et le portage SNES de DOOM, un accomplissement que John Romero, co-fondateur d'id Software, a déclaré un jour dans une interview avec Shacknouvelles il ne pensait pas que c'était possible. Les compétences de développement de Linden ont prouvé que si quelqu'un pouvait faire de Quake sur Game Boy Advance une réalité, c'était probablement lui.

Ce port a été révélé grâce à la propre sortie de Linden à travers le projet Forest of Illusion. Forest of Illusion est un projet visant à préserver l'histoire des jeux Nintendo, et Linden a tendu la main afin de distribuer la copie du port Quake qu'il a trouvé sur une carte flash de 256 Mo dans son possession.

Nous tenons à remercier Randy Linden d'avoir consacré du temps à répondre à nos questions et à garantir l'exactitude technique de cet article. Nous tenons également à remercier Joueur vintage moderne pour nous avoir permis d'utiliser toutes les images fixes de sa vidéo dont nous avions besoin. Ce port n'a aucun rapport officiel avec id Software ou ZeniMax et a été développé en tant que projet solo par Linden.

Portage Game Boy Advance de Quake

Techniquement parlant, c'est une merveille que Quake puisse même atteindre le niveau qu'il atteint sur Game Boy Advance. Il fonctionne à une bonne fréquence d'images et conserve l'éclairage et la palette de couleurs corrects du jeu Quake original. Tout est en 3D, y compris les armes et les monstres. Les jeux sur Game Boy Advance obtenaient des graphismes 3D généralement via des sprites, mais c'était la vraie affaire. Il n'utilise pas le lancer de rayons comme le faisaient d'autres jeux 3D sur ordinateur de poche, et il atteint même son objectif. effets de lumière sur des objets pré-rendus via une astuce de changement de palette pour obtenir une illusion de dynamique éclairage.

Pour être clair, ce portage n'est pas le jeu complet, et c'est un prototype que Linden avait l'intention de confier à id Software une fois qu'il serait terminé pour être publié. Cependant, la popularité de la Game Boy Advance a commencé à décliner et, à la place, le moteur personnalisé écrit par Linden est devenu plus tard le moteur d'un autre jeu entièrement développé par Linden: Cyboid. Linden nous dit qu'une "grande partie du code" est toujours le code ARM original de la version Game Boy Advance. Si vous souhaitez essayer Cyboid, une ancienne version est disponible sur le Google Play Store, mais l'APK officiel est désormais distribué sur le Amazon App Store car le jeu contient beaucoup de code 32 bits de bas niveau.

CyboïdeDéveloppeur: R et R Digital, LLC.

Prix ​​: Gratuit.

3.3.

Télécharger

Linden a également partagé avec nous une vidéo de son code exécuté sur l'iPod Video, qui a été l'une des premières versions de Cyboid. Il a été construit sur le même code moteur que celui utilisé pour son portage Quake sur Game Boy Advance.

Le portage Game Boy Advance de Quake ne contient aucun des éléments officiels du jeu, contrairement à Linden. a contacté id Software ou ZeniMax pour distribuer la version E1M1 qui contient Quake officiel actifs.

Le jeu actuellement distribué est également une version de débogage. Maintenir la touche R au démarrage amènera le joueur directement à la deuxième carte du jeu, et maintenir la touche gauche sur le D-pad l'amènera à la troisième. L'échange de carte est également accessible lorsque le joueur meurt, et les monstres n'attaqueront pas le joueur tant que le joueur ne leur tirera pas dessus en premier.

En ce qui concerne la musique, la démo utilise des fichiers publics .S3M et le mixeur sonore gère à la fois la musique stéréo et les effets sonores.

Limites techniques

Il y avait un certain nombre de limites en ce qui concerne la Game Boy Advance qui en faisaient un portage difficile. Certains des plus gros obstacles étaient la faible vitesse d'horloge, le manque de capacités graphiques 3D de l'ordinateur de poche et l'absence d'unité à virgule flottante (FPU). Il y en avait beaucoup d'autres en cours de route, mais il s'agissait de points douloureux particuliers que Linden m'a décrit comme étant problématiques. Avant d'entrer dans le vif du sujet, il est important de comprendre la présentation de la Game Boy Advance.

Capture d'écran utilisée avec la permission de Modern Vintage Gamer

La Game Boy Advance dispose de trois ensembles de RAM: l'un est la RAM de travail interne (IWRAM), un autre est la RAM de travail externe (EWRAM) et le troisième est la RAM vidéo (VRAM). Les 32 Ko d'IWRAM sont utilisés pour stocker les instructions ARM pour une exécution rapide, tandis que les 256 Ko d'EWRAM sont optimaux pour stocker des instructions Thumb uniquement et des morceaux de données plus petits. Comme Notes de Rodrigo Copetti, l'accès à l'EWRAM peut être jusqu'à six fois plus lent qu'à l'IWRAM. La majorité de la mémoire sous forme d'EWRAM n'est accessible que via un bus 16 bits, bien que la Game Boy Advance soit commercialisée comme un ordinateur de poche 32 bits. L'IWRAM était accessible via un bus 32 bits. La VRAM sur Game Boy Advance est de 96 Ko, et bien qu'elle soit principalement destinée au stockage de données graphiques, elle se trouve dans la carte mémoire du processeur et peut également être utilisée comme stockage de mémoire normal.

Les instructions Thumb sont un sous-ensemble d'instructions ARM de 32 bits et sont un ensemble d'instructions codées en mots de 16 bits. Elles présentent tous les avantages des instructions 32 bits sans prendre autant de place, ce qui les rend efficaces pour un développement optimisé. Cela signifie que même si l'accès à l'EWRAM est plus lent, les instructions Thumb, qui sont efficaces, peuvent souvent finir aussi rapidement que les instructions ARM stockées. dans IWRAM, bien que l'inconvénient des instructions Thumb soit que parfois il n'y a pas tout à fait l'équivalent Thumb d'une instruction ARM que vous souhaitez exécuter. L'EWRAM a été utilisée pour stocker la sortie de la logique de transformation mathématique 3D, qui était essentiellement la liste des bords de polygones qui étaient ensuite tracés ligne de balayage par ligne de balayage par le code de rastérisation.

Comme Linden me le dit, la partie la plus complexe et la plus difficile de tout le portage était le moteur de rendu de lignes de balayage. Il se compose de plus de 10 000 lignes de code assembleur ARM hautement optimisé, conçu pour dessiner un ensemble de pixels dans la VRAM. Le moteur de rendu scanline a utilisé la majeure partie de l'IWRAM de 32 Ko. Les bords les plus proches de la caméra sont actifs et rendus, et il s'agit essentiellement d'une grande arborescence de partitionnement d'espace binaire (BSP). La VRAM a été utilisée pour stocker les résultats de la transformation polygonale dans des tables de bord car il n'y avait pas assez d'IWRAM, mais la VRAM sur Game Boy Advance est toujours plus rapide que l'EWRAM. Les graphiques ont également été stockés et affichés ici.

Il a passé beaucoup de temps à se concentrer sur les optimisations pour s'assurer d'obtenir le temps d'exécution le plus rapide possible. Trois choses qu'il a faites pour accélérer ce temps d'exécution sont les suivantes :

  • Auto-modification du code avant son exécution, donc moins d'instructions étaient nécessaires
  • Utilisé une série de tables de recherche pour des choses comme l'inverse, le sinus, le cosinus, la tangente, etc.
  • Changement du "mode" du CPU pour accéder à des registres supplémentaires (qui sont comme des "variables") sans avoir à sauvegarder et restaurer les valeurs des registres.

Changer les modes du CPU pour obtenir des registres supplémentaires est une manœuvre incroyablement intelligente qui permet un accès rapide aux valeurs proches du CPU afin qu'elles puissent être récupérées en un seul cycle d'horloge. Comme Linden me le dit, il était possible de changer de registre et de récupérer une valeur en un seul cycle d'horloge, au lieu de stocker une valeur dans la RAM de la Game Boy Advance, ce qui prend plus de temps. Le processeur lui-même est un processeur cadencé à 16,78 MHz, ce qui signifie qu'il peut effectuer 1 678 000 cycles par seconde. Cela semble beaucoup, mais lorsque vous devez calculer et dessiner chaque pixel de l'écran, ceux-ci s'additionnent rapidement et il devient important de réduire autant d'opérations que possible.

Ce qui précède est la liste des registres généraux du chipset ARM7TDMI présent dans la Game Boy Advance. En règle générale, les développeurs n'accèdent aux registres qu'en mode "Système et utilisateur" et recourent à l'utilisation de variables normales en dehors de cela. Cependant, il a utilisé des registres dans les sept modes du chipset, et le meilleur dans tout cela est que Les modes de commutation conservent toujours les valeurs dans les registres des autres modes, afin qu'il puisse basculer entre eux.

Curieusement, Linden a également mentionné comment sa méthode de changement de banque a mis au jour un bug dans l'émulateur Nanoboy Advance. Il s'est avéré que cet émulateur ne prenait pas en charge l'utilisation des autres modes du processeur pour la sauvegarde dans les registres et la commutation, et sa démo Quake était le premier jeu connu à le faire réellement.

Linden a partagé avec nous une photo de certaines des notes qu'il a créées et a expliqué comment il a optimisé ses calculs en virgule flottante en l'absence d'un FPU approprié.

L'image ci-dessus est celle que Linden a partagée avec nous à partir de ses notes, et ce qui est particulièrement intéressant, ce sont les « comptes d'instructions diverses du cycle ARM ». Il a conçu un moyen d'optimiser les cycles de calcul afin de pouvoir réduire le nombre de cycles d'horloge pour un calcul. Comme il me l'a décrit, un nombre de 8 bits pouvait être multiplié en un cycle d'horloge, un nombre de 16 bits en deux cycles d'horloge, un nombre de 32 bits en trois cycles d'horloge et un nombre de 64 bits en quatre cycles d'horloge. .

"Il y avait deux ou trois étapes d'exécution [dans le processeur ARM]. Disons par exemple que je multiplie le registre un par le registre deux et que je mets le résultat dans le registre trois. Si je savais que le registre deux était un nombre de 16 bits au lieu de dire multiplier le registre un par le registre deux, je je le retournerais et je dirais de multiplier le registre deux par le registre un parce que cela me ferait gagner une horloge faire du vélo."

Il m'a dit que la raison pour laquelle il avait fait cela était de tirer le meilleur parti des performances de la Game Boy. Advance, car un cycle d'horloge enregistré ici et là s'additionne vraiment lorsque de nombreux calculs sont en cours. effectué. Quant au code auto-modifiable, j'ai demandé à Linden de l'expliquer.

"Le programme vient du [stockage], il transfère un gros bloc du programme dans la RAM interne pour exécution car c'est plus rapide. Chaque accès à la RAM est beaucoup, beaucoup plus lent, donc je fais un DMA [Direct Memory Access] d'un gros bloc de la ROM vers la RAM, puis je change le code du programme réel. Par exemple, ARM a la capacité de décaler les opérandes vers la gauche ou la droite ou de masquer certains bits dans le cadre du jeu d'instructions. L'instruction spécifie les bits que vous allez masquer ou le nombre de bits que vous allez décaler. Ainsi, je générerais du code qui modifierait ce qui était sur le point d'être exécuté en fonction du nombre de bits que je devais décaler. Un autre exemple concerne la multiplication matricielle 3D. Il y a tout un tas de multiplications impliquées ici. Je générerais les instructions réelles qui effectuent les multiplications dans la RAM interne, puis je les exécuterais afin que le code construise des parties de lui-même pendant son exécution.

Le code auto-modifiable a ses propres inconvénients, notamment en matière de débogage. Cela supprime également le besoin d'instructions de branchement, où le code passerait à une autre séquence d'exécution et pourrait priver le thread principal d'un temps de calcul précieux. Linden nous a également dit que les tables de recherche sont parfaitement alignées dans la ROM, de sorte qu'elles constituent un multiple parfait d'une valeur de huit bits décalée vers la gauche. La taille de la table de recherche est immense et ne rentre pas dans la RAM, et l'alignement évite également le besoin d'une instruction de chargement supplémentaire pour obtenir l'adresse de base de la table.

Au total, le prototype final a été développé sur près de deux ans.

L'avenir du port Quake de Randy Linden

J'ai demandé à Linden ce qui arriverait à l'avenir du port Quake, et il m'a dit qu'il mettait envisager de demander à ZeniMax et id Software de publier la version avec Quake officiel actifs. Il m'a également dit qu'à un moment donné, il publierait le code source, mais pour le moment, il ne se construit pas car il nécessite un ordinateur plus ancien.

Configuration de Randy Linden pour connecter une Game Boy Advance à un ordinateur à des fins de développement.

J'ai demandé à Linden pourquoi il avait choisi Quake, et il m'a dit qu'il adorait le jeu et qu'il adorait le défi de ce "projet impossible", car il était sorti de son portage DOOM pour SNES. Il a également mentionné que même s'il ne pensait pas que l'intégralité du jeu aurait pu être portée en raison de contraintes d'espace, la grande majorité du jeu aurait pu être dans le même moteur.

Si vous souhaitez découvrir Quake pour Game Boy Advance, assurez-vous de consulter sa sortie sur Forest of Illusion, que vous pouvez consulter ci-dessous.


Télécharger depuis Forêt de l'Illusion