home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tel2305s.zip / RG / RGC.C < prev    next >
C/C++ Source or Header  |  1992-02-26  |  6KB  |  315 lines

  1. /*
  2. *  rgc.c by Aaron Contorer for NCSA
  3. *  graphics routines for drawing on CGA
  4. *  Input coordinate space = 0..4095 by 0..4095
  5. *  MUST BE COMPILED WITH LARGE MEMORY MODEL!
  6. */
  7.  
  8. #include <stdio.h>        /* used for debugging only */
  9. #include <stdlib.h>
  10. #include <dos.h>        /* for the FP_SEG & FP_OFF macros */
  11. #include "externs.h"
  12.  
  13. #define TRUE 1
  14. #define FALSE 0
  15. #define INXMAX 4096
  16. #define INXSHIFT 12
  17. #define INYMAX 4096
  18. #define INYSHIFT 12
  19. #define MAGNIFY 1000
  20. #define SCRNXHI 639
  21. #define SCRNYHI 199
  22. #define MAXRW 32        /* max. number of real windows */
  23. #define CGAxmax 640        /* max. number of pixels in the x direction */
  24. #define CGAymax 200        /* max. number of pixels in the y direction */
  25. #define CGAbytes 80        /* number of bytes per line */
  26.  
  27. static int CGAactive;        /* number of currently CGAactive window */
  28. static char *CGAvidram;
  29. static unsigned char CGApbit[SCRNXHI+1];
  30. #ifdef OLD_WAY
  31. static unsigned char power2[8] = {1,2,4,8,16,32,64,128};
  32. #endif
  33. static char *CGAname = "Color Graphics Adaptor, 640 x 200";
  34.  
  35. static void CGAsetup(void );
  36.  
  37. /* Current status of an CGA window */
  38. struct CGAWIN {
  39.     char inuse;         /* true if window in use */
  40.     int pencolor, rotation, size;
  41.     int winbot,winleft,wintall,winwide;
  42.                 /* position of the window in virtual space */
  43. };
  44.  
  45. static struct CGAWIN CGAwins[MAXRW];
  46.  
  47. /* prepare variables for use in other functions */
  48. static void CGAsetup(void )
  49. {
  50.     int x;
  51.     CGApbit[0]=128; 
  52.     CGApbit[1]=64; 
  53.     CGApbit[2]=32; 
  54.     CGApbit[3]=16;
  55.     CGApbit[4]=8;   
  56.     CGApbit[5]=4;  
  57.     CGApbit[6]=2;  
  58.     CGApbit[7]=1;
  59.     for(x=8; x<=SCRNXHI; x++) 
  60.         CGApbit[x]=CGApbit[x&7];
  61. #if defined(MSC) && !defined(__TURBOC__) && !defined(__WATCOMC__)
  62.     FP_SEG(CGAvidram) = 0xB800;
  63.     FP_OFF(CGAvidram) = 0;
  64. #else
  65.     CGAvidram=MK_FP(0xB800,0);
  66. #endif
  67. }
  68.  
  69. /* go into CGA graphics mode */
  70. void RGCgmode(void)
  71. {
  72.     n_gmode(6);                 /* 640x200 BW */
  73. }
  74.  
  75. /* go into CGA 80x25 color text mode */
  76. void RGCtmode(void)
  77. {
  78.     n_gmode(3);                 /* 80x25 color text */
  79.     CGAactive=-1;
  80. }
  81.  
  82. /* draw a line from (x0,y0) to (x1,y1) */
  83. /* uses Bresenham's Line Algorithm */
  84. void RGCdrawline(int w,int x0,int y0,int x1,int y1)
  85. {
  86.     int x,y,dx,dy,d,temp,
  87.     dx2,dy2,            /* 2dx and 2dy */
  88.     direction;            /*+1 or-1, used for slope */
  89.     char transpose;        /* true if switching x and y for vertical-ish line */
  90.  
  91.     if (w!=CGAactive) 
  92.         return;
  93.     x0=(int)(((long)x0*CGAxmax)>>INXSHIFT);
  94.     y0=CGAymax-1-(int)(((long)y0*CGAymax)>>INYSHIFT);
  95.     x1=(int)(((long)x1*CGAxmax)>>INXSHIFT);
  96.     y1=CGAymax-1-(int)(((long)y1*CGAymax)>>INYSHIFT);
  97.     if(abs(y1-y0)>abs(x1-x0)) {            /* transpose vertical-ish to horizontal-ish */
  98.         temp=x1; 
  99.         x1=y1; 
  100.         y1=temp;
  101.         temp=x0; 
  102.         x0=y0; 
  103.         y0=temp;
  104.         transpose=TRUE;
  105.       } 
  106.     else 
  107.         transpose=FALSE;
  108.                 /* make sure line is left to right */
  109.     if(x1<x0) {
  110.         temp=x1; 
  111.         x1=x0; 
  112.         x0=temp; 
  113.         temp=y1; 
  114.         y1=y0; 
  115.         y0=temp;
  116.       }
  117.                 /* SPECIAL CASE: 1 POINT */
  118.     if(x1==x0&&y1==y0) { 
  119.         CGAvidram[(y1&1)*8192+(y1>>1)*80+(x1>>3)]|=CGApbit[x1];
  120.         return;
  121.       }        
  122.                 /* ANY LINE > 1 POINT */
  123.     x=x0;
  124.     y=y0;
  125.     dx=x1-x0;
  126.     if(y1>=y0) {
  127.         dy=y1-y0;
  128.         direction=1;
  129.       } 
  130.     else {
  131.         dy=y0-y1;
  132.         direction=-1;
  133.       }
  134.     dx2=dx<<1;
  135.     dy2=dy<<1;
  136.     d=(dy<<1)-dx;
  137.     if(transpose) {    
  138.                 /* CASE OF VERTICALISH (TRANSPOSED) LINES */
  139.         while(x<=x1) {
  140.             if(y>=0&&y<CGAxmax&&x>=0&&x<CGAymax)
  141.                 CGAvidram[(x&1)*8192+(x>>1)*80+(y>>3)]|=CGApbit[y];
  142.             while(d>=0) {
  143.                 y+=direction;
  144.                 d -=dx2;
  145.               }
  146.             d+=dy2;
  147.             x++;
  148.               } 
  149.           } 
  150.     else {
  151.                 /* CASE OF HORIZONTALISH LINES */
  152.         while (x <= x1) {
  153.             if(x>=0&&x<CGAxmax&&y>=0&&y<CGAymax)
  154.                 CGAvidram[(y&1)*8192+(y>>1)*80+(x>>3)]|=CGApbit[x];
  155.             while(d>=0) {
  156.                 y+=direction;
  157.                 d-=dx2;
  158.               }
  159.             d+=dy2;
  160.             x++;
  161.           }
  162.       }         /* end horizontalish */
  163. }                 /* end CGArasline() */
  164.  
  165. /*
  166. *    Clear the screen.
  167. */
  168. void RGCclrscr(int w)
  169. {
  170.     if(w==CGAactive) {
  171.         CGAsetup();
  172.         RGCgmode();
  173.       }
  174. }
  175.  
  176. /*
  177. *    Set up a new window; return its number.
  178. *    Returns -1 if cannot create window.
  179. */
  180. int RGCnewwin(void)
  181. {
  182.     int w=0;
  183.  
  184.     while(w<MAXRW&&CGAwins[w].inuse) 
  185.         w++;
  186.     if(w==MAXRW)
  187.         return(-1); /* no windows available */
  188.     CGAwins[w].pencolor=7;
  189.     CGAwins[w].winbot=0;
  190.     CGAwins[w].wintall=3120;
  191.     CGAwins[w].winleft=0;
  192.     CGAwins[w].winwide=4096;
  193.     CGAwins[w].inuse=TRUE;
  194.     return(w);
  195. }
  196.  
  197. void RGCclose(int w)
  198. {
  199.     if(CGAactive==w) {
  200.         RGCclrscr(w);
  201.         CGAactive=-1;
  202.       }
  203.     CGAwins[w].inuse=FALSE;
  204. }
  205.  
  206. /* set pixel at location (x,y) -- no range checking performed */
  207. void RGCpoint(int w,int x,int y)
  208. {
  209.     int x2,y2; /* on-screen coordinates */
  210.  
  211.     if(w==CGAactive) {
  212.         x2=(int)(((long)x*CGAxmax)>>INXSHIFT);
  213.         y2=SCRNYHI-(int)(((long)y*CGAymax)>>INYSHIFT);
  214. #ifdef OLD_WAY
  215.         CGAvidram[y2*80+(x2>>3)]|=CGApbit[x2];
  216. #else
  217.         CGAvidram[(y&1)*8192+(y>>1)*80+(x>>3)]|=CGApbit[x2];
  218. #endif
  219.       }
  220. }  
  221.  
  222. /*
  223.     Do whatever has to be done when the drawing is all done.
  224.     (For printers, that means eject page.)
  225. */
  226. void RGCpagedone(int w)
  227. {
  228.     /* do nothing for CGA */
  229.     w=w;
  230. }
  231.  
  232. /*
  233.     Copy 'count' bytes of data to screen starting at current
  234.     cursor location.
  235. */
  236. void RGCdataline(int w,char *data,int count)
  237. {
  238.     /* Function not supported yet. */
  239.     w=w;
  240.     data=data;
  241.     count=count;
  242. }
  243.  
  244. /*
  245.     Change pen color to the specified color.
  246. */
  247. void RGCpencolor(int w,int color)
  248. {
  249.     /* Function not supported. */
  250.     w=w;
  251.     color=color;
  252. }
  253.  
  254. /*
  255.     Set description of future device-supported graphtext.
  256.     Rotation=quadrant.
  257. */
  258. void RGCcharmode(int w,int rotation,int size)
  259. {
  260.     /* No rotatable device-supported graphtext is available on CGA. */
  261.     w=w;
  262.     rotation=rotation;
  263.     size=size;
  264. }
  265.  
  266. /* Not yet supported: */
  267. void RGCshowcur(void) {}
  268. void RGClockcur(void) {}
  269. void RGChidecur(void) {}
  270.  
  271. /* Ring bell in window w */
  272. void RGCbell(int w)
  273. {
  274.     if(w==CGAactive)
  275.         putchar(7);
  276. }
  277.  
  278. /* return name of device that this RG supports */
  279. char *RGCdevname(void)
  280. {
  281.     return(CGAname);
  282. }
  283.  
  284. /* initialize all RGC variables */
  285. void RGCinit(void)
  286. {
  287.     int i;
  288.     CGAsetup();
  289.     for(i=0; i<MAXRW; i++)
  290.         CGAwins[i].inuse=FALSE;
  291.     CGAactive=-1;
  292. }
  293.  
  294. /*
  295. *    Make this window visible, hiding all others.
  296. *    Caller should follow this with clrscr and redraw to show the current
  297. *    contents of the window.
  298. */
  299. void RGCuncover(int w)
  300. {
  301.     CGAactive=w;
  302. }
  303.  
  304. /* Needed for possible future functionality */
  305. void RGCinfo(int w,int a,int b,int c,int d,int v)
  306. {
  307.     w=w;
  308.     a=a;
  309.     b=b;
  310.     c=c;
  311.     d=d;
  312.     v=v;
  313. }
  314.  
  315.