Войти
ФлеймФорумЖелезо

Блеск и нищета 8/16-битных консолей и ПК (45 стр)

Страницы: 144 45 46 4753 Следующая »
#660
14:48, 11 ноя. 2019

помню была версия ELITE - делаешь копию и ломается радар :)


#661
(Правка: 14:51) 14:50, 11 ноя. 2019

Еще после полноэкранного скроллящегося марио на 50 фпс и некоторых дем которые явственно демонстрировали полноэкранный скроллинг я решил немного вскопнуть эту тему для себя, т.к. вроде как помнил, что спектрум ну никак не может честно проскроллить весь экран на 1 пиксель успев сделать это за 1 кадр.
Первое же что нагуглилось: https://chuntey.wordpress.com/2013/10/02/how-to-write-zx-spectrum… s-chapter-13/ (в самом конце этой главы)
Здесь горизонтальный скроллинг на 1 пиксель вправо, например, предлагается делать последовательностями инструкций

rr (hl) // прокручиваем байт с адресом в регистре hl через флаг переноса
inc hl // переходим к следующему адресу
тут же замечается, что конечно надо во первых развернуть цикл и во вторых инкрементировать не регистровую пару hl, а 8-битный регистр l в нужных местах проверяя на переполнение чтобы править h. однобайтовая арифметика быстрее.
Окай. В рамках теста написал абсолютно тупую скроллилку всю направленную только на демонстрацию скорости:
.lp3    
    dup 32
    rr (hl)
    inc l
    edup
    jp nz, .cont1
    inc h
.cont1    djnz .lp3
т.е. 32 раза разворачиваются инструкции rr (hl) и inc l и потом с возможными поправками h входим в цикл нужное число строк.
Так вот испытания показали, что за 1 кадр такой код успевает проскроллить только порядка половины строк экрана и при этом ни на что особо больше времени не остаётся - а должно и немало!
Ну что ж. Не вариант. Гуглим дальше.

Поэтому в следующий раз нахожу следующее: http://ralphbecket.blogspot.com/2018/07/high-speed-full-screen-dr… ng-on-zx.html
Там так то лучше почитать всё - но вот главная идея. Цель - залить экран за 1 кадр развёртки хотя бы поблочно, т.е. знакоместами.
Первая гениальная идея - спрайты 8x8 представлены кодом:

DrawSomeBitmapCell:
    ld A, SomeAttr
    ld (DE), A
    inc E
    ld (HL), SomeBitmapByte0 : inc H
    ld (HL), SomeBitmapByte1 : inc H
    ld (HL), SomeBitmapByte2 : inc H
    ld (HL), SomeBitmapByte3 : inc H
    ld (HL), SomeBitmapByte4 : inc H
    ld (HL), SomeBitmapByte5 : inc H
    ld (HL), SomeBitmapByte6 : inc H
    ld (HL), SomeBitmapByte7 : add HL, BC
    ret
Здесь предполагается что при входе в процедуру DE настроен на атрибут цветов куда надо занести цвет знакоместа, в HL находится адрес начала знакоместа, а в BC константа перехода к следующему знакоместу 1 - $0700.
Изображение спрайта для скорости прямо встроено в код immediate-константами конечно раздувая пространство, но увеличивая скорость. Прикольный ход, некое развитие идей ldpush (или наоборот).
Но вот какой момент - если ячейка должна быть пустой, то достаточно следующей процедуры:
DrawSomeBlankCell:
    ld A, SomeAttr
    ld (DE), A
    inc E
    inc L
    ret
Т.е. просто в атрибут заливаются одинаковые цвет тона и цвет фона и таким образом содержимое пикселей становится вообще неважно - и переход к следующему знакоместу вырождается в inc L в силу устройства видеопамяти спектрума. Т.е. пустые ячейки будут заполняться заметно быстрее... Это тоже крайне удачный ход!
Дальше-больше, если вы подумали что теперь программа будет в цикле вызывать эти процедуры ориентируясь на некую таблицу тайлов, то тоже нет. :D
Делается следующая таблица чистых адресов процедур которые рисуют те или иные спрайты 8x8:
DrawList:
    dw Draw0, Draw1, Draw2, ..., Draw31, [fix up]
    dw Draw32, Draw33, Draw34, ..., Draw 63, [fix up]
    ....
    dw ..., Draw767, [finish up]
