diff --git a/applications/PoP/roomtest/bug_list.md b/applications/PoP/roomtest/bug_list.md index be55401..47693f0 100644 --- a/applications/PoP/roomtest/bug_list.md +++ b/applications/PoP/roomtest/bug_list.md @@ -20,8 +20,9 @@ | [BUG-CHEAT-FIGHT-1](#bug-cheat-fight-1) | `+`/`−` в бою с вынутым мечом → Кид теряет управление | Major (чит) | открыт | | [BUG-GATE-PASS-1](#bug-gate-pass-1) | проход сквозь закрывшуюся решётку (0,9) комнаты 5 | Major | **ждёт сценария**: прогоном 2026-08-07 не воспроизведён | | [BUG-SPIKE-1](#bug-spike-1) | пики залипают выдвинутыми рядом с Кидом | **низкий** | маловоспроизводимый: ни сценарием, ни попиксельной подгонкой X не поднимается | +| [BUG-CHOMP-JUMP-1](#bug-chomp-jump-1) | прыжок с места вплотную к чомперу: кадр с отступом назад | **низкий** | маловоспроизводимый: на повторе не поднялся; на пререлиз | | [T-1](#t-1) | пики перерисовываются безусловно | оптимизация | открыт | -| [T-2](#t-2) | Кид перерисовывается в покое | оптимизация | открыт | +| ~~T-2~~ | Кид перерисовывается в покое | оптимизация | **ЗАКРЫТ 2026-08-08** — [DRAW-COST шаг 1](TASKS_OPEN.md#draw-cost) | --- @@ -279,26 +280,69 @@ Smoke-прогон уровня 3 (пользователь, 2026-08-05) дал **Приоритет:** отдаётся почти бесплатно ПОСЛЕ T-2, отдельно не окупается. -## T-2. Idle-skip: не перерисовывать Кида, когда ничего не происходит +## T-2. Idle-skip — **ЗАКРЫТ 2026-08-08** -**Сейчас:** `kid_heal` → `kid_draw` → `pop_fore_over_kid` идут каждый кадр, -даже когда Kid стоит и в его тайлах ничего не меняется. Это ровно поведение -оригинала (`draw_game_frame`, seg000:917 — `draw_moving()` + `draw_tables()` -безусловно), но у него это дёшево, а у нас нет. +Сделан как шаг 1 задачи [DRAW-COST](TASKS_OPEN.md#draw-cost) (коммит +`a25ce58`), и шире, чем формулировался здесь: пропускается не только Кид, а +ЛЮБОЙ персонаж, у которого с прошлой отрисовки этой страницы дабл-буфера не +изменился ни один вход отрисовки, — включая труп стража и ждущего стража. +Условие «обе страницы уже получили это состояние», которого требовала эта +запись, выполнено само собой: снимок входов хранится ПО СТРАНИЦАМ. -**Надо:** пропускать heal+draw Кида, когда кадр/поза/координаты не менялись -и в его тайлах нет активной анимации. +Замер: комната 1.3 с трупом стража, Кид стоит — 210 % -> 116 % кадрового +периода, ноль вызовов `pop_heal_fast` за кадр. Контракт — шапка +`pop_cdraw.h`, разбор и что делать дальше — `TASKS_OPEN.md#draw-cost`. -**Осторожно (дабл-буфер):** пропускать можно **не раньше второго подряд** -неизменного кадра — иначе одна из двух страниц останется со старым -содержимым. Условие «обе страницы уже получили это состояние». +Связь с T-1 сработала как и предсказано: пока Кида не перерисовываем, heal'а +нет, стирать пики нечем. Но T-1 остаётся открытым — трогать пики +безусловно мы всё ещё продолжаем, когда Кид рядом ДВИЖЕТСЯ. -**Связь с T-1:** после T-2 пики отпадают сами — раз Кида не перерисовываем, -heal'а нет, стирать пики нечем, редрой не нужен. +--- -**Связь с KBD-1:** это ещё и минус DI-окна в самых спокойных кадрах — ровно -там, где тапают Shift+стрелку (остаток KBD-1 отложен, см. -[`TASKS_CLOSED.md`](TASKS_CLOSED.md#kbd-1)). + + +## BUG-CHOMP-JUMP-1. Прыжок с места вплотную к чомперу: кадр с отступом назад — НИЗКИЙ ПРИОРИТЕТ, МАЛОВОСПРОИЗВОДИМ + +> **Статус 2026-08-08.** Наблюдение пользователя на приёмке L3-CHOMP: Кид +> стоит вплотную СЛЕВА от чомпера лицом вправо, прыжок с места — в анимации +> проскакивает кадр, где он «чуть отступил назад», и только потом идёт +> прыжок. В оригинале прыжок идёт прямо с места. **На повторе в тот же +> заход не воспроизвёлся** — отложено до пререлиза. + +**Что уже установлено (чтобы не разбирать заново).** + +1. **Это НЕ анимация.** `seq_3_standing_jump` (SDLPoP `seqtbl.c:382`) + состоит только из положительных смещений: + `act(run_jump), f16, f17, dx(2) f18…f22, dx(7) f23, dx(9) f24, dx(5) dy(-6) f25`. + Ни одного отрицательного `dx` — отката в последовательности нет вовсе. + Значит отступ даёт `bumped()`, то есть физика посчитала въезд в + препятствие и выровняла `Char.x` назад. + +2. **`is_obstacle` для чомпера у нас совпадает с оригиналом** (seg004:037E): + препятствие только при `modif == 2`, причём именно `== 2`, БЕЗ маски + `0x7F` — то есть окровавленный чомпер (`0x82`) в ванили не бампит вовсе. + Проверено, расхождения нет. + +3. **Прямая трасса прыжка отката НЕ показала.** Ввод «UP и RIGHT + одновременно» (mame bridge, `key UP 24` + `key RIGHT 24`) даёт чистое + движение вперёд: `x` 148 -> 155, кадр становится 178 (перемололо). Ни + одного кадра с уменьшением `x`. + +**Главная гипотеза — ПОРЯДОК НАЖАТИЙ.** Если ↑ приходит на кадр раньше →, +то `control_standing` уходит не в `standing_jump()`, а в `up_pressed()` — +вертикальный прыжок с зацепом, а он **выравнивает `Char.x`**. Отсюда и +«отступил, потом прыгнул». Проверять надо `check_jump_up` / +`jump_up_or_grab` / `grab_up_no_floor_behind` (seg005:0836 и далее), а не +прыжок с места. Внимание на `can_climb_up` (seg005:0828): там у чомпера +ЕСТЬ спецкейс (`seq_73_climb_up_to_closed_gate` при взгляде ВПРАВО) — он у +нас портирован (`pop_map.c`, ветка `TILE_MIRROR || TILE_CHOMPER`), но именно +вокруг него и стоит копать. + +**Как ловить.** Брейкпоинт на резидентном `_kid_tick` с +`{printf "f=%d x=%d act=%d col=%d",b@Kid+0,b@Kid+1,b@Kid+6,b@Kid+4; g}` — +одна строка на кадр, адрес `_Kid` из `.sprinter-cc-roomtest/roomtest.map` +(после КАЖДОЙ пересборки другой). Плюс стоп-кадр `1` в момент отступа и +чтение `Kid` из памяти. Метод — memory `z80_profiling_method`. --- diff --git a/applications/PoP/roomtest/pop_ctrl.c b/applications/PoP/roomtest/pop_ctrl.c index a71445f..0fd3cc7 100644 --- a/applications/PoP/roomtest/pop_ctrl.c +++ b/applications/PoP/roomtest/pop_ctrl.c @@ -229,16 +229,18 @@ static void safe_step(void) if (distance) { Char.repeat = 1; seqtbl_offset_char((uint8_t)(distance + SEQ_STEP_BASE)); - } else if (pop_edge_type() == EDGE_WALL) { - /* вплотную к стене: маленький шаг-1 — check_bumped отскочит назад - * (шаг назад со звуком, как оригинал), НЕ seq_39 (шаг за край=падение). */ - Char.repeat = 1; - seqtbl_offset_char((uint8_t)(1 + SEQ_STEP_BASE)); - } else if (Char.repeat != 0) { + } else if (pop_edge_type() != EDGE_WALL && Char.repeat != 0) { Char.repeat = 0; seqtbl_offset_char(SEQ_44_STEP_ON_EDGE); } else { - seqtbl_offset_char(SEQ_39_UNSAFE_STEP); /* реальный обрыв (edge=CLOSER) */ + /* Вплотную к СТЕНЕ оригинал тоже уходит сюда — seq_39 (шаг 11). + * Раньше здесь стоял «маленький шаг-1»: у стены результат тот же + * (трасса живого SDLPoP в BUG-SEAM-PINGPONG: `safe_step(d=0) -> step, + * на первом dx(1) x=62 -> bump`), но у ЧОМПЕРА бампа нет — в + * разомкнутой фазе он не препятствие, — и оригинал уносит Кида на все + * 11 px, а мы шагали на один. Отсюда «микрошаг вместо нормального + * короткого шага» перед челюстями (приёмка 2026-08-08). */ + seqtbl_offset_char(SEQ_39_UNSAFE_STEP); } }