Разбор порядка отрисовки падающей плиты: найден корень, выбран вариант B
СИМПТОМ (пользователь, ур.11 к.14). Кусок, отвалившийся от плиты нижнего ряда, рисуется ПОВЕРХ соседней трясущейся плиты; при этом передний торец соседа лежит поверх куска — порядок противоречив в разных частях перекрытия. КОРЕНЬ. draw_mob (seg007:13E5) считает ряд объекта как y_to_row_mod4(y) = (y+60)/63 % 4 - 1. Из-за % 4 ряд 3 (кусок ушёл ниже комнаты) и ряд −1 (кусок у потолка) дают ОДНО значение −1. Оригинал прогоняет его через get_tilepos -> get_tilepos_nominus и получает тайл 30, а объекты с тайлом 30 рисуются в redraw_needed_tiles ПЕРВЫМИ, до всего обхода тайлов. Мы же передаём сырой −1 в мид-оверлей как «тайл объекта», и гейт `row > pop_bg_obj_row` читает его как «объект в последнем ряду обхода», то есть «объект поверх всего», и отбрасывает возврат соседа. Один и тот же −1 у нас значит «сверху», у оригинала — «снизу». Торец при этом виден потому, что приходит из ДРУГОГО слоя: draw_loose кладёт loose_fram_bottom в backtable и foretable, минуя ptr_add_table, — тело плиты обязан вернуть мид-оверлей, а его и выключает гейт. ЧТО ПРОВЕРЕНО ЗАМЕРОМ (журнал решений в pop_dbg_ovl/pop_dbg_pass, зонды ВРЕМЕННЫЕ и будут сняты): - на застывшем кадре: слот draw_y=194, r=−1, rt=2, оверлей позван, внутри отбрасывается гейтом; - пропуск оверлея на последнем кадре полёта ЗАКОНЕН: габарит куска уже ниже габарита тайла, перекрывать нечего; - в 13/23 кусок перекрывают 2-4 тайла (накопленно за полёт), включая СВОЮ клетку, — то есть «сосед справа» покрытие не исчерпывает; - перерисовок тайлов за кадр в 13/23: максимум 6, в покое 0. ТУПИКИ, чтобы не ходить второй раз. Клип объекта тут ни при чём: add_mob_to_objtable ставит clip.right = 40, но клип применяется только при chtab_flip_clip[chtab_id], а для chtab_6_environment там 0 — поле игнорируется и в оригинале. Пункт MOB-CLIP-RIGHT закрывается как несуществующий. Добавлять торец плиты в мид-оверлей тоже не надо: в foretable он уже кладётся из fore_tile. ВЫБРАН ВАРИАНТ B: классифицировать ряд объекта (вне 0..2 = корзина 30), отдавать оверлею ориентир «раньше любого тайла» и расширить набор перекрываемых тайлов на СВОЮ клетку. Переносить проход отрисовки не нужно — heal при этом не участвует, работа та же (оверлей = два блита в окне клипа), разница с узким вариантом A всего один-два оверлея на кусок. Заодно записана ОБЯЗАТЕЛЬНАЯ задача HEAL-WIDTH: ширины точечных heal'ов взяты по клеткам (64), а фактический след плиты — 58/57 (замерено по атласам: верх 32, правая грань 26 в подземелье и 25 во дворце). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -87,6 +87,20 @@ void pop_dbg_trap(void) { pop_dbg_hits++; }
|
||||
* смена комнаты видна по скачку tilepos, а нам удобнее явно). */
|
||||
int8_t pop_dbg_obj[9];
|
||||
|
||||
/* ВРЕМЕННО (разбор оверлея падающего куска): по слоту mob.
|
||||
* pop_dbg_pass[i] — что было в проходе отрисовки:
|
||||
* bit0 рассмотрен, bit1 active, bit2 draw_y задан, bit3 defer совпал,
|
||||
* bit4 нарисован, bit5 позван mob_overlay_neighbour.
|
||||
* pop_dbg_ovl[i*4 + 0..3] — что решил mob_overlay_neighbour:
|
||||
* [0] r+128, [1] rt+128, [2] флаги, [3] col.
|
||||
* Флаги: bit0 вошли, bit1 c<=9, bit2 tile(r,c), bit3 габарит r,
|
||||
* bit4 ВЫЗОВ по r, bit5 tile(rt,c), bit6 габарит rt, bit7 ВЫЗОВ по rt. */
|
||||
uint8_t pop_dbg_pass[14];
|
||||
uint8_t pop_dbg_ovl[14 * 4];
|
||||
/* ВРЕМЕННО: какие тайлы РЕАЛЬНО перекрывают спрайт куска. Бит
|
||||
* (ряд+1)*2 + (0 своя колонка / 1 соседняя), ряды −1..2. */
|
||||
uint8_t pop_dbg_tiles[14];
|
||||
|
||||
/* Зеркало уровня 4 — см. pop_state.h. */
|
||||
int8_t pop_jumped_mirror;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user