Историята на невъзможното пренасяне: Как Quake беше пренесен към Game Boy Advance

Пренасянето на Quake към Game Boy Advance би изглеждало невъзможно, но Randy Linden успя да го направи. Ето как.

Game Boy Advance е ръчна конзола за игри, създадена от Nintendo. Пуснат е в Япония през 2001 г. и служи като наследник на Game Boy Color. Имаше ARM7TDMI с тактова честота 16,78 MHz, 32kb вътрешна работна RAM, 256kb външна RAM и 96kb VRAM. Това не е най-мощната машина, но има много игри за ръчно устройство, които мнозина пазят в спомен. Една игра, която така и не видя бял свят за устройството, беше прототип на Quake, игра, разработена от id Software, която помогна за дефинирането на жанра шутър от първо лице, който познаваме днес.

Quake е невероятно детайлна игра с фантастичен саундтрак и пристрастяващ геймплей и точно като DOOM, тя е пренесена на почти всяко едно устройство, за което се сетите. Неговият порт към Game Boy Advance е особено невероятен, тъй като не поддържа първоначално 3D графики, а Nintendo специално рекламира джобния компютър като двуизмерен геймплей. Това обаче не попречи на Ранди Линден да разработи свой собствен порт.

Снимка на порта на Quake, играна на аналогов джоб, използван с разрешение от Modern Vintage Gamer

Ако не сте запознати с Linden, той е най-известен с това, че е разработчик и на двата bleem! (емулатор на PlayStation) и SNES порта на DOOM, постижение, което Джон Ромеро, съосновател на id Software, веднъж каза в интервю за Шакнюз не смяташе, че е възможно. Уменията на Linden в разработката доказаха, че ако някой щеше да успее да направи Quake на Game Boy Advance реалност, това вероятно беше той.

Това пристанище се появи наяве благодарение на издаването му от Linden чрез проекта Forest of Illusion. Forest of Illusion е проект, насочен към запазване на историята на игрите на Nintendo и Linden посегна, за да разпространи копието на порта на Quake, който намери на 256MB флаш карта в своя владение.

Бихме искали да благодарим на Ранди Линден за това, че отдели време, за да отговори на нашите въпроси и да гарантира техническата точност на тази статия. Ние също бихме искали да благодарим Модерен винтидж геймър за това, че ни позволи да използваме всички необходими кадри от неговото видео. Този порт няма официална връзка с id Software или ZeniMax и е разработен като самостоятелен проект от Linden.

Портът Game Boy Advance на Quake

Технически погледнато, чудо е, че Quake може дори да достигне нивото, което го прави на Game Boy Advance. Работи с добра скорост на кадрите и поддържа правилното осветление и цветова палитра на оригиналната игра Quake. Всичко е 3D, включително оръжия и чудовища. Игрите на Game Boy Advance постигаха 3D графики обикновено чрез спрайтове, но това беше истинската сделка. Не използва хвърлянето на лъчи по начина, по който другите 3D игри го правеха на преносимия компютър, и дори постига точка светлинни ефекти върху предварително изобразени обекти чрез трик за смяна на палета за постигане на илюзия за динамика осветление.

За да бъде ясно, този порт не е пълната игра и е прототип, който Linden възнамеряваше да пренесе на id Software, след като бъде завършен, за да бъде направен за пускане. Въпреки това, популярността на Game Boy Advance започна да намалява и вместо това персонализираният двигател, написан от Linden, по-късно стана двигател на друга игра, разработена изцяло от Linden - Cyboid. Линден ни казва, че "голяма част от кода" все още е оригиналният ARM код от версията на Game Boy Advance. Ако искате да изпробвате Cyboid, по-стара версия е налична в Google Play Store, но официалният APK вече се разпространява в Amazon App Store тъй като играта има много 32-битов код на ниско ниво.

CyboidРазработчик: R and R Digital, LLC.

Цена: Безплатно.

3.3.

Изтегли

Линден също сподели с нас видеоклип на неговия код, изпълняван на iPod Video, който служи като една от най-ранните версии на Cyboid. Той е изграден върху същия код на двигателя, който беше използван за неговия Quake порт към Game Boy Advance.

Портът на Game Boy Advance на Quake не съдържа никакви официални активи на играта, тъй като Linden не е се свърза с id Software или ZeniMax относно разпространението на версията E1M1, която съдържа официалния Quake активи.

Играта, която в момента се разпространява, също е компилация за отстраняване на грешки. Задържането на клавиша R при зареждане ще доведе играча направо до втората карта на играта, а задържането наляво върху D-пада ще го отведе до третата. Размяната на карти също може да бъде достъпна, когато играчът умре, и чудовищата няма да атакуват играча, докато играчът не стреля по тях първи.

