mob_tick_one в file-scope + снятие временной оснастки замеров
зелёная пик 423 558 -> 414 456 работа пик 793 266 -> 783 798 ПЕРИОД логического кадра в каскаде: было 5-6 растровых, стало РОВНО 4 mob_tick_one: рабочие переменные в file-scope (было 16 байт кадра и 99 обращений `-N(ix)`, стало 17) — то же лечение, что у draw_tile и blit_b_clip. Снята временная оснастка из ГОРЯЧИХ путей: шесть вызовов pop_dbg_b1..b6 в pop_blit_b (по ~65 такта каждый на КАЖДЫЙ блит), pop_dbg_kind/m16 и подсчёт состава кадра в pop_redraw_needed, pop_dbg_m13..m15 в pop_ceil_shake_draw. Сами пустышки в pop_state.c оставлены — вставить их обратно на один замер дешевле, чем заводить заново; как это делается, записано в docs/perf_l13_room23.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -80,13 +80,9 @@ void pop_set_redraw_above(uint8_t col, uint8_t kind, uint8_t pages) __banked
|
|||||||
void pop_redraw_needed(void) __banked
|
void pop_redraw_needed(void) __banked
|
||||||
{
|
{
|
||||||
uint8_t i, row = 0, col = 0, left = 0;
|
uint8_t i, row = 0, col = 0, left = 0;
|
||||||
uint8_t cnt[10], tot = 0; /* ВРЕМЕННО: состав кадра */
|
|
||||||
if (!rd_pending) return;
|
if (!rd_pending) return;
|
||||||
for (i = 0; i < 10; i++) cnt[i] = 0;
|
|
||||||
for (i = 0; i < NTILES; i++) {
|
for (i = 0; i < NTILES; i++) {
|
||||||
if (rd_cnt[i]) {
|
if (rd_cnt[i]) {
|
||||||
if (rd_kind[i] < 8) { cnt[rd_kind[i]]++; tot++; } /* ВРЕМЕННО */
|
|
||||||
pop_dbg_kind(rd_kind[i]); /* ВРЕМЕННО */
|
|
||||||
switch (rd_kind[i]) {
|
switch (rd_kind[i]) {
|
||||||
case POP_RD_SPIKE: pop_spike_redraw(row, col); break;
|
case POP_RD_SPIKE: pop_spike_redraw(row, col); break;
|
||||||
case POP_RD_LOOSE: pop_loose_shake_draw(row, col); break;
|
case POP_RD_LOOSE: pop_loose_shake_draw(row, col); break;
|
||||||
@@ -97,7 +93,6 @@ void pop_redraw_needed(void) __banked
|
|||||||
case POP_RD_CHOMP: pop_chomp_redraw(row, col); break;
|
case POP_RD_CHOMP: pop_chomp_redraw(row, col); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
pop_dbg_m16(); /* ВРЕМЕННО */
|
|
||||||
if (--rd_cnt[i]) left++;
|
if (--rd_cnt[i]) left++;
|
||||||
else rd_kind[i] = 0;
|
else rd_kind[i] = 0;
|
||||||
}
|
}
|
||||||
@@ -105,18 +100,11 @@ void pop_redraw_needed(void) __banked
|
|||||||
}
|
}
|
||||||
for (i = 0; i < NCOLS; i++) {
|
for (i = 0; i < NCOLS; i++) {
|
||||||
if (rda_cnt[i]) {
|
if (rda_cnt[i]) {
|
||||||
cnt[8 + (rda_kind[i] == POP_RDA_CEIL ? 0 : 1)]++; tot++; /* ВРЕМЕННО */
|
|
||||||
pop_dbg_kind((uint8_t)(8 + rda_kind[i])); /* ВРЕМЕННО */
|
|
||||||
if (rda_kind[i] == POP_RDA_CEIL) pop_ceil_shake_draw(i);
|
if (rda_kind[i] == POP_RDA_CEIL) pop_ceil_shake_draw(i);
|
||||||
else pop_ceil_bake_empty(i);
|
else pop_ceil_bake_empty(i);
|
||||||
pop_dbg_m16(); /* ВРЕМЕННО */
|
|
||||||
if (--rda_cnt[i]) left++;
|
if (--rda_cnt[i]) left++;
|
||||||
else rda_kind[i] = 0;
|
else rda_kind[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tot > pop_dbg_rdmax_tot) { /* ВРЕМЕННО: расклад пика */
|
|
||||||
pop_dbg_rdmax_tot = tot;
|
|
||||||
for (i = 0; i < 10; i++) pop_dbg_rdmax[i] = cnt[i];
|
|
||||||
}
|
|
||||||
rd_pending = left;
|
rd_pending = left;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -757,9 +757,7 @@ void pop_bake_forget(void) __banked
|
|||||||
void pop_ceil_shake_draw(int col) __banked
|
void pop_ceil_shake_draw(int col) __banked
|
||||||
{
|
{
|
||||||
int x = POP_COL_XH[col] * 8;
|
int x = POP_COL_XH[col] * 8;
|
||||||
pop_dbg_m13(); /* ЗАМЕР: вход pop_ceil_shake_draw */
|
|
||||||
pop_heal_off(x, 0, 64, CEIL_BAND_H);
|
pop_heal_off(x, 0, 64, CEIL_BAND_H);
|
||||||
pop_dbg_m14(); /* ЗАМЕР: heal сделан */
|
|
||||||
/* Пометка «фон трогали» — ОДНА на восстановленный прямоугольник: пока
|
/* Пометка «фон трогали» — ОДНА на восстановленный прямоугольник: пока
|
||||||
* стоит окно (ниже), pop_blit_b пометок не ставит. Область та же, что у
|
* стоит окно (ниже), pop_blit_b пометок не ставит. Область та же, что у
|
||||||
* heal'а, — он её и стирает. */
|
* heal'а, — он её и стирает. */
|
||||||
@@ -771,7 +769,6 @@ void pop_ceil_shake_draw(int col) __banked
|
|||||||
pop_t_win_clear();
|
pop_t_win_clear();
|
||||||
pop_t_clip_top = 0;
|
pop_t_clip_top = 0;
|
||||||
gfx_set_bank(GFX_BANK_NORMAL);
|
gfx_set_bank(GFX_BANK_NORMAL);
|
||||||
pop_dbg_m15(); /* ЗАМЕР: draw_tile сделан */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_ceil_bake_empty(int col) __banked
|
void pop_ceil_bake_empty(int col) __banked
|
||||||
@@ -1257,22 +1254,30 @@ static void mob_break_loose(mob_t *m)
|
|||||||
mob_spawn_copy(m);
|
mob_spawn_copy(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mob_t *mt_m;
|
||||||
|
static uint8_t mt_pg, mt_here;
|
||||||
|
|
||||||
static void mob_tick_one(mob_t *m, uint8_t pg)
|
static void mob_tick_one(mob_t *m, uint8_t pg)
|
||||||
{
|
{
|
||||||
uint8_t here;
|
/* Рабочие переменные — file-scope, не локали: у функции пять вызовов, и
|
||||||
if (!m->active && !m->clean) return;
|
* живой через них указатель на слот SDCC спиливал в кадр (16 байт, 99
|
||||||
here = (uint8_t)(m->room == pop_t_room);
|
* обращений `-N(ix)`). То же лечение, что у draw_tile и blit_b_clip.
|
||||||
|
* Реентерабельности нет и не требуется: единственный вызывающий —
|
||||||
|
* pop_loose_mob_tick, и слоты он обходит последовательно. */
|
||||||
|
mt_m = m; mt_pg = pg;
|
||||||
|
if (!mt_m->active && !mt_m->clean) return;
|
||||||
|
mt_here = (uint8_t)(mt_m->room == pop_t_room);
|
||||||
/* Стереть кусок, нарисованный на ЭТОЙ странице в прошлый раз (у каждой
|
/* Стереть кусок, нарисованный на ЭТОЙ странице в прошлый раз (у каждой
|
||||||
* страницы своя копия фона). Раньше коридор был фиксирован под ряд 2;
|
* страницы своя копия фона). Раньше коридор был фиксирован под ряд 2;
|
||||||
* плита-потолок падает через весь ряд 0, поэтому чистим по фактической
|
* плита-потолок падает через весь ряд 0, поэтому чистим по фактической
|
||||||
* прошлой позиции. */
|
* прошлой позиции. */
|
||||||
/* Гейта по `here` здесь БЫТЬ НЕ ДОЛЖНО: prev_y[pg] — это след, который
|
/* Гейта по `mt_here` здесь БЫТЬ НЕ ДОЛЖНО: prev_y[mt_pg] — это след, который
|
||||||
* кусок оставил ИМЕННО НА ЭТОЙ странице, и стереть его надо независимо
|
* кусок оставил ИМЕННО НА ЭТОЙ странице, и стереть его надо независимо
|
||||||
* от того, где кусок сейчас. Пока чистка была под `here`, кусок,
|
* от того, где кусок сейчас. Пока чистка была под `mt_here`, кусок,
|
||||||
* улетевший в комнату снизу (mob_down_a_row), навсегда оставлял себя
|
* улетевший в комнату снизу (mob_down_a_row), навсегда оставлял себя
|
||||||
* на одной из двух страниц дабл-буфера — «застрявшая плита», видимая
|
* на одной из двух страниц дабл-буфера — «застрявшая плита», видимая
|
||||||
* через кадр (BUG-MOB-STALE-PAGE). */
|
* через кадр (BUG-MOB-STALE-PAGE). */
|
||||||
if (m->prev_y[pg] != MOB_Y_NONE) {
|
if (mt_m->prev_y[mt_pg] != MOB_Y_NONE) {
|
||||||
/* Ширина/высота — по СЛЕДУ, а не по спрайту. Спрайт куска целиком
|
/* Ширина/высота — по СЛЕДУ, а не по спрайту. Спрайт куска целиком
|
||||||
* влезает в 64x32 (41: 32x13 с y-3, 42: 26x15 с x+32,y-1, 43: 32x3),
|
* влезает в 64x32 (41: 32x13 с y-3, 42: 26x15 с x+32,y-1, 43: 32x3),
|
||||||
* но mob_render рисует ещё и ЦЕЛЫЙ соседний тайл поверх правой части
|
* но mob_render рисует ещё и ЦЕЛЫЙ соседний тайл поверх правой части
|
||||||
@@ -1286,13 +1291,13 @@ static void mob_tick_one(mob_t *m, uint8_t pg)
|
|||||||
* ЗАДЕЛ: правильнее не перерисовывать соседа вовсе, а КЛИПОВАТЬ
|
* ЗАДЕЛ: правильнее не перерисовывать соседа вовсе, а КЛИПОВАТЬ
|
||||||
* правую часть куска — оригинал так и делает (add_mob_to_objtable,
|
* правую часть куска — оригинал так и делает (add_mob_to_objtable,
|
||||||
* seg007:1161: clip.right = 40). Тогда коридор вернётся к 64x32. */
|
* seg007:1161: clip.right = 40). Тогда коридор вернётся к 64x32. */
|
||||||
pop_heal_off(MOB_X0(m->x), m->prev_y[pg] - mob_heal_up, MOB_W, mob_heal_h);
|
pop_heal_off(MOB_X0(mt_m->x), mt_m->prev_y[mt_pg] - mob_heal_up, MOB_W, mob_heal_h);
|
||||||
m->prev_y[pg] = MOB_Y_NONE;
|
mt_m->prev_y[mt_pg] = MOB_Y_NONE;
|
||||||
}
|
}
|
||||||
if (!m->active) { m->clean--; return; }
|
if (!mt_m->active) { mt_m->clean--; return; }
|
||||||
/* гравитация (move_loose): ускорение до 29 */
|
/* гравитация (move_loose): ускорение до 29 */
|
||||||
if (m->speed < 29) m->speed += 3;
|
if (mt_m->speed < 29) mt_m->speed += 3;
|
||||||
m->y += m->speed;
|
mt_m->y += mt_m->speed;
|
||||||
/* move_loose (seg007:1126): низ куска пересёк границу своего ряда —
|
/* move_loose (seg007:1126): низ куска пересёк границу своего ряда —
|
||||||
* смотрим тайл этого ряда. Пусто/loose — валится дальше, пол —
|
* смотрим тайл этого ряда. Пусто/loose — валится дальше, пол —
|
||||||
* приземление (loose_land: debris + do_knock). Через LOOSE кусок именно
|
* приземление (loose_land: debris + do_knock). Через LOOSE кусок именно
|
||||||
@@ -1304,9 +1309,9 @@ static void mob_tick_one(mob_t *m, uint8_t pg)
|
|||||||
* плиты (1,6) и (1,7), на которые сверху сыплется гряда из комнаты 1.
|
* плиты (1,6) и (1,7), на которые сверху сыплется гряда из комнаты 1.
|
||||||
* Куски пролетали сквозь них правильно, а сами плиты оставались целыми и
|
* Куски пролетали сквозь них правильно, а сами плиты оставались целыми и
|
||||||
* нарисованными (найдено прогоном 2026-08-13). */
|
* нарисованными (найдено прогоном 2026-08-13). */
|
||||||
if (m->row < 3 && m->y < 226 && MOB_Y_BOUND[m->row + 1] <= m->y) {
|
if (mt_m->row < 3 && mt_m->y < 226 && MOB_Y_BOUND[mt_m->row + 1] <= mt_m->y) {
|
||||||
uint8_t t = mob_tile_at(m);
|
uint8_t t = mob_tile_at(mt_m);
|
||||||
if (t == 11) mob_break_loose(m);
|
if (t == 11) mob_break_loose(mt_m);
|
||||||
if (t == 0 || t == 11) {
|
if (t == 0 || t == 11) {
|
||||||
/* mob_down_a_row (seg007:1387): ряд ниже, а из НИЖНЕГО ряда —
|
/* mob_down_a_row (seg007:1387): ряд ниже, а из НИЖНЕГО ряда —
|
||||||
* в комнату СНИЗУ (y -= 192, ряд 0). Именно так кусок пролетает
|
* в комнату СНИЗУ (y -= 192, ряд 0). Именно так кусок пролетает
|
||||||
@@ -1315,55 +1320,55 @@ static void mob_tick_one(mob_t *m, uint8_t pg)
|
|||||||
* кнопку (2,7) комнаты 11. Раньше мы кусок на границе комнаты
|
* кнопку (2,7) комнаты 11. Раньше мы кусок на границе комнаты
|
||||||
* ГАСИЛИ и подменяли одним «переходом вниз» из главного цикла —
|
* ГАСИЛИ и подменяли одним «переходом вниз» из главного цикла —
|
||||||
* дальше первой комнаты он не летел (BUG-MOB-MULTIROOM). */
|
* дальше первой комнаты он не летел (BUG-MOB-MULTIROOM). */
|
||||||
m->row++;
|
mt_m->row++;
|
||||||
if (m->row >= 3) {
|
if (mt_m->row >= 3) {
|
||||||
m->y = (int16_t)(m->y - 192);
|
mt_m->y = (int16_t)(mt_m->y - 192);
|
||||||
m->row = 0;
|
mt_m->row = 0;
|
||||||
m->room = pop_room_link(m->room, 3 /* вниз */);
|
mt_m->room = pop_room_link(mt_m->room, 3 /* вниз */);
|
||||||
if (!m->room) { /* улетел из уровня — просто гаснет */
|
if (!mt_m->room) { /* улетел из уровня — просто гаснет */
|
||||||
m->active = 0; m->clean = 2; /* дочистить ОБЕ страницы */
|
mt_m->active = 0; mt_m->clean = 2; /* дочистить ОБЕ страницы */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
here = (uint8_t)(m->room == pop_t_room);
|
mt_here = (uint8_t)(mt_m->room == pop_t_room);
|
||||||
}
|
}
|
||||||
} else if (!here && pop_loose_exit) {
|
} else if (!mt_here && pop_loose_exit) {
|
||||||
/* Сигнал прошлой посадки в чужой комнате ещё не разобран (он
|
/* Сигнал прошлой посадки в чужой комнате ещё не разобран (он
|
||||||
* ОДИН на кадр) — держим кусок на границе ряда и садим следующим
|
* ОДИН на кадр) — держим кусок на границе ряда и садим следующим
|
||||||
* кадром, как это уже сделано для pop_loose_landed ниже. Без
|
* кадром, как это уже сделано для pop_loose_landed ниже. Без
|
||||||
* этого второй кусок затирал первый, и из нескольких плит,
|
* этого второй кусок затирал первый, и из нескольких плит,
|
||||||
* улетевших в одну дыру, щебень оставляла только одна (найдено
|
* улетевших в одну дыру, щебень оставляла только одна (найдено
|
||||||
* прогоном 2026-08-13, уровень 13). */
|
* прогоном 2026-08-13, уровень 13). */
|
||||||
m->y = MOB_Y_BOUND[m->row + 1];
|
mt_m->y = MOB_Y_BOUND[mt_m->row + 1];
|
||||||
} else if (!here) {
|
} else if (!mt_here) {
|
||||||
/* Приземление в ПОКИНУТОЙ комнате: рисовать нечего, но щебень и
|
/* Приземление в ПОКИНУТОЙ комнате: рисовать нечего, но щебень и
|
||||||
* КНОПКА под куском обязаны сработать — сигналим главному циклу
|
* КНОПКА под куском обязаны сработать — сигналим главному циклу
|
||||||
* комнатой и тайлом (loose_land, seg007:11E8, работает с
|
* комнатой и тайлом (loose_land, seg007:11E8, работает с
|
||||||
* curmob.room, а не с отрисованной). */
|
* curmob.room, а не с отрисованной). */
|
||||||
pop_loose_exit_room = m->room;
|
pop_loose_exit_room = mt_m->room;
|
||||||
pop_loose_exit = (uint8_t)(m->row * 10 + m->col + 1);
|
pop_loose_exit = (uint8_t)(mt_m->row * 10 + mt_m->col + 1);
|
||||||
/* clean = 2 даже для чужой комнаты: пока кусок летел, он мог
|
/* clean = 2 даже для чужой комнаты: пока кусок летел, он мог
|
||||||
* рисоваться в ЭТОЙ, и след остался на обеих страницах. */
|
* рисоваться в ЭТОЙ, и след остался на обеих страницах. */
|
||||||
m->active = 0; m->clean = 2;
|
mt_m->active = 0; mt_m->clean = 2;
|
||||||
return;
|
return;
|
||||||
} else if (pop_loose_landed) {
|
} else if (pop_loose_landed) {
|
||||||
/* сигнал прошлого приземления ещё не разобран (один за кадр) —
|
/* сигнал прошлого приземления ещё не разобран (один за кадр) —
|
||||||
* подержим кусок на границе и приземлим следующим кадром */
|
* подержим кусок на границе и приземлим следующим кадром */
|
||||||
m->y = MOB_Y_BOUND[m->row + 1];
|
mt_m->y = MOB_Y_BOUND[mt_m->row + 1];
|
||||||
} else {
|
} else {
|
||||||
m->y = MOB_Y_BOUND[m->row + 1];
|
mt_m->y = MOB_Y_BOUND[mt_m->row + 1];
|
||||||
pop_loose_landed = (uint8_t)(m->row * 10 + m->col + 1);
|
pop_loose_landed = (uint8_t)(mt_m->row * 10 + mt_m->col + 1);
|
||||||
m->active = 0; m->clean = 2; /* кусок исчез — на его месте debris */
|
mt_m->active = 0; mt_m->clean = 2; /* кусок исчез — на его месте debris */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Страховка: кусок ушёл ниже поля, не поймав границу ряда (в норме этого
|
/* Страховка: кусок ушёл ниже поля, не поймав границу ряда (в норме этого
|
||||||
* не бывает — mob_down_a_row уводит его в комнату снизу). Просто гаснет,
|
* не бывает — mob_down_a_row уводит его в комнату снизу). Просто гаснет,
|
||||||
* как у оригинала кусок в комнате 0 (move_loose: `speed = -2`). */
|
* как у оригинала кусок в комнате 0 (move_loose: `speed = -2`). */
|
||||||
if (m->y - 27 >= POP_PLAYFIELD_H) {
|
if (mt_m->y - 27 >= POP_PLAYFIELD_H) {
|
||||||
m->active = 0; m->clean = 2;
|
mt_m->active = 0; mt_m->clean = 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!here) return; /* чужая комната — считаем, но не рисуем */
|
if (!mt_here) return; /* чужая комната — считаем, но не рисуем */
|
||||||
/* Порядок «плита vs Kid». В оригинале объекты рисуются при обходе СВОИХ
|
/* Порядок «плита vs Kid». В оригинале объекты рисуются при обходе СВОИХ
|
||||||
* тайлов (redraw_needed_tiles: ряды 2,1,0; колонки 0..9), и только внутри
|
* тайлов (redraw_needed_tiles: ряды 2,1,0; колонки 0..9), и только внутри
|
||||||
* ОДНОГО тайла сортируются по obj_y (sort_curr_objs, seg008:1561: кто
|
* ОДНОГО тайла сортируются по obj_y (sort_curr_objs, seg008:1561: кто
|
||||||
@@ -1372,11 +1377,11 @@ static void mob_tick_one(mob_t *m, uint8_t pg)
|
|||||||
* поверх Kid, если его тайл идёт в обходе ПОЗЖЕ тайла Kid, а при
|
* поверх Kid, если его тайл идёт в обходе ПОЗЖЕ тайла Kid, а при
|
||||||
* совпадении тайлов — если он ниже по y. */
|
* совпадении тайлов — если он ниже по y. */
|
||||||
{
|
{
|
||||||
int8_t mrow = pop_y_to_row((int16_t)m->y); /* y_to_row_mod4 */
|
int8_t mrow = pop_y_to_row((int16_t)mt_m->y); /* y_to_row_mod4 */
|
||||||
uint8_t over;
|
uint8_t over;
|
||||||
if (mrow != pop_bg_obj_row) over = (mrow < pop_bg_obj_row); /* ряды идут 2,1,0 */
|
if (mrow != pop_bg_obj_row) over = (mrow < pop_bg_obj_row); /* ряды идут 2,1,0 */
|
||||||
else if (m->col != pop_bg_obj_col) over = (m->col > pop_bg_obj_col);
|
else if (mt_m->col != pop_bg_obj_col) over = (mt_m->col > pop_bg_obj_col);
|
||||||
else over = (m->y > pop_cd[POP_CH_KID].fpy);
|
else over = (mt_m->y > pop_cd[POP_CH_KID].fpy);
|
||||||
/* РИСОВАНИЯ ЗДЕСЬ БОЛЬШЕ НЕТ — только решение, в какой проход кусок
|
/* РИСОВАНИЯ ЗДЕСЬ БОЛЬШЕ НЕТ — только решение, в какой проход кусок
|
||||||
* пойдёт. Пока heal и вывод шли в одной итерации, heal СЛЕДУЮЩЕГО
|
* пойдёт. Пока heal и вывод шли в одной итерации, heal СЛЕДУЮЩЕГО
|
||||||
* куска срезал верхнюю кромку уже нарисованного предыдущего: на 13-м
|
* куска срезал верхнюю кромку уже нарисованного предыдущего: на 13-м
|
||||||
@@ -1384,7 +1389,7 @@ static void mob_tick_one(mob_t *m, uint8_t pg)
|
|||||||
* по y, и перекрытие гарантировано (артефакт «чёрный бар», найден
|
* по y, и перекрытие гарантировано (артефакт «чёрный бар», найден
|
||||||
* прогоном 2026-08-13, комната 23). Теперь сперва тикают ВСЕ куски
|
* прогоном 2026-08-13, комната 23). Теперь сперва тикают ВСЕ куски
|
||||||
* (то есть heal'ятся все), и только потом рисуются. */
|
* (то есть heal'ятся все), и только потом рисуются. */
|
||||||
m->defer = over;
|
mt_m->defer = over;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -503,10 +503,8 @@ void pop_blit_b(atlas_t *a, uint8_t idx, int x, int ybottom)
|
|||||||
pb_yb + POP_YOFF + 1 <= pop_t_fclip_ly0 ||
|
pb_yb + POP_YOFF + 1 <= pop_t_fclip_ly0 ||
|
||||||
pb_yb + POP_YOFF - 64 >= pop_t_fclip_ly1))
|
pb_yb + POP_YOFF - 64 >= pop_t_fclip_ly1))
|
||||||
return;
|
return;
|
||||||
pop_dbg_b1(); /* ВРЕМЕННО */
|
|
||||||
pb_img = (const uint8_t *)atlas_image(pb_a, pb_idx);
|
pb_img = (const uint8_t *)atlas_image(pb_a, pb_idx);
|
||||||
gfx_w0_map(pb_a->page);
|
gfx_w0_map(pb_a->page);
|
||||||
pop_dbg_b2(); /* ВРЕМЕННО */
|
|
||||||
/* Габарит читаем БАЙТАМИ. С `uint16_t pb_w = pb_img[0] | (pb_img[1] << 8)` SDCC
|
/* Габарит читаем БАЙТАМИ. С `uint16_t pb_w = pb_img[0] | (pb_img[1] << 8)` SDCC
|
||||||
* разворачивал каждую такую строку в два десятка IX-относительных
|
* разворачивал каждую такую строку в два десятка IX-относительных
|
||||||
* пересылок: 16-битные pb_w/pb_h не влезали в регистры, и функция целиком
|
* пересылок: 16-битные pb_w/pb_h не влезали в регистры, и функция целиком
|
||||||
@@ -547,23 +545,18 @@ void pop_blit_b(atlas_t *a, uint8_t idx, int x, int ybottom)
|
|||||||
/* pb_w<256 && pb_h<256 больше не проверяем — гарантировано типом. */
|
/* pb_w<256 && pb_h<256 больше не проверяем — гарантировано типом. */
|
||||||
if (pb_x >= 0 && pb_top >= 0 &&
|
if (pb_x >= 0 && pb_top >= 0 &&
|
||||||
pb_x + (int)pb_w <= 320 && pb_top + (int)pb_h <= 256) {
|
pb_x + (int)pb_w <= 320 && pb_top + (int)pb_h <= 256) {
|
||||||
pop_dbg_b6(); /* ВРЕМЕННО: пометка «шли в noclip» */
|
|
||||||
if (pop_upside) gfx_blit_noclip_vflip(pb_x, pb_top, pb_img);
|
if (pop_upside) gfx_blit_noclip_vflip(pb_x, pb_top, pb_img);
|
||||||
else gfx_blit_noclip(pb_x, pb_top, pb_img);
|
else gfx_blit_noclip(pb_x, pb_top, pb_img);
|
||||||
} else {
|
} else {
|
||||||
if (pop_upside) gfx_blit_part_vflip(pb_x, pb_top, pb_img, 0, 0, (int)pb_w, (int)pb_h);
|
if (pop_upside) gfx_blit_part_vflip(pb_x, pb_top, pb_img, 0, 0, (int)pb_w, (int)pb_h);
|
||||||
else gfx_blit_part(pb_x, pb_top, pb_img, 0, 0, (int)pb_w, (int)pb_h);
|
else gfx_blit_part(pb_x, pb_top, pb_img, 0, 0, (int)pb_w, (int)pb_h);
|
||||||
}
|
}
|
||||||
pop_dbg_b3(); /* ВРЕМЕННО */
|
|
||||||
pop_cd_touch(pb_x, pb_top, (int)pb_w, (int)pb_h);
|
pop_cd_touch(pb_x, pb_top, (int)pb_w, (int)pb_h);
|
||||||
pop_dbg_b4(); /* ВРЕМЕННО */
|
|
||||||
} else {
|
} else {
|
||||||
blit_b_clip(pb_img, pb_x, pb_top, pb_w, pb_h);
|
blit_b_clip(pb_img, pb_x, pb_top, pb_w, pb_h);
|
||||||
pop_dbg_b3(); pop_dbg_b4(); /* ВРЕМЕННО: медленный путь целиком в b3 */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gfx_w0_unmap();
|
gfx_w0_unmap();
|
||||||
pop_dbg_b5(); /* ВРЕМЕННО */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Блит getimage-блоба из ОБЫЧНОЙ памяти (W2), а не из EMM-страницы атласа:
|
/* Блит getimage-блоба из ОБЫЧНОЙ памяти (W2), а не из EMM-страницы атласа:
|
||||||
|
|||||||
Reference in New Issue
Block a user