/*
	kvis.c

	from imvis.c 5-7-91 by R. Ambroziak

	kv1.bat = cl /AL kvis.c vimage3 graphlib

*/
#include <stdio.h>
#include <string.h>
#include <direct.h>
#include <math.h>
#include "font.h"

#define MAX_BUFF 32768
#define MENU_I 4
#define MENUXC 550
#define MENU_C 3
#define MENU_S 3
#define NUM_IMAGE 20
#define PAUSE printf("HIT ANY KEY TO CONTINUE.\n");getch()
#define NUM_DP 100
#define STR_LEN 100
#define S_SIZE 40

struct file_id
{
	char name[S_SIZE];
	long size;
	unsigned date,time;
};
extern struct file_id GF_File[];
struct board
{
	int row,col,color;
}B_Id;
int NumPath=1;
char Path[NUM_DP][STR_LEN];
int PathCheck=0;
char *LastFile;
int FontSize=2;

union intflo
{
	long lnum;
	float fnum;
};
char *menu_s[MENU_S]=
{
	"display image",
	"cycle images",
	"exit set"
};
char String[100];
int Num_Active_Image=1;
char *menu_l[NUM_IMAGE+1]=
{
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              "
};
char *menu_i[MENU_I]=
	{"zoom",
	"change color",
	"pixel info",
	"exit image"
};
char *menu_c[MENU_C]=
	{"stretch RGB","save new table","exit color"};
char VideoType='X';
int Black=0,White=191,Center=128,Num_Color=256;
int D_Grey=46,L_Grey=191,M_Grey=128;
int ScreenXs=640,ScreenYs=480;
struct   Color
{
	unsigned char  r, g, b;
};
struct Color Blk={  0,  0,  0};
struct Color D_G={ 46, 46, 46};
struct Color M_G={127,127,127};
struct Color L_G={191,191,191};
struct Color Wht={255,255,255};
unsigned char ActiveLut;
struct image_header
{
	int row,col;
	int sample;
	int record_bytes,file_records;
	int record_col_header;
	int row_col_header;
	int header_bytes;
	int imbedded_header;
	int sample_bits;
	char infile[100],image[100],Lut[100],pal_type,label[100];
	int vga_color[256];
	struct Color lut[256],lutm[256],lutc[256];
}Hdr[NUM_IMAGE];
int Img=0,Sample=1,Xc=0,Yc=0,Speed=16,Row,Col,ZoomSample=1;

unsigned char Mbuff[MAX_BUFF],Ibuff[MAX_BUFF],Buffer[4096];
unsigned char MaxHues[256][3]=
{
255,  0,  0,255, 32,  0,255, 42,  0,255, 53,  0,255, 60,  0,255, 68,  0,
255, 73,  0,255, 80,  0,255, 84,  0,255, 90,  0,255, 94,  0,255,100,  0,
255,103,  0,255,108,  0,255,112,  0,255,116,  0,255,121,  0,255,124,  0,
255,128,  0,255,132,  0,255,135,  0,255,139,  0,255,143,  0,255,146,  0,
255,150,  0,255,154,  0,255,157,  0,255,161,  0,255,164,  0,255,168,  0,
255,172,  0,255,176,  0,255,179,  0,255,183,  0,255,186,  0,255,190,  0,
255,194,  0,255,198,  0,255,202,  0,255,206,  0,255,210,  0,255,214,  0,
255,218,  0,255,222,  0,255,227,  0,255,231,  0,255,236,  0,255,241,  0,
255,245,  0,255,250,  0,254,255,  0,249,255,  0,244,255,  0,240,255,  0,
234,255,  0,229,255,  0,224,255,  0,220,255,  0,214,255,  0,209,255,  0,
204,255,  0,199,255,  0,194,255,  0,190,255,  0,184,255,  0,179,255,  0,
174,255,  0,169,255,  0,164,255,  0,158,255,  0,152,255,  0,147,255,  0,
141,255,  0,135,255,  0,130,255,  0,123,255,  0,116,255,  0,109,255,  0,
102,255,  0, 94,255,  0, 87,255,  0, 78,255,  0, 68,255,  0, 58,255,  0,
 42,255,  0, 23,255,  0,  0,255, 36,  0,255, 58,  0,255, 73,  0,255, 87,
  0,255,101,  0,255,113,  0,255,125,  0,255,135,  0,255,146,  0,255,156,
  0,255,166,  0,255,176,  0,255,186,  0,255,196,  0,255,204,  0,255,214,
  0,255,224,  0,255,233,  0,255,243,  0,255,252,  0,248,255,  0,239,255,
  0,230,255,  0,222,255,  0,214,255,  0,207,255,  0,200,255,  0,194,255,
  0,187,255,  0,181,255,  0,174,255,  0,169,255,  0,163,255,  0,157,255,
  0,152,255,  0,146,255,  0,141,255,  0,136,255,  0,131,255,  0,126,255,
  0,121,255,  0,116,255,  0,111,255,  0,106,255,  0,101,255,  0, 96,255,
  0, 92,255,  0, 86,255,  0, 81,255,  0, 77,255,  0, 71,255,  0, 66,255,
  0, 60,255,  0, 53,255,  0, 48,255,  0, 39,255,  0, 32,255,  0, 23,255,
  0,  0,255, 16,  0,255, 23,  0,255, 28,  0,255, 32,  0,255, 36,  0,255,
 39,  0,255, 42,  0,255, 45,  0,255, 48,  0,255, 50,  0,255, 53,  0,255,
 58,  0,255, 60,  0,255, 62,  0,255, 64,  0,255, 66,  0,255, 68,  0,255,
 70,  0,255, 73,  0,255, 75,  0,255, 77,  0,255, 78,  0,255, 81,  0,255,
 83,  0,255, 84,  0,255, 87,  0,255, 89,  0,255, 92,  0,255, 93,  0,255,
 94,  0,255, 97,  0,255, 98,  0,255,101,  0,255,103,  0,255,105,  0,255,
107,  0,255,109,  0,255,111,  0,255,113,  0,255,115,  0,255,117,  0,255,
119,  0,255,122,  0,255,124,  0,255,126,  0,255,129,  0,255,131,  0,255,
134,  0,255,135,  0,255,138,  0,255,140,  0,255,143,  0,255,145,  0,255,
148,  0,255,151,  0,255,154,  0,255,156,  0,255,160,  0,255,163,  0,255,
166,  0,255,169,  0,255,173,  0,255,176,  0,255,179,  0,255,183,  0,255,
188,  0,255,192,  0,255,196,  0,255,200,  0,255,204,  0,255,209,  0,255,
214,  0,255,220,  0,255,225,  0,255,231,  0,255,237,  0,255,244,  0,255,
250,  0,255,255,  0,252,255,  0,245,255,  0,238,255,  0,231,255,  0,224,
255,  0,217,255,  0,210,255,  0,203,255,  0,196,255,  0,190,255,  0,183,
255,  0,176,255,  0,170,255,  0,163,255,  0,156,255,  0,151,255,  0,144,
255,  0,137,255,  0,131,255,  0,125,255,  0,118,255,  0,112,255,  0,105,
255,  0, 98,255,  0, 90,255,  0, 83,255,  0, 77,255,  0, 68,255,  0, 60,
255,  0, 50,255,  0, 42,255,  0, 28,255,  0, 23
};
int Scan=0;
char *SubType;

