home *** CD-ROM | disk | FTP | other *** search
/ GRIPS 2: Government Rast…rocessing Software & Data / GRIPS_2.cdr / dos / pcshow / src / lattice / options.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-01-07  |  43.4 KB  |  1,314 lines

  1. /*
  2. *    options.c
  3. *
  4. *    This set of routines takes care of the image and palette manipulations
  5. *  after an image has been read in and displayed.
  6. *
  7. *  National Center for Supercomputing Applications, University of Illinois
  8. *  153 Computing Applications Building
  9. *  605 E. Springfield Ave.
  10. *  Champaign, IL  61820     (217)244-0072
  11. *
  12. *  Quincey Koziol            August 1988
  13. *
  14. */
  15.  
  16. #include "showext.h"
  17.  
  18. /**********************************************************************
  19. *  Function    :    draw_mouse()
  20. *  Purpose    :    draw the mouse cursor on the screen
  21. *  Parameters    :    none
  22. *  Returns    :    none
  23. *  Calls    :    mousecml(), makecur9()
  24. *  Called by    :    mousefunc(), parse(), window(),
  25. **********************************************************************/
  26. void draw_mouse()
  27. {
  28.     if(mode==NO9)
  29.         makecur9(mx,my);
  30.     else {
  31.         m1=1;
  32.         mousecl(&m1,&m2,&m3,&m4);
  33.       }    /* end else */
  34. }    /* end draw_mouse() */
  35.  
  36. /**********************************************************************
  37. *  Function    :    erase_mouse()
  38. *  Purpose    :    erase the mouse cursor from the screen
  39. *  Parameters    :    none
  40. *  Returns    :    none
  41. *  Calls    :    mousecml(), makecur9()
  42. *  Called by    :    mousefunc(), parse(), window(),
  43. **********************************************************************/
  44. void erase_mouse()
  45. {
  46.     if(mode==NO9)
  47.         makecur9(mx,my);
  48.     else {
  49.         m1=2;
  50.         mousecl(&m1,&m2,&m3,&m4);
  51.       }    /* end else */
  52. }    /* end erase_mouse() */
  53.  
  54. /**********************************************************************
  55. *  Function    :    read_mouse()
  56. *  Purpose    :    read the mouse position and button status and scale for correct
  57. *        display mode
  58. *  Parameters    :    none
  59. *  Returns    :    none
  60. *  Calls    :    mousecml()
  61. *  Called by    :    mousefunc(), parse(), window(),
  62. **********************************************************************/
  63. void read_mouse()
  64. {
  65.     m1=3;        /* get mouse position and button status */
  66.     mousecl(&m1,&m2,&m3,&m4);
  67.     leftbutton=rightbutton=0;
  68.     leftbutton=m2&1;        /* get left button bit from mouse variable */
  69.     rightbutton=(m2&2)>>1;        /* get right button bit from mouse variable */
  70.     if(mode!=EGA)
  71.         m3=m3>>1;                /* compensate for the mouse */
  72.     if(mode==NO9) {            /* if no9 then compensate the mouse more */
  73.         m3=m3>>2;
  74.         m4=m4>>3;
  75.       }    /* end if */
  76. }    /* end read_mouse()*/
  77.  
  78. /**********************************************************************
  79. *  Function    :    readstr
  80. *  Purpose    :    get a simple set of characters from stdin
  81. *  Parameters    :
  82. *            charstr -    pointer to the character string to be read in
  83. *  Returns    :    none
  84. *  Calls    :    getch()
  85. *  Called by    :    parse()
  86. **********************************************************************/
  87. void readstr(charstr)
  88. unsigned char *charstr;
  89. {
  90.     charstr--;
  91.     do {
  92.         charstr++;
  93.         *charstr=getch();
  94.         if(*charstr==0)
  95.             *charstr=getch()|(unsigned char)128;    /* set high bit to indicate extended code */
  96.         printf("%c",*charstr);
  97.       }    while(*charstr!=13);        /* end while */
  98.     *charstr=0;
  99. }
  100.  
  101. /**********************************************************************
  102. *  Function    :    swapint
  103. *  Purpose    :    swap two integer values
  104. *  Parameters    :
  105. *            x,y - pointers to the two values to swap
  106. *  Returns    :    none
  107. *  Calls    :    none
  108. *  Called by    :    mousefunc()
  109. **********************************************************************/
  110. void swapint(x,y)
  111. int    *x,*y;        /* values to exchange */
  112. {
  113.     int    t;        /* temporary variable */
  114.  
  115.     t=*x;
  116.     *x=*y;
  117.     *y=t;
  118. } /* end swapint() */
  119.  
  120. /**********************************************************************
  121. *  Function    :    swap
  122. *  Purpose    :    swap two character values
  123. *  Parameters    :
  124. *            x,y - pointers to the two values to swap
  125. *  Returns    :    none
  126. *  Calls    :    none
  127. *  Called by    :    options()
  128. **********************************************************************/
  129. void swap(x,y)
  130. unsigned char *x,*y;        /* values to exchange */
  131. {
  132.     unsigned char t;        /* temporary variable */
  133.  
  134.     t=*x;
  135.     *x=*y;
  136.     *y=t;
  137. } /* end swap() */
  138.  
  139. /**********************************************************************
  140. *  Function    :    findpal
  141. *  Purpose    :    loads in a new palette from an HDF file after the first one
  142. *  Parameters    :    none
  143. *  Returns    :    none
  144. *  Calls    :    DFfind(), DFgetelement(), palloc(), palloce(), select_pal()
  145. *  Called by    :    options()
  146. **********************************************************************/
  147. void findpal()
  148. {
  149.     int i,    /* local counting variable */
  150.         palold;        /* last palmax value */
  151.     char *pi; /* pointer to character array of palette read in */
  152.  
  153.     DFsetfind(dff,DFTG_IP8,DFREF_WILDCARD);    /* set the HDF file to a palette */
  154.  
  155.     palold=palmax;
  156.     if (!DFfind(dff,&ddstr)) {    /* HDF file should be set for palettes */
  157.         if(DFgetelement(dff,ddstr.tag,ddstr.ref,pal)>=0) {
  158.             pi = pal;
  159.             for (i=0; i<256; i++) {
  160.                 rmap[i] = *pi++;
  161.                 gmap[i] = *pi++;
  162.                 bmap[i] = *pi++;
  163.               } /* end for */
  164.             palmax++;
  165.           }    /* end if */
  166.     } /* end if */
  167.  
  168. /* see if there is enough space for another palette */
  169.  
  170.     if(palmax!=palold) {
  171.         if(mode!=EGA) {
  172.             if(!palloc(palmax)) {    /* if no space available then go back to last one */
  173.                 palmax--;
  174.                 displayerr("No Room For Another Palette");
  175.                 memcpy(rmap,rpal[palnum],256);
  176.                 memcpy(gmap,gpal[palnum],256);
  177.                 memcpy(bmap,bpal[palnum],256);
  178.               } /* end if */
  179.             else                /* palloc() was ok, so switch to the palette */
  180.                 palnum=palmax;
  181.           } /* end if */
  182.         else {
  183.             if(!palloce(palmax)) {    /* no space, so switch to old palette */
  184.                 displayerr("No Room For Another Palette");
  185.                 palmax--;
  186.                 memcpy(regrs,egapals[palnum],16);
  187.               } /* end if */
  188.             else {            /* enough space for a palette, so use it */
  189.                 palnum=palmax;
  190.                 select_pal(xdim,ydim,1);    /* do a frequency count and set up the ega palette */
  191.               } /* end else */
  192.           }    /* end else */
  193.       }    /* end if */
  194. } /* end findpal() */
  195.  
  196. /**********************************************************************
  197. *  Function    :    showpal
  198. *  Purpose    :    display the current palette on the screen.  EGA monitors
  199. *            directly change to data in memory, whereas VGA and NO9 monitors
  200. *            just change the data on the screen.
  201. *  Parameters    :    none
  202. *  Returns    :    none
  203. *  Calls    :    showpalv(), showpal9(), egaline()
  204. *  Called by    :    options()
  205. **********************************************************************/
  206. void showpal()
  207. {
  208. #ifdef MOUSE
  209.     if(mouse)
  210.         erase_mouse();
  211. #endif
  212.     switch (mode) {        /* different methods for showing the palette on the screen */
  213.         case VGA:
  214.             showpalv(&palstore,pal_xoff,pal_yoff);
  215.             break;
  216.  
  217.         case NO9:
  218.             showpal9(&palstore,pal_xoff,pal_yoff);
  219.             break;
  220.  
  221.         case EGA:
  222.         default:
  223.             for(i=0; i<16; i++)
  224.                 for(k=0; k<16; k++)
  225.                     palstore[0][i*16+k]=i;
  226.             for(j=0; j<8; j++)        /* for no. 9 and vga, direct memory copies are used in assembly, but ega must be done 'by hand' */
  227.                 egaline(xwhere+pal_xoff,ywhere+j+pal_yoff,&palstore[0][0],256,trans1,0);
  228.             break;
  229.       }    /* end switch(mode) */
  230. #ifdef MOUSE
  231.     if(mouse)
  232.         draw_mouse();
  233. #endif
  234. } /* end showpal() */
  235.  
  236. /**********************************************************************
  237. *  Function    :    nopal
  238. *  Purpose    :    replace the palette on the screen with the image under it.
  239. *            Once again, EGA mode changes the data in memory, whereas VGA
  240. *            NO9 change it only on the screen.
  241. *  Parameters    :
  242. *        xoff,yoff - the x & y offsets into the image where the screen is
  243. *            positioned
  244. *  Returns    :    none
  245. *  Calls    :    nopalv(), nopal9(), egaline()
  246. *  Called by    :    options()
  247. **********************************************************************/
  248. void nopal(xoff,yoff)
  249. int xoff,yoff;    /* the x & y offset into the image being displayed */
  250. {
  251. #ifdef MOUSE
  252.     if(mouse)
  253.         erase_mouse();
  254. #endif
  255.     switch(mode){        /* different routines to restore the screen */
  256.         case VGA:
  257.             nopalv(&palstore,pal_xoff,pal_yoff);
  258.             break;
  259.  
  260.         case NO9:
  261.             nopal9(&palstore,pal_xoff,pal_yoff);
  262.             break;
  263.  
  264.         case EGA:
  265.         default:
  266.             if(pal_yoff<(ydim-pal_height))
  267.                 for(j=0; j<8; j++)        /* just re plot that section of the screen */
  268.                     egaline(xwhere+pal_xoff,ywhere+j+pal_yoff,store[j+pal_yoff+yoff],min(256,xdim-pal_xoff),trans,xoff+pal_xoff);
  269.             break;
  270.       }    /* end switch(mode) */
  271. #ifdef MOUSE
  272.     if(mouse)
  273.         draw_mouse();
  274. #endif
  275. } /* end nopal() */
  276.         
  277. /**********************************************************************
  278. *  Function    :    waitq
  279. *  Purpose    :    wait for a keypress
  280. *  Parameters    :    none
  281. *  Returns    :    none
  282. *  Calls    :    none
  283. *  Called by    :    many places...
  284. **********************************************************************/
  285. void waitq()
  286. {
  287.     unsigned char c;    /* temporary variable to hold the character read in */
  288.  
  289.     c='!';
  290.     while (c=='!') {
  291.         if(kbhit()) {    /* get the next command */
  292.             c=getch();
  293.             if(c==0)
  294.                 c=getch()|(unsigned char)128;    /* set high bit to indicate extended code */
  295.           }    /* end if */
  296.        }    /* end while */
  297. }    /* waitq() */
  298.  
  299. /**********************************************************************
  300. *  Function    :    printdir
  301. *  Purpose    :    print out a listing of files ending in '.pal' in the 
  302. *            current local directory
  303. *  Parameters    :    none
  304. *  Returns    :    none
  305. *  Calls    :    textmode()
  306. *  Called by    :    options()
  307. **********************************************************************/
  308. void printdir()
  309. {
  310.     unsigned char    palnames[4096];        /* array to store palette names */
  311.     char *p,                /* pointer to position if names file */
  312.         *fnp="*.pal";        /* pattern to look for */
  313.     int    n,                    /* number of matching file names */
  314.         attr=0;                /* look for normal files */
  315.     
  316.     if((n=getfnl(fnp,palnames,sizeof(palnames),attr))<=0)    /* load the names of the palettes into an array */
  317.         printf("No Palettes In The Current Directory\n");
  318.     else
  319.         for(p=palnames; *p!='\0'; p+=strlen(p)+1)    /* write out all the names */
  320.             printf("%s\n",p);
  321.     printf("\nHit Any Key To Continue");
  322.     waitq();
  323.     textmode();
  324. } /* end printdir() */
  325.  
  326. #ifdef QAK
  327. /**********************************************************************
  328. *  Function :    slidepal
  329. *  Purpose    :    rotate the palette an arbitary amount
  330. *  Parameters    :
  331. *        offset - the amount to slide the palette
  332. *  Returns    :    none
  333. *  Calls    :    none
  334. *  Called by    :    options()
  335. **********************************************************************/
  336. void slidepal(x)
  337. int    x;    /* amount of positive or negative offset to slide the palette */
  338. {
  339.     if(mode!=EGA){
  340.         if(x<0){
  341.             memcpy(rmap,rpal[palnum]-x,256+x);        /* shift palettes down x bytes */
  342.             memcpy(gmap,gpal[palnum]-x,256+x);
  343.             memcpy(bmap,bpal[palnum]-x,256+x);
  344.             for(j=255+x; j<=255; j++){    /* fill in the leftover places */
  345.                 rmap[j]=rmap[j-1];
  346.                 gmap[j]=gmap[j-1];
  347.                 bmap[j]=bmap[j-1];
  348.               }    /* end for */
  349.           }    /* end if */
  350.         else{
  351.             memcpy(rmap+x,rpal[palnum],256-x);        /* shift palettes up x bytes */
  352.             memcpy(gmap+x,gpal[palnum],256-x);
  353.             memcpy(bmap+x,bpal[palnum],256-x);
  354.             for(j=x; j>=0; j--){        /* fill in the leftover places */
  355.                 rmap[j]=rmap[j+1];
  356.                 gmap[j]=gmap[j+1];
  357.                 bmap[j]=bmap[j+1];
  358.               }    /* end for */
  359.           } /* end else */
  360.       }    /* end if */
  361. } /* end slidepal() */
  362. #endif
  363.  
  364. /**********************************************************************
  365. *  Function :    squishpal
  366. *  Purpose    :    compress the palette an arbitrary amount
  367. *  Parameters    :
  368. *        slope  - the slope of the line to compress palette with
  369. *        offset - the amount to slide the palette
  370. *  Returns    :    none
  371. *  Calls    :    abs()
  372. *  Called by    :    options()
  373. **********************************************************************/
  374. void squishpal(x,y)
  375. int    x,        /* the slope of the line to squish the palette with */
  376.     y;        /* the offset to slide the palette by when the squishing is done */
  377. {
  378.     int        j,k,    /* temporary counting variables */
  379.             lox,    /* the value of the x-intercept if y=0 */
  380.             hix;    /* the value of the x-intercept if y=255 */
  381.  
  382.     if(x!=0){
  383.         lox=(10*((-127)-y)/x)+127;
  384.         hix=(10*(128-y)/x)+127;
  385.       }    /* end if */
  386.     else{
  387.         lox=127;
  388.         hix=127;
  389.       }    /* end else */
  390.     if(lox!=0)        /* check for the beginning value not on the beginning of the palette */
  391.         if(lox<0)
  392.             lox=0;    /* if i=it is before the palette then set it to beginning of the palette */
  393.         else{
  394.             for(j=lox-1; j>=0; j--){    /* if it is after the beginning of the palette then fill to beginning */
  395.                 rmap[j]=rpal[palnum][lox-1];
  396.                 gmap[j]=gpal[palnum][lox-1];
  397.                 bmap[j]=bpal[palnum][lox-1];
  398.               }    /* end for j */
  399.           }    /* end else */
  400.     if(hix!=255)    /* check for end value not exactly on the end of the palette */
  401.         if(hix>255)    /* if it is after the end of the palette then set it to the end of the palette */
  402.             hix=255;
  403.         else{
  404.             for(j=hix+1; j<=255; j++){    /* if it is before the end of the palette then fill to the end */
  405.                 rmap[j]=rpal[palnum][hix+1];
  406.                 gmap[j]=gpal[palnum][hix+1];
  407.                 bmap[j]=bpal[palnum][hix+1];
  408.               }    /* end for j */
  409.           }    /* end else */
  410.     if(hix<lox)        /* make sure it increments in correct fashion */
  411.         swap(&lox,&hix);
  412.     for(j=lox; j<=hix; j++){
  413.         k=x*(j-127)/10+127+y;    /* y = mx+b equation of a line */
  414.         rmap[j]=rpal[palnum][k];
  415.         gmap[j]=gpal[palnum][k];
  416.         bmap[j]=bpal[palnum][k];
  417.       }    /* end for j */
  418. } /* end squishpal() */
  419.  
  420. #ifdef QAK
  421. /**********************************************************************
  422. *  Function    :    pixelcolor
  423. *  Purpose    :    returns the color of a specified pixel
  424. *  Parameters    :
  425. *            x - the x coor. of the pixel
  426. *            y - the y coor. of the pixel
  427. *  Returns    :    the color of the pixel as a char
  428. *  Calls    :    none
  429. *  Called by    :    mousefunc()
  430. **********************************************************************/
  431. unsigned char pixelcolor(x,y)
  432. int    x,y;    /* the x and y coor. of the pixel whose color is returned */
  433. {
  434.     if(show && ((x>=pal_xoff && x<=(pal_xoff+255)) && (y>=pal_yoff && y<=(pal_yoff+pal_height))))
  435.         switch(mode) {    /* return different values for different screen types */
  436.             case VGA:
  437.             case NO9:
  438.                 return((unsigned char) (x-pal_xoff));
  439.                 break;
  440.  
  441.             case EGA:
  442.             default:
  443.                 return((unsigned char) ((x-pal_xoff)/16));
  444.                 break;
  445.           }    /* end switch */
  446.     else    /* if not in the color bar then return the normal value */
  447.         return((unsigned char) store[y+yoff][x+xoff]);
  448. }    /* end pixelcolor() */
  449. #endif
  450.  
  451. /**********************************************************************
  452. *  Function    :    updatescrn
  453. *  Purpose    :    updates the screen with the current image, color bar,
  454. *                    and the mouse cursor
  455. *  Parameters    :    none
  456. *  Returns    :    none
  457. *  Calls    :    showpic(), showpal(), pixelcolor()
  458. *  Called by    :    options()
  459. **********************************************************************/
  460. void updatescrn()
  461. {
  462.     showpic();
  463.     if(show)
  464.         showpal();
  465. #ifdef MOUSE
  466.     if(mouse)            /* if the mouse is on then replace the mouse cursor */
  467.         draw_mouse();
  468. #endif
  469. }    /* end updatescrn() */
  470.  
  471. /**********************************************************************
  472. *  Function    :    scroll
  473. *  Purpose    :    move the image around the screen
  474. *  Parameters    :
  475. *            func -    the scrolling function to be performed
  476. *  Returns    :    none
  477. *  Calls    :    updatescrn()
  478. *  Called by    :    options(), mousefunc()
  479. **********************************************************************/
  480. void scroll(func)
  481. unsigned char    func;    /* the function to be performed on the screen */
  482. {
  483.     int    i;                /* temporary variables to hold the old xoff and yoff */
  484.  
  485. #ifdef MOUSE
  486.     if(mouse)            /* if the mouse is on then hide the cursor while moving */
  487.         erase_mouse();
  488. #endif
  489.     switch(func) {    /* switch to perform the appropriate scroll */
  490.         case 'l':    /* scroll left */
  491.             i=xoff;
  492.             xoff-=10;
  493.             if(xoff<0) 
  494.                 xoff=0;
  495.             if(xoff!=i)
  496.                 updatescrn();
  497.             break;
  498.         
  499.         case 'r':    /* scroll right */
  500.             i=xoff;
  501.             xoff+=10;
  502.             if(xdim-maxx<0)
  503.                 xoff=0;
  504.             else
  505.                 if(xoff>xdim-maxx)
  506.                     xoff=xdim-maxx;
  507.             if(i!=xoff)
  508.                 updatescrn();
  509.             break;
  510.  
  511.         case 'u':    /* scroll up */
  512.             i=yoff;
  513.             yoff-=10;
  514.             if(yoff<0)
  515.                 yoff=0;
  516.             if(yoff!=i)
  517.                 updatescrn();
  518.             break;
  519.  
  520.         case 'd':    /* scroll down */
  521.             i=yoff;
  522.             yoff+=10;
  523.             if(ydim-maxy<0)
  524.                 yoff=0;
  525.             else
  526.                 if(yoff>ydim-maxy)
  527.                     yoff=ydim-maxy;
  528.             if(i!=yoff)
  529.                 updatescrn();
  530.             break;
  531.  
  532.         case 'H':    /* Move to upper left hand corner of image */
  533.             if(yoff!=0||xoff!=0) {
  534.                 xoff=0;
  535.                 yoff=0;
  536.                 updatescrn();
  537.               } /* end if */
  538.             break;
  539.  
  540.         case 'E':    /* Move to lower right hand corner of image */
  541.             if(yoff!=ydim-maxy||xoff!=xdim-maxx) {
  542.                 xoff=xdim-maxx;
  543.                 if(xoff<0)
  544.                     xoff=0;
  545.                 yoff=ydim-maxy;
  546.                 if(yoff<0)
  547.                     yoff=0;
  548.                 updatescrn();
  549.               } /* end if */
  550.             break;
  551.  
  552.         case 'U':    /* page image up */
  553.             i=yoff;
  554.             yoff-=maxy;
  555.             if(yoff<0)
  556.                 yoff=0;
  557.             if(yoff!=i)
  558.                 updatescrn();
  559.             break;
  560.  
  561.         case 'D':    /* page image down */
  562.             i=yoff;
  563.             yoff+=maxy;
  564.             if(ydim-maxy<0)
  565.                 yoff=0;
  566.             else
  567.                 if(yoff>ydim-maxy)
  568.                     yoff=ydim-maxy;
  569.             if(i!=yoff)
  570.                 updatescrn();
  571.             break;
  572.       }    /* end switch */
  573. #ifdef MOUSE
  574.     if(mouse)            /* if the mouse is on then replace the cursor after moving */
  575.         draw_mouse();
  576. #endif
  577. }    /* end scroll() */
  578.  
  579. /**********************************************************************
  580. *  Function    :    rotate
  581. *  Purpose    :    rotate the palette left or right
  582. *  Parameters    :
  583. *            func -    character to determine which direction to rotate
  584. *  Returns    :    none
  585. *  Calls    :    putpal(), memcpy()
  586. *  Called by    :    options(), mousefunc()
  587. **********************************************************************/
  588. void rotate(func)
  589. unsigned char    func;    /* parameter to determine which way to rotate the palette */
  590. {
  591.     switch(func) {        /* switch for what to do to the palette */
  592.         case 'l':        /* rotate the palette left */
  593.             if(mode!=EGA) {
  594.                 i=rmap[255];
  595.                 j=gmap[255];
  596.                 k=bmap[255];
  597.                 memcpy(rmap+1,rmap,255);        /* shift palettes up one byte */
  598.                 memcpy(gmap+1,gmap,255);
  599.                 memcpy(bmap+1,bmap,255);
  600.                 rmap[0]=i;
  601.                 gmap[0]=j;
  602.                 bmap[0]=k;
  603.               } /* end if */
  604.             else {
  605.                 i=regrs[15];
  606.                 for(j=15; j>=1; j--)
  607.                     regrs[j]=regrs[j-1];
  608.                 regrs[0]=i;
  609.               } /* end else */
  610.             putpal();
  611.             break;
  612.  
  613.         case 'r':        /* rotate the palette right */
  614.             if(mode!=EGA) {
  615.                 i=rmap[0];
  616.                 j=gmap[0];
  617.                 k=bmap[0];
  618.                 memcpy(rmap,rmap+1,255);        /* shift palettes down one byte */
  619.                 memcpy(gmap,gmap+1,255);
  620.                 memcpy(bmap,bmap+1,255);
  621.                 rmap[255]=i;
  622.                 gmap[255]=j;
  623.                 bmap[255]=k;
  624.               } /*end if */
  625.             else {
  626.                 i=regrs[0];
  627.                 for(j=0; j<=14; j++)
  628.                     regrs[j]=regrs[j+1];
  629.                 regrs[15]=i;
  630.               } /* end else */
  631.             putpal();
  632.             break;
  633.       }    /* end switch */
  634. }    /* end rotate() */
  635.  
  636. /**********************************************************************
  637. *  Function    :    expand
  638. *  Purpose    :    routine to blow up a section of the screen
  639. *  Parameters    :
  640. *            x1,y1 -    location of the upper left hand corner of the box to blow up
  641. *            x2,y2 -    location of the lower right hand corner of the box to blow up
  642. *  Returns    :    
  643. *            1 - if routine was successfully finished
  644. *            0 - if routine was interupted
  645. *  Calls    :    vgaline1()
  646. *  Called by    :    mousefunc()
  647. **********************************************************************/
  648. int expand(x1,y1,x2,y2)
  649. int    x1,y1,                    /* location of the upper left hand corner of the box to blow up */
  650.     x2,y2;                    /* location of the lower right hand corner of the box to blow up */
  651.  
  652. {
  653.     unsigned char line[640];    /* a line to blow a line of the box up into */
  654.     float    xdiff,ydiff,            /* the differences between the x and y corners */
  655.             maxxf,maxyf;            /* a float variable for maxx and maxy */
  656.     int        i,j,k,l,m;
  657.  
  658.     xdiff=x2-x1;                    /* find difference between endpoints */
  659.     ydiff=y2-y1;
  660.     maxxf=maxx;
  661.     maxyf=maxy;
  662.     l=-1;                            /* preset the line counter to calculate the first line */
  663.     for(i=0; i<maxy; i++) {        /* go through all the lines in the image */
  664.         k=(int)((i/maxyf)*ydiff)+y1;
  665.         if(k!=l) {                /* if this line is not the same as the previous then re-calculate it */
  666.             for(j=0; j<maxx; j++)        /* go through each line and magnify */
  667.                 line[j]=store[k][(int)((j/maxxf)*xdiff)+x1];
  668.             l=k;                        /* set the line */
  669.           }    /* end if */
  670.         switch(mode) {        /* use different line drawing routines for different screens */
  671.             case VGA:
  672.                 vgaline1(0,i,line,0,maxx);        /* send each line out to the screen */
  673.                 break;
  674.  
  675.             case NO9:
  676.                 no9line(0,i,line,0,maxx);
  677.                 break;
  678.  
  679.             case EGA:
  680.             default:
  681.                 egaline(0,i,line,maxx,trans,0);
  682.                 break;
  683.          }    /* end switch */
  684.         if(kbhit())    {            /* break out if the keyboard is hit */
  685.             m=getch();            /* clear the keyboard buffer */
  686.             if(m==0)            /* get extended code if necessary */
  687.                 m=getch()|(unsigned char)128;    /* set high bit to indicate extended code */
  688.             return(0);
  689.           }    /* end if */
  690.       }    /* end for */
  691.     return(1);
  692. }    /* end expand() */
  693.  
  694. /**********************************************************************
  695. *  Function    :    interpolation
  696. *  Purpose    :    routine to blow up a section of the screen and interpolate
  697. *                    data to a smooth image
  698. *  Parameters    :
  699. *            x1,y1 -    location of the upper left hand corner of the box to blow up
  700. *            x2,y2 -    location of the lower right hand corner of the box to blow up
  701. *  Returns    :    
  702. *            1 - if routine was successfully finished
  703. *            0 - if routine was interupted
  704. *  Calls    :    vgaline1(), egaline(), no9line(), interdata()
  705. *  Called by    :    mousefunc()
  706. **********************************************************************/
  707. int interpolate(x1,y1,x2,y2)
  708. int    x1,y1,                    /* location of the upper left hand corner of the box to blow up */
  709.     x2,y2;                    /* location of the lower right hand corner of the box to blow up */
  710.  
  711. {
  712.     unsigned char line[640];    /* a line to blow a line of the box up into */
  713.     float    hpercent,vpercent,    /* the percentage of the distance the pixel is towards the hi value */
  714.             vdata1,vdata2,        /* the data for the vertical interpolation */
  715.             hfinal,                /* the final result for horizontal interpolation */
  716.             hdata1,hdata2,        /* the data for horizontal interpolation */
  717.             vfinal,                /* the final result for vertical interpolation */
  718.             xdiff,ydiff,        /* the differences between the x and y corners */
  719.             tempy,tempx,        /* temporary floating value */
  720.             maxxf,maxyf;        /* a float variable for maxx and maxy */
  721.     int        i,j,hix,lox,hiy,loy;    /* integer values for the coor. in the images around the current pixel */
  722.  
  723.     xdiff=x2-x1;                    /* find difference between endpoints */
  724.     ydiff=y2-y1;
  725.     maxxf=maxx;
  726.     maxyf=maxy;
  727.     for(i=0; i<maxy; i++) {        /* go through all the lines in the image */
  728.         tempy=((i/maxyf)*ydiff)+(float)y1;    /* calculate the fractional pixel position in the image */
  729.         loy=tempy;        /* calculate the address of the lower y bound */
  730.         hiy=ceil(tempy);        /* calculate the address of the upper y bound */
  731.         vpercent=(tempy-(float)loy)/((float)hiy-(float)loy);
  732.         for(j=0; j<maxx; j++) {        /* go through each line and interpolate */
  733.             tempx=((j/maxxf)*xdiff)+(float)x1;    /* calculate the fractional pixel position in the image */
  734.             lox=tempx;                /* calculate the lower x bound */
  735.             hix=ceil(tempx);        /* calculate the upper x bound */
  736.             vdata1=(store[hiy][lox]-store[loy][lox])*vpercent+store[loy][lox];
  737.             vdata2=(store[hiy][hix]-store[loy][hix])*vpercent+store[loy][hix];
  738.             hpercent=(tempx-(float)lox)/((float)hix-(float)lox);
  739.             hfinal=(vdata2-vdata1)*hpercent+vdata1;
  740.             hdata1=(store[loy][hix]-store[loy][lox])*hpercent+store[loy][lox];
  741.             hdata2=(store[hiy][hix]-store[hiy][lox])*hpercent+store[hiy][lox];
  742.             vfinal=(hdata2-hdata1)*vpercent+hdata1;
  743.             line[j]=(hfinal+vfinal)/2.0;
  744.           }    /* end for */
  745.         switch(mode) {        /* use different line drawing routines for different screens */
  746.             case VGA:
  747.                 vgaline1(0,i,line,0,maxx);        /* send each line out to the screen */
  748.                 break;
  749.  
  750.             case NO9:
  751.                 no9line(0,i,line,0,maxx);
  752.                 break;
  753.  
  754.             case EGA:
  755.             default:
  756.                 egaline(0,i,line,maxx,trans,0);
  757.                 break;
  758.          }    /* end switch */
  759.         if(kbhit()) {                /* break out if the keyboard is hit */
  760.             i=getch();
  761.             if(i==0)                /* get extended code if necessary */
  762.                 i=getch()|(unsigned char)128;    /* set high bit to indicate extended code */
  763.             return(0);
  764.           }    /* end if */
  765.       }    /* end for */
  766.     return(1);
  767. }    /* end interpolation() */
  768.  
  769. #ifdef MOUSE
  770. /**********************************************************************
  771. *  Function    :    makehex
  772. *  Purpose    :    convert an ascii string of binary digits into an integer
  773. *  Parameters    :
  774. *                binstr -    string of binary digits
  775. *  Returns    :    integer value of binary string
  776. *  Calls    :    pow(), strlen()
  777. *  Called by    :    makemouse()
  778. **********************************************************************/
  779. int makehex(binstr)
  780. char *binstr;
  781. {
  782.     int i,j,k;        /* local counting variables */
  783.     double pow();    /* pow(x,y) returns x to the y power */
  784.  
  785.     k=strlen(binstr);    /* find the length of the binary string */
  786.     i=0;
  787.     for(j=k-1; j>=0; j--)        /* make a binary string into a hex number */
  788.         i+=((int)pow((double)2,(double)j))*((int)*(binstr++)-48);
  789.     return(i);
  790. }
  791.  
  792. /**********************************************************************
  793. *  Function    :    makemouse
  794. *  Purpose    :    make the mouse cursor into a crosshair for vga and ega modes
  795. *  Parameters    :    none
  796. *  Returns    :    none
  797. *  Calls    :    mousecl()
  798. *  Called by    :    options()
  799. **********************************************************************/
  800. void makemouse()
  801. {
  802.     int    cursor[2][16];        /* array for screen and cursor bit masks */
  803.  
  804.     if(mode!=NO9) {            /* only do this for vga and ega modes */
  805.         /* screen mask */
  806.         cursor[0][0]= makehex("1001111111111111");
  807.         cursor[0][1]= makehex("1010111111111111");
  808.         cursor[0][2]= makehex("1011011111111111");
  809.         cursor[0][3]= makehex("1011101111111111");
  810.         cursor[0][4]= makehex("1011110111111111");
  811.         cursor[0][5]= makehex("1011111011111111");
  812.         cursor[0][6]= makehex("1011111101111111");
  813.         cursor[0][7]= makehex("1011111011111111");
  814.         cursor[0][8]= makehex("1010011011111111");
  815.         cursor[0][9]= makehex("1001101101111111");
  816.         cursor[0][10]=makehex("1111101101111111");
  817.         cursor[0][11]=makehex("1111110011111111");
  818.         cursor[0][12]=makehex("1111111111111111");
  819.         cursor[0][13]=makehex("1111111111111111");
  820.         cursor[0][14]=makehex("1111111111111111");
  821.         cursor[0][15]=makehex("1111111111111111");
  822.  
  823.         /* cursor mask */
  824.         for(i=0; i<16; i++)        /* set the entire cursor mask to inverse of the screen mask */
  825.             cursor[1][i]=~cursor[0][i];
  826.         m1=9;                    /* function to define cursor shape and hot spot */
  827.         m2=0;                    /* horizontal hot spot */
  828.         m3=0;                    /* vertical hot spot */
  829.         mousecl(&m1,&m2,&m3,&cursor[0][0]);
  830.         m1=1;                    /* function to show the cursor */
  831.         mousecl(&m1,&m2,&m3,&m4);
  832.       }    /* end if */
  833. }    /* end makemouse() */
  834. #endif
  835.  
  836. #ifdef QAK
  837. /**********************************************************************
  838. *  Function    :    bounce
  839. *  Purpose    :    bounce a ball on the screen
  840. *  Parameters    :    none
  841. *  Returns    :    none
  842. *  Calls    :    drand48(), ball()
  843. *  Called by    :    options()
  844. **********************************************************************/
  845. void bounce()
  846. {
  847.     int    x1[5],x2[5],y1[5],y2[5],        /* variables to keep track of the balls position */
  848.         j,                    /* timing variable */
  849.         i,                    /* local counting variable */
  850.         maxball=0,            /* number of balls on the screen */
  851.         ballsize,            /* size of the ball in pixels */
  852.         xspeed[5],yspeed[5];        /* variables to keep track of the balls speed */
  853.  
  854.     double    drand48();        /* random number function */
  855.     long    time(),l;            /* the system time for seeding the random pointer */
  856.     void    parse(),srand48();        /* command parsing function */
  857.  
  858.     srand48(time(&l));        /* seed the random number generator */
  859.     if(mode==NO9)            /* set the ball sizes for different screens */
  860.         ballsize=8;
  861.     else
  862.         ballsize=4;
  863.     x1[0]=(int)(drand48()*(double)(maxx-ballsize-1))+1;        /* randomize starting position */
  864.     x2[0]=x1[0];
  865.     y1[0]=(int)(drand48()*(double)(maxy-ballsize-1))+1;
  866.     y2[0]=y1[0];
  867.     xspeed[0]=0;
  868.     while(xspeed[0]==0)                /* randomize speed, not allowing 0 speed in a direction */
  869.         xspeed[0]=(int)(drand48()*(double)11)-6;
  870.     yspeed[0]=0;
  871.     while(yspeed[0]==0)
  872.         yspeed[0]=(int)(drand48()*(double)11)-6;
  873. #ifdef MOUSE
  874.     m1=11;                        /* reset the mouse position counters */
  875.     mousecl(&m1,&m2,&m3,&m4);
  876. #endif
  877.     m3=m4=0;
  878.     if(mode==NO9)                /* plot the ball */
  879.         ball9(x1[0],y1[0]);
  880.     else
  881.         ball(x1[0],y1[0]);
  882.     while(!kbhit() && !m3 && !m4) {    /* bounce the ball until a key is pressed */
  883.         for(i=maxball; i>=0; i--) {        /* check through all the balls */
  884.             if(mode==NO9)
  885.                 ball9(x1[i],y1[i]);
  886.             else
  887.                 ball(x1[i],y1[i]);    /* remove the ball */
  888.             x2[i]+=xspeed[i];        /* move the ball */
  889.             y2[i]+=yspeed[i];
  890.             if(x2[i]<0 || x2[i]>(maxx-ballsize-1)) {    /* check for off screen in the x direction */
  891.                 xspeed[i]=-(xspeed[i]);    /* reverse the direction of the movement */
  892.                 x2[i]+=xspeed[i];
  893.               }    /* end if */
  894.             if(y2[i]<0 || y2[i]>(maxy-ballsize-1)) {    /* check for off screen in the y direction */
  895.                 yspeed[i]=-(yspeed[i]);
  896.                 y2[i]+=yspeed[i];
  897.               }    /* end if */
  898.             if(mode==NO9)
  899.                 ball9(x2[i],y2[i]);
  900.             else
  901.                 ball(x2[i],y2[i]);        /* plot the ball in it's new position */
  902.             x1[i]=x2[i];                /* update the balls position */
  903.             y1[i]=y2[i];
  904.             if((int)(drand48()*(double)10000)==0)    /* on very rare occasions change the ball speed */
  905.                 switch ((int)(drand48()*4)) {        /* choose which speed to change */
  906.                     case 0:
  907.                         xspeed[i]++;
  908.                         break;
  909.  
  910.                     case 1:
  911.                         xspeed[i]--;
  912.                         break;
  913.  
  914.                     case 2:
  915.                         yspeed[i]++;
  916.                         break;
  917.  
  918.                     case 3:
  919.                         yspeed[i]--;
  920.                         break;
  921.                   }    /* end switch */
  922.           }    /* end for */
  923.         for(j=0; j<(5-maxball)*600+2000; j++);    /* waiting loop */
  924.         if(maxball<4)        /* if not at the maximum amount of balls then check for addition of a ball */
  925.             if((int)(drand48()*(double)1000)==0) {    /* less than one in a hundred chance */
  926.                 maxball++;
  927.                 x1[maxball]=(int)(drand48()*(double)(maxx-ballsize-1))+1;        /* randomize starting position */
  928.                 x2[maxball]=x1[maxball];
  929.                 y1[maxball]=(int)(drand48()*(double)(maxy-ballsize-1))+1;
  930.                 y2[maxball]=y1[maxball];
  931.                 xspeed[maxball]=0;
  932.                 while(xspeed[maxball]==0)                /* randomize speed, not allowing 0 speed in a direction */
  933.                     xspeed[maxball]=(int)(drand48()*(double)11)-6;
  934.                 yspeed[maxball]=0;
  935.                 while(yspeed[maxball]==0)
  936.                     yspeed[maxball]=(int)(drand48()*(double)11)-6;
  937.                 if(mode==NO9)
  938.                     ball9(x1[maxball],y1[maxball]);
  939.                 else
  940.                     ball(x1[maxball],y1[maxball]);        /* plot the new ball */
  941.               }    /* end if */
  942. #ifdef MOUSE
  943.         m1=11;                /* check for the mouse moving */
  944.         mousecl(&m1,&m2,&m3,&m4);
  945. #endif
  946.       }    /* end while */
  947.     for(i=maxball; i>=0; i--)
  948.         if(mode==NO9)
  949.             ball9(x1[i],y1[i]);
  950.         else
  951.             ball(x1[i],y1[i]);            /* erase balls from screen */
  952.     if(kbhit()) {                    /* if it was the keyboard and not the mouse */
  953.         j=getch();                    /* flush the keyboard buffer */
  954.         if(j==0)                    /* get extended code if necessary */
  955.             j=getch()|(unsigned char)128;    /* set high bit to indicate extended code */
  956.         parse((unsigned char)j);
  957.       }    /* end if */
  958. } /* end bounce() */
  959. #endif
  960.  
  961. /**********************************************************************
  962. *  Function    :    outlinee
  963. *  Purpose    :    draw an outlined box on the ega screen
  964. *  Parameters    :
  965. *                x1,y1    - the x & y coor. of the upper left hand corner
  966. *                x2,y2    - the x & y coor. of the lower right hand corner
  967. *  Returns    :    none
  968. *  Calls    :    lineega()
  969. *  Called by    :    outline()
  970. **********************************************************************/
  971. void outlinee(x1,y1,x2,y2)
  972. int    x1,y1,x2,y2;
  973. {
  974.     int    i,j;            /* temporary counting variables */
  975.  
  976.     if(x2<x1)
  977.         swapint(&x1,&x2);
  978.     if(y2<y1)
  979.         swapint(&y1,&y2);
  980.     if(x2>=xdim)            /* clip the box if it is outside the image */
  981.         x2=xdim-1;
  982.     if(x1>=xdim)
  983.         x1=xdim-1;
  984.     if(y2>=ydim)
  985.         y2=ydim-1;
  986.     if(y1>=ydim)
  987.         y1=ydim-1;
  988.     for(i=x1+xoff; i<=x2+xoff; i++)        /* go through each pixel in the top line */
  989.         *(store[y1+yoff]+i)=~*(store[y1+yoff]+i);
  990.     for(i=x1+xoff; i<=x2+xoff; i++)        /* go through each pixel in the bottom line */
  991.         *(store[y2+yoff]+i)=~*(store[y2+yoff]+i);
  992.     for(j=y1+1+yoff; j<y2+yoff; j++) {        /* go thru and fix all the lines in between */
  993.         *(store[j]+x1+xoff)=~*(store[j]+x1+xoff);
  994.         *(store[j]+x2+xoff)=~*(store[j]+x2+xoff);
  995.       }    /* end for */
  996.     for(i=y1; i<=y2; i++) {        /* output the lines to the screen */
  997.         egaline(xwhere+x1,ywhere+i,store[i+yoff],x2-x1+1,trans,x1+xoff);
  998.       }    /* end for */
  999. }
  1000.  
  1001. /**********************************************************************
  1002. *  Function    :    outline
  1003. *  Purpose    :    call routines to put an outlined box on the screen
  1004. *  Parameters    :
  1005. *                x1,y1    - the x & y coor. of the upper left hand corner
  1006. *                x2,y2    - the x & y coor. of the lower right hand corner
  1007. *  Returns    :    none
  1008. *  Calls    :    outline9(), outlinev(), outlinee()
  1009. *  Called by    :    mousefunc()
  1010. **********************************************************************/
  1011. void outline(x1,y1,x2,y2)
  1012. int    x1,y1,x2,y2;
  1013. {
  1014.     switch(mode) {            /* switch to call different outline routines depending on monitor type */
  1015.         case NO9:
  1016.             outline9(x1,y1,x2,y2);
  1017.             break;
  1018.  
  1019.         case VGA:
  1020.             outlinev(x1,y1,x2,y2);
  1021.             break;
  1022.  
  1023.         case EGA:
  1024.         default:
  1025.             outlinee(x1,y1,x2,y2);    /* need offsets because ega has to modify the image data */
  1026.             break;
  1027.       }    /* end switch */
  1028. }
  1029.  
  1030. #ifdef MOUSE
  1031. /**********************************************************************
  1032. *  Function    :    mousefunc
  1033. *  Purpose    :    perform all of the mouse functions
  1034. *  Parameters    :    none
  1035. *  Returns    :    none
  1036. *  Calls    :    mousecl(), pixelcolor()
  1037. *  Called by    :    options()
  1038. **********************************************************************/
  1039. void mousefunc()
  1040. {
  1041.     int    off_x,off_y,            /* the offset the mouse cursor is inside the color bar */
  1042.         firstx,firsty;            /* the location of the first corner plotted in drawing a box */
  1043.  
  1044.     read_mouse();        /* get mouse position and button status */
  1045.     if(mx!=m3 || my!=m4) {    /* the mouse has been moved so update the screen */
  1046.         if(mode==NO9) {            /* update the mouse position for no9 screen */
  1047.             makecur9(mx,my);
  1048.             mx=m3;
  1049.             my=m4;
  1050.             makecur9(mx,my);
  1051.           }    /* end if */
  1052.         else {
  1053.             mx=m3;                /* update the old mouse positions */
  1054.             my=m4;
  1055.           }    /* end else */
  1056.       }    /* end if */
  1057.     if(rightbutton && show && (mx>=pal_xoff && mx<=(pal_xoff+255)))    /* if inside the color bar when the right button is pressed, then move color bar */
  1058.         if(my>=pal_yoff && my<=(pal_yoff+pal_height)) {    /* if mouse cursor is in the color bar then move it */
  1059.             nopal(xoff,yoff);        /* erase the color bar */
  1060.             if(mode==NO9) {
  1061.                 makecur9(mx,my);
  1062.                 off_x=mx-pal_xoff;        /* set the offset in the color bar */
  1063.                 off_y=my-pal_yoff;
  1064.               }    /* end if */
  1065.             else {
  1066.                 m1=2;                /* erase the cursor */
  1067.                 mousecl(&m1,&m2,&m3,&m4);
  1068.                 off_x=mx-pal_xoff;        /* set the offset in the color bar */
  1069.                 off_y=my-pal_yoff;
  1070.               }    /* end else */
  1071.             outline(pal_xoff,pal_yoff,pal_xoff+255,pal_yoff+pal_height);        /* plot the outline of the color bar */
  1072.             do {        /* keep moving the palette until the button is let up */
  1073.                 read_mouse();        /* get mouse position and button status */
  1074.                 if((m3+256-off_x)>maxx)    /* if trying to move the color bar off the left side of the screen */
  1075.                     m3=maxx-256+off_x;
  1076.                 if((m3-off_x)<0)        /* if trying to move off the right side of the screen */
  1077.                     m3=off_x;
  1078.                 if((m4+pal_height+1-off_y)>maxy)    /* if trying to move off the bottom of the screen */
  1079.                     m4=maxy-pal_height-1+off_y;
  1080.                 if((m4-off_y)<0)        /* if trying to move off the top of the screen */
  1081.                     m4=off_y;
  1082.                 if(m3!=mx || m4!=my) {    /* if mouse is moved then move outline of color bar */
  1083.                     outline(mx-off_x,my-off_y,mx-off_x+255,my-off_y+pal_height);
  1084.                     mx=m3;
  1085.                     my=m4;
  1086.                     outline(mx-off_x,my-off_y,mx-off_x+255,my-off_y+pal_height);
  1087.                   }    /* end if */
  1088.             } while(rightbutton);
  1089.             pal_xoff=mx-off_x;            /* find to upper left hand corner for the color bar */
  1090.             pal_yoff=my-off_y;
  1091.             outline(pal_xoff,pal_yoff,pal_xoff+255,pal_yoff+pal_height);
  1092.             draw_mouse();
  1093.             showpal();                    /* put the color bar back on the screen */
  1094.           }    /* end if */
  1095.     if(rightbutton) {        /* rightbutton functions */
  1096.         erase_mouse();
  1097.         if(mx>9 && mx<(maxx-9)) {    /* if not within the active region in the x dir. */
  1098.             if(my<10)            /* if within 10 pixels of top then scroll up */
  1099.                 scroll('u');
  1100.             if(my>(maxy-10))    /* if within 10 pixels of bottn then scroll down */
  1101.                 scroll('d');
  1102.           }    /* end if */
  1103.         if(mx>(maxx-10))     /* if within 10 pixels of edge of screen then do something */
  1104.             if(my<10 || my>(maxy-10))    /* if in one of the corners then page */
  1105.                 if(my<10)                /* page up */
  1106.                     scroll('U');
  1107.                 else                    /* page down */
  1108.                     scroll('D');
  1109.             else                        /* scroll right */
  1110.                 scroll('r');
  1111.         if(mx<10)            /* if within 10 pixels of edge of the screen then do something */
  1112.             if(my<10 || my>(maxy-10))    /* if in one of the corners then home/end */
  1113.                 if(my<10)                /* Home */
  1114.                     scroll('H');
  1115.                 else                    /* End */
  1116.                     scroll('E');
  1117.             else                        /* scroll left */
  1118.                 scroll('l');
  1119.         draw_mouse();
  1120.       }    /* end if */
  1121.     if(leftbutton) {    /* leftbutton functions */
  1122.         if(show && (mx>=pal_xoff && mx<=(pal_xoff+255)) && (my>=pal_yoff && my<=(pal_yoff+pal_height))) {
  1123.             if((mx-pal_xoff)<128) {            /* if on the left side then rotate that way */
  1124.                 rotate('r');
  1125.                 for(j=abs(mx-pal_xoff)*10; j>=0; j--);
  1126.               }    /* end if */
  1127.             else {                            /* must be on right side so rotate that way */
  1128.                 rotate('l');
  1129.                 for(j=(255-abs(mx-pal_xoff))*10; j>=0; j--);
  1130.               }    /* end else */
  1131.           }    /* end if */
  1132.         else {            /* draw an outlined box on the screen */
  1133.             erase_mouse();
  1134.             firstx=mx;
  1135.             firsty=my;
  1136.             outline(firstx,firsty,mx,my);
  1137.             do {        /* keep changing the size of the outline until the button is let up */
  1138.                 read_mouse();        /* get mouse position and button status */
  1139.                 if(m3!=mx || m4!=my) {    /* if mouse is moved then move outline of color bar */
  1140.                     outline(firstx,firsty,mx,my);        /* erase the outline */
  1141.                     mx=m3;
  1142.                     my=m4;
  1143.                     outline(firstx,firsty,mx,my);        /* re plot the outline */
  1144.                   }    /* end if */
  1145.               } while(leftbutton);
  1146.             outline(firstx,firsty,mx,my);
  1147.             if(firstx>mx)                    /* if square is defined backwards then flip ends */
  1148.                 swapint(&firstx,&mx);
  1149.             if(firsty>my)
  1150.                 swapint(&firsty,&my);
  1151.             if(mx>xdim-xoff)                        /* prevent the box from being outside the image */
  1152.                 mx=xdim;
  1153.             if(my>ydim-yoff)
  1154.                 my=ydim;
  1155.             if(firstx<xdim-xoff && firsty<ydim-yoff) {    /* if the box is actually in the image on the screen then expand */
  1156.                 grafmode();                                    /* clear the screen */
  1157.                 if(expandit) {                /* if preference is to expand the image */
  1158.                     if(expand(firstx+xoff,firsty+yoff,mx+xoff,my+yoff)==1)            /* expand chosen area to fill screen */
  1159.                         waitq();    /* wait for keypress */
  1160.                   }    /* end if */
  1161.                 else {                        /* if preference is to interpolate the image */
  1162.                     if(interpolate(firstx+xoff,firsty+yoff,mx+xoff,my+yoff)==1)            /* expand and smooth the chosen area to fill the screen */
  1163.                         waitq();    /* wait for keypress */
  1164.                   }    /* end else */
  1165.               }    /* end if */
  1166.             updatescrn();                                /* go back to old display */
  1167.           }    /* end else */    
  1168.       }    /* end if */
  1169. }    /* end mousefunc() */
  1170. #endif
  1171.  
  1172. /**********************************************************************
  1173. *  Function    :    options
  1174. *  Purpose    :    do all the fancy run-time things to the image
  1175. *  Parameters    :    none
  1176. *  Returns    :    none
  1177. *  Calls    :    parse(), mousecl(), mousefunc(), bounce()
  1178. *  Called by    :    main()
  1179. **********************************************************************/
  1180. void options()
  1181. {
  1182.     palnum=0;        /* start out at the first palette */
  1183. #ifdef MOUSE
  1184.     if(mouse)        /* if the mouse is already on then put it on the screen */
  1185.         draw_mouse();
  1186. #endif
  1187.     c='!';
  1188.     if(kbhit()) {
  1189.         c=getch();
  1190.         if(c==0)        /* check for extended character code */
  1191.             c=getch()|(unsigned char)128;    /* set high bit to indicate extended code */
  1192.       }    /* end if */
  1193.  
  1194.     while(c!='q' && !(c=='a' && animate) && c!='Q') {                   /* continue until 'q' */
  1195.         c='!';
  1196. #ifdef QAK
  1197.         waitcount=0;
  1198. #endif
  1199.         while (c=='!') {
  1200.             if(kbhit()) {        /* get the next command */
  1201.                 c=getch();
  1202.                 if(c==0)
  1203.                     c=getch()|(unsigned char)128;    /* set high bit to indicate extended code */
  1204.               }    /* end if */
  1205. #ifdef MOUSE
  1206.             if(mouse) {        /* if the mouse is active then perform some functions */
  1207.                 mousefunc();
  1208. #ifdef QAK
  1209.                 waitcount=0;        /* reset the counter to time out */
  1210. #endif
  1211.               }    /* end if */
  1212. #endif
  1213. #ifdef QAK
  1214.             if(waitcount>100000) {        /* if timed out then bounce the ball */
  1215.                 if(mode==VGA || mode==NO9)
  1216.                     bounce();
  1217.                 waitcount=0;        /* reset the timed out counter */
  1218.               }    /* end if */
  1219.             waitcount++;
  1220. #endif
  1221.           }    /* end while */
  1222.         if(c=='?') {                /* if help is requisitioned */
  1223.             if(mouse && mode==NO9)
  1224.                 makecur9(mx,my);
  1225.             textmode();
  1226.             printf("General Help Screen\n\n");
  1227.             printf("i\t\t - Show Information About Image\n");
  1228.             printf("a\t\t - Show Animation Again\n");
  1229.             printf("k\t\t - End Animation Mode\n");
  1230.             printf("o\t\t - Turn VGA Screen Off Or On\n");
  1231.             printf("m\t\t - Activate/Deactivate Mouse\n");
  1232.             printf(",\t\t - Magnify\Interpolate A Portion Of The Screen\n");
  1233.             printf("w\t\t - Switch Between Magnifying And Interpolating\n");
  1234.             printf("/\t\t - Slow Down Animation Speed\n");
  1235.             printf("*\t\t - Speed Up Animation Speed\n");
  1236.             printf("q\t\t - Quit Viewing Current Image\n");
  1237.             printf("Q\t\t - Exit Program\n");
  1238.             printf("?\t\t - Show This Help Sequence\n\n");
  1239.             printf("Hit <enter> For More Help, Or Any Key to Return to Graphics Mode");
  1240.             c='!';
  1241.             while (c=='!') {
  1242.                 if(kbhit()) {    /* get the next command */
  1243.                     c=getch();
  1244.                     if(c==0)
  1245.                         c=getch()|(unsigned char)128;    /* set high bit to indicate extended code */
  1246.                   }    /* end if */
  1247.               }    /* end while */
  1248.             printf("\n");
  1249.             if(c==13){    /* if enter is hit for next help screen */
  1250.                 textmode();
  1251.                 printf("Palette Help Screen\n\n");
  1252.                 printf("f\t\t - Rotate Palette Continuously Forward\n");
  1253.                 printf("b\t\t - Rotate Palette Continuously Backward\n");
  1254.                 printf("+\t\t - Speed Up Palette Rotation\n");
  1255.                 printf("-\t\t - Slow Down Palette Rotation\n");
  1256.                 printf("space bar\t - Stop Rotation Of Palette Or Animation\n");
  1257.                 printf("e\t\t - Rotate Palette Once Forward\n");
  1258.                 printf("v\t\t - Rotate Palette Once Backward\n");
  1259.                 printf("r\t\t - Reset Palette To Original Settings\n");
  1260.                 printf("c\t\t - Toggle Color Bar On Or Off The Screen\n");
  1261.                 printf("l\t\t - Load In A New Palette From Disk\n");
  1262.                 printf("n\t\t - Display Next Palette In Memory\n");
  1263.                 printf("s\t\t - Store Palette On Disk\n");
  1264.                 printf("u\t\t - Swap The Red, Green, And Blue Components Of Palettes\n");
  1265.                 printf("t\t\t - Transpose Palette\n");
  1266.                 printf("g\t\t - Invert Palette Bitwise\n");
  1267.                 printf("h\t\t - Enter Fiddle Mode\n");
  1268.                 printf("p\t\t - Move Color Bar On The Screen\n");
  1269.                 printf("d\t\t - Make Current Palette The Default Values\n\n");
  1270.                 printf("Hit <enter> For More Help, Or Any Key to Return to Graphics Mode");
  1271.                 c='!';
  1272.                 while (c=='!') {
  1273.                     if(kbhit()) {    /* get the next command */
  1274.                         c=getch();
  1275.                         if(c==0)
  1276.                             c=getch()|(unsigned char)128;    /* set high bit to indicate extended code */
  1277.                       }    /* end if */
  1278.                   }    /* end while */
  1279.                 printf("\n");
  1280.                 if(c==13) {
  1281.                     textmode();
  1282.                     printf("Image Help Screen\n\n");
  1283.                     printf("left arrow\t - Move Image Left Ten Pixels\n");
  1284.                     printf("up arrow\t - Move Image Up Ten Pixels\n");
  1285.                     printf("down arrow\t - Move Image Down Ten Pixels\n");
  1286.                     printf("right arrow\t - Move Image Right Ten Pixels\n");
  1287.                     printf("page up\t - Page Image Up A Full Screen\n");
  1288.                     printf("page down\t - Page Image Down A Full Screen\n");
  1289.                     printf("home\t\t - Move To The Upper Left Hand Corner Of The Image\n");
  1290.                     printf("end\t\t - Move To The Lower Right Hand Corner Of The Image\n");
  1291.                     printf("x\t\t - Input X and Y Coor. For Upper Left Hand Corner\n");
  1292.                     printf("Hit Any Key to Return To Graphics Mode");
  1293.                     c='!';
  1294.                     while (c=='!') {
  1295.                         if(kbhit()) {    /* get the next command */
  1296.                             c=getch();
  1297.                             if(c==0)
  1298.                                 c=getch()|(unsigned char)128;    /* set high bit to indicate extended code */
  1299.                           }    /* end if */
  1300.                        }    /* end while */
  1301.                     printf("\n");
  1302.                     }    /* end if */
  1303.               }    /* end if */
  1304.             grafmode();
  1305.             updatescrn();
  1306.           }    /* end if */
  1307.         parse(c);
  1308.       } /* end while */
  1309. #ifdef MOUSE
  1310.     if(mouse)                    /* if the mouse is on then remove the cursor before leaving */
  1311.         erase_mouse();
  1312. #endif
  1313. } /* end options() */
  1314.