PoP roomtest: loose-плита поверх Кида (порт draw_loose + draw_tile_base)

Комната 12, вис и подтягивание на кромке loose-плиты над дырой от
соседней упавшей: плита рисовалась ПОД Кидом — он лез на неё «с
переднего края» вместо проёма.  Не хватало двух кусков draw_tile:

1. draw_loose (seg008:0A38) кладёт нижнюю грань плиты (loose_fram_bottom)
   В ОБЕ таблицы — backtable И foretable, безусловно.  Это единственный
   кусок тайла с таким поведением: у обычного пола bottom идёт только в
   backtable, а fore_id = 0.  Добавлено в fore_tile (наш проход foretable
   по тайлам футпринта Кида); ceiling-случай это уже делал отдельно.
2. draw_tile_base (seg008:0A8E) подставляет id: у loose верх плиты берётся
   из loose_fram_left, у opener'а без пола слева — 148.  В нашем
   midtable-оверлее (overlay_mid_tile) стоял голый tile_table.base_id, а у
   loose он 0 — верх плиты в оверлей не попадал, и поверх Кида ложилась
   только передняя грань.  Перенесён draw_tile_base целиком.

Проверено в MAME: кадр виса на кромке целой плиты (frame 89, x=95,
col 2) — плита закрывает Кида, наружу торчат только пальцы, как в SDLPoP.

Голова стоящего Кида поверх падающей НА НЕГО плиты — артефакт САМОГО
оригинала (сверено с SDLPoP v1.24), не чинить: записано в bug_list.md
(раздел «НЕ БАГИ») и в memory.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-29 16:14:23 +03:00
parent 517d225091
commit 5f5eefc9fc
2 changed files with 36 additions and 3 deletions
+25 -2
View File
@@ -1137,6 +1137,17 @@ static void ceil_over_kid_tile(int col)
static void fore_tile(int row, int col) /* передний слой одного тайла */
{
/* draw_loose (seg008:0A38) — единственный кусок ТАЙЛА, который оригинал
* кладёт В ОБЕ таблицы БЕЗУСЛОВНО: нижняя грань loose-плиты идёт и в
* backtable, и в foretable. Значит передняя грань плиты рисуется ПОВЕРХ
* персонажа ВСЕГДА, а не только у потолка (ceil_over_kid_tile). Верх
* плиты (draw_tile_base) остаётся в backtable — поэтому голова и руки
* висящего/подтягивающегося Kid видны НАД плитой, а тело уходит ЗА неё.
* Без этого Kid лез на плиту «с переднего края» (комната 12: вис на
* кромке loose над дырой от соседней упавшей плиты). */
if (row >= 0 && tile_code_drawn(row, col) == 11)
env_b(LOOSE_FRAM_BOTTOM[get_loose_frame(pop_loose_modif[row * 10 + col])],
COL_XH[col] * 8, 63 * row + 65);
/* draw_tile_fore (seg008:690) — ТОЛЬКО add_foretable-часть. Раньше здесь
* рисовалась ещё и передняя кромка пола (bottom_id) «чтобы перекрывала
* Kid», но в оригинале bottom идёт через draw_tile_bottom в backtable
@@ -1200,8 +1211,20 @@ static void overlay_mid_tile(int row, int col)
ov_mark(x, 63 * row + 2, 64, 64); /* тайл + правый сосед (грани) */
if (code != 20 && lcode == 1) /* draw_tile_right: только 42 */
env_b(42, x, tile_table[1].right_y + dmy);
if (t->base_id) /* draw_tile_base (loose base = 0) */
env_b(t->base_id, x, t->base_y + dmy);
{ /* draw_tile_base (seg008:0A8E) — ЦЕЛИКОМ, вместе с подстановками id:
* у loose верх плиты берётся из loose_fram_left (в tile_table base_id=0),
* у opener'а без пола слева — 148. Раньше здесь стоял голый base_id, и
* верх loose-плиты в оверлей не попадал: передняя грань ложилась поверх
* Kid (foretable), а сама плита — нет, и подтягивающийся Kid рисовался
* поверх её верхней плоскости (комната 12). */
uint8_t base_id = t->base_id;
if (code == 11 && row >= 0)
base_id = LOOSE_FRAM_LEFT[get_loose_frame(pop_loose_modif[row * 10 + col])];
else if (code == 0x0F && lcode == 0)
base_id = 148;
if (base_id)
env_b(base_id, x, t->base_y + dmy);
}
if (code == 2) { /* draw_tile_anim: свои пики */
uint8_t sm = tile_mod(row, col);
uint8_t sf = (sm & 0x80) ? 5 : sm;