feat(runtime): project merged Control device tables
Docs Deploy / Build and Deploy MkDocs (push) Successful in 56s
Docs Deploy / Build and Deploy MkDocs (push) Successful in 56s
This commit is contained in:
5 files changed
+1587
-23
No files matched your search
@@ -477,8 +477,15 @@ struct UnitDatRecord112 {
|
||||
|
||||
При построении mission prototype graph FParkan сохраняет для каждого root
|
||||
упорядоченный список этих raw records. Список передаётся в
|
||||
`MissionObjectDraft` с исходными `kind`, `parent_or_link`, description и tails;
|
||||
эти данные пока не объединяются в таблицу эффективных устройств Control.
|
||||
`MissionObjectDraft` с исходными `kind`, `parent_or_link`, description и tails.
|
||||
Во время полного mission load runtime использует дерево и подготовленные CTL
|
||||
resources, чтобы построить для такого объекта упорядоченную базовую таблицу
|
||||
Control: корневые строки добавляются, дочерний `INTO` может обновить выбранную
|
||||
строку или добавить записи при sentinel `-1`, а `EXTO` добавляет строки с
|
||||
переведёнными ключами глобальной MSH-иерархии. Результат хранит исходный factory
|
||||
tag и provenance; неизвестные tag-specific callbacks он не выполняет. Preview
|
||||
режим эту таблицу не строит, а неполная typed-record list оставляет состояние
|
||||
явно unavailable.
|
||||
|
||||
Каждый graph edge от `UnitDatRoot` к effective component и далее к его MSH
|
||||
dependency также несёт `unit_component_index`. Это индекс исходной записи в
|
||||
|
||||
@@ -593,6 +593,28 @@ parent ID через Control IID `0x202`, virtual slot `+0x44`, только е
|
||||
нужно проверить это поведение явно. `EXTO` проходит отдельную ветвь, поэтому
|
||||
это правило нельзя распространять на все registry types.
|
||||
|
||||
Ветка `EXTO` заполняет другие поля. В `FUN_10003760` RVA `0x3760` и mount
|
||||
`C4`, и target `C8` сначала равны `-1`. Ветка `EXTO` вычисляет mount и
|
||||
записывает его только в `C4`; `C8` остаётся `-1`. Поэтому Control добавляет
|
||||
все typed records такого компонента в конец общей таблицы. Raw
|
||||
`parent_or_link` здесь выбирает mount-узел, а не строку Control.
|
||||
|
||||
`AniMesh.dll` (SHA-256
|
||||
`65659bf67f20e5be77d67a5b2f59968f61b94293143807fa59ca451c560c4f7e`)
|
||||
собирает глобальную нумерацию MSH-узлов: обычная корневая модель добавляет все
|
||||
`N` узлов, `EXTO`-дочерняя модель добавляет `N - 1`, начиная со своего узла `1`,
|
||||
а `INTO`-компонент не добавляет узлов. `FUN_1000a460` (RVA `0xa460`) выполняет
|
||||
эту загрузку MSH; `FUN_10005780` (RVA `0x5780`) находит первый глобальный узел
|
||||
с заданным component ID. Если у `EXTO`-модели только один узел, она не добавляет
|
||||
глобальных узлов, и поиск первого узла возвращает `-1`.
|
||||
|
||||
При добавлении `EXTO` Control отдельно переводит ключи CTLD в пространство
|
||||
глобальной MSH-иерархии: нулевой ключ заменяется mount-узлом `C4`; ненулевой
|
||||
ключ сдвигается относительно первого глобального узла компонента только при
|
||||
`C4 != -1`. Например, если компонент начинается с глобального узла `22`, его
|
||||
исходный ключ `1` становится `22`. Этот ключ выбирает модельный узел, а не
|
||||
строку Control. Записи корня остаются в исходном виде.
|
||||
|
||||
### Как Control добавляет и переопределяет устройства
|
||||
|
||||
В `Control.dll` (SHA-256
|
||||
@@ -609,6 +631,19 @@ override path применяет первую typed record и не добавл
|
||||
путь `0x20800`, поэтому такой результат парсера сам по себе не доказывает отказ
|
||||
оригинального loader-а и не позволяет объявить Rust merge полным.
|
||||
|
||||
FParkan строит базовую проекцию этой таблицы во время полного mission load для
|
||||
объектов с Unit DAT. Корневые typed records добавляются в исходном порядке;
|
||||
`EXTO` тоже добавляет все свои записи с remapped MSH-ключами; `INTO` обновляет
|
||||
одну строку по `C8`, а при sentinel `-1` добавляет весь список. Preview таблицу
|
||||
не создаёт. Проекция хранит исходный factory tag, текущий typed record и их
|
||||
provenance, но не исполняет все tag-specific callbacks и не заменяет полный
|
||||
Control runtime. Лицензированный `UNITS/BUILDS/MINE/min_l_n1.dat` подтверждает
|
||||
10 исходных устройств, четыре `INTO`-override по индексам `0..3` и добавление
|
||||
одной дочерней записи `EXTO` с ключом `22`, всего 11 устройств. Это результат
|
||||
Rust full-loader теста на оригинальных ресурсах. Ветви C4/C8 и добавление
|
||||
`EXTO` подтверждены статически по native ASM; отдельный native full-load oracle
|
||||
для всей таблицы не запускался.
|
||||
|
||||
Для tag `19` фабрика создаёт объект с его исходными классом и vtable. Базовый
|
||||
конструктор `FUN_100218b0` задаёт multiplier `+0x4c = 1.0`. Override через
|
||||
`FUN_1002d890` вызывает у выбранного объекта vtable slot `+0x1c`, то есть
|
||||
@@ -621,6 +656,16 @@ override path применяет первую typed record и не добавл
|
||||
сбрасывают их. Поэтому «переопределение» здесь означает обновить часть данных
|
||||
того же устройства, с ограничениями конкретного метода.
|
||||
|
||||
Native x86 oracle для тех же GOG DLL выполняет конструкторы и этот общий setter
|
||||
на уже созданных получателях factory tags `9`, `15`, `19` и `25` (размеры
|
||||
объектов `0x120`, `0x98`, `0x94` и `0xa4`). У всех проверенных vtable slot
|
||||
`+0x1c` указывает на RVA `0x21d50`; тест подтверждает, что override сохраняет
|
||||
существующий слот, класс/vtable, ключ, component ID и multiplier `2.5`, копируя
|
||||
новые коэффициенты. Slot `+0x24` у tag `9` указывает на отдельный обработчик
|
||||
`0x25600`, а у остальных трёх — на no-op `0xbcd0`. Tag `9` проверяется с
|
||||
нулевым pointer `+0x3c` и записью без map rows: FX host намеренно не подключён,
|
||||
поэтому его поведение этим опытом не подтверждено.
|
||||
|
||||
Статический разбор глобального Control interface показывает aggregate getters
|
||||
`1/2` (`FUN_1002b410`, RVA `0x2b410`) и setter `1` (`FUN_1002ba30`, RVA
|
||||
`0x2ba30`) для устройств tag `19`. Для конечных значений getter `1` вычисляет
|
||||
|
||||
Reference in new issue
Block a user