Смерть на кнопке ломает её насовсем (died_on_button, seg007:776)
Уровень 7 начинается падением; разбившись на кнопке открытия решётки (комната 3, тайл 2,1), Кид в оригинале открывает решётку НАСОВСЕМ, а у нас она закрывалась обратно. Чинить пришлось три места. 1. pop_phys_tick выходил по pop_kid_dead, то есть check_press до трупа не доходил вовсе. У оригинала play_kid_frame гейтится только Char.room != 0. Кнопка получала одно нажатие — в кадре смерти, потому что флаг ставит land() уже внутри цепочки. «Труп не шевелится» держит внутренний выход в kid_phys, он остался. 2. Портирован died_on_button: открывалка → пол + связь дёргается типом «щебень» (открыть насовсем), прочие кнопки → TILE_STUCK. Ветки по Char.alive в check_press не было вовсе. 3. Рестарт уровня восстанавливал только foretable, а died_on_button оставляет таймер связи нажатым (trob кнопки умирает сразу — тайл уже пол). Остаток переживал респавн, и кнопка рисовалась нажатой с первого кадра. pop_level_reset_tiles теперь возвращает и LINKMAP. Проверено в MAME по всему циклу: смерть → FF (открыта навсегда), респавн → кнопка цела и не нажата, второе падение → снова ломается. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -192,7 +192,24 @@ int8_t pop_room_col_landing(uint8_t room, uint8_t col) __banked
|
||||
}
|
||||
|
||||
/* Рестарт уровня (порт load_level из цикла play_level, seg003:57): вернуть
|
||||
* foretable в исходное состояние из эталонной копии. */
|
||||
* в исходное состояние ВСЁ, что игра правит в данных уровня.
|
||||
*
|
||||
* Это foretable (из эталонной копии — сами данные мы правим на месте) И
|
||||
* ТАБЛИЦА СВЯЗЕЙ. Про вторую легко забыть, потому что мутирует в ней ровно
|
||||
* одно поле — таймер нажатия кнопки в младших битах LINKMAP, — но забыть
|
||||
* дорого: `pop_tile_code_drawn` рисует кнопку НАЖАТОЙ, пока таймер > 1, и
|
||||
* ненулевой остаток показывает её нажатой с первого кадра уровня.
|
||||
*
|
||||
* Оставить такой остаток особенно легко из died_on_button: он ставит таймер
|
||||
* в 5 и заводит trob кнопки, но тайл к этому моменту УЖЕ пол — trob умирает
|
||||
* в первом же обходе (`default: type = -1`), не успев ни разу уменьшить
|
||||
* таймер. У оригинала ровно то же самое, просто там load_level перечитывает
|
||||
* весь файл целиком, и вопроса не возникает (найдено пользователем
|
||||
* 2026-08-18: уровень 7, комната 3, кнопка (2,1) после первого же респавна).
|
||||
*
|
||||
* LINKMAP в странице уровня остаётся ЭТАЛОННЫМ: игра правит только
|
||||
* ОЗУ-копию pop_dl2 (pop_doorlink2_set), обратно в страницу не пишет никто —
|
||||
* поэтому отдельная pristine-копия, как у foretable, тут не нужна. */
|
||||
void pop_level_reset_tiles(void) __banked
|
||||
{
|
||||
uint16_t i;
|
||||
@@ -203,6 +220,8 @@ void pop_level_reset_tiles(void) __banked
|
||||
dst = (uint8_t *)(LVL_DATA_OFF + BP_FG);
|
||||
src = (const uint8_t *)LVL_PRISTINE_OFF;
|
||||
for (i = 0; i < 24u * ROOM_TILES; i++) dst[i] = src[i];
|
||||
src = (const uint8_t *)(LVL_DATA_OFF + BP_LINKMAP);
|
||||
for (i = 0; i < 256; i++) pop_dl2[i] = src[i];
|
||||
gfx_w0_unmap();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user