[Перевод] Хитрости разработки Street Fighter II

image


Часть 1: бумажный след


В конце 90-х в мир аркадных автоматов пришла Capcom. Эта компания из Осаки, казалось, создавала один хит за другим: Ghouls’n Ghosts (1988 год), Final Fight (1989 год), Street Fighter II (1991 год), не говоря уже о множестве других превосходных игр.

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

Последние шесть месяцев я тратил своё свободное время на изучение историй успеха Capcom и, в частности, истории происхождения Street Fighter II. Инженерные решения, ставшие основой CPS-1 были потрясающими, но не менее интересной мне показалась история о том, как разработчики планировали заполненность ROM при помощи бумаги и ножниц.

CP-System 101


Появившаяся в 1988 году CPS-1 (в то время называвшаяся CP-System) стала унифицированной аркадной платформой Capcom. Среди множества её инноваций был и мощный конвейер рендеринга графики.

Хотя концепция слоёв по-прежнему использовалась, в CPS-1 отказались от ограничения в виде прямоугольных спрайтов. Слой OBJ создавался из элементов 16×16, называемых «тайлами». В Street Fighter II из тайлов создаются позы персонажей. Такой подход обеспечивал большую степень свободы для художников, которые могли проектировать «объекты» произвольных размеров и форм.

image-loader.svg


Победная поза Рю (29 тайлов), поза Tiger Uppercut Сагата (30 тайлов), Поза прыжка Хонды (45 тайлов), боевая поза Чун-Ли (25 тайлов)

За исключением нескольких простейших операций типа горизонтального и вертикального переворота CPS-1 не может изменять файлы. У неё нет функций поворота или масштабирования. Выделяло эту машину на фоне остальных исключительно возможность манипулирования большим объёмом спрайтов за один кадр (сообщается, что примерно 256).

В то время такое количество движения на экране было настоящим высшим пилотажем. Успеху игры в значительной степени способствовал «вау-фактор». В играх наподобие «The Punisher» количество тайлов в позах финального босса Кингпина составляло до 80 штук.

image-loader.svg


Экран «The Punisher» мог быть почти полностью заполнен спрайтами (источник: rq87.flyingomelette.com).

Планирование объёма, занятого на ROM


Возможности CPS-1 стали благословением для художников, но оказались проблемой для менеджеров проектов. В эпоху, когда чипы ROM были очень дорогими, разработчики заранее планировали объём ROM, который нельзя было превышать.

До CPS-1 оставаться в рамках ограничений позволяло простое деление. Количество спрайтов, которое позволялось создавать команде художников, равнялось размеру ROM, поделённому на размер прямоугольного спрайта. Но из-за свободного формата возникла проблема планирования.

Система листов


Решением стали листы бумаги и ножницы.

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

Если на доске оставалось место, значит, в ROM оставалась свободная ёмкость. Поэтому дальше мы начали заполнять пробелы как пазл.

У нас случился интересный момент — мы оставили создание концовки на потом, и ко времени, когда добрались до неё, свободная ёмкость закончилась. Мы гадали, что же делать, но потом обнаружили доску, которая просто завалилась под стол.

Мы назвали это «чудом с памятью».

— Акира Ниситани, интервью о разработке SF2


image-loader.svg


Пустой лист

Так как в CP-S используется 16 индексированных цветов (4 бита на пиксель), лист из тайлов 16×16 занимает 16×16x16×16 / 2 = 32 КиБ. Например, для игры Street Fighter II: World Warrior команда разработчиков выделила под спрайты 4,6 МиБ из 6 МиБ ROM, а поэтому распечатала 144 бумажных листа.

Бумажная археология


Эта система оказалась золотой возможностью для археолога ПО. Среди прочего можно было увидеть, какие фрагменты были добавлены позже (они встраивались в оставшееся место, а поэтому выглядели менее изящно).

К сожалению, мне удалось найти только два листа. Дхалсима (Dhalsim) я обнаружил в статье «Final Fight Developer’s Interview» [1], а Рю (Ryu) — в книге «How To Make Capcom Fighting Characters» [2]

m6iyvkfd3mcziyqn1ay5q4_pmvu.jpeg


Лист 0×3300

lss-pygvs3jwwwq2ltlz2dcxbvw.jpeg


Лист 0×4500

Обратите внимание на систему адресации файлов в левом верхнем углу каждого листа (Дхалсим 0x3300 и Рю 0x4500). Первые два шестнадцатеричных символа дают значение [0–255], являющееся ID листа, а два других — это ID тайла на этом листе.

