diff options
| author | Valentin Popov <valentin@popov.link> | 2026-10-22 11:20:42 +0300 |
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2026-10-22 11:20:42 +0300 |
| commit | ccb5af0e37b94942962004ea2e84eea1d519c4bb (patch) | |
| tree | 6bd894fa64aa018f9575c625e7517a597f3089bc /docs | |
| parent | dcc64598916dba92de74c6e27a2359fa08b72e84 (diff) | |
| download | fparkan-ccb5af0e37b94942962004ea2e84eea1d519c4bb.tar.xz fparkan-ccb5af0e37b94942962004ea2e84eea1d519c4bb.zip | |
feat(assets): sample native resource device coefficient
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/appendices/knowledge-boundaries.md | 29 | ||||
| -rw-r--r-- | docs/tomes/06-behavior.md | 60 |
2 files changed, 87 insertions, 2 deletions
diff --git a/docs/appendices/knowledge-boundaries.md b/docs/appendices/knowledge-boundaries.md index c1993ca..9db3f49 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,23 @@ CTLD и связанные resources структурно читаются, coun известны. Не названы все секции, shape types, coefficients и точный contact solver. То же относится к редким MSH auxiliary streams и части CTPT/NDPR flags. +Для `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 или реакцией на движение. diff --git a/docs/tomes/06-behavior.md b/docs/tomes/06-behavior.md index 16ea21a..125f0d5 100644 --- a/docs/tomes/06-behavior.md +++ b/docs/tomes/06-behavior.md @@ -547,6 +547,66 @@ Control consumer-у: никакой компонент пока не получÐ по `kind`, `parent_or_link` или description; semantic binding появится лишь после trace private update/load methods. +Отдельная ветка того же GOG `AniMesh.dll` показывает, когда создаётся Behavior +для host object. В `FUN_10002ff0` (RVA `0x2ff0`, SHA-256 +`65659bf67f20e5be77d67a5b2f59968f61b94293143807fa59ca451c560c4f7e`) вызывающая +сторона запрашивает IID `0x204` и сохраняет интерфейс в поле `+0x168`. Затем +отдельный импорт `GetQueue()` возвращает объект очереди; вызов метода через его +vtable slot `+0x30` даёт результат, который проверяется на ненулевое значение. +Только при ненулевом результате host class `3` вызывает +`CreateBehaviour(0, 0, self)` (RVA `0x34bd`); class `4` передаёт в +`CreateBehaviour` адреса полей prototype `+0x140` и `+0x160` (RVA `0x3426`). +Семантика метода slot `+0x30` здесь не установлена. Это подтверждает только +такую ветку и эти два класса; другие фабрики, нулевой результат и отложенные +spawn сюда не входят. + +### Один запрос Control для ресурсного устройства + +В CTLD запись tag `26` задаёт ресурсный множитель, но текущее значение +поставщика живёт в runtime state Control. GOG `Control.dll` (SHA-256 +`bcb86318089028548a178b03a21accdce15df0cc85ddd91674cf3c2f55012c6e`) +`FUN_10021d00` (RVA `0x21d00`) реализует getter selector `0x300`. Его фиксированное +слово `+0x2c` становится `fixed_words[11]` при копировании записи RVA `0x21d50`; +`fixed_words[1]` — ключ строки NDP. В объекте Control getter использует ключ +`+0x04`, provider interface `+0x44`, множитель `+0x4c` и коэффициент `+0x54`. +Provider interface направляет selector `1` и ключ в Control RVA `0xdc40`, где +читается текущее type-1 значение выбранной строки. Затем selector умножает +сначала provider на коэффициент, после чего на множитель: `provider * base * +multiplier`. Коэффициент приходит из CTLD; NDP связывает ключ с описанной +строкой, а текущее значение provider нельзя заменить предположением о состоянии +мира. + +Так этот селектор включён в цепочку добычи руды оригинала. В той же сборке +`Behavior.dll` (SHA-256 +`ddfbdbde07832358fe6e35e01c8dba9b58e7313789498b6049ed51d4ed9baf99`) +`FUN_100186b0` (RVA `0x186b0`) перечисляет устройства типа `0x1a`, а +`FUN_100198e0` (RVA `0x198e0`) суммирует успешные запросы IID `0x204` с selector +`0xe00`. В парной `Control.dll` выше `FUN_1002bb40` (RVA `0x2bb40`) для типа +`0x1a` вызывает selector `0x300`, описанный в этом разделе. Затем Behavior query +`0x1002` (RVA `0xa490`) умножает полученную сумму на текущее значение block +`+0x820`, поле `+0x58` `Transfer_Ore_OffBoard` (имя — RVA `0x22e20`, default +5.0 — RVA `0x22d90`; config selector 2 загружает блок через RVA `0x0a1a0`). +Отдельный query `0x1005` (RVA `0xa490`) возвращает поле `+0x60` +`Transfer_Power_Out` (имя — RVA `0x22e20`, default 100.0 — RVA `0x22d90`; +setter — RVA `0xaa40`). Rust helper пока описывает один Control selector `0x300` +при явно переданных входах; он не реализует эту сумму, Behavior-умножение или +подключение к игровому циклу. + +На x87 control word `0x007f` каждое умножение округляет мантиссу до 24 бит, +но промежуточная степень может выйти за диапазон `f32` и вернуться в него при +следующем умножении. Rust helper поэтому принимает явные текущие значения +provider и multiplier, проверяет tag, ключ и строку NDP, сохраняет порядок +операций, но поддерживает только конечные нормализованные значения или ноль на +входе, промежуточном и конечном этапах. Остальные случаи за этим численным +диапазоном он отклоняет; полный x87 accumulator здесь не эмулируется. + +Лицензированный тест на Unit DAT `UNITS/BUILDS/MINE/min_l_n1.dat` проходит через +компонент `fr_l_mine.ctl` и sidecar `fr_l_mine.ndp`: у найденного tag-26 +дескриптора ключ равен `2` из `22` строк, а raw коэффициент — `0x3f800000`. +Тест передаёт helper-у искусственные текущие значения `1.0` только для проверки +записи и привязки ключа; этот Unit DAT не является наблюдением живого Control +tick-а. + ### Control system и physical model `LoadControlSystem` загружает настройки controller-а: ограничения скорости, |
