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:
@@ -1,8 +1,26 @@
|
||||
# roomtest — план v2: размер кода и раскладка по окнам/банкам/страницам
|
||||
|
||||
> **Замер 2026-08-01 (актуальная сборка).** `_CODE` 25 119 Б, `_DATA` 3 709,
|
||||
> куча ~2.4 КБ. Банки: 1 (`guards.c`) 1 896, 2 (`pop_bg.c`) 13 792,
|
||||
> 3 (`pop_map.c`) 6 331, 4 (`pop_gdraw.c`) 2 236 — все из 16 384.
|
||||
> **Резидента `--w3` больше нет**: отрисовка уехала в банк 2, и это сняло
|
||||
> главное ограничение резидента (из банка его было не достать) — банк→банк
|
||||
> работает, трамплин сохраняет страницу окна на стеке. Отрисовка стража
|
||||
> вынесена из банка 2 в собственный банк 4, потому что банк 2 подошёл к
|
||||
> потолку (16 021 из 16 384) — коммит `2f3e854`.
|
||||
>
|
||||
> **Свободного места в банке 2 осталось ~2.6 КБ**, а туда же просятся
|
||||
> чомперы, зеркало и второй тайлсет (palace). Прежде чем начинать
|
||||
> `levels_plan.md` §3 — посчитать, куда это ляжет. Свободные номера банков
|
||||
> есть, гранулярность — файл.
|
||||
>
|
||||
> Из плана ниже **не сделаны шаги 5 (данные: `room_modif`, `dl1/dl2`,
|
||||
> `_kbdraw_down`; потенциал ~1.5 КБ) и 7 (дедуп `draw_tile`, отложен по
|
||||
> решению пользователя)**.
|
||||
|
||||
Статус: **план для отдельной сессии**, составлен 2026-07-29 по свежему замеру.
|
||||
Заменяет `size_optimization_plan.md` (v1, 2026-07-21): часть его пунктов уже
|
||||
сделана, часть опиралась на неверную модель банкинга. Документ самодостаточный
|
||||
Заменял `size_optimization_plan.md` (v1, 2026-07-21) — тот удалён 2026-08-01
|
||||
как полностью перекрытый этим документом. Документ самодостаточный
|
||||
— рассчитан на старт с пустого контекста.
|
||||
|
||||
Повод: перед стражами и боёвкой (новый код ~5–8 КБ) надо понять, куда он
|
||||
@@ -442,5 +460,53 @@ dir_behind`, `y_to_row`, `char_dx_forward`, `get_tile_div_mod(_m7)`,
|
||||
`bank_local_data_pattern`, `sprinter_memory_modes`, `memory_modes_implemented`,
|
||||
`sprinter_emm_budget`, `mame_mcp_bridge`, `avoid_32bit_arith_z80`,
|
||||
`libc_one_function_per_module`.
|
||||
- `applications/PoP/docs/size_optimization_plan.md` — v1 (замер 2026-07-21,
|
||||
раздел §8 про скорость отрисовки актуален и не дублируется здесь).
|
||||
- `applications/PoP/roomtest/TASKS.md` — что из этого берётся в работу сейчас.
|
||||
|
||||
---
|
||||
|
||||
## 9. Скорость отрисовки: замеры и запас
|
||||
|
||||
Перенесено из удалённого `size_optimization_plan.md` §8 (замер 2026-07-27) —
|
||||
единственная его часть, которая не была перекрыта этим документом.
|
||||
Профилирование в MAME: маркеры в порт 0xFE + `wpiset … totalcycles` (приём из
|
||||
memory `mame_mcp_bridge`); в самом `roomtest.c` для этого уже стоят полосы
|
||||
бордюра `PROF()`. Кадр Sprinter = **430 080 тактов**.
|
||||
|
||||
**Стоимость блита почти НЕ зависит от размера** — платим за проход по цепочке
|
||||
`gfx_blit → gfx_blit_part → _gfx_blit_full` (16-битная арифметика, клип,
|
||||
пересчёт src, нарезка полос >256), а не за пиксели:
|
||||
|
||||
| путь (спрайт 32×3) | тактов |
|
||||
|---|---|
|
||||
| `gfx_blit` (общее ядро, с клипом) | 13 288 |
|
||||
| линейное ядро без клипа | 4 617 |
|
||||
|
||||
Отсюда `draw_tile(0,0)` тайла шва (9 блитов) стоил **183 690 тактов = 43 %
|
||||
кадра**; сам `bar` — только 13 308.
|
||||
|
||||
**Сделано:** `gfx_blit_noclip()` в libbgi, фоновые блиты `pop_bg` уходят на
|
||||
него, когда спрайт целиком на экране (~2.9×, подтверждено в MAME). Позже
|
||||
тем же приёмом закрыты спрайты персонажей (`gfx_blit_cols_part_noclip`).
|
||||
**Не закрыт heal** — задача CLIP-1 в `../roomtest/TASKS.md`.
|
||||
|
||||
**ВАЖНО:** W3-скобку (`_bgi_begin`/`_bgi_end`) ставит САМА libbgi — вызывать
|
||||
её из модуля, собранного с `--w3`, нельзя: после `_bgi_begin` окно W3 занято
|
||||
видеобанком и код вызывающего исчезает из адресного пространства (проверено:
|
||||
белый экран).
|
||||
|
||||
**Запас, когда перестанет хватать бюджета кадра:**
|
||||
|
||||
1. **Батчинг W3-скобки** — одна `_bgi_begin`/`_bgi_end` на весь `draw_tile`
|
||||
вместо скобки на блит; нужен публичный batch-API в libbgi.
|
||||
**Осторожно, и это стало важнее, чем было:** между begin/end стоит `DI`,
|
||||
длинная серия задержит кадровое прерывание — а по разбору KBD-1
|
||||
(`../roomtest/TASKS.md`) длинные DI-окна и есть причина потери байт
|
||||
клавиатуры. Батчинг эту проблему УХУДШИТ, если делать его вслепую.
|
||||
2. **Решётка ворот одним спрайтом** — `draw_gate_back` рисует бары по одному
|
||||
(до 7 блитов). Сгенерировать в атласе «столб решётки» и выводить одним
|
||||
`gfx_blit_part` с обрезкой по фазе `gate_bot_y & 7`: 7 блитов → 1.
|
||||
3. **Не перерисовывать статичные части шва** — грань ворот, пол и кромка при
|
||||
анимации решётки не меняются (см. OPT-1 в `../roomtest/bug_list.md`).
|
||||
4. **T-1 / T-2** (`../roomtest/bug_list.md`) — перерисовка пик по причине и
|
||||
idle-skip Кида: самый большой оставшийся резерв, потому что убирает работу
|
||||
целиком, а не удешевляет её.
|
||||
|
||||
Reference in New Issue
Block a user