Полноэкранная графика на NES

Пользователи ZX Spectrum и других домашних компьютеров 80-х привыкли к красочным полноэкранным заставкам, показываемым во время загрузки игры. Сама возможность отображения таких заставок им справедливо кажется естественной. И казалось бы, такая довольно мощная для своего времени игровая система, как NES, должна с лёгкостью с этим справляться — ведь показывает же она во время игры прокрутку полного экрана с крупными спрайтами со скоростью 50/60 кадров в секунду. Однако, если задуматься, можно вспомнить, что полноэкранные заставочные картинки едва ли встречались в играх, а по большей части это был чёрный экран с относительно небольшим по площади изображением. Конечно же это не случайно. Углубимся в тему.



Как вам наверняка известно, изображение слоя фона на NES строится из блоков 8x8 пикселей (тайлов), память графики которых находится в отдельном адресном пространстве видеоконтроллера, с отдельными от основного процессора шинами адреса и данных, заведёнными на разъём картриджа. В один момент времени видеоконтроллер может адресовать всего 8 килобайт графической памяти плюс 4 килобайта тайловых карт и палитру. Это даёт два набора по 256 тайлов (один тайл 16 байт, два бита на точку). Каждый из наборов может быть назначен для отображения графики спрайтов или фона. Спрайты могут использовать и оба набора одновременно (режим 8x16), но фон — всегда только один набор. Таким образом, если не применять трюков, можно отобразить картинку, состоящую только из 256 разных тайлов. Экран имеет размер 32x30 — 960 тайлов, значит 256-тайловый набор покрывает меньше трети экрана.

Также присутствуют ограничения по цвету — похожие на атрибуты знакомест на ZX Spectrum. Местные атрибуты тоже задают цвет графики в пределах своего блока, только размер блока 16x16 пикселей, а графика двухбитная, но трёхцветная — нулевое значение 'прозрачное'. Атрибуты позволяют назначить блоку одну из четырёх трёхцветных палитр, плюс общий для всего экрана цвет фона. Таким образом, для слоя фона доступно 13 цветов одновременно, плюс отдельные 12 цветов для спрайтов.

Двухбитная картинка Картинка с атрибутами Инверсные атрибуты Набор тайлов

Двухбитная картинка, раскраска атрибутами, инверсия атрибутов для их лучшей заметности в примере, набор тайлов.



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

Galaxian
Типичный пример титульного экрана ранней игры без маппера. Здесь логотип занимает около половины одного из двух наборов графики.

Battletoads Teenage Mutant Ninja Turtles 2
Пара примеров, обходящихся относительно небольшим логотипом с чёрным фоном. Логотип занимает один набор почти целиком.

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

Deja Vu Top Gun Power Blade
Попытки сделать более эффектную и визуально крупную графику за счёт использования заливок одноцветными тайлами.



В очень многих играх используется подход 'один набор графики фона плюс спрайты'. В режиме спрайтов 8x8 можно отобразить дополнительные 64 тайла из другого набора, а в режиме 8x16 — даже 128 тайлов. Однако, при этом надо учитывать ограничение в восемь спрайтов на строку растра. Поэтому спрайтами много деталей не добавить. Зато их использование позволяет уменьшить цветовые ограничения — как обойти атрибутную сетку, так и увеличить количество отображаемых цветов, задействуя палитры спрайтов. Чаще всего спрайты на заставках применялись именно для этого, иногда их графика находится в том же самом 256-тайловом наборе, что и графика фона.



Chip 'n Dale Слой фона Спрайты
Графика фона и спрайтов в одном наборе. Спрайты используются для улучшения цветовой детализации.

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

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

Darkwing Duck Слой фона Спрайты
Детальный логотип с однотонными заливками на фоне занимает целый набор тайлов, герой выводится спрайтами из отдельного набора.



Почему более серьёзные попытки обойти ограничения были редки? На мой взгляд, основная причина в рентабельности. Настоящая полноэкранная картинка, в которой нет повторяющихся тайлов, займёт почти 16 килобайт, или почти четыре набора по 256 тайлов. А один набор — это, например, ещё один уникальный набор тайлов фона для уровня игры, а то и нескольких. Свободное место в играх оставалось очень редко (редкие исключения — Alien 3, Robocop 3), так как изначально выбирался минимально достаточный объём памяти, и его старались экономить, например, используя одну и ту же графику с разными палитрами на разных уровнях.

