PoP roomtest: clip_char (верхняя обрезка спрайта) + подстановка нажатой кнопки
Спуск Кида с кнопки (room8, кромка (0,6)) рисовался неверно: Кид просвечивал в щель между кнопкой и ближним столбом, а ближняя рука была срезана до одного оторванного пикселя. Две независимые причины. 1. Не был портирован clip_char() (seg006:1749) — оригинал перед add_objtable обрезает спрайт персонажа сверху по y_clip[curr_row+1], когда тайл над головой стена или пол. Порт: pop_clip_char_top() (pop_map.c, метрики по set_char_collision) + новый примитив gfx_blit_cols_part() в libbgi (блит column-major с пропуском skip верхних строк; обрезка сверху бесплатна — колонка непрерывна в ОЗУ, сдвигается только старт). gfx_blit_cols стал тонкой обёрткой над ним. kid_heal чистит уже ОБРЕЗАННЫЙ прямоугольник, иначе стирается кромка пола над срезом. 2. climb_overlay_tile (порт draw_floor_overlay, seg008:1E3A) выбирал ветку по СЫРОМУ коду тайла, а get_tile_to_draw (seg008:240) подменяет нажатую кнопку на floor/stuck. Тайл-кнопка не проходил тест floor → уходил в draw_other_overlay, который кладёт поверх Кида ВЕСЬ тайл вместо узкой кромки floor_left_overlay[frame-137]. Фикс — tile_code_drawn(): одна подстановка на все слои (fore_only_tile/overlay_mid_tile перестали её дублировать, W3 −293 Б). Проверено покадрово в MAME (шаг gv + снимок): кадры спуска 148..138 чистые, после приземления на кнопке мусора нет. Заодно: gfx_heal_noclip() (пара к gfx_blit_noclip; heal 11658 -> 8982 тактов) и rest_pending в pop_trob — холостой проход по 30 тайлам только когда есть отложенные редрои пик/кнопок (pop_process_trobs 89-111К -> 70-92К тактов). START_ROOM временно = 8 (отладка спуска с кнопки), вернуть на 6/старт уровня. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,12 @@ static uint8_t button_rest[POP_ROOMTILES];
|
||||
* расхождение было именно в безусловном редрое). */
|
||||
static uint8_t trob_drawn[POP_ROOMTILES];
|
||||
|
||||
/* Сколько тайлов ждут отложенного редроя (spike_rest/button_rest). Без
|
||||
* него цикл по 30 тайлам крутился КАЖДЫЙ кадр впустую: замер в MAME
|
||||
* (2026-07-27) — служебная часть pop_process_trobs ~50 000 тактов при
|
||||
* кадре 430 080, то есть ~12 % кадра на пустой проход. */
|
||||
static uint8_t rest_pending;
|
||||
|
||||
/* prandom (seg009.c:321, 32-бит LCG) — нужен для стартовой фазы факела и
|
||||
* выбора следующего кадра пламени. */
|
||||
static unsigned long trob_seed;
|
||||
@@ -57,6 +63,7 @@ void pop_trob_reset(void)
|
||||
uint8_t i;
|
||||
for (i = 0; i < POP_NROOMS; i++) room_seen[i] = 0;
|
||||
for (i = 0; i < POP_ROOMTILES; i++) { spike_rest[i] = 0; button_rest[i] = 0; trob_drawn[i] = 0; }
|
||||
rest_pending = 0;
|
||||
trobs_count = 0;
|
||||
}
|
||||
|
||||
@@ -101,6 +108,7 @@ void pop_trob_room_changed(void)
|
||||
{
|
||||
uint8_t i;
|
||||
for (i = 0; i < POP_ROOMTILES; i++) { spike_rest[i] = 0; button_rest[i] = 0; trob_drawn[i] = 0; }
|
||||
rest_pending = 0;
|
||||
}
|
||||
|
||||
/* anim_tile_modif (seg000:0B12) — при входе в комнату завести анимации её
|
||||
@@ -304,19 +312,20 @@ void pop_process_trobs(uint8_t cur_room)
|
||||
* выносит оба деления (__divuchar/__moduchar) в вершину цикла как общее
|
||||
* подвыражение аргументов redraw — 30*2=60 делений/кадр даже когда нет
|
||||
* активных пик/кнопок (тот же случай, что был в pop_loose_tick). */
|
||||
{
|
||||
uint8_t row = 0, col = 0;
|
||||
if (rest_pending) {
|
||||
uint8_t row = 0, col = 0, left = 0;
|
||||
for (i = 0; i < POP_ROOMTILES; i++) {
|
||||
if (spike_rest[i]) {
|
||||
pop_spike_redraw(row, col);
|
||||
spike_rest[i]--;
|
||||
if (--spike_rest[i]) left++;
|
||||
}
|
||||
if (button_rest[i]) {
|
||||
pop_button_redraw(row, col);
|
||||
button_rest[i]--;
|
||||
if (--button_rest[i]) left++;
|
||||
}
|
||||
if (++col == 10) { col = 0; row++; }
|
||||
}
|
||||
rest_pending = left;
|
||||
}
|
||||
|
||||
if (trobs_count == 0) return;
|
||||
@@ -398,8 +407,8 @@ void pop_process_trobs(uint8_t cur_room)
|
||||
: (uint8_t)(get_doorlink_timer(mod[tp]) > 1);
|
||||
if (sig != trob_drawn[tp]) {
|
||||
uint8_t trow = tp / 10, tcol = tp % 10;
|
||||
if (code == TILE_SPIKE) { pop_spike_redraw(trow, tcol); spike_rest[tp] = 1; }
|
||||
else { pop_button_redraw(trow, tcol); button_rest[tp] = 1; }
|
||||
if (code == TILE_SPIKE) { pop_spike_redraw(trow, tcol); spike_rest[tp] = 1; rest_pending++; }
|
||||
else { pop_button_redraw(trow, tcol); button_rest[tp] = 1; rest_pending++; }
|
||||
trob_drawn[tp] = sig;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user