La storia del porting impossibile: come Quake è stato portato su Game Boy Advance

Portare Quake su Game Boy Advance sarebbe sembrato impossibile, ma Randy Linden è riuscito a farcela. Ecco come.

Il Game Boy Advance è una console di gioco portatile creata da Nintendo. È stato rilasciato in Giappone nel 2001 ed è stato il successore del Game Boy Color. Aveva un ARM7TDMI con clock a 16,78 MHz, 32kb di RAM di lavoro interna, 256kb di RAM esterna e 96kb di VRAM. Non è la macchina più potente, ma ci sono molti giochi per il palmare che molti conservano nella memoria. Un gioco che però non ha mai visto la luce per il dispositivo è stato un prototipo di porting di Quake, un gioco sviluppato da id Software che ha contribuito a definire il genere degli sparatutto in prima persona che conosciamo oggi.

Quake è un gioco incredibilmente dettagliato con una colonna sonora fantastica e un gameplay avvincente e, proprio come DOOM, è stato portato praticamente su ogni singolo dispositivo immaginabile. Il suo porting su Game Boy Advance è particolarmente incredibile in quanto non supporta nativamente la grafica 3D e Nintendo ha commercializzato specificamente il palmare come un'esperienza di gioco bidimensionale. Ciò però non ha impedito a Randy Linden di sviluppare il proprio porting.

Foto del porting di Quake riprodotto su un Analogue Pocket utilizzato con il permesso di Modern Vintage Gamer

Se non hai familiarità con Linden, è meglio conosciuto per essere lo sviluppatore di entrambi i bleem! (un emulatore di PlayStation) e il porting di DOOM per SNES, un risultato che John Romero, co-fondatore di id Software, disse una volta in un'intervista a Shacknews non pensava fosse possibile. L'abilità nello sviluppo di Linden dimostrò che se c'era qualcuno in grado di realizzare Quake per Game Boy Advance, probabilmente era lui.

Questo port è venuto alla luce grazie al rilascio da parte di Linden attraverso il progetto Forest of Illusion. Forest of Illusion è un progetto volto a preservare la storia dei giochi Nintendo e di Linden ha contattato per distribuire la copia del port di Quake che ha trovato su una flash card da 256 MB nella sua possesso.

Vorremmo ringraziare Randy Linden per aver dedicato del tempo a rispondere alle nostre domande e ad assicurare l'accuratezza tecnica di questo articolo. Vorremmo anche ringraziare Giocatore vintage moderno per averci permesso di utilizzare tutte le immagini fisse del suo video che fossero necessarie. Questo port non ha alcuna relazione ufficiale con id Software o ZeniMax ed è stato sviluppato come progetto solista da Linden.

Il porting per Game Boy Advance di Quake

Tecnicamente parlando, è una meraviglia che Quake riesca a raggiungere il livello del Game Boy Advance. Funziona con un buon frame rate e mantiene l'illuminazione e la tavolozza dei colori corrette del gioco Quake originale. Tutto è in 3D, comprese armi e mostri. I giochi per Game Boy Advance ottenevano la grafica 3D tipicamente tramite gli sprite, ma questo era il vero affare. Non fa uso del ray casting come facevano altri giochi 3D sul palmare, e raggiunge addirittura punti effetti di luce su oggetti pre-renderizzati tramite un trucco che cambia tavolozza per ottenere un'illusione di dinamica illuminazione.

Per essere chiari, questo port non è il gioco completo, ma è un prototipo che Linden intendeva portare a id Software una volta completato per essere rilasciato. Tuttavia, la popolarità del Game Boy Advance iniziò a scemare e, invece, il motore personalizzato scritto da Linden divenne in seguito il motore di un altro gioco interamente sviluppato da Linden: Cyboid. Linden ci dice che "una grossa parte del codice" è ancora il codice ARM originale della versione per Game Boy Advance. Se vuoi provare Cyboid, sul Google Play Store è disponibile una versione precedente, ma l'APK ufficiale è ora distribuito su App Store di Amazon poiché il gioco ha molto codice a 32 bit di basso livello.

CyboideSviluppatore: R e R digitale, LLC.

Prezzo: gratuito.

3.3.

Scaricamento

Linden ha anche condiviso con noi un video del suo codice in esecuzione sull'iPod Video, che è servito per essere una delle prime versioni di Cyboid. È stato costruito sullo stesso codice motore utilizzato per il porting di Quake su Game Boy Advance.

Il port di Quake per Game Boy Advance non contiene nessuna delle risorse ufficiali del gioco, poiché Linden non l'ha fatto ha contattato id Software o ZeniMax per distribuire la versione E1M1 che contiene Quake ufficiale risorse.

Anche il gioco attualmente in distribuzione è una build di debug. Tenendo premuto il tasto R all'avvio, il giocatore verrà portato direttamente alla seconda mappa del gioco, mentre tenendo premuto il tasto direzionale sinistro lo porterà alla terza. È possibile accedere allo scambio di mappe anche quando il giocatore muore e i mostri non attaccheranno il giocatore finché il giocatore non gli sparerà per primo.

