feat(runtime): query and update loaded Control resources
Docs Deploy / Build and Deploy MkDocs (push) Successful in 1m17s
Docs Deploy / Build and Deploy MkDocs (push) Successful in 1m17s
This commit is contained in:
4 files changed
+958
-25
No files matched your search
@@ -282,15 +282,26 @@ Control различает добавление устройства и прим
|
||||
подготовленного CTL должно оставаться явным unavailable result, а не
|
||||
трактоваться как пустой список.
|
||||
|
||||
Глобальные Control selectors `1/2` и setter selector `1` по tag `19` описаны
|
||||
там же только по статическому разбору `Control.dll`; их вызовы отдельно не
|
||||
исполнялись. Проекция полного mission load недоступна для неполного списка
|
||||
typed records, Control resource у non-geometric prototype и некоторых
|
||||
неразрешённых EXTO node mappings; preview и объекты без Unit DAT root её не
|
||||
строят. Её соответствие полной загрузке игры для всех типов компонентов и
|
||||
factory paths ещё не установлено. Не восстановлен и жизненный цикл множителя
|
||||
`+0x4c` после конструктора и переопределения; также неизвестно, когда эти
|
||||
объекты создаются при отложенной загрузке.
|
||||
Global Control getters `1/2` и setter `1` проверены в native x86 oracle для
|
||||
искусственных factory/descriptor pairs `9`, `15` и `19`, а в Rust реализованы
|
||||
для текущего descriptor tag `19` с factory tags `9`, `15`, `19` и `25`. Для tag
|
||||
`25` общий getter slot `+0x10` подтверждён чтением vtable, но агрегатный вызов
|
||||
этого класса native oracle не запускал. Rust API обращается к строкам проекции
|
||||
конкретного живого `ObjectHandle`; это запрос к уже загруженной таблице, а не
|
||||
исполнение Control или Behavior tick. Setter `17`, остальные factory tags и
|
||||
внешние эффекты их методов не включены. Для tag `9` selector `0` использует
|
||||
отдельный scale `+0x11c`; остальные поддержанные классы используют коэффициент
|
||||
напрямую. Пустой набор и нулевой знаменатель остаются native no-result, а
|
||||
неподдержанный factory tag и расчётный диапазон произведения/отношения за
|
||||
нормальным диапазоном `f32` становятся явной ошибкой Rust.
|
||||
|
||||
Проекция полного mission load недоступна для неполного списка typed records,
|
||||
Control resource у non-geometric prototype и некоторых неразрешённых EXTO node
|
||||
mappings; preview и объекты без Unit DAT root её не строят. Её соответствие
|
||||
полной загрузке игры для всех типов компонентов и factory paths ещё не
|
||||
установлено. Setter `1` меняет multiplier `+0x4c` выбранных строк, но расписание
|
||||
и lifetime этих объектов после конструктора и в отложенной загрузке остаются
|
||||
непроверенными.
|
||||
|
||||
Для `Control.dll` (SHA-256
|
||||
`bcb86318089028548a178b03a21accdce15df0cc85ddd91674cf3c2f55012c6e`) tag-26
|
||||
|
||||
@@ -668,14 +668,43 @@ Native x86 oracle для тех же GOG DLL выполняет конструк
|
||||
|
||||
Статический разбор глобального Control interface показывает aggregate getters
|
||||
`1/2` (`FUN_1002b410`, RVA `0x2b410`) и setter `1` (`FUN_1002ba30`, RVA
|
||||
`0x2ba30`) для устройств tag `19`. Для конечных значений getter `1` вычисляет
|
||||
`sum(base * multiplier) / sum(base)`, а getter `2` — `sum(base)`. При встрече
|
||||
отрицательного base selector `1` сразу возвращает `1.0`, а selector
|
||||
`2` — этот base. Если подходящих записей нет или сумма base неположительна,
|
||||
getter возвращает неуспех без записи результата. Setter пишет multiplier `+0x4c`
|
||||
только устройствам tag `19` с положительным selector-0 значением; пустой набор
|
||||
возвращает успех. Это вывод статического анализа для конечных входных значений,
|
||||
без отдельного native execution oracle для глобальных selectors.
|
||||
`0x2ba30`) для текущего descriptor tag `19`. Getter `1` складывает ответы
|
||||
виртуального selector `0x200` в числитель и selector `0` в знаменатель; getter
|
||||
`2` возвращает сумму selector `0`. Для обычного factory tag `19` эти ответы
|
||||
равны `coefficient * multiplier` и `coefficient`, то есть отношение сводится к
|
||||
`sum(coefficient * multiplier) / sum(coefficient)`. У factory tag `9` selector
|
||||
`0` умножает коэффициент на отдельное поле `+0x11c`, тогда как selector `0x200`
|
||||
использует коэффициент и multiplier; эта особая база меняет знаменатель.
|
||||
Обработчик factory tag `9` расположен в Control RVA `0x255c0`, а его конструктор
|
||||
RVA `0x25460` задаёт `+0x11c = 1.0`. При встрече отрицательного ответа selector
|
||||
`0` getter `1` сразу возвращает `1.0`, а getter `2` — этот ответ. Если подходящих
|
||||
записей нет или сумма базы неположительна, getter возвращает неуспех без записи
|
||||
результата. Setter пишет multiplier `+0x4c` только устройствам с текущим
|
||||
descriptor tag `19` и положительным selector-0 ответом; пустой набор возвращает
|
||||
успех. Фильтр использует **текущий descriptor tag**, который может измениться
|
||||
при `INTO`, а виртуальный вызов остаётся методом исходного factory-класса.
|
||||
|
||||
Этот путь проверяется native x86 oracle на оригинальной `Control.dll` указанной
|
||||
выше: искусственные factory/descriptor пары `9`, `15` и `19` покрывают setter,
|
||||
отрицательные ответы, округление и тег `9` с scale `0.5`. Для factory tag `25`
|
||||
его vtable slot `+0x10` статически указывает на общий getter RVA `0x21d00`, но
|
||||
отдельный aggregate oracle этот класс не запускал. Rust хранит начальный scale
|
||||
factory `9` и предоставляет `query_loaded_mission_control_resource` для selector
|
||||
`1`/`2` и `set_loaded_mission_control_multiplier` для setter-а `1`. Вызовы
|
||||
сначала проверяют живой `ObjectHandle`, затем обращаются к таблице этого объекта
|
||||
из полной загрузки миссии. Синтетические тесты проверяют границы пустой таблицы,
|
||||
нулевого знаменателя, неподдержанных factory tags и чисел за диапазоном
|
||||
нормального `f32`; лицензированный тест сверяет реальные descriptor tags и
|
||||
получает для `min_l_n1.dat` сумму `16` и отношение `1` до setter-а.
|
||||
|
||||
В этом API пока реализованы только getter selectors `1`/`2` и setter `1`.
|
||||
Отдельный native setter selector `17`, tag-specific методы прочих factory tags,
|
||||
их внешние эффекты и вызов из регулярного шага Behavior здесь не моделируются.
|
||||
Числа должны оставаться конечными и нормальными либо точным нулём; произведения
|
||||
и отношения за поддерживаемым диапазоном `f32` возвращают явную ошибку, а не
|
||||
подменяются нулём или `None`. При проверке диапазона Rust оценивает операцию в
|
||||
`f64`, затем выполняет её в `f32`; это ограниченная проверка диапазона, а не
|
||||
эмуляция полного x87 accumulator-а.
|
||||
|
||||
Отдельная ветка того же GOG `AniMesh.dll` показывает, когда создаётся Behavior
|
||||
для host object. В `FUN_10002ff0` (RVA `0x2ff0`, SHA-256
|
||||
|
||||
Reference in new issue
Block a user