Files
Sprinter-SDCC/applications/PoP/CLAUDE.md
T
snark13 5348feb5f4 Доски приведены в соответствие с кодом; bug_list/bug_closed → BUGS_OPEN/BUGS_CLOSED
Доска отставала от кода на три задачи — планировать по ней было нельзя.
Сверка проведена грепом по исходникам, а не по записям:

- L4-MIRROR ЗАКРЫТА: шаги 1-5 сделаны и проверены пользователем в MAME
  (зеркало в атласе, постановка тайла, отражение, прыжок сквозь зеркало с
  рождением тени, левый клип тени).  Протокол с разбором решений — в архиве;
- L3-CHOMP и L3-SKEL закрыты ещё 2026-08-08/07 (коммиты dc0bd47, 4d4323f,
  db4106a, 1461ed5), на доске значились как предстоящие;
- тайлсет palace (шаг 2 levels_plan) в коде есть целиком — pop_bg_load(type),
  pal_*.atl, дворцовый wall_pattern, решётки 25-29 и в tile_table, и в
  коллизии (tile_is_floor совпадает с seg006:0628);
- в GUARD-PHYS остаток пересобран по факту: check_chomped_guard сделан,
  скелет в check_guard_fallout сделан, ветки ТЕНИ нет — она уехала в L5-SHADOW.

Приёмки: по решению пользователя уровни 1-4 приняты SMOKE-тестами, полные
обходы всех комнат делаются по готовности ВСЕХ уровней — L3-PASS/L4-PASS как
отдельные задачи отменены, вместо них политика приёмок в архиве.

Новая цель — уровень 5.  Инвентарь res2005.bin: НИ ОДНОГО нового тайла, всё
портировано на уровнях 1-4.  Единственная новая механика — спецсобытие «тень
крадёт зелье» (комната 24): заведена задача L5-SHADOW с портом по SDLPoP
(check_shadow / do_init_shad / do_auto_moves + shad_drink_move /
autocontrol_shadow_level5 + ветка тени в check_guard_fallout), включая
готовые константы и то, что у нас уже есть под это.

Заведён MIRROR-FG-STALE (низкий): place_mirror пишет тайл в данные уровня, но
не в снимок room_fg, по которому работает коллизия — если зеркало поставлено,
пока игрок В комнате 4, оно невидимо для коллизии (тень не родится).  В
обычном прохождении недостижимо: дверь выхода в другой комнате.  Записан
точный сценарий воспроизведения читом ROOMNAV и фикс на несколько строк.

Правило «в _OPEN только незакрытое» теперь выполняется буквально:
- bug_list.md → BUGS_OPEN.md, bug_closed.md → BUGS_CLOSED.md (ссылки
  обновлены во всех документах и в комментарии pop_trob.c);
- из TASKS_OPEN убраны блоки закрытых задач (L3-CHOMP, L3-SKEL, L3-PASS,
  L4-MIRROR, DRAW-CHAR), справка по связности комнат уехала в архив;
- из BUGS_OPEN убраны 8 строк таблицы закрытых багов, закрытый T-2 (уехал в
  BUGS_CLOSED) и раздел «уровень 3 — неначатые задачи» (обе записи закрыты);
  сводная таблица пересобрана по реально открытым записям.

Все внутренние ссылки проверены скриптом: битых якорей 0.  make size-check
OK (65 программ), tests-host 5/5.

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

7.0 KiB
Raw Blame History

Prince of Persia → ZX Sprinter — правила подпроекта

Порт Prince of Persia (DOS/Apple II) на Sprinter Sp2000 поверх нашего sprinter-cc / libc / libbgi. Действуют правила корневого CLAUDE.md (сборка, libc, ABI, MAME-автотест); ниже — только специфика PoP. Общение и комментарии — на русском.

Главное правило: SDLPoP — источник истины. Сначала читай, потом кодь

SDLPoP/src/ (github.com/NagyD/SDLPoP, GPLv3) — ЕДИНСТВЕННЫЙ авторитетный источник того, как оригинальный движок это делает. Правило без исключений:

  1. Перед реализацией ЛЮБОЙ функции (движение, коллизия, окклюзия, падение, loose-полы, стражники, отрисовка, тайминги, любые числовые константы) — СНАЧАЛА найди и прочитай соответствующий код в SDLPoP/src/, и портируй по нему. Не пиши по памяти, не выводи логику «из общих соображений», не угадывай значения — это источник багов, которые потом ловятся в MAME часами.
  2. По любому вопросу «как в оригинале должно быть» (что окклюдит что, в каком порядке слои, когда меняется тайл, какая скорость/задержка, что делает такой-то кадр анимации) — ответ ищи в SDLPoP/src/, а не строй гипотезу. Если в SDLPoP не нашёл — это повод копать дальше в исходнике, а не додумывать.
  3. Расхождение нашей реализации с SDLPoP — по умолчанию баг у нас, пока не доказано обратное (наша платформа/ABI требует отличия — тогда явно зафиксировать почему в комментарии и записью в docs/impl_diff.md: что делает оригинал, что делаем мы, чем платим, что проверять при регрессе).

