Автор Тема: Urban Strike hack project  (Прочитано 1981 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Arkadij

  • Пользователь
  • Сообщений: 22
    • Просмотр профиля
Urban Strike hack project
« : 26 Июнь 2020, 15:42:52 »
Всем привет! Я решил вернуться к проекту, который был в коме более 5 лет, а именно хаку Urban Strike. Я уже когда-то создал Jungle Strike Enemy Hack, где заменил врагов из Jungle Strike на врагов из Desert Strike, а в Urban Strike решил заняться переделом самих уровней - миссий, карты, картинки, расположения объектов и т.д. Единственный момент, который меня интересует, форумчане, существует ли еще распаковщик/упаковщик графики для этой игры (формат LZSS) или уже утрачен? Или может быть кто-то подскажет, как можно вытащить оттуда графику и отредактировать? Ибо у меня был большой перерыв и я потихоньку собираю обратно все знания.

Оффлайн SeregaZ

  • Пользователь
  • Сообщений: 2511
  • Пол: Мужской
  • ливнул с форума
    • Youtube
    • Просмотр профиля
Urban Strike hack project
« Ответ #1 : 26 Июнь 2020, 16:12:33 »
Красная Площадь и Ми-28Н будут? :)

Оффлайн Arkadij

  • Пользователь
  • Сообщений: 22
    • Просмотр профиля
Urban Strike hack project
« Ответ #2 : 26 Июнь 2020, 16:37:52 »
Возможно  :lol:

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5005
    • Просмотр профиля
Urban Strike hack project
« Ответ #3 : 27 Июнь 2020, 03:10:35 »
существует ли еще распаковщик/упаковщик графики для этой игры (формат 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: Я ошибся с размером в начале данных, он указывает на размер несжатых данных. Это на результат программы не влияет, но там получается ошибка в описании и лишнее выделении памяти. Возможно поправлю позже. Вообще, можно было сделать с указанием размера сжатых данных, выход был бы при другом условии.
« Последнее редактирование: 27 Июнь 2020, 04:24:55 от Sharpnull »

Онлайн Guyver(X.B.M.)

  • Пользователь
  • Сообщений: 2350
  • Пол: Мужской
  • Уничтожим Кронос!
    • Facebook
    • Twitter
    • ВКонтакте
    • Youtube
    • Просмотр профиля
Urban Strike hack project
« Ответ #4 : 27 Июнь 2020, 04:26:33 »
Я, скорее всего, не помогу. С 2010 года у меня сменилась куча ноутов и где теперь искать эти файлы - я не знаю... :neznayu: Если только у Марата осталось. Но у него, как помню, полетел ноут с жёстким и куча всего пропала...

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5005
    • Просмотр профиля
Urban Strike hack project
« Ответ #5 : 27 Июнь 2020, 04:31:40 »
Я сейчас ещё проверил http://www.hacking-cult.org/download/tsdc-v2.2-rc3-win32.rar (отсюда, тема Jungle Strike), оказалось она работает. Нужно выбрать Saxman и размер сжатых данных при декодировании. Обратно не пробовал.
--------
Хотя, в теме Urban Strike Марат писал, что Saxman сжимает не так.
Там ещё защита/CRC, нужно найти исправление.
« Последнее редактирование: 27 Июнь 2020, 04:50:23 от Sharpnull »

Оффлайн Arkadij

  • Пользователь
  • Сообщений: 22
    • Просмотр профиля
Urban Strike hack project
« Ответ #6 : 27 Июнь 2020, 10:25:23 »
Я сейчас ещё проверил http://www.hacking-cult.org/download/tsdc-v2.2-rc3-win32.rar (отсюда, тема Jungle Strike), оказалось она работает. Нужно выбрать Saxman и размер сжатых данных при декодировании. Обратно не пробовал.
--------
Хотя, в теме Urban Strike Марат писал, что Saxman сжимает не так.
Там ещё защита/CRC, нужно найти исправление.

Распаковка графики на Saxman работает, но когда сжимаю обратно остаются разводы на экране. В целом интересно, попробую что-нибудь наколдовать
У 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: Я ошибся с размером в начале данных, он указывает на размер несжатых данных. Это на результат программы не влияет, но там получается ошибка в описании и лишнее выделении памяти. Возможно поправлю позже. Вообще, можно было сделать с указанием размера сжатых данных, выход был бы при другом условии.

Я не понял, как этим StrikeLZSS пользоваться?
« Последнее редактирование: 27 Июнь 2020, 10:44:11 от Arkadij »

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5005
    • Просмотр профиля
Urban Strike hack project
« Ответ #7 : 27 Июнь 2020, 18:53:27 »
Я не понял, как этим StrikeLZSS пользоваться?
Через команду строку, я же описал. 1-й аргумент - файл со сжатой графикой, можно ром. 2-й - имя выходного файла. 3-й - смещение графики в файле, должен указывать на размер несжатых данных.
StrikeLZSS.exe "Urban Strike (UE) [!].gen" out.bin 0x1CA8F4В out.bin будет несжатый шрифт.
Не нужно цитировать так много текста, места занимает.

Оффлайн Arkadij

  • Пользователь
  • Сообщений: 22
    • Просмотр профиля
Urban Strike hack project
« Ответ #8 : 27 Июнь 2020, 20:21:45 »
Через команду строку, я же описал. 1-й аргумент - файл со сжатой графикой, можно ром. 2-й - имя выходного файла. 3-й - смещение графики в файле, должен указывать на размер несжатых данных.
StrikeLZSS.exe "Urban Strike (UE) [!].gen" out.bin 0x1CA8F4В out.bin будет несжатый шрифт.
Не нужно цитировать так много текста, места занимает.

Хорошо, попробую, уже в процессе работы :)

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5005
    • Просмотр профиля
