Секреты и трюки старых консолей и компьютеров
GameDev.ru / Сообщества / old_tricks / Статьи / Графическая архитектура Sega Mega Drive

Графическая архитектура Sega Mega Drive

Автор:

CPU

ЦП у сеги был Motorola 68000 (m68k) первого поколения.
Несмотря на то, что он называется нередко 16-битным, это не совсем соответствует действительности. В действительно архитектура m68k с самого начала описывает полноценный 32-битный процессор с полноценными 32-битными операциями и линейным доступом к 32-битному адресному пространству (в первых моделях выведены наружу были только 24 линии шины, но сами адреса всегда были 32-битные и в регистрах и в памяти). Помимо этого он имел 16 (шестнадцать) 32-битных регистров общего назначения! Честно говоря, как по мне, так даже архитектура i386 выглядит немного убого по сравнению с m68k, по крайней мере в те времена. Но почему же m68k назывался 16-битным, а маркетологи сеги нигде не протащили волшебное словосочетание "32 бита"? Потому что в самых первых линейках 16-битным было арифметико-логическое устройство этого процессора - из экономии или из каких-то других соображений, но складывал (и делал прочие операции в АЛУ) 32-битные данные этот процессор в два захода - по 16 бит за раз, что снижало производительность и не давало повода говорить об "32-битной мощи". Однако сложение адресов - например при индексации массивов - уже в первых моделях было 32-битным (АЛУ при этом не задействовалось - складывал адреса блок собственно адресации). Более того, когда более поздние модели m68k обзавелись 32-битными АЛУ - они выполняли уже существующий код с удвоенной скоростью без необходимости перекомпиляции - для программиста 16-битность АЛУ сразу была вещью "за ширмой", скомпилированный код сразу был готов к полноценной 32-битности.
Поэтому у Sega Mega Drive и карта памяти была абсолютно линейной - в самое начало (адреса от $000000 по $400000) отображалось ROM картриджа (максимально - 4Мб), в самом конце (адреса от $FF0000 по $FFFFFF) сидели 64Кб ОЗУ, а между ними болтались неиспользованные диапазоны и порты ввода-вывода.

Video Display Processor

Разрешение в пикселях 320x224 в NTSC версии или 320x240 в PAL версии.
VDP имеет 64 Кб выделенной памяти, ЦП к ней может обращаться только через порты ввода-вывода или посредством DMA.
DMA может передать из памяти ЦП (ROM картриджа или RAM ЦП) в память VDP (VRAM) или из VRAM в VRAM, включая режим заливки.

Палитра состоит из 64 слотов в отдельной памяти (Color RAM или CRAM), каждый слот в формате RGB содержит всего 3:3:3 бита, что ограничивает все возможные цвета всего 512 значениями и не более 64 цвета на экране за раз. Хотя есть еще спец-эффект затенения/просветления, что немного расширяет цветовые диапазоны, но в ограниченном числе мест применения. Так как все тайлы всегда 16-цветные, а палитра содержит 64 слота, то её можно воспринимать как массив из 4-х независимых 16-цветных палитр - и действительно в спрайтах и плитках фона (в каждой отдельно) содержатся 2ух-битные селекторы из этих 4-х палитр.

Тайлы 8x8 как фонов так и спрайтов располагаются с начала VRAM в 16-цветном режиме (4 bpp), что требует 32 байта на тайл 8x8 и таким образом всё VRAM может восприниматься как массив из 2048 тайлов. Поэтому индексы тайлов указываемые как в плитках фона так и в спрайтах 11-битные, что позволяет как раз указывать 2048 значений. Нулевой цвет в тайлах обозначает прозрачность, поэтому фактически тайлы хранят 15 цветов - и только если ни спрайты ни плитки фона не закрасили пиксель, то отображается  цвет "заднего фона" - его индекс в палитре задаётся в специальном регистре.
Вся VRAM не может быть занята тайлами - нужно еще выделить место под собственно таблицы плиток фонов, таблицу спрайтов и разные вспомогательные вещи - как правило их местоположение внутри VRAM может в широких пределах меняться программированием портов VDP.

Спрайтов возможно 80 штук - их описания хранятся в таблице спрайтов в VRAM - это массив из 8-байтных элементов. Размерности спрайтов по каждой из осей (независимо) могут составлять от 1 до 4 плиток, таким образом от 8 до 32 пикселей. В каждом сканлайне может быть отрисовано не более 20 спрайтов. Забавно что спрайты образуют связный список - каждый хранит в себе индекс следующего спрайта к отрисовке, последний хранит 0.

Всего возможны 2 независимо скроллируемых задних фона/слоя (A и B), которые из себя представляют двумерные массивы плиток по 2 байта на плитку - 11 бит на индекс тайла, 2 бита на селектор палитры, 2 бита на вертикальное/горизонтальное зеркалирование и еще 1 бит на порядок приоритета. Слои плиток могут иметь незавимимые размерности по вертикали и горизонтали кратные 32, но общий объём каждого слоя не должен превышать 8Кб. При скроллинге на экране они проворачиваются через края, что позволяет реализовывать неограниченный скроллинг, как это на консолях принято.
Но сам скроллинг реализован довольно таки любопытно.
Горизонтальный скроллинг каждого из слоёв может производится одним из трёх вариантов на выбор:
а) указывается смещение прокрутки для всего слоя как целого
б) указывается смещение прокрутки для каждой линии тайлов (массивом)
в) указывается смещение прокрутки для каждого сканлайна (тоже массивом)
Вертикальный скроллинг так же предлагает варианты:
а) смещение всего слоя как целого
б) массив из 20 смещений отдельно для каждых смежных двух колонок тайлов (то есть образуется 20 столбцов на экране с независимым скроллингом), причём так, как к этому массиву требуется обращаться каждые 16 пикселей, то он для скорости вынесен в отдельный блок памяти - так называемый VSRAM (Vertical Scroll RAM).
Самое атасное, что эти типы скроллинга можно комбинировать, что приводит визуально к чему то весьма похожему на Mode 7 из SNES, хотя и более грубому.
Вот, например, первый босс из игры Puggsy:

