Povestea portului imposibil: Cum a fost portat Quake pe Game Boy Advance

Portarea Quake la Game Boy Advance ar fi părut imposibilă, dar Randy Linden a reușit să o facă. Iată cum.

Game Boy Advance este o consolă de jocuri portabilă creată de Nintendo. A fost lansat în Japonia în 2001 și a servit drept succesor pentru Game Boy Color. Avea un ARM7TDMI tactat la 16,78 MHz, 32 kb de RAM de lucru internă, 256 kb de RAM externă și 96 kb de VRAM. Nu este cea mai puternică mașină, dar există o mulțime de jocuri pentru handheld pe care mulți le păstrează în memorie. Un joc care nu a văzut niciodată lumina zilei pentru dispozitiv a fost un port prototip al Quake, un joc dezvoltat de id Software care a ajutat la definirea genului de împușcături la persoana întâi pe care îl cunoaștem astăzi.

Quake este un joc incredibil de detaliat, cu o coloană sonoră fantastică și un joc captivant și, la fel ca DOOM, a fost portat pe aproape fiecare dispozitiv la care vă puteți gândi. Portul său pentru Game Boy Advance este deosebit de incredibil, deoarece nu acceptă în mod nativ grafica 3D, iar Nintendo a comercializat în mod special dispozitivul portabil ca fiind o experiență de joc bidimensională. Asta nu l-a împiedicat pe Randy Linden să-și dezvolte propriul port.

Fotografie cu portul Quake jucat pe un Analogue Pocket folosit cu permisiunea Modern Vintage Gamer

Dacă nu ești familiarizat cu Linden, el este cel mai bine cunoscut pentru că a fost dezvoltatorul ambelor bleem! (un emulator PlayStation) și portul SNES al DOOM, o realizare pe care John Romero, co-fondatorul id Software, a spus-o odată într-un interviu acordat Shacknews nu credea că este posibil. Competența de dezvoltare a lui Linden a dovedit că, dacă cineva avea de gând să facă din Quake pe Game Boy Advance o realitate, probabil că a fost el.

Acest port a ieșit la lumină datorită lansării lui Linden prin proiectul Forest of Illusion. Forest of Illusion este un proiect care vizează păstrarea istoriei jocurilor Nintendo și Linden a contactat pentru a distribui copia portului Quake pe care l-a găsit pe un card flash de 256 MB din deţinere.

Dorim să-i mulțumim lui Randy Linden pentru că a dedicat timp pentru a răspunde întrebărilor noastre și pentru a asigura acuratețea tehnică a acestui articol. De asemenea, am dori să mulțumim Modern Vintage Gamer pentru că ne-a permis să folosim orice fotografii din videoclipul său de care era nevoie. Acest port nu are o relație oficială cu id Software sau ZeniMax și a fost dezvoltat ca proiect solo de Linden.

Portul pentru Game Boy Advance al lui Quake

Tehnic vorbind, este o minune că Quake poate ajunge chiar la nivelul pe care îl are pe Game Boy Advance. Funcționează la o rată de cadre bună și menține iluminarea corectă și paleta de culori a jocului original Quake. Totul este 3D, inclusiv arme și monștri. Jocurile de pe Game Boy Advance au realizat grafică 3D de obicei prin sprite-uri, dar aceasta a fost adevărata afacere. Nu folosește ray casting în felul în care alte jocuri 3D au făcut-o pe dispozitivul portabil și chiar atinge un punct efecte de lumină asupra obiectelor pre-rendate printr-un truc de schimbare a paletelor pentru a obține o iluzie de dinamică iluminat.

