9234c03020
Оригинал (seg004:0004) индексирует флаги перекрытия колонкой ВНУТРИ разрешённой комнаты и хранит рядом её номер, поэтому решётка комнаты 8 остаётся в своём слоте и после перехода 8->6: переход флага 0->1 виден, bumped() срабатывает. У нас индекс — колонка отрисованной комнаты, тот же тайл менял слот, и enter_room вынужден был выбрасывать историю целиком — на кадре входа бампа не было, и Кид с разбега уходил сквозь закрытые ворота. Вариант B (сдвиг вместо тега комнаты): при БОКОВОМ переходе история не выбрасывается, а перенумеровывается на 10 слотов. check_leave двигает x ровно на ∓140 = 10 тайлов, координата грани едет на те же 140 вместе с габаритом Кида — сами флаги инвариантны, меняется только номер слота. Сдвигаются curr/above/below (prev на следующем кадре всё равно перезапишет move_coll_to_prev), освободившиеся слоты = 3 «уже перекрывал». Вверх/вниз и прочие входы в комнату — по-прежнему полная инвалидация. Дословный вариант A (10 слотов + массив номеров комнат) не взят: он тянет за собой сужение окна перебора колонок, то есть отказ от FIX_COLL_FLAGS. Заведён docs/impl_diff.md — список осознанных расхождений с SDLPoP; правило «фиксировать расхождение» в обоих CLAUDE.md теперь указывает туда. tests-host: все 5 наборов прошли. Приёмка в MAME впереди. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
92 lines
7.0 KiB
Markdown
92 lines
7.0 KiB
Markdown
# 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/`.
|
||
|
||
**Каноническая спецификация форматов `.DAT` — `docs/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/bug_list.md`,
|
||
закрытые с разбором корней — `roomtest/bug_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` — квирки
|
||
упаковки ассетов.
|