[Перевод] Реверс-инжиниринг игры Strike Commander

В начале 90-х на переднем крае прогресса PC-гейминга находилась одна компания: Origin Systems. Её слоганом был «Мы создаём миры» и, чёрт возьми, они ему соответствовали: серии Ultima, Crusader и Wing Commander потрясли воображение игроков.

На создание одной из игр ушло четыре года и больше миллиона человеко-часов: Strike Commander. Знаменитый лётный симулятор имел собственный 3D-движок под названием RealSpace, в котором впервые появились технологии, сегодня воспринимаемые как должное: наложение текстур, затенение по Гуро, изменение уровня детализации и дизеринг цветов.

Мой старой мечтой было поиграть в неё в шлеме виртуальной реальности. Благодаря Oculus Rift эта фантазия стала ещё на один шаг ближе к реальности.

Но, как оказалось, исходный код игры был утерян и никогда не будет выпущен, поэтому я решил выполнить обратную разработку.

На момент публикации этой статьи мой проект ещё не закончен, но я хочу поделиться техниками, позволившими мне сделать из этого:

750e16458f1c74c9bdec3b978c9bed14.png

вот это:

18211c2aa988e89f19508cfd2f598f6b.png

… и, возможно, вдохновить кого-нибудь присоединиться к моему приключению.

До Strike Commander


В начале 90-х лётные симуляторы были хорошими, но Falcon 3.0 или Flight simulator 4.0 больше были сосредоточены на точности лётной модели, а не красивой визуализации:

2aa317dac32ee275c33070d49277d739.jpg
46df4fb070ff277941c1228f351cd912.gif

На рынке было много лётных симуляторов и немногие заметили, что в 1990 году Origin Systems объявила о создании новой игры. Но всё изменилось после выставки CES 1991 в Чикаго, где было показано демо. Никто не мог поверить, что в игре будут элементы, присутствовавшие в то время только в лётных симуляторах ВВС: наложение текстур, затенение по Гуро, туман и многие другие. На скриншотах видны технологии, сильно обогнавшие своих конкурентов:

959921228a79fe2f15fd1f295a8b2cdf.png
14b29f2dc7146759f2d4bd705ba89d3a.png
8839a71543dc08726456c2524406d06f.png
c6b5061bf25d9b69cf2e879566836903.png

После 1991 года игру стали ждать многие. Не только из-за потрясающего движка и захватывающего сюжета — RealSpace изначально поддерживал дополнительное оборудование, очень дорогие и хрупкие аксессуары, желанные любому фанату лётных симуляторов — THRUSTMASTER WEAPON CONTROL SYSTEM и THRUSTMASTER FLIGHT CONTROL SYSTEM:

810c2f78e0913f4ee626cddabd2b9065.jpg
6b97c6e31d2fdf38056f93f8bd456530.jpg

Можно было даже подключить THRUSTMASTER RUDDER:

38bfc6dc5e65f45b2ca8d5c4f57d6e4b.jpg

Но это было ещё не всё: игра поддерживала виртуальный кокпит. Мини-джойстик ThrustMaster с четырьмя направлениями позволяет перемещать голову пилота и следить за наземными объектами/вражескими самолётами без необходимости использования шлема виртуальной реальности:

9eade9ffa83ca8671291b9d6eff006d3.png
fa9f236bcd7a0b9079685593a8e981a6.png

1993 год: первый контакт


Игра и её трёхмерный движок просто «взрывали мозг», но для них требовалась невероятно мощная машина:

  • IBM PC 486-DX2 66 МГц
  • 4 МБ ОЗУ
  • Не менее 38 МБ на жёстком диске
  • Игра поставлялась на одиннадцати флоппи-дисках по 1,44 МБ.


Если провести аналогию с современным технологическим уровнем, то рекомендуемая конфигурация была бы такой:

  • ЦП с 8 ядрами и 16 ГБ ОЗУ.
  • Два видеопроцессора Nvidia Titan.
  • Обязательная установка 1000 ГБ.
  • Игра поставляется на пяти BluRay.


И просто купить игру было недостаточно, надо было ещё пережить процесс установки! Открыв коробку, пользователь видел 8 флоппи-дисков (+3 для Speech Pack):

592bf34947948e5d97e28c82f7daceed.png
8e5f047f32bd044aa44952220a2b62ef.jpg

Интересный факт: заметьте, что на постере указана дата выхода: Рождество 1991 года. Игра была завершена только в 1993 году после долгого процесса, который Крис Роберт назвал «Апокалипсисом сегодня» компьютерных игр».

