cd_quiet: сравнение снимка без построения структуры — минус 8 016
cd_sig_make СТРОИТ структуру из тринадцати полей в стековом кадре (то есть через -n(ix)), и только потом шёл побайтовый цикл сравнения. А зовётся проверка четыре раза за кадр: pop_char_skip_mask дважды, и в ней по два слота. Новый cd_sig_same сравнивает поля прямо с источником, с ранним выходом на первом расхождении — у двигающегося персонажа это обычно первое же поле. cd_sig_make остался: он нужен pop_char_draw, чтобы снимок записать. Замер 11/15, лёгкая позиция: участок «mob_draw + guard_over_kid + skip_mask» 47 883 -> 43 875, циан 59 265 -> 55 257, синяя 223 902 -> 219 753, работа кадра 464 796 -> 456 780. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -344,6 +344,34 @@ static void cd_sig_make(uint8_t who, cd_sig_t *g)
|
|||||||
g->dx = pop_cd[who].render_dx;
|
g->dx = pop_cd[who].render_dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Совпадает ли снимок страницы с ТЕКУЩИМ состоянием персонажа.
|
||||||
|
*
|
||||||
|
* Отдельно от cd_sig_make намеренно: тот СТРОИТ структуру, и для проверки
|
||||||
|
* это лишняя работа — тринадцать записей в стековый кадр (а значит через
|
||||||
|
* `-n(ix)`), после которых идёт побайтовый цикл сравнения. А зовут проверку
|
||||||
|
* четыре раза за кадр: pop_char_skip_mask дважды, и в ней по два слота.
|
||||||
|
* Здесь сравниваем поля прямо с источником, и первое же расхождение
|
||||||
|
* заканчивает работу — у ДВИГАЮЩЕГОСЯ персонажа это обычно первое поле. */
|
||||||
|
static uint8_t cd_sig_same(uint8_t who, uint8_t p)
|
||||||
|
{
|
||||||
|
const pop_char_t *ch = (who == POP_CH_KID) ? &Kid : &Guard;
|
||||||
|
const cd_sig_t *g = &cd_sig[who][p];
|
||||||
|
if (g->frame != ch->frame) return 0;
|
||||||
|
if (g->x != ch->x) return 0;
|
||||||
|
if (g->y != ch->y) return 0;
|
||||||
|
if (g->dir != ch->direction) return 0;
|
||||||
|
if (g->action != ch->action) return 0;
|
||||||
|
if (g->ccol != ch->curr_col) return 0;
|
||||||
|
if (g->crow != ch->curr_row) return 0;
|
||||||
|
if (g->sword != ch->sword) return 0;
|
||||||
|
if (g->charid != ch->charid) return 0;
|
||||||
|
if (g->room != ch->room) return 0;
|
||||||
|
if (g->hurt != (uint8_t)((who == POP_CH_KID) ? pop_kid_hurt : pop_guard_hurt))
|
||||||
|
return 0;
|
||||||
|
if (g->dx != pop_cd[who].render_dx) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Габарит слота на странице: спрайт + накладные (клинок/брызги). y —
|
/* Габарит слота на странице: спрайт + накладные (клинок/брызги). y —
|
||||||
* КОМНАТНЫЙ (как в pop_cd), перевод в экранный делает вызывающий. */
|
* КОМНАТНЫЙ (как в pop_cd), перевод в экранный делает вызывающий. */
|
||||||
static void cd_bbox(uint8_t who, uint8_t p, int *x0, int *y0, int *x1, int *y1)
|
static void cd_bbox(uint8_t who, uint8_t p, int *x0, int *y0, int *x1, int *y1)
|
||||||
@@ -366,9 +394,6 @@ static void cd_bbox(uint8_t who, uint8_t p, int *x0, int *y0, int *x1, int *y1)
|
|||||||
* ни перепроверяй за кадр. */
|
* ни перепроверяй за кадр. */
|
||||||
static uint8_t cd_quiet(uint8_t who, uint8_t p)
|
static uint8_t cd_quiet(uint8_t who, uint8_t p)
|
||||||
{
|
{
|
||||||
cd_sig_t g;
|
|
||||||
const uint8_t *a, *b;
|
|
||||||
uint8_t i;
|
|
||||||
/* Соперника на сцене нет и на ЭТОЙ странице от него ничего не осталось —
|
/* Соперника на сцене нет и на ЭТОЙ странице от него ничего не осталось —
|
||||||
* стирать и рисовать нечего, слот «тихий». Без этого пустой слот каждый
|
* стирать и рисовать нечего, слот «тихий». Без этого пустой слот каждый
|
||||||
* кадр честно проходил heal + вход в pop_char_draw + fore-проход и стоил
|
* кадр честно проходил heal + вход в pop_char_draw + fore-проход и стоил
|
||||||
@@ -401,11 +426,7 @@ static uint8_t cd_quiet(uint8_t who, uint8_t p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cd_sig_make(who, &g);
|
return cd_sig_same(who, p);
|
||||||
a = (const uint8_t *)&g; b = (const uint8_t *)&cd_sig[who][p];
|
|
||||||
for (i = 0; i < sizeof(cd_sig_t); i++)
|
|
||||||
if (*a++ != *b++) return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Запас вокруг габарита соседа: за кадр персонаж проходит заметно меньше
|
/* Запас вокруг габарита соседа: за кадр персонаж проходит заметно меньше
|
||||||
|
|||||||
Reference in New Issue
Block a user