Музыка по ходу игры: смерть, зелья, меч, конец уровня, катсцены

Звуки 24..43 в наборе оцифровки пустые — в оригинале это Adlib-музыка, и
в digisnd её нет. На этом и построено подключение: pop_sfx_play для звука
с нулевой длиной кладёт номер в pop_mus_req, а разбирает заявку
pop_music_service() — один вызов на кадр из любого цикла (игра, интро,
катсцена). Всё чтение с диска живёт там.

Ждать полной загрузки джингла нельзя — это фриз посреди игры. Поэтому
pop_music_stream читает первую страницу (33 мс) и сразу пускает трек: она
звучит 1,5 с, а следующая читается те же 33 мс. Остальные доливаются по
одной за кадр.

Расставлено по местам оригинала: смерть (24/28/32), вступление первого
уровня и тень шестого (25), сцены перед уровнями (27/35/40), встреча с
Джафаром (29), зелья (30/33/39), время вышло (36), меч и смерть стража
(37), смерть Джафара (43), конец уровня (41/32), встреча с принцессой
(26). Темы «раз за уровень» сбрасывает pop_music_level_start.

Упакован 21 трек (2,4 МБ). Не озвучен только финал: won — 115 с и 78
страниц EMM, ему нужен кольцевой стриминг (задача MUS-WON на доске).

Проверено в MAME: вступительная тема первого уровня отыгрывается на
старте (курсор дошёл до конца, id 25). Host-тесты: 15 наборов.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-25 21:52:37 +03:00
parent 65797af44c
commit 7e6b38cca6
33 changed files with 300 additions and 35 deletions
+28 -6
View File
@@ -46,6 +46,18 @@
/* tile_is_floor (seg004): не-пол — пустота, ковёр, верх двери, стена и
* «половинки» 26..29. Дубликат крошечного switch'а из pop_map: тянуть его
* через границу банка дороже, чем повторить. */
/* Темы, которые звучат ОДИН раз за заход на уровень: тень шестого уровня
* (seg002:0090) и вступление первого. Оригинал отмечает «уже играли»
* через leveldoor_open = 0x4D, то есть портит переменную двери; у нас на
* это есть свои байты, а сбрасывает их старт уровня. */
static uint8_t shadow6_music;
void pop_music_level_start(void) __banked
{
shadow6_music = 0;
pop_ctrl_level_start();
}
static uint8_t tile_is_floor(uint8_t t)
{
switch (t) {
@@ -343,12 +355,16 @@ uint8_t pop_check_shadow(uint8_t room) __banked
return 1;
}
/* Уровень 6 (seg002:0090): условий на содержимое комнаты нет вовсе —
* тень встаёт при КАЖДОМ входе в комнату 1. Оригинал здесь ещё играет
* sound_25_presentation один раз, отмечая это `leveldoor_open = 0x4D`
* (переменная двери используется как флаг); звука у нас нет, а чужую
* переменную портить незачем — TODO вместе со звуком. */
* тень встаёт при КАЖДОМ входе в комнату 1. Оригинал играет здесь
* sound_25_presentation, помечая «уже играли» через leveldoor_open =
* 0x4D (переменную двери он использует как флаг). Чужую переменную не
* трогаем: у нас для этого свой однобайтовый флаг. */
if (pop_current_level == SHADOW_STEP_LEVEL) {
if (room != SHADOW_STEP_ROOM) return 0;
if (!shadow6_music) {
shadow6_music = 1;
pop_sfx_play(25);
}
do_init_shad(init_shad_6, room, SEQ_2_STAND);
return 1;
}
@@ -384,7 +400,6 @@ void pop_sword_disappears(void) __banked
* комнаты 3 и попадает прямо к Джафару. Всё событие — фора: пока
* pop_guard_notice_timer идёт, Джафар не встаёт в боевую стойку
* (autocontrol_guard_inactive), то есть у Кида есть ~2 секунды достать меч.
* В оригинале здесь же играет sound_29_meet_Jaffar — звука у нас нет.
*
* `pop_leveldoor_open == 0` в условии не косметика: вернувшись к Джафару
* после его смерти (дверь уже открыта), форы быть не должно.
@@ -396,6 +411,7 @@ void pop_meet_jaffar(void) __banked
if (pop_current_level != JAFFAR_LEVEL) return;
if (pop_leveldoor_open != 0) return;
if (Kid.room != JAFFAR_MEET_ROOM) return;
pop_sfx_play(29); /* тема встречи с Джафаром */
pop_guard_notice_timer = JAFFAR_NOTICE_TIME;
}
@@ -426,7 +442,13 @@ void pop_jaffar_exit(void) __banked
* Демо-уровень (0) сюда тоже не входит: его ветка — часть аттракта. */
static void on_guard_killed(void)
{
if (pop_current_level != JAFFAR_LEVEL) return;
if (pop_current_level != JAFFAR_LEVEL) {
/* seg006:1940 — победный трек за стража; за тень его нет: она не
* «убита», а слилась с Кидом. */
if (Char.charid != CHARID_1_SHADOW) pop_sfx_play(37);
return;
}
pop_sfx_play(43); /* смерть Джафара — свой трек */
pop_flash_color = POP_FLASH_WHITE;
pop_flash_time = JAFFAR_FLASH_TIME;
pop_leveldoor_open = 2;