В случае текстов на естественных языках наилучший результат даёт сжатие по словарю. Всякие побитовые упаковки после него -- это так, остатки подбирать.
Вид для печати
PPM -- это по сути алгоритм с неявным словарём; точнее, в нём словарь конструируется по мере обработки потока. В теории, при этом происходит экономия на передаче отдельного словаря. На практике, во всех алгоритмах с неявным словарём, а это не только PPM, но и всё семейство LZ*, например, происходит замусоривание словаря записями, которые никогда не будут использованы. Что уменьшает степень сжатия.
На самом деле, PPM с небольшой глубиной контекста (предыстории) на спеке сделать можно. Но смысл этого неясен.
AК априори лучше Хаффмана, оба метода энтропийные, но у Хаффмана разрядность побитовая, а в АК дробная. Поэтому АК не может быть хуже Хаффмана.
Сейчас интересен rANS, но мало материалов и даже читая материалы от разработчика не могу с ним разобраться совсем (впрочем я и с АК плохо разбираюсь, только понимаю теорию).
Сейчас на ПК для себя пользуюсь zpaq64 если есть время для сжатия, если нет, то 7zip PPMd FAST.
Хаффманом обычно дожимают, так как у него задача такая - снижение энтропии. Например если взять файл 1024 байт заполненный нулями, то Хаффман сожмёт его максимум в 8 раз + служебка всякая, а банальный LZ сделает байт 30, что даст сжатие в 33 раза. как то так.
Вопрос, кто-то изучал момент сжатия битовых изображений - спрайтов, с быстрым доступом "на лету". Пока ничего лучшего чем фиксированная таблица для Хаффмана посчитанная по факту с разбиением данных по блокам - ничего не придумывается., но там 256 байт на таблицу сразу отдаём и в среднем по 4 бита на "хвост" спрайта для выравнивания по блокам. Зато при распаковке буфер всего в пару-тройку байт нужен и довольно быстрые операции со сдвигами.
да, на этапе vsync например
почему медленно? чем, по операциям, отличается от например смешения спрайтов или наложения маски? хаффман на распаковку очень быстрый же.
по размеру - ну тут от контента зависит, хаффман же энтропийный кодер, если много будет повторяющихся данных то и сожмёт хорошо, даже 1:2 это много.
Вспомнился ещё один интересный упаковщик из прошлого — ACB (associative coding algorithm). Помню давал очень приличное сжатие.
по сравнению даже с примитивной процедурой вывода неупакованного спрайта дольше в разы
+ лишних несколько сдвигов и условных переходов на каждый распакованный байт
еще и регистры выделить надо, а их в оптимальных процедурах и так впритык
а вот однократная распаковка графики для нового уровня (и даже каждого нового экрана) вполне оправданна и на практике применяется
так, не понял здесь. экран меняется 50 раз в секунду (я про PAL ATARI), то есть отрисовывая анимированные спрайты для смены экрана, я могу данные распаковывать? чем это отличается от ранее мной описанного? это же и есть на лету. Вот появился новый монстр впервые, я его распаковываю, показываю, он улетает, удаляю. Это же "на лету" - для каждого нового экрана.
:v2_dizzy_facepalm: снова на отдельные слова реагируем, даже не пытаясь вникнуть в контекст?
то есть очевидно речь про экран ИГРЫ (я бы написал "комната", но не всякие экраны можно комнатами назвать)
а НЕ про КАДР, тем более, что крайне редко в спековских играх частота кадров ИГРЫ достигает частоты PAL
как видим, нет - термин правильный (более того, международный - см. flip-screen) - а восприятие ошибочное
значит, продолжаем обрабатывать в новом кадре
а явной синхронизации вообще в игрушках может не быть :p
...так же как и музыки (а если музыка и есть, то обычно идёт независимым от игровых событий процессом)
прерывание происходит по таймеру или по событию. в случае с музыкой по таймеру, чтобы точно знать в каком ритме идёт музыка. если вы никак не синхронизируетесь с кодом основной программы, то у вас неизбежно будут проблемы.
то есть поэтому в ZX всё любит мерцать, исчезать и появляться в любой момент? там же почти 4 мгц по сравнению с 6502 это в 2 раза больше, а на 6502 таких проблем я не наблюдаю. Да и масса источников пишет именно о работе кода игры в момент vsync. Ладно если сознательно из 50 гц вы делаете 25, но если у вас может быть сначала 50 потом 20 потом 5 потом опять 50 - как таким пользоваться? если на ZX это норма, то это прям жуть.
хотя мне кажется я сам смогу ответить на этот вопрос (ну или предположу) - в ZX нет ANTIC чипа, поэтому флип-скрин и скроллы делаются программно?
но вы не пользовались термином flip-screen
если вас интересует филигранная точность восприятия ваших слов, то имеет смысл пользоваться англицизмами - флип-скрин, фрейм и т.д.
запустил одну музыку в меню, выключил когда игра начинается
запустил другую в начале уровня, выключил после окончания уровня
где проблемы? графику не надо синхронизировать
не поэтому - с чего бы "всему" исчезать, если ничего не стирали в ходе расчётов?
например, в широко известном экзолоне нету синхронизации, но артефакты отрисовки малозаметны
нужно знать, где их ожидать, чтоб увидеть
очередная совершеннейшая бессмыслица - что значит "работа кода игры в МОМЕНТ vsync"??
какова длина "момента" вообще? а во все прочие "моменты" чем занят комп? :D
так не пользуйтесь, дизайн уровней может быть таким, что разброс получится небольшим
в zx-графике ВСЁ делается программно
пользуюсь переведённым термином screen, обозначающим участок игровой карты, в том числе в словосочетаниях
смысл имеет вчитываться внимательно, а не реагировать на уровне рефлексов на одно слово
пока идёт построчное формирование изображения, то, если вы следите за каждой строкой, вы можете менять содержимое видео памяти только для тех строк, которые еще не нарисованы. Если вы рисуете что-то в памяти, из которой луч ничего не рисует, то на следующем кадре, если вы ту область не обновите, изображение появится.
если вы не следите за vsync, и рисуете (заполняете vram) по принципу как хочу и когда хочу, то у вас неизбежны проблемы - мерцание объектов, отсутствующие объекты, обрезанные объекты (визуально это выглядит как мерцание например части спрайта).
Например для Atari есть аппаратное определение столкновений спрайтов - будете делать абы-как, оно не будет работать.
это ни о чем не говорит. всё зависит от кода программы, рассинхронизация носит накопительный характер и разницу в 50 мс например на короткой и не тяжёлой программе вы никак не заметите.
если же вы говорите о музыке на фоне, когда нет нужды стыковать кадры изображения и звука, то действительно нет никакой разницы, даже рассинхрон на 20 секунд никто не заметит, но я-то не об этом.
выдержка из сети:
В видеоиграх вертикальные импульсы так же используются для синхронизации. Большинство графических операций на игровых консолях, включая и 16-битную эру, могло быть выполнено только в течение кадрового гасящего импульса (который программисты часто называли VBLANK), требуя от программ выполнять всю обработку графики исключительно за это время.
так же дополнительная информация есть здесь, в том числе ответ про время возврата луча.
как правильно заметили - не всё. но в целом я понял в чём причина артефактов.
это всё известная азбука но при чём тут "работа кода В МОМЕНТ"? за "момент" выполнится несколько команд только :D
повторяю, это необязательно - смотреть Exolon и учить матчасть!
к спеку отношения не имеет
а при чём тут ЗВУК? полностью "проблема" высосана из пальца
как сказал, AY музыка и звуковые эффекты отдельный процесс
для эффекта просто взводится флажок когда нужно
к спеку отношения не имеет, у него нет динамических аппаратных спрайтов и видеопамять всегда доступна
повторю, видеосинхронизация на спеке необязательна и не всегда целесообразна
BelaLugoci, вы ушли немного в другую степь
Обработка игрового цикла - это одно
подготовка данных и утилизация ненужных данных происходят на этапе подготовки, в процессе игрового цикла - очень редко.
[инициация игрового экрана]
|
[обработка игровых событий внутри экрана] <-[до завершения]
|
[завершение игрового экрана] -> [принятие решения]
распаковка требуется только в первом блоке
в процессе игровых событий не требуется распаковка данных.
[инициация игрового экрана]
это неизменяемые данные совсем-совсем?
если данные для текущего уровня не позволяют их держать в готовом распакованном виде?
условный bitmap будет занимать в ОЗУ столько, сколько он весит и если буфер vram у вас например 8 Кб, и все данные у вас распакованы, то у вас уже 16 Кб занято (утрирую, там может быть как 8+1, 8+8 так и 8+28), то есть на код останется мало (помним про Бейсик, DOS и прочее в ОЗУ).
я подумал о концепции когда используется какое-то быстрое и простое кодирование, пусть для примера это будет RLE, которое сократит использование памяти например на 20%, а это уже 1-1,5 Кб к примеру.
Для вывода формируется буфер, например 2х16 байт, куда раскодируются спрайты перед копированием в vram, возможно это можно делать только регистрами, тут уж я не знаю, зависит от способа кодирования и раскодирования.
просто на современных платформах это в порядке вещей, но никто не спорит что сегодня это ЦПУ на гигагерцы и возможно для 6502/z80 это проблема. Думаю нужно проверять опытным путём. Просто в одной игре это параллакс, несколько слоев и наложений, а в другой всё проще, возможно там и можно пользоваться распаковкой на лету.
иногда в игрушках зеркалят все спрайты персонажа при его развороте
но не припомню сочетания такого с предварительной распаковкой
да достаточно на код остаётся, да еще на теневой экранный буфер и на таблицы
например, в Nemesis the Warlock для 48k спека спрайты ~20k занимают (и это, вероятно, рекорд)
но обычно спрайты жрут намного меньше, а фоны набирают из небольшого числа тайлов и декораций
это вряд ли, спрайты в играх довольно плотные, байт - узкая полоска из 8 пикселей, очень мало будет пустых подряд, как бы даже не распух размер с RLE
Вот именно в этом месте и можно использовать распаковку
именно так я и делал здесь
для каждого экрана распаковываются спрайты и обьекты которые тут находятся
Но там в принципе все пожато шоппц
Я бы не стал называть это распаковкой - она должна быть максимально быстройЦитата:
если данные для текущего уровня не позволяют их держать в готовом распакованном виде?
условный bitmap будет занимать в ОЗУ столько, сколько он весит и если буфер vram у вас например 8 Кб, и все данные у вас распакованы, то у вас уже 16 Кб занято (утрирую, там может быть как 8+1, 8+8 так и 8+28), то есть на код останется мало (помним про Бейсик, DOS и прочее в ОЗУ).
я подумал о концепции когда используется какое-то быстрое и простое кодирование, пусть для примера это будет RLE, которое сократит использование памяти например на 20%, а это уже 1-1,5 Кб к примеру.
Для вывода формируется буфер, например 2х16 байт, куда раскодируются спрайты перед копированием в vram, возможно это можно делать только регистрами, тут уж я не знаю, зависит от способа кодирования и раскодирования.
просто на современных платформах это в порядке вещей, но никто не спорит что сегодня это ЦПУ на гигагерцы и возможно для 6502/z80 это проблема. Думаю нужно проверять опытным путём. Просто в одной игре это параллакс, несколько слоев и наложений, а в другой всё проще, возможно там и можно пользоваться распаковкой на лету.
посмотри Mortal Combat
там к этому делу подошли основательно.
спасибо всем за дискуссию, будет что показать - вернусь в тему.
Для эксперимента делал в Heavy on the magick упаковку спрайтов врагов при помощи zx7, и в момент, когда монстр появляется в комнате, происходила распаковка спрайтов + маски в небольшой буфер, откуда дальше идёт отрисовка штатным методом. Небольшая задержка не заметна, - и само количество распаковываемых байт незначительно, и сам геймплей позволяет (например, при переходе между комнатами перерисовка экрана не мгновенная). Решение с буфером потому что движок игры в реальном времени зеркалит спрайт туда-сюда, оживляя монстра, и нет выигрыша держать упакованый оригинал и зеркальную копию.
В компрессор RIP добавлена возможность ограничения длины и дальности ссылок.
В компрессор OAPACK добавлен "ускоренный" режим почти без ущерба для сжатия. https://gitlab.com/eugene77/oapack
А можно ли улучшить алгоритм сжатия для Laser Compact? Или хотя бы добавить дополнительные возможности паковки картикнки без атрибутов и по третям. Как это было в ZX версиях?
https://vtrd.in/release.php?r=82a719...7ef6d0e4817b7a