Historien om den umulige havn: Hvordan Quake blev overført til Game Boy Advance

At overføre Quake til Game Boy Advance ville have været umuligt, men Randy Linden formåede at klare det. Sådan gør du.

Game Boy Advance er en håndholdt spilkonsol skabt af Nintendo. Den blev udgivet i Japan i 2001 og fungerede som efterfølgeren til Game Boy Color. Den havde en ARM7TDMI klokket til 16,78 MHz, 32 kb intern arbejds-RAM, 256 kb ekstern RAM og 96 kb VRAM. Det er ikke den mest kraftfulde maskine, men der er masser af spil til den håndholdte, som mange holder i god hukommelse. Et spil, der dog aldrig så dagens lys for enheden, var en prototypeport af Quake, et spil udviklet af id Software, der hjalp med at definere den førstepersonsskydegenre, som vi kender i dag.

Quake er et utroligt detaljeret spil med et fantastisk soundtrack og vanedannende gameplay, og ligesom DOOM er det blevet porteret til praktisk talt hver eneste enhed, du kan komme i tanke om. Dens port til Game Boy Advance er særlig utrolig, da den ikke naturligt understøtter 3D-grafik, og Nintendo markedsførte specifikt den håndholdte som værende en todimensionel spiloplevelse. Det forhindrede dog ikke Randy Linden i at udvikle sin egen havn.

Foto af Quake-porten afspillet på en analog lomme brugt med tilladelse fra Modern Vintage Gamer

Hvis du ikke er bekendt med Linden, er han bedst kendt for at være udvikleren af ​​begge bleem! (en PlayStation-emulator) og SNES-porten af ​​DOOM, en bedrift, som John Romero, medstifter af id Software, engang sagde i et interview med Shacknews han troede ikke var muligt. Lindens udviklingsfærdigheder beviste, at hvis nogen skulle være i stand til at gøre Quake på Game Boy Advance til virkelighed, så var det nok ham.

Denne havn er kommet frem i lyset takket være Lindens egen frigivelse af den gennem Forest of Illusion-projektet. Forest of Illusion er et projekt, der har til formål at bevare historien om Nintendos spil og Linden rakte ud for at distribuere kopien af ​​Quake-porten, han fandt på et 256 MB flash-kort i sit besiddelse.

Vi vil gerne takke Randy Linden for at dedikere tid til at besvare vores spørgsmål og sikre den tekniske nøjagtighed af denne artikel. Vi vil også gerne takke Moderne vintage gamer for at give os mulighed for at bruge alle stillbilleder fra hans video, der var nødvendige. Denne port har ingen officiel relation til id Software eller ZeniMax og blev udviklet som et soloprojekt af Linden.

Quake's Game Boy Advance-port

Teknisk set er det et vidunder, at Quake endda kan køre til det niveau, det gør på Game Boy Advance. Det kører med en god billedhastighed og bevarer den korrekte belysning og farvepalet i det originale Quake-spil. Alt er 3D, inklusive våben og monstre. Spil på Game Boy Advance opnåede typisk 3D-grafik gennem sprites, men dette var den rigtige vare. Det gør ikke brug af ray-casting på den måde, som andre 3D-spil gjorde på den håndholdte, og det opnår endda point lyseffekter på præ-renderede objekter via et palleskiftende trick for at opnå en illusion af dynamisk belysning.

For at være klar, er denne port ikke det fulde spil, og det er en prototype, som Linden havde til hensigt at tage til id-software, når den var færdiggjort til udgivelse. Game Boy Advances popularitet begyndte dog at aftage, og i stedet blev den brugerdefinerede motor skrevet af Linden senere motoren i et andet spil udviklet af Linden helt - Cyboid. Linden fortæller os, at en "stor del af koden" stadig er den originale ARM-kode fra Game Boy Advance-versionen. Hvis du vil prøve Cyboid, er en ældre version tilgængelig i Google Play Butik, men den officielle APK er nu distribueret på Amazon App Store da spillet har en masse 32-bit kode på lavt niveau.

CyboidUdvikler: R og R Digital, LLC.

Pris: Gratis.

3.3.

Hent

Linden delte også en video med os af sin kode, der kører på iPod Video, som tjente til at være en af ​​de tidligste versioner af Cyboid. Den blev bygget på den samme motorkode, som blev brugt til hans Quake-port til Game Boy Advance.

Game Boy Advance-havnen i Quake indeholder ingen af ​​spillets officielle aktiver, da Linden ikke har kontaktede enten id Software eller ZeniMax om distribution af E1M1-versionen, som indeholder officielt Quake aktiver.

Spillet, der i øjeblikket distribueres, er også en debug-build. Hvis du holder R-tasten nede ved opstart, vil spilleren bringes direkte til spillets andet kort, og ved at holde venstre på D-pad'en bringes spilleren til det tredje. Kortbytning kan også tilgås, når spilleren dør, og monstre vil ikke angribe spilleren, før spilleren skyder på dem først.