Що се отнася до музиката, демонстрацията използва публични .S3M файлове, а звуковият миксер обработва както стерео музика, така и звукови ефекти.

Технически граници

Имаше редица граници, когато ставаше дума за Game Boy Advance, което правеше това трудно пренасяне. Някои от най-големите пречки бяха ниската тактова честота, липсата на 3D графични възможности на ръчния компютър и липсата на модул с плаваща запетая (FPU). Имаше много други по пътя, но това бяха конкретни болезнени точки, които Линден ми очерта като проблематични. Преди да навлезем в него, важно е да разберем оформлението на Game Boy Advance.

Екранна снимка, използвана с разрешение от Modern Vintage Gamer

Game Boy Advance има три комплекта RAM -- единият е вътрешната работна RAM (IWRAM), другият е външната работна RAM (EWRAM), а третият е видео RAM (VRAM). 32kb IWRAM се използва за съхраняване на ARM инструкции за бързо изпълнение, докато 256kb EWRAM е оптимално за съхраняване на инструкции само за Thumb и по-малки части от данни. Като Родриго Копети отбелязва, EWRAM може да бъде до шест пъти по-бавен за достъп от IWRAM. По-голямата част от паметта под формата на EWRAM е достъпна само чрез 16-битова шина, въпреки че Game Boy Advance се предлага на пазара като 32-битово джобно устройство. IWRAM може да бъде достъпен чрез 32-битова шина. VRAM на Game Boy Advance идва с 96kb и макар че е предимно за съхранение на графични данни, тя се намира в картата на паметта на процесора и може да се използва и като нормално хранилище на паметта.

Thumb инструкциите са подгрупа от 32-битови ARM инструкции и са набор от инструкции, кодирани в 16-битови думи. Те имат всички предимства на 32-битовите инструкции, без да заемат много място, което ги прави ефективни за оптимизирана разработка. Това означава, че докато достъпът до EWRAM е по-бавен, инструкциите на Thumb, които са ефективни, често могат да се окажат също толкова бързи, колкото съхранените ARM инструкции в IWRAM, въпреки че недостатъкът на Thumb инструкциите е, че понякога няма точно Thumb еквивалент на ARM инструкция, която искате изпълни. EWRAM беше използван за съхраняване на изхода от логиката на 3D математическа трансформация, която основно беше списъкът с ръбове на полигони, които след това бяха проследени сканиран ред по сканиран ред от кода за растеризиране.

Както Линден ми каза, най-сложната и трудна част от целия порт беше рендиращият сканиращ ред. Състои се от над 10 000 реда високооптимизиран асемблиращ код на ARM, който е проектиран да рисува набор от пиксели към VRAM. Рендърът за сканиране използва по-голямата част от 32kb IWRAM. Краищата, които са най-близо до камерата, са активни и изобразени и по същество това е голямо дърво за разделяне на двоично пространство (BSP). VRAM беше използвана за съхраняване на резултатите от изхода на полигоналната трансформация в крайни таблици, тъй като нямаше достатъчно IWRAM, но VRAM на Game Boy Advance все още е по-бърз от EWRAM. Графиките също се съхраняват и показват тук.

Той прекара много време, фокусирайки се върху оптимизациите, за да гарантира, че е в състояние да получи възможно най-бързото време за изпълнение. Три неща, които той направи, за да ускори това време за изпълнение, включват следното:

  • Сам модифицира кода, преди да бъде изпълнен, така че са необходими по-малко инструкции
  • Използва се поредица от справочни таблици за неща като реципрочна стойност, синус, косинус, тангенс и т.н.
  • Превключва „режима“ на процесора, за да получи достъп до допълнителни регистри (които са като „променливи“), без да се налага да записвате и възстановявате стойностите на регистрите.

Превключването на режимите на процесора за получаване на допълнителни регистри е невероятно умна маневра, която позволява бърз достъп до стойности близо до процесора, така че да могат да бъдат извлечени в един такт. Както Linden ми каза, беше възможно да превключите регистрите и да извлечете стойност в един такт, за разлика от съхраняването на стойност в RAM на Game Boy Advance, което отнема повече време. Самият процесор е 16,78 MHz процесор, което означава, че може да изпълни 16780000 цикъла в секунда. Това звучи като много, но когато трябва да изчислите и начертаете всеки пиксел на екрана, те бързо се натрупват и става важно да намалите колкото се може повече операции.

