Инвентаризация делений по .asm: убраны три, остальные разобраны
Обход всех сгенерированных .asm (awk по `call __div/__mod/__mul` с привязкой к строке исходника) нашёл 31 вызов в 9 модулях. Три из них были в горячем пути: - pop_cdraw.c calc_screen_x_coord: `x * 8 / 7` -> __divsint, 2 400 тактов на ПЕРСОНАЖА КАЖДЫЙ КАДР (два вызова при живом сопернике). Заменено тождеством 8x/7 == x + x/7 плюс таблица DIV7[256] в банке 4 — резидент не тронут, обычный диапазон (obj_x 0..252 при x_bump 58..184) покрыт целиком, деление осталось только хвостом для шва (render_dx = ∓140). - pop_guard.c guard_col_from_x: /14 и %14 звались БЕЗУСЛОВНО, мимо POP_TILE_DIV — единственное 16-битное деление без подключённой таблицы. - pop_trob.c animate_chomper: `tp / 10` на чомпера каждый кадр, при том что TP_ROW/TP_COL лежали в этом же файле, но ниже по тексту. Таблицы подняты выше чомперов. Остальные 25 оставлены осознанно и расписаны в TASKS_OPEN.md: хвосты за таблицей (x вне 0..255 = персонаж в соседней комнате), намеренный медленный хвост pop_y_to_row, недостижимая ветка pop_rnd_fit и холодные места (вход стража, старт уровня, читы, имя файла, отладочный HUD). В банках 4, 6, 7 теперь ноль __div*. Тождество 8x/7 закреплено тестом geom_mul8div7_identity (перебор −420..700), таблица DIV7 сверена с x//7. tests-host: [geom] 840 -> 1961, все 5 наборов прошли. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -198,6 +198,17 @@ static uint8_t bubble_next_frame(uint8_t curr)
|
||||
return (next >= 8) ? 1 : next;
|
||||
}
|
||||
|
||||
/* Разбор номера тайла 0..29 на ряд/колонку без деления (`tp / 10`, `tp % 10`
|
||||
* — это __divuchar/__moduchar, а в animate_chomper они звались на каждого
|
||||
* чомпера каждый кадр). Определены ЗДЕСЬ, а не перед pop_process_trobs, где
|
||||
* лежали раньше: чомперы выше по файлу и оригинала не видели. */
|
||||
static const uint8_t TP_ROW[30] = {
|
||||
0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2
|
||||
};
|
||||
static const uint8_t TP_COL[30] = {
|
||||
0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9
|
||||
};
|
||||
|
||||
/* animate_chomper (seg007:0448). Модификатор: младшие 7 бит — фаза 1..N,
|
||||
* старший — «перемололо кого-то» (кровь). Фаза крутится по кругу до
|
||||
* POP_CHOMPER_SPEED (у оригинала 15), то есть челюсти смыкаются раз в N
|
||||
@@ -217,7 +228,7 @@ static void animate_chomper(uint8_t *m, int8_t *type,
|
||||
frame = (uint8_t)((*m & 0x7F) + 1);
|
||||
if (frame > POP_CHOMPER_SPEED) frame = 1;
|
||||
*m = (uint8_t)(blood | frame);
|
||||
if ((room != drawn_room || tp / 10 != Kid.curr_row ||
|
||||
if ((room != drawn_room || (int8_t)TP_ROW[tp] != Kid.curr_row ||
|
||||
(Kid.alive >= 0 && blood == 0)) && frame >= 6)
|
||||
*type = -1;
|
||||
}
|
||||
@@ -467,14 +478,6 @@ static uint8_t torch_tick;
|
||||
#define TORCH_ANIM_NOW 1
|
||||
#endif
|
||||
|
||||
/* Разбор номера тайла 0..29 на ряд/колонку без деления. */
|
||||
static const uint8_t TP_ROW[30] = {
|
||||
0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2
|
||||
};
|
||||
static const uint8_t TP_COL[30] = {
|
||||
0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9
|
||||
};
|
||||
|
||||
void pop_process_trobs(uint8_t cur_room) __banked
|
||||
{
|
||||
uint8_t i, w = 0;
|
||||
@@ -608,7 +611,7 @@ void pop_process_trobs(uint8_t cur_room) __banked
|
||||
* непрозрачны, поэтому wipe не нужен. */
|
||||
/* Створку рисует ПРАВАЯ половина двери; последний кадр анимации
|
||||
* помечаем на обе страницы, иначе дверь дрожит через кадр. */
|
||||
if (tp % 10 + 1 < 10)
|
||||
if (TP_COL[tp] < 9)
|
||||
pop_set_redraw((uint8_t)(tp + 1), POP_RD_LEVELDOOR,
|
||||
(uint8_t)(type < 0 ? 2 : 1));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user