Repository navigation
Reverse engineering
Порт написан не «по мотивам», а по разобранному коду двух модулей. Эта страница - про метод: что было на входе, как выглядит цитата, чему в комментариях можно верить, а что является нашим соглашением.
| Модуль | Что там | Адреса в цитатах |
|---|---|---|
JumpyBall.exe |
вся игра: окно, кадр, физика, меню, трасса | код 0x00011xxx..0x00024xxx, данные 0x00026xxx, 0x0003xxxx, 0x0006xxxx
|
hss.dll |
Hekkus Sound System: звук и MOD-плеер | 0x0010xxxx |
Поэтому в комментариях порта модуль назван всегда:
JumpyBall.exe Blit 0x00023b78 - это игра, а hssSpeaker::updateModSFX 0x00104370 - это библиотека. У hss.dll сохранились C++-имена, отсюда цитаты
вида hssSpeaker:: / hssMusic::; у игры имён нет вообще - только адреса.
В коде порта 292 ссылки на JumpyBall.exe, 45 упоминаний классов hss и 704
упоминания адресов вида 0x000xxxxx. Это не украшение, а правило проекта:
комментарий либо называет внешний источник истины, либо его нет. Никаких «тут
умножаем на два, потому что так ровнее».
Level_Begin, Blit_TileHV_Core, Menu_DrawFrame, Player_Respawn - не
оригинальные символы. Исполняемый файл стрипнут; это имена, которые мы дали
функциям при разборе. Твёрдый факт в цитате один - адрес. Если открыть
JumpyBall.exe самостоятельно и назвать функцию по адресу 0x0001376c иначе -
это не ошибка; сойтись обязательно только на адресе.
Отсюда практическое правило чтения вики: где рядом с описанием стоит адрес, там поведение сверено с дизассемблером. Где адреса нет - это либо следствие описанного выше, либо решение порта, и тогда сказано прямо (см. Deviations).
Оригинал грузил картинки как ресурсы: LoadBitmapW(g_hInstance, id) в
Game_Init 0x000113bc. Порт читает те же картинки из файлов BITMAP/<id>.bmp -
тот же номер, только в десятичном виде. Поэтому папка ассетов выглядит как
склад безымянных чисел, и это не лень, а прямое следствие: у картинок в
оригинале не было имён.
| В дизассемблере | Файл | Что это |
|---|---|---|
0xcc |
204.bmp |
панель мастера переназначения клавиш |
0xf7..0xfb
|
247..251
|
полоска, градиент, заголовок, две кнопки |
0xfd |
253.bmp |
логотип PocketNew |
0xfe |
254.bmp |
шрифт HUD |
0x133 |
307.bmp |
первая текстура в порядке загрузки |
0x14c |
332.bmp |
крупный шрифт (Font_Load 0x0001f4d8, ветка g_fontSize == 2) |
0x14e |
334.bmp |
последняя - карта третьего уровня |
Полный список - в jb_consts.h, каждый номер с цитатой на место загрузки.
Четыре файла - 222.bmp, 252.bmp, 302.bmp, 303.bmp - лежат в репозитории,
но кодом не используются: они были в поставке, а разбор не нашёл ни одного места,
где игра их грузит.
ARM не загружает double одной инструкцией - он читает его из литерального пула
рядом с кодом. Значит, константу можно не угадывать, а прочитать. Пример из
Physics: проверка тайла под мячом использует + 0.58, и это не «примерно
половина», а восемь байт по адресам 0x0021119c / 0x000211a4:
0x3fe28f5c 0x28f5c28f -> 0.58
Так же добыты 7.0 (ускорение), 10.0 (импульс прыжка), 20.0 (гравитация),
0.08 (параллакс), 70 / 60 / 100 / 163 (проекция) - каждое лежит отдельным
float в .data, и у каждого в цитате свой адрес.
-
Строгий C89 -
tools/c89check.cmdи та же проверка в CI: код обязан собираться не только MSVC, см. Build-and-CI. -
Дамп кадра -
jumpyball 1 frame.rawвыгружает бекбуфер и выходит; кадры можно сравнивать побайтово между сборками. -
Быстрый доступ к состоянию - ключи
--level=,--screen=,--index=,--unlocked=появились именно для проверки: попасть в нужный экран одной командой, а не проходить игру заново. -
Музыка отдельно от игры -
tools/modtest.cрендерит.tkmв WAV и печатает peak/RMS/длительность без звуковой карты, см. Audio-and-TKM.
Устройство порта
Сборка и происхождение