PoP: факелы и зелья (chtab_1) + быстрый блит фона gfx_blit_noclip
Графика chtab_1 (flame/sword/potion) — новый атлас pop_pot.atl: - склянка зелья берётся из chtab_1 (seg008 draw_tile_fore: id 12 малая / 13 большая при типах 2..4), а НЕ chtab_6 id 12 — res212 в VDUNGEON нет, каскад падал на VPALACE и рисовал кусок дворцовой декорации («мусорный объект» в комнате 5); - пакуем chtab_1 целиком (id 1..23): пламя, склянки, кадры пузырька; - MONO-блит (method_3_blit_mono, seg009:3040) красит спрайт цветом из ОБЩЕЙ 16-цветной палитры экрана — она добавлена в 0x30..0x3F, палитра chtab_1 в 0x40..0x4F; пузырёк пакуется силуэтом цвета 12 (красный), его маска — цвета 0; - в env-атлас добавлено основание факела (env 146, seg008:489 — рисует правый сосед); в статический render_room оно не попадало. Анимация (seg007 animate_torch/animate_potion + seg000:0B12 anim_tile_modif): при входе в комнату факелам и зельям задаётся случайная стартовая фаза и заводится trob; факел — get_torch_frame, пламя в ячейке ПРАВОГО соседа (xh = draw_xh+1, y = draw_main_y−40); зелье — bubble_next_frame по младшим 3 битам модификатора (старшие 5 = тип, при загрузке уровня modif <<= 3, seg009). Пламя и пузырёк не запекаются в фон: heal своей области + кадр поверх. Скорость пламени /2 — наш логический кадр короче игрового тика оригинала. Скорость отрисовки (профиль в MAME, кадр = 430 080 тактов): - замер показал, что цена блита почти НЕ зависит от размера — 13 288 тактов на спрайт 32×3 против 4 617 у линейного спрайтового ядра без клипа; платим за проход gfx_blit → gfx_blit_part → _gfx_blit_full; - в libbgi добавлен gfx_blit_noclip() — блит без клипа в ТЕКУЩЕМ банке (putsprite не годится: навязывает GFX_BANK_SPRITE, фону нужен TRANSPARENT ради ОЗУ-копии); pop_bg.blit_b уходит на него, когда спрайт целиком на экране и не нужен g_clip_top → ~2.9× на блит; - W3-скобку ставит САМА libbgi: из модуля с --w3 её вызывать нельзя — после _bgi_begin окно W3 занято видеобанком и код вызывающего исчезает (проявлялось белым экраном); - редрой шва больше не перерисовывает полосу потолка (bar начинается с POP_YOFF+3) — это удваивало стоимость блока при анимации решётки; - docs/size_optimization_plan.md §7–§8: замеры, сделанное и запас (батчинг W3-скобки, решётка одним спрайтом, лишние блиты). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -289,3 +289,47 @@ Kid, обычно 2–4 за кадр) рисовал ещё и `bottom_id` —
|
||||
`redraw_frames_above`; сузить до колонок, реально задетых спрайтом.
|
||||
6. `wall_pattern` внутри fore/overlay — тяжёлая (PRNG + до 4 блитов); проверить,
|
||||
не зовём ли её там, где оригинал ограничивается `wall_fram_main`.
|
||||
|
||||
---
|
||||
|
||||
## 8. Скорость отрисовки: замеры и запас (2026-07-27)
|
||||
|
||||
Профилирование в MAME (маркеры в порт 0xFE + `wpiset … totalcycles`, приём из
|
||||
memory `mame_mcp_bridge`). Кадр Sprinter = **430 080 тактов**.
|
||||
|
||||
**Стоимость блита почти НЕ зависит от размера** — платим за проход по цепочке
|
||||
`gfx_blit → gfx_blit_part → _gfx_blit_full` (16-битная арифметика, клип,
|
||||
пересчёт src, нарезка полос >256), а не за пиксели:
|
||||
|
||||
| путь (спрайт 32×3) | тактов |
|
||||
|---|---|
|
||||
| `gfx_blit` (общее ядро, с клипом) | 13 288 |
|
||||
| линейное спрайтовое ядро без клипа (`putsprite` при `gfx_sprite_clip(0)`) | 4 617 |
|
||||
|
||||
Отсюда `draw_tile(0,0)` тайла шва (9 блитов) стоил **183 690 тактов = 43 %
|
||||
кадра**; сам `bar` — только 13 308.
|
||||
|
||||
**СДЕЛАНО (шаг 1):** в libbgi добавлен `gfx_blit_noclip()`
|
||||
(`common/gfx_blit_noclip.c`, прототип в `include/gfx.h`) — блит без клипа в
|
||||
ТЕКУЩЕМ банке через линейное ядро; `pop_bg.blit_b` уходит на него, когда
|
||||
спрайт целиком на экране и не нужен `g_clip_top`. Выигрыш ~2.9× на каждом
|
||||
фоновом блите (подтверждено в MAME).
|
||||
**ВАЖНО:** W3-скобку (`_bgi_begin/_bgi_end`) ставит САМА libbgi — вызывать её
|
||||
из модуля, собранного с `--w3`, нельзя: после `_bgi_begin` окно W3 занято
|
||||
видеобанком и код вызывающего исчезает из адресного пространства (проверено:
|
||||
белый экран).
|
||||
|
||||
**ЗАПАС (шаг 2), когда перестанет хватать бюджета кадра:**
|
||||
|
||||
1. **Батчинг W3-скобки** — одна `_bgi_begin/_bgi_end` на весь `draw_tile`
|
||||
вместо скобки на блит; нужен публичный batch-API в libbgi (как у
|
||||
спрайтового движка). Осторожно: между begin/end стоит `DI` — длинная
|
||||
серия задержит кадровое прерывание.
|
||||
2. **Решётка ворот одним спрайтом** — `draw_gate_back` рисует бары по одному
|
||||
(`env 52`, до 7 блитов). Сгенерировать в атласе «столб решётки» (повтор
|
||||
бара на высоту тайла) и выводить одним `gfx_blit_part` с обрезкой по фазе
|
||||
`gate_bot_y & 7`: 7 блитов → 1.
|
||||
3. **Не перерисовывать статичные части шва** — грань ворот (env 47, 26×62),
|
||||
пол (41) и кромка (43) при анимации решётки не меняются; если стирать
|
||||
только полосу баров, уйдут ещё 3 блита из 9.
|
||||
4. См. также §7 (лишние блиты, которых нет в оригинале).
|
||||
|
||||
Reference in New Issue
Block a user