
/********************************************************/
/*							*/
/*	Epson MX-80 Bit-Plot Graphics Utility		*/
/*		Preliminary Version 1.0			*/
/*							*/
/*   Don Brittain		   3 January 1983	*/
/*   4200 Spruce St. #208		phone:		*/
/*   Philadelphia, PA 19104	   (215) 386-2684	*/
/*							*/
/********************************************************/

#define HSIZE 320
#define VSIZE 328
#define NO 0
#define YES 1

int versize, horsize;		/* These variables MUST be external */
int flag = YES;			/* so that the functions in the various */
				/* GRAF???? files have access to them */
static char tempbuf[10];

extern int  border(), lineplot(), grafprnt(), invert(), circle();
extern int savegraf(), getgraf();

main()

{
    printf("\n\t\tEpson MX-80 Bit-Plot Graphics Utility.");
    printf("\n\t\t    Don Brittain   3 January 1983\n\n");
    start();
    command();
}


command()	/* This is the main user interface routine.  It */
		/* reads the console then calls the appropriate */
		/* graphics function */
{
    printf("Command: ");
    gets(tempbuf);
    switch(toupper(*tempbuf))	{
	case 'B' :
		flag = YES;
		border();
		command();
	case 'K' :
		flag = NO;
		border();
		command();
	case 'L' :
		flag = YES;
		comline();
		command();
	case 'E' :
		flag = NO;
		comline();
		command();
	case 'C' :
		flag = YES;
		comcircle();
		command();
	case 'N' :
		flag = NO;
		comcircle();
		command();
	case 'P' :
		flag = YES;
		complot();
		command();
	case 'U' :
		flag = NO;
		complot();
		command();
	case 'D' :
		comdump();
		command();
	case 'I' :
		cominvt();
		command();
	case 'S' :
		flag = NO;
		getsave();
		command();
	case 'G' :
		flag = YES;
		getsave();
		command();
	case 'T' :
		comtell();
		command();
	case 'R' :
		printf("\nRESTART? ");
		gets(tempbuf);
		if(toupper(*tempbuf)=='Y')
			main();
		else
		    printf("\nRestart command ignored.\n");
		    command();
	case 'Q' :
		printf("\nQUIT? ");
		gets(tempbuf);
		if(toupper(*tempbuf)=='Y')
			exit();
		else
		    printf("\nExit command ignored.\n");
		    command();
	case 'H' :
		printf("\nGRAF recognizes the following commands:\n");
		printf("\n\tBORDER draws a border around the graph");
		printf("\n\tKILL removes all border points");
		printf("\n\tLINE allows the user to draw straight lines");
		printf("\n\tERASE is used to erase lines");
		printf("\n\tCIRCLE is used to plot circles");
		printf("\n\tNO CIRCLE is used to erase circles");
		printf("\n\tPLOT allows the user to plot individual points");
		printf("\n\tUNPLOT removes individual points");
		printf("\n\tDUMP sends a copy of the graph to the printer");
		printf("\n\tINVERT allows color inversion: black <-> white");
		printf("\n\tSAVE saves a copy of an existing graph on disk");
		printf("\n\tGET retrieves a previously SAVEd graph");
		printf("\n\tTELL returns the current graph dimensions");
		printf("\n\tRESTART erases the current graph");
		printf("\n\tQUIT returns control to CP/M");
		printf("\n\nTo execute a command, only the first letter ");
		printf("needs to be typed (in ");
		printf("\nupper or lower case).\n\n");
		command();
	default :
		putchar(7);
		puts(tempbuf);
		printf("?\n");
		command();
	}
}

		
start()		/* This routine sets up the matrix size using the external */
		/* variables horsize and versize.  Note that the actual   */
		/* graphics buffer is always HSIZE * VSIZE / 8 bytes long. */
		/* horsize and vertize really only restrict the portion of */
		/* the buffer the routines can access (thereby increasing  */
		/* the speed of some of the routines for small graphs).    */
{
    printf("\nHorizontal size: ");
    horsize=(atoi(gets(tempbuf)));
    if(horsize>HSIZE)	{
	putchar(7);
	printf("The maximum horizontal dimension is %d.", HSIZE);
	start();	}
    printf("Vertical size: ");
    versize=(atoi(gets(tempbuf)));
    if(versize>(VSIZE-8))	{
	putchar(7);
	printf("The maximum vertical dimension is %d.", VSIZE-8);
	start();	}
    printf("Do you want the initial graph to be white or black? ");
    gets(tempbuf);
    if(toupper(*tempbuf)=='B') flag = NO;
    putchar(14);
    putchar(10);
    init(horsize,versize);
    printf("\nType HELP for assistance.\n\n");
}

		
comline()	/* User interface to the lineplot() subroutine */
	
