Убраны три последних /63 %4 в pop_room.c — вызов pop_y_to_row
mob_tick_one (927) и mob_render (976/977) считали `(y+60)/63 % 4 - 1` вручную, хотя pop_y_to_row — точный эквивалент этой формулы на всём int16_t (включая усечение деления к нулю для отрицательных). В asm это были три пары __divsint+__modsint, ~16 200 тактов (3,8 % кадра) — только пока кусок плиты в полёте, то есть в самом тяжёлом кадре. В банке 7 теперь ноль __divsint. Эквивалентность закреплена тестом geom_y_to_row_matches_formula: перебор −400..400 против исходной формулы (вызовы разбросаны по трём банкам, соблазн написать деление «по месту» возвращается). tests-host: [geom] 39 -> 840, все 5 наборов прошли. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,6 +56,22 @@ TC_TEST(geom_y_to_row)
|
||||
TC_EQ(pop_y_to_row(pop_y_land[4]), -1);
|
||||
}
|
||||
|
||||
/* Цепочка сравнений в pop_y_to_row обязана совпадать с ИСХОДНОЙ формулой
|
||||
* `(y + 60) / 63 % 4 - 1` во всём рабочем диапазоне — включая усечение
|
||||
* деления К НУЛЮ для отрицательных. Тест держит инвариант: вызовы
|
||||
* разбросаны по банкам (pop_map, pop_bg, pop_room), и соблазн написать
|
||||
* деление «по месту» возвращается. */
|
||||
TC_TEST(geom_y_to_row_matches_formula)
|
||||
{
|
||||
int16_t y;
|
||||
/* −400..400 с запасом накрывает всё: кусок loose стартует у потолка
|
||||
* (ряд −1) и улетает ниже поля в комнату снизу. */
|
||||
for (y = -400; y <= 400; y++) {
|
||||
int16_t t = (int16_t)(y + 60);
|
||||
TC_EQ(pop_y_to_row(y), (int8_t)(t / 63 % 4 - 1));
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- PRNG: сверка asm-LCG с эталонной формулой ---------------------- */
|
||||
|
||||
#if POP_PRANDOM_EXACT
|
||||
@@ -137,6 +153,7 @@ int main(void)
|
||||
TC_RUN(geom_xbump_layout);
|
||||
TC_RUN(geom_yland_rows);
|
||||
TC_RUN(geom_y_to_row);
|
||||
TC_RUN(geom_y_to_row_matches_formula);
|
||||
#if POP_PRANDOM_EXACT
|
||||
TC_RUN(geom_lcg_matches_reference);
|
||||
TC_RUN(geom_lcg_seed_zero);
|
||||
|
||||
Reference in New Issue
Block a user