From af4e64455e000c7fa797a734d014ce20d062bd1b Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Tue, 18 Aug 2026 12:01:07 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9A=D1=83=D1=81=D0=BE=D0=BA=20=D1=83=D0=B7?= =?UTF-8?q?=D0=BE=D1=80=D0=B0=20=D0=BD=D0=B0=20=D1=81=D1=82=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5:=20=D0=BC=D0=BE=D0=B4=D0=B8=D1=84=D0=B8=D0=BA=D0=B0?= =?UTF-8?q?=D1=82=D0=BE=D1=80=20=D1=81=D1=82=D0=B5=D0=BD=D1=8B=20=D0=BD?= =?UTF-8?q?=D0=B5=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B2=D0=BE=D0=B4=D0=B8=D0=BB?= =?UTF-8?q?=D1=81=D1=8F=20=D0=BF=D1=80=D0=B8=20=D0=B7=D0=B0=D0=B3=D1=80?= =?UTF-8?q?=D1=83=D0=B7=D0=BA=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Флаг «no blue» лежит в нулевом бите модификатора стены В ФАЙЛЕ уровня, а отрисовка (как и оригинал) ищет его в СТАРШЕМ: load_alter_mod переводит их сдвигом на 7. Ветку стен мы пропускали намеренно — связи кладки считаются по соседям, — но noblue из соседей не выводится. Co-Authored-By: Claude Opus 5 --- applications/PoP/roomtest/BUGS_CLOSED.md | 45 ++++++++++++++++++++++++ applications/PoP/roomtest/pop_trob.c | 15 ++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/applications/PoP/roomtest/BUGS_CLOSED.md b/applications/PoP/roomtest/BUGS_CLOSED.md index 1ffee1f..3953d48 100644 --- a/applications/PoP/roomtest/BUGS_CLOSED.md +++ b/applications/PoP/roomtest/BUGS_CLOSED.md @@ -2864,3 +2864,48 @@ seg006:507). Выход из функции теперь один на обе класс целиком, а не найденный путь. Ловушка на будущее, если симптом всплывёт снова: `wp <адрес pop_cd[OPP].w>,4,w` — сработает на первой же записи «чужой» ширины. + +--- + + +## BLUELINE-NOBLUE. Кусок синего узора на стене там, где оригинал его не рисует — ЗАКРЫТ 2026-08-18 + +**Наблюдение (пользователь, 2026-08-18).** Уровень 6, комната 1, тайл (2,3): +у правой кромки левого блока висит небольшой кусочек тёмно-синего узора, +которого в оригинале нет. Диагноз пользователя («первоначальная отрисовка +фона, фикс не должен повлиять на скорость») подтвердился полностью. + +**Корень.** Полоску рисует `draw_tile_right` (`pop_room.c`, порт +seg008:0666) — её кладёт ПРАВЫЙ сосед стены: + +```c +case tiles_20_wall: + if (tbl_level_type[current_level] && (modifier_left & 0x80) == 0) + add_backtable(chtab_6, 84 /*wall stripe*/, draw_xh + 3, 0, draw_main_y - 27, ...); +``` + +Проверка `& 0x80` у нас была, а вот значения, которое она проверяет, — нет. +Модификатор стены В ФАЙЛЕ уровня и В РАНТАЙМЕ у оригинала разные: +`load_alter_mod` (seg008:1216) переводит их при загрузке комнаты — +`*curr_tile_modif <<= 7`, то есть единственный бит уровня («no blue», +авторский флаг «не рисовать полоску на моей правой кромке») переезжает в +СТАРШИЙ. Наш порт `load_alter_mod` (`pop_trob.c`) ветку стен пропускал +НАМЕРЕННО, и в комментарии это было записано: связи кладки мы считаем по +типам соседей (`pop_wall_modifier`), сохранённый модификатор стены «не +читается вовсе». + +Ошибка в слове «вовсе»: у модификатора стены ДВА независимых смысла, и +из соседей выводится только один. `noblue` проставлен вручную в данных +уровня и не выводится ниоткуда. В комнате 1 уровня 6 стена (2,2) имеет в +файле модификатор 1, то есть ровно «без полоски»; без перевода отрисовка +видела сырую единицу, `(1 & 0x80) == 0` проходило — и полоска вылезала. + +**Фикс.** `case TILE_WALL: *m = (uint8_t)(*m << 7);` в порте +`load_alter_mod`. Перевод одноразовый, при первом входе в комнату +(`room_seen`), — кадровый бюджет не трогает вообще; +24 байта в банке 6, +резидент не изменился. + +**Проверка (MAME, уровень 6 комната 1).** Попиксельный диф скриншотов до и +после: изменения ровно в боксе `(344,199)-(358,206)`, 38 пикселей — сам +артефакт и ничего кроме. На подземных уровнях изменений нет по построению: +полоска целиком под `if (PALACE)`. diff --git a/applications/PoP/roomtest/pop_trob.c b/applications/PoP/roomtest/pop_trob.c index 0986d59..ad36bc7 100644 --- a/applications/PoP/roomtest/pop_trob.c +++ b/applications/PoP/roomtest/pop_trob.c @@ -30,6 +30,7 @@ #define TILE_SWORD 0x16 /* меч-предмет на полу */ #define TILE_LEVELDOOR 0x10 /* левая половина двери уровня (на ней modif) */ #define TILE_CHOMP 0x12 /* чомпер (челюсти) */ +#define TILE_WALL 0x14 /* стена (в модификаторе — флаг «без полоски») */ #define TILE_TORCH 0x13 #define TILE_TORCH_DEBRIS 0x1E #define TILE_EMPTY 0x00 /* remove_loose: на месте провалившейся плиты */ @@ -91,10 +92,17 @@ uint8_t *pop_trob_modif(uint8_t room) __banked * рядом с ними теряет смысл (ур. 2, комн. 13). * loose -> 0: фаза тряски всегда начинается с нуля. * зелье -> <<3: старшие биты = тип, младшие 3 = фаза пузырька. + * стена -> <<7: единственный бит уровня («без полоски», см. ниже) + * переезжает в СТАРШИЙ, где его и ищет отрисовка. * - * Ветка стен (blue-line/связи кладки) НЕ портируется намеренно: у - * нас pop_bg считает связи по типам СОСЕДЕЙ прямо при отрисовке - * (wall_modifier), сохранённый модификатор стены не читается вовсе. */ + * СВЯЗИ кладки (какая грань у стены слева/справа) из этого перевода + * намеренно выкинуты: у нас их считает pop_wall_modifier по типам + * СОСЕДЕЙ прямо при отрисовке. Но второй смысл модификатора стены — + * авторский флаг «не рисовать синюю полоску на моей правой кромке» + * (noblue) — из соседей не выводится, он проставлен вручную в данных + * уровня. Без перевода отрисовка видела сырую единицу вместо 0x80, + * проверка `(mod & 0x80) == 0` проходила, и во дворце вылезал кусок + * узора на стене (BUG BLUELINE-NOBLUE, ур. 6 к. 1 тайл (2,3)). */ pop_level_access_begin(); for (i = 0; i < POP_ROOMTILES; i++) { uint8_t *m = &room_modif[room - 1][i]; @@ -102,6 +110,7 @@ uint8_t *pop_trob_modif(uint8_t room) __banked case TILE_GATE: *m = (uint8_t)((*m == 1) ? 188 : 0); break; case TILE_LOOSE: *m = 0; break; case TILE_POTION: *m = (uint8_t)(*m << 3); break; + case TILE_WALL: *m = (uint8_t)(*m << 7); break; default: break; } }