Files
Sprinter-SDCC/applications/PoP/roomtest/Makefile
T
snark13 ba3aca07bf Архивы ресурсов PBA1: звук одним файлом, музыка потоком; ALLOCS 6000
ЗАМЕР, из которого всё выросло (MAME, 2026-08-25): `open` стоит 51,4 мс,
а чтение 16 КБ из уже открытого файла — 32,6 мс.  То есть 61 % времени
загрузки уходит на ОТКРЫТИЕ, а не на данные, и чистая скорость чтения —
491 КБ/с, а не 260.  На диске игры 343 файла; одна только стартовая пачка
(kid+shadow+bg+sound+guard, ~142 файла) — это 7,3 секунды чистого open.

* toolchain/pop_pack_arc.py + pop_arc.c/h (банк 8) — формат PBA1:
  заголовок 512 Б, магия, count, записи по 4 байта (offset в СЕКТОРАХ —
  архив бывает больше 64 КБ; size в байтах — ресурс всегда <= 16 КБ,
  он обязан лезть в EMM-страницу).  Таблицу держит вызывающий на своём
  стеке: в W2 её класть нельзя, а стека в точке загрузки израсходовано
  75 байт из 1279 (замер там же).
* libc: bank_read_page — чтение из УЖЕ ОТКРЫТОГО файла в EMM-страницу.
  bank_load_file переписана через неё, поэтому дублирования работы с W3
  не осталось и резидент почти не вырос.
* Набор эффектов: 10 файлов -> SND\snd.arc, один open вместо десяти.
* Музыка: трек лежит ОДНИМ файлом и читается порциями по странице —
  нарезка на куски больше не нужна.  Этот же путь понадобится финалу
  `won` (1,2 МБ), который в память целиком не влезает.
* Менеджер звука приведён к оригиналу: играющая музыка участвует в
  таблицах приоритета наравне с эффектами (seg000:1672 + data.h:433).
  Почти вся музыка НЕперебиваема, поэтому поверх неё эффект не стартует —
  ровно как в SDLPoP; раньше эффект её перебивал.
* ALLOCS 3000 -> 6000 (решение пользователя): сборка +20 с, резидент
  -161 байт.  Куча 87 -> 248 Б.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 17:13:25 +03:00

