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) */
|
||||
|
||||
/* Контекст ТЕКУЩЕГО тайла прохода: код, левый край, база 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)
|
||||
{
|
||||
/* Нажатая кнопка → пол/stuck (get_tile_to_draw), иначе поверх Kid лезет
|
||||
* передняя грань КНОПКИ. */
|
||||
uint8_t code = pop_tile_code_drawn(row, col);
|
||||
/* Нажатая кнопка → пол/stuck (get_tile_to_draw) — это уже учтено в ft_code
|
||||
* (его ставит pop_tile_code_drawn), иначе поверх Kid лезет передняя грань
|
||||
* КНОПКИ. */
|
||||
uint8_t code = ft_code;
|
||||
const piece *t;
|
||||
int x = ft_x, dmy = ft_dmy;
|
||||
if (!FORE_ANY[code]) return; /* ранний выход, как в оригинале */
|
||||
t = &pop_tile_table[code];
|
||||
int x = POP_COL_XH[col] * 8;
|
||||
int dmy = 63 * row + 62;
|
||||
if (code == 20) {
|
||||
pop_wall_b(POP_WALL_FRAM_MAIN[pop_wall_modifier(row, col)], x, dmy);
|
||||
wall_pattern(row, col, 1);
|
||||
@@ -375,6 +406,8 @@ static void ceil_over_kid_tile(int col)
|
||||
}
|
||||
if (code == 11) /* draw_loose(1): плита-потолок */
|
||||
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 */
|
||||
}
|
||||
|
||||
@@ -405,9 +438,13 @@ static void fore_tile(int row, int col) /* передний слой одно
|
||||
* висящего/подтягивающегося Kid видны НАД плитой, а тело уходит ЗА неё.
|
||||
* Без этого Kid лез на плиту «с переднего края» (комната 12: вис на
|
||||
* кромке 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_COL_XH[col] * 8, 63 * row + 65);
|
||||
ft_x, ft_dmy + 3);
|
||||
/* draw_tile_fore (seg008:690) — ТОЛЬКО add_foretable-часть. Раньше здесь
|
||||
* рисовалась ещё и передняя кромка пола (bottom_id) «чтобы перекрывала
|
||||
* Kid», но в оригинале bottom идёт через draw_tile_bottom в backtable
|
||||
|
||||
Reference in New Issue
Block a user