В прошлый раз я исследовал начинку картриджей Super Nintendo, а теперь заглянем в ее видеосистему.
Чтобы оказаться в шкуре инженера Nintendo, работавшего в команде Масаюки Уэмуры (上村雅之), я решил изучить то, что было доступно в 1989 году. А именно - телевизор. Это позволило мне понять, какие решения нужно было принимать при проектировании видеосистемы SNES.
Вот краткое изложение того, что я узнал, надеюсь, вам тоже будет интересно.
Что находится внутри телевизора начала 90-х?
Экран, на который SNES выводит видео, представляет собой стандартный телевизор. Обычно его используют для просмотра Captain Tsubasa, Cobra, Astro Boy, Captain Herlock, Saint Seiya или Dragon Ball.
Наверху расположена антенна, которая ловит аналоговое телевещание (NTSC), кабель, передающий сигнал на тюнер, и, наконец, часть, на которой отображается картинка, называемая электронно-лучевой трубкой (ЭЛТ).
![](https://habrastorage.org/getpro/habr/upload_files/be1/12f/26f/be112f26f3d9254a4fac0e1f6343ea16.png)
И ещё один элемент, особенно важный для рассматриваемой нами темы, - дополнительное гнёздо входа (AUX). У обычного телевизора будет композитный разъем (желтый), который передает видеосигнал. Вспомогательные стереоаудиосигналы передаются через специальные разъемы (белые и красные на моем уродливом рисунке).
Как работает ЭЛТ
ЭЛТ — это супермашина для рисования линий. В то время они были рассчитаны на 15 кГц, что означало, что они могли рисовать около 15 000 линий в секунду.
Внутри ЭЛТ находится элемент с тремя электронными пушками. Пушки всегда выстреливают электроны прямо перед собой, а два набора магнитов (один вертикальный и один горизонтальный) направляют их вверх/вниз и влево/вправо.
![](https://habrastorage.org/getpro/habr/upload_files/6d6/6dc/edb/6d66dcedb2299241d762e5761f21f00c.png)
Пусть вас не смущает, что на рисунке лучи от пушек разных цветов. На деле, конечно же, электроны не имеют цвета. Но для схемы удобнее было раскрасить, чтобы читатель мог их различать и отслеживать траекторию движения каждого. Перед слоем люминофора находится маска, которая отвечает за то, чтобы электроны от каждой пушки попадали в полоску соответствующего цвета.
В мире ЭЛТ нет пикселей. Слот — это не пиксель. Рисунок ниже показывает масштаб растровой строки, куда попадают различные части слотов. Единственное, что можно гарантировать — электроны из пушки всегда попадают в правильную цветовую полосу.
![](https://habrastorage.org/getpro/habr/upload_files/95d/1e9/a28/95d1e9a28bf4987ccd951ec0b44f58e0.png)
У HD-телевизора слоты меньше, что позволяет лучше отображать цветовой сигнал. На рисунке ниже та же линия отображается горизонтально с большей точностью благодаря более высокой плотности слотов.
![](https://habrastorage.org/getpro/habr/upload_files/eee/e68/2e2/eeee682e2a1144974936bd485f3e4e7d.png)
Как управляется ЭЛТ
ЭЛТ получает пять сигналов, передаваемых по четырем проводам. Для каждого из сигналов (Красный, Зеленый и Синий) есть один провод. Они напрямую подключены к пушкам. Чем выше сигнал, тем больше электронов выстреливается и тем ярче люминофорные полосы. Отсутствие сигнала на всех трех проводах означает, что электроны не выстреливаются, то есть на строке будет отображаться чёрный цвет.
![](https://habrastorage.org/getpro/habr/upload_files/cfb/503/bfe/cfb503bfe05add61019bfab94df5a48f.png)
Белый провод на рисунке выше передаёт сигналы синхронизации. Их два, Горизонтальная синхронизация (HSYNC) и Вертикальная синхронизация (VSYNC). Оба сигнала используют один и тот же провод, поэтому он называется Композитная синхронизация (CSYNC).
Благодаря моему опыту программирования на ПК я привык к фразе "Wait for VSYNC", что формирует ложное впечатление, будто это излучает ЭЛТ. Что в корне неверно. ЭЛТ ничего не излучает, он только потребляет сигналы и пытается синхронизировать с ними пушку.
Как ЭЛТ рисует изображение
ЭЛТ рисует линию (растр) слева направо. Когда он получает событие HSYNC, он «возвращается» в левую часть экрана (X=0). Когда он получает событие VSYNC, он возвращается в верхнюю часть экрана (Y=0).
Внимательные читатели увидят тут проблему. Нет никакой возможности спуститься вниз. Система, управляющая ЭЛТ, может выдавать столько HSYNC и VSYNC, сколько захочет, одна и та же линия в верхней части экрана будет рисоваться снова и снова.
![](https://habrastorage.org/getpro/habr/upload_files/413/5b1/3f0/4135b13f070ab9b650bc09aa58f8e94f.png)
Ключ к пониманию ЭЛТ
Ключ к пониманию ЭЛТ — усвоить, что пушка движется к правой части экрана с наклоном вниз. После HSYNC ЭЛТ возвращается к X = 0, но поскольку пушка спустится немного вниз, следующая линия будет нарисована ниже предыдущей.
![](https://habrastorage.org/getpro/habr/upload_files/c0a/3e3/efe/c0a3e3efeba772e45f2ae5e9ae27ad52.png)
Это открывает кучу возможностей. На рисунке выше показан сигнал, где VSYNC выдается одновременно с последним HSYNC. Линии всегда рисуются в одном и том же месте на экране. Но посмотрите ниже, что произойдет, если VSYNC выдается между двумя HSYNC.
![](https://habrastorage.org/getpro/habr/upload_files/276/b04/bad/276b04bad1acc53e5e49fbab5dbdf35e.png)
Поскольку внизу нарисована только половина линии, ЭЛТ начинает рисовать следующую линию вверху экрана в той же позиции X. Следующий набор линий будет перемежаться с предыдущим набором.
Наборы линий называются «полями». Режим, в котором поля рисуются в одном и том же месте, называется «прогрессивной» или последовательной разверткой («p»). Режим, в котором поля чередуются, сокращенно обозначается «i». В режиме i приходится идти на компромисс: вертикальное разрешение удваивается, но частота обновления каждой строки уменьшается вдвое.
NTSC выдает два поля с частотой 30 Гц. Поэтому у всех ЭЛТ-мониторов достаточно места между строками для чересстрочной развертки. При рисовании в прогрессивном режиме интервал между строками виден. Это приводит к появлению черного пространства между строками, что характерно для растеризации ЭЛТ.
![Видимые пробелы в строках сканирования. Источник фото: retrogameboards.com Видимые пробелы в строках сканирования. Источник фото: retrogameboards.com](https://habrastorage.org/getpro/habr/upload_files/c7b/a69/84a/c7ba6984aafbcc419ce78f51e5a033ff.png)
Что находится внутри линии?
Когда речь идёт о рисования линий, ЭЛТ является числовым, но когда мы говорим о том, что находится внутри линии, он становится аналоговым. Как видно на рисунке, три пушки напрямую подключены к трём проводам RGB. Система может изменять цветовой сигнал так сильно, как ей хочется (следовательно, использовать любое горизонтальное разрешение). Единственным ограничением является распространение сигнала и плотность маски слота.
Работаем с тем, что есть
Хотя разработчики SNES могли посылать по проводам то, что хотели, им все равно нужно было убедиться, что ЭЛТ сможет с этим справиться. Поскольку оборудование предназначено для отображения сигнала NTSC, все, что они решили, должно было быть близко к следующим спецификациям:
Соотношение сторон 4:3
Количество строк: 262,5 на поле
Количество точек в строке: 341,25
Частота поля: 59,94 Гц
59,94 Гц — какое странное число... Разве электросеть не работает на частоте 60 Гц, а телевизоры не используют эту частоту переменного тока напрямую? Черно-белый NTSC раньше использовал частоту 60 Гц. Но когда инженерам вещания пришлось искать способ добавить к сигналу NTSC ещё и цвет, не нарушая обратной совместимости, они решили снизить частоту на 0,1%, чтобы избежать появления артефактов.
В роли инженера Nintendo
Теперь, когда мы знаем, как работает ЭЛТ, пришло время попробовать себя в роли инженера Nintendo и создать видеосистему.
Первый момент — сделать столько строк, сколько нам нужно. NTSC использует 262,5 строки на поле, но половина строки используется для чересстрочной развертки полей. Мы можем использовать 262 строки, чтобы сделать развёртку прогрессивной. При целевой частоте 59,94 потребуется 15 734,26 строк в секунду, что находится в пределах 4% от рейтинга 15 кГц.
Экран ЭЛТ имеет соотношение сторон 4:3. Если мы используем 350 точек по горизонтали, мы точно попадём в это соотношение сторон, и не будет никаких искажений при преобразовании изображения консоли в строки развертки.
Итак, 262 строки по 59,94 Гц, каждая с 350 точками. Значит, нам нужен тактовый генератор точек, пульсирующий с частотой 262 * 350 * 59,94 = 5 496 498 Гц. Мы можем создать ASIC, который подсчитывает тики точек. Каждые 350 тиков он выдает HSYNC. Каждые 350 * 262 = 91 700 тиков он выдает VSYNC. Думаете, это всё? Нет, мы только начинаем.
У этой наивной конструкции есть две проблемы:
Требуется частота 5 496 498 Гц, которой у нас нет. Ограничения стоимости SNES не позволяют видеосистеме получить собственный осциллятор. Имеется главный генератор, который подсистемы должны использовать через делители.
Вы не можете рисовать цвет все время. Это называется overscan (развертка за пределами экрана). И этому стоит посвятить отдельный раздел.
Развертка за пределами экрана
Когда положение пушки сбрасывается по горизонтали или вертикали, она продолжает выстреливать электроны. Если она продолжает стрелять, она создаёт видимые артефакты.
Еще телевизоры имеют тенденцию к выходу развертки за пределы полезной площади экрана, что означает, что изображение на экране немного больше, чем дисплей. Степень этого выхода за пределы экрана варьируется от телевизора к телевизору. Это нужно, чтобы скрыть дрожание, которое возникает, когда вертикальное положение пушки сбрасывается на Y=0 (после VSYNC), и она некоторое время колеблется вверх и вниз. Вы получите прямые линии только через несколько мкс. Та же проблема происходит и по горизонтали после HSYNC.
Решение всех этих проблем — «остановить» пушку ЭЛТ немного позже VSYNC и после HSYNC. Эти промежутки времени, в течение которых не происходит выстрела электронов, называются соответственно VBLANK и HBLANK.
Все игровые системы той эпохи использовали такую методику. Вот сводка конкурентов SNES:
Устройство |
Год |
Линии |
Линии VBLANK |
Видимые линии |
Строк в секунду |
Частота кадров |
Capcom arcade CPS-1 |
1989 |
262 |
38 |
224 |
15,622 |
59.6294 |
Sega Genesis |
1989 |
262 |
38 |
224 |
15,700 |
59.9227 |
Neo-Geo AES |
1990 |
264 |
40 |
224 |
15,734 |
59.18 |
Выбор вертикального разрешения SNES
Если внимательно посмотреть на приведенную выше сводную таблицу, то можно увидеть, что все конкурирующие системы, а именно Megadrive, Neo-Geo и CPS-1 от Capcom, использовали 224 видимые строки.
Вероятно, они выбрали это число не случайно. 224 — это число, делящееся на 16 (224/16 = 14), что означает, что оно хорошо сочетается с тайлами графического конвейера рендеринга.
Я думаю, что Nintendo не хотела изобретать велосипед. Им не нужно было более высокое разрешение, им нужна была лучшая графика. А вот, что действительно отличало систему Nintendo, так это ее PPU.
![](https://habrastorage.org/getpro/habr/upload_files/673/82b/f4b/67382bf4baee6c91f25db68573d591ca.png)
В конце концов они пошли безопасным путем и разделили свои 262 линии на 224 видимые + 38 пустых (как показано на рисунке слева).
Аркадным играм было позволено выглядеть настолько необычно, насколько хотелось их создателям. Разработчики R-Type в Irem были недовольны стандартными 224 активными строками ЭЛТ по умолчанию.
Они откалибровали свои регистры M72-System для отрисовки 284 строк, 512 точек и использовали тактовую частоту 8 МГц. Оставив 128 точек для HBLANK и 28 строк для VBLANK, получилось активное разрешение 384x256, что было выше, чем у других аркадных игр того времени.
Компромиссом стала частота вертикальной развертки 55,017605 Гц, что было визуально менее приятно и на 10% отличалось от рекомендуемых значений ЭЛТ. Эту частоту обновления трудно воспроизвести для «современных» эмуляторов, но какой впечатляющий подвиг для системы 1987 года!
![](https://habrastorage.org/getpro/habr/upload_files/eba/598/268/eba598268c639fbb692a1e2e72e9756d.png)
Выбор горизонтального разрешения SNES
Пока что мы выбрали количество строк в кадре (262). Мы также знаем, что не сможем выбрать dotclock (синхросигнал для воспроизведения изображений на (точечно-)растровом дисплее). Нам нужно использовать Master clock (21,47727 МГц) и использовать делитель, чтобы получить близкое к NTSC dotclock. Остаётся только использовать dotclock 21,47727 МГц / 4 = 5,3693175 МГц.
Линии, точки, частота точек и частота обновления взаимосвязаны уравнением частоты кадров:
частота обновления = (линии * точки)/dotclock
Учитывая, что наша целевая частота обновления составляет 59,94 Гц, у нас нет особого выбора в отношении количества точек в строке.
точки = 5369317.5 (dotclock) / (262 (строки) * 59,94 (частота)) ≃ 342
По ряду причин, связанных с артефактами несущей при использовании композитных выходов, инженерам Nintendo пришлось использовать 341 точку на линию вместо 342. В результате частота кадров SNES составила:
частота обновления = 5369317.5 / (341 * 262) = 60,098 Гц
60,098 Гц — это не 59,94 Гц NTSC, но поскольку, как было показано ранее с R-Type, у ЭЛТ есть некоторое допустимое отклонение, это работает.
Выбор горизонтального выхода за пределы экрана на SNES
![](https://habrastorage.org/getpro/habr/upload_files/4b1/e71/1a6/4b1e711a6930fc88dc248d6ea154920b.png)
Из 341 точек все не могут быть использованы по тем же причинам: дрожание, артефакты и выход развёртки за пределы экрана. SNES требуется выхода за пределы экрана по горизонтали, во время которого он выдает пустой сигнал.
Ограничения следующие:
Результат — соотношение сторон, близкое к 4:3. То есть 224*(4/3) = 298 видимых точек.
Нужно поиграть с графическим конвейером tilemaps, который использует тайлы 16x16. Остаются значения 304 (16x19), 288 (16x18), 272 (16x17), 256 (16x16), 240 (16*15) и так далее. Лучшим значением, которое приводит к практически полному отсутствию искажений на экране, будет 304 точки.
Третье ограничение заключалось в том, чтобы предоставить PPU достаточно времени для заполнения буфера строк спрайтов во время HBLANK. Я предполагаю, что до 128 спрайтов было слишком много данных для извлечения, и PPU требовалось больше, чем 7 мкс, предоставленных 37 точками HBLANK, если в качестве горизонтального разрешения были выбраны 304 видимых точки.
В конце концов, Nintendo остановилась на 256 видимых точках на линию с 85 точками HBLANK . Это означает, что у PPU есть 16 мкс для извлечения данных спрайта во время HBLANK. Это также означает, что соотношение сторон было не 4:3, а 8:7, что приводит к небольшому искажению при отображении на ЭЛТ.
Режим высокого вертикального разрешения: чересстрочная развертка
До сих пор мы проектировали видеосистему SNES, имея в виду только прогрессивный режим.
Разрешение с выходом за пределы экрана: 341x262
Видимое разрешение: 256x224
Частота кадров: 60,098 Гц
Несмотря на то, что именно такие параметры, в конечном итоге, использовали 99% игр, SNES также имел режимы высокого разрешения. Я могу удвоить разрешение по вертикали и/или горизонтали.
Удвоить разрешение по вертикали до 448 строк легко. Мы можем просто изменить счетчик, чтобы он выдавал VSYNC на полстроки после последнего HSYNC для чересстрочной развертки кадров. Это означает рисование 262,5 строк на кадр, но каждая строка теперь будет обновляться только с частотой 60,098/2=30,049 Гц. Это вызовет мерцание, и будет не очень приятно, но вертикальное разрешение станет выше.
Режим высокого горизонтального разрешения: хитрость
Однако удвоить горизонтальное разрешение гораздо сложнее, поскольку в консоли нет нужной частоты точек.
Хитрость заключается в том, что SNES немного сдвигает каждое второе поле по горизонтали, так что точки поля оказываются между точками предыдущего поля. В итоге вы получаете что-то, работающее с половиной частоты кадров и огромными цветовыми утечками. Это использовали многие тайтлы использовали это, в основном для экранов меню, как подробно описано в fullsnes.txt.
Hires Software
Air Strike Patrol (mission overview) (whatever mode? with Interlace)
Bishoujo Wrestler Retsuden (some text) (512×448, BgMode5+Interlace)
Ball Bullet Gun (in lower screen half) (512×224, BgMode5)
Battle Cross (in game) (but isn't hires?) (512×224, BgMode1+PseudoH)(Bug?)
BS Radical Dreamers (user name input only) (512×224, BgMode5)
Chrono Trigger (crash into Lavos sequence) (whatever mode? with Interlace)
Donkey Kong Country 1 (Nintendo logo) (512×224, BgMode5)
G.O.D. (intro & lower screen half) (512×224, BgMode5)
Jurassic Park (score text) (512×224, BgMode1+PseudoH+Math)
Kirby's Dream Land 3 (leaves in 1st door) (512×224, BgMode1+PseudoH)
Lufia 2 (credits screen at end of game) (whatever mode?)
Moryo Senki Madara 2 (text) (512×224, BgMode5)
Power Drive (in intro) (512×448, BgMode5+Interlace)
Ranma 1/2: Chounai Gekitou Hen (256×448, BgMode1+InterlaceBug)
RPM Racing (in intro and in game) (512×448, BgMode5+Interlace)
Rudra no Hihou (RnH/Treasure of the Rudras)(512×224, BgMode5)
Seiken Densetsu 2 (Secret of Mana) (setup) (512×224, BgMode5)
Seiken Densetsu 3 (512×224, BgMode5)
Shock Issue 1 & 2 (homebrew eZine) (512×224, BgMode5)
SNES Test Program (by Nintendo) (Character Test includes BgMode5/BgMode6)
Super Play Action Football (text) (512×224, BgMode5)
World Cup Striker (intro/menu) (512×224, BgMode5)
Примечание: Ranma на самом деле имеет разрешение всего 256×224 (но случайно включили чересстрочную развертку, что вызывает совершенно бесполезное мерцание).
PAL против NTSC
И это ещё не всё. В Европе телевизоры используют не NTSC, а PAL, а французы даже SECAM. Ожидаемая частота кадров составляет ровно 50 Гц, а в поле 312,5 строк.
На самом деле эту проблему решить не так уж сложно. Эти версии SNES поставляются с Master clock, работающими на частоте 17,7344750 МГц. Тот же делитель дает точечную частоту 5,32034250 МГц. Разрешение выхода за пределы экрана составляет 312 строк на 341 точку. Видимое разрешение составляет 224 строки на 256 точек. А частота кадров составляет 50,00697891 Гц.
Проблема в том, что только 224 строки графики приведут к появлению больших черных полос над и под активной зоной. Это решается с помощью «режима Overscan», который увеличивает количество видимых строк до 240 (то есть 16 строк, что соответствует высоте одного тайла).
Какой подарок для разработчиков игр, желающих портировать игру на европейский рынок, скажете вы. На практике «режим overscan» никогда не использовался. Большинство игр были специально разработаны под 224 строки, поэтому разработчики не знали, что вставлять в эти 16 дополнительных строк. В общей сложности только двенадцать игр когда-либо использовали этот режим. Nintendo все же удалось сделать что-то потрясающее со своей флагманской игрой Super Mario World, увеличив вертикальный диапазон обзора.
NTSC (256x224) |
PAL (256x240) |
Обратите внимание, что экраны NTSC и PAL используют одинаковое соотношение сторон 4:3, поэтому изображение PAL немного более сжато по вертикали, чем изображение NTSC.
Экран NTSC (4:3) |
Экран PAL (4:3) |
Помимо раздражающей черной полосы, код игры также редко пересматривался для учета VSYNC, который возникал на 50,00697891 Гц вместо 60,098 Гц. Это привело к тому, что игра работала на 17% медленнее, чем предполагалось. Короче говоря, европейский гейминг был настоящим кошмаром. Но, к счастью, без интернета мы об этом не знали.
Разъёмы
До сих пор мы рассматривали только «чистые» сигналы, необходимые для управления ЭЛТ. Однако лишь немногие телевизоры позволяли напрямую подавать сигнал на ЭЛТ. У большинства телевизоров был только желтый композитный входной разъем сзади, а некоторые модели более высокого класса имели входы S-Video.
Чтобы справиться с этим многообразием вариантов SNES делает что-то очень крутое. Он преобразует сигналы ЭЛТ как в композитный, так и в S-Video.
![](https://habrastorage.org/getpro/habr/upload_files/e1e/0fb/c42/e1e0fbc423996f6c79a72b1de56acc62.png)
AV-разъем
Ни один из сигналов не отбрасывается. Благодаря конструкции выхода AV геймеры получают выборочный доступ к чистому сигналу "RGB/CSync", "Composite" и S-Video.
![](https://habrastorage.org/getpro/habr/upload_files/ecf/c38/8aa/ecfc388aac84dbb16d1eea905b846dbd.png)
1. Красный
2. Зеленый
3. C-Sync
4. Синий
5. Земля
6. Земля
7. Яркость (S-Video)
8. Цветность (S-Video)
9. Композитное видео
10. +5 В постоянного тока
11. Левый аудио
12. Правый аудио
Европейские телевизоры, особенно во Франции, поставлялись с разъемами SCART (они же Prise peritel). Это позволяло им создавать кабели, напрямую подключаемые к ЭЛТ.
![](https://habrastorage.org/getpro/habr/upload_files/510/7eb/12f/5107eb12f54e194ce308dd889299208e.png)
Таким образом, мы могли наслаждаться играми, замедленными на 17% и с черными полосами, но зато на самом высоком уровне визуальной точности.
Комментарии (2)
NickDoom
31.07.2024 12:09Первая (ну, или сто первая, дело давнее) моя мысль при попытке погрузиться в движок Wolf3D — блин, была бы развёртка не по строкам, а по столбцам, поставили бы счётчик с переменным делением и выгребали бы данные прямо на ЭЛТ с заданной скоростью, формируя столбец изображения, растянутый по вертикали до нужной величины :)
Хотя несколько лишних счётчиков по тем временам — тот ещё конский ценник… да и концепцию Кармак подогнал уже сильно позже.
(Хотя)² — когда прогремел Wolf3D, следующая 2D-приставка могла бы стать 2.5D, если бы в телевидении сложился стандарт с развёрткой по столбцам, конечно :) до полигонов приставкам ещё было как до Луны, а пара счётчиков уже была не столь страшным делом :)
GospodinKolhoznik
Мне как в детстве Супоньев внушил, что Супер Нинтендо самая крутая на свете игровая приставка, так я до сих пор так считаю. Подсознательно, конечно. Умом то понимаю, что по современным меркам она ни о чём, сейчас в мультиварках мощнее процессоры стоят, но на эмоциональном уровне SNES до сих пор воспринимается как что то нереально крутое, роскошное и недоступное.