/* * getimage — сохранить прямоугольник экрана в буфер bitmap. * Формат: uint16 width, uint16 height, затем w*h байт (по строкам). * * Через accel-ядро: _bgi_copy_rows_raw строками экран→буфер (Фаза A * спрайтового дизайна). Чтение экрана возвращает ОЗУ-копию (видео-ОЗУ * write-only) — после рисования в temp-банке (0x54/0x5C) getimage * вернёт ФОН, а не то, что на экране (это и есть механизм heal). * * Клиппинга нет (контракт BGI: rect валиден); safe-версия отсекает * выход за экран целиком. Буфер bitmap обязан лежать вне W3 * (< 0xC000) — на время операции W3 замаплен на видеобанк. */ #include "../_bgi.h" void getimage(int left, int top, int right, int bottom, void *bitmap) { uint8_t *p = (uint8_t *)bitmap; const uint8_t *src; int w = right - left + 1; int h = bottom - top + 1; int rem; if (w <= 0 || h <= 0) return; #ifndef GFX_NOCHECK if (left < 0 || top < 0 || right > _bgi_maxx || bottom > _bgi_maxy) return; #endif *p++ = (uint8_t)w; *p++ = (uint8_t)(w >> 8); *p++ = (uint8_t)h; *p++ = (uint8_t)(h >> 8); /* Полосы <= 256 байт (лимит блока акселератора); шаг строки * буфера — полная ширина w у ОБЕИХ полос (полосы одной строки * лежат в буфере подряд). */ src = (const uint8_t *)(_gfx_addr_base + left); rem = w; _bgi_begin(); while (rem > 256) { _bgi_copy_rows_raw(src, p, 0 /* =256 */, (uint8_t)h, w, 0, (uint8_t)top); src += 256; p += 256; rem -= 256; } _bgi_copy_rows_raw(src, p, (uint8_t)rem, (uint8_t)h, w, 0, (uint8_t)top); _bgi_end(); }