safe_step по оригиналу + BUG-CHOMP-JUMP-1 в низкоприоритетные, T-2 закрыт
safe_step при distance == 0: возвращена ветка оригинала (seg005:0604) —
seq_39 (шаг 11) вместо нашего «шага-1». Для СТЕНЫ результат прежний: первый
же dx(1) даёт бамп, ровно как в трассе живого SDLPoP из BUG-SEAM-PINGPONG.
Для ЧОМПЕРА бампа нет (в разомкнутой фазе он не препятствие), и оригинал
уносит Кида на все 11 px — а мы шагали на один. Это и был «микрошаг вместо
нормального короткого шага» перед челюстями.
ВНИМАНИЕ на приёмке ур.1: это тот самый safe_step из BUG-SEAM-PINGPONG —
проверить комнату 6, осторожный шаг вплотную к воротам шва.
BUG-CHOMP-JUMP-1 (низкий, маловоспроизводим, на пререлиз): прыжок с места
вплотную к чомперу иногда даёт кадр с отступом назад. В запись сложено всё,
что выяснено: seq_3_standing_jump состоит ТОЛЬКО из положительных dx (значит
отступ даёт bumped, а не анимация); is_obstacle для чомпера у нас совпадает
с оригиналом; прямая трасса (UP+RIGHT одновременно) отката не показала —
главная гипотеза в порядке нажатий (↑ раньше → уводит в up_pressed с
выравниванием x). Там же метод ловли.
T-2 (idle-skip) закрыт — сделан шире, чем формулировался, как DRAW-COST
шаг 1 (a25ce58).
This commit is contained in:
@@ -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, отдельно не окупается.
|
||||
|
||||
<a id="t-2"></a>
|
||||
## 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)).
|
||||
<a id="bug-chomp-jump-1"></a>
|
||||
|
||||
## 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`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user