Hvad angår musik, gør demoen brug af offentlige .S3M-filer, og lydmixeren håndterer både stereomusik og lydeffekter.

Tekniske grænser

Der var en række grænser, når det kom til Game Boy Advance, der gjorde dette til en vanskelig havn. Nogle af de største forhindringer var den lave clockhastighed, manglen på 3D-grafikfunktioner på den håndholdte enhed og manglen på en flydende komma-enhed (FPU). Der var masser af andre undervejs, men det var særlige smertepunkter, som Linden skitserede for mig som værende problematiske. Før vi kommer ind i det, er det vigtigt at forstå layoutet af Game Boy Advance.

Skærmbillede brugt med tilladelse fra Modern Vintage Gamer

Game Boy Advance har tre sæt RAM - det ene er det interne arbejds-RAM (IWRAM), et andet er det eksterne arbejds-RAM (EWRAM), og det tredje er video-RAM (VRAM). De 32 kb IWRAM bruges til lagring af ARM-instruktioner til hurtig eksekvering, hvorimod 256 kb EWRAM er optimal til lagring af tommelfingerinstruktioner og mindre bidder af data. Som Rodrigo Copetti bemærker, EWRAM kan være op til seks gange langsommere at få adgang til end IWRAM. Størstedelen af ​​hukommelsen i form af EWRAM er kun tilgængelig via en 16-bit bus, på trods af at Game Boy Advance markedsføres som en 32-bit håndholdt. IWRAM kunne tilgås via en 32-bit bus. VRAM på Game Boy Advance kommer på 96 kb, og selvom det primært er til lagring af grafikdata, findes det i CPU'ens hukommelseskort og kan også bruges som normal hukommelseslagring.

Tommelfingerinstruktioner er en delmængde af 32-bit ARM-instruktioner og er et sæt instruktioner kodet til 16-bit ord. De har alle fordelene ved 32-bit instruktioner uden at optage så meget plads, hvilket gør dem effektive til optimeret udvikling. Dette betyder, at selvom EWRAM er langsommere at få adgang til, kan tommelfingerinstruktioner, der er effektive, ofte stadig ende lige så hurtigt som ARM-instruktioner gemt i IWRAM, selvom ulempen ved Thumb-instruktioner er, at nogle gange er der ikke helt den Thumb-ækvivalent til en ARM-instruktion, du vil udføre. EWRAM blev brugt til at gemme outputtet af 3D-matematiktransformationslogikken, som dybest set var listen over polygonkanter, der derefter blev sporet scanline-by-scanline af rasteriseringskoden.

Som Linden fortæller mig, var den mest komplekse og vanskelige del af hele porten scanline-rendereren. Den består af over 10.000 linjer med højoptimeret ARM-samlingskode, som er designet til at tegne et sæt pixels til VRAM. Scanline-rendereren brugte det meste af 32 kb IWRAM. Kanterne tættest på kameraet er aktive og gengivet, og det er i bund og grund et stort binært rumpartitioneringstræ (BSP). VRAM blev brugt til at gemme resultaterne af det polygonale transformationsoutput i kanttabeller, fordi der ikke var nok IWRAM, men VRAM på Game Boy Advance er stadig hurtigere end EWRAM. Grafikken blev også gemt og vist her.

Han brugte meget tid på at fokusere på optimeringer for at sikre, at det var i stand til at opnå den hurtigst mulige eksekveringstid. Tre ting, han gjorde for at fremskynde henrettelsestiden, omfattede følgende:

  • Selvmodificerede koden, før den blev udført, så der krævedes færre instruktioner
  • Brugte en række opslagstabeller til ting som reciprok, sinus, cosinus, tangent osv.
  • Skiftede CPU'en "tilstand" for at få adgang til yderligere registre (der er ligesom "variabler") uden at skulle gemme og gendanne registrenes værdier.

At skifte CPU-tilstande for at få yderligere registre er en utrolig smart manøvre, der giver hurtig adgang til værdier tæt på CPU'en, så de kan hentes i en enkelt clock-cyklus. Som Linden fortæller mig, var det muligt at skifte registre og hente en værdi i én clock-cyklus, i modsætning til at gemme en værdi i RAM'en på Game Boy Advance, hvilket tager længere tid. Selve CPU'en er en 16,78 MHz processor, hvilket betyder, at den kan gennemføre 16780000 cyklusser i sekundet. Det lyder af meget, men når du skal beregne og tegne hver pixel på skærmen, tæller de hurtigt sammen, og det bliver vigtigt at barbere så mange operationer af, som du kan.

