fore-проход: ранний выход по коду тайла + контекст тайла один раз (эффект нулевой)
Сближение с SDLPoP, замером НЕ подтвердилось — фиксирую как есть. - FORE_ANY[32]: есть ли у кода тайла хоть что-то в переднем слое. Порт ранней проверки оригинала `if (tile_table[curr_tile].fore_id == 0) return;` из начала ветки default в draw_tile_fore (seg008:0D15), расширенной нашими спецслучаями (стена 20, пики 2, чомпер 0x12, нижняя грань loose 11 — они рисуются мимо fore_id). Была в самом конце цепочки сравнений. - ft_code/ft_x/ft_dmy: контекст тайла считается один раз на тайл, как глобалы curr_tile/draw_xh/draw_main_y у load_curr_and_left_tile. Код тайла читался дважды (fore_tile и снова fore_only_tile), координаты — в каждом листе. Замер (Кид на 2,4 в щебне, MAME): pop_fore_over_char 58 764 -> 58 866, то есть в пределах шума. Ранний выход не срабатывает — в футпринте Кида тайлы почти всегда С передним слоем; снятое второе чтение кода съедено проверкой FORE_ANY и записью контекста. Отрисовка не изменилась: щебёнка блитится теми же параметрами (x=150 y=208 sx=22 w=10 h=2). Где время на самом деле: ~16 000 тактов фиксированных накладных на КАЖДЫЙ блит фона независимо от размера (atlas_image + gfx_w0_map + чтение w/h через окно 0 + арифметика клипа + unmap). Блит щебёнки 10×2 обходится в 21 168, факел 16×22 — в 31 000 при самом gfx_blit_noclip 8 706. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -318,15 +318,46 @@ static int8_t col_from_x(int xpos) /* get_tile_div_mod: колонка (
|
|||||||
|
|
||||||
#define y_to_row(y) pop_y_to_row((int16_t)(y)) /* общий (pop_geom) */
|
#define y_to_row(y) pop_y_to_row((int16_t)(y)) /* общий (pop_geom) */
|
||||||
|
|
||||||
|
/* Контекст ТЕКУЩЕГО тайла прохода: код, левый край, база Y. Порт глобалов
|
||||||
|
* оригинала (curr_tile / draw_xh / draw_main_y, которые load_curr_and_left_tile
|
||||||
|
* ставит ОДИН раз на тайл, seg008 redraw_needed_tiles) — все рисовальщики
|
||||||
|
* читают их, а не считают заново. У нас код тайла читался дважды за тайл
|
||||||
|
* (в fore_tile и снова тут), а координаты — в каждом листе. */
|
||||||
|
static uint8_t ft_code;
|
||||||
|
static int ft_x, ft_dmy;
|
||||||
|
|
||||||
|
/* Есть ли у кода тайла ХОТЬ ЧТО-ТО в переднем слое. Порт ранней проверки
|
||||||
|
* оригинала — `id = tile_table[curr_tile].fore_id; if (id == 0) return;`
|
||||||
|
* в начале ветки default у draw_tile_fore (seg008:0D15), — расширенной
|
||||||
|
* нашими спецслучаями: стена (20), пики (2), чомпер (0x12) и нижняя грань
|
||||||
|
* loose (11) рисуются мимо fore_id.
|
||||||
|
*
|
||||||
|
* Была в самом КОНЦЕ цепочки: до неё успевали отработать чтение кода тайла
|
||||||
|
* и все сравнения спецслучаев. Замер в MAME: fore-проход стоил 58 764 такта
|
||||||
|
* ради одного блита 10×2, а в позиции без переднего слоя — 112 758 тактов
|
||||||
|
* и ноль блитов. */
|
||||||
|
static const uint8_t FORE_ANY[32] = {
|
||||||
|
/* 00 empty */ 0, /* 01 floor */ 0, /* 02 spike */ 1, /* 03 pillar */ 1,
|
||||||
|
/* 04 gate */ 1, /* 05 stuck */ 0, /* 06 closebtn */ 0, /* 07 doortopf */ 1,
|
||||||
|
/* 08 bpbot */ 1, /* 09 bptop */ 1, /* 0A potion */ 1, /* 0B loose */ 1,
|
||||||
|
/* 0C dtop */ 1, /* 0D mirror */ 1, /* 0E debris */ 1, /* 0F openbtn */ 0,
|
||||||
|
/* 10 ldL */ 0, /* 11 ldR */ 0, /* 12 chomper */ 1, /* 13 torch */ 0,
|
||||||
|
/* 14 wall */ 1, /* 15 skeleton */ 0, /* 16 sword */ 0, /* 17 balcL */ 0,
|
||||||
|
/* 18 balcR */ 0, /* 19 lattpil */ 1, /* 1A lattdown */ 1, /* 1B lattsm */ 1,
|
||||||
|
/* 1C lattl */ 1, /* 1D lattr */ 1, /* 1E debristo */ 1, /* 1F — */ 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Контекст ft_* обязан быть проставлен вызывающим. */
|
||||||
static void fore_only_tile(int row, int col)
|
static void fore_only_tile(int row, int col)
|
||||||
{
|
{
|
||||||
/* Нажатая кнопка → пол/stuck (get_tile_to_draw), иначе поверх Kid лезет
|
/* Нажатая кнопка → пол/stuck (get_tile_to_draw) — это уже учтено в ft_code
|
||||||
* передняя грань КНОПКИ. */
|
* (его ставит pop_tile_code_drawn), иначе поверх Kid лезет передняя грань
|
||||||
uint8_t code = pop_tile_code_drawn(row, col);
|
* КНОПКИ. */
|
||||||
|
uint8_t code = ft_code;
|
||||||
const piece *t;
|
const piece *t;
|
||||||
|
int x = ft_x, dmy = ft_dmy;
|
||||||
|
if (!FORE_ANY[code]) return; /* ранний выход, как в оригинале */
|
||||||
t = &pop_tile_table[code];
|
t = &pop_tile_table[code];
|
||||||
int x = POP_COL_XH[col] * 8;
|
|
||||||
int dmy = 63 * row + 62;
|
|
||||||
if (code == 20) {
|
if (code == 20) {
|
||||||
pop_wall_b(POP_WALL_FRAM_MAIN[pop_wall_modifier(row, col)], x, dmy);
|
pop_wall_b(POP_WALL_FRAM_MAIN[pop_wall_modifier(row, col)], x, dmy);
|
||||||
wall_pattern(row, col, 1);
|
wall_pattern(row, col, 1);
|
||||||
@@ -375,6 +406,8 @@ static void ceil_over_kid_tile(int col)
|
|||||||
}
|
}
|
||||||
if (code == 11) /* draw_loose(1): плита-потолок */
|
if (code == 11) /* draw_loose(1): плита-потолок */
|
||||||
pop_env_b(POP_LOOSE_FRAM_BOTTOM[pop_loose_frame(pop_ceil_modif[col])], x, dby);
|
pop_env_b(POP_LOOSE_FRAM_BOTTOM[pop_loose_frame(pop_ceil_modif[col])], x, dby);
|
||||||
|
ft_code = pop_tile_code_drawn(-1, col); /* контекст тайла для листа */
|
||||||
|
ft_x = x; ft_dmy = 63 * (-1) + 62;
|
||||||
fore_only_tile(-1, col); /* draw_tile_fore */
|
fore_only_tile(-1, col); /* draw_tile_fore */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,9 +438,13 @@ static void fore_tile(int row, int col) /* передний слой одно
|
|||||||
* висящего/подтягивающегося Kid видны НАД плитой, а тело уходит ЗА неё.
|
* висящего/подтягивающегося Kid видны НАД плитой, а тело уходит ЗА неё.
|
||||||
* Без этого Kid лез на плиту «с переднего края» (комната 12: вис на
|
* Без этого Kid лез на плиту «с переднего края» (комната 12: вис на
|
||||||
* кромке loose над дырой от соседней упавшей плиты). */
|
* кромке loose над дырой от соседней упавшей плиты). */
|
||||||
if (row >= 0 && pop_tile_code_drawn(row, col) == 11)
|
ft_code = pop_tile_code_drawn(row, col); /* код тайла — ОДИН раз на тайл */
|
||||||
|
if (!FORE_ANY[ft_code]) return; /* нечего класть в передний слой */
|
||||||
|
ft_x = POP_COL_XH[col] * 8;
|
||||||
|
ft_dmy = 63 * row + 62;
|
||||||
|
if (row >= 0 && ft_code == 11)
|
||||||
pop_env_b(POP_LOOSE_FRAM_BOTTOM[pop_loose_frame(pop_loose_modif[row * 10 + col])],
|
pop_env_b(POP_LOOSE_FRAM_BOTTOM[pop_loose_frame(pop_loose_modif[row * 10 + col])],
|
||||||
POP_COL_XH[col] * 8, 63 * row + 65);
|
ft_x, ft_dmy + 3);
|
||||||
/* draw_tile_fore (seg008:690) — ТОЛЬКО add_foretable-часть. Раньше здесь
|
/* draw_tile_fore (seg008:690) — ТОЛЬКО add_foretable-часть. Раньше здесь
|
||||||
* рисовалась ещё и передняя кромка пола (bottom_id) «чтобы перекрывала
|
* рисовалась ещё и передняя кромка пола (bottom_id) «чтобы перекрывала
|
||||||
* Kid», но в оригинале bottom идёт через draw_tile_bottom в backtable
|
* Kid», но в оригинале bottom идёт через draw_tile_bottom в backtable
|
||||||
|
|||||||
Reference in New Issue
Block a user