
Поддержка The Neverhood добавлена в ScummVM

Несколько дней назад, 15 мая, в ScummVM, известный кроссплатформенный набор игровых движков для point-and-click adventure, была добавлена ветка кода с движком, который поддерживает классику квестового жанра, игру The Neverhood.
Это был один из самых захватывающих и длинных проектов в ScummVM. Разговоры об этом шедевре продолжались в течение нескольких лет, и на форумах регулярно просили добавить поддержку этой игры. Два года потребовалось на разработку движка, и я хочу коротко рассказать, как это происходило.
Стоит заметить, что добавление игры в ScummVM, это совсем не простая задача. На сегодня примерно для половины движков нам удалось получить исходники от авторов, но даже в этих случаях код всегда нужно переписывать. Так, в последнее время в проект поступает довольно много игр, написанных изначально на Паскале и Ассемблере, и чтобы их добавить, всё нужно транслировать в С++. Другая же половина движков получилась путём хардкорного реверс инжиниринга (по-другому и не скажешь), когда на вооружение берётся IDA, и мы потихоньку начинаем размечать оригинальный движок названиями функций, переменными и комментариями, слой за слоем разбираясь в логике его работы.
Именно второй подход и был вынужденно использован с The Neverhood. Попытки связаться с авторами особо не увенчались успехом, руки чесались, и в июне 2011 года проекту был дан старт.
Хроники проекта
Исходные данные:
* 800 кб бинарного кода
* Оригинал на С++
* 7,2 тысячи функций
* 340 виртуальных классов
Через два года работы двух человек получен результат:
* 36 тысяч строк кода
* 2 тысячи методов
* 320 классов
Первый коммит был прост:
Author: johndoe Date: Wed Jun 22 22:58:51 2011 +0000 NEVERHOOD: First code with basic detection, nothing else so far
Этот скелет по сути стандартен, и разработка каждого движка обычно с него и начинается. О, сколько попыток отреверсить игру для ScummVM на этом и заканчивалось! Но не в этот раз, не в этот раз. Уже через два дня был написан код для доступа внутрь BLB архивов, а спустя ещё два дня декодируется графика и начата работа над Module1500, вступлением к игре.
Нас не остановило то, что игра является хардкодом. БОльшая часть движков для приключенческих игр, поддерживаемых ScummVM, являют собой виртуальные машины (об этом можно писать отдельный пост), и их структура является не слишком сложной. Иногда же оригинальные разработчики пишут скрипты игры прямо на языке программирования, что увеличивает объём и сложность работы по реверсингу в десятки раз. Особо сложной является работа с C++. Компиляторы этого языка часто используют продвинутые оптимизации, также виртуальные классы трансилруются в ассемблер как неявные вызовы, что доставляет ещё больше головной боли. Также не упрощает работу тот факт, что IDA и Hex-Rays ещё не умеют толком работать с плюсами и приходится использовать много костылей.
Тем не менее, 4 июля заработала начальная заставка игры. Хотя она из себя представляет набор роликов в формате Smacker, однако даже для этого было необходимо реализовать систему сообщений, обновление экрана, обработку клавиатуры, затемнение палитры, переход между сценами, в общем, написать почти 3 тысячи строк кода. Через неделю была закончена первая сцена, и начата работа над второй сценой игры, Scene1002.
Далее сцены добавлялись одна за другой, каждую неделю. К слову, их в игре всего 71.
К середине сентября 2011 года, когда примерно половина сцен были реализованы, стартовала работа по рефакторингу. Оригинальный код, как и ожидаемо, содержал довольно много лапши. Стандарты же ScummVM довольно высоки, и для повышения качества кода мы всегда работаем над улучшением структуры, а часто и архитектуры оригинальных движков. Neverhood тут не исключение, были добавлены генераторы объектов, обёртки и многие функции были слиты вместе.
Работа практически не велась с января по июль 2012 года, а в августе были добавлены ещё дюжина сцен и начата работа над звуком. В Neverhood звук закодирован своим, самописным RLE кодировщиком, и требуется одновременное воспроизведение до трёх звуков помимо фоновой музыки. К началу октября, соответствующие вызовы добавлены во все сцены игры, и мы начали внутреннее альфа-тестирование.
После второй волны рефакторинга, когда была выкинута значительная часть дублирующегося кода, и движок сильно «похудел», началась подготовка ветки к слиянию с основным кодом ScummVM. Для этого было необходимо добавить меню, финальные титры, комнату Hall of Fame, а также запись и восстановление состояния игры.
21 января 2013 года, через полтора года разработки, до нас внезапно дошло, что оригинального героя таки зовут Klaymen, а не Klayman, как это было бы логично в соотетствии с грамматикой английского языка, и за этим озарением последовало массовое переимнование переменных и классов в коде.
Ещё немного рефакторинга, исправления багов, и 5 мая 2013 года был сделан Pull Request в основную ветку ScummVM.
Вот она, история проекта.
Коротко о будущем
Работа над движком далеко не завершена. Теперь необходимо убедиться, что игра работает на всех поддерживаемых платформах, в частности, на big-endian ARM.
Также пока, к сожалению, русские версии игры не поддерживаются, так как наши переводчики, как это часто бывает, слегка поменяли форматы там и сям, и движок в ScummVM падает после начальной заставки. Мы как раз сейчас над этим работаем. Возможно, что мы поработаем и над добавлением поддержки PSX версии игры.
Необходимо ещё сделать некоторую работу по рефакторингу, в частности, убрать глобальные конструкторы, которые суть зло. И, наконец, объявить о публичном бетта-тестировании.
Ссылки:
Сайт проекта ScummVM, для того, чтобы запустить The Neverhood, нужен daily build версии 1.7.0
Исходный код движка
Как запустить игру
Игру нужно скопировать с оригинального диска, нажать в ScummVM кнопку Add Game, указать путь, куда скопирована игра, и далее игра появится в списке (пока работает только английская версия и демо). Далее, двойной щелчок по названию игры, игра запустится.
Демо можно скачать отсюда. Купить полную игру можно на eBay, Amazon, также ещё попадаются на полках наших магазинов русификации.
Комментарии 92
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.