Отражение в зеркале: 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:
@@ -666,7 +666,7 @@ void pop_mirror_draw(int clip_top) __banked
|
|||||||
const uint8_t *img;
|
const uint8_t *img;
|
||||||
uint8_t page, idx, flip;
|
uint8_t page, idx, flip;
|
||||||
uint16_t w, h, vis_w;
|
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;
|
uint8_t lskip = 0;
|
||||||
|
|
||||||
if (fr->image == 255) return;
|
if (fr->image == 255) return;
|
||||||
@@ -678,6 +678,7 @@ void pop_mirror_draw(int clip_top) __banked
|
|||||||
obj_x = (fwd << 1) - 116;
|
obj_x = (fwd << 1) - 116;
|
||||||
obj_y = (int)Char.y + fr->dy;
|
obj_y = (int)Char.y + fr->dy;
|
||||||
if ((int8_t)(fr->flags ^ Char.direction) >= 0) obj_x++;
|
if ((int8_t)(fr->flags ^ Char.direction) >= 0) obj_x++;
|
||||||
|
fp_x = obj_x; /* ЛОГИЧЕСКАЯ X — её ждёт fore-проход */
|
||||||
obj_x = scr_x(obj_x);
|
obj_x = scr_x(obj_x);
|
||||||
|
|
||||||
img = (const uint8_t *)atlas_image(&kidp[page], idx);
|
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_x[dp] = bx + lskip; mi_y[dp] = top;
|
||||||
mi_w[dp] = (uint16_t)(vis_w - lskip); mi_h[dp] = (uint16_t)rows;
|
mi_w[dp] = (uint16_t)(vis_w - lskip); mi_h[dp] = (uint16_t)rows;
|
||||||
mi_valid[dp] = 1;
|
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) --- *
|
/* ---- Индикаторы HP (порт draw_kid_hp / draw_guard_hp, seg000:1416) --- *
|
||||||
|
|||||||
Reference in New Issue
Block a user