feat(runtime): project initial Behavior control groups
Docs Deploy / Build and Deploy MkDocs (push) Successful in 37s

This commit is contained in:
Valentin Popov committed 2026-10-31 08:24:58 +04:00
1 parent 6412c12c09
commit 8c11e0f470
4 files changed
+328

No files matched your search

+43
View File
@@ -763,6 +763,49 @@ tie-векторов подтверждает реакцию `FISTP`, но не
одного numeric literal; остальные формы инструкции и содержимое `.scr`
сохраняются reader-ом, но остаются вне этого исполнения.
### Начальная группировка подготовленных Control-дескрипторов
В проверенной GOG `Behavior.dll` (SHA-256
`ddfbdbde07832358fe6e35e01c8dba9b58e7313789498b6049ed51d4ed9baf99`)
`FUN_1001be10` (RVA `0x1be10`) получает список через QI с кодом `0x202` от
`owner+0x5c`. Слоты `+0x50` и `+0x1c` этого интерфейса возвращают число строк и
код-различитель для строки; цикл обрабатывает порядковые номера строк
`0..count-1` по возрастанию. Метки `1`, `2` и `30` начинают группу, добавляют
кандидата и добавляют отдельный элемент к последней группе соответственно.
Запись с меткой `2` до первого заголовка попадает в отдельный вектор; метка `30`
без группы игнорируется, как и все остальные метки.
Для источника списка проверена пара GOG DLL. В `Control.dll` SHA-256
`bcb86318089028548a178b03a21accdce15df0cc85ddd91674cf3c2f55012c6e` запрос с
кодом `0x202` отдаёт интерфейс `owner+8`; его методы-обёртки переходят к методам
чтения канонического QI `0x204`, receiver которого равен `owner+0x0c`. Метод
`Control.dll` RVA `0x8830` читает число из `[receiver+0x5b4]`, то есть
`[owner+0x5c0]`; таблица указателей находится в `[receiver+0x5b0]`, то есть
`[owner+0x5bc]`. Поле `[owner+0x5b4]` — отдельный указатель кэша, а не число
строк. Метод чтения `Control.dll` RVA `0x2c390` выбирает указатель `table[index]`,
разыменовывает указатель на дескриптор из записи `+0x48` и возвращает DWORD по
адресу этого дескриптора. Загрузчик `FUN_10021d50` (RVA `0x21d50`) сохраняет там
указатель текущего дескриптора, поэтому код-различитель — его текущая метка, а
не неизменная метка фабрики.
В оригинальном Behavior внешняя строка имеет шаг `0x34`; её `+4` получает
порядковый номер заголовка. Строка-кандидат имеет шаг `0x58`, а её `+8` хранит
порядковый номер кандидата. Номера строк с меткой `30` добавляются в отдельный
вектор последней внешней строки. Rust публикует только эти начальные номера:
`MissionBehaviorControlGroup` и
`MissionBehaviorControlGrouping` группируют строки из уже подготовленной
Control-таблицы в её исходном порядке. `MissionBehaviorControlGroupingState`
сохраняет `original_id`, `ObjectHandle` и либо результат, либо исходную причину
недоступности Control-таблицы. Полная загрузка создаёт проекцию перед публикацией
`LoadedMissionState`; предварительный просмотр возвращает пустой список. Проверки
`behavior_control_grouping_uses_current_tags_and_table_ordinals` и игнорируемый
`full_load_builds_initial_behavior_control_groupings_for_autodemo` покрывают
искусственные граничные случаи и сохранённые номера строк AutoDemo соответственно.
Это начальное разложение подготовленного списка, а не реконструкция полной
инициализации Behavior: отдельные свойства строки-кандидата, её числовые поля,
эффекты и обновление списка после изменений Control здесь не моделируются.
### Изменение provider-состояния Control
Для `Control.dll` (SHA-256