Urban Strike hack project
« Ответ #9 : 28 Июнь 2020, 07:18:01 »
Написал сжатие. Прикладываю, на github попробую добавить позже.
Использование
Распаковка:
StrikeLZSS -d "Urban Strike.gen" out.bin -p 0x1CA8F4-d - декомпрессия, -p ЧИСЛО - позиция в файле.
Сжатие:
StrikeLZSS input.bin compressed.binМожно указать -c (компрессия) и позицию во входном файле (-p). Сжатый файл имеет в начале размер как и во входном для распаковки.
Положение -d/-c и -p ЧИСЛО может быть в любом месте, порядок входного и выходного файлов важен.
О программе
Теперь выводится размер несжатых и сжатых данных без учёта 4 байтов размера у сжатых, это поможет определить, влезет ли графика назад.
Сжатие должно выдавать по размеру не больше, чем у оригинальной графики. У одних данных даже получилось на 5 байтов меньше, почему-то.
Код сжатия написал на основе моего сжатия PZZ у игры Jojo no Kimyou na Bouken - Ougon no Kaze (Japan). Оказалось, можно использовать простой алгоритм с поиском повторений у ранее записанных байтов и контрольного байта (биты указывающие на несжатый байт или на смещение + длина), отличие только в записи смещения относительно "окна" у LZSS.
Можно было написать сразу вставку в ром по смещению, указание размера вместо чтения из файла и т. п., но особо смысла нет.
Замечания
То, что я говорил про https://github.com/MichaelDipperstein/lzss, не сработало, похоже там используется другая реализация LZSS.
Сравнил код распаковки Desert Strike, Jungle Strike и Urban Strike, он одинаковый. Вы могли бы использовать те же утилиты, что использовали раньше.
Попробовал вставку графики, вроде правильно. Для отключения проверки CRC использовал Master Code - https://gamehacking.org/game/16162 - 1FF0D4:4E75.

Оффлайн Arkadij

  • Пользователь
  • Сообщений: 22
    • Просмотр профиля
Urban Strike hack project
« Ответ #10 : 28 Июнь 2020, 18:47:04 »
Написал сжатие. Прикладываю, на github попробую добавить позже.
Использование
Распаковка:
StrikeLZSS -d "Urban Strike.gen" out.bin -p 0x1CA8F4-d - декомпрессия, -p ЧИСЛО - позиция в файле.
Сжатие:
StrikeLZSS input.bin compressed.binМожно указать -c (компрессия) и позицию во входном файле (-p). Сжатый файл имеет в начале размер как и во входном для распаковки.
Положение -d/-c и -p ЧИСЛО может быть в любом месте, порядок входного и выходного файлов важен.
О программе
Теперь выводится размер несжатых и сжатых данных без учёта 4 байтов размера у сжатых, это поможет определить, влезет ли графика назад.
Сжатие должно выдавать по размеру не больше, чем у оригинальной графики. У одних данных даже получилось на 5 байтов меньше, почему-то.
Код сжатия написал на основе моего сжатия PZZ у игры Jojo no Kimyou na Bouken - Ougon no Kaze (Japan). Оказалось, можно использовать простой алгоритм с поиском повторений у ранее записанных байтов и контрольного байта (биты указывающие на несжатый байт или на смещение + длина), отличие только в записи смещения относительно "окна" у LZSS.
Можно было написать сразу вставку в ром по смещению, указание размера вместо чтения из файла и т. п., но особо смысла нет.
Замечания
То, что я говорил про https://github.com/MichaelDipperstein/lzss, не сработало, похоже там используется другая реализация LZSS.
Сравнил код распаковки Desert Strike, Jungle Strike и Urban Strike, он одинаковый. Вы могли бы использовать те же утилиты, что использовали раньше.
Попробовал вставку графики, вроде правильно. Для отключения проверки CRC использовал Master Code - https://gamehacking.org/game/16162 - 1FF0D4:4E75.

