Звук PoP: приоритеты и перебиваемость вместо «всегда перебивать»
Пользователь услышал расхождение с SDLPoP: у нас решётка обрывалась приземлением Кида, в оригинале доигрывает до конца, а приземления не слышно. Оказалось, упущен целый механизм. play_sound (seg000:12C5) НЕ играет, а только номинирует кандидата на кадр — из нескольких выживает важнейший (меньше prio = важнее, при равенстве последний). play_next_sound (seg000:1304) раз в кадр решает, запускать ли: можно, только если ничего не играет ЛИБО текущий помечен перебиваемым и новый не менее важен. Иначе номинант выбрасывается — очереди в оригинале нет. Отсюда всё, что слышно: gate_closing_fast неперебиваем и доигрывает целиком; челюсти (prio 0x10) всегда важнее решётки (0x32), поэтому решётка звучит только в паузах между укусами. Таблицы из SDLPoP с учётом fix_sound_priorities (в его config.h он определён безусловно). Створка двери уровня — единственная запись, правимая на ходу, вынесена в отдельный байт. Добавлен пропущенный stop_sounds на завершении открытия двери (seg007:455). Проверено записью MAME: старт уровня 1 был 135+210 мс (решётка, обрезанная на 80 мс), стал один всплеск 455 мс с корреляцией огибающей +0,889 со звуком 6. Заведён BUG-SND-FIRSTRUN: искажение первого эффекта при первом запуске после загрузки системы — вероятно, лечится _cbl_prime, но проверить можно только на железе. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -49,14 +49,27 @@ void pop_sfx_toggle(void) __banked;
|
||||
* честно means «звука не будет». */
|
||||
extern uint8_t pop_snd_want;
|
||||
|
||||
/* Начать эффект с номером id (0..56 — нумерация оригинала, см.
|
||||
* sound_plan.md). Перебивает играющий. У звуков без оцифровки (это
|
||||
* музыка) длина 0 — вызов просто глушит текущий.
|
||||
/* Заявить эффект с номером id (0..56 — нумерация оригинала, см.
|
||||
* sound_plan.md). НЕ запускает его немедленно и НЕ перебивает играющий:
|
||||
* это порт play_sound (seg000:12C5), который лишь НОМИНИРУЕТ кандидата на
|
||||
* текущий кадр. Из нескольких заявок за кадр выживает важнейшая, а решение
|
||||
* «запускать или нет» принимает pop_sfx_tick. Звуки без оцифровки (музыка)
|
||||
* игнорируются.
|
||||
*
|
||||
* НЕ банковая и НЕ __banked: зовётся из горячих мест (play_seq в
|
||||
* pop_kid.c, физика, боёвка), и трамплин на каждый шаг Кида не нужен. */
|
||||
void pop_sfx_play(uint8_t id);
|
||||
|
||||
/* Раз в кадр: запустить номинанта, если можно (порт play_next_sound,
|
||||
* seg000:1304). Оригинал зовёт его в конце отрисовки кадра — зовём там же.
|
||||
* Не запустили — номинант ВЫБРАСЫВАЕТСЯ, очереди у оригинала нет. */
|
||||
void pop_sfx_tick(void);
|
||||
|
||||
/* Перебиваемость съезжающей створки двери уровня (звук 15) — единственная
|
||||
* запись таблицы, которую оригинал правит на ходу (seg007:442/464):
|
||||
* 1 при закрытии двери, 0 при открытии. */
|
||||
extern uint8_t pop_sfx_slide_intr;
|
||||
|
||||
/* Оборвать текущий эффект (порт stop_sounds). */
|
||||
void pop_sfx_stop(void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user