/* Побайтовый регресс gfx_scroll_h/gfx_scroll_v. * Источник — неактивная page 1, приёмник — draw page 0. */ #include #include #include #define AX 10 #define AY 24 #define AW 300 /* проверяет разбиение ширины 255+45 */ #define AH 160 #define DIRT 0x31 static uint8_t pattern(int x, int y) { return (uint8_t)(0x40 + ((x * 3 + y * 5) & 0x3f)); } static void draw_source(void) { int x, y; for (y = AY; y < AY + AH; y++) for (x = AX; x < AX + AW; x++) putpixel(x, y, pattern(x, y)); } static void clear_target(void) { setfillstyle(SOLID_FILL, DIRT); bar(0, 0, 319, 255); } static uint8_t rect_eq(const gfx_rect_t *r, int x, int y, int w, int h) { return r->x == x && r->y == y && r->w == w && r->h == h; } static uint8_t check_h(int dx) { gfx_rect_t a = { AX, AY, AW, AH }, d; int x, y, sx; clear_target(); gfx_scroll_h(&a, dx, &d); if (dx > 0) { if (!rect_eq(&d, AX, AY, dx, AH)) return 0; } else if (dx < 0) { if (!rect_eq(&d, AX + AW + dx, AY, -dx, AH)) return 0; } else if (!rect_eq(&d, AX, AY, 0, AH)) return 0; for (y = AY; y < AY + AH; y++) for (x = AX; x < AX + AW; x++) { sx = x - dx; if (sx >= AX && sx < AX + AW) { if ((uint8_t)getpixel(x, y) != pattern(sx, y)) return 0; } else if ((uint8_t)getpixel(x, y) != DIRT) return 0; } return 1; } static uint8_t check_v(int dy) { gfx_rect_t a = { AX, AY, AW, AH }, d; int x, y, sy; clear_target(); gfx_scroll_v(&a, dy, &d); if (dy > 0) { if (!rect_eq(&d, AX, AY, AW, dy)) return 0; } else if (!rect_eq(&d, AX, AY + AH + dy, AW, -dy)) return 0; for (y = AY; y < AY + AH; y++) for (x = AX; x < AX + AW; x++) { sy = y - dy; if (sy >= AY && sy < AY + AH) { if ((uint8_t)getpixel(x, y) != pattern(x, sy)) return 0; } else if ((uint8_t)getpixel(x, y) != DIRT) return 0; } return 1; } static uint8_t check_limits(void) { gfx_rect_t a = { -5, -7, 25, 27 }, d; gfx_scroll_h(&a, 40, &d); if (!rect_eq(&d, 0, 0, 20, 20)) return 0; gfx_scroll_v(&a, -40, &d); return rect_eq(&d, 0, 0, 20, 20); } static uint8_t check_source(void) { int x, y; gfx_set_draw_page(1); for (y = AY; y < AY + AH; y++) for (x = AX; x < AX + AW; x++) if ((uint8_t)getpixel(x, y) != pattern(x, y)) { gfx_set_draw_page(0); return 0; } gfx_set_draw_page(0); return 1; } static void say(int y, const char *name, uint8_t ok) { setcolor(WHITE); outtextxy(8, y, (char *)name); setcolor(ok ? GREEN : RED); outtextxy(232, y, ok ? (char *)"PASS" : (char *)"FAIL"); } void main(void) { uint8_t t[7], i; initgraph(); gfx_set_bank(GFX_BANK_NORMAL); gfx_set_draw_page(1); draw_source(); gfx_set_draw_page(0); t[0] = check_h(8); t[1] = check_h(-13); t[2] = check_v(9); t[3] = check_v(-11); t[4] = check_limits(); t[5] = check_h(0); t[6] = check_source(); clear_target(); say(40, "H +8, wide", t[0]); say(56, "H -13, wide", t[1]); say(72, "V +9, wide", t[2]); say(88, "V -11, wide", t[3]); say(104, "clip/full dirty", t[4]); say(120, "H zero/full copy", t[5]); say(136, "source intact", t[6]); for (i = 0; i < 7 && t[i]; i++) { } setcolor(WHITE); outtextxy(8, 160, i == 7 ? (char *)"ALL PASS" : (char *)"SOME FAILED"); for (;;) { } }