CLIP-1: heal Кида и стража — линейным ядром, когда клип не нужен
kid_heal/pop_guard_heal звали gfx_heal всегда, хотя рисуют ровно тот прямоугольник, который блит в большинстве кадров кладёт noclip-ядром. Все три места heal (+ heal_off фона) сведены к общему pop_heal_fast. Замер в MAME, счётчики totalcycles на входах kid_heal и kid_tick (вся группа heal за кадр), комната 1, Кид стоит: клипающее ядро 26 200 тактов/кадр (149 кадров) noclip 15 848 тактов/кадр (239 кадров) −10 352 такта, −39.5 %. A/B в одном прогоне: вторая половина снята с пропатченным в памяти условием (jr nz → jr), то есть на той же геометрии. Размер СУММАРНО −362 Б: _CODE +17, BANK2 −116 (свободно 2708 — это тесный банк из рисков levels_plan §5), BANK3 −263, BANK4 без изменений. Грабли по дороге: первым заходом хелпер был static inline в pop_bg.h — SDCC 4.5 И встраивает тело (181 Б) в каждый вызов, И оставляет копию в каждом TU, который видит заголовок. pop_guard_heal раздулся с ~60 до 663 Б, итого +1091 Б в _CODE и +636 Б в банке стража. Отсюда pop_draw.c: обычная функция в резиденте W1, из банков это прямой call без трамплина. pop_room_clip_borders оставлен клипающим осознанно (320 не лезет в 8 бит, гейт border_dirty редкий) — причина записана в коде. Проверено визуально: ходьба, прыжок, спуск, позиция за решёткой шва (straddle — там работает клипающий фолбэк) — артефактов нет. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "pop_bg.h"
|
||||
#include "_pop_draw.h" /* pop_onscreen_cols / pop_heal_fast */
|
||||
#include "pop_state.h"
|
||||
#include "pop_geom.h"
|
||||
#include "pop_level.h" /* pop_doorlink2 — состояние нажатия кнопки */
|
||||
@@ -135,18 +136,12 @@ static void blit_b(atlas_t *a, uint8_t idx, int x, int ybottom)
|
||||
gfx_w0_unmap();
|
||||
}
|
||||
|
||||
/* heal в room-space (со сдвигом POP_YOFF) — все heal слоя фона/loose. */
|
||||
/* heal в room-space (со сдвигом POP_YOFF) — все heal слоя фона/loose.
|
||||
* Выбор ядра (noclip / клипающее) — общий с Кидом и стражем, pop_heal_fast
|
||||
* в pop_bg.h. */
|
||||
static void heal_off(int x, int y, int w, int h)
|
||||
{
|
||||
int sy = y + POP_YOFF;
|
||||
/* Без клипа — линейным ядром (~2.9×, как gfx_blit_noclip): общий
|
||||
* gfx_heal платит за клип/16-бит/split, а не за пиксели (замер:
|
||||
* 11 658 тактов на heal 22×22). */
|
||||
if (x >= 0 && sy >= 0 && w > 0 && h > 0 && w < 256 && h < 256 &&
|
||||
x + w <= 320 && sy + h <= 256)
|
||||
gfx_heal_noclip(x, sy, (uint8_t)w, (uint8_t)h);
|
||||
else
|
||||
gfx_heal(x, sy, w, h);
|
||||
pop_heal_fast(x, y + POP_YOFF, w, h);
|
||||
}
|
||||
|
||||
/* Область, куда в этом кадре рисовался ОВЕРЛЕЙ (не футпринт fore, а
|
||||
@@ -1190,6 +1185,11 @@ void pop_room_clip_borders(void) __banked
|
||||
{
|
||||
if (!border_dirty) return;
|
||||
border_dirty--;
|
||||
/* ОСТАЁТСЯ клипающим осознанно (CLIP-1, 2026-08-01): полоса шириной 320
|
||||
* не лезет в 8-битный параметр noclip-ядра, а разбивать её на два куска
|
||||
* по 160 нет смысла — гейт border_dirty пускает сюда только в кадрах
|
||||
* падения/выхода за поле, и выигрыш (~2×5.6 К тактов подготовки) там
|
||||
* тонет в цене самих 320×28 пикселей. Не «оптимизировать» повторно. */
|
||||
gfx_heal(0, 0, 320, POP_YOFF); /* верхний борт */
|
||||
gfx_heal(0, POP_CLIP_BOTTOM, 320, 256 - POP_CLIP_BOTTOM);/* статус-полоса + нижний борт */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user