Files
Sprinter-SDCC/applications/SprPoP/tools/paths.py
T
snark13 31b82661eb SprPoP: автономное приложение, выделенное из roomtest
Порт PoP переехал в applications/SprPoP — приложение, которое собирается
само: код, оригинальные данные, конверторы ресурсов и сборка внутри одной
папки.  Наружу знает единственный путь — корень тулчейна (SPRINTER_ROOT,
по умолчанию ../..).  applications/PoP/roomtest ЗАМОРОЖЕНА и остаётся
архивом закрытых задач, багов и исполненных планов.

Скопировано из applications/PoP/roomtest@4b74478.  Перенос проверен
побайтово: собранный sprpop.exe совпал с roomtest.exe того же коммита,
все 39 дисковых ресурсов и все 16 генерируемых заголовков — тоже, host-
тесты зелёные (15/15).

Раскладка:
  src/           рукописный C (roomtest.c -> sprpop.c)
  gen/           генерируемые заголовки, в репозитории
  assets/orig/   оригинальные данные игры, вне репозитория (копирайт)
  assets/packed/ то, что ложится на диск, в раскладке диска
  tools/         конверторы; все пути — в одном tools/paths.py
  build/         выход: exe, каталоги ресурсов, hdd/, промежуточные atl/

Сборка ресурсов: assets/packed и gen — версионируемые ВХОДЫ, а не то, что
пересчитывается каждым make.  Автоматика построена на ОТСУТСТВИИ файла, а
не на таймстемпах: git не хранит времена, и в свежем клоне сравнение по
времени превращалось бы в лотерею.  Недостающий ресурс или заголовок
чинится сам, рекурсивным вызовом в ветку генерации.

Музыка собирается из любого из четырёх наборов записей (make music-mp3,
music-mt32, ...); набор входит в имя stamp'а, поэтому смена набора сама
делает музыку устаревшей.  Длины реплик больше не захардкожены: упаковщик
печатает их в gen/pop_music_ticks.h, и шкала сцены выражена через них —
иначе mt32 (реплики на 6% длиннее) молча ломал катсцену.

Тулчейн: в app.mk два обратносовместимых крючка (SRC_DIR/BUILD_DIR),
HDD_IMG стал ?=; команда сборки roomtest не изменилась.  Корневой
make host-tests переключён на SprPoP.

Подгонка тайминга катсцены с принцессой (PV_MAGIC_LEAD): сцена
render-bound и идёт ~49 тиков/с вместо 60, из-за чего кода реплики
приходила раньше молнии.  Это обход, а не лечение; разбор с замерами —
docs/BUGS_OPEN.md, записи SND-PACE-DEAD, PV-RENDER-BOUND, MUS-LEFT-TEAR.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 12:12:28 +03:00

73 lines
3.6 KiB
Python
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.
"""paths.py — единственное место, где инструменты SprPoP знают раскладку
каталогов приложения. Все упаковщики берут пути отсюда, поэтому папку
SprPoP можно перенести куда угодно: важно лишь, что рядом с tools/ лежат
assets/, gen/ и build/.
Раскладка:
assets/orig/ ОРИГИНАЛЬНЫЕ данные (SDLPoP, MSDOS, записи музыки).
В репозиторий не идут — копирайт; откуда их взять,
написано в assets/orig/README.md.
build/atl/<set>/ промежуточный выхлоп упаковщиков: отдельные атласы,
из которых потом склеиваются архивы. Пересоздаётся,
в репозиторий не идёт.
assets/packed/ ровно то, что ложится на диск игры, уже в раскладке
каталогов диска (BG/, KID/, ...). В репозитории —
иначе из чистого клона без assets/orig/ ничего не
собрать.
gen/ генерируемые C-заголовки. Тоже в репозитории и по
той же причине: это такой же производный артефакт,
как .arc, и без него не скомпилировать src/.
"""
from pathlib import Path
TOOLS = Path(__file__).resolve().parent
APP = TOOLS.parent
# --- вход: оригинальные данные -------------------------------------------
ORIG = APP / "assets" / "orig"
SDLPOP = ORIG / "SDLPoP"
SDLPOP_DATA = SDLPOP / "data"
SDLPOP_SRC = SDLPOP / "src"
MSDOS = ORIG / "MSDOS"
MUSIC_ROOT = ORIG / "PoP1_DOS_music"
# Записи DOS-версии лежат в четырёх вариантах. Имена треков во всех наборах
# одинаковые, различаются каталог и расширение; ogg_MT-32 — та же музыка в
# исполнении Roland MT-32, а не другой кодек. Ключ = имя формата в Makefile.
MUSIC_FORMATS = {
"flac": ("flac", ".flac"),
"mp3": ("mp3", ".mp3"),
"ogg": ("ogg", ".ogg"),
"mt32": ("ogg_MT-32", ".ogg"),
}
def music_src(fmt="flac"):
"""(каталог, расширение) исходников музыки для формата."""
if fmt not in MUSIC_FORMATS:
raise SystemExit(
"неизвестный формат музыки %r; есть: %s"
% (fmt, ", ".join(sorted(MUSIC_FORMATS))))
sub, ext = MUSIC_FORMATS[fmt]
return MUSIC_ROOT / sub, ext
# --- выход ----------------------------------------------------------------
ATL = APP / "build" / "atl" # промежуточные атласы, по набору в папке
PACKED = APP / "assets" / "packed" # раскладка диска игры
GEN = APP / "gen" # генерируемые заголовки
def atl(name):
"""Каталог промежуточного выхлопа набора; создаётся при обращении."""
p = ATL / name
p.mkdir(parents=True, exist_ok=True)
return p
def packed(name):
"""Каталог диска игры (BG, KID, ...); создаётся при обращении."""
p = PACKED / name
p.mkdir(parents=True, exist_ok=True)
return p