unsigned char getpt();
int set_lut();
char fsplit(char *,char *,char *,char *);
FILE *open_to_read_binary(char *);
FILE *open_to_read_text(char *);
FILE *open_to_write_text(char *);
FILE *open_to_write_binary(char *);

main(argc,argv)

int argc;
char *argv[];

{
	int i,j,k;
	char string[100],ans;
	int numfile;
	FILE *fp;
	char *pathbuf;
	int n=100;
	int num;

	if(argc>1)
	{
		for(i=0;i<argc;i++)
		{
			if(strcmpi(argv[i],"scan")==0)
				Scan=1;
			if(strcmpi(argv[i],"path")==0)
				PathCheck=1;
			j=i+1;
			if(argv[i][1]==':')
				add_disk_path(argv[i]);
			if(strcmpi(argv[i],"path")==0)
				add_disk_path(argv[i+1]);
			if(argv[j][0]=='/'&&(argv[j][1]=='X'||argv[j][1]=='x'))
				VideoType='X';
			if(argv[j][0]=='/'&&(argv[j][1]=='Y'||argv[j][1]=='y'))
				VideoType='Y';
			if(argv[j][0]=='/'&&(argv[j][1]=='E'||argv[j][1]=='e'))
				VideoType='E';
			if(argv[j][0]=='/'&&(argv[j][1]=='V'||argv[j][1]=='v'))
				VideoType='V';
			if(argv[j][0]=='/'&&(argv[j][1]=='S'||argv[j][1]=='s'))
				VideoType='S';
		}
	}
	getcwd(pathbuf,99);
	strcpy(Path[NumPath],pathbuf);
	strcat(Path[NumPath++],"\\");
	video_on();
	SetVideoMode(0,&B_Id);
/* use SubPaths with type of SubType for sub images */
									/* move all Path up 1 */
	for(i=NumPath;i>0;i--)
		strcpy(Path[i],Path[i-1]);
	NumPath+=1;
									/* add '?mp\' to a new set of Paths */
	for(i=2;i<NumPath;i++)
		sprintf(Path[NumPath+i-2],"%s%s\\",Path[i],SubType+1);
	NumPath+=NumPath-2;
	if(PathCheck==1)
	{
		for(i=0;i<NumPath;i++)
			printf("%3d  '%s'\n",i,Path[i]);
		printf("\nHit any key to continue.\n\n");
		getch();
	}
	Hdr[Img].sample_bits=Hdr[Img].record_bytes=0;
	Hdr[Img].file_records=0;
	Hdr[Img].pal_type=0;
	Hdr[Img].row_col_header=0;
	if(Scan==1)
	{
		num=load_names("*.dat");
		for(i=0;i<num;i++)
		{
			strcpy(Hdr[Img].infile,GF_File[i].name);
			fp=open_to_read_binary(Hdr[Img].infile);
			if(!fp)
			{
				printf("Could not open '%s'\n\n",Hdr[Img].infile);
				exit(0);
			}
			strcpy(Hdr[Img].image,Hdr[Img].infile);
			fread((char *)&Hdr[Img].row,sizeof(int),1,fp);
			fread((char *)&Hdr[Img].col,sizeof(int),1,fp);
			fclose(fp);
			Hdr[Img].header_bytes=5120;
			video_on();
			load_image(Img,1);			
			SetVideoMode(0);
			fclose(fp);
		}
		exit(0);
	}
	while(get_file_name("*.dat",Hdr[Img].infile)>=0)
	{
		fp=open_to_read_binary(Hdr[Img].infile);
		if(!fp)
		{
			printf("Could not open '%s'\n\n",Hdr[Img].infile);
			exit(0);
		}
		strcpy(Hdr[Img].image,Hdr[Img].infile);
		fread((char *)&Hdr[Img].row,sizeof(int),1,fp);
		fread((char *)&Hdr[Img].col,sizeof(int),1,fp);
		fclose(fp);
		Hdr[Img].header_bytes=5120;
		process_image(Img);
		SetVideoMode(0);
	}
}


/**************************************************************************
**
**
**
************************************************************************* */

int open_image(fp,filenum)

FILE *fp;
int filenum;

{
	fp=open_to_read_binary(Hdr[filenum].image);
	if(!fp)
		return(-1);
	return(1);
}

/**************************************************************************
**
**
**
************************************************************************* */

char fsplit(instring,path,name,type)

char *instring,*path,*name,*type;

{
	int i,j,k;
	int dot=-1,last_slash=-1,len=strlen(instring),first_slash=-1;
	int num=0,colon=-1;
	int disk=0;
	char string[STR_LEN];

	strcpy(string,instring);
	path[0]='\0';
	name[0]='\0';
	type[0]='\0';

	for(i=0;i<len;i++)
	{
		if(string[i]==':')
			colon=i;
		else if(string[i]=='\\')
		{
			last_slash=i;
			if(first_slash<0)
				first_slash=i;
		}	
		else if(string[i]=='.')
			dot=i;
	}
	if(dot<0&&first_slash>=0&&last_slash<len-1)  /* d:test */
	{
		string[len]='\\';
		last_slash=len;
		len+=1;
		string[len]='\0';
	}
	if(dot<0&&first_slash<0&&len>colon-1)
	{
		string[len]='.';
		dot=len;
		len+=1;
		string[len]='\0';
	}
	if(colon>0)
		disk=string[0];
	if(first_slash>=0)
	{
		for(i=first_slash;i<=last_slash;i++)
			path[i-first_slash]=string[i];
		path[last_slash-first_slash+1]='\0';
	}
	if(last_slash>0&&last_slash<len-1&&dot>0)
	{
		for(i=last_slash+1;i<dot;i++)
			name[i-last_slash-1]=string[i];
		name[dot-last_slash-1]='\0';
	}
	if(colon>0&&last_slash<0&&dot>0)	/* d:test.img */
	{
		for(i=colon+1;i<dot;i++)
			name[i-colon-1]=string[i];
		name[dot-colon]='\0';
	}
	if(colon<0&&last_slash<0&&dot>0)	/* test.img */
	{
		for(i=0;i<dot;i++)
			name[i]=string[i];
		name[dot]='\0';
	}
	if(dot>0&&dot<len-1)
	{
		for(i=dot+1;i<len;i++)
			type[i-dot-1]=string[i];
		type[len-dot-1]='\0';
		if(strlen(type)>3)
			type[3]='\0';
	}
	return(disk);
}




