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:
@@ -12,6 +12,7 @@
|
||||
#include "pop_kid.h"
|
||||
#include "pop_guard.h" /* Guard/pop_gframe/CHARID_* — интерпретатор общий */
|
||||
#include "pop_bg.h" /* POP_YOFF — вертикальное центрирование */
|
||||
#include "_pop_draw.h" /* pop_onscreen_cols / pop_heal_fast */
|
||||
#include "pop_map.h" /* pop_clip_char_top (clip_char) */
|
||||
#include "pop_geom.h"
|
||||
#include "kid_data.h"
|
||||
@@ -108,7 +109,9 @@ void pop_kid_img_blit(uint8_t image, int x, int y)
|
||||
h = (uint16_t)(img[2] | ((uint16_t)img[3] << 8));
|
||||
/* Атласы Кида хранятся COLUMN-MAJOR (transpose_cols в pop_pack_kid —
|
||||
* ради бесплатного горизонтального флипа), поэтому блит обязан быть
|
||||
* колоночным. Row-major gfx_blit_noclip выдал бы марку транспонированной. */
|
||||
* колоночным. Row-major gfx_blit_noclip выдал бы марку транспонированной.
|
||||
* noclip БЕЗ проверки (CLIP-1): единственный вызывающий — полоса HP
|
||||
* (pop_gdraw.c), у неё координаты фиксированные и заведомо на экране. */
|
||||
if (w && h) gfx_blit_cols_part_noclip(x, y, img, 0, 0, 0);
|
||||
gfx_w0_unmap();
|
||||
}
|
||||
@@ -605,14 +608,20 @@ void kid_draw_splash(void)
|
||||
gfx_w0_unmap();
|
||||
}
|
||||
|
||||
/* Восстановить фон из теневой копии на месте ПРЕДЫДУЩЕГО кадра Kid. */
|
||||
/* Восстановить фон из теневой копии на месте ПРЕДЫДУЩЕГО кадра Kid.
|
||||
*
|
||||
* pop_heal_fast, а не голый gfx_heal: прямоугольник тут — это ровно тот
|
||||
* прямоугольник, который kid_draw нарисовал noclip-ядром, то есть в
|
||||
* подавляющем большинстве кадров он заведомо на экране. Клипающий путь
|
||||
* остаётся для straddle (kid_render_dx = ∓140) и падения ниже поля —
|
||||
* там координата реально уходит за экран. */
|
||||
void kid_heal(void)
|
||||
{
|
||||
uint8_t p = gfx_get_draw_page();
|
||||
if (kid_lvalid[p])
|
||||
gfx_heal(kid_lx[p], kid_ly[p] + POP_YOFF, kid_lw[p], kid_lh[p]); /* +YOFF: центрирование */
|
||||
if (kid_lvalid[p]) /* +YOFF: центрирование */
|
||||
pop_heal_fast(kid_lx[p], kid_ly[p] + POP_YOFF, kid_lw[p], kid_lh[p]);
|
||||
if (kid_ovalid[p])
|
||||
gfx_heal(kid_ox[p], kid_oy[p] + POP_YOFF, kid_ow[p], kid_oh[p]);
|
||||
pop_heal_fast(kid_ox[p], kid_oy[p] + POP_YOFF, kid_ow[p], kid_oh[p]);
|
||||
kid_lvalid[p] = kid_ovalid[p] = 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user