Распаковка игры с флоппиков на жёсткий диск и смена 13 дисков занимала добрых полчаса. И когда вы уже думали, что всё закончилось, игра начинала генерировать все карты. Размер игры увеличивался с 24 МБ до 38 МБ: в четыре раза больше, чем любая другая игра того времени.

a57ea53a7fad7985460e12b00f7862df.png

Интересный факт: карта генерировалась из одного seed (целого числа), вставленного в алгоритм генерации псевдослучайных чисел. Это была искусный приём, позволивший избежать увеличения количества данных на дисках благодаря генерированию карты после установки. Если вам интересны подробности этого приёма, рекомендую прочитать книгу The Backroom Boys и главу об игре Frontier Elite.

На 386-м PC генерирование карты занимало ОДИН ЧАС. Но Origin Systems додумалась поставлять вместе с коробкой игры отличный стостраничный журнал в мрачном антураже мира игры 2012 года. Благодаря Sudden Death весь процесс становился менее мучительным (заметьте, что на странице 38 есть фальшивая реклама, обещающая выпуск Strike Commander к Рождеству 2013 года).

Strike Commander!


Наконец, после этих шагов, игроки могли насладиться игрой… в апреле 1993 года! Несмотря на то, что игра задержалась на два года, в ней было всё, что обещала Origin, и она продавалась очень хорошо. Многие проводили долгие ночи, сражаясь в боях, даже несмотря на то, что игра, которая должна была выглядеть так:

594c64cbd7d434f7d5612fc9d0a5d4f2.png

… на минимальных настройках выглядела так:

0325b5f2d4e4f282470a8becd26ab078.png

В целом этого было достаточно, чтобы привлечь пилотов и создать хорошие воспоминания.

Утерянный исходный код


После выхода Oculus Rift мой интерес к Strike Commander снова возрос: появилось подходящее «железо». Поскольку игре было 20 лет, я ожидал, что исходный код уже выпущен, но быстро наткнулся на рассказ о печальной истории увядания Origin Systems.

В сентябре 1992 года Origin Systems была куплена Electronic Arts и примерно в 1999 году все проекты были отменены из-за плохих продаж Ultima 9. Компании пришлось сосредоточиться на другой области, в которой она тоже была первооткрывателем: MMORPG Ultima Online. Многие люди считают, что исходные коды и версии на «золоте» всех готовых игр хранятся где-то в глубинах хранилища EA. Но связавшись с людьми из Wing Commander CIC, я выяснил, что весь исходный код пропал после закрытия компании.

Сегодня в это трудно поверить, но в то время разработчиков и компании больше интересовали новые игры, а не сохранение «старья», фактора ностальгии ещё не было, не было большой базы фанатов и таких магазинов, как современный Good Old Games. Проиллюстрировать уровень «примитивности» контроля за исходниками можно многими историями, но, возможно, лучшей является история «ZAP SC» на 15 минуте 14 секунде:


В первый день работы один разработчик умудрился удалить всё дерево исходников Strike Commander на 900 МБ. Отдел ИТ потратил 72 часа на восстановление всего с машин разработчиков. В интервью также упоминается, что код Wing Commander 1 и 2 передавался на дискетах: до Strike Commander у них не было сети!

Интересный факт: неожиданный поворот событий — часть исходного кода недавно была найдена бывшими разработчиками Origin: Wing Commander CIC хранит офлайн-архив, в котором хранятся исходные коды Wing Commander I и Wing Commander III. Людям, работавшим над Ultima 8, анонимным источником был предложен (но отвергнут) исходный код «Ultima 8: Pagan». Что касается Strike Commander, то я никогда не слышал, чтобы у кого-то он остался.

Реверс-инжиниринг: возможно ли это?


За долгие годы многие команды успели поработать над играми Origin Systems и добились отличных результатов:

  • В Underworld II Revial воссоздана Ultima Underworld II: Labyrinth of Worlds.
  • В Exult воссоздана Ultima VII: The Glack Gate.
  • В Pentagram воссоздана Ultima VIII: Pagan (советую посмотреть код, дизайн, основанный на акторах, являющихся процессами внутри ядра, прекрасен).


Насколько долго и трудно это может быть? После общения с Грегори Монтуаром, выполнившим почти всю обратную разработку Another World, я понял, что работая по часу за вечер, можно реверсировать по 10 КБ ассемблерного кода на C за месяц. В Strike Commander много исполняемых файлов, и первоначальная обескураживающая оценка времени была такой:

