Разбор P14: он сводится к P4 (цене блита)
Fore-проход Кида в тяжёлой позиции (89 268) разложен зондами: вход + set_clip + char_footprint 10 872 арифметика границ окна 3 786 шов ворот + overlay-цикл 3 294 ЦИКЛ fore_tile ПО ТАЙЛАМ 67 854 76 % gate_over_char + хвост 3 462 Счётчик показал, что цикл обходит ВСЕГО 4 тайла, и 3 из них реально рисуют. То есть 67 854 — не перебор лишних тайлов и не проверки, а цена самих блитов переднего слоя: около четырёх блитов по ~16 000, где 6 765 на каждом — фиксированная накладная. Значит отдельной оптимизации fore-прохода почти нет: срезать можно цену блита (P4, ~27 000 из 67 854), char_footprint из физики (P10) и слияние двух трамплинов в банк 2 (~4 000). P4 поднят в очереди: он бьёт и по fore-проходу (4 блита), и по зелёной фазе (8 блитов) — то есть работает и в динамике, и в статике. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -670,7 +670,9 @@ static uint8_t tile_in_fclip(int row, int col)
|
||||
|
||||
static void fore_tile(int row, int col) /* передний слой одного тайла */
|
||||
{
|
||||
pop_dbg_rdmax[1]++; /* ВРЕМЕННО: сколько тайлов обошли */
|
||||
if (!tile_in_fclip(row, col)) return;
|
||||
pop_dbg_rdmax[2]++; /* ВРЕМЕННО: прошли окно клипа */
|
||||
/* draw_loose (seg008:0A38) — единственный кусок ТАЙЛА, который оригинал
|
||||
* кладёт В ОБЕ таблицы БЕЗУСЛОВНО: нижняя грань loose-плиты идёт и в
|
||||
* backtable, и в foretable. Значит передняя грань плиты рисуется ПОВЕРХ
|
||||
@@ -681,6 +683,7 @@ static void fore_tile(int row, int col) /* передний слой одно
|
||||
* кромке loose над дырой от соседней упавшей плиты). */
|
||||
ft_code = pop_tile_code_drawn(row, col); /* код тайла — ОДИН раз на тайл */
|
||||
if (!FORE_ANY[ft_code]) return; /* нечего класть в передний слой */
|
||||
pop_dbg_rdmax[3]++; /* ВРЕМЕННО: реально рисуем */
|
||||
ft_x = POP_COL_XH[col] * 8;
|
||||
ft_dmy = 63 * row + 62;
|
||||
if (row >= 0 && ft_code == 11)
|
||||
@@ -1000,6 +1003,8 @@ void pop_fore_over_char(const pop_char_t *ch, int obj_x, int obj_y,
|
||||
uint8_t frame = ch->frame, action = ch->action;
|
||||
pop_t_fclip_on = 1; /* окно = прямоугольник спрайта */
|
||||
char_footprint(obj_x, obj_y, w, h, ch->direction, ch->sword);
|
||||
pop_dbg_b1(); /* ЗАМЕР: char_footprint */
|
||||
pop_dbg_rdmax[1] = pop_dbg_rdmax[2] = pop_dbg_rdmax[3] = 0; /* ВРЕМЕННО */
|
||||
/* Футпринт считается по КАДРУ персонажа (char_x_left/right, seg006:1021)
|
||||
* и потому УЖЕ спрайта, а рядом с ним рисуются ещё клинок и «брызги»
|
||||
* удара — они уходят ВПЕРЁД-ВВЕРХ и запросто попадают в соседнюю
|
||||
@@ -1043,6 +1048,7 @@ void pop_fore_over_char(const pop_char_t *ch, int obj_x, int obj_y,
|
||||
}
|
||||
}
|
||||
}
|
||||
pop_dbg_b2(); /* ЗАМЕР: границы окна */
|
||||
cL = fp_cL; cR = fp_cR; cLraw = fp_cLraw;
|
||||
rT = fp_rT; rB = fp_rB; rTraw = fp_rTraw;
|
||||
/* set_objtile_at_char (seg006:1833): тайл, при обработке которого спрайт
|
||||
@@ -1109,6 +1115,7 @@ void pop_fore_over_char(const pop_char_t *ch, int obj_x, int obj_y,
|
||||
}
|
||||
}
|
||||
}
|
||||
pop_dbg_b3(); /* ЗАМЕР: оверлеи сделаны */
|
||||
/* draw_tile_fore (seg008:690) — foretable, рисуется ПОСЛЕ midtable, т.е.
|
||||
* ПОСЛЕ оверлеев выше: передняя грань колонны перекрывает скос пола
|
||||
* (floor_left_overlay), а не наоборот. Раньше fore шёл первым, и тёмный
|
||||
@@ -1125,6 +1132,7 @@ void pop_fore_over_char(const pop_char_t *ch, int obj_x, int obj_y,
|
||||
* Один вызов через трамплин на персонажа за кадр — не в тайловом цикле:
|
||||
* тайл-кандидат всегда ровно один, а fore-проход и так самый горячий
|
||||
* кусок кадра (memory pop_fore_layer_cost). */
|
||||
pop_dbg_b4(); /* ЗАМЕР: цикл fore_tile */
|
||||
if (pop_gate_over_char(ch)) {
|
||||
int8_t gr = ch->curr_row, gc = (int8_t)(ch->curr_col + 1);
|
||||
if (tile_in_fclip(gr, gc)) {
|
||||
|
||||
@@ -532,7 +532,6 @@ void pop_char_draw(uint8_t who) __banked
|
||||
* сдвинул. Здесь прошлый кадр уже точно надо стереть. Если heal в этом
|
||||
* кадре был, вызов бесплатен: valid/ovalid уже сняты. */
|
||||
cd_heal(who);
|
||||
pop_dbg_b1(); /* ЗАМЕР: cd_heal сделан */
|
||||
|
||||
s->cw = 0; /* окно fore-клипа: пусто, пока не нарисовали */
|
||||
s->fpw = 0; /* габарит кадра: нечего перекрывать */
|
||||
@@ -663,9 +662,7 @@ void pop_char_draw(uint8_t who) __banked
|
||||
* так что «убрать последние bcut строк вывода» = «не рисовать
|
||||
* первые bcut строк оригинала», а это ровно то, что просит
|
||||
* clip_char. */
|
||||
pop_dbg_b2(); /* ЗАМЕР: кадр загружен, геометрия готова */
|
||||
ct = pop_clip_char_top(fp_x, obj_y, w, h);
|
||||
pop_dbg_b3(); /* ЗАМЕР: clip_char_top (трамплин банк 4->3) */
|
||||
if (!pop_upside) {
|
||||
if (ct > top) {
|
||||
skip = ct - top;
|
||||
@@ -723,7 +720,6 @@ void pop_char_draw(uint8_t who) __banked
|
||||
(uint8_t)(vis_w == w ? 0 : vis_w));
|
||||
} else rows = 0;
|
||||
gfx_set_bank(GFX_BANK_NORMAL);
|
||||
pop_dbg_b4(); /* ЗАМЕР: спрайт выведен */
|
||||
/* heal чистит ТОЛЬКО нарисованное: иначе стирается кромка пола над
|
||||
* срезом (мусор/дыра в кладке на второй странице дабл-буфера). */
|
||||
s->x[dp] = bx + lskip; s->y[dp] = top;
|
||||
@@ -757,7 +753,6 @@ void pop_char_draw(uint8_t who) __banked
|
||||
* между ними (BUG-CHAR-STALE-PAGE). Без снимка слот просто не будет
|
||||
* «тихим», и следующий кадр начнётся с heal — старое сотрётся. */
|
||||
if (w && h) cd_sig_make(who, &cd_sig[who][dp]);
|
||||
pop_dbg_b5(); /* ЗАМЕР: pop_char_draw целиком */
|
||||
}
|
||||
|
||||
void pop_char_fore(uint8_t who) __banked
|
||||
|
||||
Reference in New Issue
Block a user