Фикс мерцания торцов: копия запечки требует ОКНА КЛИПА

Регресс от копии второй страницы (5ef721e), найден пользователем: уровень 1,
комната 6, Кид на кнопке (0,2) — дрожит нижняя грань переднего торца кнопки.
На уровнях 1-3 то же по торцам плит, полов и кнопок.

Причина системная.  Полная запечка зовёт draw_tile, а тот рисует тайлы
ЦЕЛИКОМ, то есть пишет ШИРЕ прямоугольника бара.  bake_copy переносит на
вторую страницу ровно бар — и всё, что легло вне него, на второй странице
остаётся прежним.  Страницы расходятся, это и есть мерцание через кадр.

У полосы потолка (pop_ceil_bake_empty) проблемы не было: там окно клипа
поставлено ещё в G1, и запечка ограничена ровно копируемым прямоугольником.
А у pop_floor_bake окна не было — до этого оно трижды отвергалось как
невыгодное по скорости.

Фикс: окно клипа в pop_floor_bake возвращено, но теперь это условие
КОРРЕКТНОСТИ, а не оптимизация — записано в коде, чтобы его не сняли снова
«как убыточное».  Само окно стоит ~8 500 такта (клипованный путь дороже
быстрого на ~1 500 на каждом из 7,6 блитов), но открывает копию второй
страницы, экономящую ~145 000: пара «запечка + копия» вдвое дешевле двух
запечек.

Второй гард того же захода: pop_set_redraw / pop_set_redraw_above гасят слот
копии при ПЕРЕпометке тайла — у кнопки с идущим таймером связи пометка
обновляется каждый кадр, и картинка каждый раз другая, копия старой не
годится.  Объявления pop_bake_slot_reset* без __banked: pop_redraw.c и
pop_room.c в одном банке, трамплин не нужен.

Заодно починен скрипт рестарта MAME: он оставлял недоеденный запрос `exit` в
очереди IPC моста, и НОВЫЙ экземпляр его подхватывал и сразу выходил.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 17:04:09 +03:00
parent 18ee60eb69
commit 35b7cd5196
3 changed files with 50 additions and 14 deletions
+14
View File
@@ -47,3 +47,17 @@ void pop_wall_pattern_reset_b(void) __banked;
void pop_gate_back_b(uint8_t modl, int xh, int dby, int dmy) __banked;
#endif
/* ---- Слоты «первая запечка была на странице N» ----------------------- *
* bake_copy (pop_room.c) копирует готовый прямоугольник со второй страницы
* дабл-буфера вместо повторного пересчёта. Это верно ТОЛЬКО пока содержимое
* тайла между двумя кадрами не изменилось. У анимированных тайлов (кнопка с
* идущим таймером связи, ворота) пометка ОБНОВЛЯЕТСЯ каждый кадр, и картинка
* при этом другая — такой тайл обязан пересчитываться честно.
*
* Поэтому pop_set_redraw / pop_set_redraw_above гасят слот на ПЕРЕпометке
* (пометка пришла, когда счётчик ещё не отработал). Объявления БЕЗ __banked:
* pop_redraw.c и pop_room.c живут в одном банке, и трамплин тут не нужен. */
void pop_bake_slot_reset(uint8_t tilepos);
void pop_bake_slot_reset_above(uint8_t col);