aboutsummaryrefslogtreecommitdiff
path: root/docs/appendices/knowledge-boundaries.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/appendices/knowledge-boundaries.md')
-rw-r--r--docs/appendices/knowledge-boundaries.md56
1 files changed, 54 insertions, 2 deletions
diff --git a/docs/appendices/knowledge-boundaries.md b/docs/appendices/knowledge-boundaries.md
index c1993ca..5791836 100644
--- a/docs/appendices/knowledge-boundaries.md
+++ b/docs/appendices/knowledge-boundaries.md
@@ -130,7 +130,7 @@ host construction phases. Не проверена другая лицензирÐ
непустым `Init`. Вызов `Behavior.dll!FUN_10019e80` (RVA `0x19e80`, SHA-256
`ddfbdbde07832358fe6e35e01c8dba9b58e7313789498b6049ed51d4ed9baf99`) исполнялся
на синтетических интерфейсах. Путь членства в реальных distributor-списках
-теперь связан с полями TMA и Unit DAT: `World3D!CreateObject` передаёт selector
+связан с полями TMA и Unit DAT: `World3D!CreateObject` передаёт selector
и class word через дескриптор в Behavior (RVA `0x7e55`, `0x7e62`), а
`Behavior.dll!FUN_10005e60` (RVA `0x5e60`) проверяет высокий бит registration
key, AI и distributor. Selector из первого DWORD после имени ресурса выбирает
@@ -203,7 +203,15 @@ prototype roots без Unit DAT и отложенные spawn после исхÐ
этой модели. Путь в `ArealMap.dll` (SHA-256
`a25f9254ebb339d70e2e07c8121950191e9584ca0858d8e9c2e2b6c671edf6ea`) к
`CreateObject` по RVA `0x14fd0`/`0x15290` показывает выбор World3D class 3 или 4
-по старшему биту, но не всю цепочку их Behavior attachment.
+по старшему биту. Для ветки GOG `AniMesh.dll` (SHA-256
+`65659bf67f20e5be77d67a5b2f59968f61b94293143807fa59ca451c560c4f7e`) RVA
+`0x2ff0` показывает одну ветку создания: после QueryInterface для IID `0x204`
+выполняется отдельный импорт `GetQueue()`, а на возвращённом объекте вызывается
+метод через vtable slot `+0x30`. `CreateBehaviour` вызывается только при
+ненулевом результате этого метода и host class `3` или `4`; class `4` получает
+адреса полей prototype `+0x140` и `+0x160`. Семантика метода slot `+0x30` не
+установлена. Другие factory paths, нулевой результат и spawn после исходной
+загрузки остаются за границами подтверждённой ветки.
Для `Handler(30)` отдельно подтверждены обратный вызов `iron3d.dll` RVA
`0x611d0` (SHA-256 `d1dc4ea8535e2069b0a05c9e8be2724dd438ba44cca7a83007d8b2e50f9e35fa`),
@@ -239,6 +247,50 @@ CTLD и связанные resources структурно читаются, coun
известны. Не названы все секции, shape types, coefficients и точный contact
solver. То же относится к редким MSH auxiliary streams и части CTPT/NDPR flags.
+Одна цепочка Unit DAT → AniMesh descriptor → Control теперь восстановлена
+статически в [главе о Behavior и Control](../tomes/06-behavior.md): raw
+`parent_or_link` копируется в descriptor. В non-`EXTO` registry path parent ID
+разрешается в индекс устройства и сдвигает локальный индекс только когда parent
+ID не равен `-1` и IID `0x202` доступен; иначе используется raw локальный индекс.
+В этом потоке нулевой raw kind пропускает узел вместе с потомками, поэтому общий
+assigned ID нельзя получать из preorder-позиции записи. Это закрывает только
+передачу полей в native loader-е; Rust ещё должен строить такую же проекцию.
+
+Control loader также различает добавление устройств и применение одной записи
+к уже выбранному устройству. Для tag `19` найденные поля и ветви описаны в
+главе, но эффективное слияние пока не реализовано. В Rust parser-е
+`Unsupported { typed_record_index: Some(_) }` означает, что разбор остановился
+внутри списка typed records; без индекса остановки unsupported может относиться
+к effect-tail после уже разобранного списка. Эти случаи нужно различать.
+Ветка default native-фабрики вызывает конструктор по RVA `0x20800`, поэтому
+неизвестный Rust parser-у tag не доказывает отказ оригинального loader-а. Подготовка assets
+сейчас пропускает Control refs у non-geometric prototype, поэтому отсутствие
+подготовленного CTL должно оставаться явным unavailable result, а не
+трактоваться как пустой список.
+
+Глобальные Control selectors `1/2` и setter selector `1` по tag `19` описаны
+там же только по статическому разбору `Control.dll`; execution oracle для этих
+глобальных вызовов нет. Остаются открытыми проверка effective merge на живых
+объектах, полный охват registry types и host factory paths, а также runtime
+жизненный цикл множителя `+0x4c`.
+
+Для `Control.dll` (SHA-256
+`bcb86318089028548a178b03a21accdce15df0cc85ddd91674cf3c2f55012c6e`) tag-26
+getter selector `0x300` восстановлен локально: RVA `0x21d00` читает provider по
+ключу `fixed_words[1]`, затем умножает provider, CTLD coefficient `fixed_words[11]`
+и поле объекта `+0x4c` именно в таком порядке. Rust helper принимает текущие
+provider и multiplier извне; он не восстанавливает их жизненный цикл или весь
+Control tick. В x86 oracle при x87 control word `0x007f` проверены порядок,
+signed zero, отрицательные входы, расширенный промежуточный диапазон и
+subnormal return. Helper ограничивает себя normal-or-zero значениями, поэтому
+явно отклоняет промежуточные случаи, где результат выходит за поддерживаемый
+диапазон f32, даже если позднее умножение вернуло бы его в диапазон. Это
+ограничение поддержки Rust helper-а, а не неверный native-результат.
+
+В Unit DAT fixture `UNITS/BUILDS/MINE/min_l_n1.dat` проверена реальная связка
+`fr_l_mine.ctl` + `fr_l_mine.ndp`: tag `26`, ключ `2` в таблице из `22` строк,
+коэффициент `1.0`. Это не запись живого resource-device значения в миссии.
+
Закрывающий эксперимент: трассировать `LoadControlSystem`,
`LoadPhysicalModel`, `CreateCollManager` и создание collision objects; связать
каждый изменяемый field с созданным shape, contact или реакцией на движение.