/*
 * _gfx_blit_full — bracket-free ядро блита под-прямоугольника картинки
 * getimage-формата (см. gfx_blit_part).  Клип по экрану + нарезка на
 * полосы ≤256 + вызов accel-leaf'а _bgi_copy_rows_raw.  БЕЗ _bgi_begin/
 * _bgi_end и БЕЗ смены банка — вызывающий обязан замапить W3 (_bgi_begin)
 * и выставить нужный _gfx_bank ДО вызова.
 *
 * Вынесено из gfx_blit_part (2026-07-12) ради batch-пасса спрайтового
 * движка v2: sprite_update держит одну W3-скобку и один банк на ВЕСЬ
 * проход, вызывая это ядро в цикле по спрайтам (амортизация обвязки —
 * см. docs/sprite-api-design.md §9.1).  gfx_blit_part теперь = _bgi_begin
 * + это ядро + _bgi_end.
 *
 * Clip fast-path: если прямоугольник целиком на экране — 4 сравнения
 * вместо полного пути коррекции краёв (TODO «клип fast-path»).
 */
#include "../_bgi.h"

void _gfx_blit_full(int x, int y, const void *img,
                    int sx, int sy, int w, int h)
{
    const uint8_t *p = (const uint8_t *)img;
    const uint8_t *src;
    uint16_t dst;
    int img_w;

    /* img_w — ПОЛНАЯ ширина картинки/ленты из заголовка getimage
     * (p[0]=lo, p[1]=hi); это шаг между строками источника (sstride).
     * sx/sy — смещение кадра внутри картинки (атлас).  Подробный разбор
     * формата и sx/sy — в common/_gfx_blit_sprite.c. */
    img_w = p[0] | (p[1] << 8);

    /* Клип по экрану — только если хоть один край вылезает. */
    if (x < 0 || y < 0 || x + w > _bgi_maxx + 1 || y + h > _bgi_maxy + 1) {
        if (x < 0) { sx -= x; w += x; x = 0; }
        if (y < 0) { sy -= y; h += y; y = 0; }
        if (x + w > _bgi_maxx + 1) w = _bgi_maxx + 1 - x;
        if (y + h > _bgi_maxy + 1) h = _bgi_maxy + 1 - y;
        if (w <= 0 || h <= 0) return;
    }

    /* src = img + 4 + sy*img_w + sx; sy*img_w умножением (__mulint,
     * O(1)) — цикл сложений был O(sy), см. _gfx_blit_sprite.c. */
    src = p + 4 + sx;
    if (sy)
        src += (uint16_t)sy * (uint16_t)img_w;

    dst = _gfx_addr_base + x;
    while (w > 256) {
        _bgi_blit_rows_raw(src, (uint8_t *)dst, 0 /* =256 */, (uint8_t)h,
                           img_w, (uint8_t)y);
        src += 256;
        dst += 256;
        w -= 256;
    }
    _bgi_blit_rows_raw(src, (uint8_t *)dst, (uint8_t)w, (uint8_t)h,
                       img_w, (uint8_t)y);
}