Pentru a fi clar, acest port nu este jocul complet și este un prototip pe care Linden intenționa să-l ia la id Software odată ce a fost finalizat, pentru a fi realizat pentru lansare. Cu toate acestea, popularitatea Game Boy Advance a început să scadă și, în schimb, motorul personalizat scris de Linden a devenit mai târziu motorul unui alt joc dezvoltat în întregime de Linden -- Cyboid. Linden ne spune că o „parte mare a codului” este încă codul ARM original din versiunea Game Boy Advance. Dacă doriți să încercați Cyboid, o versiune mai veche este disponibilă pe Google Play Store, dar APK-ul oficial este acum distribuit pe Magazinul de aplicații Amazon deoarece jocul are o mulțime de coduri de nivel scăzut pe 32 de biți.

CyboidDezvoltator: R și R Digital, LLC.

Pret: Gratuit.

3.3.

Descarca

Linden ne-a împărtășit și un videoclip cu codul său care rulează pe iPod Video, care a servit pentru a fi una dintre cele mai vechi versiuni ale Cyboid. A fost construit pe același cod de motor care a fost folosit pentru portul său Quake pentru Game Boy Advance.

Portul Quake pentru Game Boy Advance nu conține niciunul dintre activele oficiale ale jocului, deoarece Linden nu a a contactat fie id Software, fie ZeniMax despre distribuirea versiunii E1M1 care conține Quake oficial active.

Jocul care este distribuit în prezent este, de asemenea, o versiune de depanare. Dacă țineți apăsată tasta R la pornire, jucătorul va ajunge direct la a doua hartă a jocului, iar menținerea stângă pe D-pad îl va aduce pe a treia. Schimbarea hărților poate fi accesată și atunci când jucătorul moare, iar monștrii nu îl vor ataca pe jucător până când jucătorul nu trage mai întâi în ei.

În ceea ce privește muzica, demo-ul folosește fișiere publice .S3M, iar mixerul de sunet gestionează atât muzica stereo, cât și efectele sonore.

Limite tehnice

Au existat o serie de limite atunci când a fost vorba de Game Boy Advance, care au făcut din acesta un port dificil. Unele dintre cele mai mari obstacole au fost viteza scăzută a ceasului, lipsa capabilităților grafice 3D ale dispozitivului de mână și lipsa unei unități în virgulă mobilă (FPU). Au fost o mulțime de altele pe parcurs, dar acestea au fost puncte deosebite dureroase pe care Linden mi le-a subliniat ca fiind problematice. Înainte de a intra în el, este important să înțelegem aspectul Game Boy Advance.

Captură de ecran folosită cu permisiunea Modern Vintage Gamer

Game Boy Advance are trei seturi de RAM -- unul este RAM de lucru intern (IWRAM), altul este RAM de lucru extern (EWRAM) și al treilea este RAM video (VRAM). Cei 32 kb de IWRAM sunt folosiți pentru stocarea instrucțiunilor ARM pentru o execuție rapidă, în timp ce cei 256 kb de EWRAM sunt optimi pentru stocarea instrucțiunilor de tip Thumb-only și a unor bucăți mai mici de date. La fel de notează Rodrigo Copetti, EWRAM poate fi de până la șase ori mai lent la acces decât IWRAM. Majoritatea memoriei sub formă de EWRAM este accesibilă doar printr-o magistrală pe 16 biți, în ciuda faptului că Game Boy Advance este comercializat ca un handheld pe 32 de biți. IWRAM-ul poate fi accesat printr-o magistrală pe 32 de biți. VRAM-ul de pe Game Boy Advance vine la 96 kb și, deși este în primul rând pentru stocarea datelor grafice, se găsește în harta memoriei procesorului și poate fi folosit și ca stocare de memorie normală.

Instrucțiunile Thumb sunt un subset de instrucțiuni ARM pe 32 de biți și sunt un set de instrucțiuni codificate în cuvinte de 16 biți. Au toate beneficiile instrucțiunilor pe 32 de biți fără a ocupa atât de mult spațiu, făcându-le eficiente pentru o dezvoltare optimizată. Aceasta înseamnă că, în timp ce EWRAM este mai lent la accesat, instrucțiunile Thumb fiind eficiente pot ajunge adesea la fel de repede ca instrucțiunile ARM stocate. în IWRAM, deși dezavantajul instrucțiunilor Thumb este că uneori nu există echivalentul Thumb al unei instrucțiuni ARM pe care doriți să o a executa. EWRAM a fost folosit pentru stocarea rezultatului logicii de transformare matematică 3D, care a fost practic lista de margini ale poligonului care au fost apoi trasate linie cu linie de scanare prin codul de rasterizare.