/**************************************************************************
**
**
**
************************************************************************* */

int display_set_image(num)

int num;

{
	do
	{
		num=do_menu_buff(menu_l,Num_Active_Image+1,
			MENUXC,25,num,D_Grey,L_Grey,White,Font);
		Img=num;
		if(num<Num_Active_Image)
			process_image(num);
	}while(num<Num_Active_Image);

	return(num);
}


/**************************************************************************
**
**
**
************************************************************************* */

int split(string,path,name,type)

char *string,*path,*name,*type;

{
	int i,j,k;
	int dot=-1,last_slash=-1,len=strlen(string),num=0;

	for(i=0;i<len;i++)
	{
		if(string[i]=='.')
			dot=i;
		if(string[i]=='\\')
			last_slash=i;
	}
	last_slash+=1;
	if(dot==-1)
		dot=len-1;
	if(last_slash>0)
	{
		for(i=0;i<last_slash;i++)
			path[i]=string[i];
	}
	path[last_slash]='\0';
	for(i=last_slash;i<dot;i++)
		name[i-last_slash]=string[i];
	name[dot-last_slash]='\0';
	dot+=1;
	for(i=dot;i<len;i++)
		type[i-dot]=string[i];
	type[len-dot]='\0';
	if(strlen(name)>0)
		num+=1;
	if(strlen(type)>0)
		num+=1;

	return(num);
}


/**************************************************************************
**
**
**
************************************************************************* */

int process_image(filenum)

int filenum;

{
	int num=0;
	int ix=ScreenXs/2,iy=ScreenYs/2,speed=16;

	load_image(filenum,0);	
	do
	{
		num=do_menu_buff(menu_i,MENU_I,MENUXC,25,num,D_Grey,L_Grey,White,Font);
		if(num==0)
		{
			load_image(filenum,0);			
		}
		if(num==1)
		{
			Img=filenum;
			if(change_color()==0)
			{
				ZoomSample=1;
				return(0);
			}
		}
		if(num==2)
		{
			pixel_locate(&ix,&iy,&speed,filenum);
		}
	}while(num<MENU_I-1);
	ZoomSample=1;
}

/********************************************************************
**
**
**
********************************************************************* */

int video_off()

{
	SetVideoMode(0);
}

/********************************************************************
**
**
**
********************************************************************* */

int pixel_locate(x,y,speed,filenum)

int *x,*y,*speed;

{
	char ans,ans2,string[100];
	unsigned char buffer[100],buff[640];
	int csize=6,xo=*x,yo=*y,ix,iy,val;
	FILE *fp;
	long offset;
	int datfile=0,mo,da,yr,hr,min,sec;
	unsigned char dbuff[32];
	union intflo dval;
	float lat,lon,time;
	int bxs=300,bys=60;

	fp=open_to_read_binary(Hdr[filenum].image);
	if(fp)
		datfile=1;	
	else
	{
		video_off();
		printf("Could not open '%s'\n",Hdr[filenum].image);
		exit(0);
	}

	tcursor(0,*x,*y,csize,buffer);
	cursor(0,*x,*y,White,csize);
	paint_box(0,Black,buff,ScreenXs-bxs,ScreenYs-bys,bxs,bys);
	sprintf(string,"x=%3d y=%3d",*x,*y);
	plot_font_h(White,ScreenXs-bxs+2,ScreenYs-bys+1,string,2,Font);
	do
	{
		ans=getch();
		if(ans=='-'&&*speed>1)
			*speed/=2;
		if(ans=='+'&&*speed<ScreenYs/2)
			*speed*=2;
		if(ans==0)
		{
			ans2=getch();
			if(ans2==71||ans2==75||ans2==79)
				*x-=*speed;
			if(ans2==73||ans2==77||ans2==81)
				*x+=*speed;
			if(ans2==71||ans2==72||ans2==73)
				*y-=*speed;
			if(ans2==79||ans2==80||ans2==81)
				*y+=*speed;
			if(*x<0)
				*x=0;
			if(*x>=ScreenXs)
				*x=ScreenXs-1;
			if(*y<0)
				*y=0;
			if(*y>=ScreenYs)
				*y=ScreenYs-1;
			uncursor(0,xo,yo,csize,buffer);
			tcursor(0,*x,*y,csize,buffer);
			cursor(0,*x,*y,White,csize);
			paint_box(0,Black,buff,ScreenXs-bxs,ScreenYs-bys,bxs,bys);
			val=getpt(0,*x,*y);
			sprintf(string,"x=%3d y=%3d %3d",*x,*y,val);
			plot_font_h(White,ScreenXs-bxs+2,ScreenYs-bys+1,string,2,Font);
			ix=Xc*Sample+*x*ZoomSample;
			iy=Yc*Sample+*y*ZoomSample;
			offset=(long)Hdr[Img].header_bytes+(long)iy*(long)Hdr[filenum].col;
			fseek(fp,offset,SEEK_SET);
			fread((char *)dbuff,sizeof(char),32,fp);
			dval.lnum=dbuff[23];
			dval.lnum*=256;
			dval.lnum+=dbuff[22];
			dval.lnum*=256;
			dval.lnum+=dbuff[21];
			dval.lnum*=256;
			dval.lnum+=dbuff[20];
			dec2nec(&dval.lnum,1);
			lat=dval.fnum;
			dval.lnum=dbuff[27];
			dval.lnum*=256;
			dval.lnum+=dbuff[26];
			dval.lnum*=256;
			dval.lnum+=dbuff[25];
			dval.lnum*=256;
			dval.lnum+=dbuff[24];
			dec2nec(&dval.lnum,1);
			lon=dval.fnum;
			dval.lnum=dbuff[19];
			dval.lnum*=256;
			dval.lnum+=dbuff[18];
			dval.lnum*=256;
			dval.lnum+=dbuff[17];
			dval.lnum*=256;
			dval.lnum+=dbuff[16];
			dec2nec(&dval.lnum,1);
			time=dval.fnum;
			min=time;
			sec=time*60;
			sec%=60;
			mo=dbuff[9]*256+dbuff[8];
			da=dbuff[11]*256+dbuff[10];
			yr=dbuff[13]*256+dbuff[12];
			hr=dbuff[15]*256+dbuff[14];
			sprintf(string,"%5d %5d %9.5f %10.5f",ix,iy,lat,lon);
			plot_font_h(White,ScreenXs-bxs+2,ScreenYs-bys+16,string,2,Font);
			sprintf(string,"%2d-%2d-%2d %02d:%02d:%02d",mo,da,yr,hr,min,sec);
			plot_font_h(White,ScreenXs-bxs+2,ScreenYs-bys+32,string,2,Font);
			xo=*x;
			yo=*y;
		}
	}while(ans!=27&&ans!=13);
	uncursor(0,xo,yo,csize,buffer);
	paint_box(0,Black,buff,ScreenXs-bxs,ScreenYs-bys,bxs,bys);
}


