Files
Sprinter-SDCC/applications/PoP/roomtest/NEXT_SESSION.md
T
snark13 361c9d9f78 Мышь уровня 8 + холодная половина главного цикла в банк 8
Спецсобытие уровня 8 (SDLPoP seg003:0545/0ABA, seg002:07EB): когда дверь
уровня открыта, а Кид остаётся в комнате 16, через 150 кадров приходит мышь,
пробегает справа налево по верхнему ряду, наступает на кнопку (0,7) —
решётка (0,3) открывается — и убегает.

Ассетов не потребовалось: кадры 186..188 идут по таблице Кида, их спрайты
(images 130..132) уже лежат в kid16.atl, отрисовка подхватывает мышь сама.

- guards.c: pop_check_mouse, autocontrol_mouse, ветки мыши в
  autocontrol_opponent / play_guard / check_can_guard_see_kid;
- pop_leveldoor_open стал word, как в оригинале (в него же считается
  задержка — байт переполнился бы через 255 кадров);
- leave_guard больше не записывает тень и мышь в данные уровня (seg002:02F5);
- полосы HP у мыши нет (seg000:1159);
- tests-host/t_mouse: 17 проверок, единственный набор с guards.c.

Разгрузка резидента (куча в huge упала до 879 Б): pop_start_level,
find_start_level_door, чит-навигация по комнатам и лейбл номера уехали в
roomtest_cold.c (--bank 8, n_banks = 8).  _CODE 25653 -> 24825, куча -> 1707 Б;
кадровый путь не тронут.

Проверено: tests-host 6/6, make size-check OK, живьём в MAME (мышь появилась,
нажала кнопку, решётка поехала вверх, мышь ушла).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 15:21:20 +03:00