După cum îmi spune Linden, partea cea mai complexă și dificilă a întregului port a fost redarea liniei de scanare. Constă din peste 10.000 de linii de cod de asamblare ARM extrem de optimizat, care este proiectat pentru a atrage un set de pixeli în VRAM. Linia de scanare a folosit cea mai mare parte a IWRAM de 32 kb. Marginile cele mai apropiate de cameră sunt active și redate și, în esență, este un arbore mare de partiționare a spațiului binar (BSP). VRAM a fost folosit pentru a stoca rezultatele transformării poligonale în tabele de margine, deoarece nu era suficient IWRAM, dar VRAM pe Game Boy Advance este încă mai rapid decât EWRAM. Grafica a fost, de asemenea, stocată și afișată aici.

A petrecut mult timp concentrându-se pe optimizări pentru a se asigura că a putut obține cel mai rapid timp de execuție posibil. Trei lucruri pe care le-a făcut pentru a accelera acel timp de execuție au inclus următoarele:

  • Auto-modificat codul înainte de a fi executat, astfel încât au fost necesare mai puține instrucțiuni
  • S-au folosit o serie de tabele de căutare pentru lucruri precum reciprocă, sinus, cosinus, tangentă etc.
  • Am schimbat „modul” CPU pentru a avea acces la registre suplimentare (care sunt ca „variabile”) fără a fi nevoie să salvați și să restabiliți valorile registrelor.

Comutarea modurilor CPU pentru a obține registre suplimentare este o manevră incredibil de inteligentă care permite accesul rapid la valorile apropiate CPU, astfel încât acestea să poată fi recuperate într-un singur ciclu de ceas. După cum îmi spune Linden, a fost posibil să schimbi registre și să recuperezi o valoare într-un singur ciclu de ceas, spre deosebire de stocarea unei valori în memoria RAM a Game Boy Advance, care durează mai mult. CPU-ul în sine este un procesor de 16,78 MHz, ceea ce înseamnă că poate finaliza 16780000 de cicluri pe secundă. Sună mult, dar atunci când trebuie să calculați și să desenați fiecare pixel de pe ecran, aceștia se adună rapid și devine important să eliminați cât mai multe operații.

Mai sus este lista registrelor generale ale chipset-ului ARM7TDMI care se află în interiorul Game Boy Advance. De obicei, dezvoltatorii ar accesa registrele numai în modul „Sistem și utilizator” și ar recurge la utilizarea variabilelor normale în afara acestuia. Cu toate acestea, a folosit registrele în toate cele șapte moduri ale chipset-ului și cea mai bună parte este că modurile de comutare păstrează în continuare valorile în registrele celorlalte moduri, astfel încât să poată comuta între ele lor.

Destul de amuzant, Linden a menționat și modul în care metoda sa de schimbare a băncilor a scos la iveală o eroare în emulatorul Nanoboy Advance. După cum s-a dovedit, acel emulator nu a acceptat utilizarea celorlalte moduri ale procesorului pentru salvarea în registre și comutare, iar demonstrația sa Quake a fost primul joc cunoscut care a făcut-o de fapt.

Linden ne-a împărtășit o fotografie cu unele dintre notele pe care le-a creat și ne-a explicat cum și-a optimizat calculele în virgulă mobilă în absența unui FPU adecvat.

Imaginea de mai sus este una pe care Linden ne-a împărtășit-o din notele sale, iar ceea ce este deosebit de interesant este „numărul de instrucțiuni ale ciclului ARM diverse”. El a conceput o modalitate de a optimiza ciclurile pentru calcule, astfel încât să poată reduce numărul de cicluri de ceas pentru un calcul. Așa cum mi l-a descris, un număr de 8 biți poate fi multiplicat într-un ciclu de ceas, un număr de 16 biți în două cicluri de ceas, un număr de 32 de biți în trei cicluri de ceas și un număr de 64 de biți în patru cicluri de ceas. .