/**************************************************************************
**
**
**
************************************************************************* */

int dec2nec(a,n)

long *a;
int n;

{
	long *w2;
	short i,j,z[2],y;

	w2=(long *)z;
	for(i=0;i<n;i++)
	{
		*w2=a[i];
		if((z[0]==0x8000)&&(z[1]==0x0000))
		{
			z[0]=0x0000;
			z[1]=0x7f80;
			a[i]=*w2;
		}
		if((z[0]==0x0000)&&(z[1]==0x0000))
		{
			z[0]=0x0000;
			z[1]=0x0000;
			a[i]=*w2;
		}
		else	/* good number */
		{
			y=z[0]-256;
			z[0]=z[1];
			z[1]=y;
			a[i]=*w2;
		}
	}
}


/**************************************************************************
**
**
**
************************************************************************* */

int change_color()

{
	int i,j,k;
	int num=0;
	int maxr=-1,maxg=-1,maxb=-1,minr=256,ming=256,minb=256;
	float flut[3],flutm[3],fdel[3],fmin[3];
	FILE *fplut;
	int val;

	do
	{
		num=do_menu_buff(menu_c,MENU_C,MENUXC,25,num,D_Grey,L_Grey,White,Font);
		if(num==0)
		{
			for(i=0;i<256;i++)
			{
				if((Hdr[Img].lut[i].r<255||Hdr[Img].lut[i].g<255||
						Hdr[Img].lut[i].b<255)&&
					(Hdr[Img].lut[i].r>0||Hdr[Img].lut[i].g>0||Hdr[Img].lut[i].b>0))
				{
					if((int)Hdr[Img].lut[i].r>maxr)maxr=Hdr[Img].lut[i].r;
					if((int)Hdr[Img].lut[i].r<minr)minr=Hdr[Img].lut[i].r;
					if((int)Hdr[Img].lut[i].g>maxg)maxg=Hdr[Img].lut[i].g;
					if((int)Hdr[Img].lut[i].g<ming)ming=Hdr[Img].lut[i].g;
					if((int)Hdr[Img].lut[i].b>maxb)maxb=Hdr[Img].lut[i].b;
					if((int)Hdr[Img].lut[i].b<minb)minb=Hdr[Img].lut[i].b;
				}
			}
			fdel[0]=maxr-minr;
			fdel[1]=maxg-ming;
			fdel[2]=maxb-minb;
			fmin[0]=minr;
			fmin[1]=ming;
			fmin[2]=minb;
			for(i=0;i<256;i++)
			{
				flut[0]=Hdr[Img].lut[i].r;
				flut[1]=Hdr[Img].lut[i].g;
				flut[2]=Hdr[Img].lut[i].b;
				for(k=0;k<3;k++)
				{
					val=(flut[k]-fmin[k])/fdel[k]*255.0;
					if(val<0.0)
						val=0.0;
					if(val>255.0)
						val=255.0;
					flutm[k]=val;
				}
				Hdr[Img].lutm[i].r=flutm[0];
				Hdr[Img].lutm[i].g=flutm[1];
				Hdr[Img].lutm[i].b=flutm[2];
			}
			WritePalette(Hdr[Img].lutm);
		}
		if(num==MENU_C-2&&VideoType!='V')
		{
			SetVideoMode(0);
			printf(
"\n\nYou have requested that the Look Up Table be changed.  If you proceed\n");
			printf(
"you will replace the current '.pal' file with a new one and the current\n");
			printf(
"file will be destroyed.  You may wish to make a copy of it first.\n\n");
			printf("        Do you wish to continue?  (y or n)\n\n");
			if(getch()=='y')
			{
				if(strlen(Hdr[Img].Lut)>0)
				{
					fplut=open_to_read_text(Hdr[Img].Lut);
					if(fplut)
					{
						for(i=0;i<Num_Color;i++)
							fprintf(fplut,"%3d %3d %3d %3d\n",i,
								Hdr[Img].lutm[i].r,
								Hdr[Img].lutm[i].g,
								Hdr[Img].lutm[i].b);
						fclose(fplut);
					}
				}
			}
			video_on();
			WritePalette(Hdr[Img].lut);
			return(0);
		}
	}while(num<MENU_C-1);
	return(1);
}



/**************************************************************************
**
**
**
************************************************************************* */

int load_image(filenum,iop)

int filenum,iop;

