Files
Sprinter-SDCC/applications/PoP/CLAUDE.md
T
Александр Петров 774b1cc7c4 docs(PoP): документация к актуальному статусу + план следующих уровней
Документы отстали от кода: PORT_PLAN писал «PoC не начат», хотя играется
весь уровень 1, а четыре плана были исполнены целиком.

- PORT_PLAN: таблица статусов по разделам; фазы 0-3 сделаны, 4-6 нет;
  риски §8 п.1/п.3 закрыты, п.2 переформулирован под реальный движок
  (спрайтовый движок для персонажей не используется, лимит «21 спрайт»
  неприменим), п.4 — найдено расхождение таймингов: оригинал считает
  логический кадр за 5 тиков при BASE_FPS=60 (83.3 мс, в бою 100 мс), а мы
  ждём три vsync (60 мс) — игра идёт примерно на 39 % быстрее эталона.
- levels_plan.md — новый: машинерия перехода между уровнями, второй
  тайлсет (palace), потабличные различия и читы SDLPoP, которые окупаются
  сразу.  Инвентарь тайлов снят прямо с res200N.bin: уровень 2 не требует
  ни одного нового ассета и ни одной новой механики.
- roomtest/TASKS.md — новый: доска текущих задач с критериями готовности.
- Удалены как исполненные и перекрытые кодом: clip_char_plan,
  double_buffer_plan, loose_floors_plan, size_optimization_plan.  Его §8
  (замеры скорости отрисовки) не был перекрыт — перенесён в
  layout_plan_v2 §9, чтобы не потерять цифры.
- KID_PLAN / gates_spikes_plan — шапки «реализовано, оставлено
  справочником»; room_model_plan — «S1 сделан, остальное не срочно».
- docs/README.md стал индексом с отметками актуальности.
- ideas_backlog: зелье переворота экрана — оригинал переворачивает готовый
  буфер построчно, спрайты не трогает; по данным уровней тип 4 встречается
  только на уровне 9, до него механика не нужна.
- examples/scroll: ссылка на удалённый план вела к неверному факту
  «теневая копия одна — общая»; заменено на подтверждённое «у каждой
  страницы своя».

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 15:32:48 +03:00

6.7 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 требует отличия — тогда явно зафиксировать почему в комментарии).

Карта сегментов: 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.md, баги — roomtest/bug_list.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 — квирки упаковки ассетов.