Также обратите внимание, что тайлы на листах не квадратные, а прямоугольные. CP-System использует разрешение 384×224, соотношение сторон которого отличается от соотношения 4:3 ЭЛТ-дисплея. Если бы дизайнеры рисовали по квадратам, то результат выглядел бы на экране сжатым. Рисуя по прямоугольникам, они, по сути, выполнили обратное растягивание графических ресурсов, чтобы тайлы отображались так, как были нарисованы. Эта система неквадратных пикселей стала кошмаром для команды художников.

Работая над Forgotten Worlds, я заметил проблему с соотношением сторон. «Пиксели не квадратные!», — сказал я своему начальнику.

«Это невозможно, я приказал, чтобы они были квадратными!», — ответил он и сразу же позвонил в отдел оборудования.

«Пиксели квадратные!», — сказал он.

Позже я снова запротестовал, на что начальник ответил, что это была ошибка в расчётах.

— Акира Ясуда, продюсер SF2 [3]


Ужасно разочаровывает то, что удалось найти только два листа, но мы можем воссоздать их при помощи сохранённого на ROM образа. Благодаря mame и sf2platinium, опубликовавшим формат GFX-ROM, был написан инструмент, автоматизирующий процесс. После воссоздания всех листов настало время анализа и гипотез.

Изучение листов


CPS1 работает с четырьмя листами. Слой OBJ игры Street Fighter II составлен из 144 листов общим размером 4,6 МиБ. Оставшиеся 1,4 МиБ использованы для слоёв фона и переднего плана, называвшихся SCROL1 (16 листов), SCROL2 (8 листов) и SCROL3 (23 листа).

image-loader.svg


Самые объёмные по байтам персонажи — это Зангиеф (19), за которым идут Хонда (15), Дхалсим (14, он худой, но сильно растягивается!), Бланка (15), Рю (13,5), Гайл (11), Чун-Ли (10), Диктатор (9, его плащ занимает целый лист!), Сагат (6), Боксёр (6), Коготь (6) и Кен (3).

На первом листе представлен главный герой Рю, и это неудивительно.

image-loader.svg


Обратите внимание, что верхняя часть волос Рю 0x69/0x6A была помещена в 0x6F/0x9F, чтобы не путать разбивку. Непонятно, почему смещены волосы левой верхней позы. Возможно, дело в том, что адрес 0x0000 GFX ROM невозможно использовать? Анализ других игр тоже показал, что тайл 0x0000 никогда не использовался.

Кен состоит из заплаток


Посмотрев на круговую диаграмму, мы видим, что персонаж Кен занимает невозможно малое количество листов, всего три.

image-loader.svg


Палитра Рю

image-loader.svg


Палитра Кена

Так получилось, потому что Кен — это заплатки поверх тайлов Рю. Палитра Рю специально спроектирована так, чтобы быть совместимой по оттенку кожи с Кеном. Отличаются только цвета одежды и лиц.

image-loader.svg


Фрагментарность заметна на листе 0x0100, где победная поза Рю 0x76 находится с заплаткой Кена размером 2×2 в 0x70.

image-loader.svg


Победная поза Кена начинается с позы Рю. Палитра меняется и используются только отличающиеся тайлы. Обратите внимание, что белый цвет зубов Рю взять с его одежды. У Кена художникам пришлось использовать часть цвета кожи, потому что кимоно Кена красного цвета.

Поиск фрагментов


На листе 0x4700 (в предыдущем разделе) мы видим в 0xC0 портрет размером 2×2 человека, который не является бойцом. На самом деле, это фотография команды разработки. Они перечислены в титрах в конце игры. Обратите внимание, что ни точных фотографий, ни реальных имён там нет. Возможно, так сделано, чтобы разработчиков не хантили другие компании.

image-loader.svg


image-loader.svg


image-loader.svg


image-loader.svg


Любопытный факт: «NIN» — это псевдоним продюсера Capcom Акиры Ниситани. Он использовался во всех списках рекордов во всех играх, над которыми он работал, включая Forgotten Worlds, Final Fight и Street Fighter 2.

Экономить на всём


Похоже, разработчики испытывали такой дефицит ROM, что использовали симметрию частей поз. В листе 0x4E00 левая нога Сагата отсутствует в 0xBA. Для её отрисовки CPS-1 использовала отзеркаленные по горизонтали тайлы правой ноги.

image-loader.svg

Различия в листе Дхалсима (0×3300)


image-loader.svg


