SprPoP: музыка без перелинковки — длины и длительности уехали на диск
Часть I плана music_runtime_index_plan.md (MI0..MI5). gen/pop_music_tbl.h и gen/pop_music_ticks.h УДАЛЕНЫ: длины треков и длительности реплик читаются из MUS/mus.idx (формат PMI1, tools/pop_idx.py, тесты в make test-tools). Один и тот же sprpop.exe работает с любым из четырёх наборов записей — sha256 бинарника при смене MUSIC_FMT не меняется. ГДЕ ЖИВЁТ ИНДЕКС. 228 байт таблицы в W2 не положить (свободной кучи там порядка двух сотен), поэтому индекс лежит в одной странице EMM, а в резиденте от него два байта. Данные в странице — со смещения 0x100: gfx_w0_page_prepare пишет в неё стабы прерываний (0x38 и 0x66), и с нуля они попали бы прямо в записи id 10 и 21. Со смещением работает штатная защита, а не запрет прерываний (тот же приём, что CFG_BASE в pop_config.c). Число страниц в индексе не хранится — считается из blocks, чтобы не разъехалось. ПАУЗА КОНЦА УРОВНЯ — СОСТОЯНИЕМ, А НЕ СЧЁТЧИКОМ. pop_endmus_left и POP_MUS_TICKS_32/41 удалены; главный цикл ждёт pop_music_active() — «заявка лежит, идёт загрузка или трек звучит». Одного busy мало: между заявкой и первой нотой 190-230 мс (замер в sound_plan §9). Прежний счётчик закрывал эту щель ценой зависимости EXE от набора и жёсткого делителя /4, который врал в режимах FAST/FASTEST (там логический кадр 3 кадра луча, а не 4). Побочно исправилось расхождение с SDLPoP: при выключенном звуке заявка не кладётся, и уровень меняется сразу, как в оригинале (seg006:651 + seg003:387) — раньше игра держала пройденный уровень лишние 12 секунд в тишине. PV-СЦЕНА — на четырёх якорях (8 байт статики), которые считаются из индекса при входе в сцену; прежние выражения шкалы не изменились. План предлагал протащить структуру времён через пять функций — для сцены, которая идёт раз за запуск, это того не стоит. ПАМЯТЬ. За обе фазы резидент не вырос, а освободился: _CODE 23865 -> 23544, куча 239 -> 256 Б. Банк 9 похудел на 118 Б (ушла pop_mus_tbl из rodata), банк 11 — на длительности реплик. ПРОВЕРЕНО В MAME: exe побайтово одинаков для flac и mt32; все 22 трека в индексах различаются, и контрольные значения совпали с предсказанными планом (m41 732->685, m50 831->867, m53 985->1044, m56 9865->10462 блоков, 78->82 страницы); на mt32 PV-сцена проходит целиком по его длительностям; без mus.idx музыки нет, эффекты работают, игра проходима. НЕ ПРОВЕРЕНО: потоковый m56 на 82 страницах — до финала надо дойти в игре. Единственный оставшийся пункт приёмки, отмечен в sound_plan §11.5. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011MsUsEFAQfsjjQpJ7RtKVY
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
# Аудио без перелинковки: runtime-индексы музыки и эффектов
|
||||
|
||||
> Статус: **часть II (эффекты, SI0..SI4) СДЕЛАНА 2026-08-31** — разбор и
|
||||
> результаты в `sound_plan.md` §10. Часть I (музыка, MI0..MI5) — план.
|
||||
> Статус: **ОБЕ ЧАСТИ СДЕЛАНЫ 2026-08-31** — эффекты (SI0..SI4) и музыка
|
||||
> (MI0..MI5). Разбор и результаты: `sound_plan.md` §10 (эффекты) и §11
|
||||
> (музыка). Ниже — исходный план; расхождения перечислены следом.
|
||||
>
|
||||
> Что в реализации разошлось с планом ниже: файл назван `SND/snd.idx`
|
||||
> (единый basename с `snd.arc`, оба в нижнем регистре), а при отсутствии
|
||||
@@ -9,6 +10,16 @@
|
||||
> и игра непроходима (§10.5 sound_plan). Про `ticks60` в `PMI1` решено:
|
||||
> поле в формате оставить даже если сценарии перейдут на ожидание звука —
|
||||
> загрузчик волен не тащить его в память.
|
||||
>
|
||||
> Расхождения части I с планом ниже:
|
||||
> * файл назван `MUS/mus.idx` (единый стиль с `snd.idx`);
|
||||
> * пауза конца уровня переведена НЕ на runtime-тики, а на состояние
|
||||
> «заявка/загрузка/звучание» (`pop_music_active`) — §11.2: это снимает и
|
||||
> зависимость от набора, и враньё делителя `/4` в быстрых режимах, и
|
||||
> расхождение с SDLPoP при выключенном звуке;
|
||||
> * PV-сцена (§8 плана) — не структура времён через пять функций, а четыре
|
||||
> якоря-статики (8 байт), от которых отсчитываются прежние выражения;
|
||||
> * `pages` в PMI1 не хранится — считается из `blocks`.
|
||||
|
||||
## 1. Цель
|
||||
|
||||
|
||||
Reference in New Issue
Block a user