• avatar Shiru
  • 3
Вот прямо чувствую, что нет полного понимания эффекта, и моё объяснение не очень понятно. Конечно не получится без смещения по вертикали, суть эффекта в этом и стоит.

Попробую объяснить ещё раз. Эффект состоит из двух частей.

Первая часть 'рисует' залитый круг и трапецию в буфер в основном ОЗУ. Это самая обычная техника рисования полигона. В буфере для каждой строки всего два значения — самая левая точка и самая правая точка отрезка (xmin,xmax). Рисуем круг алгоритмом Брезенхема (потому что быстро): получаем координату точки, смотрим строку в буфере. Если точка нужна левее, чем левая — значим меняем в буфере на более левое значение. Если нужна правее, чем правая — тоже. Таким образом получается буфер ширины и смещения горизонтальных линий на экране, из которых состоит залитая фигура. Эта техника позволяет рисовать только выпуклые фигуры, то есть букву H ей не нарисовать (нужно два отрезка в пределах одной строки). Более сложное объяснение, если вдруг формулами понятнее, чем на пальцах: www.enlight.ru/faq3d/articles/24.htm

Вторая часть просто решает задачу быстрого вывода требуемых линий на экран, имея в распоряжении только железо SMD. С помощью изменения смещений слоя фона по HBlank мы можем вывести любую строку слоя фона в любую строку экрана. Заранее рисуем в слое фона все возможные ширины отрезков, какие нам понадобятся (т.е. от 1 до N пикселей). Теперь смотрим по буферу, подготовленному первой частью эффекта — надо отрезок шириной в три пикселя? Выводим третью строку слоя фона, где как раз и есть отрезок шириной в три пикселя. При этом смещаем её по горизонтали в нужное место экрана. Если у нас отрезок шириной в три пикселя не в одной строке экрана, а во многих — значит во все эти строки выводим строку фона с тремя пикселями.
  • avatar aa-dav
  • 1
Да, без изменения смещения по вертикали тут не получится.
  • avatar Shiru
  • 2
Я и говорю: изменением вертикального смещения слоя фона для текущей строки выбирается ширина отрезка на экране.
  • avatar aa-dav
  • 1
Техника да, понятна, я её там же и описал по своему, непонятно как сформировалась полученная в эмуляторе картина сканлайнов — она не совсем соответствует картинке если переносить линии одну-за-одной как в первых рассмотренных эффектах. Наверное каждая линия может соответствовать сразу нескольким линиям в итоговом изображении из-за подмен по hblank, то есть рендер построчно перескакивает с линию на линию не только горизонтально, но и вертикально.
  • avatar aa-dav
  • 0
Я так понял, что еще немало странностей и сложностей росло корнями из-за того, что видеочип просто не успевал бы опрашивать видеопамять за HDraw если бы были включены все фичи. В результате видеорежимы разрослись как грибы после дождя — если какая то фича включалась, то начинали отваливаться другие. Единственный режим с четырьмя фонами, например, мог выводить их только в 4-цветном режиме, что было несерьезно для 16-битной консоли. Отрубили один слой — добавилось цветности двум слоям. И так далее. Битплейны и странная раскладка Mode 7 явно растут корнями из того, что видеочип раздельно мог опрашивать чёт/нечет видеопамяти как отдельные банки независимо. Но для программиста это был напряг.
Сега же сделали один видеорежим с максимумом сбалансированных возможностей и успокоились на этом. Согласен, что слабая цветность — весьма неудачный и самый наверное неудачный шаг для своего времени. Полупрозрачность может быть только еще была бы интересной фичей.
  • avatar Shiru
  • 4
Эффект с прожектором в общем-то прост. Рисуем в слое графики фона как бы треугольник — сначала один пиксель, потом два, потом три, и так далее до полной ширины. Теперь с помощью прерывания по HBlank в каждой строке мы можем вывести в эту строку линию нужной ширины — просто выбираем нужное вертикальное смещение в слое фона для задания ширины линии и нужное горизонтальное смещение для её позиционирования по горизонтали. А имея возможность вывода линий любой ширины мы можем нарисовать на экране любую выпуклую фигуру, это самый обычный рендер полигона (буфер xmin-xmax, рисуем круги и линии алгоритмом Брезенхема).

