Files
Sprinter-SDCC/testkit/host-tests.mk
T
snark13 6673279cef PoP: скелет уровня 3, цвета стражей, окклюзия соперника; кэш соседних комнат
Скелет (L3-SKEL, ассеты + механика):
- pop_pack_guard.py получил параметр набора (GUARD/SKEL): атлас скелета
  poc/res/skel/g0..g3.atl (28 кадров), палитра — из его res750.pal (на ур. 3
  curr_guard_color = 0, оригинал палитру не подменяет);
- pop_guard_load выбирает набор по tbl_guard_type и перезагружается ПРИ СМЕНЕ
  УРОВНЯ (load_lev_spr, seg000:1092) — без этого скелет рисовался атласом
  стража и был невидим;
- load_frame: charid_4_skeleton идёт по таблице стража (seg006:529), тень —
  только в кадрах 150..189.  Пока ветка была одна (charid_2_guard), скелет
  получал image из таблицы Кида (180 при 28 спрайтах) и не рисовался;
- check_skel (seg002:1042), ветка charid_4 в enter_guard, возрождение в
  комнате 3 при падении (seg002:252), autocontrol_skeleton;
- leveldoor_open (seg007:456) — новый флаг, сбрасывается стартом уровня.

Цвета стражей (BUG-GUARD-COLOR-1, закрыт):
- все 7 палитр res10.bin -> pop_guard_pal.h, заливка 16 слотов по
  guards_color комнаты перед отрисовкой (set_chtab_palette, seg003:257).
  Проверено в MAME: ур. 2 комн. 11 = цвет 1, комн. 7 = цвет 3, полоса HP
  меняется вместе со стражем.  Грабля: gfx_pal_load отдаёт указатель в BIOS,
  а тот читает только #4000-#BFFF — таблицу из банка копируем в стек.

Кэш соседних комнат (BUG-SWORD-GHOST-1, закрыт):
- pop_map кэширует fg соседей слева/справа ЦЕЛИКОМ и резолвит col -10..19.
  Было -2..11, дальше мнимая стена: луч видимости упирался в неё (страж
  после follow_guard в col 12), Кид прятал меч посреди боя и не мог достать
  обратно.  +48 байт W2.

Окклюзия соперника:
- pop_fore_over_char получил проход other_overlay_tile (порядок midtable,
  seg008:1B06) и расширение перебора объединённым прямоугольником
  «персонаж + клинок + брызги» — падающий скелет больше не рисуется поверх
  кладки и верхней грани пола;
- клип полем 192 строк (reset_obj_clip, seg006:0507) для спрайта, клинка
  (общий pop_sword_draw) и брызг — спрайт не залезает на полосу HP;
- ROOMNAV после смерти Кида делает честный pop_start_level: телепорт
  «оживлял» мёртвого мимо старта уровня, оставляя живого скелета рядом с
  вернувшейся кучей костей.

Ассеты чомпера (под L3-CHOMP): весь набор кадров в атласе явным списком
(101-105 низ, 111-113 верх, 106-110 фронт, 114-123 кровь mono-силуэтом) —
render_room анимированные тайлы пропускает, и в атласе не было ни одного.
Число EMM-страниц не изменилось.

Тесты: tests-host все 5 наборов зелёные, t_char вырос до 65 проверок
(резолв колонок за краем комнаты, возрождение скелета); в testkit добавлен
гард «код наехал на данные» (DATA_LOC).

Доски: TASKS.md разнесён на TASKS_OPEN/TASKS_CLOSED, закрытые баги с
разбором корней — в bug_closed.md; заведены DRAW-CHAR (отрисовка одна на всех
Char, как физика после GUARD-PHYS) и L3-COLOR (зелёная кладка уровня 3:
level_var_palettes = ресурс 20, есть в MSDOS/PRINCE.DAT).

В roomtest.c временно оставлен автостоп на падении соперника (отладка
падений скелета) — помечен ВРЕМЕННО.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 22:11:03 +03:00