INSTALL.EXE 7 793 байт : 2 недели
MKTERR.EXE 203 744 байт : 1,5 года
SC.EXE 20 000 байт : 1 месяц
MKGAME.EXE 131 696 байт : 1 год
OPTTEST.EXE 870 528 байт : 7 лет
STRIKE.EXE 746 304 байт : 6 лет
=============================================
15 лет, 7 месяцев и 2 недели. Ой-ёй.

Это расстраивало: если бы кто-нибудь начал работу в 1993 году, то закончил бы шесть лет назад, и мне достаточно было бы сделать git clone! Но запустив IDA и немного изучив файлы, я понял, что реверсировать нужно не всё: 3D-движок полностью находится в STRIKE.EXE и небольшая команда сможет справиться с ним за разумное время.

Дорожная карта


Дорожная карта, которую я изначально нарисовал для реверс-инжиниринга Strike Commander, была такой:

  1. Собрать как можно больше документации.
  2. Разобраться в глобальной архитектуре Strike Commander.
  3. Выполнить обратную разработку ресурсов игры.
  4. Задокументировать этап 3 и экстраполировать (Visual Surface Determination, Level Of Detail и т.д.)
  5. Заново реализовать 3D-движок и собрать NEO_STRIKE.EXE
  6. Добавить поддержку VR-устройства Oculus Rift.


И я приступил к работе.

Часть 2. Архитектура и документация,


Архитектура


Strike Commander не состоит из одного монолитного исполняемого файла. Для обеспечения игрового процесса совместно работают шесть исполняемых файлов. Базовая идея похожа на изученную в обзоре кода Second Reality. Можно по-разному объяснить использование нескольких EXE-файлов:

  • Оптимизация сотрудничества в команде (каждый сотрудник мог работать над своей частью, не влияя на других).
  • Программы из-за реального режима DOS были ограничены 640 килобайтами ОЗУ. Большой монолитный исполняемый файл привёл бы увеличению обмена данными с диском или он вообще бы не загружался.


После изучения в IDA оказалось, что в каждом исполняемом файле используется системный вызов DOS 21h для загрузки и запуска других .EXE. Например, сюжетный режим, обеспечивающий обработку диалогов и кинематографических вставок — это OPTTEST.EXE. Он удаляет себя из ОЗУ и загружает/запускает STRIKE.EXE, когда необходим трёхмерный режим.

Для исследования и изучения компонентов, отвечающих за каждую из частей Strike Commander очень полезным оказался DosBOX. Имя текущего запущенного исполняемого файла показывается в заголовке окна:

Исполняемый файл
Скриншот
Примечания
INSTALL.EXE
1fa34a6217cac441ff2aa5a00c97781f.png

Модуль, запускающий MKGAME.EXE
MKGAME.EXE
0b4ef037c6bc2893763db9e7a389a247.png
d4962cee81e5f6b5dddf842eac5b7185.png

Настоящий установщик:
  • Создаёт загрузочный диск.
  • Определяет звуковую карту.
  • Выполняет защиту от копирования (вопрос с ответом в журнале Sudden Death).
  • Распаковывает 8 флоппи-дисков.

MKTERR.EXE
c8e4a70957f3251eadc71cb5faa3a61d.png
ee8f226cf86631c5aeadebcce7e93bb8.png
87f7fa52d2c76b1ec3b442575852c178.png
Генератор карты, создающий все элементы карты и группирующий их в PAK:
  • ALASKA.PAK
  • ANDMAL1.PAK
  • ANDMAL2.PAK
  • ARENA.PAK
  • CANYON.PAK
  • EGYPT.PAK
  • EUROPE.PAK
  • MAPDATA.PAK
  • MAURITAN.PAK
  • QUEBEC.PAK
  • RHODEI.PAK
  • SANFRAN.PAK
  • TURKEY.PAK
OPTTEST.EXE
106ef38557d496ffa5adbf2ed482d019.png

51117cb83f01eeb824a0d4c2b33d4f03.png

f79991773ebcb124759a21491e43064c.png

Отвечает за все внутриигровые диалоги, кинематографические вставки, меню, выбор оружия в ангаре и просмотр объектов.
SC.EXE
1fa34a6217cac441ff2aa5a00c97781f.png

Способ, которым запускается игра. Обычно он загружает и исполняет OPTTEST.EXE.
STRIKE.EXE
c1f18b9abe21112f1ceaffa452d9a3f7.png

Трёхмерный движок RealSpace. Отвечает за активную фазу игрового процесса.


