/* VGADEMO -- VGA graphics demo. Pixels, lines. line1() is the original 'C' line function. line2() is an optimized version with assembly language. rectangle() is the un-filled rectangle procedure. putrow() draws a horizontal line using assembly language. fillrect1() is the slow filled rectangle procedure. fillrect2() is the fast filled rectangle procedure. circle1() uses floating point arithmetic. circle2() uses integer arithmetic. circle3() also uses the circle's symmetry. */ #include #include void setmode(int mode); void cls(void); void putpixel(int x, int y, int color); int getpixel(int x, int y); void line1(int x1, int x2, int y1, int y2, int color); void line2(int x1, int x2, int y1, int y2, int color); void rectangle(int x1, int y1, int x2, int y2, int color); void fillrect1(int x1, int y1, int x2, int y2, int color); void putrow(int x1, int x2, int y, int color); void fillrect2(int x1, int y1, int x2, int y2, int color); void circle1(int x, int y, int r, int color); void circle2(int x, int y, int r, int color); void circle3(int x, int y, int r, int color); main() { int i; setmode(0x13); while(!kbhit()) { for(i = 0; i < 100; i++) putpixel(random(320), random(200), random(256)); } while(kbhit()) getch(); cls(); while(!kbhit()) { for(i = 0; i < 40; i++) line1(random(320), random(200), random(320), random(200), random(256)); } while(kbhit()) getch(); cls(); while(!kbhit()) { for(i = 0; i < 40; i++) line2(random(320), random(200), random(320), random(200), random(256)); } while(kbhit()) getch(); cls(); while(!kbhit()) { for(i = 0; i < 40; i++) rectangle(random(320), random(200), random(320), random(200), random(256)); } while(kbhit()) getch(); cls(); while(!kbhit()) { for(i = 0; i < 10; i++) fillrect1(random(320), random(200), random(320), random(200), random(256)); } while(kbhit()) getch(); cls(); while(!kbhit()) { for(i = 0; i < 40; i++) fillrect2(random(320), random(200), random(320), random(200), random(256)); } while(kbhit()) getch(); cls(); while(!kbhit()) { for(i = 0; i < 10; i++) circle1(random(320), random(200), random(50), random(256)); } while(kbhit()) getch(); cls(); while(!kbhit()) { for(i = 0; i < 10; i++) circle2(random(320), random(200), random(50), random(256)); } while(kbhit()) getch(); cls(); while(!kbhit()) { for(i = 0; i < 10; i++) circle3(random(320), random(200), random(50), random(256)); } while(kbhit()) getch(); cls(); setmode(0x03); return 0; } void setmode(int mode) { asm { mov ax,mode; xor ah,ah; int 10h; } } void cls(void) { asm { mov ax,0A000h; /* ES = video memory */ mov es,ax; xor di,di; /* Set up for clear */ xor ax,ax; mov cx,8000h; rep stosw; /* Clear the screen */ } } void putpixel(int x, int y, int color) { asm { mov bx,x; /* BX = X, CX = Y */ mov cx,y; cmp bx,320; /* Clip to screen */ jae pp_done; cmp cx,200; jae pp_done; add bh,cl; /* BX = offset */ shl cx,6; add bx,cx; mov ax,0A000h; /* ES = video memory */ mov es,ax; mov ax,color; /* AX = color */ mov es:[bx],al; /* Plot pixel */ } pp_done: } int getpixel(int x, int y) { asm { mov bx,x; /* BX = X, CX = Y */ mov cx,y; add bh,cl; /* BX = offset */ shl cx,6; add bx,cx; mov ax,0A000h; /* ES = video memory */ mov es,ax; mov al,es:[bx]; /* Read pixel */ } return _AL; } void line1(int x1, int y1, int x2, int y2, int color) { int d, x, y, sx, sy, dx, dy; dx = x2 - x1; dy = y2 - y1; if(dx > 0) sx = 1; else sx = -1; if(dy > 0) sy = 1; else sy = -1; dx = abs(dx); dy = abs(dy); x = x1; y = y1; if(dx > dy) { d = (dy - dx) / 2; /* X is major axis */ while(x != x2) { putpixel(x, y, color); /* Put pixel */ if(d >= 0) { /* Minor-axis change? */ d -= dx; /* Decrease by 1 */ y += sy; } d += dy; /* Increase by dy/dx */ x += sx; } putpixel(x, y, color); /* Put last pixel */ } else { d = (dx - dy) / 2; /* Y is major axis */ while(y != y2) { putpixel(x, y, color); /* Put pixel */ if(d >= 0) { /* Minor-axis change? */ d -= dy; /* Decrease by 1 */ x += sx; } d += dx; /* Increase by dx/dy */ y += sy; } putpixel(x, y, color); /* Put last pixel */ } } #define PUT_PIXEL(x, y, c, q) \ asm { mov bx,x; mov cx,y; cmp bx,320; jae d##q; \ cmp cx,200; jae d##q; add bh,cl; shl cx,6; \ add bx,cx; mov ax,color; mov es:[bx],al; \ } d##q: void line2(int x1, int y1, int x2, int y2, int color) { int d, x, y, sx, sy, dx, dy; dx = x2 - x1; dy = y2 - y1; if(dx > 0) sx = 1; else sx = -1; if(dy > 0) sy = 1; else sy = -1; dx = abs(dx); dy = abs(dy); x = x1; y = y1; asm mov ax,0A000h; /* ES = video memory */ asm mov es,ax; if(dx > dy) { d = (dy - dx) / 2; /* X is major axis */ while(x != x2) { PUT_PIXEL(x, y, color, 0); /* Put pixel */ if(d >= 0) { /* Minor-axis change? */ d -= dx; /* Decrease by 1 */ y += sy; } d += dy; /* Increase by dy/dx */ x += sx; } PUT_PIXEL(x, y, color, 1); /* Put last pixel */ } else { d = (dx - dy) / 2; /* Y is major axis */ while(y != y2) { PUT_PIXEL(x, y, color, 2); /* Put pixel */ if(d >= 0) { /* Minor-axis change? */ d -= dy; /* Decrease by 1 */ x += sx; } d += dx; /* Increase by dx/dy */ y += sy; } PUT_PIXEL(x, y, color, 3); /* Put last pixel */ } } void rectangle(int x1, int y1, int x2, int y2, int color) { line2(x1, y1, x2, y1, color); line2(x1, y2, x2, y2, color); line2(x1, y1, x1, y2, color); line2(x2, y1, x2, y1, color); }; void fillrect1(int x1, int y1, int x2, int y2, int color) { int i; if(y1 > y2) { /* Put Y in order */ i = y1; y1 = y2; y2 = i; } for(i = y1; i <= y2; i++) line2(x1, i, x2, i, color); } void putrow(int x1, int x2, int y, int color) { asm mov ax,0A000h; /* ES = video memory */ asm mov es,ax; asm mov ax,y; /* Get parameters */ asm mov bx,x1; asm mov cx,x2; asm cmp ax,200; /* Y out of range? */ asm jae l4; asm cmp bx,cx; /* Put X in order */ asm jle l1; asm xchg bx,cx; l1: asm cmp cx,0; asm jl l4; /* Not visible? */ asm cmp bx,319; asm jg l4; asm cmp bx,0; /* Clip to screen */ asm jge l2; asm mov bx,0; l2: asm cmp cx,319; asm jle l3; asm mov cx,319; l3: asm mov di,bx; /* DI = offset */ asm shl ax,6; asm add di,ax; asm shl ax,2; asm add di,ax; asm sub cx,bx; /* CX = length */ asm inc cx; asm mov ax,color; /* AL, AH = color */ asm mov ah,al; asm shr cx,1; /* Store by words */ asm rep stosw; asm adc cx,0; /* Store possible odd byte */ asm rep stosb; l4: } void fillrect2(int x1, int y1, int x2, int y2, int color) { int i; if(y1 > y2) { /* Put Y in order */ i = y1; y1 = y2; y2 = i; } for(i = y1; i <= y2; i++) putrow(x1, x2, i, color); } void circle1(int x, int y, int r, int color) { int i; double ix, iy; if(r < 1) r = 1; ix = 0; iy = r; for(i = 0; i < (r * 6.283); i++) { putpixel(x + ix, y + iy, color); ix = ix + iy / r; iy = iy - ix / r; } } void circle2(int x, int y, int r, int color) { int i, ix, iy; if(r < 1) r = 1; ix = 0; iy = r * 64; for(i = 0; i < ((r * 44) / 7); i++) { putpixel(x + ix / 64, y + iy / 64, color); ix = ix + iy / r; iy = iy - ix / r; } } void circle3(int x, int y, int r, int color) { int ix, iy, a, b; if(r < 1) r = 1; ix = 0; iy = r * 64; do { a = (ix + 32) >> 6; b = (iy + 32) >> 6; putpixel(x + a, y + b, color); putpixel(x - a, y + b, color); putpixel(x + a, y - b, color); putpixel(x - a, y - b, color); putpixel(x + b, y + a, color); putpixel(x - b, y + a, color); putpixel(x + b, y - a, color); putpixel(x - b, y - a, color); ix = ix + iy / r; iy = iy - ix / r; } while(b > a); }