А далее... SP ставится на начало DrawList и делается RET! :D
Т.е. процедуры возвращаясь будут просто вызывать следующие в списке процедуры пока не войдут в процедуру [finish up] которая восстановит стек и продолжит нормальную работу программы.
Так же нужны дополнительные процедуры [fix up] которые будут выправлять адреса HL и DE в конце строки (раз на 32 спрайта) под стать раскладке видеопамяти спектрума. Но их все две по идее должно быть - в конце регулярной строки и в конце трети экрана.

Так вот, по прикидкам автора статьи по ссылке такой код способен успеть залить весь экран спектрума знакоместами за 1 кадр при условии что пустых спрайтов будет больше 66%.

И вот я жопой чую, что код порта марио полагается на похожую технику - просто не скроллит честно пустые знакоместа. Но надо заметить, что его код какой то другой, ибо в описанном выше скроллинга и нет в общем то.

#662
21:01, 11 ноя. 2019

Блин, только дошла очевидная вещь - то что в марио постоянно меняются кадры тайлов и получается некое "подрагивание" это же давно известный мне гигаскрин - когда сменой изображения на чётных и нечётных кадров достигается расширение цветовых ощущений. Оно может и мельтешит в эмуляторе, но многие тайлы начинают выглядеть четырёхцветными.
Теперь вообще голова кругом - мало того что полноэкранный скроллинг, так ведь еще и двух пиксельных буферов. 8()
Вообще не понимаю какой трюк лежит в основании.

#663
21:12, 11 ноя. 2019
+ SECAM
Вдруг подумалось, что раз уж сами телевизионные компании грешили цветовым клешингом на две строки, то можно ли было и в ZX-Spectrum пойти «в ту степь»?
То есть, атрибуты цвета из памяти считывались бы единожды и в монитор передавались бы 8 раз через 8 линий задержек по 64 мкс. Причём, для растягивания по-горизонтали цвета знакоместа используется 8 линий задержек на 125 нс.
Я понимаю, что даже в 80-х подобный дизайн синрхрогенератора был бы бредом. Но в ЭВМ 50-х такая память была популярна.

P.S.: Микросхемы динамической памяти не так уж далеко ушли от линий задержек, грубо говоря…

#664
21:34, 11 ноя. 2019

Alikberov
> То есть, атрибуты цвета из памяти считывались бы единожды и в монитор
> передавались бы 8 раз через 8 линий задержек по 64 мкс.

Непонятно как это. В одной строке 32 знакоместа с разными атрибутами - почему линий задержки 8?
Внутри знакоместа линия задержки в принципе не нужна - там и так значение как бы закешировано до перехода к следующему знакоместу.

#665
21:46, 11 ноя. 2019

Alikberov
> Чтобы один атрибут не считывать ещё 7 раз в строках ниже, задерживаем его 7 раз
> последовательно

А, я наверное понял. У Apple I видеочип весь был на "цифровых линиях задержки" - сдвиговых регистрах: https://gamedev.ru/flame/forum/?id=226622&page=14#m201
Гипотетически действительно можно взять 8 сдвиговых регистра на 32 бита и сделать из них кольцо в котором прокручивать 8 раз 8 строк из 32 знакомест так что в первый цикл кольцо заполняется, а в остальные считывается.
Не знаю сколько в этом смысла.

#666
(Правка: 21:53) 21:52, 11 ноя. 2019

Alikberov
> Тaк же одна строка - ~64 мкс. Чтобы один атрибут не считывать ещё 7 раз в
> строках ниже, задерживаем его 7 раз последовательно: На 64, на 128, на 192, на
> 256, на 320, на 384 и на 448 мкс.

Зачем этот геморрой, если палитру можно переключать хоть каждую строку, программно (ну, конечно, модифицировать ЦАП и регистр палитры, нужно будет со стороны железа). 

#667
6:48, 12 ноя. 2019

Немного поисследовал в в эмуляторе порт марио. Всё-таки лютый интерес у меня возник.
Во первых - сам герой передвигается только шагами по 2 пикселя без бега и 4 пикселя с бегом. Очевидно что это одновременно является теми величинами прокруток которые движок поддерживает.
Далее для ускорения и отсечения лишних инструкций самая правая колонка знакомест заполнена атрибутами чёрными как для фона так и для тона. Хороший давно известный трюк позволяющий при появлении новых тайлов справа при скролле фигачить их сразу байтами без необходимости проверять на обрезку границей экрана.
Но что интересно то же самое сделано для целых двух колонок слева - куда изображение уплывает. Как минимум одна скрытая таким образом колонка возможно тоже полезна для ликвидации обременительных условий, но еще одна лично у меня вызывает ощущение что подрезка производилась под производительность в критических местах. Пока непонятно.
Остальные атрибуты все содержат бит повышенной яркости, чёрный цвет фона и переменный цвет тона который в незанятых ничем тайлах как правило белый. Т.е. одними только атрибутами как код выше скрывать тайлы оно не скрывает, но это логично т.к. поверх выводятся спрайты персонажей.
В общем подозреваю что движок как то берет уже готовые заранее прокрученные и выставленные во всех возможных смежных комбинациях тайлы и прямо фигачит их в знакоместа не совершая фактической попиксельной прокрутки - при этом умело умея обходить обработку пустых знакомест кроме случая когда их надо создать.

