P1: чомпер перерисовывался неизменной позой — минус 110 802 такта
Позиция заводилась с НЕПОЛНЫМ диагнозом. Я приписал 190 260 тактов
пометке от факела (пламя лежит в ячейке правого соседа, то есть поверх
чомпера, и запекается каждый кадр). Правка по этому диагнозу не дала
ничего: 769 002 против 768 684.
Зонд pop_dbg_kind показал факт: все 312 перерисовок прогона — вид
POP_RD_CHOMP, полная, и ни одной от факела. Собственная пометка чомпера
просто перебивала пометку соседа.
Настоящая причина нашлась сверкой с animate_chomper (seg007:0448).
Оригинал заканчивает её так:
if ((curr_modifier & 0x7F) < 6) redraw_at_trob();
то есть перерисовывает чомпер только пока фаза меньше 6 — пять кадров из
пятнадцати. Это не оптимизация оригинала, а следствие таблицы поз:
chomper_fram1 = {3,2,0,1,4,3,3}, и с фазы 5 до конца круга поза одна и та
же. Мы метили тайл каждый кадр, пока trob жив, а живёт он всё время, пока
Кид в том же ряду — то есть платили полный draw_tile плюс heal 32x64 за
неизменную картинку в двух третях кадров.
Сделано:
1. пометка только при фазе < 6; на фазе 5 — обе страницы дабл-буфера
(она последняя рисуемая, её поза обязана лечь на обе; вторую страницу
пометка догоняет в кадре фазы 6, где поза та же — CHOMP_FRAM1[6] == 3);
2. новый вид POP_RD_CHOMP_ANIM -> pop_chomp_anim_draw: три блита графики
чомпера поверх свежего пламени, без heal и без остальных слоёв — порт
ветки redraw_frames_anim (seg008:0211), где оригинал делает ровно
draw_tile_anim_topright / draw_tile_anim_right / draw_tile_anim и
никакого wipe;
3. приоритет полной перерисовки над anim в pop_set_redraw: у оригинала
это два независимых счётчика и full побеждает, а у нас вид один на
тайл, и без проверки исход решал бы порядок trob'ов в списке.
Обе половины работают — замер даёт 40 % полных перерисовок и 60 % лёгких.
Работа 768 684 -> 657 882 (медиана), зелёная 294 510 -> 183 420. В 40 %
кадров цена прежняя: там поза реально меняется, это честная работа.
Циан не сдвинулся ни на такт, то есть надежда P3 (Кид перестанет будиться
каждый кадр) пока не оправдалась — метки продолжают его будить.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -57,6 +57,14 @@
|
||||
`pop_dbg_rdmax_tot` = **1**: за кадр перерисовывается РОВНО ОДИН тайл, и
|
||||
стоит он все 190 260 тактов зелёной фазы.
|
||||
|
||||
> **ПОПРАВКА 2026-08-19 (после реализации P1).** Механизм ниже описан
|
||||
> верно, но ГЛАВНЫМ источником 190 260 тактов он НЕ был. Зонд
|
||||
> `pop_dbg_kind` показал, что все 312 перерисовок в прогоне — вид
|
||||
> `POP_RD_CHOMP` (полная), и ни одной от факела: собственная пометка
|
||||
> чомпера просто перебивала пометку соседа. Настоящая причина — в §6.
|
||||
> Урок ровно тот, что уже записан в `defer_unexplained_quirks`: механизм,
|
||||
> который правдоподобно объясняет цифру, ещё не доказан цифрой.
|
||||
|
||||
Цепочка:
|
||||
|
||||
1. `TORCH_ANIM_DIV = 1` — факел меняет кадр пламени КАЖДЫЙ логический кадр;
|
||||
@@ -103,6 +111,56 @@ heal 32×64 ≈ 33 700, значит на один `draw_tile` уходит ≈
|
||||
— та же болезнь (полный тайл там, где хватает полосы), но на другом
|
||||
материале.
|
||||
|
||||
## 6. Настоящая причина 190 260 тактов: перерисовка неизменной позы
|
||||
|
||||
Найдено при реализации P1, сверкой с `animate_chomper` (seg007:0448).
|
||||
Функция оригинала заканчивается так:
|
||||
|
||||
```c
|
||||
if ((curr_modifier & 0x7F) < 6) {
|
||||
redraw_at_trob();
|
||||
}
|
||||
```
|
||||
|
||||
То есть чомпер перерисовывается **только пока фаза меньше 6** — пять кадров
|
||||
из пятнадцати (`POP_CHOMPER_SPEED = 15`). Это не оптимизация оригинала, а
|
||||
следствие таблицы поз: `chomper_fram1 = {3,2,0,1,4,3,3}`, и начиная с фазы 5
|
||||
и до конца круга поза одна и та же — 3. Рисовать её десять кадров подряд
|
||||
значит рисовать ровно ту же картинку.
|
||||
|
||||
Мы же метили тайл БЕЗУСЛОВНО, каждый кадр, пока trob жив — то есть платили
|
||||
полный `draw_tile` плюс heal 32×64 за неизменную картинку в двух третях
|
||||
кадров. А trob у чомпера живёт, пока Кид в том же РЯДУ (`animate_chomper`
|
||||
снимает его только при фазе ≥ 6 и ушедшем Киде) — в 11/15 Кид стоит в (0,2),
|
||||
чомпер в (0,3), ряд один.
|
||||
|
||||
**Что сделано:**
|
||||
|
||||
1. пометка только при фазе < 6, и на фазе 5 — на ОБЕ страницы дабл-буфера
|
||||
(она последняя рисуемая, её поза обязана лечь на обе; вторую страницу
|
||||
пометка догоняет в кадре фазы 6, где поза та же самая);
|
||||
2. пометка от факела (`set_redraw_anim_right`) переведена на новый вид
|
||||
`POP_RD_CHOMP_ANIM` → `pop_chomp_anim_draw`: три блита графики чомпера
|
||||
поверх свежего пламени, без heal и без остальных слоёв — порт ветки
|
||||
`redraw_frames_anim` (seg008:0211);
|
||||
3. приоритет полной перерисовки над anim в `pop_set_redraw` — у оригинала
|
||||
это два независимых счётчика, и `full` побеждает.
|
||||
|
||||
**Результат** (замер, 552 кадра): полная перерисовка теперь в **40 %**
|
||||
кадров, лёгкий возврат челюстей — в 60 %. Зелёная фаза: 291 888 в дорогом
|
||||
кадре против 183 414 в дешёвом.
|
||||
|
||||
| | работа | зелёная |
|
||||
|---|---:|---:|
|
||||
| до P1 | 768 684 | 294 510 |
|
||||
| после P1, медиана | **657 882** | **183 420** |
|
||||
| после P1, дорогой кадр (40 %) | 765 936 | 291 888 |
|
||||
|
||||
**−110 802 на медиане** при ожидании −160 000. Разница в том, что 40 %
|
||||
кадров по-прежнему платят полную цену: там поза реально меняется, и это уже
|
||||
не лишняя работа, а честная. Дальше её можно резать только раскладом
|
||||
`draw_tile` на части (P7) или сужением heal (P8).
|
||||
|
||||
## 5. Журнал правок по этой сцене
|
||||
|
||||
| дата | правка | работа | синяя | зелёная | циан |
|
||||
@@ -111,6 +169,8 @@ heal 32×64 ≈ 33 700, значит на один `draw_tile` уходит ≈
|
||||
| 2026-08-19 | **P5**: гейты холостого хода в `pop_loose_tick` | **767 928** | 285 864 | 294 384 | 187 764 |
|
||||
| | | −33 840 | −7 374 | −26 532 | +6 |
|
||||
| 2026-08-19 | зонды для замера P2/P6 (временные) | 768 684 | 286 518 | 294 510 | 187 761 |
|
||||
| 2026-08-19 | **P1**: чомпер — перерисовка только при фазе < 6 (медиана) | **657 882** | 286 503 | 183 420 | 187 761 |
|
||||
| | | −110 802 | −15 | −111 090 | 0 |
|
||||
|
||||
Оснастка P2/P6 стоит 756 тактов на кадр — замеры до и после сопоставимы.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user