Отражение в зеркале: fore-проход поверх него (ноги/голова вылезали из арки)

Симптом (скриншоты пользователя, ур. 4): у отражения видны ноги ниже
нижней кромки зеркала, а на прыжке — голова и руки выше верхней.  В
оригинале и то и другое скрыто.

Причина: над отражением не шёл fore-проход.  В SDLPoP отражение уходит в
objtable (add_objtable(4), seg003:0798), и передний слой тайлов накрывает
его на общих основаниях — у зеркала это fore_id 77, ПЕРЕДНЯЯ ЧАСТЬ АРКИ.
Именно она прячет всё, что вылезло из проёма.  Клип obj_clip_top этого не
делает и делать не может: при curr_row = 0 он равен y_clip[1] = 3, то есть
режет только по верху поля.

У нас отражение рисуется мимо конвейера персонажей (сокращённый путь, как
и в оригинале), поэтому проход надо звать руками — ровно как это делает
pop_char_fore для слотов: pop_fore_set_clip по нарисованному
прямоугольнику + pop_fore_over_char(&Char, ...) с ЛОГИЧЕСКОЙ x кадра.

Порядок сходится сам: pop_check_mirror стоит до отрисовки персонажей, так
что получается отражение -> его fore -> Кид -> его fore, и каждый ставит
своё окно клипа.

Банк 4: 9590 -> 9770.  tests-host: все 5 наборов прошли.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-10 22:19:14 +03:00
parent 8f0362f3d4
commit 3913f1eb7d
+16 -1
View File
@@ -666,7 +666,7 @@ void pop_mirror_draw(int clip_top) __banked
const uint8_t *img;
uint8_t page, idx, flip;
uint16_t w, h, vis_w;
int fwd, obj_x, obj_y, bx, top, skip = 0, rows, cl;
int fwd, obj_x, obj_y, fp_x, bx, top, skip = 0, rows, cl;
uint8_t lskip = 0;
if (fr->image == 255) return;
@@ -678,6 +678,7 @@ void pop_mirror_draw(int clip_top) __banked
obj_x = (fwd << 1) - 116;
obj_y = (int)Char.y + fr->dy;
if ((int8_t)(fr->flags ^ Char.direction) >= 0) obj_x++;
fp_x = obj_x; /* ЛОГИЧЕСКАЯ X — её ждёт fore-проход */
obj_x = scr_x(obj_x);
img = (const uint8_t *)atlas_image(&kidp[page], idx);
@@ -725,6 +726,20 @@ void pop_mirror_draw(int clip_top) __banked
mi_x[dp] = bx + lskip; mi_y[dp] = top;
mi_w[dp] = (uint16_t)(vis_w - lskip); mi_h[dp] = (uint16_t)rows;
mi_valid[dp] = 1;
/* FORE-ПРОХОД ПОВЕРХ ОТРАЖЕНИЯ — обязателен, и без него картинка неверна.
* В оригинале отражение уходит в objtable (add_objtable(4)), а дальше его
* накрывает передний слой тайлов на общих основаниях; у зеркала это
* fore_id 77 — ПЕРЕДНЯЯ ЧАСТЬ АРКИ. Именно она прячет то, что вылезло из
* проёма: ноги ниже нижней кромки и голову с руками выше верхней (видно
* на прыжке). Клип obj_clip_top этого НЕ делает — при curr_row = 0 он
* равен y_clip[1] = 3, то есть почти не режет; работу выполняет фон.
*
* Мы рисуем отражение мимо конвейера персонажей, поэтому проход надо
* позвать руками — ровно как это делает pop_char_fore для слотов. */
pop_fore_set_clip(bx + lskip, top + POP_YOFF,
(int)(vis_w - lskip), rows);
pop_fore_over_char(&Char, fp_x, obj_y, w, h);
}
/* ---- Индикаторы HP (порт draw_kid_hp / draw_guard_hp, seg000:1416) --- *