/* * putimage — вывести образ bitmap левым-верхним углом в (left,top) * операцией op. Заголовок буфера: uint16 width, uint16 height. * * COPY_PUT — через accel-ядро gfx_blit_part (block-copy строками, до * 256 байт за burst; Фаза A спрайтового дизайна) — С КЛИППИНГОМ по * экрану (superset поведения Turbo C, где выход за экран — UB) и * с учётом текущего банка (gfx_set_bank: 0x58 даёт аппаратную * прозрачность 0xFF, 0x54/0x5C — временный вывод). * * XOR/OR/AND/NOT_PUT — тоже через акселератор (gfx_blit_part_op, * 2026-08-11; закрыт пункт 2d-1 docs/TODO.md): у железа есть блочные * AND/OR/XOR между буфером акселератора и памятью приёмника, а NOT * выражается через XOR по блоку единиц. Попиксельного пути в putimage * больше НЕТ ВООБЩЕ, и клиппинг у всех пяти операций теперь одинаковый * (раньше на непрямом пути его не было вовсе). * * Оговорки — в шапке common/_gfx_blit_full_op.c: операция читает * ОЗУ-копию экрана (при банках 0x54/0x5C это чистый фон, а не то, что * нарисовано поверх), а прозрачность #FF совместима с AND/OR, но не с XOR. * * Буфер bitmap обязан лежать вне W3 (< 0xC000) — на время операции W3 * замаплен на видеобанк. */ #include "../_bgi.h" void putimage(int left, int top, const void *bitmap, int op) { const uint8_t *p = (const uint8_t *)bitmap; int w, h; uint8_t gop; w = p[0] | (p[1] << 8); h = p[2] | (p[3] << 8); if (w <= 0 || h <= 0) return; switch (op) { case XOR_PUT: gop = GFX_OP_XOR; break; case OR_PUT: gop = GFX_OP_OR; break; case AND_PUT: gop = GFX_OP_AND; break; case NOT_PUT: gop = GFX_OP_NOT; break; case COPY_PUT: default: gfx_blit_part(left, top, bitmap, 0, 0, w, h); return; } gfx_blit_part_op(left, top, bitmap, 0, 0, w, h, gop); }