/* ACIDTRIP.C - Main file for LSDino.  This coutines must of the main routines.
   This consists of drawing routines and palette routines.
*/


#define MAIN

#include "lsdino.h"



#define firstwin(x,y) x==(y-1) || (x==2 && y==0)
#define between(b,a,c) (((a>b) && (a<c)) || ((a>c) && (a<b)))  


/* This routine contains the acutal mathmatical formula for how to bring
   down pixels.  The name is based on the first formula, which kinda reminded
   me of Rock-Paper-Scissors.
*/
char winner(char *clr,int type,int x, int y)
{
	  char color;
	  char onem3,twom3,threem3;
	  char one,two,three;
	  char poss[3];

	  one=*clr;
	  two=*(clr+1);
	  three=*(clr+2);
	  switch(type){
		    case 0:
				poss[0]=one; poss[1]=two; poss[2]=three;
				onem3=one%3;
				twom3=two%3;
				threem3=three%3;
				if (firstwin(onem3,twom3))
					  poss[1]=one;
				if (firstwin(onem3,threem3))
					  poss[2]=one;
				if (firstwin(twom3,onem3))
					  poss[0]=two;
				if (firstwin(twom3,threem3))
					  poss[2]=two;
				if (firstwin(threem3,onem3))
					  poss[0]=three;
				if (firstwin(threem3,twom3))
					  poss[1]=three;
	  
				color=poss[rand()%3]; 
				if(!(rand()%3))
					  color+=rand()&3;
				return(color);
		    case 1:
				color=(3*one+2*two+3*three)/7;
				return(color);
		    case 2:
				color=(one+10*two+three)/12;
				if(!(rand()%3))
					  color+=rand()&7;
				return(color);
		    case 3:
				color=((one<<1)+(three<<1))>>2;
				if(!(rand()%3))
					  color+=rand()&7;

				return(color);
		    case 4:                    
				if(y>125)
					  color=(one*x + (320-x)*three)/320;
				else
					  color=(3*one+2*two+3*three)/7;
				return(color);
		    case 5:
				if(rand()%3)
					  color=(4*one+3*two+three)>>3;
				else
					  color=one;
				if(!(rand()%3))
					  color+=rand()&3;
				return(color);                        

	  }
	/* Control should never reach here */
	return(rand()%255);
}


/* All of this works by placing a random series of pixels at the top, and
   then bringing those down by some mathmatical formula.
*/
void newandtrippy(int type,int doxor)
{
	  int x,y;
	  char clrs[3];

	  /* Top row is our "seed" row */

	  if(!doxor)                
		    for(x=0;x<320;x++)
					  putpix(x,0,rand()%255);

	  /* Seed row is propageted by a chance that the colors live & die */
	  for(y=1;y<200;y++){
		    x=0;                
		    clrs[0]=getpix(319,y-1);
		    clrs[1]=getpix(0,y-1);
                    clrs[2]=getpix(1,y-1);
		    putpixtype(0,y,winner(clrs,type,x,y),doxor);

		    for(x=1;x<319;x++){
				clrs[0]=getpix(x-1,y-1);
				clrs[1]=getpix(x,y-1);
				clrs[2]=getpix(x+1,y-1);
				putpixtype(x,y,winner(clrs,type,x,y),doxor);
		    }

		    clrs[0]=getpix(318,y-1);
		    clrs[1]=getpix(319,y-1);
		    clrs[2]=getpix(319,y-1);
		    putpixtype(319,y,winner(clrs,type,x,y),doxor);


	  }
}


