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 / RGE.C < prev    next >
C/C++ Source or Header  |  1992-02-26  |  6KB  |  296 lines

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