„Au fost două sau trei etape de execuție [în procesorul ARM]. Să spunem, de exemplu, înmulțesc registrul unu cu registrul doi și pun rezultatul în registrul trei. Dacă știam că registrul doi este un număr de 16 biți în loc să spun înmulțiți registrul unu cu registrul doi, am l-aș răsturna și aș spune să înmulțiți registrul doi cu unul, pentru că asta m-ar economisi un ceas ciclu."

Mi-a spus că motivul pentru care a făcut asta a fost pentru a strânge fiecare performanță din Game Boy Advance, deoarece un ciclu de ceas salvat aici și acolo se adună cu adevărat atunci când se fac o mulțime de calcule efectuat. În ceea ce privește codul care se auto-modifica, l-am rugat pe Linden să-l explice.

„Programul vine din [storage], transferă un bloc mare al programului în memoria RAM internă pentru execuție pentru că este mai rapid. Fiecare acces la RAM este mult, mult mai lent, așa că fac un DMA [Acces direct la memorie] dintr-un bloc mare din ROM în RAM și apoi schimb codul real al programului. De exemplu, ARM are capacitatea de a muta operanzii la stânga sau la dreapta sau poate masca anumiți biți ca parte a setului de instrucțiuni. Instrucțiunea specifică ce biți vei masca sau câți biți vei trece. Așadar, aș genera cod care ar modifica ceea ce era pe cale să fie executat în funcție de câți biți aveam nevoie pentru a schimba. Un alt exemplu este în ceea ce privește multiplicarea matricei 3D. Există o grămadă de înmulțiri implicate acolo. Aș genera instrucțiunile reale care fac înmulțirile în memoria RAM internă și apoi le-aș executa astfel încât codul să construiască un fel de porțiuni din el însuși în timp ce rula."

Codul cu auto-modificare are propriile sale dezavantaje, în special când vine vorba de depanare. Îndepărtează și nevoia de instrucțiuni de ramificare, unde codul ar sări la o altă secvență de execuție și poate priva firul principal de timp prețios de calcul. Linden ne-a mai spus că tabelele de căutare sunt perfect aliniate în ROM, astfel încât să fie un multiplu perfect al unei valori de opt biți deplasată la stânga. Dimensiunea tabelului de căutare este imensă și nu se potrivește în RAM, iar alinierea evită, de asemenea, necesitatea unei instrucțiuni de încărcare suplimentară pentru a obține adresa de bază a tabelului.

Una peste alta, prototipul final a fost dezvoltat pe parcursul a aproape doi ani.

Viitorul portului Quake al lui Randy Linden

L-am întrebat pe Linden ce se va întâmpla cu viitorul portului Quake și mi-a spus că pune luați în considerare să întrebați ZeniMax și id Software despre lansarea versiunii cu Quake oficial active. De asemenea, mi-a spus la un moment dat că va lansa codul sursă, dar în prezent, acesta nu se construiește, deoarece necesită un computer mai vechi.

Configurația lui Randy Linden pentru conectarea unui Game Boy Advance la un computer pentru dezvoltare.

L-am întrebat pe Linden de ce a ales Quake și mi-a spus că îi place jocul și îi place provocarea ca acesta să fie „proiectul imposibil”, deoarece era în spatele portului său DOOM pentru SNES. El a mai menționat că, deși nu crede că întregul joc ar fi putut fi portat din cauza constrângerilor de spațiu, marea majoritate a jocului ar fi putut fi în același motor.

Dacă sunteți interesat să vedeți Quake pentru Game Boy Advance, asigurați-vă că ați verificat lansarea lui pe Forest of Illusion, pe care o puteți verifica mai jos.


Descărcați din Forest of Illusion