Это всё теория. На практике и там и там одинаково сложно сделать игру типа GH, и, повторяюсь, одинаково и там и там проблема не в коде, не в операциях, и не в системе команд. В GH нет совершенно ничего необычного в плане кода, просто аккуратно спланированные растровые эффекты, грамотное использование двух слоёв фона. На SNES есть те же самые два слоя фона, и можно сделать те же самые эффекты. Причём делаются они чуть проще, т.к. есть HDMA.
Самая главная проблема на SNES — откровенно неудачная система спрайтов. Если не сделать менеджер списка спрайтов грамотно, будут тормоза, наблюдаемые во многих играх. У большинства программистов тех лет просто не было опыта и времени разбираться, как решать эту проблему (но некоторые решали). Не выглядящие крутыми демки также показывают, что проблема решаема, а блог описывает, как именно. Я также пришёл к подобному решению, увидел изыскания этого товарища уже после этого.
Ну эти демки особо крутыми не выглядят — много спрайтов в какой то момент и только.
Имхо всё же Маегава если и преувеличивал, то не сильно. Плоский прямолинейный проц с 32-битными операциями (пусть даже под капотом выполняющимися как 16-битные, но в системе команд команда одна и как бы 32-битная) и простые раскладки видеопамяти, включая таблицы спрайтов, очевидно должны сделать программирование сложных сцен и трюков на SMD проще. И даже если на SNES можно добиться таких же показателей — то это уже демосцена с выдавливанием соков, а не SMD — нет, просто сел и запрограммировал. Другое дело, что в SNES было еще много аппаратных интересностей просто отсутствующих в SMD.
Демка явно предшественница двух последующих, которые я не могу найти. В одной была графика прямо из GH, в другой очень стрёмная оригинальная графика с какой-то девочкой-роботом. В целом, можно видеть, что ещё 8 лет назад у него без проблем получалось сделать огромную кучу объектов и составные анимации без замедлений.
Вот интересно — каждый раз когда смотрю на игры с Sega, SNES, Amiga то, по сравнению с Atari XE/XL и C64, бросается в глаза, что спрайты субъективно выглядят очень отдельными от фона и, как правило, для анимации прорисовано очень мало кадров. Соответственно, возникает устойчивое впечатление, что делали на скорую руку.
Провёл небольшое исследование в том же эмуляторе Exodus.
А прикольно у них там.
На слое А рисуется потолок и «внешние углы». Они реально перерисовываются при движении под нужный угол.
На слое Б рисуется пол и «внутренние углы». Даже если там статичные тайлы они значит рассчитаны под любой ракурс который может дать игра. Возможно их истинное число просто невелико, учитывая что есть флаги отражения тайлов по осям.
Так или иначе углы действительно создаются на лету тайлами или их содержимым и разбиты разумно на оба фона как «внутренние» и «внешние».
Вот indoor-эффект я до сих пор не смог раскусить до конца (аналогично ещё в Toy Story, но попроще). Т.е. я знаю, как это делается в общем случае, не на SMD, но если большинство эффектов из игр на SMD/SNES я повторить на них же готов и точно знаю, как это сделать, то этот — нет. Я бы стал делать честный рендер углов стен с подгрузкой графики в видеопамять, но они обходятся (довольно большим) набором статичных тайлов.
Не факт что и откуда первое пришло. Например выше тут упоминается команда Zyrinx — они пришли из демосцены и сделали игру Red Zone для Sega Mega Drive и настолько гордились тем что сделали, что прямо в титульных экранах игры вставили вот такую заметку:
Стоит сперва начало посмотреть до первых геймплейных моментов (не пропуская заставки), а потом перемотать на 7:40 и позырить на indoor-геймплей.
Практически «прикладное демостроение». С той лишь разницей, что сперва эти эффекты появились в играх и только потом перекочевали в демосцену. Независимый скролл каждого сканлайна на олдскул платформе был реализован в Coma Light 13, например, в 2012 году :).
Вероятно память буфера строки стоила бы слишком дорого в плане места на кристалле. В NES динамическая память OAM (описание спрайтов, X/Y/тайл/палитра) размером 2x256 байт занимает аж четверть кристалла PPU. Для варианта с буфером строки понадобилось бы ещё 2x256 байт, плюс возможно логика заняла бы сравнимо или больше, чем логика со сдвиговыми регистрами.
Пиксельный буфер в импортных приставках мне не припоминается нигде. Впервые я увидел эту идею в V2Z80 (который задолго до V6Z80P), который из ранних 2000-х, и она показалась мне очевидной и логичной. Чуть позже узнал, что и в советском игровом автомате ТИА-МЦ-1 ~1988 года спрайты тоже сделаны с буфером строки, там даже три буфера 256x4 (16-цветные спрайты). А потом уже стал вникать в эти детали по популярным приставкам, и удивился, что там сделано совершенно иначе.
«снимает ограничение на одновременное кол-во спрайтов в строке»
Ну не снимает, а скорее как то меняет — и еще надо смотреть как. Технически всё-равно надо успеть сформировать строку.
У спец-регистров в принципе bandwidth может как бы и не быть, то есть загрузив их в начале строки можно как бы «бесплатно» не пересекаясь в них лазить хоть каждый пиксель — на то они и регистры.
Но в любом случае победил в высокопроизводительных игровых системах окончательно блиттинг, причём в весь сюрфейс сразу и во много потоков, а роль видеоадаптера свелась к неспешному скармливанию в видеопорт уже готовых полностью пикселей.
Вот что мне неочевидно во многих приставках (и СМД в частности) — это отображение спрайтов из специальных регистров вместо того, чтоб рендерить все в пиксельный буфер. Я может уже надоел тут всем со своим буфером :), но когда я делал спрайтовый процессор, я понял, что лучше соорудить FSM, которая пройдется по объектам (спрайтам/тайлам), вычитает из памяти их графику и нарендерит ее в тру-колорный пиксельный массив сканлайна. Плюсы: снимает ограничение на одновременное кол-во спрайтов в строке, балансирует нагрузку на доступ в ОЗУ. У меня при том еще и ОЗУ 1-портовое и общее с другими подсистемами. У СМД ОЗУ 2-портовое, статический порт используется исключительно видеопроцессором. Зачем при этом мутить кашу из мультиплексиров спрайтовых регов, непонятно.
Не не, эффект я понял сразу же. Я почему то забуксовал с наложением его на картину видеопамяти из эмулятора — смутно брезжило, что линии перескакивают и по вертикали, но уверенности не было. Теперь немного исправил пост, чтобы читателям тоже было понятнее.
Вот прямо чувствую, что нет полного понимания эффекта, и моё объяснение не очень понятно. Конечно не получится без смещения по вертикали, суть эффекта в этом и стоит.
Попробую объяснить ещё раз. Эффект состоит из двух частей.
Первая часть 'рисует' залитый круг и трапецию в буфер в основном ОЗУ. Это самая обычная техника рисования полигона. В буфере для каждой строки всего два значения — самая левая точка и самая правая точка отрезка (xmin,xmax). Рисуем круг алгоритмом Брезенхема (потому что быстро): получаем координату точки, смотрим строку в буфере. Если точка нужна левее, чем левая — значим меняем в буфере на более левое значение. Если нужна правее, чем правая — тоже. Таким образом получается буфер ширины и смещения горизонтальных линий на экране, из которых состоит залитая фигура. Эта техника позволяет рисовать только выпуклые фигуры, то есть букву H ей не нарисовать (нужно два отрезка в пределах одной строки). Более сложное объяснение, если вдруг формулами понятнее, чем на пальцах: www.enlight.ru/faq3d/articles/24.htm
Вторая часть просто решает задачу быстрого вывода требуемых линий на экран, имея в распоряжении только железо SMD. С помощью изменения смещений слоя фона по HBlank мы можем вывести любую строку слоя фона в любую строку экрана. Заранее рисуем в слое фона все возможные ширины отрезков, какие нам понадобятся (т.е. от 1 до N пикселей). Теперь смотрим по буферу, подготовленному первой частью эффекта — надо отрезок шириной в три пикселя? Выводим третью строку слоя фона, где как раз и есть отрезок шириной в три пикселя. При этом смещаем её по горизонтали в нужное место экрана. Если у нас отрезок шириной в три пикселя не в одной строке экрана, а во многих — значит во все эти строки выводим строку фона с тремя пикселями.
Самая главная проблема на SNES — откровенно неудачная система спрайтов. Если не сделать менеджер списка спрайтов грамотно, будут тормоза, наблюдаемые во многих играх. У большинства программистов тех лет просто не было опыта и времени разбираться, как решать эту проблему (но некоторые решали). Не выглядящие крутыми демки также показывают, что проблема решаема, а блог описывает, как именно. Я также пришёл к подобному решению, увидел изыскания этого товарища уже после этого.
Имхо всё же Маегава если и преувеличивал, то не сильно. Плоский прямолинейный проц с 32-битными операциями (пусть даже под капотом выполняющимися как 16-битные, но в системе команд команда одна и как бы 32-битная) и простые раскладки видеопамяти, включая таблицы спрайтов, очевидно должны сделать программирование сложных сцен и трюков на SMD проще. И даже если на SNES можно добиться таких же показателей — то это уже демосцена с выдавливанием соков, а не SMD — нет, просто сел и запрограммировал. Другое дело, что в SNES было еще много аппаратных интересностей просто отсутствующих в SMD.
Демка явно предшественница двух последующих, которые я не могу найти. В одной была графика прямо из GH, в другой очень стрёмная оригинальная графика с какой-то девочкой-роботом. В целом, можно видеть, что ещё 8 лет назад у него без проблем получалось сделать огромную кучу объектов и составные анимации без замедлений.
И судя по всему кусок стены над дверью еще накрыт спрайтами, а не фонами. Три больших таких спрайта прямо над ней. В общем не без заморочек.
Что-то сюда картинка как то косячно загрузилась. Вот она же на фастпике: i91.fastpic.ru/big/2018/0925/be/6ce8e44d70e132d8ab446c2e3df679be.gif
А прикольно у них там.
На слое А рисуется потолок и «внешние углы». Они реально перерисовываются при движении под нужный угол.
На слое Б рисуется пол и «внутренние углы». Даже если там статичные тайлы они значит рассчитаны под любой ракурс который может дать игра. Возможно их истинное число просто невелико, учитывая что есть флаги отражения тайлов по осям.
Так или иначе углы действительно создаются на лету тайлами или их содержимым и разбиты разумно на оба фона как «внутренние» и «внешние».
Стоит сперва начало посмотреть до первых геймплейных моментов (не пропуская заставки), а потом перемотать на 7:40 и позырить на indoor-геймплей.
Пиксельный буфер в импортных приставках мне не припоминается нигде. Впервые я увидел эту идею в V2Z80 (который задолго до V6Z80P), который из ранних 2000-х, и она показалась мне очевидной и логичной. Чуть позже узнал, что и в советском игровом автомате ТИА-МЦ-1 ~1988 года спрайты тоже сделаны с буфером строки, там даже три буфера 256x4 (16-цветные спрайты). А потом уже стал вникать в эти детали по популярным приставкам, и удивился, что там сделано совершенно иначе.
Ну не снимает, а скорее как то меняет — и еще надо смотреть как. Технически всё-равно надо успеть сформировать строку.
У спец-регистров в принципе bandwidth может как бы и не быть, то есть загрузив их в начале строки можно как бы «бесплатно» не пересекаясь в них лазить хоть каждый пиксель — на то они и регистры.
Но в любом случае победил в высокопроизводительных игровых системах окончательно блиттинг, причём в весь сюрфейс сразу и во много потоков, а роль видеоадаптера свелась к неспешному скармливанию в видеопорт уже готовых полностью пикселей.
Попробую объяснить ещё раз. Эффект состоит из двух частей.
Первая часть 'рисует' залитый круг и трапецию в буфер в основном ОЗУ. Это самая обычная техника рисования полигона. В буфере для каждой строки всего два значения — самая левая точка и самая правая точка отрезка (xmin,xmax). Рисуем круг алгоритмом Брезенхема (потому что быстро): получаем координату точки, смотрим строку в буфере. Если точка нужна левее, чем левая — значим меняем в буфере на более левое значение. Если нужна правее, чем правая — тоже. Таким образом получается буфер ширины и смещения горизонтальных линий на экране, из которых состоит залитая фигура. Эта техника позволяет рисовать только выпуклые фигуры, то есть букву H ей не нарисовать (нужно два отрезка в пределах одной строки). Более сложное объяснение, если вдруг формулами понятнее, чем на пальцах: www.enlight.ru/faq3d/articles/24.htm
Вторая часть просто решает задачу быстрого вывода требуемых линий на экран, имея в распоряжении только железо SMD. С помощью изменения смещений слоя фона по HBlank мы можем вывести любую строку слоя фона в любую строку экрана. Заранее рисуем в слое фона все возможные ширины отрезков, какие нам понадобятся (т.е. от 1 до N пикселей). Теперь смотрим по буферу, подготовленному первой частью эффекта — надо отрезок шириной в три пикселя? Выводим третью строку слоя фона, где как раз и есть отрезок шириной в три пикселя. При этом смещаем её по горизонтали в нужное место экрана. Если у нас отрезок шириной в три пикселя не в одной строке экрана, а во многих — значит во все эти строки выводим строку фона с тремя пикселями.