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

  1. /*
  2. *
  3. *  rgh.c by Aaron Contorer for NCSA
  4. *
  5. *  graphics routines for drawing on Hercules monochrome card
  6. *  Input coordinate space = 0..4095 by 0..4095
  7. *  MUST BE COMPILED WITH LARGE MEMORY MODEL!
  8. *
  9. *  RGH = routines callable from outside
  10. *  HGC = routines for internal use only
  11. *
  12. */
  13. #include <stdio.h>    /* used for debugging only */
  14. #include <stdlib.h>
  15. #include <dos.h>    /* used for HGC init call */
  16. #ifdef MSC
  17. #include <conio.h>
  18. #endif
  19. #include "externs.h"
  20.  
  21. #ifdef __TURBOC__
  22. #define outpw outport
  23. #endif
  24.  
  25. #define TRUE 1
  26. #define FALSE 0
  27. #define INXMAX 4096
  28. #define INXSHIFT 12
  29. #define INYMAX 4096
  30. #define INYSHIFT 12
  31. #define MAGNIFY 1000
  32. #define SCRNXHI 719
  33. #define SCRNYHI 347
  34. #define MAXHERC 32        /* max. number of Hercules windows */
  35. #define HGCxmax 720        /* max. number of pixels in the x direction */
  36. #define HGCymax 348        /* max. number of pixels in the y direction */
  37.  
  38.             /* Hercules control */
  39. #define INDXPORT 0x3b4
  40. #define DATAPORT 0x3b5
  41. #define CTRLPORT 0x3b8
  42. #define CONFPORT 0x3bf
  43. #define SCRN_ON 8
  44.  
  45. #ifdef QAK
  46. #define GRPH 0x02
  47. #define TEXT 0x20
  48. #endif
  49. #define GRPH 0x06
  50. #define TEXT 0x25
  51.             /* graphics */
  52. #ifdef MSC
  53. static unsigned int HGCgtable[12]={ 
  54.     0x35, 0x2d, 0x2e, 0x07,
  55.     0x5b, 0x02, 0x57, 0x57,
  56.     0x02, 0x03, 0x00, 0x00
  57. };
  58.             /* text */
  59. static unsigned int HGCttable[12]={
  60.     0x61, 0x50, 0x52, 0x0f,
  61.     0x19, 0x06, 0x19, 0x19,
  62.     0x02, 0x0d, 0x0b, 0x0c
  63. };
  64.  
  65. #else
  66. static unsigned char HGCgtable[12]={ 
  67.     0x35, 0x2d, 0x2e, 0x07,
  68.     0x5b, 0x02, 0x57, 0x57,
  69.     0x02, 0x03, 0x00, 0x00
  70. };
  71.             /* text */
  72. static unsigned char HGCttable[12]={
  73.     0x61, 0x50, 0x52, 0x0f,
  74.     0x19, 0x06, 0x19, 0x19,
  75.     0x02, 0x0d, 0x0b, 0x0c
  76. };
  77. #endif
  78.  
  79. static int HGCactive;        /* number of currently HGCactive window */
  80. static char *HGCram;
  81. static unsigned char HGCpbit[SCRNXHI+1];
  82. #ifdef OLD_WAY
  83. static unsigned char power2[8] = {1,2,4,8,16,32,64,128};
  84. #endif
  85. static char *HGCname = "Hercules High-Resolution Graphics";
  86. static void HGCrasline(int w,int x0,int y0,int x1,int y1);
  87. static void HGCsetup(void );
  88.  
  89. /* Current status of an HGC window */
  90. struct HGCWIN {
  91.     char inuse;                 /* true if window in use */
  92.     int pencolor, rotation, size;
  93.     int winbot,winleft,wintall,winwide;    /* position of the window in virtual space */
  94. };
  95.  
  96. static struct HGCWIN HGCwin[MAXHERC];
  97.  
  98. /* prepare variables for use in other functions */
  99. static void HGCsetup(void ) 
  100. {
  101.     int x;
  102.  
  103.     HGCpbit[0]=128; 
  104.     HGCpbit[1]=64; 
  105.     HGCpbit[2]=32; 
  106.     HGCpbit[3]=16;
  107.     HGCpbit[4]=8;   
  108.     HGCpbit[5]=4;  
  109.     HGCpbit[6]=2;  
  110.     HGCpbit[7]=1;
  111.     for(x=8; x<=SCRNXHI; x++) 
  112.         HGCpbit[x]=HGCpbit[x&7];
  113. #if defined(MSC) && !defined(__TURBOC__) && !defined(__WATCOMC__)
  114.     FP_SEG(HGCram) = 0xB000;  FP_OFF(HGCram) = 0;
  115. #else
  116.     HGCram=(char *)MK_FP(0xB000,0x0);
  117. #endif
  118. }
  119.  
  120. /* go into HGC graphics mode */
  121. void RGHgmode(void)
  122. {
  123. #ifdef MSC
  124.      unsigned int *hdata=HGCgtable;
  125.     unsigned int port;
  126. #else
  127.      char *hdata=HGCgtable;
  128.     char port;
  129. #endif
  130.     long *video;         /* long does 4 chars at a time */
  131.     int memloc;
  132.                         /* set video chips */
  133. #ifdef MSC
  134.     outpw(CTRLPORT,GRPH|SCRN_ON);
  135.     outpw(CONFPORT,0x01);
  136.     for(port=0; port<12; port++) {
  137.         outpw(INDXPORT,port);
  138.         outpw(DATAPORT,*(hdata++));
  139.       }    /* end for */
  140. #else
  141.     outp(CTRLPORT,GRPH|SCRN_ON);
  142.     outp(CONFPORT,0x01);
  143.     for(port=0; port<12; port++) {
  144.         outp(INDXPORT,port);
  145.         outp(DATAPORT,*(hdata++));
  146.       }
  147. #endif
  148.                         /* clear video buffer */
  149.     video=(long *)HGCram;
  150.     for(memloc=0; memloc<8191; memloc++)
  151.         *(video++)=0;
  152. }
  153.  
  154. /* go into HGC text mode, compatible with IBM Monochrome */
  155. void RGHtmode(void)
  156. {
  157. #ifdef MSC
  158.     unsigned int *hdata=HGCttable;
  159.     unsigned port;
  160. #else
  161.     char *hdata=HGCttable;
  162.     char port;
  163. #endif
  164.     long *video; /* long does 4 chars at a time */
  165.     int memloc;
  166.                 /* set video chips */
  167. #ifdef MSC
  168.     outpw(CTRLPORT,TEXT|SCRN_ON);
  169.     outpw(CONFPORT,0x01);
  170.     for(port=0; port<12; port++) {
  171.         outpw(INDXPORT,port);
  172.         outpw(DATAPORT,*(hdata++));
  173.       }
  174. #else
  175.     outp(CTRLPORT,TEXT|SCRN_ON);
  176.     outp(CONFPORT,0x01);
  177.     for(port=0; port<12; port++) {
  178.         outp(INDXPORT,port);
  179.         outp(DATAPORT,*(hdata++));
  180.       }
  181. #endif
  182.  
  183.                 /* clear video buffer */
  184.     video=(long *)HGCram;
  185.     for(memloc=0; memloc<1000; memloc++)
  186.         *(video++)=0;
  187.     HGCactive=-1;
  188. }
  189.  
  190. /* draw a line from (x0,y0) to (x1,y1) */
  191. /* uses Bresenham's Line Algorithm */
  192. static void HGCrasline(int w,int x0,int y0,int x1,int y1)
  193. {
  194.     int x,y,dx,dy,d,temp,
  195.     dx2,dy2,        /* 2dx and 2dy */
  196.     direction;        /* +1 or -1, used for slope */
  197.     char transpose;    /* true if switching x and y for vertical-ish line */
  198.  
  199.     x0=(int)(((long)x0*HGCxmax)>>INXSHIFT);
  200.     y0=HGCymax-1-(int)(((long)y0*HGCymax)>>INYSHIFT);
  201.     x1=(int)(((long)x1*HGCxmax)>>INXSHIFT);
  202.     y1=HGCymax-1-(int)(((long)y1*HGCymax)>>INYSHIFT);
  203.     if(abs(y1-y0)>abs(x1-x0)) {        /* transpose vertical-ish to horizontal-ish */
  204.         temp=x1; 
  205.         x1=y1; 
  206.         y1=temp;
  207.         temp=x0; 
  208.         x0=y0; 
  209.         y0=temp;
  210.         transpose=TRUE;
  211.       } 
  212.     else 
  213.         transpose=FALSE;
  214.                                     /* make sure line is left to right */
  215.     if(x1<x0) {
  216.         temp=x1; 
  217.         x1=x0; 
  218.         x0=temp; 
  219.         temp=y1; 
  220.         y1=y0; 
  221.         y0=temp;
  222.       }
  223.                                 /* SPECIAL CASE: 1 POINT */
  224.     if(x1==x0&&y1==y0) { 
  225.         HGCram[0x2000*(y1%4)+90*(y1/4)+(x1/8)]|=HGCpbit[x1];
  226.         return;
  227.       }        
  228.                                 /* ANY LINE > 1 POINT */
  229.     x=x0;
  230.     y=y0;
  231.     dx=x1-x0;
  232.     if(y1>=y0) {
  233.         dy=y1-y0;
  234.         direction=1;
  235.       } 
  236.     else {
  237.         dy=y0-y1;
  238.         direction=-1;
  239.       }
  240.     dx2=dx<<1;
  241.     dy2=dy<<1;
  242.     d=(dy<<1)-dx;
  243.     if (transpose) {    
  244.                             /* CASE OF VERTICALISH (TRANSPOSED) LINES */
  245.         while(x<=x1) {
  246.             if(y>=0&&y<HGCxmax&&x>=0&&x<HGCymax)
  247.                 HGCram[0x2000*(x%4)+90*(x/4)+(y/8)]|=HGCpbit[y];
  248.             while(d>=0) {
  249.                 y+=direction;
  250.                 d-=dx2;
  251.               }
  252.             d+=dy2;
  253.             x++;
  254.           } 
  255.       } 
  256.     else {
  257.                             /* CASE OF HORIZONTALISH LINES */
  258.         while(x<=x1) {
  259.             if(x>=0&&x<HGCxmax&&y>=0&&y<HGCymax)
  260.                 HGCram[0x2000*(y%4)+90*(y/4)+(x/8)]|=HGCpbit[x];
  261.             while(d>=0) {
  262.                 y+=direction;
  263.                 d-=dx2;
  264.               }
  265.             d+=dy2;
  266.             x++;
  267.           }
  268.       }                    /* end horizontalish */
  269.     w=w;
  270. }                         /* end HGCrasline() */
  271.  
  272. /*
  273.     Clear the screen.
  274. */
  275. void RGHclrscr(int w)
  276. {
  277.     if(w==HGCactive) {
  278.         HGCsetup();
  279.         RGHgmode();
  280.       }
  281. }
  282.  
  283. /*
  284.     Set up a new window; return its number.
  285.     Returns -1 if cannot create window.
  286. */
  287. int RGHnewwin(void)
  288. {
  289.     int w=0;
  290.  
  291.     while(w<MAXHERC&&HGCwin[w].inuse) 
  292.         w++;
  293.     if(w==MAXHERC)
  294.         return(-1);                 /* no windows available */
  295.     HGCwin[w].pencolor=7;
  296.     HGCwin[w].winbot=0;
  297.     HGCwin[w].wintall=3120;
  298.     HGCwin[w].winleft=0;
  299.     HGCwin[w].winwide=4096;
  300.     HGCwin[w].inuse=TRUE;
  301.     return(w);
  302. }
  303.  
  304. void RGHclose(int w)
  305. {
  306.     if(HGCactive==w) {
  307.         RGHclrscr(w);
  308.         HGCactive=-1;
  309.       }
  310.     HGCwin[w].inuse=FALSE;
  311. }
  312.  
  313. /* set pixel at location (x,y) -- no range checking performed */
  314. void RGHpoint(int w,int x,int y)
  315. {
  316.     int x2,y2;         /* on-screen coordinates */
  317.     if(w==HGCactive) {
  318.         x2=(int)(((long)x*HGCxmax)>>INXSHIFT);
  319.         y2=SCRNYHI-(int)(((long)y*HGCymax)>>INYSHIFT);
  320.         HGCram[0x2000*(y2%4)+90*(y2/4)+(x2/8)]|=HGCpbit[x2];
  321.       }
  322. }  
  323.  
  324. void RGHdrawline(int w,int x0,int y0,int x1,int y1)
  325. {
  326.     if(w==HGCactive)
  327.         HGCrasline(w,x0,y0,x1,y1);
  328. }
  329.  
  330. /*
  331.     Do whatever has to be done when the drawing is all done.
  332.     (For printers, that means eject page.)
  333. */
  334. void RGHpagedone(int w)
  335. {
  336.     /* do nothing for HGC */
  337.     w=w;
  338. }
  339.  
  340. /*
  341.     Copy 'count' bytes of data to screen starting at HGCactive
  342.     cursor location.
  343. */
  344. void RGHdataline(int w,char *data,int count)
  345. {
  346.     /* Function not supported yet. */
  347.     w=w;
  348.     count=count;
  349.     data=data;
  350. }
  351.  
  352. /*
  353.     Change pen color to the specified color.
  354. */
  355. void RGHpencolor(int w,int color)
  356. {
  357.     /* Function not supported yet. */
  358.     w=w;
  359.     color=color;
  360. }
  361.  
  362. /*
  363.     Set description of future device-supported graphtext.
  364.     Rotation=quadrant.
  365. */
  366. void RGHcharmode(int w,int rotation,int size)
  367. {
  368.     /* No rotatable device-supported graphtext is available on HGC. */
  369.     w=w;
  370.     rotation=rotation;
  371.     size=size;
  372. }
  373.  
  374. /* Not yet supported: */
  375. void RGHshowcur(void) {}
  376. void RGHlockcur(void) {}
  377. void RGHhidecur(void) {}
  378.  
  379. /* Ring bell in window w */
  380. void RGHbell(int w)
  381. {
  382.     if(w==HGCactive)
  383.         putchar(7);
  384. }
  385.  
  386. /* return name of device that this RG supports */
  387. char *RGHdevname(void)
  388. {
  389.     return(HGCname);
  390. }
  391.  
  392. /* initialize all RGH variables */
  393. void RGHinit(void)
  394. {
  395.     int i;
  396.  
  397.     HGCsetup();
  398.     for(i=0; i<MAXHERC; i++)
  399.         HGCwin[i].inuse=FALSE;
  400.     HGCactive=-1;
  401. }
  402.  
  403. /*
  404.     Make this window visible, hiding all others.
  405.     Caller should follow this with clrscr and redraw to show the HGCactive
  406.     contents of the window.
  407. */
  408. void RGHuncover(int w)
  409. {
  410.     HGCactive=w;
  411. }
  412.  
  413. /* Needed for possible future functionality */
  414. void RGHinfo(int w,int a,int b,int c,int d,int v)
  415. {
  416.     w=w;
  417.     a=a;
  418.     b=b;
  419.     c=c;
  420.     d=d;
  421.     v=v;
  422. }
  423.