Эффект с прожектором в общем-то прост. Рисуем в слое графики фона как бы треугольник — сначала один пиксель, потом два, потом три, и так далее до полной ширины. Теперь с помощью прерывания по HBlank в каждой строке мы можем вывести в эту строку линию нужной ширины — просто выбираем нужное вертикальное смещение в слое фона для задания ширины линии и нужное горизонтальное смещение для её позиционирования по горизонтали. А имея возможность вывода линий любой ширины мы можем нарисовать на экране любую выпуклую фигуру, это самый обычный рендер полигона (буфер xmin-xmax, рисуем круги и линии алгоритмом Брезенхема).
В Clockwork Tortoise скорее всего были выходцы с демосцены, как в Zyrinx. Либо Jesper Kyd на них так повлиял.
У Sega был большой опыт с аркадами, они по сути просто немного урезали одну из своих аркадных платформ. К сожалению, они видимо слегка спешили, и упустили пару моментов, которые сделали бы железо ещё удачнее — в частности, 64-цветная палитра и 9-битный видео ЦАП очевидный просчёт, сделать чуть больше цветов было бы не сильно дороже, но явно лучше. И не сделали прерывание Z80 от таймера YM2612, по сути это всего один проводок, но он очень упростил бы жизнь.
У Nintendo с опытом было похуже. Вообще инженерная работа была проделана очень хорошая, в том плане, что огромная куча наворотов очень аккуратно и красиво организована в наборе регистров, и предусмотрены некоторые очень полезные и крутые фичи (HDMA, window mask, color math). Но там видимо сильно давил прошлый ограниченный опыт и идея сделать обратную совместимость, которую на полпути отбросили, а наследие осталось и сильно повредило результату: такие же карты тайлов, как на NES (ещё одна местная боль), крайне ограниченные спрайты и прочие странности. В общем-то даже 65816 и SPC700 скорее всего были выбраны по причине начального курса на обратную совместимость и простоту перестройки программистов на новую платформу (SPC700 тоже очень похож на 6502, но дурные официальные мнемоники маскируют этот факт).
Да да, я буду про это завтра писать — все эти неудобные форматы и неудобные упаковки по разным массивам видеопамяти. Довольно напряжно. Sega конечно в целом на фоне SNES проста как две копейки и потому проще программируется. Но возможностей то реально из-за этого меньше. Впрочем два года форы у SNES делают это логичным.
В GH нет рендера в видеопамять, там всюду готовые тайлы. Т.е. формат хранения графики с точки зрения переносимости этой игры непринципиален. Битпланы и плюс и минус, что-то рендерить сложнее, что-то проще (если надо всего 2-4 цвета, например). С практической точки зрения на SNES тоже всегда всё 16-цветное, фоны в 4 и 256 цветов используются очень редко.
Лично мне гораздо больше нравится писать под 65816, чем под 68000, никакой боли. Для понимания надо просто попробовать, трудно объяснить на словах, почему 3 РОН (на самом деле не сильно-то они общего назначения, по сути РОН всего один) не являются проблемой. Так только кажется, если смотреть издали, с других колоколен (8080 и 68K). Если искать проблемы в архитектуре 6502, это прежде всего ограниченность косвенной адресации, т.к. если надо иметь полностью динамический указатель для двух вещей одновременно (типа источник и приёмник в LZ-распаковщике), начинаются пляски с регистром Y (косвенная адресация всегда идёт по (ZP),y).
Вычислительная мощь однозначно сопоставимая, никаких сомнений у меня нет. Несопоставимо — это когда разница в разы, такого тут и близко нет. Реальная боль в заднице на SNES — вовсе не процессор, а видеоконтроллер, в особенности система спрайтов. Ладно битпланы, но ограничение на 1024 тайла на слой фона, только два формата спрайтов одновременно, только 512 тайлов на спрайты (!!!!), расположение тайлов спрайтов, разбросанные по двум спискам биты OAM, и много чего ещё — вот это реально очень напрягает.
У меня сложилось впечатление, что SNES без чипов дополнений на картриджах хуже подходит для динамического рендера. Его формат тайлов размазан по нескольким bit-plane-ам за исключением Mode 7, где другие проблемы, и тем более размазан, чем больше цветность тайлов.
У SMD же всегда всё 16-цветное и всегда тетрады бит плотно упакованы в один байт для пары соседних пикселей.
Проц на мой взгляд должен быть объективно быстрее и удобнее в программировании — семейство 6502 жутко неортогональное, 16-битный вариант использованный в SNES использует сегментацию памяти, 3 регистра общего назначения, постоянно надо лазить в память для получения второго аргумента арифметико-логической команды — из-за чего маппинг ПЗУ картриджа с ОЗУ представляет собой некоторую кашу для упрощения этих вещей…
В Sega 32-битная архитектура, плоская память, 16 высокоортогональных регистров общего назначения — я в принципе поверю, что даже если вычислительная мощь была сопоставимая, то всё равно программировать на этом WDC по сравнению с этим Motorola было «болью в заднице».
Опять таки, пару демок что видел на ютубе SMD vs SNES — у SMD динамический рендер обладал меньшей цветностью — мне показалось что как раз из-за размазки их по битплейнам. Хотя Mode 7 возможно можно раскрыть в более интересные эффекты, но там не применялось.
Маегава, конечно, погорячился. Что-что, а процессор является наименьшей проблемой на SNES, писать под него очень легко — это же чуть улучшенный 6502, едва ли можно придумать процессор проще. Да и про торможение боссов, это смотря как написать. На SNES сцене есть один человек (не могу сейчас вспомнить и найти, он постоянно менял ники), очень любит спорить именно на эту тему со случайными прохожими. Он написал демку Gunstar Heroes-подобной игры, там у него и составные объекты, и вращение — всё нормально, ничего не тормозит. Исходя из собственного опыта, я тоже уверен, что GH на SNES написать можно было без особых проблем.
В дополнение к комментарию Shiru — посмотрел в эмуляторе на Super C — там используется горизонтальная раскладка A-B, поэтому по горизонтали проблем с прокруткой не могло быть. По вертикали же используется только тот факт, что некоторые телевизоры не отображают полоски сверху и снизу. В эмуляторе FCEUX можно либо выбрать регион PAL либо прямо в опциях NTSC указать отрисовку кадра с 0 до 239 строки (по умолчанию стоит 8 — 231, то есть скрыты по полоске тайлов сверху и снизу как в NTSC физически и происходило) и тогда рваные обновления тайлов сверху/снизу станут видны.
Была всего одна игра с дополнительными 2K VRAM для карт тайлов, Gauntlet. Остальные выкручивались как могли. Проблема с диагональным скроллом при двух картах тайлов только в том, как скрыть область дорисовки новых тайлов.
Самый простой вариант диагонального скролла в SMB3 и Felix The Cat — вертикальная раскладка карт тайлов. По вертикали вообще ничего не дорисовывается, уровень всего два экрана в высоту (минус высота панельки снизу). По горизонтали дорисовывается прямо на экране (т.к. карта тайлов в ширину с экран). SMB3 просто не заморачивается по этому поводу, дорисовка видна визуально на краях экрана. Felix скрывает два вертикальных столбца на краях экрана, чтобы сделать дорисовку незаметной — слева аппаратной фичей выключения рендеринга в левом столбце, а справа столбцом чёрных спрайтов (т.к. аппаратной фичи для правого столбца не предусмотрено).
В других играх, где уровень выше двух экранов, стоит вопрос, скрывать вертикальную или горизонтальную дорисовку. Если выбрать горизонтальную раскладку экрана, легко скрыть горизонтальную дорисовку за экраном, но видна вертикальная. Её можно отсечь с помощью панельки или включения/гашения рендера позже начала/раньше конца кадра (обрезав высоту на 16 пикселей). Если не ошибаюсь, с гашением сделано в Jurassic Park. Можно сделать раскладку вертикальной, тогда вертикальная дорисовку получается скрыта, но видна горизонтальная. Её можно скрыть как в Felix, или оставить видимой как в SMB3 (нередко так и делали).
Часто не скрывали дорисовку просто потому что на старых ЭЛТ телевизорах края растра уходили за края видимой области экрана. Потому на всех ТВ-приставках времён ЭЛТ в гайдлайнах есть требования к safe area — к соблюдению области, в которой изображение будет гарантировано видимым. Т.е. за пределами safe area нельзя размещать критичную информацию типа очков или статуса. На NES это отступы примерно по 16 пикселей по вертикали и 8-16 по горизонтали.
Можно сделать горизонтальную раскладку, тогда область горизонтальной дорисовки скрыта, а вертикальной видна.
В продвинутых чипах кроме спрайтов могут быть другие команды, например примитивы, заливки.
Количество же обращений к памяти как раз меньше, чем при блиттинге, и я описал почему (блиттер: чтение, чтение, запись, сканлайн: чтение).
Эм. Если я правильно понял такой подход используется как раз во всяких 8-битных и 16-битных консолях при этом «дисплей листом» в них можно считать таблицу описания спрайтов и параметры фонов. То есть прямо перед формированием очередного сканлайна видеоизображения видеочип просматривает таблицу спрайтов, выделяет те из них которые попадают в данный сканлайн и формируют эту строку — отсюда ограничения на максимальное количество спрайтов в одной строке и тому подобное. Главный плюс этого для 8/16-бит заключается в крайне скромным требованиям к количеству видеопамяти — таблица спрайтов очень экономно их описывает. Недостаток — списки спрайтов сканируются каждый сканлайн заново — и как следствие число обращений к видеопамяти резко увеличивается по сравнению с блиттинговым подходом — видеочип как правило не оставляет центральному процессору шансов обратиться к видеопамяти в периоды HDraw, а иногда и на весь VDraw.
Рисует он в свою видеопамять как в единый большой фреймбуфер (в котором можно выделить окно рендера).
Ну собственно, это и есть ответ.
Некоторые видеопроцы используют другой способ вывода видео. Каждую строку изображения дисплей лист выполняется полностью, но отрисовывается не фреймбуфер (битмап 1024х512, например), а буфер строки (1024х1), который обычно находится во внутренней памяти чипа. Такой способ требует намного меньше обращений к общему видеоОЗУ, поскольку оно используется только для чтения битмапов, текстур.
2Д:
— чтение текстуры,
— чтение фреймбуфера (+ накладывание по маске),
— запись фреймбуфера.
1Д:
— чтение текстуры (+ накладывание по маске на буфер строки, + запись в буфер строки).
Видеовыхлоп формируется из буфера строки (буфер, ессно двойной). Отрисовывается только часть сцены, видимая в данной строке.
Недостаток метода — меньший размер дисплей-листа, ибо за строку можно выполнить меньше команд. Профит — примерно в 3 раза меньший бандвиз ОЗУ.
«Я правильно понимаю, что дисплей-лист выполняется блиттером (т.е. рисует 2-D битмапы в ОЗУ)?»
Не понял вопроса. Видеочип PS1 может выполнять разные команды поступающие в порт ввода — от выставления render-state-ов и блиттинга 2Д-изображений до растеризации треугольников с текстурированием и освещением. Рисует он в свою видеопамять как в единый большой фреймбуфер (в котором можно выделить окно рендера).
Про Nintendo DS не планировал, но у меня будут еще обстоятельные уроки по программированию его непосредственного предтечи — Game Boy Advance, там даже обратная совместимость. Собственно они взяли GBA, навесили на него дополнительную память, расширили функционал видеочипа до 3D, вставили вдвое более быстрый процессор, два дисплея и получился DS.
Осенью 1995 года графика PS1 порвала мне мозг — то, что я видел на экране телевизора в супермаркете, было невозможно. До сих пор у меня валяется одна приставка, правда с убитым лазером. Временами даже хочется написать его эмулятор.
Процессор был еще без конвеера, но в качестве предтечи оного в нём всегда одна следующая инструкция извлекалась из памяти и дешифровалась в процессе выполнения текущей инструкции.
У финских VS1001 так же. После каждого JMP обязательно стоит NOP.
Вся VRAM в 1Мб с точки зрения GPU представлена как один большой битмап фреймбуфера 1024x512 16–битных пикселей. Забавно, что все данные поступающие для сохранения в VRAM никогда не указываются своими линейными адресами — всегда адресация идёт как бы к двум координатам (x,y) в этом фреймбуфере.
В тсконф у меня так лежат битмапы для спрайтового процессора.
Я правильно понимаю, что дисплей-лист выполняется блиттером (т.е. рисует 2-D битмапы в ОЗУ)? Для сравнения FT812 выполняет ДЛ каждую строку и строит 1-D пиксельный буфер «на лету». Но у FT812 частота повыше и транзисторов побольше на тот же функционал.
Хотелось бы узнать как устроен 3-D у Nintendo DS. Очень милая архитектура. Про него будет статья?
Почти сломал голову пытаясь понять почему фазовая модуляция в каких то случаях эквивалентна частотной, как говорит википедия. Но кажется наглядно понял — пока нарастает вычитание фазы это действительно как бы уменьшает частоту и наоборот когда слагаемое к фазе начинает нарастать.
Хаха! :) Действительно. Пересмотрел свои статьи, имеено да, эта ссылка упоминалась gamedev.ru/flame/forum/?id=226622&page=3#m32 в первой версии статье о мапперах денди. «Вот здесь: hypr.ru/blog/graphics/283.html есть отличная статья на тему того какими ухищрениями занимались создатели видеоигр для денди для этого дела. Частично там затронута и тема мапперов». В процессе реструктуризации она потерялась оттуда, ибо более уместна в статье про видеочип же.
Про Gravis Ultrasound, мне кажется, стоило упомянуть. Хотя это тоже цифра как и SB, но всё же отличия были существенны и тогда это воспринималось как большой шаг вперёд, как я помню.
В Clockwork Tortoise скорее всего были выходцы с демосцены, как в Zyrinx. Либо Jesper Kyd на них так повлиял.
У Nintendo с опытом было похуже. Вообще инженерная работа была проделана очень хорошая, в том плане, что огромная куча наворотов очень аккуратно и красиво организована в наборе регистров, и предусмотрены некоторые очень полезные и крутые фичи (HDMA, window mask, color math). Но там видимо сильно давил прошлый ограниченный опыт и идея сделать обратную совместимость, которую на полпути отбросили, а наследие осталось и сильно повредило результату: такие же карты тайлов, как на NES (ещё одна местная боль), крайне ограниченные спрайты и прочие странности. В общем-то даже 65816 и SPC700 скорее всего были выбраны по причине начального курса на обратную совместимость и простоту перестройки программистов на новую платформу (SPC700 тоже очень похож на 6502, но дурные официальные мнемоники маскируют этот факт).
Лично мне гораздо больше нравится писать под 65816, чем под 68000, никакой боли. Для понимания надо просто попробовать, трудно объяснить на словах, почему 3 РОН (на самом деле не сильно-то они общего назначения, по сути РОН всего один) не являются проблемой. Так только кажется, если смотреть издали, с других колоколен (8080 и 68K). Если искать проблемы в архитектуре 6502, это прежде всего ограниченность косвенной адресации, т.к. если надо иметь полностью динамический указатель для двух вещей одновременно (типа источник и приёмник в LZ-распаковщике), начинаются пляски с регистром Y (косвенная адресация всегда идёт по (ZP),y).
Вычислительная мощь однозначно сопоставимая, никаких сомнений у меня нет. Несопоставимо — это когда разница в разы, такого тут и близко нет. Реальная боль в заднице на SNES — вовсе не процессор, а видеоконтроллер, в особенности система спрайтов. Ладно битпланы, но ограничение на 1024 тайла на слой фона, только два формата спрайтов одновременно, только 512 тайлов на спрайты (!!!!), расположение тайлов спрайтов, разбросанные по двум спискам биты OAM, и много чего ещё — вот это реально очень напрягает.
SMDдинамический рендер обладал меньшей цветностью..."имелся ввиду SNES
У SMD же всегда всё 16-цветное и всегда тетрады бит плотно упакованы в один байт для пары соседних пикселей.
Проц на мой взгляд должен быть объективно быстрее и удобнее в программировании — семейство 6502 жутко неортогональное, 16-битный вариант использованный в SNES использует сегментацию памяти, 3 регистра общего назначения, постоянно надо лазить в память для получения второго аргумента арифметико-логической команды — из-за чего маппинг ПЗУ картриджа с ОЗУ представляет собой некоторую кашу для упрощения этих вещей…
В Sega 32-битная архитектура, плоская память, 16 высокоортогональных регистров общего назначения — я в принципе поверю, что даже если вычислительная мощь была сопоставимая, то всё равно программировать на этом WDC по сравнению с этим Motorola было «болью в заднице».
Опять таки, пару демок что видел на ютубе SMD vs SNES — у SMD динамический рендер обладал меньшей цветностью — мне показалось что как раз из-за размазки их по битплейнам. Хотя Mode 7 возможно можно раскрыть в более интересные эффекты, но там не применялось.
Самый простой вариант диагонального скролла в SMB3 и Felix The Cat — вертикальная раскладка карт тайлов. По вертикали вообще ничего не дорисовывается, уровень всего два экрана в высоту (минус высота панельки снизу). По горизонтали дорисовывается прямо на экране (т.к. карта тайлов в ширину с экран). SMB3 просто не заморачивается по этому поводу, дорисовка видна визуально на краях экрана. Felix скрывает два вертикальных столбца на краях экрана, чтобы сделать дорисовку незаметной — слева аппаратной фичей выключения рендеринга в левом столбце, а справа столбцом чёрных спрайтов (т.к. аппаратной фичи для правого столбца не предусмотрено).
В других играх, где уровень выше двух экранов, стоит вопрос, скрывать вертикальную или горизонтальную дорисовку. Если выбрать горизонтальную раскладку экрана, легко скрыть горизонтальную дорисовку за экраном, но видна вертикальная. Её можно отсечь с помощью панельки или включения/гашения рендера позже начала/раньше конца кадра (обрезав высоту на 16 пикселей). Если не ошибаюсь, с гашением сделано в Jurassic Park. Можно сделать раскладку вертикальной, тогда вертикальная дорисовку получается скрыта, но видна горизонтальная. Её можно скрыть как в Felix, или оставить видимой как в SMB3 (нередко так и делали).
Часто не скрывали дорисовку просто потому что на старых ЭЛТ телевизорах края растра уходили за края видимой области экрана. Потому на всех ТВ-приставках времён ЭЛТ в гайдлайнах есть требования к safe area — к соблюдению области, в которой изображение будет гарантировано видимым. Т.е. за пределами safe area нельзя размещать критичную информацию типа очков или статуса. На NES это отступы примерно по 16 пикселей по вертикали и 8-16 по горизонтали.
Можно сделать горизонтальную раскладку, тогда область горизонтальной дорисовки скрыта, а вертикальной видна.
Количество же обращений к памяти как раз меньше, чем при блиттинге, и я описал почему (блиттер: чтение, чтение, запись, сканлайн: чтение).
Некоторые видеопроцы используют другой способ вывода видео. Каждую строку изображения дисплей лист выполняется полностью, но отрисовывается не фреймбуфер (битмап 1024х512, например), а буфер строки (1024х1), который обычно находится во внутренней памяти чипа. Такой способ требует намного меньше обращений к общему видеоОЗУ, поскольку оно используется только для чтения битмапов, текстур.
2Д:
— чтение текстуры,
— чтение фреймбуфера (+ накладывание по маске),
— запись фреймбуфера.
1Д:
— чтение текстуры (+ накладывание по маске на буфер строки, + запись в буфер строки).
Видеовыхлоп формируется из буфера строки (буфер, ессно двойной). Отрисовывается только часть сцены, видимая в данной строке.
Недостаток метода — меньший размер дисплей-листа, ибо за строку можно выполнить меньше команд. Профит — примерно в 3 раза меньший бандвиз ОЗУ.
Не понял вопроса. Видеочип PS1 может выполнять разные команды поступающие в порт ввода — от выставления render-state-ов и блиттинга 2Д-изображений до растеризации треугольников с текстурированием и освещением. Рисует он в свою видеопамять как в единый большой фреймбуфер (в котором можно выделить окно рендера).
Про Nintendo DS не планировал, но у меня будут еще обстоятельные уроки по программированию его непосредственного предтечи — Game Boy Advance, там даже обратная совместимость. Собственно они взяли GBA, навесили на него дополнительную память, расширили функционал видеочипа до 3D, вставили вдвое более быстрый процессор, два дисплея и получился DS.
У финских VS1001 так же. После каждого JMP обязательно стоит NOP.
В тсконф у меня так лежат битмапы для спрайтового процессора.
Я правильно понимаю, что дисплей-лист выполняется блиттером (т.е. рисует 2-D битмапы в ОЗУ)? Для сравнения FT812 выполняет ДЛ каждую строку и строит 1-D пиксельный буфер «на лету». Но у FT812 частота повыше и транзисторов побольше на тот же функционал.
Хотелось бы узнать как устроен 3-D у Nintendo DS. Очень милая архитектура. Про него будет статья?
Вот: hypr.ru/blog/graphics/283.html
А её автор — и есть сам Shiru. Так что вы, по сути, автору про его же статью рассказываете :)