Звук 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:
@@ -529,12 +529,18 @@ static void animate_leveldoor(uint8_t *m, int8_t *type, uint8_t cur_room)
|
||||
if (sp >= *m) { *m = 0; *type = -1; pop_sfx_play(14); } /* seg007:437 */
|
||||
else {
|
||||
*m = (uint8_t)(*m - sp);
|
||||
if (*type == 4) pop_sfx_play(15); /* seg007:443 */
|
||||
/* seg007:442: створку НА ЗАКРЫТИИ перебивать можно. */
|
||||
if (*type == 4) { pop_sfx_slide_intr = 1; pop_sfx_play(15); }
|
||||
}
|
||||
} else {
|
||||
if (*m < 43) { (*m)++; pop_sfx_play(15); } /* seg007:465 */
|
||||
/* seg007:464: на ОТКРЫТИИ створка неперебиваема — иначе съезд
|
||||
* обрывается посреди и «конца» не слышно. */
|
||||
if (*m < 43) { (*m)++; pop_sfx_slide_intr = 0; pop_sfx_play(15); }
|
||||
if (*m >= 43) {
|
||||
*m = 43; *type = -1;
|
||||
/* seg007:455: дверь открылась — оригинал глушит всё. Без этого
|
||||
* неперебиваемый съезд (1,6 с) продолжал бы блокировать очередь. */
|
||||
pop_sfx_stop();
|
||||
/* Условие оригинала — переход ИЗ 0 или 2, то есть ровно один раз
|
||||
* за открытие; иначе зеркало ставилось бы заново каждый кадр,
|
||||
* пока дверь стоит открытой. */
|
||||
|
||||
Reference in New Issue
Block a user