home *** CD-ROM | disk | FTP | other *** search
- /*
- * options.c
- *
- * This set of routines takes care of the image and palette manipulations
- * after an image has been read in and displayed.
- *
- * National Center for Supercomputing Applications, University of Illinois
- * 153 Computing Applications Building
- * 605 E. Springfield Ave.
- * Champaign, IL 61820 (217)244-0072
- *
- * Quincey Koziol August 1988
- *
- */
-
- #include "showext.h"
-
- /**********************************************************************
- * Function : draw_mouse()
- * Purpose : draw the mouse cursor on the screen
- * Parameters : none
- * Returns : none
- * Calls : mousecml(), makecur9()
- * Called by : mousefunc(), parse(), window(),
- **********************************************************************/
- void draw_mouse()
- {
- if(mode==NO9)
- makecur9(mx,my);
- else {
- m1=1;
- mousecl(&m1,&m2,&m3,&m4);
- } /* end else */
- } /* end draw_mouse() */
-
- /**********************************************************************
- * Function : erase_mouse()
- * Purpose : erase the mouse cursor from the screen
- * Parameters : none
- * Returns : none
- * Calls : mousecml(), makecur9()
- * Called by : mousefunc(), parse(), window(),
- **********************************************************************/
- void erase_mouse()
- {
- if(mode==NO9)
- makecur9(mx,my);
- else {
- m1=2;
- mousecl(&m1,&m2,&m3,&m4);
- } /* end else */
- } /* end erase_mouse() */
-
- /**********************************************************************
- * Function : read_mouse()
- * Purpose : read the mouse position and button status and scale for correct
- * display mode
- * Parameters : none
- * Returns : none
- * Calls : mousecml()
- * Called by : mousefunc(), parse(), window(),
- **********************************************************************/
- void read_mouse()
- {
- m1=3; /* get mouse position and button status */
- mousecl(&m1,&m2,&m3,&m4);
- leftbutton=rightbutton=0;
- leftbutton=m2&1; /* get left button bit from mouse variable */
- rightbutton=(m2&2)>>1; /* get right button bit from mouse variable */
- if(mode!=EGA)
- m3=m3>>1; /* compensate for the mouse */
- if(mode==NO9) { /* if no9 then compensate the mouse more */
- m3=m3>>2;
- m4=m4>>3;
- } /* end if */
- } /* end read_mouse()*/
-
- /**********************************************************************
- * Function : readstr
- * Purpose : get a simple set of characters from stdin
- * Parameters :
- * charstr - pointer to the character string to be read in
- * Returns : none
- * Calls : getch()
- * Called by : parse()
- **********************************************************************/
- void readstr(charstr)
- unsigned char *charstr;
- {
- charstr--;
- do {
- charstr++;
- *charstr=getch();
- if(*charstr==0)
- *charstr=getch()|(unsigned char)128; /* set high bit to indicate extended code */
- printf("%c",*charstr);
- } while(*charstr!=13); /* end while */
- *charstr=0;
- }
-
- /**********************************************************************
- * Function : swapint
- * Purpose : swap two integer values
- * Parameters :
- * x,y - pointers to the two values to swap
- * Returns : none
- * Calls : none
- * Called by : mousefunc()
- **********************************************************************/
- void swapint(x,y)
- int *x,*y; /* values to exchange */
- {
- int t; /* temporary variable */
-
- t=*x;
- *x=*y;
- *y=t;
- } /* end swapint() */
-
- /**********************************************************************
- * Function : swap
- * Purpose : swap two character values
- * Parameters :
- * x,y - pointers to the two values to swap
- * Returns : none
- * Calls : none
- * Called by : options()
- **********************************************************************/
- void swap(x,y)
- unsigned char *x,*y; /* values to exchange */
- {
- unsigned char t; /* temporary variable */
-
- t=*x;
- *x=*y;
- *y=t;
- } /* end swap() */
-
- /**********************************************************************
- * Function : findpal
- * Purpose : loads in a new palette from an HDF file after the first one
- * Parameters : none
- * Returns : none
- * Calls : DFfind(), DFgetelement(), palloc(), palloce(), select_pal()
- * Called by : options()
- **********************************************************************/
- void findpal()
- {
- int i, /* local counting variable */
- palold; /* last palmax value */
- char *pi; /* pointer to character array of palette read in */
-
- DFsetfind(dff,DFTG_IP8,DFREF_WILDCARD); /* set the HDF file to a palette */
-
- palold=palmax;
- if (!DFfind(dff,&ddstr)) { /* HDF file should be set for palettes */
- if(DFgetelement(dff,ddstr.tag,ddstr.ref,pal)>=0) {
- pi = pal;
- for (i=0; i<256; i++) {
- rmap[i] = *pi++;
- gmap[i] = *pi++;
- bmap[i] = *pi++;
- } /* end for */
- palmax++;
- } /* end if */
- } /* end if */
-
- /* see if there is enough space for another palette */
-
- if(palmax!=palold) {
- if(mode!=EGA) {
- if(!palloc(palmax)) { /* if no space available then go back to last one */
- palmax--;
- displayerr("No Room For Another Palette");
- memcpy(rmap,rpal[palnum],256);
- memcpy(gmap,gpal[palnum],256);
- memcpy(bmap,bpal[palnum],256);
- } /* end if */
- else /* palloc() was ok, so switch to the palette */
- palnum=palmax;
- } /* end if */
- else {
- if(!palloce(palmax)) { /* no space, so switch to old palette */
- displayerr("No Room For Another Palette");
- palmax--;
- memcpy(regrs,egapals[palnum],16);
- } /* end if */
- else { /* enough space for a palette, so use it */
- palnum=palmax;
- select_pal(xdim,ydim,1); /* do a frequency count and set up the ega palette */
- } /* end else */
- } /* end else */
- } /* end if */
- } /* end findpal() */
-
- /**********************************************************************
- * Function : showpal
- * Purpose : display the current palette on the screen. EGA monitors
- * directly change to data in memory, whereas VGA and NO9 monitors
- * just change the data on the screen.
- * Parameters : none
- * Returns : none
- * Calls : showpalv(), showpal9(), egaline()
- * Called by : options()
- **********************************************************************/
- void showpal()
- {
- #ifdef MOUSE
- if(mouse)
- erase_mouse();
- #endif
- switch (mode) { /* different methods for showing the palette on the screen */
- case VGA:
- showpalv(&palstore,pal_xoff,pal_yoff);
- break;
-
- case NO9:
- showpal9(&palstore,pal_xoff,pal_yoff);
- break;
-
- case EGA:
- default:
- for(i=0; i<16; i++)
- for(k=0; k<16; k++)
- palstore[0][i*16+k]=i;
- 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' */
- egaline(xwhere+pal_xoff,ywhere+j+pal_yoff,&palstore[0][0],256,trans1,0);
- break;
- } /* end switch(mode) */
- #ifdef MOUSE
- if(mouse)
- draw_mouse();
- #endif
- } /* end showpal() */
-
- /**********************************************************************
- * Function : nopal
- * Purpose : replace the palette on the screen with the image under it.
- * Once again, EGA mode changes the data in memory, whereas VGA
- * NO9 change it only on the screen.
- * Parameters :
- * xoff,yoff - the x & y offsets into the image where the screen is
- * positioned
- * Returns : none
- * Calls : nopalv(), nopal9(), egaline()
- * Called by : options()
- **********************************************************************/
- void nopal(xoff,yoff)
- int xoff,yoff; /* the x & y offset into the image being displayed */
- {
- #ifdef MOUSE
- if(mouse)
- erase_mouse();
- #endif
- switch(mode){ /* different routines to restore the screen */
- case VGA:
- nopalv(&palstore,pal_xoff,pal_yoff);
- break;
-
- case NO9:
- nopal9(&palstore,pal_xoff,pal_yoff);
- break;
-
- case EGA:
- default:
- if(pal_yoff<(ydim-pal_height))
- for(j=0; j<8; j++) /* just re plot that section of the screen */
- egaline(xwhere+pal_xoff,ywhere+j+pal_yoff,store[j+pal_yoff+yoff],min(256,xdim-pal_xoff),trans,xoff+pal_xoff);
- break;
- } /* end switch(mode) */
- #ifdef MOUSE
- if(mouse)
- draw_mouse();
- #endif
- } /* end nopal() */
-
- /**********************************************************************
- * Function : waitq
- * Purpose : wait for a keypress
- * Parameters : none
- * Returns : none
- * Calls : none
- * Called by : many places...
- **********************************************************************/
- void waitq()
- {
- unsigned char c; /* temporary variable to hold the character read in */
-
- c='!';
- while (c=='!') {
- if(kbhit()) { /* get the next command */
- c=getch();
- if(c==0)
- c=getch()|(unsigned char)128; /* set high bit to indicate extended code */
- } /* end if */
- } /* end while */
- } /* waitq() */
-
- /**********************************************************************
- * Function : printdir
- * Purpose : print out a listing of files ending in '.pal' in the
- * current local directory
- * Parameters : none
- * Returns : none
- * Calls : textmode()
- * Called by : options()
- **********************************************************************/
- void printdir()
- {
- unsigned char palnames[4096]; /* array to store palette names */
- char *p, /* pointer to position if names file */
- *fnp="*.pal"; /* pattern to look for */
- int n, /* number of matching file names */
- attr=0; /* look for normal files */
-
- if((n=getfnl(fnp,palnames,sizeof(palnames),attr))<=0) /* load the names of the palettes into an array */
- printf("No Palettes In The Current Directory\n");
- else
- for(p=palnames; *p!='\0'; p+=strlen(p)+1) /* write out all the names */
- printf("%s\n",p);
- printf("\nHit Any Key To Continue");
- waitq();
- textmode();
- } /* end printdir() */
-
- #ifdef QAK
- /**********************************************************************
- * Function : slidepal
- * Purpose : rotate the palette an arbitary amount
- * Parameters :
- * offset - the amount to slide the palette
- * Returns : none
- * Calls : none
- * Called by : options()
- **********************************************************************/
- void slidepal(x)
- int x; /* amount of positive or negative offset to slide the palette */
- {
- if(mode!=EGA){
- if(x<0){
- memcpy(rmap,rpal[palnum]-x,256+x); /* shift palettes down x bytes */
- memcpy(gmap,gpal[palnum]-x,256+x);
- memcpy(bmap,bpal[palnum]-x,256+x);
- for(j=255+x; j<=255; j++){ /* fill in the leftover places */
- rmap[j]=rmap[j-1];
- gmap[j]=gmap[j-1];
- bmap[j]=bmap[j-1];
- } /* end for */
- } /* end if */
- else{
- memcpy(rmap+x,rpal[palnum],256-x); /* shift palettes up x bytes */
- memcpy(gmap+x,gpal[palnum],256-x);
- memcpy(bmap+x,bpal[palnum],256-x);
- for(j=x; j>=0; j--){ /* fill in the leftover places */
- rmap[j]=rmap[j+1];
- gmap[j]=gmap[j+1];
- bmap[j]=bmap[j+1];
- } /* end for */
- } /* end else */
- } /* end if */
- } /* end slidepal() */
- #endif
-
- /**********************************************************************
- * Function : squishpal
- * Purpose : compress the palette an arbitrary amount
- * Parameters :
- * slope - the slope of the line to compress palette with
- * offset - the amount to slide the palette
- * Returns : none
- * Calls : abs()
- * Called by : options()
- **********************************************************************/
- void squishpal(x,y)
- int x, /* the slope of the line to squish the palette with */
- y; /* the offset to slide the palette by when the squishing is done */
- {
- int j,k, /* temporary counting variables */
- lox, /* the value of the x-intercept if y=0 */
- hix; /* the value of the x-intercept if y=255 */
-
- if(x!=0){
- lox=(10*((-127)-y)/x)+127;
- hix=(10*(128-y)/x)+127;
- } /* end if */
- else{
- lox=127;
- hix=127;
- } /* end else */
- if(lox!=0) /* check for the beginning value not on the beginning of the palette */
- if(lox<0)
- lox=0; /* if i=it is before the palette then set it to beginning of the palette */
- else{
- for(j=lox-1; j>=0; j--){ /* if it is after the beginning of the palette then fill to beginning */
- rmap[j]=rpal[palnum][lox-1];
- gmap[j]=gpal[palnum][lox-1];
- bmap[j]=bpal[palnum][lox-1];
- } /* end for j */
- } /* end else */
- if(hix!=255) /* check for end value not exactly on the end of the palette */
- if(hix>255) /* if it is after the end of the palette then set it to the end of the palette */
- hix=255;
- else{
- for(j=hix+1; j<=255; j++){ /* if it is before the end of the palette then fill to the end */
- rmap[j]=rpal[palnum][hix+1];
- gmap[j]=gpal[palnum][hix+1];
- bmap[j]=bpal[palnum][hix+1];
- } /* end for j */
- } /* end else */
- if(hix<lox) /* make sure it increments in correct fashion */
- swap(&lox,&hix);
- for(j=lox; j<=hix; j++){
- k=x*(j-127)/10+127+y; /* y = mx+b equation of a line */
- rmap[j]=rpal[palnum][k];
- gmap[j]=gpal[palnum][k];
- bmap[j]=bpal[palnum][k];
- } /* end for j */
- } /* end squishpal() */
-
- #ifdef QAK
- /**********************************************************************
- * Function : pixelcolor
- * Purpose : returns the color of a specified pixel
- * Parameters :
- * x - the x coor. of the pixel
- * y - the y coor. of the pixel
- * Returns : the color of the pixel as a char
- * Calls : none
- * Called by : mousefunc()
- **********************************************************************/
- unsigned char pixelcolor(x,y)
- int x,y; /* the x and y coor. of the pixel whose color is returned */
- {
- if(show && ((x>=pal_xoff && x<=(pal_xoff+255)) && (y>=pal_yoff && y<=(pal_yoff+pal_height))))
- switch(mode) { /* return different values for different screen types */
- case VGA:
- case NO9:
- return((unsigned char) (x-pal_xoff));
- break;
-
- case EGA:
- default:
- return((unsigned char) ((x-pal_xoff)/16));
- break;
- } /* end switch */
- else /* if not in the color bar then return the normal value */
- return((unsigned char) store[y+yoff][x+xoff]);
- } /* end pixelcolor() */
- #endif
-
- /**********************************************************************
- * Function : updatescrn
- * Purpose : updates the screen with the current image, color bar,
- * and the mouse cursor
- * Parameters : none
- * Returns : none
- * Calls : showpic(), showpal(), pixelcolor()
- * Called by : options()
- **********************************************************************/
- void updatescrn()
- {
- showpic();
- if(show)
- showpal();
- #ifdef MOUSE
- if(mouse) /* if the mouse is on then replace the mouse cursor */
- draw_mouse();
- #endif
- } /* end updatescrn() */
-
- /**********************************************************************
- * Function : scroll
- * Purpose : move the image around the screen
- * Parameters :
- * func - the scrolling function to be performed
- * Returns : none
- * Calls : updatescrn()
- * Called by : options(), mousefunc()
- **********************************************************************/
- void scroll(func)
- unsigned char func; /* the function to be performed on the screen */
- {
- int i; /* temporary variables to hold the old xoff and yoff */
-
- #ifdef MOUSE
- if(mouse) /* if the mouse is on then hide the cursor while moving */
- erase_mouse();
- #endif
- switch(func) { /* switch to perform the appropriate scroll */
- case 'l': /* scroll left */
- i=xoff;
- xoff-=10;
- if(xoff<0)
- xoff=0;
- if(xoff!=i)
- updatescrn();
- break;
-
- case 'r': /* scroll right */
- i=xoff;
- xoff+=10;
- if(xdim-maxx<0)
- xoff=0;
- else
- if(xoff>xdim-maxx)
- xoff=xdim-maxx;
- if(i!=xoff)
- updatescrn();
- break;
-
- case 'u': /* scroll up */
- i=yoff;
- yoff-=10;
- if(yoff<0)
- yoff=0;
- if(yoff!=i)
- updatescrn();
- break;
-
- case 'd': /* scroll down */
- i=yoff;
- yoff+=10;
- if(ydim-maxy<0)
- yoff=0;
- else
- if(yoff>ydim-maxy)
- yoff=ydim-maxy;
- if(i!=yoff)
- updatescrn();
- break;
-
- case 'H': /* Move to upper left hand corner of image */
- if(yoff!=0||xoff!=0) {
- xoff=0;
- yoff=0;
- updatescrn();
- } /* end if */
- break;
-
- case 'E': /* Move to lower right hand corner of image */
- if(yoff!=ydim-maxy||xoff!=xdim-maxx) {
- xoff=xdim-maxx;
- if(xoff<0)
- xoff=0;
- yoff=ydim-maxy;
- if(yoff<0)
- yoff=0;
- updatescrn();
- } /* end if */
- break;
-
- case 'U': /* page image up */
- i=yoff;
- yoff-=maxy;
- if(yoff<0)
- yoff=0;
- if(yoff!=i)
- updatescrn();
- break;
-
- case 'D': /* page image down */
- i=yoff;
- yoff+=maxy;
- if(ydim-maxy<0)
- yoff=0;
- else
- if(yoff>ydim-maxy)
- yoff=ydim-maxy;
- if(i!=yoff)
- updatescrn();
- break;
- } /* end switch */
- #ifdef MOUSE
- if(mouse) /* if the mouse is on then replace the cursor after moving */
- draw_mouse();
- #endif
- } /* end scroll() */
-
- /**********************************************************************
- * Function : rotate
- * Purpose : rotate the palette left or right
- * Parameters :
- * func - character to determine which direction to rotate
- * Returns : none
- * Calls : putpal(), memcpy()
- * Called by : options(), mousefunc()
- **********************************************************************/
- void rotate(func)
- unsigned char func; /* parameter to determine which way to rotate the palette */
- {
- switch(func) { /* switch for what to do to the palette */
- case 'l': /* rotate the palette left */
- if(mode!=EGA) {
- i=rmap[255];
- j=gmap[255];
- k=bmap[255];
- memcpy(rmap+1,rmap,255); /* shift palettes up one byte */
- memcpy(gmap+1,gmap,255);
- memcpy(bmap+1,bmap,255);
- rmap[0]=i;
- gmap[0]=j;
- bmap[0]=k;
- } /* end if */
- else {
- i=regrs[15];
- for(j=15; j>=1; j--)
- regrs[j]=regrs[j-1];
- regrs[0]=i;
- } /* end else */
- putpal();
- break;
-
- case 'r': /* rotate the palette right */
- if(mode!=EGA) {
- i=rmap[0];
- j=gmap[0];
- k=bmap[0];
- memcpy(rmap,rmap+1,255); /* shift palettes down one byte */
- memcpy(gmap,gmap+1,255);
- memcpy(bmap,bmap+1,255);
- rmap[255]=i;
- gmap[255]=j;
- bmap[255]=k;
- } /*end if */
- else {
- i=regrs[0];
- for(j=0; j<=14; j++)
- regrs[j]=regrs[j+1];
- regrs[15]=i;
- } /* end else */
- putpal();
- break;
- } /* end switch */
- } /* end rotate() */
-
- /**********************************************************************
- * Function : expand
- * Purpose : routine to blow up a section of the screen
- * Parameters :
- * x1,y1 - location of the upper left hand corner of the box to blow up
- * x2,y2 - location of the lower right hand corner of the box to blow up
- * Returns :
- * 1 - if routine was successfully finished
- * 0 - if routine was interupted
- * Calls : vgaline1()
- * Called by : mousefunc()
- **********************************************************************/
- int expand(x1,y1,x2,y2)
- int x1,y1, /* location of the upper left hand corner of the box to blow up */
- x2,y2; /* location of the lower right hand corner of the box to blow up */
-
- {
- unsigned char line[640]; /* a line to blow a line of the box up into */
- float xdiff,ydiff, /* the differences between the x and y corners */
- maxxf,maxyf; /* a float variable for maxx and maxy */
- int i,j,k,l,m;
-
- xdiff=x2-x1; /* find difference between endpoints */
- ydiff=y2-y1;
- maxxf=maxx;
- maxyf=maxy;
- l=-1; /* preset the line counter to calculate the first line */
- for(i=0; i<maxy; i++) { /* go through all the lines in the image */
- k=(int)((i/maxyf)*ydiff)+y1;
- if(k!=l) { /* if this line is not the same as the previous then re-calculate it */
- for(j=0; j<maxx; j++) /* go through each line and magnify */
- line[j]=store[k][(int)((j/maxxf)*xdiff)+x1];
- l=k; /* set the line */
- } /* end if */
- switch(mode) { /* use different line drawing routines for different screens */
- case VGA:
- vgaline1(0,i,line,0,maxx); /* send each line out to the screen */
- break;
-
- case NO9:
- no9line(0,i,line,0,maxx);
- break;
-
- case EGA:
- default:
- egaline(0,i,line,maxx,trans,0);
- break;
- } /* end switch */
- if(kbhit()) { /* break out if the keyboard is hit */
- m=getch(); /* clear the keyboard buffer */
- if(m==0) /* get extended code if necessary */
- m=getch()|(unsigned char)128; /* set high bit to indicate extended code */
- return(0);
- } /* end if */
- } /* end for */
- return(1);
- } /* end expand() */
-
- /**********************************************************************
- * Function : interpolation
- * Purpose : routine to blow up a section of the screen and interpolate
- * data to a smooth image
- * Parameters :
- * x1,y1 - location of the upper left hand corner of the box to blow up
- * x2,y2 - location of the lower right hand corner of the box to blow up
- * Returns :
- * 1 - if routine was successfully finished
- * 0 - if routine was interupted
- * Calls : vgaline1(), egaline(), no9line(), interdata()
- * Called by : mousefunc()
- **********************************************************************/
- int interpolate(x1,y1,x2,y2)
- int x1,y1, /* location of the upper left hand corner of the box to blow up */
- x2,y2; /* location of the lower right hand corner of the box to blow up */
-
- {
- unsigned char line[640]; /* a line to blow a line of the box up into */
- float hpercent,vpercent, /* the percentage of the distance the pixel is towards the hi value */
- vdata1,vdata2, /* the data for the vertical interpolation */
- hfinal, /* the final result for horizontal interpolation */
- hdata1,hdata2, /* the data for horizontal interpolation */
- vfinal, /* the final result for vertical interpolation */
- xdiff,ydiff, /* the differences between the x and y corners */
- tempy,tempx, /* temporary floating value */
- maxxf,maxyf; /* a float variable for maxx and maxy */
- int i,j,hix,lox,hiy,loy; /* integer values for the coor. in the images around the current pixel */
-
- xdiff=x2-x1; /* find difference between endpoints */
- ydiff=y2-y1;
- maxxf=maxx;
- maxyf=maxy;
- for(i=0; i<maxy; i++) { /* go through all the lines in the image */
- tempy=((i/maxyf)*ydiff)+(float)y1; /* calculate the fractional pixel position in the image */
- loy=tempy; /* calculate the address of the lower y bound */
- hiy=ceil(tempy); /* calculate the address of the upper y bound */
- vpercent=(tempy-(float)loy)/((float)hiy-(float)loy);
- for(j=0; j<maxx; j++) { /* go through each line and interpolate */
- tempx=((j/maxxf)*xdiff)+(float)x1; /* calculate the fractional pixel position in the image */
- lox=tempx; /* calculate the lower x bound */
- hix=ceil(tempx); /* calculate the upper x bound */
- vdata1=(store[hiy][lox]-store[loy][lox])*vpercent+store[loy][lox];
- vdata2=(store[hiy][hix]-store[loy][hix])*vpercent+store[loy][hix];
- hpercent=(tempx-(float)lox)/((float)hix-(float)lox);
- hfinal=(vdata2-vdata1)*hpercent+vdata1;
- hdata1=(store[loy][hix]-store[loy][lox])*hpercent+store[loy][lox];
- hdata2=(store[hiy][hix]-store[hiy][lox])*hpercent+store[hiy][lox];
- vfinal=(hdata2-hdata1)*vpercent+hdata1;
- line[j]=(hfinal+vfinal)/2.0;
- } /* end for */
- switch(mode) { /* use different line drawing routines for different screens */
- case VGA:
- vgaline1(0,i,line,0,maxx); /* send each line out to the screen */
- break;
-
- case NO9:
- no9line(0,i,line,0,maxx);
- break;
-
- case EGA:
- default:
- egaline(0,i,line,maxx,trans,0);
- break;
- } /* end switch */
- if(kbhit()) { /* break out if the keyboard is hit */
- i=getch();
- if(i==0) /* get extended code if necessary */
- i=getch()|(unsigned char)128; /* set high bit to indicate extended code */
- return(0);
- } /* end if */
- } /* end for */
- return(1);
- } /* end interpolation() */
-
- #ifdef MOUSE
- /**********************************************************************
- * Function : makehex
- * Purpose : convert an ascii string of binary digits into an integer
- * Parameters :
- * binstr - string of binary digits
- * Returns : integer value of binary string
- * Calls : pow(), strlen()
- * Called by : makemouse()
- **********************************************************************/
- int makehex(binstr)
- char *binstr;
- {
- int i,j,k; /* local counting variables */
- double pow(); /* pow(x,y) returns x to the y power */
-
- k=strlen(binstr); /* find the length of the binary string */
- i=0;
- for(j=k-1; j>=0; j--) /* make a binary string into a hex number */
- i+=((int)pow((double)2,(double)j))*((int)*(binstr++)-48);
- return(i);
- }
-
- /**********************************************************************
- * Function : makemouse
- * Purpose : make the mouse cursor into a crosshair for vga and ega modes
- * Parameters : none
- * Returns : none
- * Calls : mousecl()
- * Called by : options()
- **********************************************************************/
- void makemouse()
- {
- int cursor[2][16]; /* array for screen and cursor bit masks */
-
- if(mode!=NO9) { /* only do this for vga and ega modes */
- /* screen mask */
- cursor[0][0]= makehex("1001111111111111");
- cursor[0][1]= makehex("1010111111111111");
- cursor[0][2]= makehex("1011011111111111");
- cursor[0][3]= makehex("1011101111111111");
- cursor[0][4]= makehex("1011110111111111");
- cursor[0][5]= makehex("1011111011111111");
- cursor[0][6]= makehex("1011111101111111");
- cursor[0][7]= makehex("1011111011111111");
- cursor[0][8]= makehex("1010011011111111");
- cursor[0][9]= makehex("1001101101111111");
- cursor[0][10]=makehex("1111101101111111");
- cursor[0][11]=makehex("1111110011111111");
- cursor[0][12]=makehex("1111111111111111");
- cursor[0][13]=makehex("1111111111111111");
- cursor[0][14]=makehex("1111111111111111");
- cursor[0][15]=makehex("1111111111111111");
-
- /* cursor mask */
- for(i=0; i<16; i++) /* set the entire cursor mask to inverse of the screen mask */
- cursor[1][i]=~cursor[0][i];
- m1=9; /* function to define cursor shape and hot spot */
- m2=0; /* horizontal hot spot */
- m3=0; /* vertical hot spot */
- mousecl(&m1,&m2,&m3,&cursor[0][0]);
- m1=1; /* function to show the cursor */
- mousecl(&m1,&m2,&m3,&m4);
- } /* end if */
- } /* end makemouse() */
- #endif
-
- #ifdef QAK
- /**********************************************************************
- * Function : bounce
- * Purpose : bounce a ball on the screen
- * Parameters : none
- * Returns : none
- * Calls : drand48(), ball()
- * Called by : options()
- **********************************************************************/
- void bounce()
- {
- int x1[5],x2[5],y1[5],y2[5], /* variables to keep track of the balls position */
- j, /* timing variable */
- i, /* local counting variable */
- maxball=0, /* number of balls on the screen */
- ballsize, /* size of the ball in pixels */
- xspeed[5],yspeed[5]; /* variables to keep track of the balls speed */
-
- double drand48(); /* random number function */
- long time(),l; /* the system time for seeding the random pointer */
- void parse(),srand48(); /* command parsing function */
-
- srand48(time(&l)); /* seed the random number generator */
- if(mode==NO9) /* set the ball sizes for different screens */
- ballsize=8;
- else
- ballsize=4;
- x1[0]=(int)(drand48()*(double)(maxx-ballsize-1))+1; /* randomize starting position */
- x2[0]=x1[0];
- y1[0]=(int)(drand48()*(double)(maxy-ballsize-1))+1;
- y2[0]=y1[0];
- xspeed[0]=0;
- while(xspeed[0]==0) /* randomize speed, not allowing 0 speed in a direction */
- xspeed[0]=(int)(drand48()*(double)11)-6;
- yspeed[0]=0;
- while(yspeed[0]==0)
- yspeed[0]=(int)(drand48()*(double)11)-6;
- #ifdef MOUSE
- m1=11; /* reset the mouse position counters */
- mousecl(&m1,&m2,&m3,&m4);
- #endif
- m3=m4=0;
- if(mode==NO9) /* plot the ball */
- ball9(x1[0],y1[0]);
- else
- ball(x1[0],y1[0]);
- while(!kbhit() && !m3 && !m4) { /* bounce the ball until a key is pressed */
- for(i=maxball; i>=0; i--) { /* check through all the balls */
- if(mode==NO9)
- ball9(x1[i],y1[i]);
- else
- ball(x1[i],y1[i]); /* remove the ball */
- x2[i]+=xspeed[i]; /* move the ball */
- y2[i]+=yspeed[i];
- if(x2[i]<0 || x2[i]>(maxx-ballsize-1)) { /* check for off screen in the x direction */
- xspeed[i]=-(xspeed[i]); /* reverse the direction of the movement */
- x2[i]+=xspeed[i];
- } /* end if */
- if(y2[i]<0 || y2[i]>(maxy-ballsize-1)) { /* check for off screen in the y direction */
- yspeed[i]=-(yspeed[i]);
- y2[i]+=yspeed[i];
- } /* end if */
- if(mode==NO9)
- ball9(x2[i],y2[i]);
- else
- ball(x2[i],y2[i]); /* plot the ball in it's new position */
- x1[i]=x2[i]; /* update the balls position */
- y1[i]=y2[i];
- if((int)(drand48()*(double)10000)==0) /* on very rare occasions change the ball speed */
- switch ((int)(drand48()*4)) { /* choose which speed to change */
- case 0:
- xspeed[i]++;
- break;
-
- case 1:
- xspeed[i]--;
- break;
-
- case 2:
- yspeed[i]++;
- break;
-
- case 3:
- yspeed[i]--;
- break;
- } /* end switch */
- } /* end for */
- for(j=0; j<(5-maxball)*600+2000; j++); /* waiting loop */
- if(maxball<4) /* if not at the maximum amount of balls then check for addition of a ball */
- if((int)(drand48()*(double)1000)==0) { /* less than one in a hundred chance */
- maxball++;
- x1[maxball]=(int)(drand48()*(double)(maxx-ballsize-1))+1; /* randomize starting position */
- x2[maxball]=x1[maxball];
- y1[maxball]=(int)(drand48()*(double)(maxy-ballsize-1))+1;
- y2[maxball]=y1[maxball];
- xspeed[maxball]=0;
- while(xspeed[maxball]==0) /* randomize speed, not allowing 0 speed in a direction */
- xspeed[maxball]=(int)(drand48()*(double)11)-6;
- yspeed[maxball]=0;
- while(yspeed[maxball]==0)
- yspeed[maxball]=(int)(drand48()*(double)11)-6;
- if(mode==NO9)
- ball9(x1[maxball],y1[maxball]);
- else
- ball(x1[maxball],y1[maxball]); /* plot the new ball */
- } /* end if */
- #ifdef MOUSE
- m1=11; /* check for the mouse moving */
- mousecl(&m1,&m2,&m3,&m4);
- #endif
- } /* end while */
- for(i=maxball; i>=0; i--)
- if(mode==NO9)
- ball9(x1[i],y1[i]);
- else
- ball(x1[i],y1[i]); /* erase balls from screen */
- if(kbhit()) { /* if it was the keyboard and not the mouse */
- j=getch(); /* flush the keyboard buffer */
- if(j==0) /* get extended code if necessary */
- j=getch()|(unsigned char)128; /* set high bit to indicate extended code */
- parse((unsigned char)j);
- } /* end if */
- } /* end bounce() */
- #endif
-
- /**********************************************************************
- * Function : outlinee
- * Purpose : draw an outlined box on the ega screen
- * Parameters :
- * x1,y1 - the x & y coor. of the upper left hand corner
- * x2,y2 - the x & y coor. of the lower right hand corner
- * Returns : none
- * Calls : lineega()
- * Called by : outline()
- **********************************************************************/
- void outlinee(x1,y1,x2,y2)
- int x1,y1,x2,y2;
- {
- int i,j; /* temporary counting variables */
-
- if(x2<x1)
- swapint(&x1,&x2);
- if(y2<y1)
- swapint(&y1,&y2);
- if(x2>=xdim) /* clip the box if it is outside the image */
- x2=xdim-1;
- if(x1>=xdim)
- x1=xdim-1;
- if(y2>=ydim)
- y2=ydim-1;
- if(y1>=ydim)
- y1=ydim-1;
- for(i=x1+xoff; i<=x2+xoff; i++) /* go through each pixel in the top line */
- *(store[y1+yoff]+i)=~*(store[y1+yoff]+i);
- for(i=x1+xoff; i<=x2+xoff; i++) /* go through each pixel in the bottom line */
- *(store[y2+yoff]+i)=~*(store[y2+yoff]+i);
- for(j=y1+1+yoff; j<y2+yoff; j++) { /* go thru and fix all the lines in between */
- *(store[j]+x1+xoff)=~*(store[j]+x1+xoff);
- *(store[j]+x2+xoff)=~*(store[j]+x2+xoff);
- } /* end for */
- for(i=y1; i<=y2; i++) { /* output the lines to the screen */
- egaline(xwhere+x1,ywhere+i,store[i+yoff],x2-x1+1,trans,x1+xoff);
- } /* end for */
- }
-
- /**********************************************************************
- * Function : outline
- * Purpose : call routines to put an outlined box on the screen
- * Parameters :
- * x1,y1 - the x & y coor. of the upper left hand corner
- * x2,y2 - the x & y coor. of the lower right hand corner
- * Returns : none
- * Calls : outline9(), outlinev(), outlinee()
- * Called by : mousefunc()
- **********************************************************************/
- void outline(x1,y1,x2,y2)
- int x1,y1,x2,y2;
- {
- switch(mode) { /* switch to call different outline routines depending on monitor type */
- case NO9:
- outline9(x1,y1,x2,y2);
- break;
-
- case VGA:
- outlinev(x1,y1,x2,y2);
- break;
-
- case EGA:
- default:
- outlinee(x1,y1,x2,y2); /* need offsets because ega has to modify the image data */
- break;
- } /* end switch */
- }
-
- #ifdef MOUSE
- /**********************************************************************
- * Function : mousefunc
- * Purpose : perform all of the mouse functions
- * Parameters : none
- * Returns : none
- * Calls : mousecl(), pixelcolor()
- * Called by : options()
- **********************************************************************/
- void mousefunc()
- {
- int off_x,off_y, /* the offset the mouse cursor is inside the color bar */
- firstx,firsty; /* the location of the first corner plotted in drawing a box */
-
- read_mouse(); /* get mouse position and button status */
- if(mx!=m3 || my!=m4) { /* the mouse has been moved so update the screen */
- if(mode==NO9) { /* update the mouse position for no9 screen */
- makecur9(mx,my);
- mx=m3;
- my=m4;
- makecur9(mx,my);
- } /* end if */
- else {
- mx=m3; /* update the old mouse positions */
- my=m4;
- } /* end else */
- } /* end if */
- 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 */
- if(my>=pal_yoff && my<=(pal_yoff+pal_height)) { /* if mouse cursor is in the color bar then move it */
- nopal(xoff,yoff); /* erase the color bar */
- if(mode==NO9) {
- makecur9(mx,my);
- off_x=mx-pal_xoff; /* set the offset in the color bar */
- off_y=my-pal_yoff;
- } /* end if */
- else {
- m1=2; /* erase the cursor */
- mousecl(&m1,&m2,&m3,&m4);
- off_x=mx-pal_xoff; /* set the offset in the color bar */
- off_y=my-pal_yoff;
- } /* end else */
- outline(pal_xoff,pal_yoff,pal_xoff+255,pal_yoff+pal_height); /* plot the outline of the color bar */
- do { /* keep moving the palette until the button is let up */
- read_mouse(); /* get mouse position and button status */
- if((m3+256-off_x)>maxx) /* if trying to move the color bar off the left side of the screen */
- m3=maxx-256+off_x;
- if((m3-off_x)<0) /* if trying to move off the right side of the screen */
- m3=off_x;
- if((m4+pal_height+1-off_y)>maxy) /* if trying to move off the bottom of the screen */
- m4=maxy-pal_height-1+off_y;
- if((m4-off_y)<0) /* if trying to move off the top of the screen */
- m4=off_y;
- if(m3!=mx || m4!=my) { /* if mouse is moved then move outline of color bar */
- outline(mx-off_x,my-off_y,mx-off_x+255,my-off_y+pal_height);
- mx=m3;
- my=m4;
- outline(mx-off_x,my-off_y,mx-off_x+255,my-off_y+pal_height);
- } /* end if */
- } while(rightbutton);
- pal_xoff=mx-off_x; /* find to upper left hand corner for the color bar */
- pal_yoff=my-off_y;
- outline(pal_xoff,pal_yoff,pal_xoff+255,pal_yoff+pal_height);
- draw_mouse();
- showpal(); /* put the color bar back on the screen */
- } /* end if */
- if(rightbutton) { /* rightbutton functions */
- erase_mouse();
- if(mx>9 && mx<(maxx-9)) { /* if not within the active region in the x dir. */
- if(my<10) /* if within 10 pixels of top then scroll up */
- scroll('u');
- if(my>(maxy-10)) /* if within 10 pixels of bottn then scroll down */
- scroll('d');
- } /* end if */
- if(mx>(maxx-10)) /* if within 10 pixels of edge of screen then do something */
- if(my<10 || my>(maxy-10)) /* if in one of the corners then page */
- if(my<10) /* page up */
- scroll('U');
- else /* page down */
- scroll('D');
- else /* scroll right */
- scroll('r');
- if(mx<10) /* if within 10 pixels of edge of the screen then do something */
- if(my<10 || my>(maxy-10)) /* if in one of the corners then home/end */
- if(my<10) /* Home */
- scroll('H');
- else /* End */
- scroll('E');
- else /* scroll left */
- scroll('l');
- draw_mouse();
- } /* end if */
- if(leftbutton) { /* leftbutton functions */
- if(show && (mx>=pal_xoff && mx<=(pal_xoff+255)) && (my>=pal_yoff && my<=(pal_yoff+pal_height))) {
- if((mx-pal_xoff)<128) { /* if on the left side then rotate that way */
- rotate('r');
- for(j=abs(mx-pal_xoff)*10; j>=0; j--);
- } /* end if */
- else { /* must be on right side so rotate that way */
- rotate('l');
- for(j=(255-abs(mx-pal_xoff))*10; j>=0; j--);
- } /* end else */
- } /* end if */
- else { /* draw an outlined box on the screen */
- erase_mouse();
- firstx=mx;
- firsty=my;
- outline(firstx,firsty,mx,my);
- do { /* keep changing the size of the outline until the button is let up */
- read_mouse(); /* get mouse position and button status */
- if(m3!=mx || m4!=my) { /* if mouse is moved then move outline of color bar */
- outline(firstx,firsty,mx,my); /* erase the outline */
- mx=m3;
- my=m4;
- outline(firstx,firsty,mx,my); /* re plot the outline */
- } /* end if */
- } while(leftbutton);
- outline(firstx,firsty,mx,my);
- if(firstx>mx) /* if square is defined backwards then flip ends */
- swapint(&firstx,&mx);
- if(firsty>my)
- swapint(&firsty,&my);
- if(mx>xdim-xoff) /* prevent the box from being outside the image */
- mx=xdim;
- if(my>ydim-yoff)
- my=ydim;
- if(firstx<xdim-xoff && firsty<ydim-yoff) { /* if the box is actually in the image on the screen then expand */
- grafmode(); /* clear the screen */
- if(expandit) { /* if preference is to expand the image */
- if(expand(firstx+xoff,firsty+yoff,mx+xoff,my+yoff)==1) /* expand chosen area to fill screen */
- waitq(); /* wait for keypress */
- } /* end if */
- else { /* if preference is to interpolate the image */
- if(interpolate(firstx+xoff,firsty+yoff,mx+xoff,my+yoff)==1) /* expand and smooth the chosen area to fill the screen */
- waitq(); /* wait for keypress */
- } /* end else */
- } /* end if */
- updatescrn(); /* go back to old display */
- } /* end else */
- } /* end if */
- } /* end mousefunc() */
- #endif
-
- /**********************************************************************
- * Function : options
- * Purpose : do all the fancy run-time things to the image
- * Parameters : none
- * Returns : none
- * Calls : parse(), mousecl(), mousefunc(), bounce()
- * Called by : main()
- **********************************************************************/
- void options()
- {
- palnum=0; /* start out at the first palette */
- #ifdef MOUSE
- if(mouse) /* if the mouse is already on then put it on the screen */
- draw_mouse();
- #endif
- c='!';
- if(kbhit()) {
- c=getch();
- if(c==0) /* check for extended character code */
- c=getch()|(unsigned char)128; /* set high bit to indicate extended code */
- } /* end if */
-
- while(c!='q' && !(c=='a' && animate) && c!='Q') { /* continue until 'q' */
- c='!';
- #ifdef QAK
- waitcount=0;
- #endif
- while (c=='!') {
- if(kbhit()) { /* get the next command */
- c=getch();
- if(c==0)
- c=getch()|(unsigned char)128; /* set high bit to indicate extended code */
- } /* end if */
- #ifdef MOUSE
- if(mouse) { /* if the mouse is active then perform some functions */
- mousefunc();
- #ifdef QAK
- waitcount=0; /* reset the counter to time out */
- #endif
- } /* end if */
- #endif
- #ifdef QAK
- if(waitcount>100000) { /* if timed out then bounce the ball */
- if(mode==VGA || mode==NO9)
- bounce();
- waitcount=0; /* reset the timed out counter */
- } /* end if */
- waitcount++;
- #endif
- } /* end while */
- if(c=='?') { /* if help is requisitioned */
- if(mouse && mode==NO9)
- makecur9(mx,my);
- textmode();
- printf("General Help Screen\n\n");
- printf("i\t\t - Show Information About Image\n");
- printf("a\t\t - Show Animation Again\n");
- printf("k\t\t - End Animation Mode\n");
- printf("o\t\t - Turn VGA Screen Off Or On\n");
- printf("m\t\t - Activate/Deactivate Mouse\n");
- printf(",\t\t - Magnify\Interpolate A Portion Of The Screen\n");
- printf("w\t\t - Switch Between Magnifying And Interpolating\n");
- printf("/\t\t - Slow Down Animation Speed\n");
- printf("*\t\t - Speed Up Animation Speed\n");
- printf("q\t\t - Quit Viewing Current Image\n");
- printf("Q\t\t - Exit Program\n");
- printf("?\t\t - Show This Help Sequence\n\n");
- printf("Hit <enter> For More Help, Or Any Key to Return to Graphics Mode");
- c='!';
- while (c=='!') {
- if(kbhit()) { /* get the next command */
- c=getch();
- if(c==0)
- c=getch()|(unsigned char)128; /* set high bit to indicate extended code */
- } /* end if */
- } /* end while */
- printf("\n");
- if(c==13){ /* if enter is hit for next help screen */
- textmode();
- printf("Palette Help Screen\n\n");
- printf("f\t\t - Rotate Palette Continuously Forward\n");
- printf("b\t\t - Rotate Palette Continuously Backward\n");
- printf("+\t\t - Speed Up Palette Rotation\n");
- printf("-\t\t - Slow Down Palette Rotation\n");
- printf("space bar\t - Stop Rotation Of Palette Or Animation\n");
- printf("e\t\t - Rotate Palette Once Forward\n");
- printf("v\t\t - Rotate Palette Once Backward\n");
- printf("r\t\t - Reset Palette To Original Settings\n");
- printf("c\t\t - Toggle Color Bar On Or Off The Screen\n");
- printf("l\t\t - Load In A New Palette From Disk\n");
- printf("n\t\t - Display Next Palette In Memory\n");
- printf("s\t\t - Store Palette On Disk\n");
- printf("u\t\t - Swap The Red, Green, And Blue Components Of Palettes\n");
- printf("t\t\t - Transpose Palette\n");
- printf("g\t\t - Invert Palette Bitwise\n");
- printf("h\t\t - Enter Fiddle Mode\n");
- printf("p\t\t - Move Color Bar On The Screen\n");
- printf("d\t\t - Make Current Palette The Default Values\n\n");
- printf("Hit <enter> For More Help, Or Any Key to Return to Graphics Mode");
- c='!';
- while (c=='!') {
- if(kbhit()) { /* get the next command */
- c=getch();
- if(c==0)
- c=getch()|(unsigned char)128; /* set high bit to indicate extended code */
- } /* end if */
- } /* end while */
- printf("\n");
- if(c==13) {
- textmode();
- printf("Image Help Screen\n\n");
- printf("left arrow\t - Move Image Left Ten Pixels\n");
- printf("up arrow\t - Move Image Up Ten Pixels\n");
- printf("down arrow\t - Move Image Down Ten Pixels\n");
- printf("right arrow\t - Move Image Right Ten Pixels\n");
- printf("page up\t - Page Image Up A Full Screen\n");
- printf("page down\t - Page Image Down A Full Screen\n");
- printf("home\t\t - Move To The Upper Left Hand Corner Of The Image\n");
- printf("end\t\t - Move To The Lower Right Hand Corner Of The Image\n");
- printf("x\t\t - Input X and Y Coor. For Upper Left Hand Corner\n");
- printf("Hit Any Key to Return To Graphics Mode");
- c='!';
- while (c=='!') {
- if(kbhit()) { /* get the next command */
- c=getch();
- if(c==0)
- c=getch()|(unsigned char)128; /* set high bit to indicate extended code */
- } /* end if */
- } /* end while */
- printf("\n");
- } /* end if */
- } /* end if */
- grafmode();
- updatescrn();
- } /* end if */
- parse(c);
- } /* end while */
- #ifdef MOUSE
- if(mouse) /* if the mouse is on then remove the cursor before leaving */
- erase_mouse();
- #endif
- } /* end options() */
-