• avatar Vinnny
  • 2
зафиксирую ссылку на предоставленные игры, а то найти её почти нереально :)
  • avatar aa-dav
  • 2
Marsmare: Alienation — огонь! Прошёл и отзыв написал.
  • avatar Vinnny
  • 0
быстрее бы декабрь, холодно :)
Потрясающее комьюнити. Отличные знания.
  • avatar nodeus
  • 2
Добавил в лист.

Господа, пройдемте и проголосуем за работы!
  • avatar SAA
  • 0
«интереснее» в том что от стандартных корок, которые не тянули, зато имели свои инструменты вроде ЯВУ и трансляторов ассемблера, пришлось перейти к собственной архитектуре которая обеспечивала приличную пропускную, но потребовала написать и трансляторы и компилятор и отладчики. Это все очень интересно, любительство оно такое в чем то беспощадное и требовательное, азартное :)

Суть же телодвижений с спрайт-тайтлами, ну в какой то момент показалось что имея аппаратное наложение слоев друг на друга, можно наслаждаться отрисовкой в квази-фрейм буфере (можно так группировать тайтлы/спрайты что в области графического представления, в области спрайтов — будете работать с массивом небольшой размерности, скажем 256х128 или 256х256. И это казалось что ли убер экономией видеопамяти, казалось конечно… Ну аппаратное наложение слоев конечно сильно экономило время и такты, но вот отрисовка в области спрайтов какой либо анимации… все равно вылилось в полноценный фрейм-буфер, который из блочного ОЗУ ПЛИС само собой переполз в SDRAM.
  • avatar Vinnny
  • 1
свежак
2020 Kazan Dacha Meeting (3.11-6.11)
photos.app.goo.gl/DwxHmyi3Vx4AB3pGA
  • avatar nyuk
  • 0
Я познал Makefile. Ну ладно, ок, не совсем еще познал. Как минимум, талмуд стоило бы прочитать.

В общем, все части демы, сколько бы их не было, собираются и пакуются одним сценарием. Чтобы добавить сборку еще одной части, просто добавляю её имя в перечисление. Ну и там контроль наличия файлов, чтобы каждый раз не пересобирались.

gist.github.com/akanyuk/7d98ffeeac1316b42d10917f208b85e2
Да, я прочёл. Ближе всего идея тумана похожа на нюковский запилятор, но применённый не к графике, а напрямую к коду.
Хех, «интереснее» — это в смысле преодоления собственноручно созданных себе трудностей? И зачем на полноценную корку вешать функции очень примитивного блиттера, какой в чистом виде получился бы быстрее и проще?

Что касается аппаратных тайлоспрайтов, это же древнее решение для древних же проблем, которые давно отпали сами собой (то есть тормознутости и малых объёмов видеопамяти). Никаких разумных причин применять это решение сейчас при создании нового псевдоретро железа не вижу. Смысл есть только в ускорении относительно старого готового железа новой прошивкой (дендиконфа)
  • avatar SAA
  • 1
Да все отлично описали! Особенно пункт б) автоскролинг реализованный на счетчике адреса чтения данных спрайта со смещением — классика, там по сути делать ничего не надо, пиши смещение и весь экран горизонтально или вертикально скролируется. Но :) хотелось чего то очень продвинутого и универсального, без заморочек, настолько быстрого что бы можно было писать в ЯВУ, даже без оптимизации — и в итоге для нас это оказался clear render для frame buffer. Рискну предположить почему так, потому что читать про преодолевание трудностей это одно — здорово, очень интересно, испытываешь кураж прошедшего головоломное приключение человека и гордишься им. Однако читая ты не можешь оставить без анализа те трудности которые пришлось преодолевать другому и заранее закладываешь себе дорожку без них. С одной стороны — красивый хак, с другой — универсальность и избежание хака. Ну это так мысли в слух, возможно я не прав :)
  • avatar aa-dav
  • 1
Ясно. Классические аркадно-консольные архитектуры решали все такие проблемы методично ровно по линии меньшего сопротивления:
а) обновлять VRAM можно только во время VBlank
б) слой(и) фона аппаратно скроллируется «с проворотом» так что скроллерам надо лишь раз на 8 пикселей прокрутки обновлять одну полоску тайлов фона(ов)
в) спрайты это отдельный фон из независимых объектов (отчего были всегда лимиты на количество спрайтов отображаемых в одной строке)
г) цвета палетризированы в два этапа — в плитке фона или спрайте есть селектор одной из нескольких разных палитр отчего информация о цвете еще сжимается.
Таково как бы классическое противостояние между Tile/Sprite Engine и Framebuffer render.
  • avatar SAA
  • 1
