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