Можно предположить, что хорошее сжатие данных позволило бы обойти ограничения по памяти. Но на NES для того, чтобы графику можно было упаковать, необходимо использовать в качестве видеопамяти на картридже ОЗУ вместо ПЗУ, и хранить графику в ПЗУ кода. Само по себе это встречалось часто (Contra, Battletoads), но объём внешнего видео-ОЗУ был ограничен 8 килобайтами, что даёт те же 512 тайлов одновременно. Переслать в видеопамять дополнительные тайлы во время отображения кадра просто не получится — заранее распаковать их некуда, так как объём основного ОЗУ всего два килобайта, скорости процессора для распаковки на лету никак не хватит, к тому же нет доступа к видеопамяти во время отображения растра.



Обойти ограничение на количество тайлов фона и отобразить больше 256 тайлов, включая действительно полноэкранную картинку, конечно можно. Для этого нужно использовать маппер и ПЗУ графики, а также программный трюк — в нужный момент прохода луча по растру средствами видеоконтроллера и/или маппера переключая набор тайлов.

Такие трюки типичны для NES, они нередко используются и во время игрового процесса, например, чтобы отобразить фон уровня и панель статуса. Главная сложность в том, чтобы дождаться нужного момента. Это может быть сделано точно рассчитанной фиксированной задержкой, ожиданием в цикле установки флага 'нулевого спрайта' — когда луч доходит до спрайта с индексом 0, непрозрачные пиксели которого накладываются на непрозрачные пиксели фона — или превышения лимита спрайтов на строку, либо использованием строчного прерывания. Первые два варианта тратят время процессора впустую, третий требует наличия генератора прерываний в маппере, который встречался только в наиболее продвинутых ASIC-мапперах (MMC3, FME-7), что опять поднимает вопрос рентабельности.

При необходимости нескольких переключений за кадр только на ожидание флагов спрайтов рассчитывать нельзя, они срабатывают всего один раз за кадр. Остаются прерывания или фиксированная задержка. В последнем случае нужно дополнительно учитывать использование канала DPCM — при его работе чтение сэмплов тормозит процессор, сбивая фиксированные тайминги, что может привести к нестабильному артефакту в месте смены наборов. Способы обойти эту проблему — делать в месте переключения банков несколько одноцветных строк, либо делать место переключения банков 'внахлёст', повторяя нижнюю строку тайлов одного набора в верхней строке другого.



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



Wrestlemania Challenge. Игра использует маппер UNROM с ОЗУ графики, поэтому графика фона и спрайтов помещается в двух наборах. Нулевой спрайт представляет собой полоску из двух пикселей в нижней части буквы G в слове Challenge.

Wrestlemania Challenge
Полная картинка.

Второй набор Первый набор
Первый и второй наборы тайлов фона.

Спрайты Нулевой спрайт
Слой спрайтов и нулевой спрайт на нём, обведённый зелёным прямоугольником.



Battletoads and Double Dragon того же разработчика использует аналогичный принцип, но на этот раз маппер ANROM, схожий с UNROM. На титульном экране играет музыка с оцифрованными ударными высокого качества, воспроизводимыми силами процессора, а не DPCM, что несколько усложняет код, но не меняет принцип. Нулевой спрайт представляет собой одиночный пиксель с координатами 201,86.

Battletoads Double Dragon
Полная картинка.

Первый набор Второй набор Спрайты
Два набора тайлов фона и слой спрайтов.



Robocop 3 использует маппер MMC1 и ПЗУ спрайтов. Графикой фона заполнено два банка (512 тайлов). Часть девочки, лицо героя и пункты меню выводятся спрайтами, находящимися в отдельном, третьем банке. Нулевой спрайт — полоска в середине изображения девочки.

Robocop 3
Полная картинка.

Первый набор Второй набор
Первый и второй наборы тайлов фона.

Спрайты Нулевой спрайт
Слой спрайтов и нулевой спрайт на нём, обведённый зелёным прямоугольником.



В качестве бонуса — карты использования памяти для этих трёх игр. Они демонстрируют, что обычно в играх на NES едва ли найдётся лишний байт, хотя бывают и исключения.

Wrestlemania Challenge

Battletoads Double Dragon

Robocop 3



Отдельно надо сказать о трюке, часто встречающемся на других платформах — обновлении палитры во время отображения кадра, что даёт возможность отобразить больше цветов на экране, чем позволяет размер палитры. К сожалению, видеосистема NES устроена таким образом, что изменить содержимое палитры при включённом отображении без видимых артефактов очень сложно — адрес записи в видеопамять также используется как один из счётчиков для схемы отображения. Нужно успеть обновить палитру за время горизонтального гашения, попадание в которое осложняется джиттером и работой DPCM, после чего восстановить текущую позицию отображения. Времени хватит на изменение всего одной-двух ячееек палитры, плюс для скрытия артефакта придётся выключить отображение на время всей последующей строки. Поэтому трюк редко встречался в коммерческих играх, при этом области с разными палитрами разделены одной-двумя пустыми строками.



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