Воссозданный лист Дхалсима совпадает почти идеально. Однако мы видим, что выделенная красным поза не попала в игру. Ею пожертвовали ради приёма Чун-Ли «Hundred Rending Legs», что может свидетельствовать о том, что его добавили позже. В 0x4C мы видим фрагменты, выделенные Бланке.

Различия в листе Рю (0×4500)


image-loader.svg


Похожие различия мы видим и на листе Рю. Перед выпуском игры были удалены две позы (в 0xC2 и 0xCC), чтобы уместить приём Чун-Ли «Spinning Bird Kick» (его тоже добавили в конце разработки?) и портреты команды для титров.

Как долго использовалась система листов?


Учитывая наличие в то время мощных рабочих станций наподобие X68000, мне всегда было любопытно, как долго использовалась система листов до того, как написали инструмент для сборки ресурсов GFX. Благодаря возможности изучения листов других игр это можно было приблизительно прикинуть.

Первым делом стоило посмотреть на все игры, созданные той же командой, начав с проектов, выпущенных до SF2, Forgotten World и Final Fight. Хотя у меня не было времени искать палитры и я использовал стандартные градации серого, всё равно можно чётко увидеть формы.

image-loader.svg


Листы Forgotten World (1988 год) и Final Fight (1989 год)

Неудивительно, что используется та же структура. Позже я проверил и другие игры, например, Street Fighter 2: Champion Edition и Street Fighter 2: Hyper Fighting. GFX минимально усовершенствовался [4], а структура листов осталась неизменной.

image-loader.svg


Листы Street Fighter 2: Champion Edition (1992 год) и Street Fighter 2: Hyper Fighting (1992 год)

Другие команды Capcom


В Capcom разными командами параллельно разрабатывалось множество игр. Посмотрев на работу других команд, отвечавших за Ghouls 'n Ghosts и Strider, я снова увидел тот же процесс.

image-loader.svg


Листы Ghouls 'n Ghosts (1988 год) и Strider (1989 год)

Игры, созданные не Capcom


Некоторые игры для CPS-1 были созданы не Capcom. Например, Pang-3 компании Mitchell Corporation. Тут тоже нет никаких изменений.

image-loader.svg


CPS-2 и Super Street Fighter 2


Похоже, система листов использовалась в большинстве, если не во всех играх для CPS-1. Изучать игры для CPS-2 было чуть сложнее, потому что Capcom добавила множество механизмов защиты. Хотя команды 68000 и команды Z-80 были зашифрованы, GFX ROM были просто перемешаны и их легко можно просмотреть.

В первой игре для CPS-2, Super Street Fighter 2 (1993 год) к имевшимся двенадцати персонажам были добавлены ещё четыре новых. Листы старых персонажей не изменились.

image-loader.svg


Листы Рю и Кэмми из Super Street Fighter 2 (1993 год)

Но если посмотреть на листы Кэмми (0x9000), то видно, что структура создана не вручную. Похоже, вместо этого была использована система размещения, движущаяся сверху вниз и слева направо. Наверно, примерно в 1992 году Capcom начала использовать инструменты для создания новых GFX ROM в SSF2. Неизвестно, применялись ли рабочие станции x68000.

Street Fighter Alpha


Другие игры для CPS-2, Street Fighter Alpha (1995 год) и Street Fighter Alpha 3 (1998 год) тоже имеют такую же структуру, то есть применялся тот же инструмент. Все листы выглядят как пюре, в котором нет ни одного свободного тайла. С большой вероятностью, ни одна из игр для CPS-2 не использовала систему листов.

image-loader.svg


Просьба об интервью


Я предпринял множество попыток поговорить с разработчиками, работавшими над системами CPS-1/CPS-2. Но все они пока завершились провалом. Я хочу задокументировать и сохранить информацию о том, как программировали эти машины. Особенно любопытно мне то, как использовалась X68000. Если вы сами или ваши знакомые работали со всем этим, то напишите мне!

Ссылки


[1] Final Fight Developer’s Interview

[2] How To Make Capcom Fighting Characters

[3] Twitter-аккаунт Akiman

[4] Differences Between SF2 World Warrior and SF2 Champion Edition

Часть 2: невозможное вращение


Как мы узнали в предыдущей части, оборудование, на котором работал Street Fighter 2 — это тайловый движок, способный отражать тайл по вертикали или горизонтали и не имеющий возможности смешивания. Для игры наподобие Street Fighter II это было проблемой, потому что режим привлечения игроков содержал вращающийся логотип с отображением под ним просвечивающего текста «World Warrior».

