Шаг D: паласные ветки отрисовки + потерянный верх ворот
Порт семи мест seg008, расходящихся по tbl_level_type, плюс общая дыра порта, которая на дворце стала видна. Паласные ветки (все — «в подземелье этого нет»): - doortop_fram_top / doortop_fram_bot (seg008:413, 506): декоративная панель над воротами. У шва она и есть тот «ковёр», которого не хватало. - stripe_id соседа слева (seg008:486): орнаментная лента под окнами. Она непрерывная, потому что stripe_id = 145 у пола, кнопок, зелья, loose, чомпера и меча; без неё лента шла кусками (только blueline). - полоска на стене id 84 (seg008:510), при (modifier & 0x80) == 0. - blueline_fram3: условие `num == !!level_type` — в подземелье пропускается num==0, в паласе num==1 (seg008:501). - левая половина кнопки-opener без пола (id 148) — только подземелье (seg008:628). - склянка зелья: id += 2 во дворце (seg008:747). - remove_loose возвращает ТИП УРОВНЯ, и он ложится модификатором пустой клетки от упавшей плиты (seg007:846/1083). Потерянный вывод (НЕ паласное расхождение, просто заметили здесь): draw_tile_anim_topright (seg008:0568) не был портирован вовсе — верх ворот, который рисует тайл НАД ними: маска 68 (mono, чёрным) + door_fram_top [(modifier>>2) % 8] = 60..67. Ids 60..68 в атлас не паковались. Симптом — чёрный клин над воротами; нашёлся сравнением с эталоном SDLPoP (--screenshot) и трассой add_backtable. Флаг тайлсета pop_palace вынесен в резидент (pop_tile.c): по нему расходятся ветки в банке 7 (полная отрисовка), банке 2 (fore-проход) и банке 3 (модификатор пустой клетки) — читается напрямую, без трамплина. Известное расхождение: модификатора ряда СНИЗУ у нас нет (pop_t_below — только fg), поэтому паласная панель над воротами в комнате снизу не рисуется. Помечено в коде. tests-host: 5/5 (добавлен include-путь до pop_bg_atlas.h и стаб pop_palace). Проверено в MAME: уровень 4 совпадает с эталоном SDLPoP в рядах 0-1 попиксельно (кроме фазы пламени); уровень 1 не изменился. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -91,6 +91,7 @@ int pop_bg_load(uint8_t set) __banked
|
||||
if (bg_set == 0xFF && /* chtab_1 от набора не зависит */
|
||||
atlas_load(&pop_pot_at, bg_path(POP_POT_ATL)) != 0) return -1;
|
||||
bg_set = set;
|
||||
pop_palace = (uint8_t)(set == 1);
|
||||
/* Палитра — ПОСЛЕ атласов: если атлас не загрузился, цвета остаются от
|
||||
* прежнего набора и картинка хотя бы не разъезжается. */
|
||||
return bg_load_tile_pal(pop_tile_pal[set]);
|
||||
@@ -156,10 +157,34 @@ static uint8_t potion_type(uint8_t modif) { return (uint8_t)((modif & 0xF8) >> 3
|
||||
|
||||
|
||||
|
||||
/* Дворец? — по ЗАГРУЖЕННОМУ набору (pop_palace ставит pop_bg_load), а не по
|
||||
* номеру уровня: так ветки отрисовки и картинки заведомо согласованы даже в
|
||||
* момент смены. */
|
||||
#define PALACE (pop_palace)
|
||||
|
||||
/* Декоративная панель над воротами — ТОЛЬКО в паласе (в подземелье над
|
||||
* воротами не рисуется ничего). Индекс — модификатор тайла doortop.
|
||||
* seg008:407 doortop_fram_top / seg008:453 doortop_fram_bot. */
|
||||
static const uint8_t DOORTOP_FRAM_TOP[4] = {0, 81, 83, 0};
|
||||
static const uint8_t DOORTOP_FRAM_BOT[4] = {78, 80, 82, 0};
|
||||
|
||||
/* Верх ворот: его рисует тайл НАД воротами (draw_tile_anim_topright,
|
||||
* seg008:0568). Кадр — по открытости соседа снизу-слева; 68 — маска,
|
||||
* mono-блит чёрным «продавливает» фон под створкой.
|
||||
* Без этого над воротами оставался чёрный клин — виден у шва во дворце,
|
||||
* где сверху идёт декоративная панель doortop. */
|
||||
static const uint8_t DOOR_FRAM_TOP[8] = {60, 61, 62, 63, 64, 65, 66, 67};
|
||||
#define GATE_TOP_MASK 68
|
||||
|
||||
/* topright тайла снизу-слева (seg008.c:410). */
|
||||
static void draw_topright(uint8_t tt, int x, int dby)
|
||||
static void draw_topright(uint8_t tt, uint8_t tmod, int x, int dby)
|
||||
{
|
||||
if (tt == 7 || tt == 12) return;
|
||||
if (tt == 7 || tt == 12) { /* верх ворот */
|
||||
if (!PALACE) return; /* подземелье: ничего (seg008:413) */
|
||||
if (DOORTOP_FRAM_TOP[tmod & 3])
|
||||
pop_env_b(DOORTOP_FRAM_TOP[tmod & 3], x, dby);
|
||||
return;
|
||||
}
|
||||
if (tt == 20) { pop_wall_b(2, x, dby); return; }
|
||||
if (pop_tile_table[tt].topright_id)
|
||||
pop_env_b(pop_tile_table[tt].topright_id, x, dby);
|
||||
@@ -236,7 +261,7 @@ static void draw_tile(int row, int col)
|
||||
int dmy = dby - 3;
|
||||
const piece *t = &pop_tile_table[code];
|
||||
const piece *lt = &pop_tile_table[lcode];
|
||||
uint8_t rbl_code;
|
||||
uint8_t rbl_code, rbl_mod;
|
||||
uint8_t wmod;
|
||||
|
||||
/* тайл снизу-слева (для topright). Ниже нижнего ряда — берём ряд 0
|
||||
@@ -250,11 +275,28 @@ static void draw_tile(int row, int col)
|
||||
* load_rowbelow (seg008:368). См. BUG-SEAM-WEDGE-1. */
|
||||
if (lc < 0) rbl_code = pop_t_below ? (uint8_t)(pop_t_below[10] & 0x1F) : 20;
|
||||
else rbl_code = pop_t_below ? (uint8_t)(pop_t_below[lc] & 0x1F) : 1;
|
||||
} else rbl_code = pop_tile_code(row + 1, col - 1);
|
||||
/* Модификатора ряда снизу у нас нет (pop_t_below — только fg), а он
|
||||
* нужен паласной панели над воротами. Ставим 0 = «панели нет»:
|
||||
* случай узкий (ворота в комнате СНИЗУ, по диагонали от пустого
|
||||
* тайла нижнего ряда), но расхождение с оригиналом честное. */
|
||||
rbl_mod = 0;
|
||||
} else {
|
||||
rbl_code = pop_tile_code(row + 1, col - 1);
|
||||
rbl_mod = pop_tile_mod(row + 1, col - 1);
|
||||
}
|
||||
|
||||
/* --- draw_tile_anim_topright (seg008:0568): верх ВОРОТ снизу-слева.
|
||||
* Условие дословно: свой тайл пуст / верх большой колонны / верх двери,
|
||||
* а снизу-слева — ворота. --- */
|
||||
if ((code == 0 || code == 9 || code == 12) && rbl_code == 4) {
|
||||
uint8_t om = (rbl_mod > 188) ? 188 : rbl_mod;
|
||||
pop_env_b(GATE_TOP_MASK, x, dby); /* маска (mono, чёрным) */
|
||||
pop_env_b(DOOR_FRAM_TOP[(om >> 2) & 7], x, dby);
|
||||
}
|
||||
|
||||
/* --- floorright (seg008.c:392) — только can_see_bottomleft --- */
|
||||
if (code == 0 || code == 9 || code == 12 || code == 26) {
|
||||
draw_topright(rbl_code, x, dby);
|
||||
draw_topright(rbl_code, rbl_mod, x, dby);
|
||||
/* floor-right тень (blitters_9_black) на ЧЁРНОМ фоне = no-op
|
||||
* (чёрный силуэт по чёрному) — не рисуем. Если tile_left имеет
|
||||
* floor_right: lt->floor_right. */
|
||||
@@ -263,6 +305,10 @@ static void draw_tile(int row, int col)
|
||||
/* --- draw_tile_right (seg008.c:456) --- */
|
||||
if (code != 20) {
|
||||
if (lcode == 20) {
|
||||
/* Полоска на стене (seg008:510) — только палас и только если у
|
||||
* стены не взведён старший бит модификатора. */
|
||||
if (PALACE && (lmod & 0x80) == 0)
|
||||
pop_env_b(84, x + 3 * 8, dmy - 27);
|
||||
pop_wall_b(1, x, pop_tile_table[20].right_y + dmy); /* грань стены */
|
||||
} else if (lcode == 0) {
|
||||
if (lmod <= 3 && BLUELINE_FRAM1[lmod])
|
||||
@@ -271,15 +317,26 @@ static void draw_tile(int row, int col)
|
||||
uint8_t num;
|
||||
pop_env_b(42, x, pop_tile_table[1].right_y + dmy); /* правый треуг. пола */
|
||||
num = (lmod <= 3) ? lmod : 0;
|
||||
if (num != 0) /* dungeon: level_type=0 */
|
||||
/* seg008:501 — `if (num == !!level_type) return;`: в подземелье
|
||||
* пропускается num==0, в паласе num==1. */
|
||||
if (num != (PALACE ? 1 : 0))
|
||||
pop_env_b(BLUELINE_FRAM3[num], x, dmy - 20); /* силуэт кладки */
|
||||
} else if (lcode == 7 || lcode == 12) {
|
||||
/* Низ декоративной панели над воротами (seg008:506) — только
|
||||
* палас; в подземелье у doortop right_id нулевой и ветка пустая. */
|
||||
if (PALACE && DOORTOP_FRAM_BOT[lmod & 3])
|
||||
pop_env_b(DOORTOP_FRAM_BOT[lmod & 3], x, lt->right_y + dmy);
|
||||
} else {
|
||||
if (lt->right_id)
|
||||
pop_env_b(lt->right_id, x, lt->right_y + dmy);
|
||||
/* Орнаментная лента соседа (seg008:486) — только палас. Она и
|
||||
* даёт непрерывную полосу под окнами: stripe_id = 145 у пола,
|
||||
* кнопок, зелья, loose, чомпера и меча. */
|
||||
if (PALACE && lt->stripe_id)
|
||||
pop_env_b(lt->stripe_id, x, dmy - 27);
|
||||
/* Основание факела (seg008:489): рисует ПРАВЫЙ сосед. */
|
||||
if (lcode == 19 || lcode == 30)
|
||||
pop_env_b(146, x, dby - 28);
|
||||
/* stripe — только палас, dungeon пропускает */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,8 +382,9 @@ static void draw_tile(int row, int col)
|
||||
uint8_t base_id = t->base_id;
|
||||
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) /* opener, слева пусто */
|
||||
base_id = 148; /* левая половина без пола */
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user