Per quanto riguarda la musica, la demo utilizza file .S3M pubblici e il mixer audio gestisce sia la musica stereo che gli effetti sonori.

Confini tecnici

C'erano una serie di limiti quando si trattava del Game Boy Advance che rendevano questo porting difficile. Alcuni dei maggiori ostacoli erano la bassa velocità di clock, la mancanza di capacità grafiche 3D del palmare e la mancanza di un'unità a virgola mobile (FPU). Ce ne sono stati molti altri lungo il percorso, ma questi erano particolari punti dolenti che Linden mi ha descritto come problematici. Prima di addentrarci nel dettaglio, è importante comprendere il layout del Game Boy Advance.

Screenshot utilizzato con il permesso di Modern Vintage Gamer

Il Game Boy Advance ha tre set di RAM: uno è la RAM di lavoro interna (IWRAM), un altro è la RAM di lavoro esterna (EWRAM) e il terzo è la RAM video (VRAM). I 32kb di IWRAM vengono utilizzati per memorizzare istruzioni ARM per un'esecuzione rapida, mentre i 256kb di EWRAM sono ottimali per memorizzare istruzioni solo Thumb e blocchi di dati più piccoli. COME Nota Rodrigo Copetti, l'accesso a EWRAM può essere fino a sei volte più lento rispetto a IWRAM. La maggior parte della memoria sotto forma di EWRAM è accessibile solo tramite un bus a 16 bit, nonostante il Game Boy Advance sia commercializzato come palmare a 32 bit. È possibile accedere all'IWRAM tramite un bus a 32 bit. La VRAM sul Game Boy Advance arriva a 96kb e, sebbene serva principalmente per archiviare dati grafici, si trova nella mappa di memoria della CPU e può essere utilizzata anche come normale memoria di archiviazione.

Le istruzioni Thumb sono un sottoinsieme delle istruzioni ARM a 32 bit e sono un insieme di istruzioni codificate in parole a 16 bit. Presentano tutti i vantaggi delle istruzioni a 32 bit senza occupare troppo spazio, rendendole efficienti per uno sviluppo ottimizzato. Ciò significa che mentre l'accesso alla EWRAM è più lento, le istruzioni Thumb che sono efficienti spesso possono comunque risultare altrettanto veloci delle istruzioni ARM memorizzate in IWRAM, anche se lo svantaggio delle istruzioni Thumb è che a volte non esiste l'equivalente Thumb di un'istruzione ARM che si desidera eseguire. L'EWRAM è stata utilizzata per memorizzare l'output della logica di trasformazione matematica 3D che era fondamentalmente l'elenco dei bordi del poligono che venivano poi tracciati linea di scansione per linea di scansione dal codice di rasterizzazione.

Come mi ha detto Linden, la parte più complessa e difficile dell'intero porting è stata il renderer della linea di scansione. Consiste di oltre 10.000 righe di codice di assemblaggio ARM altamente ottimizzato progettato per disegnare una serie di pixel nella VRAM. Il renderer scanline ha utilizzato la maggior parte dei 32kb di IWRAM. I bordi più vicini alla telecamera sono attivi e sottoposti a rendering ed è essenzialmente un grande albero di partizionamento binario dello spazio (BSP). La VRAM è stata utilizzata per memorizzare i risultati dell'output della trasformazione poligonale nelle tabelle dei bordi perché non c'era abbastanza IWRAM, ma la VRAM sul Game Boy Advance è ancora più veloce della EWRAM. Anche la grafica è stata archiviata e visualizzata qui.

Ha trascorso molto tempo concentrandosi sulle ottimizzazioni per garantire che fosse in grado di ottenere il tempo di esecuzione più veloce possibile. Tre cose che ha fatto per accelerare i tempi di esecuzione includevano quanto segue:

  • Ha automodificato il codice prima che fosse eseguito, quindi erano necessarie meno istruzioni
  • Utilizzato una serie di tabelle di ricerca per cose come reciproco, seno, coseno, tangente, ecc.
  • Cambiata la "modalità" della CPU per ottenere l'accesso a registri aggiuntivi (che sono come "variabili") senza dover salvare e ripristinare i valori dei registri.

Cambiare le modalità della CPU per ottenere registri aggiuntivi è una manovra incredibilmente intelligente che consente un rapido accesso ai valori vicini alla CPU in modo che possano essere recuperati in un singolo ciclo di clock. Come mi dice Linden, era possibile cambiare registro e recuperare un valore in un ciclo di clock, invece di memorizzare un valore nella RAM del Game Boy Advance, che richiede più tempo. La CPU stessa è un processore da 16,78 MHz, il che significa che può completare 16780000 cicli al secondo. Sembra molto, ma quando devi calcolare e disegnare ogni pixel sullo schermo, questi si sommano rapidamente e diventa importante eliminare quante più operazioni possibile.

