Переключение банков видеопамяти в Famicom/NES/Денди на примере игры Contra Force
Как я писал в статье про графическую архитектуру Famicom/NES/Денди возможности видеочипа консоли были ограничены сразу с нескольких сторон. Всё изображение обязательно состояло из четырёхцветных тайлов 8x8 пикселей и было всего два банка по 256 уникальных таких тайлов которые могли одновременно быть выведены на экран (при этом бОльшая часть изображения состояла из повторяющихся тайлов). Для игр первого поколения подобных Lode Runner или Bomberman двух этих банков видеоданных хватало на всю игру. Но с усложнением игр 512 уникальных тайлов на кадр резко перестало хватать и были изобретены мапперы переключающие банки на лету чтобы значительно увеличить разнообразие выводимого изображения.
Сегодня мы рассмотрим как переключались эти банки тайлов в первом уровне игры Contra Force чтобы увидеть как все эти технические ограничения с одной стороны обходились, а с другой влияли и в некоторых случаях даже формировали геймплей игр.
Те кто не играл в эту игру или забыл её первый уровень могут посмотреть его целиком одной картинкой по ссылке. Если браузер сожмёт картинку в один экран — просто увеличьте. Картинка очень большая.
Стартует игра где то в складской зоне порта:
Посмотрим как выглядит в этот момент содержимое банков тайлов видепамяти в эмуляторе FCEUX:
Квадратный блок слева — это банк тайлов квадратно–гнездовой сетки плиток фона, а квадрат справа — банк тайлов для подвижных спрайтов. Тайлы имеют размер 8x8 пикселей и эмулятором отображаются в сетке квадратов со стороной в 16 тайлов — каждый банк содержит их по 256 штук. В игре используется маппер MMC3 который разбивает первый банк на 2 равных зоны которые я тут обозначил как (A) и (B) и позволяет их переключать независимо. Второй же банк побит на 4 равных зоны с независимым переключением, я буду их обозначать цифрами 1–4 за исключением одного момента о котором скажу чуть позже.
Тайлы изображены в однотонной нейтральной палитре, но на экран они выводятся будучи раскрашенными в одну из восьми палитр (их видно снизу). Палитры имеют по 4 цвета первый из которых всегда чёрный (на деле — прозрачный, но если и спрайт и фон над пикселем экрана прозрачны, то он закрасится черным цветом), поэтому одновременно на экране может присутствовать не более 25 разных цветов (8*3+1).
Рассмотрим сперва банк плиток фона. В зоне (A) лежит набор тайлов которые будут неизменны на протяжении всего уровня — это облака, волнистая поверхность воды, стены, некоторые бетонные блоки и т.п. Зона (B) будет переключаться по мере прохождения уровня и сейчас в ней содержится изображения кораблей на фоне моря, всяких портовых конструкций на горизонте и тому подобное. Их видно на скриншоте выше. Но несмотря на то, что эта зона будет переключаться на другие банки памяти во всех них будут неизменными первая полоска с тайлами повсеместно встречающихся ящиков и нижняя полоска пикселей бетонных стен.
Теперь посмотрим на банк тайлов подвижных спрайтов. Первые два заняты под две вещи — изображения ног в разных фазах движения и корпусов трупов — все они едины и для врагов и для игроков, поэтому во всех вариантах переключения банков неизменно присутствуют здесь в зоне обозначенной мной как (1) (хотя она не совпадает с физическим банком (1), напоминаю что банки одинаковы по размерам — весь банк поделен на четыре четверти). Далее в зоне (2) находятся изображения выше пояса персонажей которые выбраны для игры. В игру можно играть вдвоём выбирая аватаров из четырёх возможных персонажей. Для каждой комбинации из одновременно присутствующих на экране двух героев делается переключение двух первых зон банка тайлов спрайтов. Даже если играет один игрок (как на скриншотах) вторым героем незримо присутствующим в тайлах выбирается второй по счёту персонаж — Smith.
Идём дальше — третья зона спрайтов — самая интересная. Сейчас она заполнена мусором, но именно она будет переключаться в ходе прогресса по уровню и по сути на ней и сконцентрируется наше внимание в дальнейшем.
Четвёртая зона — неизменяемая и преимущественно содержит вещи которые всегда могут появится в кадре — изображения взрывов, разнообразных пуль и снарядов, саквояжей–призов, а так же ноги одной из фаз врагов.
Вернёмся к игре и сделаем несколько шагов навстречу поджидающим нас опасностям:
Еще до того как на экране появятся враги третья зона банка спрайтов переключится на банк, который я назвал «массовка»:
Я обвёл тут третью зону пурпурным цветом и в дальнейшем буду так же делать, т.к. меняться будет только она.
Посмотрим что мы сейчас в ней имеем — изображения выше пояса боевика с пистолетом в разных фазах движения, то же самое для трёх фаз боевика с гранатой и одно изображение боевика с огнемётом. Вот эти три разных вида врагов могут одновременно присутствовать сейчас на экране и в игре у нас на следующих ста метрах появятся первые два из них. Огнемётчика мы увидим в только в самом конце уровня.
Бежим дальше и забежав в большой пустой ангар замечаем, что зона (B) банка плиток фона сменилась на следующее:
Корабли и строения на горизонте к этому моменту уже действительно отсутствуют на экране ибо их скрыли стены ангара, пробегаем чуть дальше и видимо погрузчик, который пытается задавить нас:
Здесь вообще разработчики совершили очень крутой трюк, который я даже не припомню в других играх именно в таком виде. Заметьте как я отделил пурпурным зоны выше и ниже погрузчика, а так же то, что на уровне самого погрузчика отсутствуют какие либо тайлы стен. Это великолепный пример использования техники HBlank–отсечения, погрузчик не является подвижным спрайтом — он слишком велик для этого. Он является огромным куском фона с независимым скроллингом по горизонтали и движок игры скроллит его таким образом, что создаётся иллюзия движения его как огромного объекта. Если бы на его уровне присутствовали бы еще плитки фона они бы двигались вместе с ним как одно целое и это разрушило бы иллюзию.
Идём дальше и замечаем как зона (3) спрайтов меняется на что–то новенькое:
В этом банке присутствуют изображения двух врагов — боевика с УЗИ и боевика с гранатомётом. Теперь в кадре могут присутствовать только два этих врага одновременно.
Кроме того в этот же момент зона (B) банка тайлов фона (нижняя половина) начинает циклически меняться на два варианта которые я называл для себя «технозона»:
(технозона кадр 1)
(технозона кадр 2)
Постоянная смена двух вариантов банка создаст иллюзию движения транспортёрных лент и всяческих механизмов, присутствующих в следующих двести метрах игрового поля:
А вот гранатомётчики будут встречаться нам очень недолго и зона (3) спрайтов быстро сменится на новый вариант:
Его я назвал «человек с ружьём», ибо это единственный тип врага который нам будет встречаться еще очень долго. Однако помимо него здесь присутствуют новые типы подвижных объектов — падающие и едущие по транспортёрной ленте ящики, висящие в воздухе платформы, а так же бочки, которые в одном месте попытаются нас задавить.
Далее идёт длинная полоса испытаний в середине которой, как раз после пытающихся нас задавить бочек произойдёт переключение плиток фона (B) на новый вариант с вентиляторами:
Этот новый вариант технозоны будет длится до самого конца уровня и зона (B) уже не будет переключаться.
Зато тайлы врагов переключатся на «массовку» с которой уровень начинался и здесь нам уже встретятся не только боевики с пистолетами и гранатами, но и обещанный огнемётчик:
Вот только стрелять он будет почему то не огнём, а снарядами базуки, хотя огнемётчики стреляющие огнём в дальнейшем в игре встретятся.
Преодолев остаток уровня мы добегаем до босса:
На изображения разных фаз его движения не хватит всей зоны (3) и она будет переключаться много раз в четыре разных варианта исполнения:
(Первый босс бежит)
(Первый босс прыгает)
(Первый босс делает перекат)
(Первый босс умирает)
Вот так игра Contra Force переключает банки видеопамяти в своём первом уровне и в этом ей помогает маппер MMC3B (вариант платы TL–ROM с 128Кб ПЗУ кода и 128Кб ПЗУ графических данных).
Все эти ограничения и переключения нередко диктовали сам геймплей игр — на экране одновременно не могло находится большое (под «большими» здесь понимаются числа начинающиеся с трёх) количество разных видов врагов, поэтому в многочисленных мордобоях они высыпали всегда «волнами». Выкручивались разработчики как могли, поэтому «респект им и уважуха» за наше счастливое детство.
Сегодня мы рассмотрим как переключались эти банки тайлов в первом уровне игры Contra Force чтобы увидеть как все эти технические ограничения с одной стороны обходились, а с другой влияли и в некоторых случаях даже формировали геймплей игр.
Те кто не играл в эту игру или забыл её первый уровень могут посмотреть его целиком одной картинкой по ссылке. Если браузер сожмёт картинку в один экран — просто увеличьте. Картинка очень большая.
Стартует игра где то в складской зоне порта:
Посмотрим как выглядит в этот момент содержимое банков тайлов видепамяти в эмуляторе FCEUX:
Квадратный блок слева — это банк тайлов квадратно–гнездовой сетки плиток фона, а квадрат справа — банк тайлов для подвижных спрайтов. Тайлы имеют размер 8x8 пикселей и эмулятором отображаются в сетке квадратов со стороной в 16 тайлов — каждый банк содержит их по 256 штук. В игре используется маппер MMC3 который разбивает первый банк на 2 равных зоны которые я тут обозначил как (A) и (B) и позволяет их переключать независимо. Второй же банк побит на 4 равных зоны с независимым переключением, я буду их обозначать цифрами 1–4 за исключением одного момента о котором скажу чуть позже.
Тайлы изображены в однотонной нейтральной палитре, но на экран они выводятся будучи раскрашенными в одну из восьми палитр (их видно снизу). Палитры имеют по 4 цвета первый из которых всегда чёрный (на деле — прозрачный, но если и спрайт и фон над пикселем экрана прозрачны, то он закрасится черным цветом), поэтому одновременно на экране может присутствовать не более 25 разных цветов (8*3+1).
Рассмотрим сперва банк плиток фона. В зоне (A) лежит набор тайлов которые будут неизменны на протяжении всего уровня — это облака, волнистая поверхность воды, стены, некоторые бетонные блоки и т.п. Зона (B) будет переключаться по мере прохождения уровня и сейчас в ней содержится изображения кораблей на фоне моря, всяких портовых конструкций на горизонте и тому подобное. Их видно на скриншоте выше. Но несмотря на то, что эта зона будет переключаться на другие банки памяти во всех них будут неизменными первая полоска с тайлами повсеместно встречающихся ящиков и нижняя полоска пикселей бетонных стен.
Теперь посмотрим на банк тайлов подвижных спрайтов. Первые два заняты под две вещи — изображения ног в разных фазах движения и корпусов трупов — все они едины и для врагов и для игроков, поэтому во всех вариантах переключения банков неизменно присутствуют здесь в зоне обозначенной мной как (1) (хотя она не совпадает с физическим банком (1), напоминаю что банки одинаковы по размерам — весь банк поделен на четыре четверти). Далее в зоне (2) находятся изображения выше пояса персонажей которые выбраны для игры. В игру можно играть вдвоём выбирая аватаров из четырёх возможных персонажей. Для каждой комбинации из одновременно присутствующих на экране двух героев делается переключение двух первых зон банка тайлов спрайтов. Даже если играет один игрок (как на скриншотах) вторым героем незримо присутствующим в тайлах выбирается второй по счёту персонаж — Smith.
Идём дальше — третья зона спрайтов — самая интересная. Сейчас она заполнена мусором, но именно она будет переключаться в ходе прогресса по уровню и по сути на ней и сконцентрируется наше внимание в дальнейшем.
Четвёртая зона — неизменяемая и преимущественно содержит вещи которые всегда могут появится в кадре — изображения взрывов, разнообразных пуль и снарядов, саквояжей–призов, а так же ноги одной из фаз врагов.
Вернёмся к игре и сделаем несколько шагов навстречу поджидающим нас опасностям:
Еще до того как на экране появятся враги третья зона банка спрайтов переключится на банк, который я назвал «массовка»:
Я обвёл тут третью зону пурпурным цветом и в дальнейшем буду так же делать, т.к. меняться будет только она.
Посмотрим что мы сейчас в ней имеем — изображения выше пояса боевика с пистолетом в разных фазах движения, то же самое для трёх фаз боевика с гранатой и одно изображение боевика с огнемётом. Вот эти три разных вида врагов могут одновременно присутствовать сейчас на экране и в игре у нас на следующих ста метрах появятся первые два из них. Огнемётчика мы увидим в только в самом конце уровня.
Бежим дальше и забежав в большой пустой ангар замечаем, что зона (B) банка плиток фона сменилась на следующее:
Корабли и строения на горизонте к этому моменту уже действительно отсутствуют на экране ибо их скрыли стены ангара, пробегаем чуть дальше и видимо погрузчик, который пытается задавить нас:
Здесь вообще разработчики совершили очень крутой трюк, который я даже не припомню в других играх именно в таком виде. Заметьте как я отделил пурпурным зоны выше и ниже погрузчика, а так же то, что на уровне самого погрузчика отсутствуют какие либо тайлы стен. Это великолепный пример использования техники HBlank–отсечения, погрузчик не является подвижным спрайтом — он слишком велик для этого. Он является огромным куском фона с независимым скроллингом по горизонтали и движок игры скроллит его таким образом, что создаётся иллюзия движения его как огромного объекта. Если бы на его уровне присутствовали бы еще плитки фона они бы двигались вместе с ним как одно целое и это разрушило бы иллюзию.
Идём дальше и замечаем как зона (3) спрайтов меняется на что–то новенькое:
В этом банке присутствуют изображения двух врагов — боевика с УЗИ и боевика с гранатомётом. Теперь в кадре могут присутствовать только два этих врага одновременно.
Кроме того в этот же момент зона (B) банка тайлов фона (нижняя половина) начинает циклически меняться на два варианта которые я называл для себя «технозона»:
(технозона кадр 1)
(технозона кадр 2)
Постоянная смена двух вариантов банка создаст иллюзию движения транспортёрных лент и всяческих механизмов, присутствующих в следующих двести метрах игрового поля:
А вот гранатомётчики будут встречаться нам очень недолго и зона (3) спрайтов быстро сменится на новый вариант:
Его я назвал «человек с ружьём», ибо это единственный тип врага который нам будет встречаться еще очень долго. Однако помимо него здесь присутствуют новые типы подвижных объектов — падающие и едущие по транспортёрной ленте ящики, висящие в воздухе платформы, а так же бочки, которые в одном месте попытаются нас задавить.
Далее идёт длинная полоса испытаний в середине которой, как раз после пытающихся нас задавить бочек произойдёт переключение плиток фона (B) на новый вариант с вентиляторами:
Этот новый вариант технозоны будет длится до самого конца уровня и зона (B) уже не будет переключаться.
Зато тайлы врагов переключатся на «массовку» с которой уровень начинался и здесь нам уже встретятся не только боевики с пистолетами и гранатами, но и обещанный огнемётчик:
Вот только стрелять он будет почему то не огнём, а снарядами базуки, хотя огнемётчики стреляющие огнём в дальнейшем в игре встретятся.
Преодолев остаток уровня мы добегаем до босса:
На изображения разных фаз его движения не хватит всей зоны (3) и она будет переключаться много раз в четыре разных варианта исполнения:
(Первый босс бежит)
(Первый босс прыгает)
(Первый босс делает перекат)
(Первый босс умирает)
Вот так игра Contra Force переключает банки видеопамяти в своём первом уровне и в этом ей помогает маппер MMC3B (вариант платы TL–ROM с 128Кб ПЗУ кода и 128Кб ПЗУ графических данных).
Все эти ограничения и переключения нередко диктовали сам геймплей игр — на экране одновременно не могло находится большое (под «большими» здесь понимаются числа начинающиеся с трёх) количество разных видов врагов, поэтому в многочисленных мордобоях они высыпали всегда «волнами». Выкручивались разработчики как могли, поэтому «респект им и уважуха» за наше счастливое детство.
11 комментариев
Кстати, забавно, покопал немного еще в этом направлении и подсказали сайт с фотографиями оголённых плат картриджей для Famicom/NES: bootgod.dyndns.org:7777/
Там можно наглядно убедится, что игры первой волны действительно представляли из себя просто две микросхемы ПЗУ напрямую разведенные дорожками на шины консоли.
Например японский картридж игры первого поколения — Pac-Man выглядел так:
Ни резистора ни конденсатора лишнего — всё что есть это микросхема ПЗУ в 16Кб с кодом/данными (PRG) разведенная на левую сторону контактов (адресное пространство ЦП) и ПЗУ в 8Кб с тайлами (CHR) разведенная на правую сторону контактов (адресное пространство видеочипа). Логично, но интересно было в этом убедится, ибо я в России таких картриджей даже шанса не имел увидеть, игры первого поколения дошли до меня уже только на многоигровках где мапперы не могли не быть.
Вообще сама мысль, что какой нибудь Donkey Kong мог быть единственной игрой на картридже для меня в детстве звучала бы кощунственно. xD
А как же уровень с танком в Batman — Return of the Joker?
вообще «имплантировать» огромного босса прямо в уровень — это был хайтек.
тут явно то же самое, но ей богу не играл в эту игру в детстве.
Побежал играть. :)