153 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Точка входа для следующей сессии (обновлено 2026-08-12, вечер)
Файл для старта с чистого контекста: где всё стоит, что делать первым, какие
грабли уже собраны. Читать целиком — он короткий. Дальше по ссылкам:
`TASKS_OPEN.md` (доска), `BUGS_OPEN.md` (открытые баги), `CLAUDE.md`.
---
## 1. СЛЕДУЮЩАЯ ЗАДАЧА: smoke-прогон уровня 8
Зелья приняты пользователем (уровень 2 — «−HP», уровень 7 — перо), уровень 7
считается прошедшим smoke. Спецсобытие уровня 8 —
[L8-MOUSE](TASKS_CLOSED.md#l8-mouse) — **закрыто 2026-08-12**: мышь
портирована, покрыта хост-набором `t_mouse` (17 проверок) и проверена живьём в
MAME (появилась, нажала кнопку (0,7) комнаты 16, решётка (0,3) поехала вверх,
ушла и погасла). Новых тайлов уровень 8 не приносит вовсе.
Осталось пройти сам уровень: он длинный, с возвратом через два чомпера
комнаты 4, и стражи там сильнее прежних — комната 5 держит **skill 7**
(максимум из встречавшихся), комнаты 12/22/24 — skill 2/3/3.
Правило появления мыши (сверено с оригиналом, детали в
[TASKS_CLOSED](TASKS_CLOSED.md#l8-mouse)): счётчик — сам `leveldoor_open`,
растёт только пока Кид в комнате 16, срабатывание ровно на 150, **второго
раза нет**; сбрасывает только рестарт уровня. Тупика это не создаёт — низом
через провал есть путь к двери уровня ценой 1 HP.
Резидент разгружен ([MEM-COLD1](TASKS_CLOSED.md#mem-cold1)): холодная половина
главного цикла уехала в **банк 8** (`roomtest_cold.c`), куча 879 → **1707 Б**.
Следующие кандидаты — [MEM-COLD2](TASKS_OPEN.md#mem-cold2).
Ощущенческий хвост прежний — [GRAB-KBD-TIMING](BUGS_OPEN.md#grab-kbd-timing),
разбирается после готовности всех уровней (решение пользователя).
## 2. Состояние репозитория
Всё закоммичено, `main` чист. `tests-host`: **6 наборов** проходят
(`[char] 65`, `[geom] 3144`, `[grab] 55`, `[mouse] 17`, `[phys] 1727`,
`[wall] 1`). `make size-check`: OK (65 программ, роста нет).
Коммиты 2026-08-12:
| хеш | что |
|---|---|
| `b5951c9` | зацеп за кромку нижнего ряда: `do_fall` пускает ряд до 3 + `check_grab` в midair |
| `d7d18ae` | зелье медленного падения (перо) + цвет пузырьков по типу зелья |
Раньше (2026-08-11, вечер): `abe4a83` уровень 5, `740cc6d` арка у ворот,
`e4ef489` L6-SHADOW, `9ecea17` уровень 6 → 7.
Уровни 1-6 проходятся.
## 3. Состояние окружения
- **MAME запущена с мостом**, на HDD — roomtest, собранный с
`-DFIRST_LEVEL=8`. **ПРАВИЛО ПОЛЬЗОВАТЕЛЯ: перед сборкой образа —
`make clean`, потом `make`, потом `make hdd`** (memory
`mame_build_clean_rule`). Без этого `make hdd` кладёт на диск ПРОШЛУЮ
сборку: `FIRST_LEVEL` живёт внутри `roomtest.c`, и без изменения исходника
make считает `.exe` актуальным — 2026-08-12 на этом уехал уровень 1 вместо
8, заметил пользователь. После пересборки образа MAME **обязана** пройти
полный рестарт (memory `mame_hdd_rebuild_restart`).
- Адреса состояния сместились после MEM-COLD1: брать из
`.sprinter-cc-roomtest/roomtest.map` заново (`cur_room` 0xA33D,
`pop_leveldoor_open` 0xA34C, `Kid` 0xA3B1, `Guard` 0xA759 — на сборку
2026-08-12). Мост: `setmem ADDR HEXBYTES` (не `write`), `mem ADDR N`.
- **Остановка MAME — `mame/v306/bridge_cmd.sh 'cmd exit'`**, НЕ `kill`
(правило пользователя). `pkill -f` бывает не срабатывает, и остаются ДВА
инстанса, оба отвечающих на файловый IPC — тогда скриншоты приходят от
чужой машины. Проверять `pgrep -f mame.arm` после остановки.
- Прогон без MCP-инструментов: запустить `run_bridge.sh`**sleep 6**
`bridge_cmd.sh 'cont'`**sleep 8**`keyseq d:{ENTER}`
`keyseq roomtest{ENTER}``snap <путь>.png`. Тайминги — правило
пользователя, длиннее ставить не надо. **Имя .exe на образе — не длиннее
8 символов (FAT 8.3) и БЕЗ подчёркивания** (`keyseq` не умеет `_`).
- **Вести игру из моста — по обратной связи из памяти, а не по скриншотам**:
`mem 0xA46A 10` = `pop_char_t` Кида, `mem 0xA3F7 1` = номер комнаты (адреса
из `.sprinter-cc-roomtest/roomtest.map`+`.sym`). Полный рецепт (удержания,
чит-навигация, тайминги нажатий) — memory `mame_mcp_bridge`.
- **MCP-инструменты `mame-z80` не поднимались**: сервер падал на
`ModuleNotFoundError: mcp.server.fastmcp` — вышел `mcp` 2.0, где FastMCP
переехал. В `~/.claude.json` зафиксировано `--with "mcp<2"`; подхватится
при следующем СТАРТЕ сессии Claude (внутри текущей — нет).
- **SDLPoP собран с отладочной информацией** (`-O0 -g3`); pkg-config на
машине нет, команда сборки — в истории этого файла (`git log -p`).
- **НЕ ПРИБРАНО:** в `SDLPoP/src/seg008.c` диагностический `fprintf` с меткой
`DBGMIRROR` в начале `add_objtable` (гейтится по `obj_type == 1 || == 4`).
## 4. Что сделано в libbgi и чем это полезно дальше
Блочные операции акселератора — полный набор AND/OR/XOR/NOT, строками и
колонками: `gfx_blit_op` / `gfx_blit_part_op`, `gfx_blit_cols_op` /
`gfx_blit_cols_part_wx_op` (клип-окно и флип — как у копирующих близнецов),
опкод патчится SMC. `putimage` лишился попиксельного пути целиком (закрыт
пункт 2d-1 `docs/TODO.md`). Регресс — `tests/accop` (10/10 PASS в MAME,
побайтно). Механика и три ловушки — memory `accel_block_ops`; главные:
операция читает ОЗУ-КОПИЮ экрана (не VRAM), а прозрачность `#FF` совместима
с AND/OR, но не с XOR.
**Вид тени (OR+XOR) отложен** до готовности всех уровней — разбор, замеры и
варианты в [`../docs/shadow_render.md`](../docs/shadow_render.md).
## 5. Остальное открытое
- **[FORE-DUP](BUGS_OPEN.md#fore-dup)** — передний слой тайла рисуется дважды
при перекрытии объектов (Кид+отражение всегда, Кид+соперник — весь ближний
бой). Картинку не портит, тратит такты. **Сначала замерить, потом
чинить** — окно клипа в своё время дало 3.2×.
- **[DIED-ON-BUTTON](BUGS_OPEN.md#died-on-button)** — `died_on_button`
(seg007:776) не портирован.
- **TORCH-ANIM-RIGHT** — под запечённым пламенем могут застыть пики/меч/зелье
справа от факела; на уровнях 1-4 такого соседства нет.
- **GUARD-PHYS ЗАКРЫТ** 2026-08-11: нажатие напольной кнопки НЕ-Кидом
проверено живьём на уровне 6 (тень встаёт на `closer` и роняет решётку).
- **[GATE-FORE-KID](BUGS_OPEN.md#gate-fore-kid)** — Кид в проёме ворот виден
поверх решётки; портирован только шовный случай.
- Долгие: `BUG-SPIKE-1`, `BUG-CHOMP-JUMP-1` (оба низкий приоритет),
`L3-COLOR`, `L1-SPEED` (игра на ~39 % быстрее оригинала), `TUNE-1`.
## 6. Грабли, собранные 2026-08-12
- **Тест, который «проходит» и на сломанном коде, ничего не стоит.** Первая
версия регресса на спуск-зацеп засчитывала ЛЮБОЙ вис — а Кид на первых
кадрах падения цепляется обратно за ту же верхнюю кромку. Признак цели
обязан быть позиционным. Проверять новый регресс откатом фикса — обязательно.
- **`action == 3` (midair) — это не только падение**: кадры спуска `seq_68`
тоже идут с ним. Ждать «начала падения» по одному `action` нельзя.
- **Клавиши, зажатые из моста, переживают точечный `release`**: плагин
переустанавливает удержания каждый кадр, и после серии `hold` осталось 6
незакрытых входов — у пользователя «Кид ходит как с зажатым Shift».
Заканчивать работу с вводом только `pause` + `cont` (release_all).
- **Чит-навигация `+`/`` теряет нажатия и роняет Кида** из комнат без пола:
уровень 7 из комнаты 17 всегда сваливается в 1, и кольцо `` до комнаты 14
не доходит никогда. Ходить циклом с проверкой номера комнаты.
## Грабли 2026-08-10/11
- **Не оценивать железо по своей же memory-заметке.** Заявил, что accel
умеет только копирование и XOR потребует ~25 % кадра на CPU — неверно,
поправил пользователь. Заметка описывала копирование, я принял её
неполноту за свойство железа. Проверять по драйверу MAME
(`mame/sources/MAME/src/mame/sinclair/sprinter.cpp`) и `docs/new/06-accel.md`.
- **lldb через FIFO — плохая идея.** Повторяющиеся `-o` при
`breakpoint command add` записываются НЕПОЛНЫМИ. **Работает надёжно:**
`fprintf(stderr, ...)` прямо в SDLPoP, пересборка (секунды) и чтение stdout.
- **`make` без `hdd` не обновляет образ MAME**, а `FIRST_LEVEL` живёт в
`roomtest.c` — при смене нужен `touch roomtest.c`.
- **Доска отставала от кода на три задачи** (`L3-CHOMP`, `L3-SKEL`, шаги 3/5
`L4-MIRROR` значились несделанными). Перед планированием — сверять
`TASKS_OPEN.md` с кодом грепом, а не верить записи.
- Диапазон `obj_x` = **416..695** (посчитан из `kid_data.bin`). Пригодится
всякий раз, когда нужна таблица по экранной X.