Пики оставались навсегда: запечка фона консервировала выдвинутый кадр
Уровень 7, комната 19. Кнопка в (0,5) при нажатии зовёт pop_floor_bake, а тот перерисовывает и правого соседа — пики (0,6) — в банке, который пишет в ОЗУ-копию. Кадр брался живой, и выдвинутая пика оставалась в фоне: дальше heal возвращал её каждый кадр. В (0,7) чисто, потому что окно клипа запечки кончается на x=219, а колонка 7 начинается с 224. Флаг pop_t_bake_rest («в фон кладём покой») для этого и был, но читал его только pop_loose_frame. Кадр пик считался по месту в ЧЕТЫРЁХ слоях. Добавлен pop_spike_frame — порт get_spike_frame (SDLPoP seg008:08A0), которого у нас не было, — и все четыре слоя переведены на него; заодно позу покоя в запечке стал отдавать pop_chomp_pose. Одна точка лечит все пять путей запечки, включая вход в комнату. Резидент +28 Б, скорость не затронута. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2909,3 +2909,81 @@ case tiles_20_wall:
|
||||
после: изменения ровно в боксе `(344,199)-(358,206)`, 38 пикселей — сам
|
||||
артефакт и ничего кроме. На подземных уровнях изменений нет по построению:
|
||||
полоска целиком под `if (PALACE)`.
|
||||
|
||||
---
|
||||
|
||||
<a id="spike-baked"></a>
|
||||
## SPIKE-BAKED. Выдвинутые пики консервировались в фон и оставались навсегда
|
||||
|
||||
**Наблюдение (пользователь, 2026-08-18).** Уровень 7, комната 19. Пики стоят
|
||||
в `(0,6)` и из-за изометрии частью выходят в ячейку `(0,7)`. Выдвигаются
|
||||
корректно все; **прячутся корректно только те, что в `(0,7)`**, а в `(0,6)`
|
||||
остаются два вида мусора: куски остриёв на фоне дальней стены и белые точки в
|
||||
дырах пола. Пользователь сразу указал и на класс («первоначальная отрисовка
|
||||
фона, фикс не должен повлиять на скорость»), и на причину («в `(0,5)` не пол,
|
||||
а кнопка») — оба попадания верные.
|
||||
|
||||
**Артефакты, снятые в MAME на живом кадре с мусором.**
|
||||
|
||||
| что | значение |
|
||||
|-----|----------|
|
||||
| `pop_t_bg[6]` (живой modif пики) | `0x00` — пики УБРАНЫ |
|
||||
| `pop_t_fg[0..9]` | `03 04 13 0F 01 06 02 04 01 03` → `(0,5)` = `0x06` closer-кнопка, `(0,6)` = `0x02` spike |
|
||||
| мусор на экране | x 198..215, y 63..88 |
|
||||
|
||||
Модификатор нулевой, а пиксели пик есть — значит рисует их не живое
|
||||
состояние. И `pop_spike_redraw` каждый кадр делает `pop_heal_off(192, 62,
|
||||
64, 40)` — ровно поверх этого прямоугольника. Мусор переживает СВОЙ ЖЕ heal,
|
||||
а heal восстанавливает ОЗУ-копию фона: пики в ней и лежат.
|
||||
|
||||
**Корень.** Кнопка при смене состояния метится `POP_RD_FLOOR`, а это
|
||||
`pop_floor_bake(0,5)` — ЗАПЕЧКА, то есть рисование в банке, который пишет и в
|
||||
ОЗУ-копию. Запечка перерисовывает свой тайл **и правого соседа**:
|
||||
|
||||
```c
|
||||
pop_t_bake_rest = 1;
|
||||
draw_tile(row, col);
|
||||
if (col + 1 < 10) draw_tile(row, col + 1); /* <- это пики (0,6) */
|
||||
```
|
||||
|
||||
`pop_t_bake_rest` для того и заведён — «в фон кладём состояние ПОКОЯ», — но
|
||||
читал его ТОЛЬКО `pop_loose_frame`. Кадр пик считался прямо по месту,
|
||||
`(m & 0x80) ? 5 : m`, в ЧЕТЫРЁХ слоях, и ни один флага не спрашивал. Так
|
||||
выдвинутая пика попадала в ОЗУ-копию, и дальше heal возвращал её вечно.
|
||||
|
||||
Всё сходится численно. Окно клипа запечки — `x 160..219` (ширина 60 от
|
||||
кнопки), спрайт пики — `x 192..222`, `y 62..88`. Пересечение `x 192..219` —
|
||||
это и есть наблюдаемые 198..215; а `(0,7)` начинается с 224, за окном
|
||||
запечки, — потому там и чисто. Правая часть пики живёт только в видео-ОЗУ и
|
||||
честно стирается.
|
||||
|
||||
**Фикс (`pop_tile.c`).** Порт `get_spike_frame` (SDLPoP seg008:08A0), которого
|
||||
у нас не было, — плюс наша платформенная оговорка про запечку:
|
||||
|
||||
```c
|
||||
uint8_t pop_spike_frame(uint8_t m)
|
||||
{
|
||||
if (pop_t_bake_rest) return 0;
|
||||
return (uint8_t)((m & 0x80) ? 5 : m);
|
||||
}
|
||||
```
|
||||
|
||||
Все четыре слоя (`draw_tile_anim`, `draw_tile_anim_right` соседа, fore-проход,
|
||||
mid-оверлей) переведены на него. Заодно `pop_chomp_pose` тоже стал отдавать
|
||||
позу покоя в запечке: у чомпера ровно та же схема, а рядом с кнопкой он
|
||||
встретится так же легко.
|
||||
|
||||
Одна точка вместо четырёх лечит ВСЕ пять путей запечки сразу, включая
|
||||
`pop_room_draw` — вход в комнату с выдвинутыми пиками тоже консервировал бы их.
|
||||
|
||||
**Цена.** Резидент +28 Б, банки без изменений; в кадре — один `call` на слой,
|
||||
и только на тайлах-пиках. Скорость не затронута, как и предполагал
|
||||
пользователь.
|
||||
|
||||
**Проверка.** Пользователь прошёл сценарий вручную на пересобранном билде —
|
||||
мусора нет.
|
||||
|
||||
**Урок (записан в `pop_tile.h` над `pop_t_bake_rest`).** Флаг «сейчас
|
||||
запечка» обязана спрашивать САМА функция «кадр по модификатору», а не
|
||||
вызывающий слой: слоёв отрисовки у тайла четыре, и забыть один слишком легко.
|
||||
Для новой анимированной ловушки это теперь обязательный пункт.
|
||||
|
||||
Reference in New Issue
Block a user