FORE-DUP: передний слой рисуется дважды при перекрытии — заведено с разбором
Найдено вопросом пользователя. У нас fore-проход зовёт каждый рисующий по своему прямоугольнику, поэтому тайл, накрытый двумя объектами, рисуется два раза (Кид+отражение — всегда, Кид+соперник — весь ближний бой). В оригинале дубль невозможен по построению: redraw_at_char (seg003:0427) только ПОМЕЧАЕТ тайлы, а set_redraw_fore (seg007:0550) — redraw_frames_fore[tilepos] = frames, присваивание. Единственный обход тайлов рисует передний кусок один раз. Картинку не портит (прозрачный блит идемпотентен), тратит такты в самом горячем месте. Запись требует СНАЧАЛА замера: окно клипа вместо перебора тайлов в своё время дало 3.2x, и переход на пометки может часть вернуть. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -329,3 +329,55 @@ seg007:0101) и перерисовывает весь его слой `anim` п
|
|||||||
добавить в `trob_rcode`-проверку нужные коды и соответствующий вид пометки
|
добавить в `trob_rcode`-проверку нужные коды и соответствующий вид пометки
|
||||||
(`POP_RD_SPIKE` / `POP_RD_FLOOR`), а зелье — переставить в порядке обхода
|
(`POP_RD_SPIKE` / `POP_RD_FLOOR`), а зелье — переставить в порядке обхода
|
||||||
так, чтобы оно рисовалось ПОСЛЕ факела.
|
так, чтобы оно рисовалось ПОСЛЕ факела.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## FORE-DUP. Передний слой тайла рисуется ДВАЖДЫ при перекрытии объектов
|
||||||
|
|
||||||
|
Найдено пользователем 2026-08-10 (вопросом, а не по симптому — картинка
|
||||||
|
верная, страдают только такты).
|
||||||
|
|
||||||
|
**У нас.** Fore-проход зовёт КАЖДЫЙ рисующий по своему прямоугольнику:
|
||||||
|
`pop_char_fore` для слотов Кида и соперника, `pop_mirror_draw` для отражения.
|
||||||
|
Окно клипа (`pop_fore_set_clip`) у каждого своё. Если футпринты двух
|
||||||
|
объектов накрывают один тайл, его передний кусок рисуется два раза.
|
||||||
|
|
||||||
|
Когда случается:
|
||||||
|
- **Кид и отражение** — ВСЕГДА (стоят на одном тайле зеркала); этот случай
|
||||||
|
создан фиксом fore-прохода над отражением 2026-08-10;
|
||||||
|
- **Кид и соперник в одном тайле** — то есть весь ближний бой;
|
||||||
|
- Кид и падающий кусок плиты.
|
||||||
|
|
||||||
|
**Картинку не портит:** куски переднего слоя идут прозрачным блитом-копией,
|
||||||
|
операция идемпотентная. Портило бы при XOR/mono с накоплением — таких в
|
||||||
|
fore-слое нет.
|
||||||
|
|
||||||
|
**Такты тратит,** и в самом дорогом месте: fore-проход исторически самая
|
||||||
|
тяжёлая часть кадра (memory `pop_fore_layer_cost` — было 78 % кадра, окно
|
||||||
|
клипа и кэш кладки дали 3.2×).
|
||||||
|
|
||||||
|
**Как устроено в оригинале — дубль НЕВОЗМОЖЕН по построению.**
|
||||||
|
`redraw_at_char` (seg003:0427) ничего не рисует, а только помечает тайлы
|
||||||
|
своего прямоугольника:
|
||||||
|
|
||||||
|
```c
|
||||||
|
for (tile_row = x_top_row; tile_row <= char_bottom_row; ++tile_row)
|
||||||
|
for (tile_col = x_col_left; tile_col <= x_col_right; ++tile_col)
|
||||||
|
set_redraw_fore(get_tilepos(tile_col, tile_row), 1);
|
||||||
|
```
|
||||||
|
|
||||||
|
а `set_redraw_fore` (seg007:0550) — это `redraw_frames_fore[tilepos] = frames`,
|
||||||
|
ПРИСВАИВАНИЕ. Два персонажа на одном тайле оставят там ту же единицу, и
|
||||||
|
единственный обход тайлов нарисует передний кусок один раз.
|
||||||
|
|
||||||
|
**Что делать.** Механизм пометок у нас уже есть и прямо назван портом этой
|
||||||
|
архитектуры — `pop_redraw.h`. Fore-слой остался единственным местом на
|
||||||
|
прямом вызове. Приведение к оригиналу: `pop_char_fore`/`pop_mirror_draw`
|
||||||
|
вместо прохода ставят пометки, а один проход в конце кадра их разбирает.
|
||||||
|
|
||||||
|
**СНАЧАЛА ЗАМЕРИТЬ, потом чинить.** Это самый горячий путь, и окно клипа
|
||||||
|
(вместо перебора тайлов) в своё время дало 3.2× — переход на пометки может
|
||||||
|
часть этого вернуть назад. Замер: брейкпоинт на листьях fore-слоя со
|
||||||
|
счётчиком, сцена «бой в комнате 3 уровня 1» и «Кид на тайле зеркала,
|
||||||
|
ур. 4»; сравнить число нарисованных кусков с числом уникальных тайлов.
|
||||||
|
Если дубль мал — оставить как есть и закрыть запись.
|
||||||
|
|||||||
Reference in New Issue
Block a user