Если вы видели автомат в 1991 году, то можете помнить, что эффект выглядел странно, но было трудно сказать, в чём дело, потому что логотип вращался очень быстро, а ЭЛТ-дисплей немного всё размазывал.

image-loader.svg


Воссозданный режим привлечения игроков «вращение и зум».

При помощи программы просмотра листов мы можем взглянуть на GFXROM. Использованные в логотипе тайлы можно найти в листе 0x8200.

image-loader.svg


Как и ожидалось, мы видим две версии графики, маленькую и увеличенную. Но как их использовали?

MAME спешит на помощь


Благодаря современным технологиям мы можем замедлить анимацию. MAME может записывать попиксельно чёткую последовательность изображений в формате mng, чтобы мы могли изучить каждый кадр по отдельности.

$ mame sf2 -mngwrite sf2.mng
image-loader.svg


Внимательно изучив каждый кадр, мы можем определить следующее:

  • Маленький логотип движется вниз, чтобы оставить достаточно места под большой.
  • Логотип вращается дважды.
  • После первого вращения маленький логотип заменяется большим.
  • Тайлы не отражаются по горизонтали или вертикали. Их позиции просто вращаются вокруг центра логотипа.
  • Просвечивание достигается отрисовкой текста через кадр.
  • При достаточно быстром движении эффект визуально «приемлем».


Другие вращения и масштабирования в Street Fighter II


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

Экран 1:

image-loader.svg


Здесь масштабирование выполняется «накладыванием» тайлов один поверх другого с постепенным раздвижением.

Экран 2:

image-loader.svg


Любопытный факт: обратите внимание, что спрайты бойцов возникают на один кадр после фона. Так получилось потому, что CPS-1 использует кадровый буфер спрайтов, откладывающий обновление слоя спрайтов на один кадр.

Экран 3:

image-loader.svg


Экран 4:

image-loader.svg


Эффект в Street Fighter 2: Champion Edition


Годом позже, в марте 1992 года, Capcom выпустила сильно улучшенную версию под названием «Champion Edition». По этому случаю режим привлечения игроков был переделан.

Логотип больше не вращается, и вместо этого имитирует уменьшение и увеличение масштаба.

image-loader.svg


Переход от маленького логотипа к большому происходит, когда все тайлы собраны в одной точке. Это гораздо более реалистично, чем эффект в SF2: WW.

Street Fighter 2 Hyper Fighting


Последняя игра, выпущенная на CPS-1 (после которой Capcom перешла на CPS-2) — это Street Fighter 2 Hyper-Fighting (декабрь 1992 года).

image-loader.svg


Режим привлечения игроков за исключением текста не особо изменился. От анимации текста полностью избавились и осталось только масштабирование логотипа.

Взгляд на другие платформы


image-loader.svg


Спустя год после выпуска на аркадных автоматах Capcom издала 15 июля 1992 года порт для Super Nintendo. Компания проделала отличную работу, ей удалось сохранить всех персонажей, движения и красивые графические эффекты, несмотря на то, что консоль имела гораздо меньшую ёмкость памяти и разрешение.

Как ни удивительно, но благодаря Mode 7 + HDMAA консоли SNES ей удалось отрендерить более красивый эффект вращения.

Для небольшого просвечивания был использован простой дизеринг с колебаниями.

И снова благодаря MAME мы можем просмотреть всю анимацию кадр за кадром.

$ mame snes -cart "sf2.zip" -mngwrite sf2snes.mng


image-loader.svg


Часть 3: Досадная опечатка


Одна из моих любимых историй о Street Fighter II — это рассказ Akiman о проблеме, обнаруженной незадолго до выпуска.

Всего за три дня до дедлайна я обнаружил нечто ужасное. Я сделал ошибку в подзаголовке «World Warrior», написав его «World Warrier».

— Akiman, ведущий графический дизайнер SF2 (перевод Shmuplation)

image-loader.svg


Воссоздание проблемы. Ой!

Чтобы полностью понять проблему, нам нужно разобраться, как работает оборудование аркадного автомата. CPS-1 — это супермашина для отрисовки тайлов. Она может отрисовывать кучу тайлов, но не способна их изменять. Они берутся из GFX ROM в неизменном виде и отправляются на экран (хотя их можно отражать по горизонтали или вертикали).

GFX ROM и ROM с командами процессора 68000 прожигаются по отдельности. Описанная Akiman проблема заключалась в том, что GFX ROM уже был записан, но он всё ещё мог вносить изменения в команды.