Примечание: если удалить архив карт PAK, STRIKE.EXE обнаружит отсутствие файла и автоматически запустит MKTERR.EXE для генерирования карты. То есть большая часть работы происходит в OPTTEST.EXE и STRIKE.EXE. Но мы ещё не разобрались, как между ними передаются параметры. Системный вызов DOS 21h позволяет использовать параметры командной строки, хранить данные в определённой странице памяти, а также состояние игры можно сохранять на жёстком диске. IDA подскажет нам, как обстоит дело в нашем случае.

Список важных файлов


Важные файлы, используемые игрой:

//Исполняемые файлы
16 -rw-r--r-- 1 fabiensanglard staff 7,793 17 Jan 03:02 INSTALL.EXE
264 -rw-r--r-- 1 fabiensanglard staff 131,696 17 Jan 03:02 MKGAME.EXE
400 -rw-r--r-- 1 fabiensanglard staff 203,744 17 Jan 03:03 MKTERR.EXE
1704 -rw-r--r-- 1 fabiensanglard staff 870,528 17 Jan 03:02 OPTTEST.EXE
16 -rw-r--r-- 1 fabiensanglard staff 7,793 17 Jan 03:09 SC.EXE
1464 -rw-r--r-- 1 fabiensanglard staff 746,304 17 Jan 03:03 STRIKE.EXE

//Ресурсы
19832 -rw-r--r-- 1 fabiensanglard staff 10,150,560 17 Jan 03:03 GAMEFLOW.TRE
952 -rw-r--r-- 1 fabiensanglard staff 485,877 17 Jan 03:02 MISC.TRE
1304 -rw-r--r-- 1 fabiensanglard staff 665,456 17 Jan 03:02 MISSIONS.TRE
13544 -rw-r--r-- 1 fabiensanglard staff 6,932,708 17 Jan 03:02 OBJECTS.TRE
1760 -rw-r--r-- 1 fabiensanglard staff 899,145 17 Jan 03:02 SOUND.TRE
3288 -rw-r--r-- 1 fabiensanglard staff 1,681,738 17 Jan 03:02 TEXTURES.TRE

//Карты
2040 -rw-r--r-- 1 fabiensanglard staff 1,042,674 17 Jan 03:05 ALASKA.PAK
2040 -rw-r--r-- 1 fabiensanglard staff 1,042,570 17 Jan 03:04 ANDMAL1.PAK
2040 -rw-r--r-- 1 fabiensanglard staff 1,042,960 17 Jan 03:09 ANDMAL2.PAK
2048 -rw-r--r-- 1 fabiensanglard staff 1,046,382 17 Jan 03:09 ARENA.PAK
2040 -rw-r--r-- 1 fabiensanglard staff 1,043,268 17 Jan 03:06 CANYON.PAK
2032 -rw-r--r-- 1 fabiensanglard staff 1,038,716 17 Jan 03:05 EGYPT.PAK
2024 -rw-r--r-- 1 fabiensanglard staff 1,033,096 17 Jan 03:07 EUROPE.PAK
656 -rw-r--r-- 1 fabiensanglard staff 333,464 17 Jan 03:02 MAPDATA.PAK
2040 -rw-r--r-- 1 fabiensanglard staff 1,044,396 17 Jan 03:03 MAURITAN.PAK
2032 -rw-r--r-- 1 fabiensanglard staff 1,037,798 17 Jan 03:04 QUEBEC.PAK
2040 -rw-r--r-- 1 fabiensanglard staff 1,043,840 17 Jan 03:08 RHODEI.PAK
2048 -rw-r--r-- 1 fabiensanglard staff 1,046,316 17 Jan 03:06 SANFRAN.PAK
2048 -rw-r--r-- 1 fabiensanglard staff 1,045,766 17 Jan 03:08 TURKEY.PAK

//Файлы начальных чисел для генерирования карт
80 -rw-r--r-- 1 fabiensanglard staff 37,732 17 Jan 03:02 MSFILES.PAK

// Палитра 3D-движка
8 -rw-r--r-- 1 fabiensanglard staff 1,806 17 Jan 03:02 PALETTE.IFF