Кроме того присутствует еще одна любопытная деталь - псевдослой "WINDOW", который можно прилепить к любому краю слоя A и который будет перебивать его изображение и при этом никак не скроллится - что предполагалось использовать для всяких прилепленных к краю экрана статус-баров и прочих окошек с информацией и текстом.
Если сложить это с "посканлайновым скроллингом", то по моему становится ясно, что разработчики видеочипа всячески пытались его программистов избавить от необходимости использовать технику HBlank-отсечения. Это даже вызывает вопросы - возможно ли в этом чипе вообще реализовать HBlank-отсечение, не исключено, что видеочип плотно блокировал на период обновления экрана порты с помощью которых нужные эффекты достигались на других консолях и именно поэтому в нём и присутствует такой сложно обустроенный скроллинг.
Тем не менее судя по интернету псевдослой WINDOW мало кем использовался.

При всех этих данных любопытно как в игре Adventures of Batman and Robin достигается эффект перспективы:

Для этого в эмуляторе с хорошим дебаггером (Exodus) посмотрел как они это сделали - и это, чёрт побери, просто и изящно.
У них в слое поле именно так и нарисовано тайлами - именно с этими перспективными искажениями, а дальше уже изящное дело техники зациклить этот фрагмент таким образом, чтобы переставляя как раз построчные смещения картинка бесшовно зацикливалась. И ведь действительно сделано на оригинальном железе без каких либо модчипов...
Тут, как говорится, лучше один раз увидеть, вот этот трюк:

Изображение

Здесь эмулятор сеги Exodus любезно позволяет увидеть нам содержимое заднего фона/слоя B.
Обычно здесь было бы видно квадратно-гнездовой массив плиток, но игра делает финт - этими плитками она рисует такой вот пейзаж в сразу перспективной проекции (в результате возникает конечно же перерасход тайлов, т.к. речь идёт практически о битмапе, правда сильно помогает зеркалирование тайлов, но больших деталей поле и не содержит на всём своём протяжении - ряд вот домов, меняются только вывески.
Зеленым выделением же показано как раз как этот слой отображается на экран - за счёт построчных смещений эффект перспективы плавно продляется и в динамике зацикливается на бесконечность. Горизонтальные линии же зеленой зоны все всегда одинаковой ширины - ширины собственно экрана. По мере движения вправо меняются очертания левой и правой их границ - становясь идеальным прямоугольником только ровно в центре симметрии слоя. Чёрные же пропуски у левого края слоя как раз соответствуют тому, что в разных местах прокрутка прокручивает до зацикливания разное число битмаповских пикселей. С другого края такая же картина.

Нашёл еще коды для пропуска текущего уровня в этом Adventures of Batman and Robin для сеги и внимательно поразглядывал его еще.
Как я понял, перехват HBlank там всё таки техника возможная, плодотворная и может сочетаться с трюком показанным выше для еще большего перфоманса.
Как минимум можно в строке подменять вертикальное смещение слоя, что позволяет управлять перспективой не только по горизонтали как на видео выше, но и по вертикали - то есть имитировать не только горизонтальную, но и вертикальную смену ракурса перспективы одновременно.
Это даёт возможность еще больше погрузится в псевдо-3Д разными способами.
Это опять таки лучше показывать, поэтому вот видео и временные метки к нему ниже:

01:32 - уже показанный выше эффект смены перспективы в горизонтальном направлении с сохранением вертикального ракурса
15:45 - довольно забавное одновременные управление и горизонтальными и вертикальными смещениями как массивами для создания иллюзии частичного вращения слоёв, причём один слой по HBlank разорван на 2 якобы независимых
16:30 - одновременное управление и горизонтальной и вертикальной перспективами - наиболее сильная имитация 3D в игре
30:20 - вот тут очень забавно - псевдо-3D тут нет, но луч прожектора сделан таким же трюком - его переменная величина и "хвост" создаются ничем иным как такой же подменой параметров скроллинга для сканлайнов (как по вертикали так и по горизонтали) на лету. На самом деле задний фон с которого берется изображение луча и пятна прожектора из себя представляет ровный большой квадрат перечеркнутый слева-направо сверху-вниз ровно под 45 градусов границей разделения между пустотой и шахматной сеткой луча.
35:10 - еще один босс имитирующий небольшие повороты через управление слоем
41:35 - еще одна, ранее не встречавшаяся, реализация "плавающей" перспективы, через перпективу+наклон. Тоже довольно забавно.
47:10 - имитация гоночной трассы, классика.
53:10 - эффект "трубы", еще одна, встречающаяся не в одной игре, техника имитации перспективы - оба слоя трудятся по разные стороны от спрайтов

В общем несмотря на отсутствие Mode 7 сега могла довольно много и разных имитаций 3D за счёт управления сканлайнами. Это не говоря про прямой рендеринг на процессоре.

(скомбинировано в одну статью с разрешения Kollect3D)

22 ноября 2017

#16bit, #4generation

2001—2017 © GameDev.ru — Разработка игр