From cbae48dbc4b113d46c366020a9329a96bb44a310 Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Sat, 18 Jul 2026 11:37:56 +0300 Subject: [PATCH] =?UTF-8?q?applications/PoP/roomtest:=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?-=D0=BE=D0=B2=D0=B5=D1=80=D0=BB=D0=B5=D0=B9=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=BE=D0=B4=D1=8A=D1=91=D0=BC=D0=B5=20(draw=5Ff?= =?UTF-8?q?loor=5Foverlay)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Проблема из динамики: при подъёме [1,2]→[0,3] нижняя часть Kid, которая физически за полом назначения, просвечивала. Порт SDLPoP draw_floor_overlay (seg008:1457): на кадрах подъёма 137..144, если тайл-назначения floor-подобный (floor/pillar/stuck/torch) И тайл СЛЕВА пуст (кромка), передний край пола (floor_left_overlay[frame-137] = {32,151,151,150,150,151,32,32}) + низ пола рисуются ПОВЕРХ нижней части Kid. - pop_bg: climb_overlay_tile + доп-проход в pop_fore_over_kid (новый параметр frame) на кадрах 137..144. - pop_pack_bg.py: CLIMB_OVERLAY_ENV_IDS={32,150,151} явно добавлены в env-фон (не попадают в used render_room — рантайм-анимация); env4 count 16→24. - roomtest: передача Kid.frame в pop_fore_over_kid. Проверено в MAME (кадр 137): при подтягивании видна только голова/плечи Kid над кромкой [0,3], нижняя часть скрыта за полом. Co-Authored-By: Claude Opus 4.8 --- applications/PoP/poc/res/bg/pop_env1.atl | Bin 11725 -> 11873 bytes applications/PoP/poc/res/bg/pop_env4.atl | Bin 1230 -> 1684 bytes applications/PoP/roomtest/pop_bg.c | 31 +++++++++++++++++++++- applications/PoP/roomtest/pop_bg.h | 3 ++- applications/PoP/roomtest/roomtest.c | 4 +-- applications/PoP/toolchain/pop_pack_bg.py | 8 +++++- 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/applications/PoP/poc/res/bg/pop_env1.atl b/applications/PoP/poc/res/bg/pop_env1.atl index bfc986bf607e21e8fae1a517e460cfe0e9ef5bef..b1c5df54fd6a39a8f23fea448acf1d88ac2561f8 100644 GIT binary patch delta 287 zcmX>b{V--i28#@%5XZzEmHG{g3O0<43=Afm3IZV7f?LWCM0W^Ef%!VZ3cMix1raHJ z5FI6^zzm}IiOEQV=xvhHVj!AF24cF>o;aM+G4vAt(Ysen`mVRYKB%U>1mg%ES3k5hOlX1j>(r(*IH9 LL7dGpj2m?ToIzRf delta 159 zcmaDDb2fTH#>4`Ji47d}GK>l~jEoEn3pf-6K=cwWDLWATML-J7pCP2c3*y^|Nb!T{ zW1=n83wIe(NO`h7Gd!TKbCav=GsS`s`UdZ)Gk7l@A4k>CK* TybOxE66_!W5ZJtdaib0Z?V}Y< diff --git a/applications/PoP/poc/res/bg/pop_env4.atl b/applications/PoP/poc/res/bg/pop_env4.atl index 9b98786373b9f34b029e0e69b6ea6e36f83b7716..395c5d04afb9d3c539cde87b029d81d2f9f64d57 100644 GIT binary patch literal 1684 zcmcJPF>(Si3;=b3G!#(5WT>u8ktR>b4>IQH?j?Cx$~+}saU@yN$!8g8q8Y}zT}!fW zfXnB{`wRSkybb^Ze(tSr!};*YzI%Nh_1{n9-p~8mjvIRZ-JW)|{yZOfr8jhj15CY0 z9g$LOkb7e}^PI6;L5XvE!pIny3gU^zJ>+WHUux`hZhvJ~+`2VfOu*TM98HJkOoC3* zMvvz_!XDcFLN4X59WQp8LSO7W&7rqin$Xl&w(%>w@@jFehU>3Z6|d$)YyAUThH!mr z`R+6Ty;yfBcLKEzRq6G1q!Bi7d&@Qcmu6QhohIcV~hI4xerq`-%4VHS%5 WGl&lYQVjeIlO0(kH+wQpWd;B}?hASV diff --git a/applications/PoP/roomtest/pop_bg.c b/applications/PoP/roomtest/pop_bg.c index e98743d..6945220 100644 --- a/applications/PoP/roomtest/pop_bg.c +++ b/applications/PoP/roomtest/pop_bg.c @@ -429,7 +429,30 @@ static void fore_tile(int row, int col) /* передний слой одно } } -void pop_fore_over_kid(int obj_x, int obj_y, uint16_t w, uint16_t h, int8_t dir) +/* Пол-оверлей при подъёме (draw_floor_overlay, seg008:1457): когда Kid + * подтягивается на floor-подобный тайл назначения (floor/pillar/stuck/torch), + * а тайл СЛЕВА пуст (т.е. кромка), передний край пола перекрывает нижнюю + * часть Kid — иначе видна часть, что должна быть за полом. Кадр подъёма + * 137..144 индексирует floor_left_overlay. */ +static const uint8_t FLOOR_LEFT_OVERLAY[8] = {32, 151, 151, 150, 150, 151, 32, 32}; + +static void climb_overlay_tile(int row, int col, uint8_t fidx) +{ + uint8_t code = tile_code(row, col); + int x, dmy, dby; + const piece *t; + if (code != 1 && code != 3 && code != 5 && code != 19) return; /* не floor-тайл */ + if (tile_code(row, col - 1) != 0) return; /* слева не пусто → не кромка */ + x = COL_XH[col] * 8; + dmy = 63 * row + 62; + dby = dmy + 3; + t = &tile_table[code]; + env_b(FLOOR_LEFT_OVERLAY[fidx], x, dmy + (code == 5 ? 1 : 0)); + if (t->bottom_id) env_b(t->bottom_id, x, dby); /* draw_tile_bottom */ +} + +void pop_fore_over_kid(int obj_x, int obj_y, uint16_t w, uint16_t h, + int8_t dir, uint8_t frame) { int wh = (int)((w + 1) >> 1); /* char_width_half */ int xl = obj_x / 2 + 58; /* char_x_left (58-база) */ @@ -445,5 +468,11 @@ void pop_fore_over_kid(int obj_x, int obj_y, uint16_t w, uint16_t h, int8_t dir) for (r = rT; r <= rB; r++) for (c = cL; c <= cR; c++) fore_tile(r, c); + if (frame >= 137 && frame <= 144) { /* подъём: пол назначения поверх Kid */ + uint8_t fidx = (uint8_t)(frame - 137); + for (r = rT; r <= rB; r++) + for (c = cL; c <= cR; c++) + climb_overlay_tile(r, c, fidx); + } gfx_set_bank(GFX_BANK_NORMAL); } diff --git a/applications/PoP/roomtest/pop_bg.h b/applications/PoP/roomtest/pop_bg.h index f91001e..c335591 100644 --- a/applications/PoP/roomtest/pop_bg.h +++ b/applications/PoP/roomtest/pop_bg.h @@ -33,6 +33,7 @@ void pop_room_draw(uint8_t room_num, * звать ПОСЛЕ kid_draw. obj_x — ЛОГИЧЕСКАЯ X кадра (до ×8/7), obj_y — низ * спрайта, w/h — размер кадра, dir — направление Kid (<0 влево). Метрики * берутся из pop_kid (kid_fp_*). См. redraw_at_char/set_char_collision. */ -void pop_fore_over_kid(int obj_x, int obj_y, uint16_t w, uint16_t h, int8_t dir); +void pop_fore_over_kid(int obj_x, int obj_y, uint16_t w, uint16_t h, + int8_t dir, uint8_t frame); #endif diff --git a/applications/PoP/roomtest/roomtest.c b/applications/PoP/roomtest/roomtest.c index 8e4fddb..960a467 100644 --- a/applications/PoP/roomtest/roomtest.c +++ b/applications/PoP/roomtest/roomtest.c @@ -50,7 +50,7 @@ int main(void) kid_init(SEQ_STAND, 1, 1, 0); kid_draw(); pop_fore_over_kid(kid_fp_obj_x(), kid_fp_obj_y(), - kid_fp_width(), kid_fp_height(), Kid.direction); + kid_fp_width(), kid_fp_height(), Kid.direction, Kid.frame); if (pop_ctrl_init() != 0) { /* raw-канал клавиатуры (забирает ввод у DSS) */ closegraph(); @@ -72,7 +72,7 @@ int main(void) } kid_draw(); /* нарисовать новый кадр */ pop_fore_over_kid(kid_fp_obj_x(), kid_fp_obj_y(), - kid_fp_width(), kid_fp_height(), Kid.direction); + kid_fp_width(), kid_fp_height(), Kid.direction, Kid.frame); } pop_ctrl_close(); diff --git a/applications/PoP/toolchain/pop_pack_bg.py b/applications/PoP/toolchain/pop_pack_bg.py index 27aea11..f36da90 100644 --- a/applications/PoP/toolchain/pop_pack_bg.py +++ b/applications/PoP/toolchain/pop_pack_bg.py @@ -45,6 +45,11 @@ OUT_DIR = os.path.join(HERE, "..", "poc", "res", "bg") # столбов, ворот, дебриса. См. tile_table.fore_id + анализ pop_background_strategy. FORE_ENV_IDS = {9, 12, 49, 88, 91, 95, 100} +# Пол-оверлей подъёма (floor_left_overlay, draw_floor_overlay seg008): рисуется +# рантаймом поверх нижней части Kid при подтягивании на пол у кромки — НЕ +# попадает в used render_room, добавляем явно в env-фон. (32 обычно уже есть.) +CLIMB_OVERLAY_ENV_IDS = {32, 150, 151} + ENV_SHIFT = 5 # env фон: страница = id>>5, idx = id&31 ENV_MASK = (1 << ENV_SHIFT) - 1 @@ -235,7 +240,8 @@ def write_header(out_path, env_pages, wall_name, fore_name): def main(): os.makedirs(OUT_DIR, exist_ok=True) used = collect_used() - env_ids = sorted(id for ch, id in used if ch != R.CHTAB_WALL) + env_ids = sorted(set(id for ch, id in used if ch != R.CHTAB_WALL) + | CLIMB_OVERLAY_ENV_IDS) # + пол-оверлей подъёма wall_ids = sorted(id for ch, id in used if ch == R.CHTAB_WALL) env_bg = [i for i in env_ids if i not in FORE_ENV_IDS]