{
	int i,j,k;
	int sample=0;
	int xs,ys;
	FILE *fp;
	long offset=0;
	char string[100];

	Row=Hdr[filenum].row;
	Col=Hdr[filenum].col;
	if(VideoType=='S')
		Speed=8;

	if(Hdr[filenum].sample_bits==0)
		Hdr[filenum].sample_bits=8;

	if((Row==0||Col==0)&&Hdr[filenum].row_col_header==0)
		return(-1);
	fp=open_to_read_binary(Hdr[filenum].image);
	if(!fp)
	{
		video_off();
		printf("Could not open Hdr[%d].image = '%s'\n",
			filenum,Hdr[filenum].image);
		exit(0);
	}
	if(Hdr[filenum].row_col_header==1)
	{
		fread((char *)&Hdr[filenum].row,sizeof(int),1,fp);
		fread((char *)&Hdr[filenum].col,sizeof(int),1,fp);
		Col=Hdr[filenum].col;
		Row=Hdr[filenum].row;
		if(Row<=0||Col<=0)
			return(-1);
	}
	else if(Hdr[filenum].imbedded_header==1)
	{
		offset=Hdr[filenum].col;
		fseek(fp,offset,SEEK_SET);
	}
	else if(Hdr[filenum].header_bytes>0)
	{
		offset=Hdr[filenum].header_bytes;
		fseek(fp,offset,SEEK_SET);
	}
	video_on();
	do
	{
		Sample=sample+=1;
		Row=Hdr[filenum].row/sample;
		Col=Hdr[filenum].col/sample;
		offset=(sample-1);
		offset*=Hdr[filenum].col;
		offset+=Hdr[filenum].header_bytes;
	}while(Col>ScreenXs||Row>ScreenYs);
	Hdr[filenum].sample=sample;
	if(Hdr[filenum].pal_type>0)
		set_lut(Hdr[filenum].pal_type);
	else
	{
		if(set_lut('P',Hdr[filenum].Lut)<0)
			set_lut('G');
	}
	plot_full_image(fp,sample,filenum);
	if(iop==1)
		return(1);
	if(sample>1)
	{
		sample=ZoomSample;
		if(limit_area_fixed(&Xc,&Yc,&xs,&ys,&Speed,&sample)!=27)
		{
			ZoomSample=sample;
			plot_sub_image(fp,sample,filenum);
		}
		else
		{
			ZoomSample=Sample;
		}
	}
	fclose(fp);
}

/**************************************************************************
**
**
**
************************************************************************* */

int plot_sub_image(fp,sample,filenum)

FILE *fp;
int sample,filenum;

{
	int i,j,k;
	long offset;

	rewind(fp);
	paint_box(3,0,Mbuff,0,0,ScreenXs,ScreenYs);
	offset=Hdr[filenum].col;
	offset*=Yc*Sample;
	offset+=Xc*Sample;
	if(Hdr[filenum].header_bytes>0)
		offset+=Hdr[filenum].header_bytes;
	fseek(fp,offset,SEEK_SET);
	Row=ScreenYs;
	Col=ScreenXs;
	if((Yc*Sample+Row*sample)>Hdr[filenum].row)
		Row=(Hdr[filenum].row-Yc*Sample)/sample;
	if((Xc*Sample+Col*sample)>Hdr[filenum].col)
		Col=(Hdr[filenum].col-Xc*Sample)/sample;
	offset=Hdr[filenum].col;
	offset*=(sample-1);
	for(i=0;i<Row;i++)
	{
		if(fread((char *)Mbuff,sizeof(char),Hdr[filenum].col,fp)<1)
		{
			return(-1);
		}
		fseek(fp,offset,SEEK_CUR);
		if(sample>1)
			for(j=0;j<Col;j++)
				Mbuff[j]=Mbuff[j*sample];
		if(VideoType=='V'||VideoType=='E')
		{
			if(ActiveLut=='P')
			{
				for(j=0;j<Col;j++)
					Mbuff[j]=Hdr[filenum].vga_color[Mbuff[j]];
			}
			else
			{
				for(j=0;j<Col;j++)
					Mbuff[j]/=16;
			}
		}
		plotrow(3,0,Col-1,i,Mbuff);
	}

	return(1);
}


/**************************************************************************
**
**
**
************************************************************************* */

int plot_full_image(fp,sample,filenum)

FILE *fp;
int sample,filenum;

{
	int i,j,k;
	long offset;
	char string[100];
	int row,col;
	FILE *fpsub;

	strcpy(string,Hdr[filenum].image);
	for(i=0;i<strlen(string);i++)
		if(string[i]=='.')
			string[i]='\0';
	strcat(string,SubType);
	fpsub=open_to_read_binary(string);
	if(fpsub)
	{
		fread((char *)&row,sizeof(int),1,fpsub);
		fread((char *)&col,sizeof(int),1,fpsub);
		for(i=0;i<row;i++)
		{
			fread((char *)Mbuff,sizeof(char),col,fpsub);
			plotrow(0,0,col-1,i,Mbuff);
		}
		fclose(fpsub);
	}
	else
	{
		rewind(fp);
		offset=Hdr[filenum].header_bytes;
		if(offset>0)
			fseek(fp,offset,SEEK_SET);
		offset=(sample-1);
		offset*=Hdr[filenum].col;
		for(i=0;i<Row;i++)
		{
			fread((char *)Mbuff,sizeof(char),Hdr[filenum].col,fp);
			if(offset>0)
				fseek(fp,offset,SEEK_CUR);
			if(sample>1)
				for(j=0;j<Col;j++)
					Mbuff[j]=Mbuff[j*sample];
			if(VideoType=='V'||VideoType=='E')
			{
				if(ActiveLut=='P')
				{
					for(j=0;j<Col;j++)
						Mbuff[j]=Hdr[filenum].vga_color[Mbuff[j]];
				}
				else
				{
					for(j=0;j<Col;j++)
						Mbuff[j]/=16;
				}
			}
			plotrow(3,0,Col-1,i,Mbuff);
		}
		if(sample>1)
		{
			fpsub=open_to_write_binary(string);
			if(fpsub)
			{
				fwrite((char *)&Row,sizeof(int),1,fpsub);
				fwrite((char *)&Col,sizeof(int),1,fpsub);
				for(i=0;i<Row;i++)
				{
					getrow(0,0,Col-1,i,Mbuff);
					fwrite((char *)Mbuff,sizeof(char),Col,fpsub);
				}
				fclose(fpsub);
			}
		}
	}
}



/**************************************************************************
**
**
**
************************************************************************* */

int limit_area_fixed(xc,yc,xs,ys,speed,sample)

int *xc,*yc,*xs,*ys,*speed,*sample;

