feat(fx): play ambient Control sound commands
Docs Deploy / Build and Deploy MkDocs (push) Successful in 38s

This commit is contained in:
Valentin Popov committed 2026-10-31 22:06:49 +04:00
1 parent 3f4059b726
commit 7ba8a0d84e
7 files changed
+573 -24

No files matched your search

+35
View File
@@ -218,6 +218,41 @@ OneShot -> воспроизвести разовый звук молни
отдельный spatial source, применяет DirectSound range/pan и текущий listener.
Отсутствие устройства вывода не должно останавливать симуляцию.
### Звуки Control
Команда Op2 может принадлежать не погоде, а экземпляру эффекта на узле модели.
`fparkan-fx::ambient_sound` хранит её временное окно и предыдущее значение
фазы. В режиме 0 разовый звук начинается при строгом пересечении начала окна:
`previous <= start && start < phase`, если фаза движется вперёд. Значение
`phase == 1` для этой проверки заменяется нулём и подготавливает следующий
цикл. Режим 2 включает loop на обеих границах окна; внутри окна уже работающий
источник обновляется, а не запускается заново. Выход за окно останавливает его.
Позиция интерполируется между двумя локальными точками и проходит через ту же
матрицу владельца, что и графические команды. Минимальная и максимальная
дистанции остаются постоянными; частота интерполируется по фазе окна.
Каждая команда получает отдельный источник звука, даже если ресурс совпадает
с ресурсом соседней команды. Дождь сохраняет свой loop. Перемещение слушателя,
потеря фокуса и завершение приложения затрагивают все эти источники.
Эти ветви восстановлены в GOG `Effect.dll` (сборка из
[таблицы бинарников](original-binaries.md)): init RVA `0x12D10`, update
`0x12EB0`. Живой loop `sounds.lib:f_defl.wav` передаёт в звуковой backend
диапазон `12/80`, частоту `1` и мировую позицию из матрицы владельца.
В режиме 2 признак loop берётся из первого DWORD body, а не из command flag.
Обычное создание эффекта Control сохраняет time mode заголовка и задаёт
постоянную фазу нулём. Raw selector строки служит ID экземпляра, а не номером
режима времени. Поэтому `f_comp_sfx` с time mode 0 и началом окна `0.001`
остаётся тихим до управляющей команды Control. Preview такие команды ещё не
исполняет. Периодические звуки с time mode 2 уже следуют общим часам и текущей
позе узла. `render_coverage control_op2_supported` считает подготовленные
команды, а `control_sound_start/stop` показывает фактические переходы.
Неизвестные backend modes 1/3, ненулевое поле body+76, неподдержанное время
или привязка владельца пропускаются с `render_coverage control_op2_unsupported`.
Они не заменяются разовым звуком или произвольным loop.
## Цвет солнца
Солнце берёт цвет спрайта и прозрачность бликов из `palette[10]` расписания