Quanto sopra è l'elenco dei registri generali del chipset ARM7TDMI presente nel Game Boy Advance. In genere, gli sviluppatori accederebbero sempre e solo ai registri all'interno della modalità "Sistema e Utente" e ricorrerebbero all'utilizzo di variabili normali al di fuori di quella. Tuttavia, ha utilizzato i registri in tutte e sette le modalità del chipset, e la parte migliore è proprio questa le modalità di commutazione mantengono ancora i valori nei registri delle altre modalità, quindi può passare dall'una all'altra loro.

Stranamente, Linden ha anche menzionato come il suo metodo di cambio banca abbia portato alla luce un bug nell'emulatore Nanoboy Advance. Come si è scoperto, quell'emulatore non supportava l'utilizzo delle altre modalità della CPU per il salvataggio nei registri e il cambio, e la sua demo di Quake fu il primo gioco conosciuto a farlo effettivamente.

Linden ha condiviso con noi una foto di alcune delle note che ha creato e ha spiegato come ha ottimizzato i suoi calcoli in virgola mobile in assenza di una FPU adeguata.

L'immagine sopra è quella che Linden ha condiviso con noi dai suoi appunti, e ciò che è particolarmente interessante è il "conteggio delle istruzioni del ciclo ARM varie". Ha ideato un modo per ottimizzare i cicli per i calcoli in modo da poter ridurre il numero di cicli di clock per un calcolo. Come mi ha descritto, un numero a 8 bit può essere moltiplicato in un ciclo di clock, un numero a 16 bit in due cicli di clock, un numero a 32 bit in tre cicli di clock e un numero a 64 bit in quattro cicli di clock. .

"C'erano due o tre fasi di esecuzione [nel processore ARM]. Supponiamo ad esempio che moltiplichi il registro uno per il registro due e inserisco il risultato nel registro tre. Se sapessi che il registro due è un numero a 16 bit invece di dire moltiplica il registro uno per il registro due, I lo capovolgerei e direi di moltiplicare il registro due per il registro uno perché questo mi farebbe risparmiare un orologio ciclo."

Mi ha detto che il motivo per cui lo ha fatto è stato quello di spremere ogni minima prestazione dal Game Boy Avanza, poiché un ciclo di clock salvato qua e là si somma davvero quando vengono eseguiti molti calcoli eseguita. Per quanto riguarda il codice automodificante, ho chiesto a Linden di spiegarmelo.

"Il programma proviene da [storage], trasferisce un grosso blocco del programma nella RAM interna per l'esecuzione perché è più veloce. Ogni accesso alla RAM è molto, molto più lento, quindi eseguo un DMA [Direct Memory Access] di un grosso blocco dalla ROM alla RAM, quindi cambio il codice effettivo del programma. Ad esempio, ARM ha la capacità di spostare gli operandi a sinistra o a destra oppure può mascherare determinati bit come parte del set di istruzioni. L'istruzione specifica quali bit mascherare o di quanti bit spostare. Quindi, genererei un codice che modificherebbe ciò che stava per essere eseguito in base al numero di bit che dovevo spostare. Un altro esempio riguarda la moltiplicazione di matrici 3D. Ci sono un sacco di moltiplicazioni coinvolte lì. Genererei le istruzioni effettive che eseguono le moltiplicazioni nella RAM interna e poi le eseguirei in modo che il codice costruisca porzioni di se stesso mentre è in esecuzione."

Il codice automodificante ha i suoi svantaggi, in particolare quando si tratta di debug. Elimina anche la necessità di istruzioni di ramo, in cui il codice salterebbe a un'altra sequenza di esecuzione e potrebbe privare il thread principale di prezioso tempo di calcolo. Linden ci ha anche detto che le tabelle di ricerca sono perfettamente allineate nella ROM in modo che siano un multiplo perfetto di un valore di otto bit spostato a sinistra. La dimensione della tabella di ricerca è immensa e non rientra nella RAM e l'allineamento evita anche la necessità di un'istruzione di caricamento aggiuntiva per ottenere l'indirizzo di base della tabella.

Nel complesso, il prototipo finale è stato sviluppato in quasi due anni.

Il futuro del porting Quake di Randy Linden

Ho chiesto a Linden cosa sarebbe successo al futuro del porto di Quake e lui mi ha detto che stava mettendo prendere in considerazione la possibilità di chiedere a ZeniMax e id Software di rilasciare la versione con Quake ufficiale risorse. Mi ha anche detto che ad un certo punto rilascerà il codice sorgente, ma al momento non è compilabile poiché richiede un computer più vecchio.

Configurazione di Randy Linden per collegare un Game Boy Advance a un computer per lo sviluppo.

Ho chiesto a Linden perché avesse scelto Quake e lui mi ha detto che amava il gioco e amava la sfida rappresentata dal fatto che questo fosse un "progetto impossibile", dato che era nato dal porting di DOOM per SNES. Ha anche detto che, sebbene non creda che l'intero gioco avrebbe potuto essere portato a causa di vincoli di spazio, la stragrande maggioranza del gioco avrebbe potuto essere con lo stesso motore.

Se sei interessato a dare un'occhiata a Quake per Game Boy Advance, assicurati di controllare la sua uscita su Forest of Illusion, che puoi controllare qui sotto.


Scarica da Foresta dell'Illusione