/*
 * _gfx_heal_full — bracket-free ядро heal прямоугольника экрана из
 * ОЗУ-копии (см. gfx_heal).  Клип по экрану + нарезка на полосы ≤256 +
 * вызов accel-leaf'а _bgi_heal_rows_raw (src == dst, strides 0).  БЕЗ
 * _bgi_begin/_bgi_end и БЕЗ смены банка — вызывающий обязан замапить W3
 * и выставить банк GFX_BANK_NORMAL (0x50) ДО вызова.
 *
 * Вынесено из gfx_heal (2026-07-12) ради batch-пасса движка v2:
 * sprite_update лечит ВСЕ старые позиции под одной W3-скобкой и одним
 * банком 0x50 (docs/sprite-api-design.md §9.1).  gfx_heal теперь =
 * save-банк + set 0x50 + _bgi_begin + это ядро + _bgi_end + restore.
 *
 * Clip fast-path: целиком на экране → 4 сравнения вместо полного пути.
 */
#include "../_bgi.h"

void _gfx_heal_full(int x, int y, int w, int h)
{
    uint8_t *scr;

    if (x < 0 || y < 0 || x + w > _bgi_maxx + 1 || y + h > _bgi_maxy + 1) {
        if (x < 0) { w += x; x = 0; }
        if (y < 0) { 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;
    }

    scr = (uint8_t *)(_gfx_addr_base + x);
    while (w > 256) {
        _bgi_heal_rows_raw(scr, y, 0 /* =256 */, (uint8_t)h);
        scr += 256;
        w   -= 256;
    }
    _bgi_heal_rows_raw(scr, y, (uint8_t)w, (uint8_t)h);
}