{
    int x,y,h,v;
    
    if(flag)
    	printf("\n\t------- Line Plotting Function -------\n\n");
    else
	printf("\n\t------- Line Erasing Function -------\n\n");
    printf("Input the coordinates of the first endpoint.\n");
    printf("\tHorizontal coord: ");
    x=atoi(gets(tempbuf));
    printf("\tVertical coords: ");
    y=atoi(gets(tempbuf));
    printf("Input the coordinates of the second endpoint.\n");
    printf("\tHorizontal coord: ");
    h=atoi(gets(tempbuf));
    printf("\tVertical coord (1000 to ABORT command): ");
    v=atoi(gets(tempbuf));
    if(v==1000) 	{
	printf("Function aborted.\n\n");
	flag=YES;
	return();	}
    lineplot(x,y,h,v);
}


complot()		/* Interface to pixplot() and  unpixplot() */

{
    if(flag)
	printf("\n\t------- Point Plotting Function -------\n\n");
    else
	printf("\n\t------- Point Erasing Function -------\n\n");
    printf("Enter the coordinate 1000 to QUIT. \n");
    plotaux();
}

plotaux()

{
    int h,v;

    printf("\tHorizontal coord: ");
    h=atoi(gets(tempbuf));
    if(h==1000) {
	flag = YES;
	return();	}
    printf("\tVertical coord: ");
    v=atoi(gets(tempbuf));
    if(v==1000) {
	flag = YES;
	return();	}
    if(flag)
    	pixplot(h,v);
    else
	unpixplot(h,v);
    plotaux();
}

comdump()	/* Interface to grafprnt(), the graph-printing subr. */

{
    int n;
    
    printf("How many spaces do you want in the left margin? ");
    n=atoi(gets(tempbuf));
    if((n+versize/5)>80) n=80-versize/5;
    grafprnt(n);
}


cominvt()	/* Interface to the inversion subr. (black <-> white) */

{
    int x,y,h,v;
    
    printf("\n\t------- Graph Inversion Function -------\n\n");
    printf("Input the horizontal range.\n");
    printf("   Beginning value: ");
    x=atoi(gets(tempbuf));
    printf("   End value: ");
    h=atoi(gets(tempbuf));
    printf("Input the Vertical range.\n");
    printf("   Beginning value: ");
    y=atoi(gets(tempbuf));
    printf("   End value (1000 to ABORT): ");
    v=atoi(gets(tempbuf));
    if(v==1000)	{
	printf("Command aborted.\n\n");
	command();	}
    else
	invert(x,h,y,v);
}

	
comcircle()		/* Interface to the circle-plotting subr. */

{
    int x,y,r;
    
    if(flag)
	printf("\n\t------- Circle Plotting Function -------\n\n");
    else
	printf("\n\t------- Circle Erasing Function -------\n\n");
    printf("Input the coordinates for the center of the circle.\n");
    printf("\tHorizontal Coord: ");
    x=atoi(gets(tempbuf));
    printf("\tVertical Coord: ");
    y=atoi(gets(tempbuf));
    printf("Input the radius (1000 to ABORT): ");
    r=atoi(gets(tempbuf));
    if(r==1000)	{
	printf("Function aborted.\n\n");
	flag=YES;
	return();	}
    circle(x,y,r);
}


getsave()	/* Interface to getgraf() and  savegraf() -- routines */
		/* to store and retrieve graphics images  */
{
    if(flag)
	printf("\n\t------- Graph Retrieval Utility -------\n\n");
    else
	printf("\n\t------- Graph Save Utility -------\n\n");
    printf("Enter the name of the graph: ");
    gets(tempbuf);
    if(flag)
	getgraf(tempbuf);
    else
	savegraf(horsize,versize,tempbuf);
    putchar(10);
    putchar(14);
    flag=YES;
}

comtell()	/* Prints the current graph dimensions -- useful mainly */
		/* for debugging the file-handling routines */
{
    printf("\nThe current graph dimensions are --");
    printf("\n\tHorizontal size: %3d",horsize);
    printf("\n\tVertical size: %3d\n\n",versize);
}