Маппер MMC2/MMC4 (две вариации одного маппера) был специально разработан для обхода ограничения на количество тайлов фона. Он позволяет отображать до 512 тайлов, переключаясь между двумя наборами в любом месте тайловой карты, используя два тайла в качестве кода переключения набора. Использовался он всего в 4 играх, причём применение было совершенно не впечатляющим — для отображения текста и портретов персонажей одновременно с картой в трёх стратегических играх, а также портретов противников и некоторых игровых элементов в Punch-Out.

Punch-Out
Переключение банков используется только для отображения портрета персонажа справа.

Fire Emblem
Переключение банков используется для портрета персонажа и текста в окне.

MMC5 — самый мощный из всех существующих мапперов, значительно расширяющий графические и звуковые возможности NES. Позволяет отображать до 16384 тайлов на экране, одновременно уменьшая размер атрибута до 8x8 (своя палитра для каждого тайла). Использовался в полутора десятках игр, но его потенциал не был раскрыт нигде, в частности для вывода полноэкранных картинок он не применялся.

Uncharted Waters
Несмотря на потенциал маппера, графика мало отличается от других игр.



Мы рассмотрели историю. Сейчас, когда разработкой занимаются только энтузиасты, дела обстоят иначе. Вопрос рентабельности больше не стоит, а ПЗУ небольшого объёма найти стало даже труднее, чем большого. При желании можно использовать даже десятки мегабайт, такой маппер реально существует — очень похожий на UNROM, но защёлкивающий шину адреса вместо шины данных. Программируемая логика открывает возможность создания новых сложных мапперов, сравнимых с MMC5 или превосходящих его. Всё это позволяет использовать ранее малодоступные способы обхода ограничений.

Была реализована очевидная возможность вывода полноэкранных картинок трёхкратным переключением наборов тайлов во время прохода луча по растру. Делались эксперименты и с переключением между двумя экранами аналогично Gigascreen на ZX Spectrum, что может рассматриваться либо как повышение цветового разрешения на точку, либо как увеличение вертикального разрешения. Всё, что для этого нужно — большое ПЗУ графики либо 16 килобайт ОЗУ графики с поддержкой переключения банков.

Было реализовано повышение цветового разрешения за счёт уменьшения высоты атрибутов — аналогично мультиколору на ZX Spectrum. Это делается использованием двух копий тайловой карты, отличающихся областью атрибутов. При отображении кадра каждые 8 строк происходит переключение между тайловыми картами, таким образом вертикальное цветовое разрешение увеличивается вдвое, уменьшая размер атрибута до 16x8.

Примеры достижимого этими способами уровня графики можно увидеть с помощью NES Image Converter 2, позволяющего конвертировать изображения в форматы 256x240 (без мерцания), 256x480 или 512x240 (с мерцанием), с атрибутами 16x8.

Конечно, на практике подобные программные способы обхода ограничений в основном пригодны для статичных изображений и мало востребованы в играх.

Аппаратный подход также открывает новые возможности. При применении дополнительного ОЗУ для тайловых карт, которое крайне редко встречалось в коммерческих играх (4 игры), можно получить дополнительные две тайловые карты, а значит, увеличить цветовое разрешение предыдущим методом в четыре раза, получив атрибуты 16x4. Также возможно создать маппер, сочетающий возможности MMC5 и дополнительное ОЗУ тайловых карт, что позволит уменьшить атрибуты до 8x4. С ещё более сложным маппером можно достичь предельного цветового разрешения 8x1. Пока подобные расширения реализованы не были.



В заключении пара слов о 'неспектрумах'. В статье рассмотрены только способы обхода графических ограничений, преполагающие, что железо самой приставки не подвергается никаким изменениям. Но существуют и примеры обратного подхода — расширение возможностей самой приставки. Например, в середине 2006-х это было сделано китайскими инженерами, разработавшими набор чипов VT03, на котором построено небольшое количество клонов тех лет. В них, помимо прочего, доступны режимы расширенной графики с 16-цветными тайлами и спрайтами. До сих пор доступен сайт разработчика, где можно найти документацию на английском языке и даже эмулятор. Диаметрально противоположный вариант — Hi-Def NES, адаптер, устанавливаемый в оригинальные приставки и добавляющий HDMI-выход с опциональным сглаживанием HQx, все дополнительные звуковые чипы и многие другие возможности, обычно присущие эмуляторам. В некотором роде этот проект стирает грань между реальным железом и эмуляторами.

