Files
Sprinter-SDCC/libbgi/common/gfx_heal_noclip.c
T
snark13 6582154381 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>
2026-07-28 09:50:47 +03:00

31 lines
1.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* gfx_heal_noclip — восстановить прямоугольник экрана из ОЗУ-копии БЕЗ
* клипа: вызывающий гарантирует, что прямоугольник целиком на экране,
* w,h ≤ 255. Быстрый вариант gfx_heal для тайловых движков (пара к
* gfx_blit_noclip).
*
* Зачем: gfx_heal идёт через общее ядро _gfx_heal_full (клип, нарезка
* полос >256, 16-битная арифметика) — замер в MAME (PoP roomtest,
* 2026-07-27): heal области 22×22 стоил 11 658 тактов при кадре 430 080,
* т.е. цена почти вся в обвязке, а не в пикселях. Линейное спрайтовое
* ядро _gfx_heal_sprite_noclip делает ту же работу без этого груза.
*
* Банк — как у gfx_heal: на время операции ВСЕГДА GFX_BANK_NORMAL
* (чтение отдаёт ОЗУ-копию, запись должна дойти и до ОЗУ), затем
* пользовательский банк восстанавливается. W3-скобка ставится ЗДЕСЬ:
* из модуля, собранного с --w3, её вызывать нельзя (после _bgi_begin
* окно W3 занято видеобанком и код вызывающего исчезает).
*/
#include "../_bgi.h"
void gfx_heal_noclip(int x, int y, uint8_t w, uint8_t h)
{
uint8_t saved = gfx_get_bank();
gfx_set_bank(GFX_BANK_NORMAL);
_bgi_begin();
_gfx_heal_sprite_noclip(x, y, w, h);
_bgi_end();
gfx_set_bank(saved);
}