29-May-86 07:33:11-PDT,6294;000000000001 Return-Path: Received: FROM ATHENA.MIT.EDU BY USC-ISIB.ARPA WITH TCP ; 29 May 86 07:32:45 PDT Received: by ATHENA (5.45/4.7) id AA04243; Thu, 29 May 86 10:31:56 EDT Received: by JASON (5.45/4.7) id AA09933; Thu, 29 May 86 10:32:11 EDT Message-Id: <8605291432.AA09933@JASON> To: info-ibmpc@usc-isib Subject: SINE.C from Dr Dobbs 5/86 Date: Thu, 29 May 86 10:32:08 -0500 From: Mark Colan Hi, I typed in the SINE.C example program from Dr Dobb's Journal, May 1986. The article describes a simple plotting routine for the IBM EGA in high resolution (640x350) graphics mode. Author is Nabajyoti Barkakati. The program typed in is nearly but not EXACTLY verbatum. Execution of the program illustrates the slowness of drawing dots using the BIOS interface. Enjoy! Mark Colan MIT Project Athena --------------------------SINE.C BEGINS HERE---------------------------- /* * SINE.C * * Plot sin(x) vs x on an enhanced color display with an IBM enhanced * graphics adapter in the high resolution mode. Purpose is to test * the video routines. */ #include #include #define BLUE 1 /* Color number 1 is BLUE */ #define RED 4 /* Color number 4 is RED */ #define BOTTOM 4 /* Bottom margin */ #define TOP 345 /* Top margin */ #define LEFT 4 /* Left margin */ #define RIGHT 635 /* Right margin */ #define TWOPI 6.283 /* approximate value of 2*pi */ #define MAXPNT 100 /* Points on the sinusoid */ main() { int i, x, y, oldx, oldy, midpoint; double xd, yd, ampl; v_init(RED); /* initialize the display */ midpoint = (TOP - BOTTOM)/2; ampl = (double)midpoint - (double)BOTTOM; oldx = LEFT; oldy = midpoint; for (i=0; i<=MAXPNT; i++) { yd = ampl * sin(TWOPI * ((double)i)/((double)MAXPNT)); xd = ((double)RIGHT - (double)LEFT) * (double)i / (double)MAXPNT; x = LEFT + (int)xd; y = midpoint + (int)yd; /* * Draw a line from the old point to the new point */ v_draw(oldx, oldy, x, y, BLUE); /* * save the new coordinates */ oldx = x; oldy = y; } /* * Draw a box around the plot */ v_draw(LEFT, BOTTOM, RIGHT, BOTTOM, BLUE); v_draw(RIGHT, BOTTOM, RIGHT, TOP, BLUE); v_draw(RIGHT, TOP, LEFT, TOP, BLUE); v_draw(LEFT, TOP, LEFT, BOTTOM, BLUE); exit(0); } /* * VIDEO.C * * This file contains the video display modules. Uses the int86 function of * Lattice C 2.15 to draw graphs on an enhanced color display with the IBM * Enhanced Graphics Adapter. * * by N. Barkakati, Silver Sprint, MD 20904 */ #include #define void int #define EGAMODE 16 /* ROM BIOS call: EGA hi res (640x350) mode */ #define MAXROW 24 #define MAXCOLUMN 79 #define MAXYDOT 349 /* max rows on EGA */ #define MAXXDOT 639 /* max columns on EGA */ #define BIOS_VIDEO 16 /* BIOS Video service interrupt number */ #define SETMODE 0 /* Service: set video mode */ #define SETCOLOR 11 /* Service: set color palette */ #define WRITE_PIX 12 /* Service: write pixel */ static union REGS xr,yr; /* see dos.h for explanation */ /* * v _ i n i t * * Initialize the display: * put EGA into high-resolution mode * set background color */ void v_init(bgcolor) int bgcolor; { /* * set high resolution mode */ xr.h.ah = SETMODE; xr.h.al = EGAMODE; int86(BIOS_VIDEO, &xr, &yr); /* * set background color */ xr.h.ah = SETCOLOR; xr.h.bh = 0; xr.h.bl = bgcolor; int86(BIOS_VIDEO, &xr, &yr); } /* * v _ d r a w * * Draw a line of specified color between the two points (x1,y1) * and (x2,y2). Uses Bresenham's Algorithm described in J.D. Foley * and A Van Dam, FUNDAMENTALS OF INTERACTIVE COMPUTER GRAPHICS, * Addison-Wesley, 1982, pp.433-435. */ void v_draw(x1, y1, x2, y2, color) int x1, y1, x2, y2, color; { int dx, dy, incr1, incr2, incr3, d, x, y, xend, yend; dx = abs(x2-x1); dy = abs(y2-y1); if (dy <= dx) { /* * absolute value of slope of line is less than 1 */ if (x1 > x2) { /* * start at point with smaller x coordinate */ x = x2; y = y2; xend = x1; dy = y1-y2; } else { x = x1; y = y1; xend = x2; dy = y2-y1; } d = (2 * dy) - dx; incr1 = 2 * dy; incr2 = 2 * (dy - dx); incr3 = 2 * (dy + dx); putdot(x, y, color); while (x++ < xend) { if (d >= 0) { if (dy <= 0) { /* * negative or zero slope */ d += incr1; } else { /* * positive slope */ y++; d += incr2; } } else { if (dy >= 0) { /* * negative or zero slope */ d += incr1; } else { /* * positive slope */ y--; d += incr3; } } putdot(x, y, color); } } else { /* * absolute value of slope is greater than 1 */ if (y1 > y2) { /* * start with smaller y coordinate */ y = y2; x = x2; yend = y1; dx = x1 - x2; } else { y = y1; x = x1; yend = y2; } d = (2 * dx) - dy; incr1 = 2 * dx; incr2 = 2 * (dx - dy); incr3 = 2 * (dx + dy); putdot(x, y, color); while (y < yend) { y++; if (d >= 0) { if (dx <= 0) { /* * negative or zero slope */ d += incr1; } else { /* * positive slope */ x++; d += incr2; } } else { if (dx >= 0) { /* * negative or zero slope */ d += incr1; } else { /* * positive slope */ d += incr3; x--; } } putdot(x, y, color); } } } /* * p u t d o t * * Put a dot of specified color at location (x,y) on screen. Check if * dot coordinates are within screen bounds. * * ^ y-axis * |_______ * Convention: | | Origin at lower left corner of screen * | | * |_______|__ x-axis * (0,0) */ void putdot(x, y, color) int x, y, color; { if ( x<0 | x>MAXXDOT | y<0 | y>MAXYDOT ) return; xr.x.dx = MAXYDOT - y; xr.x.cx = x; xr.h.ah = WRITE_PIX; xr.h.al = color; int86( BIOS_VIDEO, &xr, &yr ); }