DRAW-COST шаг 1: пропуск неизменившегося персонажа — 210% -> 116% кадра
Персонаж, у которого с прошлой отрисовки ЭТОЙ страницы дабл-буфера не изменился ни один вход отрисовки, а фон в его прямоугольнике не трогали, уже нарисован правильно: heal, блит и fore-проход пропускаются целиком. Не спецкейс «мёртвый страж», а общее правило — покрывает и труп, и стоящего Кида, и ждущего стража. Механизм: снимок входов по страницам (pop_cdraw.c, cd_sig/cd_quiet) + позиционная метка «фон трогали вот здесь» (pop_cd_touch в резидентном pop_tile.c, зовёт сам pop_blit_b). Решение перепроверяется перед отрисовкой, а pop_char_draw страхуется собственным heal — если тик всё-таки сдвинул персонажа, прошлый кадр стирается там. Слоты рядом (32 px) — перерисовываем оба, иначе heal соседа выест кусок из «тихого». Метка обязана быть ПОЗИЦИОННОЙ: с флагом «фон трогали хоть где-то» выигрыш был ровно нулевым — факелы анимируются каждый кадр и гасили пропуск для всех сразу (597 684 такта, как без оптимизации). Замеры (MAME, брейкпоинты по totalcycles, бюджет кадра 430 000): комн. 1.3, труп стража, Кид стоит: 210 % -> 116 % (500 772 такта), ноль вызовов pop_heal_fast за кадр, весь фон — 2 блита (44 136); комн. 1.1, Кид стоит вдали от факелов: 404 112 (94 %), цикл 4 -> 3 кадра. Узкое место сместилось на ЛОГИКУ: 60 % кадра уходит на тик персонажей, которые СТОЯТ, ещё 28 % — на loose_tick + process_trobs в комнате без единой ловушки. Разбивка и план — TASKS_OPEN.md#draw-cost.
This commit is contained in:
@@ -335,6 +335,7 @@ void pop_spike_redraw(int row, int col) __banked
|
||||
* оставались бы; чёрная плита стирает старые бары в VRAM+ОЗУ-копию. */
|
||||
void pop_room_redraw_seam_left(void) __banked
|
||||
{
|
||||
pop_cd_touch(0, POP_YOFF + 3, 32, 62); /* bar мимо pop_blit_b (DRAW-COST) */
|
||||
gfx_set_bank(GFX_BANK_NORMAL);
|
||||
setfillstyle(SOLID_FILL, BLACK);
|
||||
/* Полосу кладки У ПОТОЛКА (ряд −1) НЕ трогаем: её низ на room-space y=2,
|
||||
@@ -369,6 +370,7 @@ void pop_ceil_shake_draw(int col) __banked
|
||||
void pop_ceil_bake_empty(int col) __banked
|
||||
{
|
||||
int x = POP_COL_XH[col] * 8;
|
||||
pop_cd_touch(x, POP_YOFF, 64, CEIL_BAND_H + 1); /* bar мимо pop_blit_b */
|
||||
gfx_set_bank(GFX_BANK_NORMAL);
|
||||
setfillstyle(SOLID_FILL, BLACK);
|
||||
bar(x, POP_YOFF, x + 63, POP_YOFF + CEIL_BAND_H); /* стереть плиту в ОЗУ-копии */
|
||||
@@ -441,6 +443,7 @@ void pop_potion_draw(int row, int col, uint8_t modif) __banked
|
||||
void pop_floor_bake(int row, int col) __banked
|
||||
{
|
||||
int x = POP_COL_XH[col] * 8;
|
||||
pop_cd_touch(x, POP_YOFF + 63 * row + 26, 60, 39); /* bar мимо pop_blit_b */
|
||||
int yb = POP_YOFF + 63 * row;
|
||||
/* Wipe СВОЕЙ ячейки + правой грани (заходит в соседа) + перерисовка пола.
|
||||
* НИЗ строго yb+64 (≈ низ передней грани пола): ниже — СТЕНА ряда ниже
|
||||
@@ -490,6 +493,7 @@ void pop_gate_redraw(int row, int col) __banked
|
||||
if (col + 1 > 9 || row < 0 || row > 2) return;
|
||||
x = POP_COL_XH[col + 1] * 8;
|
||||
yt = POP_YOFF + 63 * row;
|
||||
pop_cd_touch(x, yt + 3, 32, 62); /* bar мимо pop_blit_b (DRAW-COST) */
|
||||
gfx_set_bank(GFX_BANK_NORMAL);
|
||||
setfillstyle(SOLID_FILL, BLACK);
|
||||
bar(x, yt + 3, x + 31, yt + 64);
|
||||
@@ -521,6 +525,8 @@ void pop_loose_bake_empty(int row, int col) __banked
|
||||
* снова, и на второй странице дабл-буфера его не было → мерцание.
|
||||
* Тот же урок уже учтён в pop_floor_bake. */
|
||||
yb += POP_YOFF;
|
||||
/* bar идёт мимо pop_blit_b — пометить область самим (DRAW-COST). */
|
||||
pop_cd_touch(x, yb, 72, POP_YOFF + 63 * row + 66 - yb);
|
||||
gfx_set_bank(GFX_BANK_NORMAL);
|
||||
setfillstyle(SOLID_FILL, BLACK);
|
||||
bar(x, yb, x + 39, POP_YOFF + 63 * row + 65); /* сам тайл: +40 (кусок пола заходит вправо; сосед перерисуется) */
|
||||
@@ -716,8 +722,15 @@ static void mob_tick_one(mob_t *m, uint8_t pg)
|
||||
void pop_loose_mob_tick(void) __banked
|
||||
{
|
||||
uint8_t pg = gfx_get_draw_page() & 1, i;
|
||||
for (i = 0; i < MOB_MAX; i++)
|
||||
for (i = 0; i < MOB_MAX; i++) {
|
||||
/* Летящий кусок и его дочистка ходят по чужим пикселям СВОИМ heal'ом,
|
||||
* мимо pop_blit_b — пока он в кадре, персонажей пропускать нельзя
|
||||
* (DRAW-COST). Взводим ДО тика: кусок может исчезнуть прямо в нём, а
|
||||
* стереть себя ему всё равно надо будет. */
|
||||
if (mobs[i].active || mobs[i].clean)
|
||||
pop_cd_touch(MOB_X0(mobs[i].x), mobs[i].y - 27 + POP_YOFF, MOB_W, 64);
|
||||
mob_tick_one(&mobs[i], pg);
|
||||
}
|
||||
}
|
||||
|
||||
static void mob_render(mob_t *m, uint8_t pg)
|
||||
|
||||
Reference in New Issue
Block a user