Перевод пятой статьи из серии от Fabien Sanglard, в этот раз про порт Another World на Sega Genesis.
Разработка MegaDrive/Genesis началась сразу после того, как Sega выпустила свою Master System в 1987 году. В то время целью Sega было создание чего-то, что превосходит PC Engine от NEC и Famicom от Nintendo.
Серия статей
- Полигоны Another World.
- Полигоны Another World: Amiga 500.
- Полигоны Another World: Atari ST.
- Полигоны Another World: IBM PC.
- Полигоны Another World: Sega Genesis.
- Полигоны Another World: Super Nintendo.
История
Под руководством Масами Исикавы команде потребовался всего год на создание 16-битной системы. Консоль, запущенная 29 октября 1988 года в Японии, не очень хорошо себя зарекомендовала, за первый год было продано 400 000 устройств. Несмотря на выпуск многочисленных периферийных устройств и опережние NES на целое поколение, MegaDrive не нашёл своей аудитории.
Выпуск в США (январь 1989 г.) и Европе (сентябрь 1990 г.) был не самым удачным[1]. Спасение пришло в середине 1990 года, когда Том Калинске стал генеральным директором Sega America. Снижение цен, самоотверженная команда разработчиков из США, агрессивная рекламная кампания на телевидении («Genesis does what Nintendon’t») и замена входящей в комплект игры Altered Beast на Sonic the Hedgehog вывели Genesis на вершину хит-парадов.
В сочетании с поздним Nintendo SNES и проблемной NEC TurboGrafx-16, Sega в январе 1992 года контролировала 65% рынка 16-битных консолей и по продажам превосходила Nintendo четыре рождественских сезона подряд с 1990 по 1994 год. Продано было 39,7 миллиона единиц по всему миру[2].
Архитектура
Если рассматривать с технической стороны, то Genesis имеет впечатляющую Motorola 68000 (7,61 МГц), до 8 МБ ПЗУ, 64 КБ ОЗУ, 64 КБ видеопамяти, видео процессор ASIC (13 МГц) и Z-80 (3,58 МГц) с 8 КБ для аудио управления TI 76489 и YM 2612.
Видео система
Компонент, отвечающий за генерацию видеосигнала, называется VDP (Video Display Processor). Он управляет VRAM и CRAM, где хранятся палитры.
Обратите внимание, что процессор 68000 не может адресовать VRAM, он может «общаться» только с VDP через регистры, замапленные в RAM. Передача данных обычно осуществляется с помощью DMA видео процессора, который имеет доступ к RAM и VRAM. VDP также имеет регистры для разрешения VRAM операций чтения/записи, но они довольно медленные.
68000 останавливается во время DMA передачи, но Z-80 может продолжать работать до тех пор, пока нет необходимости в доступе к ОЗУ.
DMA довольно быстр во время BLANK и работает в два раза быстрее, чем цикл 68000. Это так же быстро, как 68000 во время активного сканирования.
— Genesis Developer Manual
Цветовая система похожа на Atari ST с 3 битами на канал, в сумме 9 бит на цвет.
Видео процессор (VDP)
VDP является графическим ядром ASIC системы. Он основан на спрайтовом движке, что означает отсутствие кадрового буфера. Он работает с четырьмя слоями[3], называемыми Scroll B, Scroll A, Windows и Sprites.
Scroll A и Scroll B являются скролфилдами. Они могут быть больше экрана и перемещаться независимо друг от друга, чтобы создать эффект параллакса. Scroll A также может быть использована в качестве «Window», которое нельзя прокручивать и поэтому хорошо подходит для отображения HUD элементов.
Все элементы слоёв используют 4-битные индексы в палитре своих слоёв (следовательно, всего четыре палитры). Индекс палитры 0 всегда считается прозрачным во всех четырех палитрах. Это даёт 15 цветов на слой[4]. Все палитры хранятся в 128 байтах, называемых CRAM.
Когда VDP генерирует строки развёртки для телевизора, для каждого пикселя система приоритета сообщает, в каком порядке следует выбирать слои. Нет поддержки смешивания (прозрачности) между слоями, но прозрачность может быть достигнута (используя индекс 0). Если упростить, удобной аналогией для понимания приоритета будет Z-компонента со Scroll B, находящимся сзади, и Sprite, находящимся впереди. Пока VDP попадает в прозрачные пиксели, он продолжает переходить на следующий уровень.
Слои
Скроллфилды состоят из ячеек размером 8×8. Слой ячейки состоит из 32 байтов, представленных в виде 8 линий полубайтов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Ячейка VRAM (64 полубайт): ========================== WORD | WORD | WORD | WORD | ----------------------------------------------------- BYTE | BYTE | BYTE | BYTE | BYTE | BYTE | BYTE | BYTE ----------------------------------------------------- 0 0 F F F F 0 0 0 F 0 0 0 0 F 0 F 0 F 0 F 0 0 F F 0 F 0 F 0 0 F F 0 0 0 0 F 0 F F 0 F F F 0 0 F 0 F 0 0 0 0 F 0 0 0 F F F F 0 0 Экран (8 строк по 8 пикселей): ============================= 0 0 F F F F 0 0 0 F 0 0 0 0 F 0 F 0 F 0 F 0 0 F F 0 F 0 F 0 0 F F 0 0 0 0 F 0 F F 0 F F F 0 0 F 0 F 0 0 0 0 F 0 0 0 F F F X 0 0 |
Содержимое скроллфилда задаётся записями в его «таблице имён»[5].
Слой спрайтов может отображать до 80 спрайтов независимо от содержимого двух скроллов. Спрайты могут быть больше, чем Ячейки, от 8х8 до 32х32. Свойства (положение в виртуальном пространстве 512×512, приоритет и многое другое) спрайта задаются записью в «таблице спрайтов»[6].
Доступно два режима: «H32» с ячейками 32×28 (256×224 пикселей) и «H40» с ячейками 40×28 (320×224 пикселей).
NTSC vs PAL
Есть разница между американскими телевизорами и европейскими телевизорами. PAL имеет 576 видимых линий, в то время как NTSC имеет 486 видимых линий. Genesis решил это, предоставив режим PAL с 30 горизонтальными ячейками (на две больше, чем в NTSC 28). Дополнительные ячейки позволили избежать больших чёрных полос сверху и снизу экрана. Однако это было значительным бременем для разработчика, и вроде как они никогда особо не парились на этот счёт.
Чтобы ещё подлить масла в огонь — ранние игры на MegaDrive, такие как Sonic The Hedgehog, работали на 17% медленнее на европейских консолях (даже музыка была медленнее). Разработчики в Японии и США не следовали передовым методам и полагали, что сигнал VBLANK, используемый для измерения времени, запускается каждые 16 мс. Поскольку PAL обновляется с частотой 50 Гц, а NTSC обновляется с частотой 60 Гц, VBLANK в Европе срабатывает раз в 20 мс, а не 16.
Another World на Genesis
Порт на Genesis — первый, рассмотренный в этой серии, сделанный не Delphine Software. Interplay позаботилась о многих портах помимо Genesis, включая Macintosh, Super Nintendo и даже Apple IIGS.
Задача портирования на Sega легла на Майкла Бертона, а Ребекка Хейнеман позаботилась о трёх других платформах. Поскольку Genesis основан на 68000, большая часть кода из Atari ST версии могла быть повторно использована для реализации виртуальной машины.
Для североамериканского релиза Interplay был обеспокоен тем, что клиенты будут путать игру с TV сериалом[7]. Игра была переименована в Out Of This World. Забавно, что сериал под названием Out Of This World вышел в 1991 году[8], но уже было поздно снова менять название игры.
В Interplay также были обеспокоены тем, что игровая упаковка была слишком красивой, поэтому они исправили ошибку.
Майкл не сразу ответил на запросы по электронной почте, поэтому остальная часть этой статьи основана на наблюдениях, сделанных с эмуляторами GenS и Exodus, а также на результатах дизасемблирования.
Невозможная структура
Руководство по программному обеспечению Genesis[9] — это чудо, которое содержит даже тщательного документированные тайминги DMA. Изучив его, Фабьен надеялся увидеть, что VDP широко используется, поскольку он выделяется двумя вещами, в которых Another World нуждается больше всего.
VDP мог бы использовать DMA FILL[10] для отрисовки полигонов, как Amiga Blitter. Функция DMA COPY[11] идеально подходила для реализации опкода VM COPY. К сожалению, некоторые детали не сработали.
Во-первых, необходим огромный объём VRAM. Размещение всех четырёх кадровых буферов 320×200 в VRAM — это слишком много для 64 КБ. Это не было концом, поскольку кадровый буфер мог быть упакован, а разрешение снижено, чтобы уменьшить потребление видеопамяти.
Во-вторых, операции записи DMA FILL выполняются с 16-битной гранулярностью, которая быстра, но когда требовался отдельный ниббл, чтение из VRAM с регистрами VDP, установка маски и обратная запись снизили бы частоту кадров.
Наконец, слой ячеек несовместим с тем, как работает DMA FILL. Для Another World необходимо записывать длинные строки пикселей, но линия разбита на два слова (4 байта) с шагом 28 байтов. Поскольку у DMA FILL нету шага, для этого потребовалось бы много запросов, и издержки убили бы частоту кадров.
Эта невозможная конструкция была подтверждена отслеживанием VDP регистров #17[12] в эмуляторе Exodus, который показал, что DMA COPY и DMA FILL никогда не использовались.
Архитектура Another World на Genesis
Не имея возможности построить движок, основанный на рендеринге VDP, в свою VRAM, Another World пошёл по тяжёлому для 68000 пути, подобному тому, что мы видели на Atari ST.
Три кадровых буфера, два BKGD и «рабочий» буфер хранятся в оперативной памяти. Там 68000 выполняет все операции рендеринга и копирования.
Как только кадр завершен, он записывается DMA в неиспользуемый двойной буфер в VRAM. На следующем VBLANK «активный» буфер VRAM флипается.
Все слои отключены, кроме Scroll A, если верить Gens. Оригинальный Scroll A изменяется в зависимости от того, какой из двойных буферов был записан последним.
По сравнению с Atari ST единственная оптимизация, по-видимому, заключается в реализации COPY, которая теперь использует инструкцию movem. Прирост производительности неясен (5%?).
Без фреймбуфера
В VAM VRAM нет кадровых буферов для отрисовки, но есть способ обойти это, покрывая весь экран Ячейками и переводя координаты пространства экрана в координаты Ячейки.
Для pixel perfect порта можно использовать режим H40 для получения разрешения 320×224 пикселей. Удаление трёх линий Ячеек привело бы к разрешению 320х200, что и было необходимо.
При 320×200 кадровый буфер будет иметь размер 320 * 300/2 = 32 000 байт. Если мы посмотрим на полосу пропускания VDP DMA[13], то увидим, что для NTSC системы потребуется 32000/11556 = 2,7 кадра, а на PAL системе 32000/21654 = 1,4 кадра.
1 2 3 4 5 6 7 8 9 10 11 |
Пропускная способность DMA, байт/фрейм: =============================== Частота Разрешение On VBLANK On Active Display Total -------------------------------------------------------------------------- 60 Hz 256 x 224 6118 3584 9702 320 x 224 7524 4032 11556 50 Hz 256 x 224 14329 3584 17913 320 x 224 17622 4032 21654 256 x 240 11753 3840 15593 320 x 240 14454 4320 18774 |
На заметку: обратите внимание на то, что система PAL превосходит NTSC, когда речь идет о передаче из ОЗУ в VRAM. Именно поэтому большинство демо-групп работают с PAL MegaDrive вместо NTSC Genesis.
Если посмотреть на диаграмму и учесть игровую логику виртуальной машины и рендеринг полигонов поверх передачи из RAM в VRAM, мы увидим, что игра будет выдавать лишь 12-15 кадров в секунду на NTSC, что было неприемлемо.
1 2 3 4 5 6 7 |
Framerate for # missed VSYNCs: ============================== Missed VSYNCs : 0 1 2 3 4 5 6 7 ------------------------------------------------------- NTSC Framerate : 60 30 20 15 12 10 8 7 PAL Framerate : 50 25 16 12 10 8 7 6 |
Чтобы уменьшить нагрузку на полосу пропускания, VDP устанавливается в режиме «H32» с разрешением 32х28. Некоторые столбцы и строки настроены на использование Чёрной ячейки и никогда больше не используются. Эти дополнительные чёрные ячейки еще больше снижают разрешение, а также сохраняют соотношение сторон, равное 1:3.
Только 28×22 Ячейки активно отрисовываются, что даёт разрешение 224×176 и кадровый буфер 224 * 176/2 = 19,712 байт.
Это более низкое разрешение ускорило выполнение опкодов копирования, заполнения и отрисовки полигонов, а также снизило стоимость переноса из RAM в VRAM. В системе NTSC 19,712 / 9702 = 2 пропущенных кадра. Добавьте ещё один для отрисовки/копирования/заполнения, и вы получите 15-12 кадров в секунду, что, кажется, подтверждается реальными кадрами[14].
В системе PAL стоимость передачи составляет 19712/17913 = 1,1 кадра. Это, вероятно, привело к пропуску 2 vsync и лучшей частоте кадров, чем на NTSC, близкой к 16-12fps.
Обратите внимание на дополнительные черты лица и то, как Лестер выглядит более обеспокоенным. Снизу виден клиппинг (правая рука Лестера). Разница в глубине цвета заметна, но это не проблема.
Поговорим о цвете
Кое-что могло заинтересовать вас ранее при описании видеосистемы — VDP поддерживает прозрачность для каждого пикселя. Это достигается тем, что нулевой индекс цвета на всех слоях рассматривается как прозрачный. Это эффективно уменьшает количество цветов, доступных на слой, до 15. Но Another World нуждается в 16. Это проблема.
Фабьен представлял себе решение в использовании Плоскость B и заполнении повторяющейся ячейкой с цветовым индексом 0x01. При загрузке палитры цвет 0 из плоскости A также копируется в палитру плоскости B по индексу 0x01. Затем воспроизведение может продолжаться как обычно. Поскольку плоскость B отстаёт от плоскости A, любой цвет, установленный на 0x0, вместо этого будет установлен на 0x1 плоскости B.
Но оказалось, что ничего из этого не было нужно. Запустив игру на Exodus и глядя на палитры в реальном времени, Фабьен заметил, что все палитры используют один и тот же чёрный цвет с индексом 0. Всё, что нужно было сделать разработчику, это установить BACKGROUND COLOR (цвет, который используется, когда все слои прозрачны) чёрным и покончить с этим.
Итог
Это был, без сомнения, самый сложный из изученных портов. Несмотря на мощный процессор и VDP, MegaDrive, похоже, проседал во время передачи RAM/VRAM, которая, честно говоря, никогда не была рассчитана на вывод в полноэкранном режиме.
Возможно, что-то можно было бы сделать с системой кэширования Ячеек, чтобы передавать только грязные данные, чтобы уменьшить объём передаваемых данных, но, скорее всего, разработчику попросту не дали достаточно времени для порта.
Более низкое разрешение не особо заметно, но ячейки, преднамеренно оставленные чёрными, добавили полосы. В системе NTSC это было не слишком большой проблемой, но на телевизоре PAL чёрные ячейки кадрового буфера ещё больше добавили к «естественным» чёрным полосам.
Парились ли по этому поводу игроки того времени? Вряд ли. StarFox на SNES имеет ту же частоту кадров/дополнительные чёрные полосы, но всё равно запомнилась как отличная игра. Фабьен верит, что это справедливо и для Out of This World/Another world на Genesis/MegaDrive.
Ссылки
- Wikipedia: Sega Genesis, Запуск.
- Продажи Mega Drive.
- Genesis Software Manual: VDP 315-5313.
- Существует много приёмов для отображения большего количества цветов, таких как изменение палитры в HBLANK или потоковая передача цветов в BACKGROUND REGISTER, но они здесь не актуальны.
- VDP, таблицы имён.
- VDP, таблица спрайтов
- Другой мир (телесериал, 1964).
- Фантастическая девушка (телесериал, 1981).
- Genesis Software Manual..
- VDP DMA FILL.
- VDP DMA COPY.
- VDP Registers 0x17.
- segaretro.org, MegaDrive DMA Bandwidth.
- Out of This World on US Model 2 Sega Genesis through S-Video.