Таки нашел, глубоко в историю ушло :) Если мне опять же память не изменяет то тут 6809, и конечно с одним единственным танком он справляется. Танк состоит из 4 спрайтов. Все в одном слое, видео с наложением слоев не нашел, только фото монитора. Видно что на один такой примитив да успевает отрабатываться.
Наложение с прозрачностью
Демо вращение гусениц в 4 спрайтах
  • avatar SAA
  • 1
Спрайт и Тайл — думал это одно и тоже. Представим себе массивы 32 x 24 таких массивов 3 штуки.

char layer[3][32*24];

Я перешел на Си, что было понятно о чем я. Это не сам спрайт, разумеется. Но, ячейка массива содержит число от 0 до 255, являющееся индексом (idx) спрайта. До спрайта мы еще не добрались, так как лежит он в каком то линейном участке памяти по смещению idx*sizeof(sprite). Если спрайт 32х32 8 бит (говорю «если» потому что уже не помню точно что там было) цвета каждой точки то его sizeof = 1024 байта или 1Кб. Вопрос доступны ли они все в пространстве процессора? Конечно нет, так как даже 64 таких спрайта займут все адресное пространство к примеру 6502. Но железке на это наплевать так как считанный адрес спрайта, например address = layer[0][idx] << 10, это просто шина нужной разрядности с которой адрес приходит на ША блочного ОЗУ ПЛИС. Конечно там начинается сложность с тем что развертка по строке движется линейно по экрану, переходя с одного спрайта на другой и поэтому часть адреса постоянна, а часть обновляется счетчиком — но не об этом сейчас. И так у нас три канала по которым летят данные из области ОЗУ с битмапом спрайта, с его непосредственным содержимым. Эти три канала D0,D1,D2 мы можем перемешать по принципу встреченного байта прозрачности (для простоты просто нуля). Если в D0 в данном такте появился 0 то значит нужно выдать ARGB из канала D1, но если и в канале D1 у нас тоже прозрачный пиксель (ноль), то берем ARGB из канала D2. Это все довольно просто описывается в HDL, не в ЯВУ.
Имея такую аппаратную примочку мы освобождаем процессор только от маскирования потока из областей спрайтов и необходимости постоянно лить данные спрайтов, когда они меняются на экране, в фрейм-буфер. Для Спрайтового движка понятия фрейм-буфер я считаю не применимо. Это по сути текстовый экран только буква не 8х8 а 32х32 и летит не с знакогенератора (который может быть и в ПЗУ), а из области ОЗУ со спрайтом. Мы меняем код спрайта в этом слое и в течении 12 тактов, без каких либо затрат на пересылку байт битмапа 32х32 (а это прилично!) получаем смену изображения. Все что нам нужно это просто загодя (за 12 тактов раньше) начать формировать растр по строке. Так как данные будут сыпаться в этой конвейер друг за другом, перерывов между ними не будет и работать можно с дичайшим FPS меняя спрайты всего экрана чуть ли не 100 раз за кадр. Заменить 768 байт на новые — это не вопрос даже для 6502 с 1,75МГц клока.
Но… грустно становится когда нам надо произвести скролинг внутри знакоместа, ну кого к примеру устроит резкий прыжок танчика на 32 точки вперед? И вот тут бывает так что танчик то не 32х32, а нечто побольше. Мало того хотелось бы двигать его не только прямо, а скажем по диагонали или вообще под произвольным углом. И мы начинаем копировать байты внутри спрайтовой области ОЗУ. А поскольку плана у нас три, и мы хотели бы что то еще двигать на задних планах, траву, кроны деревьев, какие либо еще произвольные объекты. То увы даже загнав имеющуюся корку 6502 на 50МГц (выше не получалось) удается разве что 20FPS обеспечить. Разговор конечно не про один объект, а про кучу различных. И даже 6809 выдавал до 30FPS на сценах, как ниже. Не из за одного «танчика», конечно это все затевалось. У меня к сожалению ничего продемонстрировать не осталось из того проекта, так как уже на симулях стало понятно — что это все не то. Но можно показать к чему пришли.
В итоге это все вылилось в фрейм-буфер 1024х768х8бит с двойной буферизацией, и то что там применено в качестве процессора :) отдельная песня — вывозило только 75% заполнения экрана. Но вот даже такая демка, которую для этой аппаратуры писал мой товарищ — 8 битные корки и даже 16 битные корки процессоров ложило наглухо. А это наверное 10%-20% имеющейся пропускной.
Demo clear render
  • avatar aa-dav
  • 1