#668
7:42, 12 ноя. 2019

P.S.
Догадался еще в эмуляторе заполнить знакоместа краевых колонок черно-белыми атрибутами чтобы видеть что там происходит. Забавно.
Действительно в краевой колонке справа сразу целиком появляются вновь возникающие на поле тайлы, но больше того - синхронно они же (немного смещённо-поломанные в силу раскладки видеопамяти) появляются в самой левой колонке назначение которой я не мог понять выше. Выходит что таким образом тайлы вталкиваются сразу блоками 16x16, что видимо проще и возможно быстрее. Судя по всему при этом самая нижняя-правая полоска пикселей требует особого отношения, т.к. у неё нет "края слева". Далее тайлы скроллятся получается что выпадая с левого края в правый и из него на видимое поле, но при этом и в первую и во вторую колонки слева тайлы "заталкиваются" с игрового поля.
Полностью подтвердилась гипотеза что игра обрабатывает только блоки в которых есть битмапы, причём довольно эффективно. Например если в левые колонки запихался целиком тайл блока с поля и при этом после него идёт пустота, а с правого края экрана ничего не появляется (чтобы начать заполнять самую левую колонку), то там навечно застывает этот запихнутый туда и теперь невидимый за чёрными знакоместами тайл 16x16 и пока до него не доедет очередной тайл с видимого поля или пока слева на его высоте чего то не появится - он продолжит висеть там незримый и неподвижный. Т.е. "вдвиг" пустых тайлов просто ничего не делает. Noop.

Ок, гипотеза верна - но как игра знает какие тайлы надо обрабатывать а какие нет?
Есть подозрение уже что есть просто заранее предрассчитанная структура данных полученная прекомпиляцией в которой для каждой позиции на поле можно быстро получить какие тайлы на экране надо скроллить.

#669
8:22, 12 ноя. 2019


Вoт блин! Загрузить бы эти демки в мой Atari!
#670
12:01, 12 ноя. 2019

Прикольно они на конечностях робота сымитировали "освещение по Фонгу" :)

#671
(Правка: 21:43) 21:32, 12 ноя. 2019

=A=L=X=
> У Apple I видеочип весь был на "цифровых линиях задержки" - сдвиговых
> регистрах: https://gamedev.ru/flame/forum/?id=226622&page=14#m201
Выхoдит, моё ноу-хау - не моё.
У меня была идея дизайна ПК, где при записи пикселя в видеопамять процессор уходил в долгое Wait-ожидание, пока адрес с процессора не совпадал с адресом синхрогенератора.

Dmitry_Milk
Кaк-то я прикалывался на Atari в студию кабельного телевидения и рисовал настроечную таблицу, записывая на ВМ12. Года 22 назад, по-моему. Тот Atari всё кореец просил для своей коллекции.
Без доков тяжело было с графикой работать, так как в Atari видеорежимы можно смешивать и чередовать от текста 40x25, до графики 80x200x16 / 160x200x4 / 320x200 кажется.
Методом тыка я что-то побочно там добивался, но не мог справиться, так как тогда для меня та графика была экзотикой. Как и звук, правда не стерео.
Программ - 0, документации - 0. Лишь советский справочник 80-х по Бейсикам разных ПК.

#672
23:06, 12 ноя. 2019

Новостная заметка на Хабр
Историк музея опубликовал схемы Atari 7800

#673
23:31, 12 ноя. 2019

Alikberov
> на Atari в студии кабельного телевидения

Да ты мажор был :)

#674
1:44, 13 ноя. 2019

Dmitry_Milk
> Да ты мажор был :)

Кaк-то я прикалывался на Atari в студию кабельного
Нe прикалывался в студии, а прикалывался в студию. Ну, типа, сидел в гостиной с ВМ12 и Atari, а сигнал передавался ещё и в другую комнату.
Страницы: 144 45 46 4753 Следующая »
ФлеймФорумЖелезо