Оптимизация: логический кадр уложился в бюджет, цикл 4 растровых кадра -> 3
Главный цикл спейсится тремя gfx_wait_vsync, поэтому работа сверх 430 000 тактов стоит сразу целый лишний растровый кадр. Было 470 964, стало ~425 600 — игра быстрее на треть (16,7 логических кадров/с против 12,5). - pop_y_to_row: цепочка сравнений вместо (y+60)/63%4-1. ВАЖНО: медленный хвост вынесен в ОТДЕЛЬНУЮ функцию — SDCC видит одинаковое выражение в двух ветках и поднимает деление в вершину, быстрые возвраты не спасают. - col_from_x (pop_bg) и get_tile_div_mod (pop_map) — общие резидентные таблицы POP_TILE_DIV/POP_TILE_MOD в pop_tile.c (const банка из чужого банка не читается). - pop_fore_over_char: расширение окна считается арифметикой, а не перебором 10 колонок и 3 рядов (условие монотонно -> границы). Формулы сверены с прежним перебором перебором значений, расхождений нет. - pop_cd_touch: цикл по страницам развёрнут, x+w/y+h считаются один раз. Зовётся с каждого блита фона, стоил 6 846 тактов. - process_trobs: tp/10 и tp%10 у факелов — таблицей. - Пустой слот соперника (стража на сцене нет, на странице ничего не нарисовано) считается «тихим»: ни heal, ни вход в pop_char_draw, ни fore-проход. Приём для поиска делений: брейкпоинт на __divsint/__divuint/__divuchar с печатью адреса возврата (printf "%04X", w@(sp)). Профиль остатка — TASKS_OPEN.md#draw-cost. tests-host: 5/5. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -223,6 +223,13 @@ 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-проход и стоил
|
||||
* ~8 200 тактов из ничего (замер MAME, комната без стража). */
|
||||
if (who == POP_CH_OPP && Guard.charid == 0 &&
|
||||
!pop_cd[who].valid[p] && !pop_cd[who].ovalid[p])
|
||||
return 1;
|
||||
if (!pop_cd[who].valid[p]) return 0;
|
||||
if (pop_cd_dirty & (1 << p)) { /* фон правили — но задели ли нас? */
|
||||
int x0, y0, x1, y1;
|
||||
@@ -254,7 +261,10 @@ uint8_t pop_char_skip_mask(void) __banked
|
||||
* рядом — перерисовываем ОБОИХ. */
|
||||
uint8_t st = (uint8_t)(q0 ? POP_CH_KID : POP_CH_OPP);
|
||||
uint8_t mv = (uint8_t)(st ^ 1);
|
||||
if (pop_cd[mv].valid[p]) {
|
||||
/* valid[st] тоже: «тихий» слот, в котором на этой странице НИЧЕГО не
|
||||
* нарисовано (соперника на сцене нет), выесть невозможно, а bbox у
|
||||
* него мусорный — правило соседства к нему неприменимо. */
|
||||
if (pop_cd[st].valid[p] && pop_cd[mv].valid[p]) {
|
||||
int ax0, ay0, ax1, ay1, bx0, by0, bx1, by1;
|
||||
cd_bbox(st, p, &ax0, &ay0, &ax1, &ay1);
|
||||
cd_bbox(mv, p, &bx0, &by0, &bx1, &by1);
|
||||
|
||||
Reference in New Issue
Block a user