Карта сегментов: seg005 control-диспетчер, seg006 play_kid/коллизия/ seqtbl, seg007 mob/loose/падающие объекты, seg008 отрисовка тайлов/ слои/окклюзия, seg009 чтение ресурсов. Слои окклюзии у нас = слои SDLPoP. См. memory pop_check_sdlpop_first.

Вторичные референсы (когда в SDLPoP непонятно/нужен другой ракурс):

  • Prince-of-Persia-Apple-II/ — оригинальный 6502-исходник 1989 (Мехнер).
  • PR/ (github.com/NagyD/PR, GPLv2) — Princed Resources.
  • mininim/ — независимая реализация.

Все эти папки — справочник логики/структур/констант и источник ассетов, но НЕ код для копирования (лицензии несовместимы, наш ABI другой): читаем и переписываем под наш движок, а не вставляем куски.

Ассеты

Готовые распакованные VGA-256 ассеты (то, что нужно под 320×256×256) — SDLPoP/data/ (res<id>.png/.pal/.bin). Брать оттуда, а НЕ писать свой декодер DOS .DAT. Локальные .DAT — в MSDOS/.

Каноническая спецификация форматов .DATdocs/POP-DAT-FormatSpecifications.pdf (грепаемая копия — docs/POP-DAT-FormatSpecifications.txt): первоисточник Princed для DAT v1.0 (контейнер/индекс/чек-сумма, кодеки RLE/LZG, палитры, формат уровней, звук), на нём построены и SDLPoP, и Princed Resources. Наши разборы (docs/MSDOS_RESOURCE_FORMAT.md / docs/APPLEII_RESOURCE_FORMAT.md / docs/README.md) — практические заметки/сверки; при расхождении источник истины — спецификация. Формат уровня почти идентичен в Apple II и DOS.

Упаковка ассетов под Sprinter (атласы .atl, палитра) — python-скрипты в toolchain/ (render_room.py, pop_pack_bg.py, pop_pack_kid.py, pop_extract_kid_data.py). Их дёргают Makefile'ы тестов.

Структура папки

  • docs/ — планы и форматы; индекс с отметками актуальности — docs/README.md, начинать чтение оттуда. Ключевое: levels_plan.md (следующий этап), layout_plan_v2.md (раскладка кода по окнам/банкам + скорость отрисовки), PORT_PLAN.md (карта фаз со статусами).
  • roomtest/активная разработка: уровень 1 целиком (Kid, стражи, ловушки, ворота, loose-полы). Свой CLAUDE.md; текущие задачи — roomtest/TASKS_OPEN.md (закрытые с протоколами — roomtest/TASKS_CLOSED.md), открытые баги — roomtest/BUGS_OPEN.md, закрытые с разбором корней — roomtest/BUGS_CLOSED.md.
  • poc/ — ранний proof-of-concept (снег/атлас/kbd_raw); ассеты в poc/res/.
  • bgtest/, coltest/ — отдельные проверки фона/коллизии.
  • toolchain/ — python-упаковщики ассетов + эталонные PNG (1.1-2.png).
  • SDLPoP/, PR/, Prince-of-Persia-Apple-II/, mininim/, MSDOS/ — референсы/оригинальные данные (см. выше).

Ключевые архитектурные решения (memory/)

  • pop_port_project — общий статус порта.
  • pop_banking_architecture — будущее: big+BANK_W1, графику нельзя в W3, один файл = один банк = прямые вызовы, main резидентен.
  • pop_background_strategy — фон = композиция тайлов в рантайме (вариант 3).
  • pop_kid_plan / pop_hang_state / pop_fore_layer / pop_fall_debug_baseline — этапы Kid.
  • kbd_raw_fifo_drain — held-state клавиатуры (единственный принципиальный пробел движка, закрыт <kbd_raw.h>): вычерпывать FIFO SIO циклом.
  • png_strip_padding_tradeoff, pop_tile_atlas_palette_merge — квирки упаковки ассетов.