Просто для информации.
Pape писал в книге что он оптимизировал код. Это очень свообразная оптимизация. Даже тот фрагмент что в книжке — без бутылки не разобраться.
Stalker (автор STS) в те годы пытался активно дизассемблировать именно R-Type. Как видно, не особо что вышло…
Чтобы два раза не вставать, из интересного в играх.
Savage (I) — рисует спрайты с создаваемой на лету «автомаской». «Автомаска» это биты графики спрайта, сдвинутые влево, сдвинутые вправо, наложенные по OR и инвертированные.
Т.е. из 00010000 сделает 00111000 и в итоге маска 11000111.
Примерно так же, как делается утолщеннный фонт. Но он это делает, естественно, по таблице. Хотя, припоминая дела 26-летней давности, я пробовал сранивать свою таблицу полученную описанным способом и она во многих местах не совпадала с имеющейся таблицей. Поэтому толи они вручную подредактировали таблицу (что может быть) толи сделали таблицу масок байтов вообще полностью вручную.
Dark Fusion делает 5 спрайтов бэкграунда (сдвинутых на 2pix), обеспечивая спрайты с пустым байтом-«концевиком» спереди и сзади, которым она и затирает фоновую графику при скроллинге. То есть графика шириной 3 байта имеет след. модификации:
00000000 11111111 11111111 11111111
00000011111111 11111111 11111111 00
000011111111 11111111 11111111 0000
0011111111 11111111 11111111 000000
11111111 11111111 11111111 00000000
Xecutor — определяет столкновения, читая собственную графику кораблика с экрана после того как выведет всех enemy-«тварюшек».
Jack The Nippper II не ждет int (как и подавляющее число игрушек) и использует технику как я её назвал «микробуфферинга», т.е. глобального бэкбуфера нет, локально бэкбуферится только то, что в данный момент накладывается друг на друга.
Из интересного не в играх — Shock последняя часть, с белыми «кувыркающимися» буквами SHOCK и звёздами — ВСЁ рисует ДО луча, то есть отрисовывает всё за верхний border. И вообще, интересный факт из всех демок E.S.I. А в курсе ли вы, что _ВСЕ_ они идут на 48к компьютере? Интересно, почему и зачем это. AY чип в оригинальном спектруме был только на 128к модели. Но графика вся выводится в 48к режиме, используя «гонки с лучом», и не просто графика, не используется память, все демки работают в 48к.
Из интересного. Когда-то очень давно, когда я увидел Lyra, я считал что демки _принципиально_ должны быть сделаны именно так, т.е. строго под 48к модель, несмотря на то что есть doublebuffered 128к экран. И использование doublebuffering'а мы считали «ламерством». Правда, жизнь расставила свои приоритеты, пока я усердно в поте лица устраивал гонки с лучом (например, сортируя спрайты), подъехала CB Satisfaction, где невозмутимо используется два экрана… =)
Насчет гонок с лучом. Гуглим книжку «RACING THE BEAM».
Вопрос именно в том как получается всё плавно но за 2 инта и без разрывов.
Любая программа, привязанная к int'у и перерисовывающая всё за 1/25sec (2*int) работает достаточно плавно.
«Разрывы» — это tearing графики? Zynaps все же синхронизируется с int'ом.
Tearing в Zynaps ещё как есть, просто он очень специфичный, надо знать, как он выглядит: время 3:52 и внимательно-внимательно смотрим далее. А столь специфичен он потому что они намеренно делают следующее. Они не обрабатывают «bulk» (т.е. широкую площадь) до и после луча (в месте потенциального сечения). Tearing будет заметен глазом когда МНОГО графики было ДО луча и МНОГО графики будет ПОСЛЕ луча, таким образом делая полосу «сечения» лучом хорошо заметной (МНОГОЕ сдвинуто до (выше луча) и МНОГОЕ (ниже луча) еще не сдвинуто). Вместо этого они обрабатывают по знакоместам (в некотором смысле симулируя столбцовый экран, бггг, вижу тут Lethargeek'а). Когда графика перерисовывается по знакоместам, проблема tearing'а случится только в нескольких «неудачных» знакоместах, попавших «под луч». Вдобавок, как я полагаю (не уверен на 100%), они используют трюк, начиная подвижную графику обновлять в рандомном порядке, таким образом делая «несчастливыми» знакоместами каждый раз разные. Это гораздо менее заметно для глаза.
Дичь с Zynaps совсем в другом. Насколько это мне известно с 90х, он рисует инверсную графику, накладывая её по AND и затирает атрибутами :))
— это изображение с paper black и white ink, т.е. в атрибутах байт 07.
Потому что за 1 int (1/50sec, 50fps) не успевает.
Т.е. он где то бэкбуферит чтобы потом за два инта проскочить и вылезти как по его документации писано «за два инта на 25 фпс»?
Вопрос до конца не понятен. Почему за 2int'а? Потому что за 1 int (1/50sec, 50fps) не успевает. Не хватает производительности CPU. Если на реальном «железном» спектруме включить 7Mhz «turbo» Zynaps начинает стабильно работать в 50fps, причем графика не сечется, спрайты монстриков не исчезают.
по геймплею чётко видно, что нижние и верхние препятствия на скроллящейся части экрана никогда не пересекаются лишь приближаясь ровно к центру
Есть фоновая графика уровня в Zynaps и по центру, это не на первом уровне.
Относительно «демо-анимы» можно поговорить отдельно, хотя не знаю интересна ли тебе эта тема. Я лично считаю аниму просто один из приёмов в репертуаре, не главным, но безусловно полезным. Я делал демо чисто на аниме, я делал демо с элементами анимации; я не знаю всё, что закодил ты, но я смотрел Iris и я могу себе представить, что для тебя как для олдскул кодера у меня анимы очень много. Поэтому скажу так. Не всё что я делаю в своих демо основано на быстро распаковываемых данных. Но я безусловно держу эту опцию в уме и при необходимости/возможности — применяю.
Я не считаю что всё нужно паковать одним компрессором. Есть компрессоры которые жмут хуже, но намного быстрее распаковывают; они полезны в своей нише. Есть компрессоры, которые прекрасно жмут, но распаковывают часами (см. Shrinkler на диаграмме в комментарии чуть выше).
Короче, есть некая условная грань оптимальности Парето. Как бы если ты готов затратить некое конечное кол-во вычислительных ресурсов, ты не сможешь получить сжатие выше, чем позволяет эта грань. Грань на данным момент показана на диаграмме в комментарии выше по треду. Глядя на эту грань, я выбираю себе лучший компрессор для текущей задачи. Например, для универсального сжатия в ядре демо я сейчас использую MegaLZ; LZSA2 для меня в этой роли сейчас на втором месте, из-за слегка худшего сжатия графики. Но если в демо что-то не будет успевать на стыках, я поставлю LZSA2 и решу эту проблему. В то же самое время, один из эффектов у меня сейчас в демо требует покадровой распаковки атрибутов (пикселы сделаны эффектом, а вот раскраска — анимацией). В этом случае скорость абсолютно важна, поэтому в эффекте задействован LZSA1.
Некоторые успехи товарищей на других платформах ты можешь увидеть на моей диаграмме. Если очень коротко, я протестировал дохренища всего, не думаю что много упущено. Всегда есть потенциал что-то упустить из вида; но фундаментально, на Z80, с моей точки зрения все ведущие игроки сейчас обозначены.
И, да, запаковка на Z80 представляется мне абсолютно архаичной. С моей точки зрения в ней тупо нет смысла.
Напомни, что именно является «святым граалем» твоих поисков оптимального компрессора.
Могу ошибаться, но с моей точки зрения, это поиск наиболее сильного сжатия (требование №1 к любому компрессору) в то же время при самой высокой скорости _распаковки_ на z80.
При этом запаковка на z80, как таковая, абсолютно не принимается в расчет.
Видимо, всё это для целей демо-«анимы», т.е. основанных на быстро распаковываемых данных. Подтверди, так это или не так.
Изучал ли ты успехи товарищей на других 8-битных платформах? Каковы они?
На этом графике показаны результаты 3х распаковщиков MegaLZ — самый медленный это старый («DEC40.asm», 110 байт), совпадающий по скорости с Hrum — это новый оптимизированный по размеру (92 байта) и тот, который чуть быстрее 3*LDIR — новый оптимизированный по скорости (234 байта).
Учти что график генерируется на основе старого корпуса (того же, что в 2017 году), а табличка выше — на основе нового. Я буду переходить на новый корпус из-за того, что в старом было маловато графики (где-то 20% данных) и великовата средняя длина файла, что слегка искажает результаты тестов (скажем, на старом корпусе LZSA2 слегка обходит MegaLZ по сжатию, т.к. имеет намного большее окно, а отставание на графике не так заметно из-за небольшого кол-ва графики в корпусе). С поправкой на эти моменты, вот где я сейчас:
программисту на опкоды тоже начхать обычно, важен только полный (со всеми дополнительными данными) размер команд, если он у всех одинаков (как в исходном арме) или можно подобрать аналоги нужного размера — тогда это еще можно с толком использовать, если нет — ну не похрен ли, сколько там опкод занимает
www.youtube.com/watch?v=gVAtXqESDcs
R-TYPE アール・タイプ в японском оригинале звучит как «Ару Тайпу»
Pape писал в книге что он оптимизировал код. Это очень свообразная оптимизация. Даже тот фрагмент что в книжке — без бутылки не разобраться.
Stalker (автор STS) в те годы пытался активно дизассемблировать именно R-Type. Как видно, не особо что вышло…
Savage (I) — рисует спрайты с создаваемой на лету «автомаской». «Автомаска» это биты графики спрайта, сдвинутые влево, сдвинутые вправо, наложенные по OR и инвертированные.
Т.е. из 00010000 сделает 00111000 и в итоге маска 11000111.
Примерно так же, как делается утолщеннный фонт. Но он это делает, естественно, по таблице. Хотя, припоминая дела 26-летней давности, я пробовал сранивать свою таблицу полученную описанным способом и она во многих местах не совпадала с имеющейся таблицей. Поэтому толи они вручную подредактировали таблицу (что может быть) толи сделали таблицу масок байтов вообще полностью вручную.
Dark Fusion делает 5 спрайтов бэкграунда (сдвинутых на 2pix), обеспечивая спрайты с пустым байтом-«концевиком» спереди и сзади, которым она и затирает фоновую графику при скроллинге. То есть графика шириной 3 байта имеет след. модификации:
00000000 11111111 11111111 11111111
00000011111111 11111111 11111111 00
000011111111 11111111 11111111 0000
0011111111 11111111 11111111 000000
11111111 11111111 11111111 00000000
Xecutor — определяет столкновения, читая собственную графику кораблика с экрана после того как выведет всех enemy-«тварюшек».
Jack The Nippper II не ждет int (как и подавляющее число игрушек) и использует технику как я её назвал «микробуфферинга», т.е. глобального бэкбуфера нет, локально бэкбуферится только то, что в данный момент накладывается друг на друга.
Из интересного не в играх — Shock последняя часть, с белыми «кувыркающимися» буквами SHOCK и звёздами — ВСЁ рисует ДО луча, то есть отрисовывает всё за верхний border. И вообще, интересный факт из всех демок E.S.I. А в курсе ли вы, что _ВСЕ_ они идут на 48к компьютере? Интересно, почему и зачем это. AY чип в оригинальном спектруме был только на 128к модели. Но графика вся выводится в 48к режиме, используя «гонки с лучом», и не просто графика, не используется память, все демки работают в 48к.
Из интересного. Когда-то очень давно, когда я увидел Lyra, я считал что демки _принципиально_ должны быть сделаны именно так, т.е. строго под 48к модель, несмотря на то что есть doublebuffered 128к экран. И использование doublebuffering'а мы считали «ламерством». Правда, жизнь расставила свои приоритеты, пока я усердно в поте лица устраивал гонки с лучом (например, сортируя спрайты), подъехала CB Satisfaction, где невозмутимо используется два экрана… =)
Насчет гонок с лучом. Гуглим книжку «RACING THE BEAM».
Любая программа, привязанная к int'у и перерисовывающая всё за 1/25sec (2*int) работает достаточно плавно.
«Разрывы» — это tearing графики? Zynaps все же синхронизируется с int'ом.
Tearing в Zynaps ещё как есть, просто он очень специфичный, надо знать, как он выглядит: время 3:52 и внимательно-внимательно смотрим далее. А столь специфичен он потому что они намеренно делают следующее. Они не обрабатывают «bulk» (т.е. широкую площадь) до и после луча (в месте потенциального сечения). Tearing будет заметен глазом когда МНОГО графики было ДО луча и МНОГО графики будет ПОСЛЕ луча, таким образом делая полосу «сечения» лучом хорошо заметной (МНОГОЕ сдвинуто до (выше луча) и МНОГОЕ (ниже луча) еще не сдвинуто). Вместо этого они обрабатывают по знакоместам (в некотором смысле симулируя столбцовый экран, бггг, вижу тут Lethargeek'а). Когда графика перерисовывается по знакоместам, проблема tearing'а случится только в нескольких «неудачных» знакоместах, попавших «под луч». Вдобавок, как я полагаю (не уверен на 100%), они используют трюк, начиная подвижную графику обновлять в рандомном порядке, таким образом делая «несчастливыми» знакоместами каждый раз разные. Это гораздо менее заметно для глаза.
Дичь с Zynaps совсем в другом. Насколько это мне известно с 90х, он рисует инверсную графику, накладывая её по AND и затирает атрибутами :))
— это изображение с paper black и white ink, т.е. в атрибутах байт 07.
Вопрос именно в том как получается всё плавно но за 2 инта и без разрывов.
Т.е. он где то бэкбуферит чтобы потом за два инта проскочить и вылезти как по его документации писано «за два инта на 25 фпс»?
Вопрос до конца не понятен. Почему за 2int'а? Потому что за 1 int (1/50sec, 50fps) не успевает. Не хватает производительности CPU. Если на реальном «железном» спектруме включить 7Mhz «turbo» Zynaps начинает стабильно работать в 50fps, причем графика не сечется, спрайты монстриков не исчезают.
Есть фоновая графика уровня в Zynaps и по центру, это не на первом уровне.
Короче, есть некая условная грань оптимальности Парето. Как бы если ты готов затратить некое конечное кол-во вычислительных ресурсов, ты не сможешь получить сжатие выше, чем позволяет эта грань. Грань на данным момент показана на диаграмме в комментарии выше по треду. Глядя на эту грань, я выбираю себе лучший компрессор для текущей задачи. Например, для универсального сжатия в ядре демо я сейчас использую MegaLZ; LZSA2 для меня в этой роли сейчас на втором месте, из-за слегка худшего сжатия графики. Но если в демо что-то не будет успевать на стыках, я поставлю LZSA2 и решу эту проблему. В то же самое время, один из эффектов у меня сейчас в демо требует покадровой распаковки атрибутов (пикселы сделаны эффектом, а вот раскраска — анимацией). В этом случае скорость абсолютно важна, поэтому в эффекте задействован LZSA1.
Некоторые успехи товарищей на других платформах ты можешь увидеть на моей диаграмме. Если очень коротко, я протестировал дохренища всего, не думаю что много упущено. Всегда есть потенциал что-то упустить из вида; но фундаментально, на Z80, с моей точки зрения все ведущие игроки сейчас обозначены.
И, да, запаковка на Z80 представляется мне абсолютно архаичной. С моей точки зрения в ней тупо нет смысла.
Могу ошибаться, но с моей точки зрения, это поиск наиболее сильного сжатия (требование №1 к любому компрессору) в то же время при самой высокой скорости _распаковки_ на z80.
При этом запаковка на z80, как таковая, абсолютно не принимается в расчет.
Видимо, всё это для целей демо-«анимы», т.е. основанных на быстро распаковываемых данных. Подтверди, так это или не так.
Изучал ли ты успехи товарищей на других 8-битных платформах? Каковы они?