108 lines
5.8 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.
# ----------------------------------------------------------------------
# host-tests.mk — общие правила модульных тестов, исполняемых под ucsim_z80.
#
# Сама обвязка (crt0_ucsim.s, tcheck.*, run_ucsim.py) лежит в testkit/ и ни
# к какому подпроекту не привязана: тестировать так можно и libc, и логику
# приложений — всё, что на plain C и не трогает железо.
#
# Подключается из каталога с наборами t_*.c:
#
# TESTKIT := $(abspath ../../../../testkit)
# ENGINE_DIR := $(abspath ..) # где лежат модули под тестом
# OBJS_geom := build/eng_pop_geom.rel # что доложить в этот набор
# include $(TESTKIT)/host-tests.mk
#
# Набор t_<имя>.c подхватывается wildcard'ом, регистрировать не надо.
# ----------------------------------------------------------------------
ifndef TESTKIT
$(error перед include надо задать TESTKIT — путь к каталогу testkit/)
endif
PROJ_ROOT ?= $(abspath $(TESTKIT)/..)
SDCC := $(PROJ_ROOT)/third_party/sdcc/bin/sdcc
SDASZ80 := $(PROJ_ROOT)/third_party/sdcc/bin/sdasz80
UCSIM := $(PROJ_ROOT)/third_party/sdcc/bin/ucsim_z80
RUNNER := $(TESTKIT)/run_ucsim.py
BUILD := build
# --code-loc: стартовый код занимает 13 байт по 0x0000, код с 0x0200.
# --data-loc 0x8000: данные заведомо выше кода.
#
# CODE_LOC переопределяется набором, если ему нужна нижняя память под
# данные: так делает t_phys в roomtest — он кладёт по 0x100 страницу
# таблиц анимации, которую на устройстве туда приводит маппинг W0.
# EXTRA_INC — заголовки, которых нет ни в testkit, ни в ENGINE_DIR
# (например libc/libbgi, когда модуль под тестом их включает).
# DATA_LOC — та же история сверху: набор, чей код перерос 0x8000, обязан
# отодвинуть данные, иначе линкер молча кладёт хвост кода (_HOME, деления
# из libsdcc) ПОВЕРХ _DATA — тест ведёт себя как «зациклился», хотя логика
# ни при чём. Проверку наложения делает check-overlap ниже.
CODE_LOC ?= 0x0200
DATA_LOC ?= 0x8000
EXTRA_INC ?=
CFLAGS := -mz80 --no-std-crt0 --std-c99 --opt-code-size -I$(TESTKIT) \
$(if $(ENGINE_DIR),-I$(ENGINE_DIR)) $(EXTRA_INC) $(EXTRA_CFLAGS)
LDFLAGS := -mz80 --no-std-crt0 --code-loc $(CODE_LOC) --data-loc $(DATA_LOC)
SUITES := $(patsubst t_%.c,%,$(notdir $(wildcard t_*.c)))
COMMON := $(BUILD)/crt0_ucsim.rel $(BUILD)/tcheck.rel
.PHONY: all clean $(addprefix t_,$(SUITES))
# Иначе make считает .rel/.ihx промежуточными и удаляет их после прогона —
# следующий `make` пересобирал бы всё заново.
.SECONDARY:
# OBJS_<набор> подставляется в правило по имени цели — нужен второй проход
# раскрытия, иначе модуль не попадёт в зависимости и не соберётся.
.SECONDEXPANSION:
# Ярлык каталога в отчёте — с родителем: «tests-host» само по себе
# неоднозначно, когда таких каталогов несколько.
LABEL := $(notdir $(patsubst %/,%,$(dir $(CURDIR))))/$(notdir $(CURDIR))
all: $(addprefix run-,$(SUITES))
@echo "$(LABEL): все наборы прошли ($(words $(SUITES)))"
# Прогон одного набора. Раннер сам разбирает tc_result и возвращает код.
# Наложение кода на данные линкер sdld НЕ считает ошибкой: код просто
# ложится поверх _DATA, и тест виснет/врёт без единого предупреждения.
# Ловим сами — конец _CODE (CODE_LOC + l__CODE) против DATA_LOC.
define CHECK_OVERLAP
@python3 -c "import sys; \
d={p[1]:int(p[2],16) for p in (l.split() for l in open('$(1)')) if len(p)==3 and p[0]=='DEF'}; \
end=$(CODE_LOC)+d.get('l__CODE',0); \
sys.exit(0) if end<=$(DATA_LOC) else sys.exit('%s: КОД НАЕХАЛ НА ДАННЫЕ — _CODE кончается на 0x%04X, а DATA_LOC = 0x%04X.\n Поднять DATA_LOC в Makefile набора (стек в crt0_ucsim — 0xFEF0).' % ('$(1)', end, $(DATA_LOC)))"
endef
run-%: $(BUILD)/%.ihx
$(call CHECK_OVERLAP,$(BUILD)/$*.noi)
@python3 $(RUNNER) $(UCSIM) $(BUILD)/$*.ihx $(BUILD)/$*.noi
# Удобный псевдоним: `make t_geom` вместо `make run-geom`.
t_%: run-% ;
$(BUILD)/%.ihx: $(BUILD)/%.rel $(COMMON) $$(OBJS_$$*)
@$(SDCC) $(LDFLAGS) -o $@ $(COMMON) $(BUILD)/$*.rel $(OBJS_$*)
$(BUILD)/%.rel: t_%.c $(TESTKIT)/tcheck.h | $(BUILD)
@$(SDCC) $(CFLAGS) -c -o $@ $<
# Модули под тестом собираются ТЕМ ЖЕ компилятором и с той же семантикой,
# что и продукт, — включая модули с inline-asm, которые хостовой сборкой
# не проверить в принципе.
$(BUILD)/eng_%.rel: $(ENGINE_DIR)/%.c | $(BUILD)
@$(SDCC) $(CFLAGS) -c -o $@ $<
$(BUILD)/tcheck.rel: $(TESTKIT)/tcheck.c $(TESTKIT)/tcheck.h | $(BUILD)
@$(SDCC) $(CFLAGS) -c -o $@ $<
$(BUILD)/crt0_ucsim.rel: $(TESTKIT)/crt0_ucsim.s | $(BUILD)
@$(SDASZ80) -plosgff $@ $<
$(BUILD):
@mkdir -p $(BUILD)
clean:
@rm -rf $(BUILD)