# Build lib/bgi256.lib — Sprinter BGI graphics driver (320×256×256).
#
# libbgi/ — самостоятельная графическая библиотека, отделённая от libc.
# Две driver-библиотеки собираются из одной исходной базы:
#   bgi256.lib = common/*.rel + bgi256/*.rel   (эта — Фаза 1)
#   bgi16.lib  = common/*.rel + bgi16/*.rel    (Фаза 2; пока не собирается)
# common/ — mode-agnostic: .rel компилируется ОДИН раз и кладётся в ОБА
# архива (один исходник для функций, общих 256- и 16-цветной версиям).
# bgi256/ — mode-specific leaf'ы (реальные реализации, без обёрток).
#
# Каждый .c — отдельный .rel в архиве (1 публичная функция = 1 модуль);
# линкер тянет только нужные .rel → DCE на уровне файлов.  См. план
# «Рефакторинг GFX → BGI» и memory/bgi_two_lib_design.
#
#   make            build lib/bgi256.lib
#   make clean      remove build/ + lib/bgi256.lib
#
# (Фаза 2 добавит bgi16.lib = common + bgi16; common .rel переиспользуются.)

PROJ_ROOT := $(abspath $(CURDIR)/..)
SDCC_BIN  := $(PROJ_ROOT)/third_party/sdcc/bin
SDCC      := $(SDCC_BIN)/sdcc
SDAR      := $(SDCC_BIN)/sdar

# -I libbgi/include (gfx.h, graphics.h) + -I libc/include (palette.h,
# sprinter_exit.h — публичные заголовки libc; libbgi всегда линкуется с
# libc).  SDCC stdint и пр. — из собственного include-пути SDCC.
INC       := -I$(CURDIR)/include -I$(PROJ_ROOT)/libc/include
CC_FLAGS  := -mz80 --no-std-crt0 --std-c99 --opt-code-size $(INC)

BUILD     := $(CURDIR)/build

COMMON_C := $(wildcard $(CURDIR)/common/*.c)
BGI256_C := $(wildcard $(CURDIR)/bgi256/*.c)
# BGI16_C := $(wildcard $(CURDIR)/bgi16/*.c)   # Фаза 2

COMMON_RELS := $(patsubst $(CURDIR)/common/%.c,$(BUILD)/common/%.rel,$(COMMON_C))
BGI256_RELS := $(patsubst $(CURDIR)/bgi256/%.c,$(BUILD)/bgi256/%.rel,$(BGI256_C))
KNOWN_RELS  := $(COMMON_RELS) $(BGI256_RELS)

LIB_DIR  := $(PROJ_ROOT)/lib
LIB256   := $(LIB_DIR)/bgi256.lib

# Штамп списка модулей — иначе удаление/переименование исходника не
# триггерит перелинковку и stale .rel остаётся в архиве.  На exFAT
# грубая mtime — сравниваем по списку, не по времени.
MODLIST := $(BUILD)/.modules
ifneq ($(shell cat $(MODLIST) 2>/dev/null),$(KNOWN_RELS))
_ := $(shell mkdir -p $(BUILD); echo "$(KNOWN_RELS)" > $(MODLIST); rm -f $(LIB256))
endif

all: $(LIB256)

# Pattern rule для common/ и bgi256/ (один уровень под build/).
$(BUILD)/common/%.rel: $(CURDIR)/common/%.c
	@mkdir -p $(dir $@)
	$(SDCC) $(CC_FLAGS) -c -o $@ $<

$(BUILD)/bgi256/%.rel: $(CURDIR)/bgi256/%.c
	@mkdir -p $(dir $@)
	$(SDCC) $(CC_FLAGS) -c -o $@ $<

# Archive — sdar rcs = replace/create/symtab.  Перед упаковкой удаляем
# stale .rel (wildcard не знает об удалённых исходниках).
$(LIB256): $(COMMON_RELS) $(BGI256_RELS) $(MODLIST)
	@find $(BUILD) -name '*.rel' -print | sort > $(BUILD)/.have
	@printf '%s\n' $(KNOWN_RELS) | sort > $(BUILD)/.want
	@comm -23 $(BUILD)/.have $(BUILD)/.want | while read f; do \
	    echo "  stale: $$f (исходник удалён) — rm"; \
	    rm -f "$$f" "$${f%.rel}.asm" "$${f%.rel}.lst" "$${f%.rel}.sym"; \
	done
	rm -f $@
	$(SDAR) -rcs $@ $(COMMON_RELS) $(BGI256_RELS)
	@echo "  Built $@ with $(words $(COMMON_RELS)) common + $(words $(BGI256_RELS)) bgi256 modules."

clean:
	rm -rf $(BUILD) $(LIB256)

.PHONY: all clean