{
	int i,j,k;
	int xco=*xc,yco=*yc,xso,yso;
	char ans;

	xso=*xs=ScreenXs/Sample*(*sample);
	yso=*ys=ScreenYs/Sample*(*sample);

	tbox_val(3,*xc,*yc,*xs,*ys,Mbuff,Black,White,Center);
	do
	{
		ans=getch();
		unbox(3,*xc,*yc,*xs,*ys,Mbuff);
		if(ans==27)
		{
			return(27);
		}
		else if(ans=='-'&&*speed>1)*speed/=2;
		else if(ans=='+'&&*speed<ScreenYs)*speed*=2;
		else if(ans=='l'&&*sample<Sample)
			*sample+=1;
		else if(ans=='s'&&*sample>1)
			*sample-=1;
		*xs=ScreenXs/Sample*(*sample);
		*ys=ScreenYs/Sample*(*sample);

		if(ans==0)
		{
			ans=getch();
			if(ans==71)
			{
				*xc-=*speed;
				*yc-=*speed;
			}
			else if(ans==73)
			{
				*xc+=*speed;
				*yc-=*speed;
			}
			else if(ans==79)
			{
				*xc-=*speed;
				*yc+=*speed;
			}
			else if(ans==81)
			{
				*xc+=*speed;
				*yc+=*speed;
			}
			else if(ans==72)
				*yc-=*speed;
			else if(ans==80)
				*yc+=*speed;
			else if(ans==75)
				*xc-=*speed;
			else if(ans==77)
				*xc+=*speed;
		}
		if(*xs>ScreenXs)*xs=ScreenXs;
		if(*ys>ScreenYs)*ys=ScreenYs;
		if(*xs<2)*xs=2;
		if(*ys<2)*ys=2;
		if((*xc+*xs)>=ScreenXs)*xc=ScreenXs-*xs;
		if((*yc+*ys)>=ScreenYs)*yc=ScreenYs-*ys;
		if(*xc<0)*xc=0;
		if(*yc<0)*yc=0;
		tbox_val(3,*xc,*yc,*xs,*ys,Mbuff,Black,White,Center);
	}while(ans!=83&&ans!='x'&&ans!=27&&ans!=13);
	unbox(3,*xc,*yc,*xs,*ys,Mbuff);
	return(ans);
}

/**************************************************************************
**
**
**
************************************************************************* */

int video_on()

{
	int i,ret;

	i=GetVideoBoardID();
	if(i==0)
		VideoType='E';
	if(i==1&&(VideoType=='X'||VideoType=='Y'))
		VideoType='S';
	if(i<0)
	{
		printf("Computer will not support enough colors.\n\n");
		exit(0);
	}
	if(VideoType=='X')
	{
		SetVideoMode(480,&B_Id);
		if(B_Id.row==480)
		{
			set_lut('G');
			strcpy(SubType,".xmg");
		}
		else
		{
			if(i>1)
				VideoType='Y';
			else if(i==1)
				VideoType='V';
			else if(i==0)
				VideoType='E';
		}
	}
	if(VideoType=='V')
	{
		ret=SetVideoMode(0x12,&B_Id);
		strcpy(SubType,".vmg");
	}
	if(VideoType=='Y')
	{
		ret=SetVideoMode(400,&B_Id);
		strcpy(SubType,".ymg");
	}
	if(VideoType=='S')
	{
		ret=SetVideoMode(0x13,&B_Id);
		set_lut('G');
		strcpy(SubType,".smg");
		FontSize=3;
	}
	if(VideoType=='E')
	{
		ret=SetVideoMode(0x10,&B_Id);
		strcpy(SubType,".emg");
	}
	ScreenXs=B_Id.col;
	ScreenYs=B_Id.row;
	Num_Color=B_Id.color;
	if(ret>=0)
		return(1);
	else
	{
		SetVideoMode(0,&B_Id);
		printf("Could not boot video board\n\n");
		exit(0);
	}
}
/**************************************************************************
**
**
**
************************************************************************* */

int read_lbl(label,filenum)

char *label;
int filenum;

{
	int i,j,k;
	char string1[100],string2[100],string3[100];
	FILE *fp;
	int status=1,numread;

	fp=open_to_read_text(label);
	Hdr[filenum].sample_bits=Hdr[filenum].record_bytes=0;
	Hdr[filenum].file_records=0;
	Hdr[filenum].pal_type=0;
	Hdr[filenum].row_col_header=0;
	while(fscanf(fp,"%s",string1)==1)
	{
		if(strcmpi(string1,"end")==0)
		{
			fclose(fp);
			return(status);
		}
		if(strcmpi(string1,"image_lines")==0&&Hdr[filenum].file_records==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
				fclose(fp);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].row);
			printf("Row = %d\n",Hdr[filenum].row);
		}
		if(strcmpi(string1,"sample_bits")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
				fclose(fp);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].sample_bits);
			printf("Sample_Bits = %d\n",Hdr[filenum].sample_bits);
		}
		if(strcmpi(string1,"file_records")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
				fclose(fp);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].row);
			printf("Row = %d\n",Hdr[filenum].row);
			Hdr[filenum].file_records=Hdr[filenum].row;
		}
		if(strcmpi(string1,"line_samples")==0&&Hdr[filenum].record_bytes==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
				fclose(fp);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].col);
			printf("Col = %d\n",Hdr[filenum].col);
		}
		if(strcmpi(string1,"record_bytes")==0||
			strcmpi(string1,"image_record_bytes")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
				fclose(fp);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].col);
			printf("Col = %d\n",Hdr[filenum].col);
			Hdr[filenum].record_bytes=Hdr[filenum].col;
		}
		if(strcmpi(string1,"header_bytes")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
				fclose(fp);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].header_bytes);
			printf("Header_Bytes = %d\n",Hdr[filenum].header_bytes);
		}
		if(strcmpi(string1,"image_pointer")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
				fclose(fp);
				return(status);
			}			
			k=0;
			for(i=0;i<strlen(string3);i++)
				if(string3[i]!=39)		/* single quote */
					Hdr[filenum].image[k++]=string3[i];
			Hdr[filenum].image[k]='\0';
			printf("Image = %s\n",Hdr[filenum].image);
		}
		if(strcmpi(string1,"pal_type")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
				fclose(fp);
				return(status);
			}			
			k=0;
			for(i=0;i<strlen(string3);i++)
				if(string3[i]!=39)		/* single quote */
					string1[k++]=string3[i];
			string1[k]='\0';
			Hdr[filenum].pal_type=string1[0];
			printf("Pal_Type = %c\n",Hdr[filenum].pal_type);
		}
		if(strcmpi(string1,"pal_pointer")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
				fclose(fp);
				return(status);
			}			
			k=0;
			for(i=0;i<strlen(string3);i++)
				if(string3[i]!=39)		/* single quote */
					Hdr[filenum].Lut[k++]=string3[i];
			Hdr[filenum].Lut[k]='\0';
			printf("Lut = %s\n",Hdr[filenum].Lut);
		}
		if(strcmpi(string1,"row_col_header")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
				fclose(fp);
				return(status);
			}			
			Hdr[filenum].row_col_header=1;
			Hdr[filenum].header_bytes=4;
		}
	}
	fclose(fp);
	return(status);
}



/********************************************************************
**
**	type  g -- grey all lut[] files
**			G -- grey only lut[]
**			i -- initial header map
**			r -- reset lut[] to lutc[]
**			p -- positive (0-127) magenta, negative (128-255) green
**
********************************************************************* */

