Проверка «задет ли слот» без пяти аргументов: минус 3 684

pop_cd_hit принимает (p, x0, y0, x1, y1) — три последних идут стеком, и
функция целиком уезжает в IX-фрейм: 45 % её тактов на `-n(ix)` (asm).
А зовут её из cd_quiet до восьми раз за кадр.

Новый pop_cd_hit_slot(who, p) берёт координаты прямо из pop_cd, а само
сравнение вынесено в hit_rect с file-scope аргументами.  Первая попытка —
обёртка, которая внутри всё равно звала pop_cd_hit — не дала ничего
(1799 Z80 вместо 1318, то есть стало хуже), и это записано здесь, чтобы
не повторять: снимать аргументы со стека нужно у ТОГО, кто их читает.

asm на путь «спрайт + накладной»: было 1799 + 2x1318 = 4435 тактов Z80,
стало 1221 + 2x1009 = 3239 (-27 %).

Замер 11/15, лёгкая позиция: синяя 219 894 -> 218 052, циан 41 280 ->
39 438, работа кадра 442 662 -> 438 978.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 16:56:50 +03:00
parent f47d79ded8
commit e501982457
3 changed files with 50 additions and 11 deletions
+1 -11
View File
@@ -414,17 +414,7 @@ static uint8_t cd_quiet(uint8_t who, uint8_t p)
*
* Для skip_mask объединение по-прежнему годится: там вопрос «рядом ли
* два слота», и загрубление в бОльшую сторону безопасно. */
const pop_cdraw_t *q = &pop_cd[who];
int y0 = q->y[p] + POP_YOFF;
if (pop_cd_hit(p, q->x[p], y0,
q->x[p] + (int)q->w[p] - 1, y0 + (int)q->h[p] - 1))
return 0;
if (q->ovalid[p]) {
int oy = q->oy[p] + POP_YOFF;
if (pop_cd_hit(p, q->ox[p], oy,
q->ox[p] + (int)q->ow[p] - 1, oy + (int)q->oh[p] - 1))
return 0;
}
if (pop_cd_hit_slot(who, p)) return 0;
}
return cd_sig_same(who, p);
}