Уровень 4: skip по маске тайлов + порт loose_land, ворота 0xFF, пламя в фон
ОПТИМИЗАЦИЯ. Метка «фон трогали» была одним union-прямоугольником на страницу, и три факела комнаты склеивались в полосу x 40..280 на всю комнату — Кид, стоящий между крайними факелами, терял пропуск перерисовки и каждый кадр платил полным fore-проходом. Теперь это маска тайлов (uint16_t pop_cd_dmask[2][3]: бит = колонка, слово = ряд, набор = страница), проверка — три AND через резидентный pop_cd_hit. Гранулярность тайла — это гранулярность оригинала (redraw_frames_anim[tilepos], set_wipe; подтайловое уточнение там только по высоте, wipe_heights). Замер на (1,7): циан 233 515 -> 24 781, работа за кадр 517 609 -> 306 553, период 4 -> 3 растровых кадра. BUG-LOOSE-BUTTON-1. Упавшая плита не нажимала кнопку. Три слоя: порт loose_land не звал trigger_button вовсе; pop_room_col_landing считала площадкой только чистый пол, а у оригинала их семь (пол, пика, обе кнопки, зелье, оба факела); сигнал приходил в момент ОТРЫВА плиты, из-за чего ворота начинали открываться, пока она ещё в воздухе. Нажатие в оригинале ОДНО, но с button_type = tiles_14_debris — это «открыть НАСОВСЕМ» (modifier 0xFF), и кнопка съедается. Посадка в комнате снизу переехала на новый сигнал pop_loose_exit (взводит mob_tick_one, когда кусок ушёл ниже поля). BUG-GATE-FF-1. 0xFF был перегружен: сторожевое «тайла нет» в gate_modif и живое «открыто навсегда» из trigger_gate. gate_passable заворачивал Кида в воротах, нарисованных открытыми. Мёртвая ветка убрана. BUG-TORCH-CHOMP-1. Чомпер (0,7) комнаты 23 healит x 224..255 / y 30..93 и стирал пламя факела (0,6), которое рисуется в ячейке правого соседа. Фикс — запекать пламя (GFX_BANK_NORMAL): у факела все девять кадров на общем канвасе 16x18 и непрозрачны, протухнуть в ОЗУ-копии нечему, а heal чомпера сам возвращает огонь и кладёт челюсти поверх — z-порядок как в оригинале. Пузырёк зелья так нельзя (ползёт вверх, нужен heal) — остаётся в SPRITE. Заведено открытым: died_on_button (seg007:776) не портирован — нужен тайл tiles_5_stuck в атласе. Проверено пользователем в MAME (уровень 4: плита 16(1,1) -> кнопка 17(0,1) -> ворота 23(0,9); комната 23 с чомпером и факелом); make -C tests-host — все 5 наборов. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -54,6 +54,8 @@
|
||||
#define TILE_WALL 20
|
||||
#define TILE_LOOSE 11 /* проваливающийся пол */
|
||||
#define TILE_DEBRIS 14 /* щебень (упавший loose) */
|
||||
#define TILE_TORCH 19 /* факел */
|
||||
#define TILE_TORCH_DEBRIS 30 /* факел + щебень (loose_land) */
|
||||
#define TILE_SPIKE 2 /* пики */
|
||||
#define TILE_CLOSER 6 /* кнопка-закрывалка (DROP) */
|
||||
#define TILE_POTION 10 /* зелье */
|
||||
@@ -319,7 +321,14 @@ uint8_t pop_gate_modif(int8_t col, int8_t row) __banked
|
||||
static uint8_t gate_passable(int8_t col, int8_t row)
|
||||
{
|
||||
uint8_t gm = gate_modif(col, row);
|
||||
if (gm == 0xFF) return 0;
|
||||
/* Ветки `if (gm == 0xFF) return 0;` здесь БЫТЬ НЕ ДОЛЖНО: 0xFF — это не
|
||||
* только сторожевое «тайла нет» из gate_modif, но и живой модификатор
|
||||
* «ворота открыты НАСОВСЕМ» (trigger_gate по button_type = щебень,
|
||||
* seg007:623). Значение это появилось только когда заработал порт
|
||||
* loose_land, и ворота выходили нарисованными открытыми (отрисовка
|
||||
* клампит modl>188 -> 188), но непроходимыми. Сторож сюда не приходит:
|
||||
* зовут нас только там, где тайл ТОЧНО ворота, а (0xFF>>2)+6 = 69 и так
|
||||
* больше любого fph. */
|
||||
return (uint8_t)((gm >> 2) + 6) >= (uint8_t)CD_ACT->fph;
|
||||
}
|
||||
|
||||
@@ -2126,9 +2135,24 @@ void pop_loose_tick(void) __banked
|
||||
if (pop_loose_landed) { /* loose_land (seg007:11E8): на месте куска — щебень */
|
||||
uint8_t pos = (uint8_t)(pop_loose_landed - 1);
|
||||
uint8_t r = 0, c = pos;
|
||||
uint8_t tt = (uint8_t)(g_fg[pos] & 0x1F); /* тайл, НА который села плита */
|
||||
pop_loose_landed = 0;
|
||||
while (c >= 10) { c -= 10; r++; }
|
||||
g_fg[pos] = TILE_DEBRIS;
|
||||
/* Плита, севшая на КНОПКУ, её нажимает (seg007:11E8, ветки
|
||||
* tiles_15_opener / tiles_6_closer). Тонкость: на opener оригинал
|
||||
* подставляет button_type = tiles_14_debris, а это у trigger_gate
|
||||
* отдельная ветка «открыть НАСОВСЕМ» (возврат 2 -> animate_door
|
||||
* доводит створку и ставит modifier 0xFF, после чего ворота
|
||||
* заморожены и обычный opener их больше не трогает). Сама кнопка
|
||||
* съедается: тайл станет щебнем ниже, нажаться второй раз нечему.
|
||||
* Модификатор (индекс LINKLOC) тайл не меняет, берём его как есть. */
|
||||
if (tt == TILE_OPENER || tt == TILE_CLOSER)
|
||||
pop_trigger_button(g_room, pos,
|
||||
(uint8_t)(tt == TILE_OPENER ? TILE_DEBRIS : tt),
|
||||
pop_trob_modif(g_room)[pos]);
|
||||
/* На факеле — отдельный тайл «факел с щебнем» (seg007:1067). */
|
||||
g_fg[pos] = (uint8_t)((tt == TILE_TORCH || tt == TILE_TORCH_DEBRIS)
|
||||
? TILE_TORCH_DEBRIS : TILE_DEBRIS);
|
||||
/* Перерисовка ПО ПЛОЩАДИ ПОЛА (не LOOSE_GONE: та стирает и верх стены
|
||||
* ряда ниже — оставался чёрный прямоугольник под тайлом). Обе
|
||||
* страницы дабл-буфера. */
|
||||
|
||||
Reference in New Issue
Block a user