int set_lut(type,filename)

char type,*filename;

{
	int i,k,hue,brite,j;
	int r,g,b;
	float color[3];
	double dbrite,dval;
	float val,minval,sat,inten;
	float fval,fk;
	FILE *fplut;
	int end=0,scale,sum;
	char string[100];
	long del,mindel,l1,l2,l3,l4;

	scale=1;
	if(Num_Color==16)
		scale=17;
	if(type=='P')
	{
		fplut=open_to_read_text(filename);
		if(fplut)
		{
			i=0;
			do
			{
				i+=1;
				fscanf(fplut,"%s",string);
			}while(strcmpi(string,"end")!=0&&i<50);
			if(strcmpi(string,"end")!=0)
				rewind(fplut);
			for(i=0;i<256;i++)
			{
				fscanf(fplut,"%d%d%d%d",&k,&r,&g,&b);
				Hdr[Img].lut[i].r=r;
				Hdr[Img].lut[i].g=g;
				Hdr[Img].lut[i].b=b;
			}
			fclose(fplut);
		}
		else
			return(-1);
		if(VideoType=='V'||VideoType=='E')
		{
			for(i=0;i<256;i++)
			{
				sum=Hdr[Img].lut[i].r;
				sum+=Hdr[Img].lut[i].g;
				sum+=Hdr[Img].lut[i].b;
				sum/=48;
				Hdr[Img].vga_color[i]=sum;
			}
			for(k=0;k<Num_Color;k++)
			{
				Hdr[Img].lut[k].r=k*scale;
				Hdr[Img].lut[k].g=k*scale;
				Hdr[Img].lut[k].b=k*scale;
			}
		}
		ActiveLut='P';
	}
	if(type=='g')
	{
		for(k=0;k<Num_Color;k++)
		{
			Hdr[Img].lutc[k].r=Hdr[Img].lut[k].r=k*scale;
			Hdr[Img].lutc[k].g=Hdr[Img].lut[k].g=k*scale;
			Hdr[Img].lutc[k].b=Hdr[Img].lut[k].b=k*scale;
		}
		ActiveLut='g';
	}
	if(type=='G')
	{
		for(k=0;k<Num_Color;k++)
		{
			Hdr[Img].lut[k].r=k*scale;
			Hdr[Img].lut[k].g=k*scale;
			Hdr[Img].lut[k].b=k*scale;
		}
		ActiveLut='G';
	}
	if(type=='i')
	{
		for(k=0;k<Num_Color;k++)
		{
			Hdr[Img].lutc[k].r=Hdr[Img].lut[k].r=k*scale;
			Hdr[Img].lutc[k].g=Hdr[Img].lut[k].g=k*scale;
			Hdr[Img].lutc[k].b=Hdr[Img].lut[k].b=k*scale;
		}
		Hdr[Img].lut[ 64].r=  0;Hdr[Img].lut[ 64].g=  0;Hdr[Img].lut[ 64].b=128;
		Hdr[Img].lut[127].r=  0;Hdr[Img].lut[127].g=100;Hdr[Img].lut[127].b=  0;
		Hdr[Img].lut[191].r=255;Hdr[Img].lut[191].g=  0;Hdr[Img].lut[191].b=  0;
		Hdr[Img].lut[192].r=255;Hdr[Img].lut[192].g=128;Hdr[Img].lut[192].b=  0;
		Hdr[Img].lut[193].r=255;Hdr[Img].lut[193].g=255;Hdr[Img].lut[193].b=  0;
		Hdr[Img].lut[194].r=  0;Hdr[Img].lut[194].g=255;Hdr[Img].lut[194].b=  0;
		Hdr[Img].lut[195].r=  0;Hdr[Img].lut[195].g=255;Hdr[Img].lut[195].b=255;
		Hdr[Img].lut[196].r= 20;Hdr[Img].lut[196].g= 55;Hdr[Img].lut[196].b=255;
		Hdr[Img].lut[253].r=100;Hdr[Img].lut[253].g=  1;Hdr[Img].lut[253].b=  1;
		Hdr[Img].lut[254].r=100;Hdr[Img].lut[254].g=  1;Hdr[Img].lut[254].b=  1;
		ActiveLut='i';
	}
	if(type=='r')
	{
		for(k=0;k<Num_Color;k++)
		{
			Hdr[Img].lut[k].r=Hdr[Img].lutc[k].r;
			Hdr[Img].lut[k].g=Hdr[Img].lutc[k].g;
			Hdr[Img].lut[k].b=Hdr[Img].lutc[k].b;
		}
		ActiveLut='r';
	}
	mindel=16777216;
	for(i=0;i<Num_Color;i++)
	{
		l1=Blk.r;
		l2=Hdr[Img].lut[i].r;
		l3=Hdr[Img].lut[i].g;
		l4=Hdr[Img].lut[i].b;
		del=(l1-l2)*(l1-l2)+(l1-l3)*(l1-l3)+(l1-l4)*(l1-l4);
		if(del<mindel)
		{
			mindel=del;
			Black=i;
		}
	}
	mindel=16777216;
	for(i=0;i<Num_Color;i++)
	{
		l1=D_G.r;
		l2=Hdr[Img].lut[i].r;
		l3=Hdr[Img].lut[i].g;
		l4=Hdr[Img].lut[i].b;
		del=(l1-l2)*(l1-l2)+(l1-l3)*(l1-l3)+(l1-l4)*(l1-l4);
		if(del<mindel)
		{
			mindel=del;
			D_Grey=i;
		}
	}
	mindel=16777216;
	for(i=0;i<Num_Color;i++)
	{
		l1=M_G.r;
		l2=Hdr[Img].lut[i].r;
		l3=Hdr[Img].lut[i].g;
		l4=Hdr[Img].lut[i].b;
		del=(l1-l2)*(l1-l2)+(l1-l3)*(l1-l3)+(l1-l4)*(l1-l4);
		if(del<mindel)
		{
			mindel=del;
			M_Grey=i;
		}
	}
	mindel=16777216;
	for(i=0;i<Num_Color;i++)
	{
		l1=L_G.r;
		l2=Hdr[Img].lut[i].r;
		l3=Hdr[Img].lut[i].g;
		l4=Hdr[Img].lut[i].b;
		del=(l1-l2)*(l1-l2)+(l1-l3)*(l1-l3)+(l1-l4)*(l1-l4);
		if(del<mindel)
		{
			mindel=del;
			L_Grey=i;
		}
	}
	mindel=16777216;
	for(i=0;i<Num_Color;i++)
	{
		l1=Wht.r;
		l2=Hdr[Img].lut[i].r;
		l3=Hdr[Img].lut[i].g;
		l4=Hdr[Img].lut[i].b;
		del=(l1-l2)*(l1-l2)+(l1-l3)*(l1-l3)+(l1-l4)*(l1-l4);
		if(del<mindel)
		{
			mindel=del;
			White=i;
		}
	}
	WritePalette(Hdr[Img].lut);
	return(1);
}

