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>
This commit is contained in:
@@ -4,6 +4,54 @@
|
||||
гипотеза с причиной, по которой её стоит проверить, и с тем, что мешает
|
||||
сделать это прямо сейчас.
|
||||
|
||||
## Зелье «переворот экрана» (upside-down)
|
||||
|
||||
**Вопрос пользователя (2026-08-01).** Тайлы фона у нас лежат строками, а
|
||||
кадры Кида/стражей — КОЛОНКАМИ (`transpose_cols` в `pop_pack_kid.py`, ради
|
||||
бесплатного горизонтального зеркала). Значит вертикальный переворот для
|
||||
персонажей заметно сложнее, чем для фона. Верно; но прежде чем это чинить,
|
||||
надо знать три факта.
|
||||
|
||||
**Факт 1 — когда оно вообще нужно.** Зелье переворота — тип 4
|
||||
(`proc_get_object`, `seg006.c:1885` → `toggle_upside()`). Скан всех уровней
|
||||
по данным (`res200N.bin`, тайл 10 = зелье, тип в backtable): тип 4
|
||||
встречается **впервые на уровне 9** (две склянки), и больше нигде. Тип 3
|
||||
(перо, медленное падение) — уровень 7. То есть **до уровня 9 механика не
|
||||
нужна вообще**, и «на первом этапе просто не реализовывать» — не компромисс,
|
||||
а точное соответствие данным уровней 1..8.
|
||||
|
||||
**Факт 2 — что именно делает оригинал.** НЕ переворачивает спрайты.
|
||||
`flip_screen` (`seg009.c:1042`) → `flip_not_ega` (`seg009.c:1023`) меняет
|
||||
местами СТРОКИ готового offscreen-буфера (top↔bottom, порядок пикселей
|
||||
внутри строки не трогает — это вертикальное зеркало, не поворот на 180°).
|
||||
Вызывается вокруг отрисовки кадра целиком (`seg003.c:296..301`): перевернул
|
||||
буфер → дорисовал → перевернул обратно. Так что в оригинале это
|
||||
post-process всего экрана, и вопрос «как перевернуть колоночный спрайт»
|
||||
там просто не возникает.
|
||||
|
||||
**Факт 3 — почему нам этот приём не подходит как есть.** У нас нет шага
|
||||
«готовый offscreen → экран»: рисуем прямо в видеостраницу, а heal берёт фон
|
||||
из ОЗУ-копии этой же страницы. Переворот всей страницы построчно — это
|
||||
320×192 Б копирования КАЖДЫЙ кадр, что мимо бюджета на порядок.
|
||||
|
||||
**Варианты, которые надо будет взвесить (не сейчас):**
|
||||
1. **Предпечённые перевёрнутые атласы.** Второй набор кадров
|
||||
Кида/стража, перевёрнутый по вертикали ещё в `pop_pack_kid.py` (там уже
|
||||
есть транспонирование — добавляется одной строкой). Рантайм: выбор
|
||||
набора + зеркальная арифметика Y. Память: ещё ~28 страниц EMM при
|
||||
бюджете ~3.3 МБ — не проблема. Похоже, самый дешёвый по тактам путь.
|
||||
2. **Фон рисовать с обратным Y** — для row-major тайлов строка остаётся
|
||||
непрерывным accel-прогоном, меняется только адрес назначения; цена —
|
||||
вызов на строку вместо вызова на тайл. Померить, прежде чем закладывать.
|
||||
3. **Аппаратная помощь** — до проектирования проверить, есть ли у
|
||||
акселератора направление копирования «вниз» (обратный инкремент адреса);
|
||||
если есть, вариант 1 может и не понадобиться. Смотреть
|
||||
`docs/new/06-accel.md` и `docs/reference/accel_r.txt`.
|
||||
|
||||
**Почему не сейчас.** Уровни 1..8 этого не требуют, а к уровню 9 у нас уже
|
||||
будет ответ на вопрос «сколько стоит кадр» (задачи CLIP-1/T-2) — без него
|
||||
выбирать между вариантами выше бессмысленно.
|
||||
|
||||
## Заменить генератор псевдослучайных чисел
|
||||
|
||||
Сейчас стоит LCG оригинала, шаг на ассемблере (~1 020 тактов), бит-в-бит
|
||||
|
||||
Reference in New Issue
Block a user