/* Blends the colors of the current screen together some */
void smooth_screen(void)
{
        int x,y,avg,avgcnt;
        char *scr;

        scr=malloc(64000);
        if(scr==NULL)
                notenoughmem("a copy of the screen (64000 bytes)");
        
        fmemcpy(scr,screenbuffer,64000);
        
        y=1;
        while(y<199){
                x=1;
                while(x<319){
                        avg=(scr[x+y*320]    +scr[x-1+y*320]    +scr[x+1+y*320]    +
                            scr[x+(y-1)*320]+scr[x-1+(y-1)*320]+scr[x+1+(y-1)*320]+
                            scr[x+(y+1)*320]+scr[x-1+(y+1)*320]+scr[x+1+(y+1)*320])/9;
/* if this differs to greatly it'll make the picture look like shit.  This
   is mainly here to stop from blending a group of pixels where the formula
   might loop from 0 to 255.  This way, we don't come out with an average of
   127 and then everywhere else have the color be 0 or 255, very differnt
   in the palette
*/
                        if(abs(scr[x+y*320]-avg)<20)
                                screenbuffer[x+y*320]=avg|0x01;
                        x++;
                }
                y++;
        }
        free(scr);
}


/* Various routines used to distort the current image in some way */
void distort(int type,int x,int y,int *color)
{
     int cy,xx,yy;
	
     switch(type&0xFFF0){
	    case DISTORTX: *color += loopster[x%sizeof(loopster)]; break;
	    case DISTORTY: *color += loopster[x%sizeof(loopster)] + loopster[y%sizeof(loopster)]; break;
	    case DISTORTZ: cy=(y/2)|1; *color+=abs(x%cy-(cy/2)); break;
	    case ICECREAM:xx=abs(160-x);
				yy=abs(100-y);
				cy= *color;
				cy +=  abs((((xx*xx+yy*yy)>>8) %30)-15)*2;
				*color = cy;
				break;
	    case SWIRL:   xx=abs(160-x);
				yy=abs(100-y);
				cy= *color;
				cy +=  (xx*xx+yy*yy)>>8;
				*color = cy;
				break;
				
		   
     }
}

/* Used for image #8 */
unsigned char clr(char color,int quad,int x,int y,int imagenum)
{
     int newcolor;

     if(quad==2 || quad==4 || quad==6 || quad==8)
	    newcolor=quad*CLRQUAD-color;
     else
	    newcolor=(quad-1)*CLRQUAD+color;

     return(newcolor);     
}

