Закрыты BUG-GUARD-IX-1 и BUG-GATE-SEAM-ROW1 (уровень 4)
BUG-GUARD-IX-1 — «зависание» в бою со стражем. Не зависание: главный цикл крутился, а отладочная локаль frozen сама становилась ненулевой. Корень — у main затирался IX (0xBFFA -> 0xBF00), и все его локали адресовали живой стековый мусор. Затирал check_chomped_guard: coll_row() пишет по flags + scan_off, длину берёт из win_lo/win_hi, а scan_off выставляла только coll_scan_prepare() из пути Кида. Ряд стража писался по смещению Кида длиной стража и при Киде у правого края комнаты вылезал за flags[13] — прямо в сохранённый IX. Фикс: coll_scan_prepare() в начале get_row_collision_data(); заодно чинится расчёт (scan_left0 задаёт x колонок, чомпер-коллизия стража считалась по координатам Кида). На уровне 1 не проявлялось: бой идёт левее середины, запись оставалась внутри массива — данные были неверны молча. BUG-GATE-SEAM-ROW1 — решётка в шве не анимировалась. Плита комнаты 1 открывает ворота комнаты 8 в (1,9), видимые через левый шов, а change-driven редрой смотрел только m[9] (ряд 0) и перерисовывал жёстко draw_tile(0,0). На уровне 1 та же связка работала лишь потому, что решётка соседа стояла в (0,9). Фикс: сигнатура по всем трём рядам, маска изменившихся рядов в seam_rows (переживает оба кадра дабл-буфера), pop_room_redraw_seam_left(rows) перерисовывает только помеченные. Плюс ряд выше (changed | changed>>1): верх решётки (draw_tile_anim_topright, seg008:0568) рисует тайл над-справа от ворот, без этого чёрный треугольник над ними оставался статичным. Проверено пользователем в MAME (бой в комнате 18; анимация решётки в стартовой комнате), детекторы IX висели без починки и не сработали; make -C tests-host — все 5 наборов. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1636,8 +1636,23 @@ static void coll_row_bases(int8_t row)
|
||||
}
|
||||
}
|
||||
|
||||
/* Одиночный ряд во ВНЕШНИЙ массив (единственный вызывающий —
|
||||
* check_chomped_guard).
|
||||
*
|
||||
* coll_scan_prepare() тут ОБЯЗАТЕЛЕН, и это не перестраховка: coll_row
|
||||
* пишет по `flags + scan_off`, а число байт берёт из win_lo/win_hi. Без
|
||||
* prepare scan_off/scan_left0 остаются от ПРОШЛОГО окна (его считает
|
||||
* check_collisions для Кида), а окно тут уже своё, стражево. Когда
|
||||
* стражево окно шире или правее кидова, запись уезжает за границу
|
||||
* flags[COLL_N] — а сразу за ней в кадре check_chomped_guard лежит
|
||||
* СОХРАНЁННЫЙ IX. Затёртый младший байт превращал кадровый указатель
|
||||
* main (0xBFFA) в 0xBF00, и дальше main читал свои локали из чужого
|
||||
* стекового мусора: игра «зависала», потому что отладочный `frozen`
|
||||
* становился ненулевым (BUG-GUARD-IX-1). Заодно чинится и сам расчёт:
|
||||
* scan_left0 задаёт x колонок, и страж считался по координатам Кида. */
|
||||
static void get_row_collision_data(int8_t row, uint8_t *flags)
|
||||
{
|
||||
coll_scan_prepare();
|
||||
coll_row_bases(row);
|
||||
coll_row(flags);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user