/********************************************************************
**
**     options:
**
**       -1 -- remove menu but get no answer
**        0 -- return answer and set menu colors to GREYs
**        1 -- return answer but leave colors alone
**
********************************************************************* */

int do_menu_buff(menu,num,xc,yc,start,back,words,boxs,font)

char *menu[];
int num,xc,yc,start,back,words,boxs;
int font[128][25];

{
	int i,j,k;
	char ans,ans2;
	int len=0,l,size=2,val,valo;
	int black=Black,dGREY=back,lGREY=words,white=boxs;
	int wide;

	for(k=0;k<num;k++)
		if((l=strlen(menu[k]))>len)len=l;
	if(len==0)return(-1);
	wide=(len+1)*15/size+1;
	if((639-wide)<xc)xc=639-wide;

	if((xc+(len+1)*15/size+1)<640)
	{
		save_sub_mem(xc,yc,(len+1)*15/size+1,30/size*num+1);
		paint_box(0,dGREY,Buffer,xc,yc,(len+1)*15/size+1,30/size*num+1);
		
		for(k=0;k<num;k++)
		{	
			box(0,xc,yc+k*(30/size),dGREY,(len+1)*15/size,30/size);
			plot_font_h(lGREY,xc+15/size,yc+k*30/size+5/size,menu[k],size,font);
		}
		box(0,xc,yc,M_Grey,(len+1)*15/size,30/size*num);
		val=valo=start;
		box(0,xc,yc+val*(30/size),white,(len+1)*15/size,30/size);
		do
		{
			if((ans=getch())==0)
			{
				ans2=getch();
				if(ans2==50)
				{
					recall_sub_mem(xc,yc,(len+1)*15/size+1,30/size*num+1);

					getch();
					paint_box(0,dGREY,Buffer,
						xc,yc,(len+1)*15/size+1,30/size*num+1);
					for(k=0;k<num;k++)
					{	
						plot_font_h(lGREY,xc+15/size,
									yc+k*30/size+5/size,menu[k],size,font);
					}
				}
				if(ans2=='H')
				{
					if(val>0)val-=1;
					else val=num-1;
				}
				if(ans2=='P')
				{
					if(val<num-1)val+=1;
					else val=0;
				}
			}

			for(i=0;i<num;i++)
				if(ans==menu[i][0])
				{
					val=i;
					ans=13;
				}
			if(ans==27)
			{
				val=num-1;
				ans=13;
			}

			box(0,xc,yc+valo*(30/size),dGREY,(len+1)*15/size,30/size);
			valo=val;
			box(0,xc,yc,M_Grey,(len+1)*15/size,30/size*num);
			box(0,xc,yc+val*(30/size),white,(len+1)*15/size,30/size);
		}while(ans!=13);
	}
	box(0,xc,yc,dGREY,(len+1)*15/size,30/size*num);
	box(0,xc,yc+val*(30/size),M_Grey,(len+1)*15/size,30/size);

	recall_sub_mem(xc,yc,(len+1)*15/size+1,30/size*num+1);
	return(val);
}

/********************************************************************
**
**
**
********************************************************************* */

int save_sub_mem(xc,yc,xs,ys)

int xc,yc,xs,ys;

{
	int i,j,k;

	for(i=0;i<ys;i++)
		getrow(3,xc,xc+xs-1,i+yc,Mbuff+xs*i);
}

/********************************************************************
**
**
**
********************************************************************* */

int recall_sub_mem(xc,yc,xs,ys)

int xc,yc,xs,ys;

{
	int i,j,k;

	for(i=0;i<ys;i++)
		plotrow(3,xc,xc+xs-1,i+yc,Mbuff+xs*i);
}


/***********************************************************************
**
**
**
**
************************************************************************/

FILE *open_to_write_binary(name)

char *name;

{
	int i,j,k;
	FILE *fp;
	char string[STR_LEN];

	for(j=0;j<NumPath;j++)
	{
		sprintf(string,"%s%s",Path[j],name);
		fp=fopen(string,"wb");
		if(fp)
		{
			strcpy(LastFile,name);
			return(fp);
		}
	}
	clearerr(fp);
	fp=NULL;
	return(fp);
}


/***********************************************************************
**
**
**
**
************************************************************************/

FILE *open_to_read_binary(name)

char *name;

{
	int i,j,k;
	FILE *fp;
	char string[STR_LEN];
	int len;

	string[0]='\0';
	for(j=0;j<NumPath;j++)
	{
		len=strlen(Path[j])+strlen(name);
		if(len>0&&len<STR_LEN);
		{
			sprintf(string,"%s%s",Path[j],name);
			fp=fopen(string,"rb");
			if(fp)
			{
				strcpy(LastFile,name);
				return(fp);
			}	
		}
	}
	clearerr(fp);
	fp=NULL;
	return(fp);
}

/**************************************************************************
**
**
**
************************************************************************* */

int add_disk_path(string)

char *string;

{
	int i,j,k;
	char dsk,pth[STR_LEN],nam[10],typ[10],str[STR_LEN];
	int match,add=0;

	dsk=fsplit(string,pth,nam,typ);
	if(dsk>0)
		sprintf(str,"%c:%s",dsk,pth);
	else
		sprintf(str,"%s",pth);
	if((dsk>0||strlen(pth)>0)&&NumPath<NUM_DP)
	{
		match=0;
		for(i=0;i<NumPath;i++)
		{
			if(strcmpi(Path[i],str)==0)
				match=1;
		}
		if(match==0)
		{
			strcpy(Path[NumPath],str);
			NumPath+=1;
			add+=1;
		}
	}
	return(add);
}



/***********************************************************************
**
**
**
**
************************************************************************/

FILE *open_to_read_text(name)

char *name;

{
	int i,j,k;
	FILE *fp;
	char string[STR_LEN];

	for(j=0;j<NumPath;j++)
	{
		sprintf(string,"%s%s",Path[j],name);
		fp=fopen(string,"rt");
		if(fp)
		{
			strcpy(LastFile,name);
			return(fp);
		}
	}
	clearerr(fp);
	fp=NULL;
	return(fp);
}

                                            