feat(assets): decode CTLD tag 17 records
Docs Deploy / Build and Deploy MkDocs (push) Successful in 37s

This commit is contained in:
Valentin Popov committed 2026-10-31 10:36:12 +04:00
1 parent 3e3ab0e0c6
commit 8c403ab4f7
3 files changed
+314 -4

No files matched your search

+3 -1
View File
@@ -425,7 +425,9 @@ Global Control getters `1/2` и setter `1` проверены в native x86 orac
этого класса native oracle не запускал. Rust API обращается к строкам проекции
конкретного живого `ObjectHandle`; это запрос к уже загруженной таблице, а не
исполнение Control или Behavior tick. Setter `17`, остальные factory tags и
внешние эффекты их методов не включены. Для tag `9` selector `0` использует
внешние эффекты их методов не включены. Структурное чтение записи CTLD с
меткой 17 ещё не восстанавливает её обработчики и игровое поведение.
Для tag `9` selector `0` использует
отдельный scale `+0x11c`; остальные поддержанные классы используют коэффициент
напрямую. Пустой набор и нулевой знаменатель остаются native no-result, а
неподдержанный factory tag и расчётный диапазон произведения/отношения за
+23 -1
View File
@@ -1525,7 +1525,7 @@ offsets 119–121. В `fr_l_gener.ctl` найдено 35 строк type 4, вк
`f_gener_ball` с offset 85.
Control.dll `+0x8B10` передаёт указатель текущей записи диспетчеру `+0x2D4B0`.
Для tags `2`, `3`, `4`, `5`, `8`, `10`, `21` и `27` подтверждён общий читатель
Для tags `2`, `3`, `4`, `5`, `8`, `10`, `17`, `21` и `27` подтверждён общий читатель
`+0x21D50`: таблица виртуальных методов tag `2` (`+0x3CBD8`) вызывает его через
обёртку `+0x29650`, остальные перечисленные vtable указывают прямо на него в
позиции `+0x1C`. Читатель потребляет
@@ -1536,6 +1536,28 @@ Control.dll `+0x8B10` передаёт указатель текущей зап
а также отказ при оборванном завершающем NUL. Это подтверждает структурный
формат, но не назначает смысл всем коэффициентам устройств.
Путь записи с меткой `17` проверен на GOG `Control.dll` с SHA-256
`bcb86318089028548a178b03a21accdce15df0cc85ddd91674cf3c2f55012c6e`:
ветвь `0x11` фабрики `+0x2D4B0` вызывает конструктор `+0x24760`, который
устанавливает указатель на виртуальную таблицу `0x1003C840`. Ячейка `+0x1C`
этой таблицы ссылается прямо на общий читатель `+0x21D50`. В ресурсах
`weapon.rlb:bm_m_01.ctl` и `weapon.rlb:bm_l_01.ctl` таблица привязок
заканчивается на смещении `0x120`, где начинается запись с меткой `17`.
Общий префикс размером `0xB0` байт включает саму метку; счётчик по `+0xAC` и
слово длины в этих двух ресурсах равны нулю, поэтому указатель чтения
переходит на `0x1D4`. Там начинаются `0x54` байта заголовка таблиц эффектов;
таблицы содержат соответственно `4`, `2`, `2` и `2` строки по 100 байт и
заканчиваются на `0x620`. Записи из реестра объектов `bm_m_01` и `bm_l_01`
при обычной подготовке ресурсов сохраняют явно указанные списки точек CPT
(`bm_m_a.cpt` и `bm_l_a.cpt`) и таблицы узлов NDP (`bm_m_01.ndp` и
`bm_l_01.ndp`); в первой таблице эффектов находятся три строки type 4.
Синтетический тест проверяет непустые массивы значений и строки у записи с
меткой 17 и следующей записи с меткой 4, затем переход к таблице эффектов.
Если считать 17 неизвестной, чтение остановится перед
ней; общий разбор позволяет пройти запись и прочитать следующие таблицы,
оставляя слова tag 17 числами без толкования. Обработчики этой метки и их
игровое поведение ещё не восстановлены.
Resolver прототипов хранит явную registry-ссылку на `.cpt` отдельно от ссылки
на `.ctl`. Если строки type 4 разобраны и явная ссылка на CPT есть, подготовка
читает ровно указанные archive/name; имя CPT не выводится из имени CTL. В CPT