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:
@@ -132,6 +132,16 @@ openness рисует `bar(BLACK)` по всему col0 + **полный `draw_t
|
||||
`pop_button_redraw` — wipe своей ячейки + правой грани (дальний угол в
|
||||
0,3), низ строго yb+64 (не залезать в стену ряда 1).
|
||||
|
||||
## НЕ БАГИ (кривая картинка, но совпадает с оригиналом — НЕ чинить)
|
||||
|
||||
- **Голова стоящего Кида поверх падающей на него loose-плиты.** Комната 12:
|
||||
зацеп не удался, Кид остался стоять, сбитая плита падает прямо на него —
|
||||
голова рисуется ПОВЕРХ плиты. Сверено покадрово с SDLPoP v1.24 (2026-07-29):
|
||||
там ровно то же самое. Артефакт оригинального движка (порядок midtable), а
|
||||
не наш баг; «починка» увела бы от эталона. Отличать от соседних случаев,
|
||||
которые БЫЛИ нашими багами и исправлены: вис/подтягивание на кромке плиты и
|
||||
падение вместе с плитой — там плита обязана быть поверх Кида.
|
||||
|
||||
## Заметки
|
||||
|
||||
- Тестовые клавиши осторожного шага: **J** = шаг влево, **L** = шаг вправо
|
||||
@@ -438,7 +448,7 @@ Kid ставится на первый пол, `pop_trob_reset()` возвращ
|
||||
| 9 | | |
|
||||
| 10 | | |
|
||||
| 11 | | |
|
||||
| 12 | | |
|
||||
| 12 | пофикшено | вис/подтягивание на кромке loose-плиты: плита рисовалась ПОД Кидом. Не хватало двух кусков `draw_tile`: (а) `draw_loose` кладёт нижнюю грань плиты И в foretable (поверх персонажа), (б) `draw_tile_base` подставляет верх плиты из `loose_fram_left`, а в нашем midtable-оверлее стоял голый `base_id` (у loose он 0). Голова Кида поверх падающей на него плиты — см. «НЕ БАГИ» |
|
||||
| 13 | недостижима в игре | |
|
||||
| 14 | | |
|
||||
| 15 | | |
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user