Ovenstående er listen over generelle registre for ARM7TDMI-chipsættet, der er inde i Game Boy Advance. Typisk vil udviklere kun få adgang til registrene i "System og Bruger"-tilstanden og ty til at bruge normale variabler uden for det. Han gjorde dog brug af registre i alle syv tilstande af chipsættet, og det bedste ved det er det skiftende tilstande beholder stadig værdierne i registrene for de andre tilstande, så han kunne skifte mellem dem.

Sjovt nok nævnte Linden også, hvordan hans metode til bankskifte afslørede en fejl i Nanoboy Advance-emulatoren. Som det viste sig, understøttede den emulator ikke at bruge de andre tilstande af CPU'en til at gemme i registre og skifte, og hans Quake-demo var det første kendte spil, der rent faktisk gjorde det.

Linden delte et billede med os af nogle af de noter, han lavede, og forklarede, hvordan han optimerede sine flydende kommaberegninger i mangel af en ordentlig FPU.

Ovenstående billede er et, som Linden delte med os fra sine noter, og det, der er særligt interessant, er "diverse ARM-cyklusinstruktionstællinger". Han udtænkte en måde at optimere cyklusserne til beregninger på, så han kunne reducere antallet af urcyklusser til en beregning. Som han beskrev det for mig, kunne et 8-bit tal multipliceres i én clock-cyklus, et 16-bit-tal i to clock-cyklusser, et 32-bit-tal i tre clock-cyklusser og et 64-bit-tal i fire clock-cyklusser .

"Der var to eller tre stadier af eksekvering [i ARM-processoren]. Sig for eksempel, at jeg multiplicerer register et med register to og sætter resultatet i register tre. Hvis jeg vidste, at register to var et 16-bit tal i stedet for at sige multiplicer register en med register to, I ville vende det, og jeg ville sige at gange register to med register et, fordi det ville spare mig for et ur cyklus."

Han fortalte mig, at grunden til, at han gjorde dette, var for at presse hver eneste præstation ud af Game Boy Advance, da en klokkecyklus gemt her og der virkelig lægger sig op, når der udføres mange beregninger udført. Hvad angår den selvmodificerende kode, bad jeg Linden om at forklare det.

"Programmet kommer fra [lagring], det overfører en stor blok af programmet til intern RAM til udførelse, fordi det er hurtigere. Hver RAM-adgang er meget, meget langsommere, så jeg laver en DMA [Direct Memory Access] af en stor blok fra ROM til RAM, og så ændrer jeg den faktiske programkode. For eksempel har ARM evnen til at flytte operander til venstre eller højre, eller den kan maskere visse bits som en del af instruktionssættet. Instruktionen specificerer, hvilke bits du vil maskere, eller hvor mange bits du vil skifte efter. Så jeg ville generere kode, der ville ændre, hvad der lige skulle udføres baseret på, hvor mange bits jeg skulle skifte. Et andet eksempel er med hensyn til 3D matrix multiplikation. Der er en hel masse multiplikationer involveret der. Jeg ville generere de faktiske instruktioner, der udfører multiplikationerne i den interne RAM og derefter udføre dem, så koden på en måde byggede dele af sig selv, mens den kørte."

Selvmodificerende kode har sine egne ulemper, især når det kommer til fejlretning. Det fjerner også behovet for greninstruktioner, hvor koden ville springe til en anden eksekveringssekvens og kan fratage hovedtråden dyrebar beregningstid. Linden fortalte os også, at opslagstabellerne er perfekt justeret i ROM'en, så de er et perfekt multiplum af en otte-bit værdi flyttet til venstre. Størrelsen på opslagstabellen er enorm og passer ikke ind i RAM, og justeringen undgår også behovet for en ekstra indlæsningsinstruktion for at få tabellens baseadresse.

Alt i alt blev den endelige prototype udviklet over næsten to år.

Fremtiden for Randy Lindens Quake-havn

Jeg spurgte Linden, hvad der ville ske med Quake-havnens fremtid, og han fortalte mig, at han satte overveje at spørge ZeniMax og id Software om at frigive versionen med den officielle Quake aktiver. Han fortalte mig også på et tidspunkt, at han vil frigive kildekoden, men i øjeblikket bygger den ikke, da den kræver en ældre computer.

Randy Lindens opsætning til at forbinde en Game Boy Advance til en computer til udvikling.

Jeg spurgte Linden, hvorfor han valgte Quake, og han fortalte mig, at han elskede spillet, og han elskede udfordringen ved at være det "umulige projekt", da det var bagved hans DOOM for SNES port. Han nævnte også, at selvom han ikke mener, at hele spillet kunne have været porteret på grund af pladsbegrænsninger, kunne langt størstedelen af ​​spillet have været i den samme motor.

Hvis du er interesseret i at tjekke Quake til Game Boy Advance, så sørg for at tjekke udgivelsen af ​​den på Forest of Illusion, som du kan tjekke ud nedenfor.


Download fra Forest of Illusion