Горното е списъкът с общи регистри на чипсета ARM7TDMI, който е в Game Boy Advance. Обикновено разработчиците имат достъп до регистрите само в режим "Система и потребител" и прибягват до използване на нормални променливи извън него. Въпреки това, той използва регистри във всичките седем режима на чипсета и най-добрата част от това е, че режимите на превключване все още запазват стойностите в регистрите на другите режими, така че той може да превключва между тях тях.

Колкото и да е забавно, Линден също спомена как неговият метод за превключване на банки е открил бъг в емулатора Nanoboy Advance. Както се оказа, този емулатор не поддържаше използването на други режими на процесора за записване в регистри и превключване, а неговата демонстрация на Quake беше първата известна игра, която наистина го направи.

Linden сподели с нас снимка на някои от бележките, които е създал, и обясни как е оптимизирал своите изчисления с плаваща запетая при липса на подходящ FPU.

Изображението по-горе е това, което Linden сподели с нас от своите бележки, и това, което е особено интересно, е „разните инструкции за цикъл на ARM се броят“. Той измисли начин за оптимизиране на циклите за изчисления, така че да може да намали броя на тактовите цикли за изчисление. Както ми го описа, едно 8-битово число може да бъде умножено за един такт, 16-битово число за два такта, 32-битово число за три такта и 64-битово число за четири такта. .

„Имаше два или три етапа на изпълнение [в ARM процесора]. Да кажем например, че умножавам регистър едно по регистър две и поставям резултата в регистър три. Ако знаех, че регистър две е 16-битово число, вместо да казвам умножение на регистър едно по регистър две, аз ще го обърна и бих казал да умножа регистър две по регистър едно, защото това ще ми спести часовник цикъл."

Той ми каза, че причината да направи това е да изтръгне всяка частица от производителността на Game Boy Предварително, тъй като часовниковият цикъл, запазен тук и там, наистина се добавя, когато се извършват много изчисления изпълнени. Що се отнася до самопроменящия се код, помолих Линден да го обясни.

„Програмата идва от [памет за съхранение], тя прехвърля голям блок от програмата във вътрешна RAM за изпълнение, защото е по-бърза. Всеки достъп до RAM е много, много по-бавен, така че правя DMA [директен достъп до паметта] на голям блок от ROM в RAM и след това променям действителния програмен код. Например ARM има способността да измества операндите наляво или надясно или може да маскира определени битове като част от набора от инструкции. Инструкцията уточнява кои битове ще маскирате или с колко бита ще преместите. И така, щях да генерирам код, който да модифицира това, което тъкмо трябваше да бъде изпълнено, въз основа на това колко бита трябва да преместя. Друг пример е по отношение на 3D матрично умножение. Тук има цял куп умножения. Бих генерирал действителните инструкции, които извършват умноженията във вътрешната RAM памет, и след това бих ги изпълнил, така че кодът да създава части от себе си, докато работи."

Самомодифицирането на кода има своите недостатъци, особено когато става въпрос за отстраняване на грешки. Премахва и необходимостта от инструкции за разклоняване, при които кодът ще премине към друга последователност за изпълнение и може да лиши основната нишка от ценно време за изчисление. Линден също така ни каза, че справочните таблици са идеално подравнени в ROM, така че да са перфектно кратно на осем-битова стойност, изместена наляво. Размерът на таблицата за търсене е огромен и не се побира в RAM, а подравняването също така избягва необходимостта от допълнителна инструкция за зареждане, за да се получи основният адрес на таблицата.

Като цяло окончателният прототип е разработен в продължение на близо две години.

Бъдещето на Quake порта на Ранди Линден

Попитах Линден какво ще се случи с бъдещето на пристанището Quake и той ми каза, че поставя обмислете да попитате ZeniMax и id Software относно пускането на версията с официалния Quake активи. Той също така ми каза в даден момент, че ще пусне изходния код, но в момента той не се изгражда, тъй като изисква по-стар компютър.

Настройката на Randy Linden за свързване на Game Boy Advance към компютър за разработка.

Попитах Линден защо е избрал Quake и той ми каза, че харесва играта и харесва предизвикателството, че това е „невъзможният проект“, тъй като беше на гърба на неговия DOOM за SNES порт. Той също така спомена, че въпреки че не вярва, че цялата игра може да е била пренесена поради ограничения в пространството, по-голямата част от играта може да е била в същия двигател.

Ако се интересувате да проверите Quake за Game Boy Advance, не забравяйте да проверите изданието му в Forest of Illusion, което можете да разгледате по-долу.


Изтеглете от Forest of Illusion