В Clockwork Tortoise скорее всего были выходцы с демосцены, как в Zyrinx. Либо Jesper Kyd на них так повлиял.
  • avatar Shiru
  • 1
У Sega был большой опыт с аркадами, они по сути просто немного урезали одну из своих аркадных платформ. К сожалению, они видимо слегка спешили, и упустили пару моментов, которые сделали бы железо ещё удачнее — в частности, 64-цветная палитра и 9-битный видео ЦАП очевидный просчёт, сделать чуть больше цветов было бы не сильно дороже, но явно лучше. И не сделали прерывание Z80 от таймера YM2612, по сути это всего один проводок, но он очень упростил бы жизнь.

У Nintendo с опытом было похуже. Вообще инженерная работа была проделана очень хорошая, в том плане, что огромная куча наворотов очень аккуратно и красиво организована в наборе регистров, и предусмотрены некоторые очень полезные и крутые фичи (HDMA, window mask, color math). Но там видимо сильно давил прошлый ограниченный опыт и идея сделать обратную совместимость, которую на полпути отбросили, а наследие осталось и сильно повредило результату: такие же карты тайлов, как на NES (ещё одна местная боль), крайне ограниченные спрайты и прочие странности. В общем-то даже 65816 и SPC700 скорее всего были выбраны по причине начального курса на обратную совместимость и простоту перестройки программистов на новую платформу (SPC700 тоже очень похож на 6502, но дурные официальные мнемоники маскируют этот факт).
  • avatar aa-dav
  • 0
Да да, я буду про это завтра писать — все эти неудобные форматы и неудобные упаковки по разным массивам видеопамяти. Довольно напряжно. Sega конечно в целом на фоне SNES проста как две копейки и потому проще программируется. Но возможностей то реально из-за этого меньше. Впрочем два года форы у SNES делают это логичным.
  • avatar Shiru
  • 2
В GH нет рендера в видеопамять, там всюду готовые тайлы. Т.е. формат хранения графики с точки зрения переносимости этой игры непринципиален. Битпланы и плюс и минус, что-то рендерить сложнее, что-то проще (если надо всего 2-4 цвета, например). С практической точки зрения на SNES тоже всегда всё 16-цветное, фоны в 4 и 256 цветов используются очень редко.

Лично мне гораздо больше нравится писать под 65816, чем под 68000, никакой боли. Для понимания надо просто попробовать, трудно объяснить на словах, почему 3 РОН (на самом деле не сильно-то они общего назначения, по сути РОН всего один) не являются проблемой. Так только кажется, если смотреть издали, с других колоколен (8080 и 68K). Если искать проблемы в архитектуре 6502, это прежде всего ограниченность косвенной адресации, т.к. если надо иметь полностью динамический указатель для двух вещей одновременно (типа источник и приёмник в LZ-распаковщике), начинаются пляски с регистром Y (косвенная адресация всегда идёт по (ZP),y).

Вычислительная мощь однозначно сопоставимая, никаких сомнений у меня нет. Несопоставимо — это когда разница в разы, такого тут и близко нет. Реальная боль в заднице на SNES — вовсе не процессор, а видеоконтроллер, в особенности система спрайтов. Ладно битпланы, но ограничение на 1024 тайла на слой фона, только два формата спрайтов одновременно, только 512 тайлов на спрайты (!!!!), расположение тайлов спрайтов, разбросанные по двум спискам биты OAM, и много чего ещё — вот это реально очень напрягает.
  • avatar aa-dav
  • 0
"… у SMD динамический рендер обладал меньшей цветностью..."
имелся ввиду SNES
  • avatar aa-dav
  • 0