/* Main image drawing routine.  If you want an image to appear in LSDino,
give it a new number and put it in the case statement here.  Then update
your .INI file.
*/
void drawimage(int imagenum,int doxor)
{
	  int x,y,i=0;
	  int tx,ty,tx2;
	  int xx,yy,bb;
	  char cy,cx;
	  int color;


	  switch(imagenum){
		    case 0:
				for(x=0;x<80;x++){
					  for(y=0;y<100;y++){
						    i=i%100 + 1;
						    tx=abs(x-80); 
						    if(!tx) tx=1;
						    ty=abs(y-50);    
						    if(!ty) ty=1;  
						    /* Upper Left */
						    putpixtype(x,y,((x+1)*(y+1))/(tx*ty) + x +y+i,doxor);
						    putpixtype(159-x,99-y,((x+1)*(y+1))/(tx*ty) + x +y+i,doxor);
						    
						    /* Upper Right */
						    putpixtype(319-x,y,((x+1)*(y+1))/(tx*ty) + x +y+i,doxor);
						    putpixtype(x+160,99-y,((x+1)*(y+1))/(tx*ty) + x +y+i,doxor);

						    /* Lower Right */
						    putpixtype(319-x,199-y,((x+1)*(y+1))/(tx*ty) + x +y+i,doxor);
						    putpixtype(x+160,100+y,((x+1)*(y+1))/(tx*ty) + x +y+i,doxor);
						    
						    /* Lower Left */
						    putpixtype(x,199-y,((x+1)*(y+1))/(tx*ty) + x +y+i,doxor);
						    putpixtype(159-x,100+y,((x+1)*(y+1))/(tx*ty) + x +y+i,doxor);
						    
					  }
				}
				
				break;
		    case 1:  /* circle */
				for(x=0;x<320;x++){
					  for(y=0;y<200;y++){
						    xx=x-160;
						    yy=y-100;
						    color=(xx*xx+yy*yy)>>8;
						    putpixtype(x,y,color,doxor);
					  }
				}
				break;
		    case 2: 
				for(x=0;x<320;x++)
					  for(y=0;y<200;y++){
						    xx = abs(x-160);
						    yy = abs(100 - y)+1;
						    color=(xx%yy);
						    putpixtype(x,y,color,doxor);
					  }
				break;
		   case 3:
				bb=255;
				for(x=0;x<320;x++)
					  for(y=0;y<200;y++){                              
					     
					     color = (x|y)%(x+y+1);
					     putpixtype(x,y,color,doxor);
					  }
				break;
		    case 4:
				doxor|=DISTORTZ;
				for(x=0;x<320;x++)
					  for(y=0;y<200;y++){
						    color=sintable[(x+y)] +  sintable[y];
						    putpixtype(x,y,color,doxor);
					  }
				break;
		   case 5: /* grid-type thing going out from 0,0 */
				for(x=0;x<320;x++){
					  for(y=0;y<200;y++){
					     tx=x+200;
					     putpixtype(x,y,(tx%(y+1))&tx,doxor);
					  }
				}
				break;
		   case 6:  /* smoothed out boxes */
				xx=0;
				for(x=0;x<320;x++){
					  for(y=0;y<200;y++){
					     yy=y*16/10;
					     color=(xx^(x|yy))/2;

					     xx=getpix(x-1,y);
						    
					     putpixtype(x,y,color,doxor);
					  }
				}
				break;
		   case 7: /* distorted boxed */
				for(x=0;x<320;x++)
					  for(y=0;y<200;y++){                          
				     xx=abs(160-x);
				     yy=abs(100-y);
				     bb=(costable[abs(xx-yy)]*sintable[xx+yy]+costable[xx+yy]*sintable[abs(xx-yy)])>>8;
					 color=bb;
						 putpixtype(x,y,color,doxor|DISTORTZ);
				}
				break;
		 case 23:
			for(x=0;x<320;x++)
				for(y=0;y<200;y++){                             
					yy=abs((((y/100)&0x01)*-100)+(y%100));
					xx=abs(((((x/160)&0x01))*-160)+(x%160));
					putpixtype(x,y,xx+yy,doxor);
				}
			break;
		 case 31:
		   case 24:
		   case 8: /* straight lines, in an outward spiral. */
				if(imagenum==24)
					 doxor|=DISTORTX;
				for(x=0;x<160;x++){
					for(y=0;y<=((x*20/32));y++){                                   
					     if(x==0)
						    color = CLRQUAD;
				   else
						    color = ((y*32*CLRQUAD)/20) / (x);
					     
					     
				   if(imagenum==31){
	/* 1 */                            putpixtype(x+160,99-y,clr(color+1,8,x,y,imagenum),doxor);
	/* 4 */                            putpixtype(159-x,99-y,clr(color+1,5,x,y,imagenum),doxor);                                   
				   }else{
	/* 1 */                            putpixtype(x+160,99-y,clr(color+1,1,x,y,imagenum),doxor);
	/* 4 */                            putpixtype(159-x,99-y,clr(color+1,4,x,y,imagenum),doxor);                                   
				   }
     /* 5 */                       putpixtype(159-x,y+100,clr(color+1,5,x,y,imagenum),doxor);
     /* 8 */                       putpixtype(x+160,y+100,clr(color+1,8,x,y,imagenum),doxor);
				   xx=160-x;
				   yy=100-y;
				   if(yy==0)
					color=CLRQUAD;
				   else
					color= xx*CLRQUAD / ((yy*32/20));   
				   if(imagenum==31){
	/* 2 */                            putpixtype(319-x,y,clr(color,7,x,y,imagenum),doxor);
	/* 3 */                            putpixtype(x,y,clr(color,6,x,y,imagenum),doxor); 
				   }else{
	/* 2 */                            putpixtype(319-x,y,clr(color,2,x,y,imagenum),doxor);
	/* 3 */                            putpixtype(x,y,clr(color,3,x,y,imagenum),doxor); 
				   }
     /* 6 */                       putpixtype(x,199-y,clr(color,6,x,y,imagenum),doxor);                           
     /* 7 */                       putpixtype(319-x,199-y,clr(color,7,x,y,imagenum),doxor); 
					}
				}
				break;
		   case 25:
				for(x=0;x<320;x++){
					  for(y=0;y<200;y++){                                   
						    color=costable[abs(x-160)*10/22]+costable[abs(y-100)*10/22];
						    cy=y/2;
						    if(!cy)
							   cy=1;
						    color+=abs(x%cy-(cy/2));
						    putpixtype(x,y,color,doxor);
					  }
				}
				break;
		 case 17:
                        for(x=0;x<320;x++)
                                for(y=0;y<200;y++){
                                      xx=abs(x-160);
                                      yy=abs(y-100);
                                      bb=((xx*xx+yy*yy)>>8);
                                      color=(yy+loopster[(bb+xx)%sizeof(loopster)])&(xx+loopster[(bb+yy)%sizeof(loopster)]);
                                      putpixtype(x,y,color,doxor);
                                }
                        break;
                   case 28: /* * */
			tx=0;
				for(y=0;y<200;y++){
					for(x=0;x<320;x++){
                                                xx=x-160;
                                                yy=y-100;
                                                bb=((xx*xx+yy*yy)>>8);
                                                if(!bb)
                                                        bb=1;
                                                bb=(x%bb+y%bb+tx)*2/5;
                                                tx=bb&255;
                                                color=bb*2;
                                                putpixtype(x,y,color,doxor);
                                        }
                                }
				break;
		   case 26:
			  for(x=0;x<320;x++)
				    for(y=0;y<200;y++){
					     color=(x+y)&(x-y);
					     putpixtype(x,y,color,doxor);
				    }
			  break;
		   case 27:
				for(x=0;x<320;x++)
					  for(y=0;y<200;y++){
					     color=(y+loopster[x%sizeof(loopster)])&(x+loopster[y%sizeof(loopster)]);
					     putpixtype(x,y,color,doxor);
					  }
				break;
		   case 16:
				for(x=0;x<320;x++)
					  for(y=0;y<200;y++){
						    xx=abs(x-160);
						    yy=abs(y-100);
						    cy=xx*yy/4;
						    cx=xx&yy;
						    color=cy^cx;
						    putpixtype(x,y,color,doxor);
					  }
				break;
		   case 9:
				for(x=0;x<320;x++){
					  for(y=0;y<200;y++){
						    tx=x-160; tx2=x-120;
						    yy=y-100;      
					color=((tx*tx-yy*yy)>>8);
						    putpixtype(x,y,color,doxor|DISTORTX);
					  }
				}
				break;
		   case 15:
			  drawimage(8,NORMAL|(doxor&0xFF0));
			  drawimage(2,OR|(doxor&0xFF0));
			  break;
		   case 10: /* kick ass again */
			  drawimage(8,NORMAL|(doxor&0xFF0));
			  drawimage(1,OR|(doxor&0xFF0));
			  break;
		   case 13: /* pretty awesome */
			  drawimage(31,NORMAL|(doxor&0xFF0));
			  drawimage(17,OR|(doxor&0xFF0));
			  break;
		   case 12: /* wonderful */
			  drawimage(0,NORMAL|(doxor&0xFF0));
			  drawimage(1,OR|(doxor&0xFF0));
			  break;
		   case 14: /* truly awesome! */
			  drawimage(8,NORMAL|(doxor&0xFF0));
			  drawimage(0,OR|(doxor&0xFF0));
			  break;
		   case 11: /* kick ass */
			  drawimage(0,NORMAL|(doxor&0xFF0));
			  drawimage(17,OR|(doxor&0xFF0));
			  break;                
		   case 18: /* kick ass again - SWIRL */
			  drawimage(8,SWIRL);
                          break;
		   case 19: /* pretty awesome */
			  drawimage(1,NORMAL|(doxor&0xFF0));
			  drawimage(17,AVG|(doxor&0xFF0));
			  break;
		   case 20:
			  drawimage(5,NORMAL|(doxor&0xFF0));
			  drawimage(1,AVG|(doxor&0xFF0));
			  break;
		   case 21:
			  drawimage(8,NORMAL|(doxor&0xFF0));
			  drawimage(16,AVG|(doxor&0xFF0));
			  break;
		   case 22:
			  avg_first=2;
			  drawimage(0,NORMAL|(doxor&0xFF0));
			  drawimage(6,AVG|(doxor&0xFF0));
			  avg_first=1;
			  break;
		case 32:
		    avg_first=2;
			  drawimage(31,NORMAL|(doxor&0xFF0));
			  drawimage(1,AVG|(doxor&0xFF0));
		    break;
		case 30:
			  drawimage(0,DISTORTY|(doxor&0x0F));
		    break;              
		    case 34: newandtrippy(0,doxor); break;
		    case 35: newandtrippy(1,doxor); break;
		    case 36: newandtrippy(2,doxor); break;
		    case 37: newandtrippy(3,doxor); break;
		    case 38: newandtrippy(4,doxor); break;
		    case 39: newandtrippy(5,doxor); break;
		    case 40: drawimage(8,ICECREAM|(doxor&0x0F)); break;
		    case 41: drawimage(10,SWIRL|(doxor&0x0F)); break;
		    case 42: drawimage(23,ICECREAM|(doxor&0x0F)); break;
		    case 43: drawimage(34,SWIRL|(doxor&0x0F)); break;
		    case 44: drawimage(35,SWIRL|(doxor&0x0F)); break;
		    case 45: drawimage(39,SWIRL|(doxor&0x0F)); break;
		    case 46:
				  for(x=0;x<320;x++){
					  for(y=0;y<200;y++)
						    putpixtype(x,y,0,doxor);
					  
				  }
				  break;
	  }
}


