From 740cc6d652d5829f9aa60bfa196d699f025e4bb8 Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Tue, 11 Aug 2026 21:46:38 +0300 Subject: [PATCH] =?UTF-8?q?=D0=90=D1=80=D0=BA=D0=B0=20=D1=83=20=D0=B2?= =?UTF-8?q?=D0=BE=D1=80=D0=BE=D1=82:=20=D1=81=D0=BF=D0=B5=D1=86=D1=81?= =?UTF-8?q?=D0=BB=D1=83=D1=87=D0=B0=D0=B9=20=C2=ABLattice=20+=20door=20A?= =?UTF-8?q?=C2=BB=20(seg008:622)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Уровень 5, комната 12, тайл (0,9): чёрная дыра вместо арки. У doortop нет своей базы (base_id 0), и рядом с lattice_down оригинал рисует пару одним спрайтом 6, опущенным на 3 px. Ветки у нас не было. Правка нужна В ДВУХ местах: pop_room.c (сама отрисовка) и toolchain/render_room.py — pop_pack_bg.py собирает атлас по обходу render_room, без этого спрайт 6 не попал бы в pop_env*.atl. Найдено сверкой с оригиналом: prince megahit 5 --screenshot-level даёт карту уровня, снимок MAME совмещается с клеткой комнаты, разница по яркости показала расхождение ровно в (0,9) — 1892 пикселя до фикса, 995 после (остаток = Кид, факел, статус-полоса). Что рисует оригинал в тайле, показала трасса POP_TRACE_BT в add_backtable: id=6 32x63 рядом с id=85 32x4. Методика записана в BUGS_CLOSED.md и memory. Co-Authored-By: Claude Opus 5 --- applications/PoP/poc/res/bg/pal_env0.atl | Bin 9272 -> 11292 bytes applications/PoP/poc/res/bg/pop_env0.atl | Bin 9272 -> 11292 bytes applications/PoP/roomtest/BUGS_CLOSED.md | 40 ++++++++++++++++++++++ applications/PoP/roomtest/pop_room.c | 14 ++++++-- applications/PoP/toolchain/render_room.py | 11 ++++-- 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/applications/PoP/poc/res/bg/pal_env0.atl b/applications/PoP/poc/res/bg/pal_env0.atl index 5d57118f262811e2e7bc3334f754183b797ac427..81f29702bb00085ffdaae7e662ea968f07af6267 100644 GIT binary patch delta 1165 zcmdntF(+ce3>EF zNN8AiXmBtPVZ%`Q(9mF@30N>p9;g>91j#1@Ex@W7WFV0a2*U-S`X>kQO0q%NlP?NM z!I;OIlyMRxM4H62IH*g??FK|ezL$!v4gari!hJ_%}fnYw&=nuRI zeF6yM43KOg&PKQcKX4*U1e#tCwJ9tJ=!g)Y-9gCV0pde^0CptMnPET&BLIjCkq5gP zEQy>TKq?{fAftg=ktM-w4_G__jfP4GA_1TpxC6nO!E*nR0aSkS1%8Cb_yyo`rY8W8 zGd~2=UjPw(fdUAPg#wbCPy+-1PcGyZ=YaD5Po5|s0T0B90+Ki-;EFaPnG4iFw)jLL gxMvh4geMzFvTy?Z4{_JzVI{%^_gCm<0SOHr0082IWB>pF delta 60 zcmbOevBP7+jEM^*CT`%65|B`^VPs@rm?Ezr0-|p)Fff2<38jsf9K_je7{WqALP94m M)Ku6ktMH#20Os2dhX4Qo diff --git a/applications/PoP/poc/res/bg/pop_env0.atl b/applications/PoP/poc/res/bg/pop_env0.atl index 5d57118f262811e2e7bc3334f754183b797ac427..81f29702bb00085ffdaae7e662ea968f07af6267 100644 GIT binary patch delta 1165 zcmdntF(+ce3>EF zNN8AiXmBtPVZ%`Q(9mF@30N>p9;g>91j#1@Ex@W7WFV0a2*U-S`X>kQO0q%NlP?NM z!I;OIlyMRxM4H62IH*g??FK|ezL$!v4gari!hJ_%}fnYw&=nuRI zeF6yM43KOg&PKQcKX4*U1e#tCwJ9tJ=!g)Y-9gCV0pde^0CptMnPET&BLIjCkq5gP zEQy>TKq?{fAftg=ktM-w4_G__jfP4GA_1TpxC6nO!E*nR0aSkS1%8Cb_yyo`rY8W8 zGd~2=UjPw(fdUAPg#wbCPy+-1PcGyZ=YaD5Po5|s0T0B90+Ki-;EFaPnG4iFw)jLL gxMvh4geMzFvTy?Z4{_JzVI{%^_gCm<0SOHr0082IWB>pF delta 60 zcmbOevBP7+jEM^*CT`%65|B`^VPs@rm?Ezr0-|p)Fff2<38jsf9K_je7{WqALP94m M)Ku6ktMH#20Os2dhX4Qo diff --git a/applications/PoP/roomtest/BUGS_CLOSED.md b/applications/PoP/roomtest/BUGS_CLOSED.md index e9ef845..e8c1534 100644 --- a/applications/PoP/roomtest/BUGS_CLOSED.md +++ b/applications/PoP/roomtest/BUGS_CLOSED.md @@ -2421,3 +2421,43 @@ if ((Guard.charid != charid_1_shadow || current_level == 12) && ... персонажа). Константа `SHADOW_FIGHT_LEVEL` в `pop_guard.h`. **Проверено (пользователь, 2026-08-11):** тень выпивает и уходит, боя нет. + +--- + + +## BUG-LATTICE-DOORTOP. Чёрная дыра на месте арки у ворот — ЗАКРЫТ + +**Наблюдение (пользователь, 2026-08-11).** Уровень 5, комната 12, тайл +(0,9): чёрный квадрат вместо арки. + +**Корень.** `draw_tile_base` (seg008:622) начинается со СПЕЦСЛУЧАЯ, которого +у нас не было: + +```c +if (tile_left == tiles_26_lattice_down && curr_tile == tiles_12_doortop) { + id = 6; // Lattice + door A + ybottom += 3; +} +``` + +У `doortop` своей базы нет (`base_id == 0`), поэтому рядом с аркой пара +«арка + верх двери» рисуется ОДНИМ спрайтом 6, опущенным на 3 px. Без +ветки тайл не рисовал ничего, кроме полоски `bottom_id` 85 (32×4). + +**Фикс.** Ветка добавлена в `pop_room.c` (draw_tile) И в +`toolchain/render_room.py` — последнее обязательно: `pop_pack_bg.py` +собирает атлас по обходу `render_room`, поэтому без правки скрипта спрайт 6 +просто не попал бы в `pop_env*.atl` (см. memory `pop_atlas_dynamic_ids`). + +**Как найдено — методика, годная для любого «не так нарисовано»:** + +1. `./prince megahit --screenshot-level` в SDLPoP рисует карту ВСЕГО + уровня (комнаты разложены по `roomxs`/`roomys`, клетка 320×192). +2. Вырезать нужную комнату и совместить со снимком MAME перебором смещения + (у нас совпало на `crop(101, 50, +640, +192)`, масштаб 2×1). +3. Разница по порогу яркости даёт карту расхождений: до фикса — белый + прямоугольник ровно в (0,9) и 1892 пикселя, после — 995 (Кид, факел, + статус-полоса, то есть динамика). +4. Что именно рисует оригинал в тайле — трасса `POP_TRACE_BT=1` (печать в + `add_backtable`, `src/seg008.c`, выводит room/row/col/id/размер). Она + сразу показала `id=6 w=32 h=63` рядом со «своим» `id=85 w=32 h=4`. diff --git a/applications/PoP/roomtest/pop_room.c b/applications/PoP/roomtest/pop_room.c index 215225f..8a57840 100644 --- a/applications/PoP/roomtest/pop_room.c +++ b/applications/PoP/roomtest/pop_room.c @@ -384,13 +384,23 @@ static void draw_tile(int row, int col) * рисует (draw_tile_aboveroom) — только нижние/правые грани. --- */ if (row >= 0) { uint8_t base_id = t->base_id; - if (code == 11) /* loose: левая грань (анимир.) */ + int base_yb = dmy; + if (lcode == 26 && code == 12) { + /* «Lattice + door A» (seg008:622): у doortop своей базы нет + * (base_id 0), и когда слева от него стоит арка (lattice_down), + * пара рисуется ОДНИМ спрайтом 6, опущенным на 3 px. Без этой + * ветки на месте тайла оставалась чёрная дыра — уровень 5, + * комната 12, тайл (0,9) (BUG-LATTICE-DOORTOP). */ + base_id = 6; + base_yb += 3; + } + else if (code == 11) /* loose: левая грань (анимир.) */ base_id = POP_LOOSE_FRAM_LEFT[pop_loose_frame(pop_loose_modif[row * 10 + col])]; else if (code == 0x0F && lcode == 0 && !PALACE) /* opener, слева пусто */ base_id = 148; /* левая половина без пола — только */ /* подземелье (seg008:628) */ if (base_id) - pop_env_b(base_id, x, t->base_y + dmy); + pop_env_b(base_id, x, t->base_y + base_yb); } /* --- draw_tile_anim (seg008.c:0B2B) — левый кадр выдвинутых пик в diff --git a/applications/PoP/toolchain/render_room.py b/applications/PoP/toolchain/render_room.py index 93cd8bb..87a41fb 100755 --- a/applications/PoP/toolchain/render_room.py +++ b/applications/PoP/toolchain/render_room.py @@ -647,11 +647,18 @@ def draw_tile(canvas, room, drawn_row, col, left_edge_code=20): # ---- draw_tile_base (seg008.c:611) ---- base_id = t[0] base_y = t[2] - if code == 11: # loose floor: базовая (верхняя) часть = loose_fram_left[0] = 41 + ybottom = draw_main_y + if left_code == 0x1A and code == 0x0C: + # seg008:622 «Lattice + door A»: у doortop своей базы нет (base_id 0), + # и рядом с аркой (lattice_down слева) он рисуется ОДНИМ спрайтом 6, + # опущенным на 3 px. Без этой ветки на месте тайла чёрная дыра. + base_id = 6 + ybottom += 3 + elif code == 11: # loose floor: базовая (верхняя) часть = loose_fram_left[0] = 41 base_id = 41 img = load_sprite(base_id, reason=f"base({TILE_NAMES.get(code,'?')})") if img: - blit(canvas, img, x, base_y + draw_main_y - img.height + 1) + blit(canvas, img, x, base_y + ybottom - img.height + 1) # ---- draw_tile_anim ---- (spike/potion/chomper animated) skipped