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

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