Звуковые эффекты 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>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
* См. pop_trob.h.
|
||||
*/
|
||||
#include "pop_trob.h"
|
||||
#include "pop_sfx.h" /* звуковые эффекты (../docs/sound_plan.md) */
|
||||
#include "pop_state.h" /* pop_leveldoor_open */
|
||||
#include "pop_level.h"
|
||||
#include "pop_geom.h"
|
||||
@@ -265,6 +266,7 @@ static void animate_chomper(uint8_t *m, int8_t *type,
|
||||
frame = (uint8_t)((*m & 0x7F) + 1);
|
||||
if (frame > POP_CHOMPER_SPEED) frame = 1;
|
||||
*m = (uint8_t)(blood | frame);
|
||||
if (frame == 2) pop_sfx_play(47); /* щелчок челюстей, seg007:297 */
|
||||
if ((room != drawn_room || (int8_t)TP_ROW[tp] != Kid.curr_row ||
|
||||
(Kid.alive >= 0 && blood == 0)) && frame >= 6)
|
||||
*type = -1;
|
||||
@@ -463,8 +465,9 @@ void pop_trigger_button(uint8_t room, uint8_t tilepos,
|
||||
set_doorlink_timer(modifier, POP_DBG_GATE_HOLD);
|
||||
if (link_timer < 2) {
|
||||
pop_add_trob(room, tilepos, 1); /* кнопка нажимается */
|
||||
/* seg007:766: щелчок кнопки — шум, страж оборачивается. Звука у
|
||||
* нас нет, флаг обязан быть (BUG-GUARD-DEAF-1). */
|
||||
/* seg007:766: щелчок кнопки — шум, и страж оборачивается
|
||||
* (флаг обязателен даже без звука, BUG-GUARD-DEAF-1). */
|
||||
pop_sfx_play(3);
|
||||
is_guard_notice = 1;
|
||||
}
|
||||
do_trigger_list(modifier, button_type);
|
||||
@@ -523,10 +526,13 @@ static void animate_leveldoor(uint8_t *m, int8_t *type, uint8_t cur_room)
|
||||
uint8_t sp;
|
||||
if (*type < 7) (*type)++;
|
||||
sp = leveldoor_close_speeds[*type - 3];
|
||||
if (sp >= *m) { *m = 0; *type = -1; }
|
||||
else *m = (uint8_t)(*m - sp);
|
||||
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 */
|
||||
}
|
||||
} else {
|
||||
if (*m < 43) (*m)++;
|
||||
if (*m < 43) { (*m)++; pop_sfx_play(15); } /* seg007:465 */
|
||||
if (*m >= 43) {
|
||||
*m = 43; *type = -1;
|
||||
/* Условие оригинала — переход ИЗ 0 или 2, то есть ровно один раз
|
||||
@@ -546,7 +552,7 @@ static void animate_leveldoor(uint8_t *m, int8_t *type, uint8_t cur_room)
|
||||
static const uint8_t gate_close_speeds[9] = {0, 0, 0, 20, 40, 60, 80, 100, 120};
|
||||
static const int8_t door_delta[3] = {-1, 4, 4};
|
||||
|
||||
static void animate_door(uint8_t *m, int8_t *type)
|
||||
static void animate_door(uint8_t *m, int8_t *type, uint8_t audible)
|
||||
{
|
||||
int8_t anim_type = *type;
|
||||
uint8_t mod = *m;
|
||||
@@ -555,18 +561,23 @@ static void animate_door(uint8_t *m, int8_t *type)
|
||||
if (anim_type < 8) { anim_type++; *type = anim_type; }
|
||||
{
|
||||
int new_mod = (int)mod - gate_close_speeds[anim_type];
|
||||
if (new_mod < 0) { mod = 0; *type = -1; }
|
||||
if (new_mod < 0) { mod = 0; *type = -1; pop_sfx_play(6); }
|
||||
else mod = (uint8_t)new_mod;
|
||||
}
|
||||
} else if (mod != 0xFF) {
|
||||
mod = (uint8_t)(mod + door_delta[anim_type]);
|
||||
if (anim_type == 0) { /* закрытие */
|
||||
if (mod == 0) *type = -1; /* gate_stop */
|
||||
/* seg007:376: скрип закрывающейся решётки — раз в четыре
|
||||
* шага модификатора и ТОЛЬКО если комната на экране
|
||||
* (play_door_sound_if_visible), иначе на 13-м уровне
|
||||
* скрипели бы решётки из соседних комнат. */
|
||||
else if (mod < 188 && (mod & 3) == 3 && audible) pop_sfx_play(4);
|
||||
} else { /* открытие */
|
||||
if (mod >= 188) {
|
||||
if (anim_type < 2) { mod = 238; *type = 0; } /* открыт → потом закрывать */
|
||||
if (anim_type < 2) { mod = 238; *type = 0; pop_sfx_play(7); }
|
||||
else { mod = 0xFF; *type = -1; } /* насовсем */
|
||||
}
|
||||
} else if ((mod & 7) == 0) pop_sfx_play(5); /* seg007:386 */
|
||||
}
|
||||
} else {
|
||||
*type = -1;
|
||||
@@ -672,7 +683,7 @@ void pop_process_trobs(uint8_t cur_room) __banked
|
||||
animate_button(mod[tp], &type); /* mod[tp] = индекс LINKLOC кнопки */
|
||||
break;
|
||||
case TILE_GATE:
|
||||
animate_door(&mod[tp], &type);
|
||||
animate_door(&mod[tp], &type, (uint8_t)(room == cur_room));
|
||||
break;
|
||||
case TILE_LOOSE:
|
||||
animate_loose(&mod[tp], &type, room, tp, cur_room);
|
||||
|
||||
Reference in New Issue
Block a user