SprPoP: звуковые эффекты без перелинковки — раскладка уехала на диск
Часть II плана music_runtime_index_plan.md (SI0..SI4). gen/pop_sound_tbl.h БОЛЬШЕ НЕ ГЕНЕРИРУЕТСЯ: раскладка набора читается из SND/snd.idx (формат PSI1, писатель и разборщик — tools/pop_idx.py, 22 теста в make test-tools). Один и тот же sprpop.exe работает с набором SDLPoP (9 страниц) и MSDOS (10) — sha256 бинарника при смене набора не меняется. Заодно умолчание источника эффектов переведено на SDLPoP (SND_SRC=sdlpop): сборка обязана работать без оригинального дистрибутива DOS. У кого он есть, включает лучший набор явно — make SND_SRC=msdos (там полнее оцифровка: в SDLPoP звук 48 spiked пустой). Устройство: pop_snd_tbl/pop_snd_page/pop_snd_pages — резидентные данные (pop_snd_data.c), тип и инварианты — рукописный pop_snd_tbl.h. Записи читаются ОДНИМ read прямо в таблицу, поэтому sizeof(pop_snd_ent_t) == 5 стало частью дискового контракта: проверяется статически и полем размера записи в заголовке. POP_SND_PAGES как compile-time размер набора исчез — вместо него POP_SND_MAX_PAGES (вместимость, 16) и runtime pop_snd_pages. Цена: таблица переехала из _CODE в _DATA, суммарный резидент почти не изменился (куча 239 -> 229 Б); банк 8 +601 Б на чтение и валидацию. Валидация не доверяет файлу: заголовок целиком плюс каждая запись (страница, смещение, кратность блоку, непересечение с блоком тишины, выход за последнюю страницу). Последнее считается В БЛОКАХ — байтовый адрес конца не влезает в uint16, а 32-битная арифметика на Z80 дорога. НЕТ ИНДЕКСА — ЭФФЕКТОВ НЕТ, НО МУЗЫКА ИГРАЕТ. Первая версия просто возвращала ошибку, и игра становилась непроходимой: тишину льёт первый блок набора, без набора CBL не открывался, а с ним вставала музыка (её блоки считает тот же насос) — заставка ждала конца трека вечно. Теперь поднимается пустой набор с блоком тишины. Заливается ровно 128 байт и под DI: gfx_w0_page_prepare ставит в страницу IRQ-стабы, и заливка всей страницы затирала их — первое же прерывание давало чёрный экран. Грабли сборки: смена SND_SRC тихо давала неверный результат (sdlpop -> msdos -> sdlpop оставлял чужой набор в assets/packed). Причина не в логике, а в секундной гранулярности mtime. Лечение убирает время из решения: смена варианта сносит stamp'ы своего семейства, а упаковка, сборка архива и копия индекса делаются одним рецептом. То же получила и музыка (MUSIC_FMT). Проверено в MAME: таблица в памяти совпадает с файлом из образа побайтово; один EXE поднимает оба набора; отладочный --order reverse (30 из 31 записей отличаются от штатных) звучит правильно; битый индекс выключает эффекты, не роняя игру; без индекса PV-сцена проходит с музыкой; Ctrl+S работает в обоих режимах. Разбор — docs/sound_plan.md §10. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011MsUsEFAQfsjjQpJ7RtKVY
This commit is contained in:
@@ -17,8 +17,9 @@ sprinter-cc / libc / libbgi. Действуют правила корневог
|
||||
## Главное правило: SDLPoP — источник истины. Сначала читай, потом кодь
|
||||
|
||||
**`assets/orig/SDLPoP/src/` (github.com/NagyD/SDLPoP, GPLv3) — ЕДИНСТВЕННЫЙ
|
||||
авторитетный источник того, как оригинальный движок это делает.** Правило
|
||||
без исключений:
|
||||
авторитетный источник того, как оригинальный движок это делает.** В
|
||||
репозитории его нет: заполняется `make fetch` (`make fetch-check` — что уже
|
||||
на месте). Правило без исключений:
|
||||
|
||||
1. **Перед реализацией ЛЮБОЙ функции** (движение, коллизия, окклюзия,
|
||||
падение, loose-полы, стражники, отрисовка, тайминги, любые числовые
|
||||
@@ -69,6 +70,8 @@ make собрать build/sprpop.exe и разложить build
|
||||
make hdd + образ build/hdd/sprpop.chd
|
||||
make mame-link однократно: подставить образ в MAME (см. ниже)
|
||||
make -C tests/host модульные тесты движка под ucsim_z80 (секунды, без MAME)
|
||||
make test-tools тесты упаковщиков на хосте (форматы, которые читает Z80)
|
||||
make fetch скачать внешние данные в assets/orig/ (SDLPoP + музыка)
|
||||
make resources перегенерировать ресурсы из assets/orig/
|
||||
make music-mp3 музыка из другого набора (flac|mp3|ogg|mt32)
|
||||
make clean снести build/ (ассеты не трогает)
|
||||
@@ -93,13 +96,19 @@ make distclean clean + снести assets/packed/ (вернуть — mak
|
||||
|---|---|
|
||||
| `src/` | рукописный C: главный цикл `sprpop.c`, холодная половина `sprpop_cold.c`, движок `pop_*.c` |
|
||||
| `gen/` | генерируемые заголовки (индексы архивов, таблицы кадров, шрифт, палитры). **Руками не править** — их печатают упаковщики; лежат в репозитории, потому что без них `src/` не собрать |
|
||||
| `assets/orig/` | оригинальные данные (SDLPoP, MSDOS, записи музыки). Вне репозитория — копирайт; что и откуда взять, написано в `assets/orig/README.md` |
|
||||
| `assets/orig/` | оригинальные данные (SDLPoP, записи музыки; MSDOS — необязательно). Вне репозитория — копирайт; вместо них в репозитории лежит `tools/fetch_orig.py`, который их качает (`make fetch`). Правила — в `assets/orig/README.md` |
|
||||
| `assets/packed/` | то, что ложится на диск игры, уже в раскладке диска (`BG/`, `KID/`, …). В репозитории — иначе из чистого клона не собрать |
|
||||
| `tools/` | конверторы ресурсов. Раскладку путей знает ОДИН файл — `tools/paths.py`; менять пути нужно там, а не в отдельных упаковщиках |
|
||||
| `tools/` | конверторы ресурсов. Раскладку путей знает ОДИН файл — `tools/paths.py`; менять пути нужно там, а не в отдельных упаковщиках. Адреса ВНЕШНИХ источников — так же в одном: `tools/fetch_orig.py` |
|
||||
| `docs/` | планы, доски, справочники; `docs/PoP/` — форматы ресурсов оригинала |
|
||||
| `tests/host/` | модульные тесты движка под ucsim_z80 |
|
||||
| `build/` | выход: `sprpop.exe`, каталоги ресурсов, `hdd/`, промежуточные `atl/` |
|
||||
|
||||
Звуковые ЭФФЕКТЫ по умолчанию берутся из SDLPoP (`SND_SRC=sdlpop`) — сборка
|
||||
обязана работать без оригинального дистрибутива DOS. У кого лежит
|
||||
`assets/orig/MSDOS/`, включает его набор явно (`make SND_SRC=msdos`): там
|
||||
оцифровка полнее — в SDLPoP пуст звук 48 `spiked` (насаживание на пики).
|
||||
Разбор — `docs/sound_plan.md`.
|
||||
|
||||
Музыка собирается из одного из четырёх наборов записей
|
||||
(`assets/orig/PoP1_DOS_music/`): `flac` по умолчанию, плюс `mp3`, `ogg` и
|
||||
`mt32` (исполнение Roland MT-32 — звучит иначе, длина треков другая). Набор
|
||||
@@ -153,6 +162,8 @@ Makefile склеивает архивы прямо в `assets/packed/<КАТА
|
||||
| `pop_kid.c/.h` | Анимация/движение: интерпретатор seqtbl `play_seq` + frame_table (`seg006`), окна `Char` (loadkid/loadshad), атласы Кида. |
|
||||
| `pop_cdraw.c/.h` | ОТРИСОВКА персонажей — одна на всех Char (порт `add_kid_to_objtable`/`add_guard_to_objtable`): спрайт, clip_char, брызги, клинок, heal; полоса HP и палитры соперника. Там же ПРОПУСК неизменившегося кадра (`pop_char_skip_mask`). |
|
||||
| `pop_ctrl.c/.h` | Управление: диспетчер `control()` (`seg005`) + ввод `read_user_control` (`seg006`) поверх `<kbd_raw.h>`. |
|
||||
| `pop_sfx.c` + `pop_sfx_cold.c` | Звук: насос CBL в резиденте + холодная загрузка набора. Раскладка эффектов НЕ компилируется в EXE — читается с диска (`SND/snd.idx`, формат `PSI1`); см. `docs/sound_plan.md` §10. |
|
||||
| `pop_snd_tbl.h` + `pop_snd_data.c` | Тип записи набора и инварианты (рукописный заголовок) + резидентные `pop_snd_tbl`/`pop_snd_page`/`pop_snd_pages`. Размер записи 5 байт — часть дискового контракта, проверяется статически. |
|
||||
| `pop_map.c/.h` | Коллизия с картой + физика падения/приземления/стены + loose-полы (`seg005/006/007`). |
|
||||
|
||||
## Банки: две мины, которых компилятор не видит
|
||||
|
||||
Reference in New Issue
Block a user