У меня сложилось впечатление, что SNES без чипов дополнений на картриджах хуже подходит для динамического рендера. Его формат тайлов размазан по нескольким bit-plane-ам за исключением Mode 7, где другие проблемы, и тем более размазан, чем больше цветность тайлов.
У SMD же всегда всё 16-цветное и всегда тетрады бит плотно упакованы в один байт для пары соседних пикселей.
Проц на мой взгляд должен быть объективно быстрее и удобнее в программировании — семейство 6502 жутко неортогональное, 16-битный вариант использованный в SNES использует сегментацию памяти, 3 регистра общего назначения, постоянно надо лазить в память для получения второго аргумента арифметико-логической команды — из-за чего маппинг ПЗУ картриджа с ОЗУ представляет собой некоторую кашу для упрощения этих вещей…
В Sega 32-битная архитектура, плоская память, 16 высокоортогональных регистров общего назначения — я в принципе поверю, что даже если вычислительная мощь была сопоставимая, то всё равно программировать на этом WDC по сравнению с этим Motorola было «болью в заднице».
Опять таки, пару демок что видел на ютубе SMD vs SNES — у SMD динамический рендер обладал меньшей цветностью — мне показалось что как раз из-за размазки их по битплейнам. Хотя Mode 7 возможно можно раскрыть в более интересные эффекты, но там не применялось.
  • avatar Shiru
  • 1
Маегава, конечно, погорячился. Что-что, а процессор является наименьшей проблемой на SNES, писать под него очень легко — это же чуть улучшенный 6502, едва ли можно придумать процессор проще. Да и про торможение боссов, это смотря как написать. На SNES сцене есть один человек (не могу сейчас вспомнить и найти, он постоянно менял ники), очень любит спорить именно на эту тему со случайными прохожими. Он написал демку Gunstar Heroes-подобной игры, там у него и составные объекты, и вращение — всё нормально, ничего не тормозит. Исходя из собственного опыта, я тоже уверен, что GH на SNES написать можно было без особых проблем.
  • avatar aa-dav
  • 1
В дополнение к комментарию Shiru — посмотрел в эмуляторе на Super C — там используется горизонтальная раскладка A-B, поэтому по горизонтали проблем с прокруткой не могло быть. По вертикали же используется только тот факт, что некоторые телевизоры не отображают полоски сверху и снизу. В эмуляторе FCEUX можно либо выбрать регион PAL либо прямо в опциях NTSC указать отрисовку кадра с 0 до 239 строки (по умолчанию стоит 8 — 231, то есть скрыты по полоске тайлов сверху и снизу как в NTSC физически и происходило) и тогда рваные обновления тайлов сверху/снизу станут видны.
  • avatar Shiru
  • 1
И нам нужно редактирование сообщений. Последняя строка лишняя, осталась от перетасовки абзацев. Прямо как артефакт дорисовки.
  • avatar Shiru
  • 3
Была всего одна игра с дополнительными 2K VRAM для карт тайлов, Gauntlet. Остальные выкручивались как могли. Проблема с диагональным скроллом при двух картах тайлов только в том, как скрыть область дорисовки новых тайлов.

Самый простой вариант диагонального скролла в SMB3 и Felix The Cat — вертикальная раскладка карт тайлов. По вертикали вообще ничего не дорисовывается, уровень всего два экрана в высоту (минус высота панельки снизу). По горизонтали дорисовывается прямо на экране (т.к. карта тайлов в ширину с экран). SMB3 просто не заморачивается по этому поводу, дорисовка видна визуально на краях экрана. Felix скрывает два вертикальных столбца на краях экрана, чтобы сделать дорисовку незаметной — слева аппаратной фичей выключения рендеринга в левом столбце, а справа столбцом чёрных спрайтов (т.к. аппаратной фичи для правого столбца не предусмотрено).