Но как устранить ошибку, если графика уже останется неизменной?

Теперь я могу спокойно рассказывать эту историю, но на самом деле мы обнаружили только через много месяцев после того, как вся работа над спрайтами была завершена. Так как логотип уже был создан, я не мог просто изменить в нём букву.

«Возможно, я смогу заставить её выглядеть как «o», — подумал я; начал пробовать накладывать разные другие спрайты, пока наконец она не стала похожа на «o». Какое облегчение!

— Akiman, ведущий графический дизайнер SF2 (перевод Shmuplation)


Всё дело в деталях


Это описание решения заставило меня поискать подробности. Как он превратил «e» в «o»? Так как у меня был инструмент извлечения листов, я поискал текст; логотип и опечатка нашлись на листе 0x7B00.

image-loader.svg


Логотип отрисовывался при помощи 16 вызовов отрисовки, использующих тайлы 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE и 0xDF.

image-loader.svg


Akiman решил эту проблему, подойдя к делу практично. Он заметил, что в слове «World» есть слог «or», который должен поместиться вместо «ier». Поэтому от отбросил последние три тайла 0xDD, 0xDE и 0xDF, заменив их на 0xCD и 0xCE.

image-loader.svg


Ситуация улучшилась, но таким образом он перенёс проблему в другое место, потому что позаимствованная правая палка «W» выглядела как «l», а не как«i». На логотипе теперь было написано «The World Warrlor».

На этом этапе ему нужно было найти способ разрезать верхнюю часть «l», чтобы она выглядела как точка буквы «i», но как это сделать, если 68000 не может выполнять запись в тайл?

Гайл спешит на помощь


Последним куском пазла стали икры ног Гайла. Если приглядеться к тайлу 0x96, то можно заметить, что у него виден только один пиксель в левом нижнем углу.

image-loader.svg


Ранее я не упоминал кое-какую особенность: управление палитрами полностью находится под контролем 68000. Процессор может отправить команду отрисовки тайлов, использовав для этого любую нужную палитру.

image-loader.svg


Палитра Гайла

image-loader.svg


Палитра World Warrier

Зелёная палитра Гайла бесполезна, так как в логотипе используются синие цвета. Но если сравнить их, то можно заметить, что индекс 14 в палитре Гайла тёмно-зелёный, а в палитре логотипа — тёмно-синий.

Использование тайла 0x96 с палитрой логотипа позволяет процессору 68000 создать систему (очень затратную) в которой 255 пикселей тратятся на прозрачность, зато 256-й можно использовать в качестве карандаша.

Этот тайл-карандаш используется для отправки трёх команд отрисовки с координатами, накладывающимися на «l». По сути, это создаёт линию, перерезающую верхнюю часть и превращающую её в точку буквы «i».

image-loader.svg


Так что если вы всё это время задавались вопросом, почему «i» в слове «Warrior» выглядит странно, то теперь знаете ответ.

image-loader.svg


Эпилог


Опечатку исправили в последующих версиях Street Fighter 2, где в наборе тайлов «World Warrior» появилось правильное сочетание «IOR».

image-loader.svg


Забавно, что их не использовали, потому что подзаголовок сменился с «World Warrior» на «Champion Edition», а потом на «Hyper-fighting».

Часть 4: точная анимация полосы здоровья


Проблема


Если вы прочитали предыдущие части, то вам совершенно ясно, что машина, на которой работал Street Fighter II, могла обрабатывать только тайлы, составленные из 16×16 пикселей. Помня об этом, посмотрите короткий фрагмент геймплея. Вы обратите внимание на нечто странное, невозможное.

image-loader.svg


«Полоска здоровья» противника анимирована плавно и попиксельно. Как такое возможно? Если бы разработчик работал с тремя тайлами (один для «края», один для «полного здоровья» и один для «пустого здоровья»), то полоски здоровья из двенадцати тайлов менялись бы только с инкрементом в 16 пикселей.

image-loader.svg


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

Точное отслеживание здоровья


Изучение листов игры показывает, как программистам Capcom удалось заставить систему работать плавно. Тайлы полоски здоровья находятся в листе 0x81.

image-loader.svg


Мы видим здесь не три, а двенадцать тайлов, что доказывает, что многие проблемы можно решить добавлением ОЗУ или места на накопителе.

Промежуточные состояния тайла заранее отрендерены в строке OxF0. Эти дополнительные тайлы обеспечивают попиксельно точную анимацию полоски здоровья.

image

© Habrahabr.ru