Документация, относящаяся к Strike Commander


  • Формат архива PAK (wc1g.txt).
  • Формат архива TRE (wc1g.txt).
  • RLE, Run Length Encoding для изображений и анимаций (wc1g.txt).
  • Формат IFF (IFF.txt и A Quick Introduction to IFF.txt).
  • Аудиоформат Creative Voice (VOC) (Creative Voice (VOC) file format.txt).
  • Формат музыки Extended MIDI (XMIDI). Исходный код формата открыт его автором Джоном Майлсом (AIL2.ZIP и XMIDI.TXT).
  • Система разработки Borland DOS C++ Development System (Borland C++ Power Programming Book and Disk Programming_.pdf).
  • The Art of Assembly Language DOS 16bits edition (веб-сайт).
  • Бесплатная версия IDA (загрузка IDA5.0).
  • Руководство для плейтестеров Origin PlayerTester Guide (содержит подробности об области повреждений в самолёте) Strike Commander Playtesters Guide (1998)(Origin Systems).pdf.
  • Аэродинамические свойства реактивного самолёта, Уэйн Сайкс, Game Developer Magazine, декабрь 1994 года (GDM_December_1994.pdf).
  • Журнал Sudden Death (StrikeCommanderManual.pdf).
  • Руководство по стратегиии в Strike Commander (StrikeCommanderStrategyGuide.pdf).
  • Технический отчёт (Origin_Software_Technogoly_Entertainment_Report.pdf).
  • Брайан Хук, «Создание трёхмерного игрового движка на C++»: программирование драйверов Thrust Master (AST3D.zip).

Часть 3. Обратная разработка ресурсов.


Система архивов


Форматы PAK и TRE понятны на 100% благодаря спецификациям Марио.

  • Список файлов в архивах TRE.


Архивами легко управлять/распаковывать их с помощью TreArchive и PakArchvive в libRealSpace.

Самолёты


Самолёты хранятся в полностью укомплектованных файлах в архивах IFF. Они понятны на 95%. Состоят из четырёх ключевых частей:

  1. Аэродинамические свойства.
  2. Система повреждений и очки «жизни»
  3. Система вооружения
  4. Внешний вид
    1. Трёхмерные данные
    2. Текстуры


См. спецификации формата JET.

Карты


Карты понятны на 95%. Они хранятся в X.PAK, но также ссылаются на текстуры в TEXTURES.TRE. См. спецификации формата карт.

См. спецификации формата текстур карты.

Меню


Меню понятны на 50% (визуализация, но не логика).

Пока спецификаций нет.

Анимации


Анимации понятны на 50%:

  • Возможен рендеринг и воспроизведение отдельных слоёв.
  • Понятен выбор используемой палитры.
  • Неизвестен сборщик, объединяющий слои.


См. спецификации формата анимаций.

Палитры


Палитры понятны на 100%: см. спецификации формата палитр.

ИИ/игровая логика


Пока над ними не работали. Вероятно, все они находятся в EXE.

С учётом времени и документации, найденной в руководстве плейтестера, думаю, что там не простое дерево принятия решений. Вероятно, иерархические конечные автоматы.

См. подробное рассмотрение всех техник в книге Arctificial Intelligence for Games.

Сохранения игр


Формат сохранённых игр понятен на 75%: см. спецификации формата сохранённых игр.

Часть 4. Запускаем игру заново.


Начат проект переписывания Strike Commander. Полный исходный код можно найти на GitHub:

git clone https://github.com/fabiensanglard/libRealSpace

Движок


18211c2aa988e89f19508cfd2f598f6b.png

Самолёты/объекты


1d102e77399346a65450a5f26b717ea4.png
d24a5140910475be3efa85c04377a115.png
bfe0a662385098265ba7bc1ed47ba369.png
e672bca3f2863cdac6ed70bba4a90bda.png

Меню


9269c52fa0c3d44776b1fe71ed2f1195.png

Программа просмотра карты


7e3a465bf749f9f41c8e965a04e4f3e0.png
fafe88a40752288aab4fde2b29a3e546.png

Формат графики


b6e25db74d92f24ca9420e9f3ef541bb.png
dbf7bc013bfa088bc49265c8e943044a.png

Программа просмотра анимации


0ce786412c393802224a86d802bb6167.png
8563d736b3051563d2e6482ebe8bdb2c.png

Программа просмотра игрового процесса


Пока ничего! Я сильно надеялся, что в игре используется виртуальная машина в стиле SCUMM. Эта часть выполняется OPTTEST.EXE

Палитры


Эффекты палитры наверно будет сложно воссоздать: когда пилот испытывает слишком большие перегрузки, экран становится серым (а потом тёмным, если становится ещё больше G). Это реализовано интерполяцией между палитрами. Здесь может помочь шейдер.

e842c170d4c1f668d149981da2869f9d.png
cebdf109b1cc4df58ad5bed1ebe1807e.png

Поддержка Oculus Rift


Работа над интеграцией Oculus Rift пока не начата. [прим. пер.: последний коммит в Github проекта датирован октябрём прошлого года, так что, похоже, увы…]

© Habrahabr.ru