diff options
| author | Valentin Popov <valentin@popov.link> | 2026-10-31 16:00:48 +0300 |
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2026-10-31 16:00:48 +0300 |
| commit | 6c7740f13396c124b9ec1df2ae7b05daee2f4905 (patch) | |
| tree | 61c169293d67281a6258c212ce9d734e7d2e702a /docs/appendices/script-vm.md | |
| parent | 5adefa67146885f1a307e80117b698b965d70ceb (diff) | |
| download | fparkan-6c7740f13396c124b9ec1df2ae7b05daee2f4905.tar.xz fparkan-6c7740f13396c124b9ec1df2ae7b05daee2f4905.zip | |
feat(runtime): project factory-2 selector 6 metadata
Diffstat (limited to 'docs/appendices/script-vm.md')
| -rw-r--r-- | docs/appendices/script-vm.md | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/docs/appendices/script-vm.md b/docs/appendices/script-vm.md index 145d2a2..f7f8b97 100644 --- a/docs/appendices/script-vm.md +++ b/docs/appendices/script-vm.md @@ -1502,7 +1502,69 @@ RVA `0x2bb9a` загружает `device+0x174` как `f32`, сохраняет буфер и возвращает `AL=1`/`RET 8`; другие текущие теги возвращают false. Наличие поля `+0x174` подтверждено для экземпляра фабрики `2`. INTO сохраняет исходный тип экземпляра, поэтому проверка тега descriptor отдельно не доказывает -наличие этого поля у другой фабрики. В Rust selector `6` пока не поддержан. +наличие этого поля у другой фабрики. Rust selector `6` сначала проверяет +текущий descriptor tag: тег не `2` даёт `Ok(None)`; затем требуется известная +фабрика `2` и конечное нормальное число либо ноль любого знака в `+0x174`. В +`Control.dll` (SHA-256 +`bcb86318089028548a178b03a21accdce15df0cc85ddd91674cf3c2f55012c6e`) поле +получает ноль в конструкторе по RVA `0x294c0`; чтение, сравнение пары строк и +пересчёт находятся по RVA `0x2bb40`, `0x29940` и `0x296f0`. + +Typed record хранит две ASCII C-строки в words `[27..35)` и `[35..43)`. Строка +заканчивается на первом NUL: байты за ним игнорируются, а регистр при сравнении +не учитывается. Если новая, изменённая пара содержит пустую строку, native +recalc завершается до `CreateObject` и selector `35`, поэтому сохраняются +прежние биты. Пустая пара конструктора уже совпадает с текущей и вообще не +запускает recalc. Иначе append и первая активная запись `INTO` применяют +результат в исходном порядке. Для нераспознанной формы поле остаётся +недоступным; ошибка разбора распознанного, но повреждённого ресурса прерывает +новую загрузку до публикации. + +В общем случае native selector 35 не равен сумме сырых Max: +`Control.dll` getter `0x0dc40` (selector 3) читает Max по `descriptor+4`, где +указатель descriptor лежит в начале runtime provider row, затем умножает его +на масштабы владельца `+0x660` и `+0x548`. Функция `0x13620` складывает выходы +в порядке строк с округлением `f32`; при `row+0x24 != 0xffffffff` добавляется +индексированный вклад. Конструктор `0xb240` задаёт runtime `row+0x24` +служебное значение `0xffffffff`. Только в свежей форме поддержанного BULL оба +масштаба равны `1`, а все `row+0x24` равны +`0xffffffff`, поэтому формула сводится к NDP Max сумме. + +Пересчёт создаёт временный объект запросом `9` через `World3D.dll+0x7cb0`. +Загрузчик `Control.dll+0x32280` формирует для его корня входной контекст с +полем `+0xc8 = 0xffffffff`. Для разрешённых opcode `1` и `12`, а +также `4` только после FXID/CPT-проверки, подтверждённые callbacks сохраняют +входы суммы: `Control.dll` RVA `0x43d0` меняет только локальные слова; в +`AniMesh.dll` (`65659bf67f20e5be77d67a5b2f59968f61b94293143807fa59ca451c560c4f7e`) +RVA `0x5500/0x93c0` меняют узлы и список модели, а `0x5320` не пишет её +масштабы. Это статическая граница свежего пути, не снимок живого native World +после всех creation callbacks. + +Проверка opcode `4` читает только выбранные строки и принимает FXID-типы +`2/3/4/5/7/8/9` с распознанными ASCII-ссылками и CPT offsets внутри компонента; +типы `1/6/10`, отсутствующие ресурсы и непроверенные offsets оставляют поле +недоступным. В `Effect.dll` (SHA-256 +`386a3e8db1ce23f61957825d633c7dae1ed40c25cab0cf10a534385fd7cee789`) проверены +инициализаторы типов `2/3/4/5/7/8/9` по RVA `0x12d10/0x103b0/0x108c0/0x28a0/ +0x1720/0x11230`; тип `9` разделяет путь типа `3`. + +`AssetManager::initial_control_effect_opcodes` собирает исходный порядок кодов +выбранной начальной группы до фильтра opcode `4`. `Some([])` означает, что +по структуре данных команд нет: группа отсутствует, пуста или её беззнаковый +индекс не меньше числа групп. Условия отдельных строк этот читатель не +вычисляет. `None` означает неподдержанный либо +неполный формат, а повреждённая структура возвращает ошибку. Такая разница не +позволяет принять неизвестный разбор за пустую сумму. + +Ресурсные callbacks в этой цепочке привязаны также к следующим образам. +Записи палитры и звуковые либо графические буферы имеют отдельное хранение; +проверенные начальные вызовы не меняют входы суммы NDP. + +| Модуль | SHA-256 | Существенные RVA | +|---|---|---| +| `World3D.dll` | `17e4a3089b2583a8cf2356c9db0390b1aba138356a09130d79b4e7e4791da61e` | `0x7cb0` — создание; `0x4b10/0x4cb0` — текстуры и lightmap | +| `Ngi32.dll` | `bab9840d94f4e4e74ffc26677724fa896cf4823845504d09a9e025f80016edf5` | `0x11f80` — чтение ресурса; `0x11410` — счётчик палитры; `0xd620/0xe900` — звуковые буферы | +| `Terrain.dll` | `af87d1b2e728a0be73c52be3b44cc196ab46da7799f25a15d40f8c9b0b425ead` | `0x166a0/0x17ac0` — получение указателя на числовое поле World | FCA0 передаёт в owner query порядковый номер `i`; query `0x2bb40` находит устройство `i` и вызывает его reader. Уже reader `FUN_10021d00` получает provider |
