Взгляд на сбои при рендеринге спрайтов на Nintendo за пределами экрана

И то, что я использовал для создания ограничений рендеринга Pixel Vision 8

Когда я снимал некоторые игровые кадры из Zelda II, я заметил странный небольшой сбой. Я был в туннеле, сражаясь с красной Дайрой, вооруженной топором, и в левой части экрана мелькнула часть слизи. Когда я двинулся вперед, я увидел, что фактически прямо за экраном был тонкий экран.

Итак, почему это произошло?

PPU от Nintendo

Во время исследования Nintendo PPU, устройства обработки изображений, я много узнал о рендеринге строк развертки в дополнение к тому, что заставляет спрайты обтекать экран. Это произошло, когда X позиция спрайта превысила 255. Хотя большинство игроков сочли бы это ошибкой программного обеспечения, это было серьезным ограничением в рендерере NES, с которым пришлось столкнуться разработчикам.

Если задуматься, NES - это 8-битная система. Это означает, что позиция X и Y любого спрайта на экране может изменяться только от 0 до 255. Сегодня мы бы использовали целое число без знака для представления этого. Когда вы пытаетесь добавить 1 к 8-битному значению, установленному на 255, он возвращается к нулю. Поскольку NES имела разрешение экрана 256 x 240, это означало, что технически не было места, чтобы скрыть спрайты по горизонтали за пределами экрана.

Для большинства игр, созданных на NES, это было не идеально. Поскольку разместить спрайты за экраном было негде, возникла проблема с перемещением их в поле зрения при прокрутке. Чтобы обойти эту проблему, разработчики воспользовались возможностью переразвертки ЭЛТ. Это была граница по краю экрана, где пиксели не отображались, но технически не были видны на большинстве телевизоров того времени.

Визуализация сцены

Давайте посмотрим на пример того, как это работает, более подробно. NES могла отображать на экране только 32 столбца и 30 рядов плиток одновременно.

Что ж, большинство разработчиков NES знали, что последний столбец экрана не виден на ЭЛТ. Внизу экрана был похожий желоб, но, поскольку последняя видимая строка развертки находится на 240, это не было большой проблемой. NES может пропустить рендеринг последнего столбца и очистить его, чтобы создать желоб для всего, что находится за пределами экрана.

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

Понимание упаковки спрайтов

Но вернемся к проблеме, которую я снял в Zelda II. Хотя это похоже на то, что я описал выше, здесь происходит кое-что еще.

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

Большинство спрайтов в Zelda II имеют ширину 16 пикселей, что равно 2 спрайтам в поперечнике. Это был редкий крайний случай, когда желоба за пределами развертки шириной всего 8 пикселей было недостаточно, чтобы скрыть спрайт. Обожаю эти маленькие глюки. Они добавляют уникальные характеристики, которые делают NES такой уникальной. Все из-за некоторых жестких ограничений, которые разработчики научились обходить или игнорировать. Сегодня это можно было бы считать более серьезной ошибкой рендеринга.

Пример кода

Изучение того, как прятать спрайты в желобе развертки, является критически важным методом для создания более аутентичных 8-битных игр. Вот почему, когда я разработал Pixel Vision 8, свою игровую консоль Fantasy, я добавил поддержку маскировки в правой и нижней части экрана. Вы можете сделать это в Chip Editor Tool, установив количество столбцов и строк, которые будут включены в область нерабочей области.

Если вам интересно узнать немного больше о том, как это работает в PV8 или в целом, я написал небольшой пример кода Lua, чтобы помочь визуальным эффектам переразвертываться.

Когда вы запустите этот код в PV8, он выдаст следующее:

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