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 своей ячейки + правой грани (дальний угол в
|
`pop_button_redraw` — wipe своей ячейки + правой грани (дальний угол в
|
||||||
0,3), низ строго yb+64 (не залезать в стену ряда 1).
|
0,3), низ строго yb+64 (не залезать в стену ряда 1).
|
||||||
|
|
||||||
|
## НЕ БАГИ (кривая картинка, но совпадает с оригиналом — НЕ чинить)
|
||||||
|
|
||||||
|
- **Голова стоящего Кида поверх падающей на него loose-плиты.** Комната 12:
|
||||||
|
зацеп не удался, Кид остался стоять, сбитая плита падает прямо на него —
|
||||||
|
голова рисуется ПОВЕРХ плиты. Сверено покадрово с SDLPoP v1.24 (2026-07-29):
|
||||||
|
там ровно то же самое. Артефакт оригинального движка (порядок midtable), а
|
||||||
|
не наш баг; «починка» увела бы от эталона. Отличать от соседних случаев,
|
||||||
|
которые БЫЛИ нашими багами и исправлены: вис/подтягивание на кромке плиты и
|
||||||
|
падение вместе с плитой — там плита обязана быть поверх Кида.
|
||||||
|
|
||||||
## Заметки
|
## Заметки
|
||||||
|
|
||||||
- Тестовые клавиши осторожного шага: **J** = шаг влево, **L** = шаг вправо
|
- Тестовые клавиши осторожного шага: **J** = шаг влево, **L** = шаг вправо
|
||||||
@@ -438,7 +448,7 @@ Kid ставится на первый пол, `pop_trob_reset()` возвращ
|
|||||||
| 9 | | |
|
| 9 | | |
|
||||||
| 10 | | |
|
| 10 | | |
|
||||||
| 11 | | |
|
| 11 | | |
|
||||||
| 12 | | |
|
| 12 | пофикшено | вис/подтягивание на кромке loose-плиты: плита рисовалась ПОД Кидом. Не хватало двух кусков `draw_tile`: (а) `draw_loose` кладёт нижнюю грань плиты И в foretable (поверх персонажа), (б) `draw_tile_base` подставляет верх плиты из `loose_fram_left`, а в нашем midtable-оверлее стоял голый `base_id` (у loose он 0). Голова Кида поверх падающей на него плиты — см. «НЕ БАГИ» |
|
||||||
| 13 | недостижима в игре | |
|
| 13 | недостижима в игре | |
|
||||||
| 14 | | |
|
| 14 | | |
|
||||||
| 15 | | |
|
| 15 | | |
|
||||||
|
|||||||
@@ -1137,6 +1137,17 @@ static void ceil_over_kid_tile(int col)
|
|||||||
|
|
||||||
static void fore_tile(int row, 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-часть. Раньше здесь
|
/* draw_tile_fore (seg008:690) — ТОЛЬКО add_foretable-часть. Раньше здесь
|
||||||
* рисовалась ещё и передняя кромка пола (bottom_id) «чтобы перекрывала
|
* рисовалась ещё и передняя кромка пола (bottom_id) «чтобы перекрывала
|
||||||
* Kid», но в оригинале bottom идёт через draw_tile_bottom в backtable
|
* 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); /* тайл + правый сосед (грани) */
|
ov_mark(x, 63 * row + 2, 64, 64); /* тайл + правый сосед (грани) */
|
||||||
if (code != 20 && lcode == 1) /* draw_tile_right: только 42 */
|
if (code != 20 && lcode == 1) /* draw_tile_right: только 42 */
|
||||||
env_b(42, x, tile_table[1].right_y + dmy);
|
env_b(42, x, tile_table[1].right_y + dmy);
|
||||||
if (t->base_id) /* draw_tile_base (loose base = 0) */
|
{ /* draw_tile_base (seg008:0A8E) — ЦЕЛИКОМ, вместе с подстановками id:
|
||||||
env_b(t->base_id, x, t->base_y + dmy);
|
* у 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: свои пики */
|
if (code == 2) { /* draw_tile_anim: свои пики */
|
||||||
uint8_t sm = tile_mod(row, col);
|
uint8_t sm = tile_mod(row, col);
|
||||||
uint8_t sf = (sm & 0x80) ? 5 : sm;
|
uint8_t sf = (sm & 0x80) ? 5 : sm;
|
||||||
|
|||||||
Reference in New Issue
Block a user