/* this routine was originally for palette rotation, but has grown to be
 the main routine which handles everything that isn't drawing a screen.
 Putting a new number in here w/ code will let you implement a new palette
 routine
  */
void update_fade(int method)
{
     int updatewhich;
     int i,j00,j002,j003;
     int start[MAXCYCLE],color[MAXCYCLE],direction[MAXCYCLE],meupdatewho;
     unsigned char originalpal[256][3],newcolor;
     int SIZE[MAXCYCLE],numcycle,cycles;

     if(!method){
		    /* This code implements the following weighting scale for the
			 different effects.

				Standard Palette Rotation      4/12
				Acid Effect                    3/12
				Compression                    1/12
				Distortion                     1/12
				Bouncing Box                   1/12
				Color Change                   1/12
				Color Bars                     1/12
		    */

		    method=rand()%2;
		    if(method)
				method=(rand()%8)+2;
     }
     if(nopalchange && (method==7 || method==8))
	    method=1;
     if(forcerotate)
	    method=forcerotate;

     switch(method){
	    case 0:
	    case 1:
		   for(i=0;i<rand()%128+128 && !kbhit();i++){
                          delay(delaytime);
                          rotate_dac();
			  update_dac();
		   }
		   return;
	    case 2:
	    case 3:
	    case 4:
	    case 5:
		   realtime_acid(method-1);
		   return;          
	    case 9:
            case 10:                
		   realtime_acid(method-2);
		   return;
	    case 6:
		   dobox();
		   return;
	    case 7:
		   do{
			  updatewhich=rand()%3;
			  pal[updatewhich]=rand()%NUMPAL;
		   }while(pal[0]==pal[1] || pal[1]==pal[2] || pal[2]==pal[0]);
		   set_fade(palettes[pal[0]],palettes[pal[1]],palettes[pal[2]]);
                   fadeto_dac();
		   return;
	    case 8:
		   numcycle=rand()%MAXCYCLE;
                   memcpy(fadeto,dacbox,sizeof(dacbox));
                   memcpy(originalpal,dacbox,sizeof(dacbox));
                   for(cycles=0;cycles<=numcycle;cycles++){
			  SIZE[cycles]=rand()%60+61;
			  color[cycles]=rand()%NUMPAL;
			  start[cycles]=rand()%128;
                          direction[cycles]=(rand()&1)?2:-1;
		   }
                   for(i=0;i<256 && !kbhit();i++){
			  memcpy(dacbox,originalpal,sizeof(dacbox));
			  for(cycles=0;cycles<=numcycle;cycles++){               
				 if(cycles==0){  /* We want to rotate the palette once */
					rotate_dac();
                                        memcpy(originalpal,dacbox,sizeof(dacbox));
				 }
				 for(j00=0;j00<SIZE[cycles];j00++){
					meupdatewho=start[cycles]+j00;
					while(meupdatewho>255)
					     meupdatewho-=256;
					while(meupdatewho<0)
					     meupdatewho+=256;
					if(meupdatewho){ /* Don't fuck w/ color 0 ! */
					     for(j002=0;j002<3;j002++){
                                                    j003=abs(SIZE2-j00);
                                                    if(i==0){
                                                            newcolor=(fadeto[meupdatewho][j002]*j003 + ((palettes[color[cycles]][j002]*(SIZE2-j003))))/SIZE2;
                                                            fadeto[meupdatewho][j002]=newcolor;
                                                    }else{
                                                            newcolor=(dacbox[meupdatewho][j002]*j003 + ((palettes[color[cycles]][j002]*(SIZE2-j003))))/SIZE2;
                                                            dacbox[meupdatewho][j002]=newcolor;
                                                    }
                                             }          
                                        }    
                                 }
                                 start[cycles]+=direction[cycles];
                                 if(!(rand()%90))
                                        if(direction[cycles]>0)
                                             direction[cycles] = -1;
                                        else
                                             direction[cycles] = 2;

                          }
			  if(i==0)
				 fadeto_dac();
			  else
				 update_dac();
                          delay(delaytime);                   
		   }
		   update_fade(7);
		   return;
     }
}