Такое ощущение, что тут речь не про спрайты как они преимущественно понимаются — массив имеющих независимые координаты объектов на экране где мы выбираем какие тайлы в спрайтах отображаются, но их количество как правило не покрывает все пиксели экрана и главное что они все могут быть выведены хоть в одну координату оставив остальной экран пустой. Тут же больше похоже что речь про тайловые фоны — квадратно-гнездовые сетки из тайлов иногда аппаратно скроллируемые, но как одно целое. Они по определению всегда покрывают весь экран и образуют квадратно-гнездовую сетку. В последнем случае становится понятно почему нужно попиксельно возится со скроллингом «спрайтов» в памяти спрайтов. Но даже если и так, то всё-равно не очень понятно что тут 8-битные процессоры не вывозили — если выводом такой графики заведует отдельная микросхема то они хотя бы небольшое количество тайлов и не вижу куда бы тут танчики не влезли — подвижных там не очень много… Не кажется чем то сверхъестественным.
  • avatar SAA
  • 0
т.е. стандартно мы бы накладывали поверх спрайт скажем с травой, спрайт с дорогой, поверх которой накладывался бы «танчик». Т.е. все три спрайта находятся в своих пространствах по одной координате X,Y. Но маскируются друг другом с приоритетом по каналу. Канал 1 перекрывает канал 2, канал 2 перекрывает канал 3, пиксель с цветом «прозрачный» может вылезти на канал 1 из любого канала. Наверное я все еще сильней запутал, но смысл очень простой. Есть три экрана спрайтов заданных байтом 32х24 знакоместа. Это три независимых плана, которые контроллер объединяет в один видимый на экране монитора. Спрайты находятся в своих областях ОЗУ как объекты 32х32х256. Прозрачный цвет не маскируется (допустим 0x00) и через него мы можем увидеть любой пиксель спрайта нижнего плана (2,3).
  • avatar aa-dav
  • 0
если бы было три спрайтовых плана с приоритетом отрисовки
Непонятно что это точно означает.
  • avatar SAA
  • 1
Спасибо за статейку! Читать такие вещи очень интересно, на хабре читал про 6809 с огромным интересом и продолжение про apple вполне себе дополняет. Особенно интересно было узнать что у 65С816 есть такие инструкции и DP.

Как то с другом мы обсуждали возможности в разрезе Clear reander engine vs Sprite/Tile Engine. Ну и закусились на тему, а что было бы если бы у бабушки были бы… если бы было три спрайтовых плана с приоритетом отрисовки (подобие Z-буфера). Было бы мол тогда интересней программить в ЯВУ те же танчики? Ну сказано сделано, примерно недели две возни с верилогом и готовый адаптер для отрисовки такой графики появился. Повозится конечно пришлось, что бы выйти на времянки 1024х768 (ЕМНИП). 12 стадий в конвейере устройства, причем регистры на стадии в ФУ конвейера, вовсе нет — простенькие мультиплексоры даже пришлось огораживать. Какое то время мне казалось что я не вывожу на этой ПЛИС задачу и как бы вообще на голую шину не пришлось ставить регистры в отрезки между ФУ. Но нет обошлось 12 стадиями. Жуткое чудо юдо.


Да, но это я к тому что вот это вот убер устройство хотели повесить на корку 6502, ну и оно не потянуло. Потом я рассматривал 6809 и тоже нет, не потянуло :) Потому что, если бы только проблемы отрисовки спрайтов поверх других спрайтов с аппаратным перекрытием, а ведь еще и скроллинг этих спрайтов попиксельно в памяти самих спрайтов. После этого как то утвердился в мысли о том что такого рода аппаратура мало что даст для программера, нужен именно прокаченный процессор и желательно такой который может за такт не одну инструкцию, и при это еще бы и асинхронно.
  • avatar aa-dav
  • 0
По ссылке там есть еще вторая часть статьи где описывается трюк с туманом. Я глубоко не вчитывался, так поверхностно текст просканировал глазами и похоже что какие то трюки с лукап-таблицами и вроде тоже непростые.
Ссылку на пост на Хабре мне прислали товарищи, и хотя читать её было весело, по сути ничего нового для квалифицированного Z80 кодера там не сообщалось. А вот этот трюк со вторым планом я пока нигде не встречал, спасибо за пересказ. Нужно будет прочесть первоисточник целиком, похоже что там у ребят всё очень благополучно с креативным мышлением.