408 lines
26 KiB
Makefile
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.
# roomtest — проверка порта статического фона PoP (Шаг 3): реальная
# композиция слоёв (pop_bg.c) для комнаты 1. --memory huge --gfx 256.
PROJ_ROOT := $(abspath $(CURDIR)/../../..)
EXAMPLE := roomtest
# small: W1+W2 как единое 32КБ-пространство, DATA сразу за CODE (иначе
# CODE ~23КБ переполняет W1 и лезет в фиксированный DATA@0x8000 в huge).
MEMORY ?= huge # small-раскладка + банки кода в W3 (стражи)
# Резидента --w3 БОЛЬШЕ НЕТ: отрисовка уехала в БАНК 2 (pop_bg + pop_cdraw
# в одной странице — вызовы между ними прямые, если функция не помечена
# __banked). Так снято главное ограничение резидента: из банка его было
# не достать ни прямо, ни транзитивно, а банк→банк работает (трамплин
# сохраняет страницу окна на СТЕКЕ, проверено вложенной цепочкой
# банк1→банк2→банк1 в MAME 2026-07-30). Теперь в банки можно уводить и
# логику, которая рисует. См. docs/layout_plan_v2.md §2, memory
# sdcc_banked_call_rules.
# Банк 5 = pop_ctrl.c (MEM-BANK5). CODE и DATA делят одно 32-КБ
# пространство W1+W2, поэтому килобайт кода, уехавший в банк, — это
# килобайт, доступный данным. Кандидат выбран не по размеру, а по частоте
# вызова: диспетчер управления дёргается один раз за кадр на персонажа и
# горячих банк→банк переходов не создаёт (в отличие от pop_level, чей
# pop_level_tile зовётся из банка 2 на КАЖДЫЙ тайл). Шина control_*
# переехала в pop_state.c — см. там.
# --max-allocs-per-node: во сколько вариантов размещения регистров SDCC
# упирается на узел. У sprinter-cc дефолт 100000 (агрессивно, как fast-сборки
# библиотек) — на roomtest это МИНУТЫ на банк, потому что модули крупные.
# Дефолт SDCC — 3000, и для разработки его достаточно: разница в размере
# единицы процента, а сборка кратно быстрее. Замер (2026-08-05) — в шапке
# TASKS_CLOSED.md, запись BUILD-FAST.
#
# make — быстрая сборка (ALLOCS=3000)
# make ALLOCS=100000 — как раньше: минимальный код, для замеров размера
# и для «релизного» образа
#
# ВАЖНО: любое сравнение занятости банков имеет смысл только при ОДНОМ и том
# же ALLOCS — иначе сравниваются не правки, а уровни оптимизации.
# 6000, а не 3000 (решение пользователя 2026-08-25): сборка дольше секунд на
# двадцать, зато SDCC размещает регистры плотнее и резидент W1 худеет
# примерно на 150 байт — а это ровно те байты, которых не хватает куче.
ALLOCS ?= 6000
# Build info не хранится вручную в C: ID и дата извлекаются Make из текущего
# commit. Переопределения удобны для воспроизводимой release-сборки.
BUILD_ID ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo dev)
BUILD_DATE ?= $(shell git log -1 --format=%cs 2>/dev/null || echo unknown)
BUILD_FLAGS := -DPOP_BUILD_ID=\"$(BUILD_ID)\" -DPOP_BUILD_DATE=\"$(BUILD_DATE)\"
# Единственный список банковых исходников: из него строятся И ключи
# sprinter-cc, И зависимости roomtest.exe. Раньше эти списки жили отдельно,
# поэтому добавленные pop_shadow.c/pop_sfx_cold.c компилировались, но make не
# замечал их последующие изменения и оставлял устаревший exe.
BANK1_SRCS := guards.c
BANK2_SRCS := pop_bg.c
BANK3_SRCS := pop_map.c
BANK4_SRCS := pop_cdraw.c pop_kdraw.c
BANK5_SRCS := pop_ctrl.c pop_tile_cold.c
BANK6_SRCS := pop_trob.c
BANK7_SRCS := pop_room.c pop_redraw.c
BANK8_SRCS := roomtest_cold.c pop_arc.c pop_level_cold.c pop_kboot.c pop_guard_cold.c \
pop_shadow.c pop_sfx_cold.c pop_qsave.c pop_qsave_coldio.c \
pop_level_qsave.c
# Банк 9 — оболочка: menu/settings/config/font, автомат, global timer,
# title, attract-demo и таблица рекордов. Здесь остаются небольшие редкие
# верхнеуровневые точки входа, но не рендеры крупных заставок.
BANK9_SRCS := pop_menu.c pop_status.c pop_music.c pop_config.c pop_app.c pop_timer.c pop_ui.c pop_title.c pop_demo.c \
pop_flow.c pop_hof.c
# Банк 10 — единый владелец экранных палитр/fade. Он намеренно отделён от UI:
# его будут вызывать и игровой lifecycle, и все cutscene-ветки.
BANK10_SRCS := pop_pal.c
# Банк 11 — тяжёлая кинематика заставок: интерпретатор сценария и renderer
# story/PV. Так анимации не вытесняют menu/config из банка оболочки.
BANK11_SRCS := pop_cutscene.c pop_intro.c
BANKED_SRCS := $(BANK1_SRCS) $(BANK2_SRCS) $(BANK3_SRCS) $(BANK4_SRCS) \
$(BANK5_SRCS) $(BANK6_SRCS) $(BANK7_SRCS) $(BANK8_SRCS) \
$(BANK9_SRCS) $(BANK10_SRCS) $(BANK11_SRCS)
BANK_FLAGS := $(foreach f,$(BANK1_SRCS),--bank 1=$(f)) \
$(foreach f,$(BANK2_SRCS),--bank 2=$(f)) \
$(foreach f,$(BANK3_SRCS),--bank 3=$(f)) \
$(foreach f,$(BANK4_SRCS),--bank 4=$(f)) \
$(foreach f,$(BANK5_SRCS),--bank 5=$(f)) \
$(foreach f,$(BANK6_SRCS),--bank 6=$(f)) \
$(foreach f,$(BANK7_SRCS),--bank 7=$(f)) \
$(foreach f,$(BANK8_SRCS),--bank 8=$(f)) \
$(foreach f,$(BANK9_SRCS),--bank 9=$(f)) \
$(foreach f,$(BANK10_SRCS),--bank 10=$(f)) \
$(foreach f,$(BANK11_SRCS),--bank 11=$(f))
EXTRA_FLAGS ?= --gfx 256 -I $(CURDIR)/../poc/res/bg --max-allocs $(ALLOCS) \
$(BANK_FLAGS) $(PROF_FLAGS) $(BUILD_FLAGS)
# Профилирование полосами бордюра (см. PROF() в roomtest.c) — ВКЛЮЧЕНО по
# умолчанию, пока идёт работа с производительностью; make PROF=0 выключает.
# Каждая фаза кадра красит бордюр в свой цвет, высота полосы на скриншоте
# MAME = время фазы в растровых строках.
PROF ?= 1
PROF_FLAGS := -DPROF_BORDER=$(PROF)
# Стартовый уровень (отладка): make LEVEL=9 — начать сразу с девятого.
# Дефолт держим на отлаживаемом сейчас уровне; для «настоящей» игры — LEVEL=1.
# Константа объявлена в pop_tune.h (её видят обе половины главного цикла).
LEVEL ?= 1
PROF_FLAGS += -DFIRST_LEVEL=$(LEVEL)
# Стартовая КОМНАТА и позиция Кида в ней (отладка): make ROOM=15 POS=2 —
# начать прямо в целевой комнате оптимизации, минуя проход уровня. POS —
# тайл 0..29, то есть row*10+col. Дефолт — сцена 11/15 (Кид в 0,2), по
# которой сняты замеры в docs/perf_l11_room15.md. make ROOM= (пусто)
# возвращает штатный старт из данных уровня.
ROOM ?=
POS ?= 2
ifneq ($(strip $(ROOM)),)
PROF_FLAGS += -DDBG_START_ROOM=$(ROOM) -DDBG_START_POS=$(POS)
endif
EXTRA_SRCS := pop_vflip.c pop_pace.c pop_sfx.c pop_state.c pop_draw.c pop_tile.c \
pop_kid.c pop_level.c pop_geom.c pop_guard.c pop_qsave_io.c
BG_DIR := $(CURDIR)/../poc/res/bg
KID_DIR := $(CURDIR)/../poc/res/kid
LVL_DIR := $(CURDIR)/../SDLPoP/data/LEVELS
# res2000 — attract-demo; res2001..res2014 — штатная игра. res2015/copy
# protection намеренно не пакуется и не существует в маршруте загрузчика.
LVL_NUMS := 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
LVL_DATA := $(foreach n,$(LVL_NUMS),$(LVL_DIR)/res20$(n).bin)
# ДВА тайлсета: pop_* — подземелье (уровни 1-3, 7-9, 12, 13),
# pal_* — дворец (4-6, 10, 11, 14). Раскладка id у них общая, различаются
# файлы и палитра тайлсета (*tile.pal, 32 записи). chtab_1 (pop_pot.atl:
# пламя, меч-предмет, зелья) от набора не зависит — один на оба.
BG_SETS := pop pal
BG_PAGES := 0 1 2 3 4 5 6 7 8 9
BG_DATA := $(foreach s,$(BG_SETS),\
$(foreach n,$(BG_PAGES),$(BG_DIR)/$(s)_env$(n).atl) \
$(BG_DIR)/$(s)_wall.atl $(BG_DIR)/$(s)_fore.atl \
$(BG_DIR)/$(s)_tile.pal) \
$(BG_DIR)/pop_pot.atl
# ВСЕ 28 страниц Kid — иначе кадры торможения/разворота/приседа (image>23)
# не рисуются (отрисовка пропускает незагруженную страницу). Палитра —
# ЕДИНАЯ игровая (env+wall+kid).
KID_PAGES := $(foreach n,0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27,$(KID_DIR)/kid$(n).atl)
# Зеркальный ПО ВЕРТИКАЛИ набор (зелье инверсии, уровень 9): те же спрайты с
# развёрнутыми колонками. Готовит упаковщик, а не рантайм — разворот
# страницы стоит 0.59 с против 0.045 с на её чтение с диска (замер MAME
# 2026-08-12, протокол в pop_vflip.c).
KID_VPAGES := $(foreach n,0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27,$(KID_DIR)/kid$(n)_v.atl)
KID_DATA := $(KID_PAGES) $(KID_VPAGES) $(KID_DIR)/kid.pal \
$(KID_DIR)/sword.atl $(KID_DIR)/sword_v.atl
# Таблицы анимации (кадры+seqtbl) — отдельный бинарь в EMM-странице, его
# делает pop_extract_kid_data.py (не упаковщик спрайтов) — своё правило ниже.
KID_BIN := $(KID_DIR)/kid_data.bin
GUARD_DIR := $(CURDIR)/../poc/res/guard
GUARD_DATA := $(GUARD_DIR)/g0.atl $(GUARD_DIR)/g1.atl $(GUARD_DIR)/g2.atl \
$(GUARD_DIR)/g3.atl $(GUARD_DIR)/g4.atl \
$(GUARD_DIR)/g0_v.atl $(GUARD_DIR)/g1_v.atl $(GUARD_DIR)/g2_v.atl \
$(GUARD_DIR)/g3_v.atl $(GUARD_DIR)/g4_v.atl
# Скелет — ОТДЕЛЬНЫЙ набор спрайтов (SKEL.DAT в оригинале): его грузит
# уровень 3 (tbl_guard_type == 2), кадров меньше (28 против 34).
SKEL_DIR := $(CURDIR)/../poc/res/skel
# Зеркального набора у скелета НЕТ: зелье инверсии — уровень 9, там обычный
# страж (tbl_guard_type[9] = 0). См. pop_pack_guard.py.
SKEL_DATA := $(SKEL_DIR)/g0.atl $(SKEL_DIR)/g1.atl $(SKEL_DIR)/g2.atl \
$(SKEL_DIR)/g3.atl
# Джафар — тоже отдельный набор (VIZIER.DAT): его грузит уровень 13
# (tbl_guard_type == 3). Кадров столько же, сколько у стража (34), но
# палитра своя, из файла набора: curr_guard_color для не-стражей = 0.
# Зеркального набора нет по той же причине, что у скелета.
VIZIER_DIR := $(CURDIR)/../poc/res/vizier
VIZIER_DATA := $(VIZIER_DIR)/g0.atl $(VIZIER_DIR)/g1.atl $(VIZIER_DIR)/g2.atl \
$(VIZIER_DIR)/g3.atl $(VIZIER_DIR)/g4.atl
# ТЕНЬ — свой набор, запечённый упаковщиком (наложение спрайта на себя со
# сдвигом; наш блит так не умеет, см. ../docs/shadow_atlas_plan.md). Две
# половины в одном наборе: sk* — кадры вне боя (спрайты Кида), sf* — кадры
# 150..189 (SHADOW.DAT, это тоже графика Кида, а не стража).
SHADOW_DIR := $(CURDIR)/../poc/res/shadow
SHADOW_DATA := $(foreach n,0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27,$(SHADOW_DIR)/sk$(n).atl) \
$(foreach n,0 1 2 3,$(SHADOW_DIR)/sf$(n).atl)
# ЗВУКОВЫЕ ЭФФЕКТЫ — оригинальная оцифровка, приведённая к частоте CBL
# (10 937,5 Гц, 8 бит моно). 8 страниц по 16 КБ; см. ../docs/sound_plan.md.
SND_DIR := $(CURDIR)/../poc/res/sound
# Число файлов задаёт упаковщик (POP_SND_PAGES в pop_sound_tbl.h): с
# 2026-08-25 звук не режется по границе страницы, поэтому страниц стало 10.
# Список ОБЯЗАН совпадать: недостающий файл — это молча пропавшие эффекты.
SND_PARTS := $(foreach n,0 1 2 3 4 5 6 7 8 9,$(SND_DIR)/s$(n).bin)
# На диск уходит ОДИН архив вместо десяти файлов: `open` дороже чтения
# (51,4 мс против 32,6 мс на 16 КБ, замер 2026-08-25), см. pop_arc.h.
SND_ARC := $(SND_DIR)/snd.arc
SND_DATA := $(SND_ARC)
# МУЗЫКА: записи DOS-версии, приведённые к формату CBL и порезанные на
# страницы EMM (toolchain/pop_pack_music.py). Пока в игре звучит один
# трек — story_1_absence на первом экране intro; список расширяется
# добавлением номеров в MUS_IDS, имена кусков задаёт упаковщик.
MUS_DIR := $(CURDIR)/../poc/res/music
MUS_IDS := 55
MUS_DATA := $(foreach i,$(MUS_IDS),$(MUS_DIR)/m$(i).bin)
# UI: два исходных шрифта SDLPoP в одном EMM-атласе. Файл короче страницы:
# хвост использует menu для временного snapshot палитры (без расхода W2).
FONT_DIR := $(CURDIR)/../poc/res/font
FONT_ATL := $(FONT_DIR)/font.atl
FONT_DATA := $(FONT_ATL)
# TITLE: четыре готовые композиции `show_title()` до story/intro. Каждая
# режется на пять полос высотой <=49 px, так что runtime держит ровно одну
# EMM-страницу во время рисования, а не отдельный framebuffer.
TITLE_DIR := $(CURDIR)/../poc/res/title
TITLE_SCENES := 0 1 2 3
TITLE_PARTS := 0 1 2 3 4
TITLE_DATA := $(TITLE_DIR)/title.pal \
$(foreach s,$(TITLE_SCENES),$(foreach p,$(TITLE_PARTS),$(TITLE_DIR)/t$(s)_$(p).atl))
# PV/INTRO: story и fallback-стадии режутся на полосы. Для настоящего PV
# intro есть ещё чистый фон `b0_*` и шесть <=16K actor-атласов: они остаются
# в EMM на время сцены, а не перечитывают полный 320x200 кадр с HDD.
PV_DIR := $(CURDIR)/../poc/res/pv
PV_STORY := 0 1 2 3 4
PV_SCENES := 0 1 2 3 4 5 6 7
PV_PARTS := 0 1 2 3 4
PV_ANIM := $(foreach p,$(PV_PARTS),$(PV_DIR)/b0_$(p).atl) \
$(PV_DIR)/a0.atl $(PV_DIR)/a1.atl $(PV_DIR)/a2.atl \
$(PV_DIR)/j0.atl $(PV_DIR)/j1.atl \
$(PV_DIR)/j2.atl $(PV_DIR)/h0.atl $(PV_DIR)/t0.atl
PV_DATA := $(PV_DIR)/story.pal $(PV_DIR)/pv.pal \
$(foreach s,$(PV_STORY),$(foreach p,$(PV_PARTS),$(PV_DIR)/s$(s)_$(p).atl)) \
$(foreach s,$(PV_SCENES),$(foreach p,$(PV_PARTS),$(PV_DIR)/p$(s)_$(p).atl)) \
$(PV_ANIM)
EXTRA_DATA := $(BG_DATA) $(KID_DATA) $(KID_BIN) $(GUARD_DATA) $(SKEL_DATA) \
$(VIZIER_DATA) $(SHADOW_DATA) $(SND_DATA) $(MUS_DATA) $(FONT_DATA) $(TITLE_DATA) $(PV_DATA) $(LVL_DATA)
# Образ HDD для MAME: ресурсы раскладываются ПО КАТАЛОГАМ (8.3, как в DSS),
# чтобы корень диска не зарастал десятками .atl.
# BG\ — фон (env/wall/fore/pot)
# KID\ — персонаж (kid0..27, палитра, меч, таблицы анимации)
# GUARD\ — стражи (появятся здесь же)
# FONT\ — текстовый атлас pause/settings UI
# TITLE\ — нарезанные композиции оригинальной заставки
# PV\ — story и Princess/Jaffar intro, нарезанные полосами
# LEVELS\ — уровни
HDD_PACK_ARGS := $(EXAMPLE).exe \
$(foreach f,$(BG_DATA),BG:$(f)) \
$(foreach f,$(KID_DATA) $(KID_BIN),KID:$(f)) \
$(foreach f,$(GUARD_DATA),GUARD:$(f)) \
$(foreach f,$(SKEL_DATA),SKEL:$(f)) \
$(foreach f,$(VIZIER_DATA),VIZIER:$(f)) \
$(foreach f,$(SHADOW_DATA),SHADOW:$(f)) \
$(foreach f,$(SND_DATA),SND:$(f)) \
$(foreach f,$(MUS_DATA),MUS:$(f)) \
$(foreach f,$(FONT_DATA),FONT:$(f)) \
$(foreach f,$(TITLE_DATA),TITLE:$(f)) \
$(foreach f,$(PV_DATA),PV:$(f)) \
$(foreach f,$(LVL_DATA),LEVELS:$(f))
include $(PROJ_ROOT)/app.mk
TC := $(PROJ_ROOT)/applications/PoP/toolchain
# Упаковщики создают сразу ГРУППУ файлов. Обычное multi-output правило
# заставляло GNU make при `-B` запускать один и тот же упаковщик отдельно для
# каждого .atl/.bin. Stamp-файл представляет один запуск генератора; все
# созданные им файлы зависят от этого stamp без собственных рецептов.
RESOURCE_STAMP_DIR := .resource-stamps
BG_STAMP := $(RESOURCE_STAMP_DIR)/bg
GUARD_STAMP := $(RESOURCE_STAMP_DIR)/guard
SKEL_STAMP := $(RESOURCE_STAMP_DIR)/skel
VIZIER_STAMP := $(RESOURCE_STAMP_DIR)/vizier
SHADOW_STAMP := $(RESOURCE_STAMP_DIR)/shadow
SOUND_STAMP := $(RESOURCE_STAMP_DIR)/sound
MUSIC_STAMP := $(RESOURCE_STAMP_DIR)/music
KID_STAMP := $(RESOURCE_STAMP_DIR)/kid
KID_BIN_STAMP := $(RESOURCE_STAMP_DIR)/kid-bin
FONT_STAMP := $(RESOURCE_STAMP_DIR)/font
TITLE_STAMP := $(RESOURCE_STAMP_DIR)/title
PV_STAMP := $(RESOURCE_STAMP_DIR)/pv
$(RESOURCE_STAMP_DIR):
mkdir -p $@
$(BG_STAMP): $(TC)/pop_pack_bg.py $(TC)/render_room.py | $(RESOURCE_STAMP_DIR)
cd $(TC) && python3 pop_pack_bg.py dungeon && python3 pop_pack_bg.py palace
touch $@
$(BG_DATA): $(BG_STAMP)
@test -f $@ || { $(MAKE) -B $(BG_STAMP); test -f $@; }
$(GUARD_STAMP): $(TC)/pop_pack_guard.py | $(RESOURCE_STAMP_DIR)
cd $(TC) && python3 pop_pack_guard.py
touch $@
$(GUARD_DATA): $(GUARD_STAMP)
@test -f $@ || { $(MAKE) -B $(GUARD_STAMP); test -f $@; }
$(SKEL_STAMP): $(TC)/pop_pack_guard.py | $(RESOURCE_STAMP_DIR)
cd $(TC) && python3 pop_pack_guard.py SKEL
touch $@
$(SKEL_DATA): $(SKEL_STAMP)
@test -f $@ || { $(MAKE) -B $(SKEL_STAMP); test -f $@; }
$(VIZIER_STAMP): $(TC)/pop_pack_guard.py | $(RESOURCE_STAMP_DIR)
cd $(TC) && python3 pop_pack_guard.py VIZIER
touch $@
$(VIZIER_DATA): $(VIZIER_STAMP)
@test -f $@ || { $(MAKE) -B $(VIZIER_STAMP); test -f $@; }
$(SHADOW_STAMP): $(TC)/pop_pack_shadow.py $(TC)/pop_pack_bg.py $(TC)/pop_pack_kid.py | $(RESOURCE_STAMP_DIR)
cd $(TC) && python3 pop_pack_shadow.py
touch $@
$(SHADOW_DATA) pop_shadow_atlas.h: $(SHADOW_STAMP)
@test -f $@ || { $(MAKE) -B $(SHADOW_STAMP); test -f $@; }
$(SOUND_STAMP): $(TC)/pop_pack_sound.py | $(RESOURCE_STAMP_DIR)
cd $(TC) && python3 pop_pack_sound.py
touch $@
$(SND_PARTS) pop_sound_tbl.h: $(SOUND_STAMP)
@test -f $@ || { $(MAKE) -B $(SOUND_STAMP); test -f $@; }
$(SND_ARC): $(SND_PARTS) $(TC)/pop_pack_arc.py
python3 $(TC)/pop_pack_arc.py $@ $(SND_PARTS)
$(MUSIC_STAMP): $(TC)/pop_pack_music.py | $(RESOURCE_STAMP_DIR)
cd $(TC) && python3 pop_pack_music.py $(MUS_IDS)
touch $@
$(MUS_DATA) pop_music_tbl.h: $(MUSIC_STAMP)
@test -f $@ || { $(MAKE) -B $(MUSIC_STAMP); test -f $@; }
$(KID_STAMP): $(TC)/pop_pack_kid.py $(TC)/pop_pack_bg.py | $(RESOURCE_STAMP_DIR)
cd $(TC) && python3 pop_pack_kid.py
touch $@
$(KID_DATA): $(KID_STAMP)
@test -f $@ || { $(MAKE) -B $(KID_STAMP); test -f $@; }
$(KID_BIN_STAMP): $(TC)/pop_extract_kid_data.py | $(RESOURCE_STAMP_DIR)
cd $(TC) && python3 pop_extract_kid_data.py
touch $@
kid_data.h $(KID_BIN): $(KID_BIN_STAMP)
@test -f $@ || { $(MAKE) -B $(KID_BIN_STAMP); test -f $@; }
$(FONT_STAMP): $(PROJ_ROOT)/toolchain/pop_extract_font.py \
$(CURDIR)/../SDLPoP/src/menu.c $(CURDIR)/../SDLPoP/src/seg009.c | $(RESOURCE_STAMP_DIR)
cd $(PROJ_ROOT) && python3 toolchain/pop_extract_font.py
touch $@
$(FONT_ATL) pop_font.h: $(FONT_STAMP)
@test -f $@ || { $(MAKE) -B $(FONT_STAMP); test -f $@; }
$(TITLE_STAMP): $(PROJ_ROOT)/toolchain/pop_pack_title.py \
$(CURDIR)/../SDLPoP/data/TITLE/res51.png \
$(CURDIR)/../SDLPoP/data/TITLE/res52.png \
$(CURDIR)/../SDLPoP/data/TITLE/res53.png \
$(CURDIR)/../SDLPoP/data/TITLE/res54.png \
$(CURDIR)/../SDLPoP/data/TITLE/res55.png | $(RESOURCE_STAMP_DIR)
cd $(PROJ_ROOT) && python3 toolchain/pop_pack_title.py
touch $@
$(TITLE_DATA): $(TITLE_STAMP)
@test -f $@ || { $(MAKE) -B $(TITLE_STAMP); test -f $@; }
$(PV_STAMP): $(PROJ_ROOT)/toolchain/pop_pack_intro.py \
$(CURDIR)/../SDLPoP/data/TITLE/res41.png \
$(CURDIR)/../SDLPoP/data/TITLE/res42.png \
$(CURDIR)/../SDLPoP/data/TITLE/res43.png \
$(CURDIR)/../SDLPoP/data/TITLE/res44.png \
$(CURDIR)/../SDLPoP/data/TITLE/res45.png \
$(CURDIR)/../SDLPoP/data/TITLE/res51.png \
$(CURDIR)/../SDLPoP/data/PV/res801.png \
$(CURDIR)/../SDLPoP/data/PV/res805.png \
$(CURDIR)/../SDLPoP/data/PV/res816.png \
$(CURDIR)/../SDLPoP/data/PV/res851.png \
$(CURDIR)/../SDLPoP/data/PV/res870.png \
$(CURDIR)/../SDLPoP/data/PV/res901.png \
$(CURDIR)/../SDLPoP/data/PV/res920.png \
$(CURDIR)/../SDLPoP/data/PV/res951.png \
$(CURDIR)/../SDLPoP/data/PV/res953.png \
$(CURDIR)/../SDLPoP/data/PV/res959.png \
$(CURDIR)/../SDLPoP/data/PV/res981.png \
$(foreach n,802 803 804 806 807 808 809 810 811 812 813 814 815 817,$(CURDIR)/../SDLPoP/data/PV/res$(n).png) \
$(foreach n,852 853 854 855 856 857 858 859 860 861 862 863 864,$(CURDIR)/../SDLPoP/data/PV/res$(n).png) \
$(CURDIR)/../SDLPoP/data/PV/res952.png \
$(foreach n,151 152 153 154 155 156 157 158 159,$(CURDIR)/../SDLPoP/data/PRINCE/res$(n).png) | $(RESOURCE_STAMP_DIR)
cd $(PROJ_ROOT) && python3 toolchain/pop_pack_intro.py
touch $@
$(PV_DATA): $(PV_STAMP)
@test -f $@ || { $(MAKE) -B $(PV_STAMP); test -f $@; }
# Явные цели позволяют собирать ресурсы без `make -B`, который по смыслу
# принудительно пересобирает также libc, libbgi и само приложение.
resources-bg: $(BG_DATA)
resources-kid: $(KID_DATA) $(KID_BIN)
resources-actors: $(GUARD_DATA) $(SKEL_DATA) $(VIZIER_DATA) $(SHADOW_DATA)
resources-sound: $(SND_DATA)
resources-music: $(MUS_DATA)
resources-font: $(FONT_DATA)
resources-title: $(TITLE_DATA)
resources-pv: $(PV_DATA)
resources-levels: $(LVL_DATA)
resources: resources-bg resources-kid resources-actors resources-sound resources-music resources-font resources-title resources-pv resources-levels
resources-rebuild:
$(MAKE) -B resources
# Принудительная перелинковка только roomtest, без глобального `-B` и без
# принудительной пересборки библиотек/ресурсов.
relink: resources
$(MAKE) -W Makefile $(EXAMPLE).exe
# HDD_PACK_ARGS содержит все эти файлы; make обязан подготовить их до запуска
# упаковщика и при чистой сборке, а не полагаться на старое содержимое дерева.
hdd: resources
# sprinter-cc собирает все модули одним вызовом и depfile пока не выдаёт.
# Банковые .c берём из того же списка, что формирует --bank; любой локальный
# заголовок также обязан перелинковать приложение. wildcard намеренно
# широкий: цена лишней полной сборки ниже риска получить stale-бинарник.
LOCAL_HEADERS := $(wildcard *.h)
$(EXAMPLE).exe: Makefile $(PROJ_ROOT)/app.mk $(BANKED_SRCS) $(LOCAL_HEADERS) \
$(BG_DATA) $(KID_DATA) $(KID_BIN) $(FONT_DATA) $(TITLE_DATA) $(PV_DATA) $(LVL_DATA)
clean-resources:
rm -rf $(RESOURCE_STAMP_DIR)
.PHONY: resources resources-rebuild resources-bg resources-kid resources-actors relink \
resources-sound resources-music resources-font resources-title resources-pv resources-levels clean-resources