Класс :) Спасибо :)

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5005
    • Просмотр профиля
Urban Strike hack project
« Ответ #11 : 14 Июль 2020, 04:36:35 »
Новая версия 1.2.0, выложил https://github.com/infval/StrikeLZSS, сборка программы. По этому поводу больше не буду ничего делать, если будут проблемы, пишите, лучше в ЛС.
Изменения
* Добавлено улучшенное сжатие по умолчанию. Отключается опцией -nu (not ultra :)).
* Если размер в начале сжатого файла был 0x00000000, происходил вылет. Пустые файлы допускаются.
* Добавлена проверка на выход за пределы данных при распаковке. Происходит с неверными файлами.
* Точная проверка аргументов командной строки, раньше допускалось писать что угодно после первого символа, например -d и -d123 считалось одинаково.
* Если позиция при распаковке была между [0xFFFFFFFC, 0xFFFFFFFF], из-за переполнения допускалось выполнение дальше. Макс. размер входного файла всё равно меньше 2GB.
* Убрано ограничение на 16МБ распакованного файла, добавлял на случай ошибочных данных, так как для этих игр нет смысла в данных >= 65536 байт из-за ограничений памяти Mega Drive. Теперь если ОЗУ не хватит, то будет ошибка выделения памяти (malloc()).
* И по мелочи, связанное с кодом в основном.
Компиляция
Не стал добавлять проект Visual Studio 2019, потому что можно просто создать новый пустой консольный C/C++ проект и добавить файл main.c. Я также: убирал добавление отладочной информации в Release сборки, чтобы не было абсолютного пути до проекта; делал статическую линковку, чтобы не было зависимости от DLL, но лучше так не делать и ставить Microsoft Visual C++ 2019 Redistributable Package.
Добавил простой Makefile, можно скомпилировать с помощью MinGW, если через MinGW-консоль ввести команду make.
Улучшенное сжатие
Я говорил, что моё сжатие не должно быть хуже оригинала, но всё-таки у некоторых данных из Strike игр было хуже на 1 байт, но в остальных также или лучше.
С улучшенным сжатием хуже не должно быть, а сжатие улучшено где-то на 2%. Но это точно не лучший алгоритм, потому что повторное применение алгоритма давало результат на 1 байт меньше в двух местах, не стал так делать из-за мизерной пользы.
Обычное сжатие, в котором ищется всегда макс. последовательность - не лучший, иногда взятие меньше даёт улучшение. Я заметил, когда имеет смысл брать меньше, но не знаю почему это работает. Можно было изучить информацию по сжатию, но так не интересно.
Алгоритм Saxman
Та программа по случайности распаковывала шрифт, но дефис (48-й тайл) там был неправильный. После сжатия Saxman'ом, узнал, что размер "окна" 4096 (у нас 2048), а начальное смещение 0x0FDC (у нас 0x07EE). Из-за смещения близкого к концу "окна" шрифт получался почти правильно, но после распаковки больше 2048 байтов всё равно было бы неверно. В Saxman алгоритме предполагается, что "окно" уже заполнено нулями, экономии не так много и требует очищения памяти. И он может поставить в начале файла 2 байта (Little-Endian) - размер сжатых данных.

Оффлайн ElectrixX

  • Пользователь
  • Сообщений: 799
  • Єдиний на світі є такий КітПес)
    • Просмотр профиля
Re: Urban Strike hack project
« Ответ #12 : 14 Июль 2020, 12:34:44 »
Sharpnull, ты походу писарь крутой, не хочешь присоединиться к какому нибудь проекту? или чем то уже занимаешься? просто спросил))

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5005
    • Просмотр профиля
Urban Strike hack project
« Ответ #13 : 14 Июль 2020, 18:05:36 »
ElectrixX, такое стоит спрашивать в ЛС. Не крутой, посредственный. Ни с кем над ретро не работаю. Идей и незаконченного много, но вряд ли что-то получится.