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:
@@ -94,6 +94,11 @@ void gfx_blit(int x, int y, const void *img);
|
||||
* пиксели). Для тайловых движков; где нужен клип — gfx_blit/gfx_blit_part. */
|
||||
void gfx_blit_noclip(int x, int y, const void *img);
|
||||
|
||||
/* Быстрый heal БЕЗ клипа: прямоугольник обязан быть целиком на экране,
|
||||
* w,h ≤ 255. Пара к gfx_blit_noclip (общее ядро тратит время на клип и
|
||||
* 16-бит, а не на пиксели: замер — 11 658 тактов на heal 22×22). */
|
||||
void gfx_heal_noclip(int x, int y, uint8_t w, uint8_t h);
|
||||
|
||||
/* Блит под-прямоугольника (sx,sy,w,h) картинки (атлас кадров:
|
||||
* кадр N ленты — sx = N*FRAME_W). Под-прямоугольник обязан лежать
|
||||
* внутри img; по экрану — клиппится. */
|
||||
@@ -107,6 +112,14 @@ void gfx_blit_part(int x, int y, const void *img,
|
||||
* Для персонажей (флип); фон — обычный gfx_blit (row-major). */
|
||||
void gfx_blit_cols(int x, int y, const void *img, uint8_t flip);
|
||||
|
||||
/* То же с ОБРЕЗКОЙ СВЕРХУ: рисуются только строки [skip, skip+rows) кадра,
|
||||
* (x,y) — экранная позиция ПЕРВОЙ нарисованной строки (как gfx_blit_part).
|
||||
* rows <= 0 = «до низа кадра». Для персонажа, ушедшего головой под пол
|
||||
* (порт clip_char/obj_clip_top в PoP). Обрезка сверху бесплатна: колонка —
|
||||
* непрерывный кусок ОЗУ, сдвигается только старт. */
|
||||
void gfx_blit_cols_part(int x, int y, const void *img, uint8_t flip,
|
||||
int skip, int rows);
|
||||
|
||||
/* Восстановить прямоугольник экрана из ОЗУ-копии (стирание спрайта/
|
||||
* оверлея, нарисованного банком с битом 2: 0x54/0x5C). Всегда
|
||||
* работает банком GFX_BANK_NORMAL независимо от gfx_set_bank;
|
||||
|
||||
Reference in New Issue
Block a user