Files
Sprinter-SDCC/applications/PoP/roomtest/pop_sfx_cold.c
T
snark13 8ea4c32e51 Звуковые эффекты PoP: оцифровка оригинала через CBL
Набор digisnd1..3.dat приведён упаковщиком к 10 937,5 Гц (частота
железа), склеен в 8 EMM-страниц с выравниванием каждого звука на 128 —
размер блока запроса CBL, поэтому ни один блок не пересекает границу
страницы и проигрыватель не знает слова «стык».

Насос (pop_sfx.c) резидентный: его зовут из прерывания CBL, из горячих
мест физики и из play_seq.  Тишину льём свою (первый блок набора), а не
через CBL_UNDERRUN_SILENCE с его malloc — куча в резиденте W2 тесная.
Открытие CBL разведено с загрузкой (pop_sfx_start отдельно от
pop_sfx_init): пока ESTEX читает файлы, насос не успевает долить блок и
железо крутит хвост буфера — на слух скрежет.

Разведены все места play_sound() SDLPoP, у которых есть оцифровка
(id 0..23, 44..49): посадки, падение, удары о стену, зацеп, тряска и
провал плит, ворота, дверь уровня, пики, чомпер, кнопки, боёвка, меч,
зеркало, скелет, зелье.  Таблица соответствий — docs/sound_plan.md §8.
Музыкальные id остаются с нулевой длиной до фазы музыки.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 15:16:43 +03:00

77 lines
3.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* pop_sfx_cold.c — ХОЛОДНАЯ половина звука: поднять набор и открыть CBL.
* Отрабатывает один раз за запуск, поэтому живёт в банке 8; горячая
* половина (насос, запуск эффекта) — в резиденте, см. pop_sfx.c.
*/
#include <stdint.h>
#include <sprinter_mem.h>
#include <cbl.h>
#include "pop_sfx.h"
#define POP_SND_FILES /* имена файлов нужны ТОЛЬКО здесь, см. pop_sound_tbl.h */
#include "_pop_sfx.h"
static uint8_t snd_blk; /* блок EMM под весь набор */
int pop_sfx_init(void) __banked
{
uint8_t i, blk;
if (pop_snd_ok) return 0;
/* Одним блоком: страницы блока идут подряд по логическому индексу, и
* таблица звуков адресует их именно так (page = смещение >> 14). */
blk = mem_alloc_pages(POP_SND_PAGES);
if (!blk) return -1;
for (i = 0; i < POP_SND_PAGES; i++) {
pop_snd_page[i] = mem_get_page(blk, i);
if (!pop_snd_page[i] ||
pop_page_read(pop_snd_files[i], pop_snd_page[i], 16384) != 0) {
mem_free_block(blk);
return -1;
}
}
snd_blk = blk;
return 0;
}
/* ЗАПУСТИТЬ ВЫВОД — ОТДЕЛЬНО ОТ ЗАГРУЗКИ, и это не косметика.
*
* Пока идёт чтение файлов, CBL держать открытым НЕЛЬЗЯ: ESTEX уходит в
* диск надолго, насос не успевает долить очередные 128 байт, и железо
* крутит по кругу хвост своего 256-байтового буфера. На слух это
* сплошной скрежет (поймано пользователем на старте, 2026-08-20).
* Поэтому загрузка страниц и открытие CBL разведены: грузим молча,
* включаем звук последним действием, а на время загрузки уровня глушим
* (pop_sfx_pause).
*
* Параметры: 10 937,5 Гц, 8 бит моно — формат данных один в один
* (sound_plan.md). OTIR, а не акселератор: тот нужен только для 16 бит.
* UNDERRUN_APP, а не SILENCE: тишину насос льёт СВОЮ (первый блок
* набора), и просить у libc буфер через malloc не надо — куча в
* резиденте W2 тесная, и её отказ ронял бы весь звук. */
int pop_sfx_start(void) __banked
{
if (pop_snd_ok) return 0;
if (!snd_blk) return -1; /* набор не загружен */
if (cbl_open(CBL_FREQ_10K9, CBL_FMT_MONO8, CBL_PUMP_OTIR,
CBL_UNDERRUN_APP, pop_sfx_fill) != 0)
return -1;
pop_snd_ok = 1;
return 0;
}
void pop_sfx_pause(void) __banked
{
if (!pop_snd_ok) return;
pop_sfx_stop();
cbl_close();
pop_snd_ok = 0;
}
void pop_sfx_close(void) __banked
{
pop_sfx_pause();
if (snd_blk) { mem_free_block(snd_blk); snd_blk = 0; }
}