ФИКС РЕГРЕССИИ: start_chompers ломал play_seq через окно W0

Симптом (уровень 3, комната 22): после спуска с уступа Кид проваливался
СКВОЗЬ пол; при подъёме проскакивало лишнее движение вперёд с прыжком вверх.

Корень.  play_seq держит W0 замапленным на страницу данных Кида весь цикл и
читает seqtbl прямо через окно (макрос SEQ).  Вызов pop_start_chompers,
поставленный в dc0bd47 внутрь обработки SEQ_UP/SEQ_DOWN, лезет за тайлами
уровня: pop_level_access_begin/end — это ровно gfx_w0_map/unmap.  После
возврата цикл продолжал читать байткод из закрытого окна, то есть исполнял
мусор.

Фикс: SEQ_UP/SEQ_DOWN только взводят флаг, а pop_start_chompers зовётся
после выхода из цикла, когда W0 уже размаплен.  Эффект тот же — трасса
кадра не меняется, чомперы заводятся в том же кадре.

Заодно убрана вложенность того же рода внутри самого pop_start_chompers:
start_anim_chomper получает mod параметром, а не зовёт pop_trob_modif —
тот при первом обращении к комнате сам перемапливает W0 под её bg.

Остальные точки вызова (start_fall, land, enter_room) проверены: там окно
W0 не открыто.
This commit is contained in:
2026-08-08 20:00:01 +03:00
parent 073a6e0264
commit 1461ed5633
2 changed files with 23 additions and 5 deletions
+7 -3
View File
@@ -234,9 +234,9 @@ static uint8_t next_chomper_timing(uint8_t timing)
/* start_anim_chomper (seg007:08C7): запустить, только если стоит (0) или
* уже прошёл фазу размыкания (>=6). */
static void start_anim_chomper(uint8_t room, uint8_t tp, uint8_t modifier)
static void start_anim_chomper(uint8_t *mod, uint8_t room, uint8_t tp,
uint8_t modifier)
{
uint8_t *mod = pop_trob_modif(room);
uint8_t old = (uint8_t)(mod[tp] & 0x7F);
if (old == 0 || old >= 6) {
mod[tp] = modifier;
@@ -252,6 +252,9 @@ void pop_start_chompers(uint8_t room, int8_t row) __banked
uint8_t timing = 15, col, tp;
uint8_t *mod;
if ((uint8_t)row >= 3) return; /* вне комнаты — нечего */
/* pop_trob_modif ДО открытия окна: при первом обращении к комнате он
* сам лезет за её bg в страницу уровня, то есть перемапит W0 и закроет
* его — а мы внутри окна читаем тайлы. */
mod = pop_trob_modif(room);
pop_level_access_begin();
for (col = 0; col < 10; col++) {
@@ -259,7 +262,8 @@ void pop_start_chompers(uint8_t room, int8_t row) __banked
if ((pop_level_tile_raw(room, tp) & 0x1F) == TILE_CHOMP) {
uint8_t m = (uint8_t)(mod[tp] & 0x7F);
if (m == 0 || m >= 6) {
start_anim_chomper(room, tp, (uint8_t)(timing | (mod[tp] & 0x80)));
start_anim_chomper(mod, room, tp,
(uint8_t)(timing | (mod[tp] & 0x80)));
timing = next_chomper_timing(timing);
}
}