diff --git a/applications/PoP/roomtest/bug_closed.md b/applications/PoP/roomtest/bug_closed.md index 774f619..822258e 100644 --- a/applications/PoP/roomtest/bug_closed.md +++ b/applications/PoP/roomtest/bug_closed.md @@ -741,3 +741,30 @@ dir_56_none`. То есть стражи — такая же часть дан проверка занимает несколько строк — заспавнить кусок, сменить комнату, тикать до приземления, проверить щебень в данных уровня. Стоит первым в `../docs/host_tests_plan.md`. + + +## BUG-SEAM-DRAW-1. Кид, упершийся в решётку на шве, не рисуется — **ЗАКРЫТ (не воспроизводится)** + +**Как было заведено.** Комната 5: Кид добегает до закрытой решётки (0,9), +решётка его держит, но экран переключается на комнату 1, и в ней Кида не +видно — он стоит на `x = 57..60`, левее кромки комнаты (col 0 начинается с 58). + +**Проверка 2026-08-03.** Не воспроизводится: Кид упирается и встаёт на +`x = 61`, `curr_col = -1`, `room = 1` — и в комнате 1 РИСУЕТСЯ, за решёткой, +как и должен. + +Почему сходится: при `x = 61` персонаж уже внутри системы координат комнаты 1 +(`obj_x = 2*61 − 116 = 6`), поэтому никакого straddle-смещения не требуется и +обычная отрисовка справляется. Отрицательная `curr_col` тут не противоречие — +это правило `get_tile_div_mod_m7`: `(61 − 7 − 58) / 14 = −1`. + +**Что осталось за скобками.** Само переключение экрана штатное: `leave_room` +(seg002:423) уводит вправо при `char_x_right >= 201`, а левая грань решётки как +раз 201 — оригинал в этой позе тоже перелистнёт. + +И остаётся теоретический остаток: при `x <= 60` (`obj_x <= 4`) спрайт уходил бы +за левую кромку и обрезался. В текущей сборке Кид туда не встаёт, поэтому баг +и не воспроизводится. Полное лекарство — довести модель straddle (S3 в +`../docs/room_model_plan.md`): держать `Kid.room` отдельно от `drawn_room` и +рисовать со смещением ±140, как `xpos_in_drawn_room` (seg004:0405). Пока +поводов для этого нет — заводить обратно только по живому наблюдению. diff --git a/applications/PoP/roomtest/bug_list.md b/applications/PoP/roomtest/bug_list.md index 0840489..b0d6605 100644 --- a/applications/PoP/roomtest/bug_list.md +++ b/applications/PoP/roomtest/bug_list.md @@ -20,11 +20,14 @@ BUG-DEATH-1 (смерть от меча), BUG-GATE-ANIM-1 (анимация во закрыты — BUG-KBD-4 (фантомный отжим Shift), BUG-RESPAWN-2 (стражи не оживают), BUG-DRAWORDER-1 (Кид поверх тела стража) и BUG-LOOSE-2 (осколки только от одной из двух плит). У BUG-DRAWORDER-1 остался артефакт «ноги поверх головы», -сверенный с SDLPoP и записанный в «НЕ БАГИ». +сверенный с SDLPoP и записанный в «НЕ БАГИ». Тогда же закрыт как +невоспроизводящийся BUG-SEAM-DRAW-1 (Кид в шве рисуется) и заведён +BUG-GATE-PASS-1 — однократное наблюдение прохода сквозь закрывшуюся решётку, +которое ЖДЁТ надёжного сценария. | ID | что | тип | статус | |----|-----|-----|--------| -| [BUG-SEAM-DRAW-1](#bug-seam-draw-1) | у решётки на шве экран переключается, а Кид в шве НЕ рисуется | Minor | открыт | +| [BUG-GATE-PASS-1](#bug-gate-pass-1) | проход сквозь закрывшуюся решётку (0,9) комнаты 5 | Major | **ждёт сценария воспроизведения** | | [T-1](#t-1) | пики перерисовываются безусловно | оптимизация | открыт | | [T-2](#t-2) | Кид перерисовывается в покое | оптимизация | открыт | | [обход 24 комнат](#обход-всех-24-комнат-уровня-1) | таблица заполнена на 5 строк из 24 | ревизия | открыт | @@ -51,7 +54,7 @@ BUG-DRAWORDER-1 (Кид поверх тела стража) и BUG-LOOSE-2 (ос | 4 | комната 12: разбить плиты (0,1)/(0,2) и потолок в 16, выйти-вернуться | остаются разбитыми, проём не закрывается | | 5 | комната 17 из 23: разбить (1,5)/(1,6), выпить зелье (2,3), вернуться | всё остаётся | | 6 | **после смерти** зайти в те же комнаты | ВСЁ восстановлено (в оригинале смерть = `load_level`) | -| 7 | комната 12: разбег в закрытую решётку (0,9) с полушага | не проходит насквозь; экран может перелистнуться — это [BUG-SEAM-DRAW-1](#bug-seam-draw-1) | +| 7 | комната 12: разбег в закрытую решётку (0,9) с полушага | не проходит насквозь; перелистывание экрана штатно (см. BUG-SEAM-DRAW-1 в `bug_closed.md`) | | 8 | комната 6: бег справа налево от (0,9), длинный прыжок (0,6)→(0,7) | не влетает внутрь стены | | 9 | комната 5: с кнопки (0,6) падение на (2,7), присед, вставание | остаётся в комнате 5 (проверено трассой: `fr=111 x=177` → `seq_47` → `fr=15 x=173`) | | 10 | комната 5: нажать кнопку (0,4) | поднимаются ОБЕ решётки — (0,5) видно на экране, (0,9) проверять из комнаты 1 | @@ -74,28 +77,52 @@ BUG-DRAWORDER-1 (Кид поверх тела стража) и BUG-LOOSE-2 (ос # Открытые баги уровня 1 - -## BUG-SEAM-DRAW-1. Кид, упершийся в решётку на шве, не рисуется + +## BUG-GATE-PASS-1. Проход сквозь закрывшуюся решётку — ЖДЁТ СЦЕНАРИЯ -**Симптом.** Комната 5: Кид добегает до закрытой решётки (0,9), решётка его -ДЕРЖИТ (проверено: x встаёт на 60 и дальше не растёт), но экран -переключается на комнату 1, и в ней Кид не виден — он стоит на `x = 57..60`, -левее кромки комнаты (col 0 начинается с 58). +**Статус: наблюдался один раз, воспроизвести повторно НЕ удалось.** Заведён, +чтобы наблюдение не потерялось; закрывать нельзя — ни как исправленный, ни как +«не баг», пока нет надёжного сценария. -**Разбор.** Переключение экрана само по себе штатное: `leave_room` -(seg002:423) уводит вправо при `char_x_right >= 201`, а левая грань решётки -как раз 201 — то есть в оригинале экран тоже перелистнётся, если персонаж -встанет ровно на грань. Не штатно то, что персонажа в шве **не рисуют**: -`update_kid_render_dx` даёт смещение только когда `kid_room != cur_room`, а -`enter_room` сразу выравнивает `kid_room = cur_room`. Это остаток -непортированной модели straddle (S3 в `pop_kid_plan`). +**Что наблюдалось (2026-08-03).** Комната 5: Кид стоял НА тайле решётки (0,9) +и ждал, пока она опустится. После закрытия пошёл вправо — прошёл в комнату 1 +и упал на (1,1). -**Что делать.** Довести S3: держать `Kid.room` отдельно от `drawn_room` и -рисовать персонажа со смещением ±140, как `xpos_in_drawn_room` (seg004:0405). +**Что уже измерено и в чём загвоздка.** Сразу после наблюдения повторить не +получилось: в том же месте Кид стоит на `x = 196`, `col = 9`, и решётка его +ДЕРЖИТ — то есть штатно. +Арифметика оригинала объясняет разницу. `is_obstacle` (seg004) ставит +плоскость блокировки в `x_bump[col + FIRST_ONSCREEN_COLUMN] + TILE_MIDX`, для +колонки 9 это **x = 205**. При этом «колонка 9» по `get_tile_div_mod_m7` — +это `x ∈ [191, 205)`. Пока `curr_col == 9`, Кид гарантированно левее +плоскости и обязан блокироваться; чтобы пройти, он должен оказаться **правее +205**, то есть уже на дальней стороне решётки, — и тогда уход вправо законен: +решётка закрылась у него за спиной, в оригинале она блокирует плоскость, а не +весь тайл. +Отсюда рабочая гипотеза: в момент наблюдения Кид стоял правее 205 (успел зайти +по тайлу дальше, пока решётка была поднята), и поведение штатное. Но повторить +эту позу и снять `x` пока не удалось, поэтому гипотеза НЕ подтверждена. +**Что снять в следующий раз** (без этих чисел вопрос не закрыть): +1. `Kid.x` и `Kid.curr_col` в момент, когда решётка уже закрылась, а Кид ещё + стоит на её тайле — до шага вправо; +2. модификатор решётки (openness) комнаты 5, тайл 9 — `can_bump_into_gate()` + считает её препятствием только пока `(modif >> 2) + 6 < char_height`, то + есть пока она опустилась достаточно низко относительно РОСТА кадра; +3. `Kid.x` покадрово на самом шаге вправо — где именно перестал блокировать. + +Быстрый способ снять первое: отладочный стоп-кадр (**1** заморозить, **2** +продолжить), затем чтение `_Kid` из отладчика MAME. + +**Возможный корень, если гипотеза не подтвердится.** Проверка идёт по колонке, +которая на шве уже принадлежит СОСЕДНЕЙ комнате (`curr_row_coll_room[]` в +оригинале); у нас межкомнатная коллизия на шве — исторически проблемное место +(ср. закрытый BUG-SEAM-PINGPONG). Второй кандидат — `char_height` в +`can_bump_into_gate()`: если он берётся не от того кадра, решётка может +перестать считаться препятствием раньше времени. # Оптимизация отрисовки (записано 2026-07-29)