24ced6058f
Эффекты берём из MSDOS/digisnd*.dat: 28 из 31 звука совпадают побайтно с набором SDLPoP, но три различаются не в пользу последнего — у него sword_vs_sword короче, sword_moving другой, а spiked вообще пустой (7 сэмплов против 5 069). MIDI наоборот: у MSDOS формат 0 (всё слито в одну дорожку), у SDLPoP формат 1 с 8-9 дорожками — готовое разделение голосов, если дойдём до пути B (MIDI -> три канала AY). Упаковщик: 31 эффект -> 10 937,5 Гц, 131 072 Б = 8 EMM-страниц. Начало каждого звука выровнено на 128 (блок запроса CBL), а страница кратна 128, поэтому ни один блок не пересекает границу страницы — проигрывателю не нужна логика стыка.
44 lines
2.5 KiB
C
44 lines
2.5 KiB
C
/*
|
|
* pop_sfx.h — звуковые ЭФФЕКТЫ PoP через COVOX-Blaster.
|
|
*
|
|
* Данные — оригинальная оцифровка игры (`digisnd1..3.dat`), приведённая
|
|
* упаковщиком к 10 937,5 Гц. Конвертировать в рантайме нечего: у PoP
|
|
* сэмплы 8 бит БЕЗЗНАКОВЫЕ МОНО, и это ровно формат CBL (см. <cbl.h> и
|
|
* ../docs/sound_plan.md).
|
|
*
|
|
* ОДИН ГОЛОС. Оригинал тоже одноголосый: `play_sound` глушит
|
|
* предыдущий звук (`stop_sounds`, seg009.c), поэтому новый эффект просто
|
|
* перебивает играющий, и никакого микшера не нужно.
|
|
*
|
|
* ПОЧЕМУ ЭТО НЕ ЛОМАЕТ КАДР. Насос живёт в прерывании CBL и отдаёт 128
|
|
* байт раз в ~11,7 мс. Кадровые прерывания при этом теряются (ветка CBL
|
|
* в трамплине делает приватный RETI), но нам всё равно: темп кадра
|
|
* считается ПО ЛУЧУ (pop_pace.h), а не по прерываниям. Если бы пейсинг
|
|
* остался на них — звук сломал бы игру.
|
|
*/
|
|
#ifndef POP_SFX_H
|
|
#define POP_SFX_H
|
|
|
|
#include <stdint.h>
|
|
|
|
/* Поднять звук: занять 8 EMM-страниц, вычитать в них набор, открыть CBL.
|
|
* 0 — OK, -1 — не получилось (тогда pop_sfx_play молча ничего не делает,
|
|
* игра идёт без звука). Звать один раз при старте. */
|
|
int pop_sfx_init(void) __banked;
|
|
|
|
/* Закрыть CBL и отпустить страницы; звать на выходе. */
|
|
void pop_sfx_close(void) __banked;
|
|
|
|
/* Начать эффект с номером id (0..56 — нумерация оригинала, см.
|
|
* sound_plan.md). Перебивает играющий. У звуков без оцифровки (это
|
|
* музыка) длина 0 — вызов просто глушит текущий.
|
|
*
|
|
* НЕ банковая и НЕ __banked: зовётся из горячих мест (play_seq в
|
|
* pop_kid.c, физика, боёвка), и трамплин на каждый шаг Кида не нужен. */
|
|
void pop_sfx_play(uint8_t id);
|
|
|
|
/* Оборвать текущий эффект (порт stop_sounds). */
|
|
void pop_sfx_stop(void);
|
|
|
|
#endif
|