Музыка по ходу игры: смерть, зелья, меч, конец уровня, катсцены
Звуки 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:
@@ -159,6 +159,38 @@ int8_t pop_music_load(uint8_t id) __banked
|
||||
return (r < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
/* ЗАПУСК С ПОДКАЧКОЙ НА ХОДУ — для игровых джинглов (смерть, зелья, меч).
|
||||
* Ждать полной загрузки нельзя: это фриз на треть секунды посреди игры.
|
||||
* Зато можно начать сразу после ПЕРВОЙ страницы: она звучит 1,5 с, а
|
||||
* следующая читается 33 мс — запас сорокакратный. Дальше вызывающий
|
||||
* доливает по странице за кадр (pop_music_load_step, pop_music_loading).
|
||||
*
|
||||
* Номера страниц известны сразу после mem_alloc_pages, поэтому таблицу для
|
||||
* насоса заполняем целиком: данные в этих страницах появятся раньше, чем
|
||||
* он до них доберётся.
|
||||
* 0 — играет, -1 — трека нет или память кончилась. */
|
||||
int8_t pop_music_stream(uint8_t id) __banked
|
||||
{
|
||||
uint8_t i, n;
|
||||
|
||||
if (pop_music_load_begin(id) != 0) return -1;
|
||||
if (pop_music_load_step() < 0) return -1; /* первая страница */
|
||||
n = ld_slot;
|
||||
pop_mus_left = 0; /* насос — на тишину */
|
||||
for (i = 0; i < ld_pages; i++)
|
||||
pop_mus_page[i] = mem_get_page(slot_blk[n], i);
|
||||
if (n != mus_cur) slot_release(mus_cur);
|
||||
mus_cur = n;
|
||||
slot_pages[n] = ld_pages;
|
||||
slot_blocks[n] = pop_mus_tbl[id].blocks;
|
||||
slot_id[n] = id;
|
||||
pop_mus_id = id;
|
||||
pop_mus_pg = 0;
|
||||
pop_mus_ptr = 0;
|
||||
pop_mus_left = slot_blocks[n];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pop_music_play(void) __banked
|
||||
{
|
||||
uint8_t n, i;
|
||||
@@ -182,6 +214,21 @@ void pop_music_play(void) __banked
|
||||
pop_mus_left = slot_blocks[n];
|
||||
}
|
||||
|
||||
void pop_music_service(void) __banked
|
||||
{
|
||||
/* Один вызов на кадр из ЛЮБОГО цикла — игрового, интро, катсцены.
|
||||
* Заявку кладёт pop_sfx_play (звук без оцифровки = музыка оригинала),
|
||||
* а диск трогаем только здесь. */
|
||||
if (pop_mus_req) {
|
||||
uint8_t id = pop_mus_req;
|
||||
|
||||
pop_mus_req = 0;
|
||||
(void)pop_music_stream(id);
|
||||
} else if (ld_busy) {
|
||||
(void)pop_music_load_step();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t pop_music_busy(void) __banked
|
||||
{
|
||||
return (uint8_t)(pop_mus_left != 0);
|
||||
|
||||
Reference in New Issue
Block a user