applications/PoP: порт Prince of Persia — PoC (roomtest) + пайплайн
Порт PoP на Sprinter. Текущий PoC — applications/PoP/roomtest/: комната 1 (фон-композиция тайлов) + Kid с управлением на raw-клавиатуре и коллизией с картой. - roomtest — pop_bg (фон), pop_kid (спрайты Kid, column-major флип, seqtbl-анимация), pop_ctrl (порт control() PoP на held-state kbd_raw), pop_map (коллизия seg004/005: бег/стоп у стены, падение/приземление, отскок seq_47, вертикальный прыжок K4.1). MEMORY=small (DATA сразу за CODE, ~23КБ кода не лезет в huge). - toolchain (PoP) — pop_pack_kid/pop_pack_bg/render_room/extract — распаковка res-графики MSDOS в атласы + композиция комнат. - toolchain/ (корень) — make_hdd.sh (быстрый HDD-тест вместо FDD), png_strip.py / room_compose.py (ассет-пайплайн). - docs — PORT_PLAN, KID_PLAN, форматы ресурсов (Apple II / MSDOS / DAT). - bgtest/coltest/poc — ранние PoC (фон, коллизия, первый прототип). .gitignore: build-артефакты applications/*/*/*; исключены внешние референс-репозитории (SDLPoP/mininim/PR/Apple-II — свои git-клоны) и оригинальные game-данные MSDOS/ (копирайт, только для реверса форматов). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
build_tile_atlases.py — собирает tileNN.atl для всех 32 типов тайлов
|
||||
из applications/PoP/poc/res/tiles/{TYPE:X}-{N}.png (см.
|
||||
gen_tile_placeholders.py). Для каждого типа находит ВСЕ файлы
|
||||
{TYPE:X}-*.png (сколько бы вариантов ни было — 1 заглушка или много
|
||||
настоящих), сортирует по номеру варианта и собирает через
|
||||
png_strip.py + mkatlas.py. Типы без ни одного файла — пропускаются
|
||||
(room_draw их и так не рисует).
|
||||
|
||||
Запускать заново каждый раз, когда добавили/заменили картинки в
|
||||
res/tiles/ — атласы просто пересоберутся.
|
||||
"""
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
PROJ_ROOT = HERE.parents[3] # .../C-Compiler
|
||||
TILES_DIR = HERE.parent / "res" / "tiles"
|
||||
OUT_DIR = HERE.parent / "res" / "tiles"
|
||||
PNG_STRIP = PROJ_ROOT / "toolchain" / "png_strip.py"
|
||||
MKATLAS = PROJ_ROOT / "toolchain" / "mkatlas.py"
|
||||
|
||||
ROOM_TILE_W = 32
|
||||
ROOM_ROW_H = 64 # см. room.c room_row_h — держать в синхроне
|
||||
|
||||
PATTERN = re.compile(r"^([0-9A-Fa-f]+)-(\d+)\.png$")
|
||||
|
||||
|
||||
def run(cmd):
|
||||
print("+", " ".join(str(c) for c in cmd))
|
||||
subprocess.run([str(c) for c in cmd], check=True)
|
||||
|
||||
|
||||
def main():
|
||||
by_type = {}
|
||||
for f in TILES_DIR.glob("*.png"):
|
||||
m = PATTERN.match(f.name)
|
||||
if not m:
|
||||
continue
|
||||
t = int(m.group(1), 16)
|
||||
n = int(m.group(2))
|
||||
by_type.setdefault(t, {})[n] = f
|
||||
|
||||
if not by_type:
|
||||
sys.exit(f"build_tile_atlases: нет файлов TYPE-N.png в {TILES_DIR}")
|
||||
|
||||
built = 0
|
||||
for t in sorted(by_type):
|
||||
variants = by_type[t]
|
||||
files = [variants[n] for n in sorted(variants)]
|
||||
strip_raw = OUT_DIR / f"tile{t:02x}.raw"
|
||||
strip_pal = OUT_DIR / f"tile{t:02x}.pal"
|
||||
atl = OUT_DIR / f"tile{t:02x}.atl"
|
||||
|
||||
run([sys.executable, PNG_STRIP, strip_raw, strip_pal,
|
||||
*files, "--canvas", f"{ROOM_TILE_W}x{ROOM_ROW_H}",
|
||||
"--anchor", "top-left"])
|
||||
run([sys.executable, MKATLAS, atl,
|
||||
f"{strip_raw}:{ROOM_TILE_W}x{ROOM_ROW_H}:{len(files)}x1"])
|
||||
built += 1
|
||||
|
||||
print(f"build_tile_atlases: собрано {built} атласов "
|
||||
f"(типы: {', '.join('%X' % t for t in sorted(by_type))})")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user