/* * rgv.c by Quincey Koziol for NCSA * * graphics routines for drawing on EGA * Input coordinate space = 0..4095 by 0..4095 * MUST BE COMPILED WITH LARGE MEMORY MODEL! * */ #include #include #include /* used for VGA init call */ #include "externs.h" #define TRUE 1 #define FALSE 0 #define INXMAX 4096 #define INXSHIFT 12 #define INYMAX 4096 #define INYSHIFT 12 #define SCRNXHI 639 #define SCRNYHI 479 #define VGAxmax 640 /* max. number of pixels in the x direction */ #define VGAymax 480 /* max. number of pixels in the y direction */ #define VGAbytes 80 /* number of bytes per line */ #define MAXRW 32 /* max. number of real windows */ static int VGAactive; /* number of currently EGAactive window */ static char *VGAname="Video Graphics Array, 640 x 480"; /* Current status of an VGA window */ struct VGAWIN { char inuse; /* true if window in use */ int pencolor, rotation, size; int winbot,winleft,wintall,winwide; /* position of the window in virtual space */ }; static struct VGAWIN VGAwins[MAXRW]; /* Set up a new window; return its number. Returns -1 if cannot create window. */ int RGVnewwin(void) { int w=0; while(w>INXSHIFT); y2=SCRNYHI-(int)(((long)y*VGAymax)>>INYSHIFT); VGAset(x2,y2,VGAwins[w].pencolor); } } /* draw a line from (x0,y0) to (x1,y1) */ /* uses Bresenham's Line Algorithm */ void RGVdrawline(int w,int x0,int y0,int x1,int y1) { int x,y,dx,dy,d,temp, dx2,dy2, /* 2dx and 2dy */ direction; /* +1 or -1, used for slope */ char transpose; /* true if switching x and y for vertical-ish line */ #ifdef DEBUG printf("RGVdrawline(): x0=%d, y0%d\n",x0,y0); printf("x1=%d, y1=%d\n",x1,y1); #endif if(w!=VGAactive) return; x0=(int)(((long)x0*VGAxmax)>>INXSHIFT); y0=VGAymax-1-(int)((VGAymax*(long)y0)>>INYSHIFT); x1=(int)(((long)x1*VGAxmax)>>INXSHIFT); y1=VGAymax-1-(int)((VGAymax*(long)y1)>>INYSHIFT); if(abs(y1-y0)>abs(x1-x0)) { /* transpose vertical-ish to horizontal-ish */ temp=x1; x1=y1; y1=temp; temp=x0; x0=y0; y0=temp; transpose=TRUE; } else transpose=FALSE; /* make sure line is left to right */ if(x1 1 POINT */ x=x0; y=y0; dx=x1-x0; if(y1>=y0) { dy=y1-y0; direction=1; } else { dy=y0-y1; direction=-1; } dx2=dx<<1; dy2=dy<<1; d=(dy<<1)-dx; if(transpose) { /* CASE OF VERTICALISH (TRANSPOSED) LINES */ while(x<=x1) { if(y>=0 && y< VGAxmax && x>=0 && x=0) { y+=direction; d-=dx2; } d+=dy2; x++; } } else { /* CASE OF HORIZONTALISH LINES */ while(x<=x1) { if(x>=0 && x=0 && y=0) { y+=direction; d-=dx2; } d+=dy2; x++; } } /* end horizontalish */ } /* end RGVdrawline() */ /* Do whatever has to be done when the drawing is all done. (For printers, that means eject page.) */ void RGVpagedone(int w) { /* do nothing for VGA */ w=w; } /* Copy 'count' bytes of data to screen starting at current cursor location. */ void RGVdataline(int w,char *data,int count) { /* Function not supported yet. */ w=w; data=data; count=count; } /* Change pen color to the specified color. */ void RGVpencolor(int w,int color) { if(!color) color=1; color&=0x7; /* flip color scale */ VGAwins[w].pencolor=8-color; } /* Set description of future device-supported graphtext. Rotation=quadrant. */ void RGVcharmode(int w,int rotation,int size) { /* No rotatable device-supported graphtext is available on VGA. */ w=w; rotation=rotation; size=size; } /* Not yet supported: */ void RGVshowcur(void) {} void RGVlockcur(void) {} void RGVhidecur(void) {} /* Ring bell in window w */ void RGVbell(int w) { if(w==VGAactive) putchar(7); } /* return name of device that this RG supports */ char *RGVdevname(void ) { return(VGAname); } /* Make this window visible, hiding all others. Caller should follow this with clrscr and redraw to show the current contents of the window. */ void RGVuncover(int w) { VGAactive=w; } /* initialize all RGV variables */ void RGVinit(void) { int i; for(i=0; i