существует ли еще распаковщик/упаковщик графики для этой игры (формат LZSS) или уже утрачен?
У
Guyver были наработки давно (есть на emu-land, можно его спросить).
Я разобрал алгоритм с помощью GHIDRA и
загрузчика от
DrMefistO. Сначала в эмуляторе в окне памяти предположил, где лежат несжатые данные (RAM: 0xFF26F2 - здесь "окно" алгоритма, 0xFF2EF2 - два байта, которые копируются в VRAM), перехватил запись в коде (ROM: границы функции с 0x762A по 0x76E2 включительно), открыл в GHIDRA ром и проанализировал функцию (изначально она была неопределенна, почему-то), разобрал выданный код на C.
Действительно, там обычный LZSS, но с двумя отличиями: размер окна 2048, а не 4096, начальное положение окна 0x7EE, а не 0. Обычный, потому что код практически такой, что видел в одной игре.
Прикладываю свой код и сборку на C, который только декодирует. Он принимает аргументы:
StrikeLZSS.exe "Urban Strike (UE) [!].gen" out.bin 0x1CA8F4Входной, выходной файлы и необязательная позиция в файле (можно hex или десятичное). В начале данных должен быть размер несжатых данных (4 байта Big-Endian), так они лежат в роме. В данном примере позиция на шрифт.
Чтобы узнать положение графики я ставил breakpoint на PC: 762A - начало функции, в регистре A2 уже хранится положение в роме, с размером в начале.
Не делал много проверок, поэтому программа может падать при неправильных данных. Выделение памяти зависит от размера файла, умножается на 9 (макс. сжатие), в выходном файле размер правильный.
Я думаю, что можно изменить первый попавшийся алгоритм LZSS. Например,
https://github.com/MichaelDipperstein/lzss.
Размер окна, заменить:
#define WINDOW_SIZE (1 << OFFSET_BITS)
на
#define WINDOW_SIZE 0x800Положение при декодировании:
nextChar = 0;
на
nextChar = 0x7EE;Положение при кодировании:
windowHead = 0;
на
windowHead = 0x7EE;Не проверял и не знаю как хорошо сжимает. Если не справитесь или если кто-то не предоставит готовые программы, позже посмотрю. С хакингом игры не помогу, не разбираюсь.
--------
UPD: Я ошибся с размером в начале данных, он указывает на размер
несжатых данных. Это на результат программы не влияет, но там получается ошибка в описании и лишнее выделении памяти. Возможно поправлю позже. Вообще, можно было сделать с указанием размера сжатых данных, выход был бы при другом условии.