В других играх, где уровень выше двух экранов, стоит вопрос, скрывать вертикальную или горизонтальную дорисовку. Если выбрать горизонтальную раскладку экрана, легко скрыть горизонтальную дорисовку за экраном, но видна вертикальная. Её можно отсечь с помощью панельки или включения/гашения рендера позже начала/раньше конца кадра (обрезав высоту на 16 пикселей). Если не ошибаюсь, с гашением сделано в Jurassic Park. Можно сделать раскладку вертикальной, тогда вертикальная дорисовку получается скрыта, но видна горизонтальная. Её можно скрыть как в Felix, или оставить видимой как в SMB3 (нередко так и делали).

Часто не скрывали дорисовку просто потому что на старых ЭЛТ телевизорах края растра уходили за края видимой области экрана. Потому на всех ТВ-приставках времён ЭЛТ в гайдлайнах есть требования к safe area — к соблюдению области, в которой изображение будет гарантировано видимым. Т.е. за пределами safe area нельзя размещать критичную информацию типа очков или статуса. На NES это отступы примерно по 16 пикселей по вертикали и 8-16 по горизонтали.

Можно сделать горизонтальную раскладку, тогда область горизонтальной дорисовки скрыта, а вертикальной видна.
Диагональный скролл в Super C был засчет тех самых дополнительных 2K VRAM, или там еще какая-то фича?
  • avatar FoxyLab
  • 0
А вот и запуск эпической игры Star Trek (этот вариант написан на языке Ada и скомпилирован в моем эмуляторе):

Осталось разобраться с геймплеем, но вспоминая, как в былые времена сажал самолет переключателем Р/ГРД/Г (олдовые люди :-) поймут, о чем это я) — разве это проблема?
  • avatar tsl
  • 1
В продвинутых чипах кроме спрайтов могут быть другие команды, например примитивы, заливки.
Количество же обращений к памяти как раз меньше, чем при блиттинге, и я описал почему (блиттер: чтение, чтение, запись, сканлайн: чтение).
  • avatar aa-dav
  • 1
Эм. Если я правильно понял такой подход используется как раз во всяких 8-битных и 16-битных консолях при этом «дисплей листом» в них можно считать таблицу описания спрайтов и параметры фонов. То есть прямо перед формированием очередного сканлайна видеоизображения видеочип просматривает таблицу спрайтов, выделяет те из них которые попадают в данный сканлайн и формируют эту строку — отсюда ограничения на максимальное количество спрайтов в одной строке и тому подобное. Главный плюс этого для 8/16-бит заключается в крайне скромным требованиям к количеству видеопамяти — таблица спрайтов очень экономно их описывает. Недостаток — списки спрайтов сканируются каждый сканлайн заново — и как следствие число обращений к видеопамяти резко увеличивается по сравнению с блиттинговым подходом — видеочип как правило не оставляет центральному процессору шансов обратиться к видеопамяти в периоды HDraw, а иногда и на весь VDraw.
  • avatar tsl
  • 1
Рисует он в свою видеопамять как в единый большой фреймбуфер (в котором можно выделить окно рендера).
Ну собственно, это и есть ответ.
Некоторые видеопроцы используют другой способ вывода видео. Каждую строку изображения дисплей лист выполняется полностью, но отрисовывается не фреймбуфер (битмап 1024х512, например), а буфер строки (1024х1), который обычно находится во внутренней памяти чипа. Такой способ требует намного меньше обращений к общему видеоОЗУ, поскольку оно используется только для чтения битмапов, текстур.
2Д:
— чтение текстуры,
— чтение фреймбуфера (+ накладывание по маске),
— запись фреймбуфера.
1Д:
— чтение текстуры (+ накладывание по маске на буфер строки, + запись в буфер строки).
Видеовыхлоп формируется из буфера строки (буфер, ессно двойной). Отрисовывается только часть сцены, видимая в данной строке.
Недостаток метода — меньший размер дисплей-листа, ибо за строку можно выполнить меньше команд. Профит — примерно в 3 раза меньший бандвиз ОЗУ.