/* This function will draw a random image based upon the predefined base
images...
*/
void newrandom(int maximag)
{
        int i=1;
        int distort;

        drawimage(okrandimag[rand()%sizeof(okrandimag)],0);
        while(i<maximag){
                if(!(rand()%3))
                        distort=DISTORTX<<(rand()%5);
                else
                        distort=0;
                drawimage(okrandimag[rand()%sizeof(okrandimag)],((rand()%6)+1)|distort);
                i++;
        }
}

/* Creates a brand new random palette, with no duplicate colors */
/* Does not update the palette. */
void random_palette(void)
{
	  int i;

	  if(nopalchange)
		    return;
	  do{
		    for(i=0;i<3;i++)
				pal[i]=rand()%NUMPAL;
	  }while(pal[0]==pal[1] || pal[1]==pal[2] || pal[2]==pal[0]);
}


void main(int argc,char *argv[])
{
        int i=0,times,ragc,lp,randimag=0;
        unsigned int t;
        int done;
        char ch,clr[81];

        read_ini();
         
        t=time(NULL); /* This will be our random seed, and will be overwritten
					  if the user specified the -seed@ option */

	for(i=1;i<argc;i++){
		if(argv[i][0]=='-'){
			if(strcmp(argv[i],"-help")==0){
				printf("LSDino Help: \n\n");
				printf("LSDino can be ran with or without options. The options allow you\n"); 
				printf("to create custom screens by blending existing screens.  All options\n");  
				printf("are specified by a number and a prefix, except for the first, which\n");
				printf("is just a number by its self.  The prefixes available are: \n\n");
				printf("	A - Average (First image is two times as strong)\n");
				printf("	B - Blend from first image on top to second image on bottom\n");
				printf("	D - Double Average, 1st image counted as image value & inverse\n");
				printf("		image value, then averaged with the third\n");
					  printf("        G - averaGe (Equal strengths)\n");
				printf("	H - distort Horizontal - Distorts based upon the X axis\n");
				printf("	N - aNd - Performs a bit-wise AND between images\n");
				printf("	O - Or - Performs a bit-wise OR between images\n");
                                printf("        P - Use a predefined screen from the image array (0-%d)\n",numimages-1); 
				printf("	V - Performs a vertical distortion\n");
				printf("	X - Performs an XOR between images\n");
				printf("	Z - Performs a double-distortion, horizontal & vertical\n");
					  printf("        I - Ice Cream Distortion\n");
					  printf("        S - Swirl Distortion\n");
					  printf(" -seed@   - Set random seed to number after @ sign (no space)\n");
					  printf(" -delay@  - Set the delay value to number after @ (no space)\n");
					  printf(" -c###    - Set the color palette, # is from 0-C\n");
					  printf(" -rgb     - Be prompted to enter RGB values.\n");
					  printf(" -fx@#    - Force the palette / graphic effect to #\n");
                                          printf(" -rand@#  - Run lsdino in random image form - this can give both\n");
                                          printf("          - good and bad screens, but they're pretty neat.\n");
					  printf("\n\n");
				exit(0);
			}
				if(strnicmp(argv[i],"-seed@",6)==0)
                                        t=atoi(argv[i]+6);            

                                if(strnicmp(argv[i],"-rand@",6)==0)
                                        randimag=atoi(argv[i]+6);            
				if(strnicmp(argv[i],"-delay@",7)==0)
					  delaytime=atoi(argv[i]+7);
				if(strnicmp(argv[i],"-fx@",4)==0)
					  forcerotate=atoi(argv[i]+4);
				if(strnicmp(argv[i],"-c",2)==0){
					  nopalchange=1;                                                        
					  for(lp=0;lp<3;lp++)
						    if(toupper(argv[i][2+lp])>='A')
								pal[lp]=toupper(argv[i][2+lp]-'A'+10);
						    else
								pal[lp]=argv[i][2+lp]-'0';
				}
				if(strnicmp(argv[i],"-rgb",4)==0){
					  nopalchange=1;
					  printf("Please enter the values for the RGB colors you want to see.\n\n\n");
					  for(lp=0;lp<3;lp++){                                        
						    printf("\nEnter red value for color #%d: ",lp+1);
						    gets(clr);
						    palettes[lp][0]=atoi(clr);                                        
						    printf("\nEnter green value for color #%d: ",lp+1);
						    gets(clr);
						    palettes[lp][1]=atoi(clr);
						    printf("\nEnter blue value for color #%d: ",lp+1);
						    gets(clr);
						    palettes[lp][2]=atoi(clr);
						    pal[lp]=lp;
					  }
				}

		}
	}
	  srand(t); /* Set our random seed, or set seed if it was overwridden by
				the user */
	  vgamode(); /* Switch to 320x200x256 */

	  random_palette(); /* Establishes our random palette */

#if 0 /* I think this code is useless... */
	  update_dac(); /* Make the dac we have set (dacbox) and video's dac
				be the same */
#endif

	  /* Let's go to a straight black screen */
	set_dac(palettes[PALBLACK],palettes[PALBLACK],palettes[PALBLACK]);
	update_dac();


	  /* All this code processes the screen options the user selected, if
		    he/she selected any   Does not process random seed info */
	ragc=argc;
	  if(argc>1){
		   for(i=1;i<argc;i++){
			  if(isdigit(argv[i][0]))                                 
				 drawimage(atoi(argv[i]),0);
			else
				 switch(argv[i][0]){                    
				case '-':
				   ragc--;
				   break;
					case 'A':
					     avg_first=2;
					     avg_second=1;               
					     drawimage(atoi(argv[i]+1),AVG);
					     break;
					case 'G':
					     avg_first=1;
					     avg_second=1;
					     drawimage(atoi(argv[i]+1),AVG);
					     break;
					case 'X':
					     drawimage(atoi(argv[i]+1),XOR);
					     break;
					case 'O':
					     drawimage(atoi(argv[i]+1),OR);
					     break;
				case 'P':
					     drawimage(okimgs[atoi(argv[i]+1)],0);
				   break;
					case 'N':
					     drawimage(atoi(argv[i]+1),AND);
					     break;
					case 'B':
					     drawimage(atoi(argv[i]+1),BLEND);
					     break;
					case 'H':
					     drawimage(atoi(argv[i]+1),DISTORTX);
					     break;
					case 'Z':
					     drawimage(atoi(argv[i]+1),DISTORTZ);
					     break;
					case 'V':
					     drawimage(atoi(argv[i]+1),DISTORTY);
					     break;                              
				case 'D':
				   drawimage(atoi(argv[i]+1),DBLAVG);
				   break;
					case 'I':
					     drawimage(atoi(argv[i]+1),ICECREAM);
					     break;
					case 'S':
					     drawimage(atoi(argv[i]+1),SWIRL);
					     break;
				 }
		   }
	  }
          if(ragc==1)  /* if our options weren't a -, and we didn't display anything */
                 if(randimag)
                        newrandom(randimag);
                 else
                        drawimage(okimgs[rand() % numimages],0);
		    


	  /* Number of times we've looped through current image */
	  times=0;
	  
          paltype=(palforce?(palforce-1):rand()&1);
	  /* Jump to our previously established random palette and then fade
	  to it */
          set_fade(palettes[pal[0]],palettes[pal[1]],palettes[pal[2]]);
          fadeto_dac();

	  done=0;
	  do{
		    if(kbhit()){
				ch=getch();
				if(ch=='+')
					  dropped_acid=1;
				else if(strchr(palrefa,toupper(ch))!=NULL){
					  pal[0]=strchr(palrefa,toupper(ch))-palrefa;
					  set_fade(palettes[pal[0]],palettes[pal[1]],palettes[pal[2]]);
					  fadeto_dac();
				}else if(strchr(palrefb,toupper(ch))!=NULL){
					  pal[1]=strchr(palrefb,toupper(ch))-palrefb;
					  set_fade(palettes[pal[0]],palettes[pal[1]],palettes[pal[2]]);
					  fadeto_dac();
				}else if(strchr(palrefc,toupper(ch))!=NULL){
					  pal[2]=strchr(palrefc,toupper(ch))-palrefc;
					  set_fade(palettes[pal[0]],palettes[pal[1]],palettes[pal[2]]);
					  fadeto_dac();
                                }else if(ch=='\\'){
                                        smooth_screen();
                                }else
                                        done=1;
		    }else
				update_fade(0);
		    times++;
		    
		    if(((times>=7+rand()%3) || dropped_acid) && !done){
				dropped_acid=0;
				switch(rand()&1) {
					  case 0:
						    set_fade(palettes[PALWHITE],palettes[PALWHITE],palettes[PALWHITE]);
						    break;
					  case 1:                         
						    set_fade(palettes[PALBLACK],palettes[PALBLACK],palettes[PALBLACK]);
						    break;
				}

				/* Draws a new image, if the user didn't press a key*/
                                if(!kbhit()){
					  fadeto_dac();
                                          random_palette();

                                          paltype=(palforce?(palforce-1):rand()%2);
                                          if(randimag)
                                                newrandom(randimag);
                                          else
                                                drawimage(okimgs[rand() % numimages],0);

                                          if(rand()&1)
                                                smooth_screen();
                                          if(!(rand()&0x03)){
                                                smooth_screen();
                                          if(!(rand()&0x7))
                                                smooth_screen();
                                }                                                        
                                set_fade(palettes[pal[0]],palettes[pal[1]],palettes[pal[2]]);
                                fadeto_dac();
			}
				times=0;
		    }
	  }while(!done);
#ifdef __SC__
	  txtmode();
#endif
          end();
	  printf("Random Seed value: %d\r\n\r\n",t);
}

