From b49ba1566619111e5b568f578a1ef655c98473e1 Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Tue, 18 Aug 2026 15:11:33 +0300 Subject: [PATCH] =?UTF-8?q?DIED-ON-BUTTON:=20=D0=BD=D0=B0=D0=B9=D0=B4?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=B2=D1=82=D0=BE=D1=80=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=BE=D0=B2=D0=B8=D0=BD=D0=B0=20=E2=80=94=20?= =?UTF-8?q?=D1=84=D0=B8=D0=B7=D0=B8=D0=BA=D0=B0=20=D1=82=D1=80=D1=83=D0=BF?= =?UTF-8?q?=D0=B0=20=D0=B2=D1=8B=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=20=D1=86=D0=B5=D0=BB=D0=B8=D0=BA=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Кид гибнет на кнопке открытия решётки (уровень 7, комната 3, тайл 2,1) — в оригинале решётка открыта насовсем, у нас отжимается. Мало того, что died_on_button (seg007:776) не портирован: pop_phys_tick целиком выходит по pop_kid_dead, так что check_press до трупа не доходит вовсе. У оригинала play_kid_frame гейтится только Char.room != 0. Фикса пока нет — запись в BUGS_OPEN. Co-Authored-By: Claude Opus 5 --- applications/PoP/roomtest/BUGS_OPEN.md | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/applications/PoP/roomtest/BUGS_OPEN.md b/applications/PoP/roomtest/BUGS_OPEN.md index 6f585bd..b120a68 100644 --- a/applications/PoP/roomtest/BUGS_OPEN.md +++ b/applications/PoP/roomtest/BUGS_OPEN.md @@ -329,6 +329,46 @@ if (curr_tile2 == tiles_15_opener || curr_tile2 == tiles_6_closer) { Что нужно: сам порт `died_on_button`, константа `TILE_STUCK = 5` и тайл заклиненной кнопки в атласе фона (сейчас его там нет). +### Вторая половина: до `check_press` труп вообще не доходит (2026-08-18) + +Найдено на живом сценарии (пользователь): уровень 7 начинается падением, и +если не зацепиться за кромку, Кид разбивается на `(2,1)` комнаты 3 — а это +кнопка открытия решётки. В оригинале решётка после этого открыта НАСОВСЕМ, +у нас отжимается. + +Оказалось, порта `died_on_button` мало — до него нет пути: + +```c +void pop_phys_tick(void) __banked +{ + if (pop_kid_dead) return; /* <- вся физика трупа выключена */ +``` + +У оригинала `play_kid_frame` (seg000:1231) гейт ровно один — `Char.room != 0`; +весь список, включая `check_press`, крутится и на трупе (по `alive` разведены +только `check_spiked`/`check_chomped_kid`, и то через `resurrect_time`). + +Отсюда наблюдаемое поведение: кнопка получает РОВНО ОДНО нажатие — в кадре +самой смерти, потому что `pop_kid_dead` ставит `land()` уже ВНУТРИ цепочки, +после раннего возврата. Решётка успевает приоткрыться и потом закрывается. +Снято в MAME: Кид `frame 185, action 5 (bumped), alive 0, (2,1) room 3`, +`pop_kid_dead = 1`, тайл `(2,1)` = `0x0F` opener, modif `0x12` (индекс связи), +openness ворот `(2,6)` ползёт вниз (146 → 112). + +Кадр смерти проходит проверки `check_press` штатно (`action == ACT_BUMPED`, +флаги кадра 185 = `0x49`, бит `FRAME_NEEDS_FLOOR` есть) — то есть после снятия +раннего возврата труп начнёт давить кнопку КАЖДЫЙ кадр, как живой. Это ещё +не оригинал: там на `alive >= 0` уходит `died_on_button`, который делает +эффект ПОСТОЯННЫМ и снимает кнопку с тайла. Значит чинить надо обе половины +разом, иначе получится «кнопка держится, пока труп лежит» — поведение, +которого нет ни в оригинале, ни сейчас. + +**Побочное наблюдение, НЕ проверено:** openness ворот остановился на 112 и +дальше не убывал, хотя `animate_door` (у нас совпадает с seg007:0522) обязан +досчитать до 0 и снять trob. Довести проверку не удалось — в сцене залип +`frozen` (клавиша фриза осталась в raw-битмапе, `2` перестала сниматься). +Если подтвердится — это отдельный баг, к `died_on_button` отношения не имеющий. + ---