17 комментариев

avatar
Shiru Очень интересная и полновесная статья! В отличии от наших спектрумовских друзей я понимаю все ньюансы, т.к. две игры всё таки сделал на NES. Однако всё равно много нового узнал. Спасибо!
avatar
Спасибо, обалденная статья, прочитал на одном дыхании. Я давно почитываю о NES, поэтому все оказалось более чем понятным, да и написано доходчиво очень.
Захотелось что-нибудь попробовать нарисовать, я всё же старый фанат приставки. А есть ли какой-то сайт с коллекцией заставок для NES?
avatar
Полной коллекции наверное пока нет нигде, но я когда подбирал примеры для статьи, попалась такая подборка, там довольно много: nestitlescreens.tumblr.com/. И ещё некоторое время назад нашумело видео PRESS START, почти три часа титульных экранов: www.youtube.com/watch?t=1267&v=iOvaSOFLtJU
avatar
Обалденная подборка, спасибо!











avatar
А как простите вот это тогда сделано? Тут явно не повторяющиеся тайлы, а дизеринг а-ля Флойд-Штейнберг и все это больше чем полэкрана.

avatar
Отличный вопрос. Японская версия этой игры — эксклюзив для Famicom Disk System, у которой всего 8 килобайт видео-ОЗУ, так что на картинке принципиально не может быть больше 512 тайлов, с переключениями в середине кадра, аналогично Wrestlemania и другим примерам. На самом деле здесь всего 452 уникальных тайла, примерно половина экрана. Просто возникает такая вот иллюзия, вероятно за счёт рамки из одинаковых тайлов и надписей внизу.

А вот картриджная американская версия имеет куда как менее эффектный титульный экран, так как место на картридже дороже условно-бесплатного на дискете:

Mystery Quest
avatar
К сожалению NES никак не привлекает, больше тянет на Атари, Коммодор и Амстрад, но все равно очень интересно написано, прям исчерпывающе! Спасибо за наглядные скриншоты с раскладками по тайлсетам!
avatar
Больше платформ, хороших и разных. Считаю, было бы здорово, если бы кто-то, хорошо разбирающийся в этих платформах, тоже поделился здесь своим опытом. У меня есть только ограниченный и давний опыт по C64, рассказать особо нечего, а Atari мне очень нравится (есть 130XE), но сам ничего не делаю и в дебри особо не лезу (кроме 2600, но это опять приставка).
avatar
Отличная статья, очень интересно! Автору — респект
avatar
Доступно, наглядно, познавательно!
+100 за прекраснейший материал!
avatar
Годно! Далеко не очевидная история с проблемой полного экрана, которая накладывает вполне себе конкретную визуальную стилистику на всю платформу.
avatar
Практически все моменты устройства видеосистемы на NES определяют узнаваемую визуальную стилистику, которую легко опознать с первого взгляда. Размеры объектов, их расположение, и всё такое. Аналогичная история на некоторых других платформах того времени, а вот дальше, с ростом мощности видеосистем, узнаваемость падала.
avatar
У меня к сожалению от этого обилия вариантов только запуталось всё в голове! Вопрос: что будет считаться реально базовой конфигурацией? Что будет типа как 48к спекртум для NES? И какой маппер будет, допустим, вторым по распространённости, типа, я не знаю, классики 128к? Просто непонятно, что такое «базовая конфигурация», если каждая программа может в теории приходить на своей собственной железке!
avatar
Базовая конфигурация — это когда в картридже только два ПЗУ, чип региональной защиты (для NES), и ничего больше. Получается 16 или 32 килобайта ПЗУ кода и 8 килобайт ПЗУ графики. Это примерно как ZX 16 и 48K. Аналог ZX 128K (больше памяти, чуть посложнее видео) — маппер семейства UxROM или аналогичный, по распространённости они вполне тянут на второе место. Добавляют до 256 килобайт ПЗУ кода с одним переключаемым окном, плюс 8К ОЗУ графики. При желании этот маппер можно немного доработать и адресовать единицы-десятки мегабайт ПЗУ кода, делалось китайцами и любителями. Другие мапперы расширяют память более сложным образом, дают больше окон, банки для ПЗУ графики, память для сохранений и другие навороты.
avatar
Спасибо, вот такая информация всегда самая трудно добываемая!
avatar
смотрю эти заставки… сколько всякого разного на денди понаделали…
  • Nuts_
  • 0
avatar
Совсем по-другому после прочтения этой статьи смотрится high hopes by aspekt:

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.