L4-MIRROR шаги 3 и 5 + левый клип колонок в libbgi

libbgi: новая gfx_blit_cols_part_wx — обрезка СЛЕВА (skipw) в дополнение к
верхней (skip/rows) и правой (maxw).  По подсказке пользователя сделано
примитивом, а не обходным путём «нарисовать и вернуть фон поверх лишнего»:
для column-major левая обрезка стоит ровно столько же, сколько правая —
колонка это непрерывный кусок ОЗУ, меняется стартовая колонка источника и
экранная X.  Внутри это уже было (так клипается левый край экрана), наружу
не было выведено.  Полное тело блита колонками переехало туда,
gfx_blit_cols_part_w стала обёрткой (skipw=0).  size-check: OK, роста нет
(62 программы, -22..-33 Б на пользователей блита).

Шаг 5 — клип ТЕНИ (seg008:1699): на уровне зеркала она показывается только
СПРАВА от него, obj_clip_left = 137 + (mirror_column-4)*32.

Шаг 3 — ОТРАЖЕНИЕ (check_mirror, seg003:0798): пока Кид стоит на тайле
зеркала, каждый кадр рисуется его зеркальная копия с клипом
left = (curr_col<<5)+9 и top = y_clip[curr_row+1].  Отдельной функцией
pop_mirror_draw, а НЕ третьим слотом Char — это структура самого оригинала:
отражение идёт сокращённым путём load_frame_to_obj + add_objtable(4), без
клинка, брызг, fore-прохода и пропуска кадра; гейтить всё это в общем теле
значило бы добавить ветки в самый горячий путь.  Свой heal (pop_mirror_heal)
рядом с pop_char_heal, в skip-маске не участвует.

tests-host: заглушки pop_mirror_draw/pop_mirror_heal (pop_map теперь на них
ссылается), все 5 наборов прошли.

Цена: _CODE 24501 -> 24629, банк 3 10551, банк 4 8267 -> 9590.
НЕ ПРОВЕРЕНО В MAME.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-10 22:09:45 +03:00
parent 844fa6d767
commit 8f0362f3d4
8 changed files with 259 additions and 67 deletions
+24 -5
View File
@@ -2613,11 +2613,30 @@ static void jump_through_mirror(void)
hitp_curr = 1;
}
/* Линия клипа отражения СВЕРХУ — y_clip[curr_row+1] оригинала. Таблица та
* же, что в pop_clip_char_top; держим её здесь копией из четырёх значений,
* а не тащим наружу: ряд у отражения всегда 0..2. */
static int mirror_clip_top(int8_t row)
{
static const int16_t y_clip[5] = { -60, 3, 66, 129, 192 };
int8_t r = (int8_t)(row + 1);
if (r < 0 || r > 4) return 0;
return (int)y_clip[r];
}
void pop_check_mirror(void) __banked
{
if (pop_jumped_mirror == -1) jump_through_mirror();
/* Ветка ОТРИСОВКИ ОТРАЖЕНИЯ (шаг 3 задачи L4-MIRROR) сюда добавится
* позже: пока Кид стоит на тайле зеркала, оригинал каждый кадр рисует
* его зеркальную копию типом 4 objtable с клипом left = (curr_col<<5)+9
* и top = y_clip[curr_row+1]. */
if (pop_jumped_mirror == -1) { jump_through_mirror(); return; }
/* Отражение: пока Кид СТОИТ на тайле зеркала, рисуем его зеркальную
* копию (в оригинале — add_objtable(4)). Условия оригинала: тайл под
* персонажем — зеркало, distance_mirror >= 0 (вошёл в тайл достаточно
* глубоко) и его комната = отрисованная. */
if (Kid.room != g_room) return;
pop_loadkid();
if (get_tile_at_char() != TILE_MIRROR) return;
pop_load_frame();
if (mirror_image() >= 0)
pop_mirror_draw(mirror_clip_top(Char.curr_row));
/* Char остался ОТРАЖЁННЫМ — как в оригинале: обратно он не сохраняется,
* а следующий тик перезагружает окно из Kid. */
}