
/********************************************************/
/*							*/
/*		GRAF Demonstration Program		*/
/*							*/
/*	Uses the following .GRF files:			*/
/*	   TITLE, SMALL, MEDIUM, HUGH, BAR1		*/
/*	   BAR2, CIRCLE, LINE, and STAR			*/
/*							*/
/*   Don Brittain		    3 January 1983	*/
/*   4200 Spruce St. #208 	      phone:		*/
/*   Philadelphia, PA 19104	   (215) 386-2684	*/
/*							*/
/********************************************************/

#define HSIZE 320
#define VSIZE 328
#define LIST 5
#define ESC 27

short grafbuf[HSIZE][VSIZE/8];
int horsize, versize;
int flag=1;
char grafname[13];

#include "libc.h"

main()

{
    bdos(LIST,12);
    crlf(8);
    graph("title");
    crlf(3);
    margin(23);
    pr("PRELIMINARY VERSION 1.0\n");
    margin(23);
    pr("    3 January 1983");
    crlf(19);
    margin(27);
    pr("Don Brittain\n");
    margin(23);
    pr("4200 Spruce St. #208\n");
    margin(22);
    pr("Philadelphia, PA  19104\n");
    margin(26);
    pr("(215) 386-2684");
    crlf(12);
    pr("This program was written to illustrate the power of GRAF.  All\n");
    pr("the examples were created with this preliminary version.\n\n");
    pr("Actually, GRAF is just an interactive 'shell' allowing (minimal) \n");
    pr("access to the modules grafutil.c, grafplot.c, grafline.c, graf-\n");
    pr("circ.c, grafinvt.c, and graffile.c.  These modules were originally\n");
    pr("written to be included in C programs requiring graphics.  GRAF\n");
    pr("hardly begins to utilize the real power of these subroutines.\n");
    pr("With them, C programs can easily be written to plot functions,\n");
    pr("draw recursive figures, plot solutions of ordinary differential\n");
    pr("equations, etc.  For technical details regarding the graphics\n");
    pr("modules (and a discussion of their shortcomings) see the file\n");
    pr("GRAF.DOC.\n\n");
    pr("I would appreciate being informed of any applications using these\n");
    pr("graphics subroutines.  Suggestions, criticisms, and improvements\n");
    pr("regarding any of my programs are always welcome.  I would also \n");
    pr("like to know about any other MX-80 graphics programs in the public\n");
    pr("domain.  I am particularly interested in 3-D graphics.  (This\n");
    pr("version of GRAF is FAR from supporting 3-D images!)\n\n");
    pr("Now for the demonstration:");
    crlf(10);
    pr("GRAF can create small graphs (as small as  1 x 1  pixels!):");
    graph("small");
    pr("Medium-size graphs:");
    graph("medium");
    crlf(5);
    pr("And hugh graphs (as large as  320 x 320  pixels):");
    graph("hugh");
    pr("GRAF makes bar graphs easily:");
    graph("bar1");
    pr("and can 'invert' graphs with a single command:");
    graph("bar2");
    crlf(8);
    pr("GRAF also has a circle (ellipse?) plotting command:");
    crlf(2);
    graph("circle");
    crlf(3);
    pr("and the ability to plot (or unplot) points and lines:");
    crlf(3);
    graph("line");
    crlf(17);
    pr("In order to use GRAF, simply type 'graf' after CP/M signs on,\n");
    pr("enter the dimensions of the graph when asked, then (following the\n");
    pr("'command:' prompt) type HELP.  A list of GRAF commands, together\n");
    pr("with a brief description of their actions, will be displayed on\n");
    pr("your console.\n\n     Have fun!");
    crlf(5);
    graph("star");
    crlf(35);
}
    
    
graph(name)

char *name;

{
    FILE *fopen(), *fp;
    int vrt;
    register i,j;

    graffcb(name);
    fp=fopen(grafname,"r");
    if(fp==NULL) 	{
	printf("\nERROR: %s does not exist on ",grafname);
	printf("the current drive.\n\n");
	return();	}
    horsize=getw(fp);
    versize=getw(fp);
    vrt=(versize+7)/8;
    printf("\nThe graph in %s has the following dimensions:",grafname);
    printf("\n\tHorizontal size: %3d",horsize);
    printf("\n\tVertical size: %3d\n\n",versize);
    for(j=0; j<vrt; j++)
	for(i=0; i<horsize; i++)
	    grafbuf[i][j]=getc(fp);
    fclose(fp);
    grafprnt();
}

graffcb(name)

char *name;

{
    register i;

    for(i=0; (grafname[i]=toupper(name[i]))!='\0'; i++);
    grafname[i++]='.';
    grafname[i++]='G';
    grafname[i++]='R';
    grafname[i++]='F';
    grafname[i]='\0';
}

pr(name)

char *name;

{
    register i;
    
    margin(5);
    for(i=0; name[i]!='\0'; i++)
	bdos(LIST,name[i]);
}
	
	
grafprnt()

{
    register i, j;
    int v,w;
    
    v=(versize+7)/8;
    w=50-horsize/8;
    crlf(3);
    setline(8);
    clmar(w);
    for(j=0; j<v; j++)	{
	bitmode(horsize);
	for(i=0; i<horsize; i++)
	    bdos(LIST, grafbuf[i][j]);
	clmar(w);	}
    crlf(3);
    setline(12);
}


setline(n)	/* routine to set the line-spacing on the MX-80 */
int n;
{
    bdos(LIST,ESC);
    bdos(LIST,'A');
    bdos(LIST,n);
}

bitmode(n)	/* sets n chars of dot graphics (480 dots/line) on MX-80 */
int n;
{
    bdos(LIST,ESC);
    bdos(LIST,'K');
    if(n<256)
	{
	bdos(LIST,n);
	bdos(LIST,0);
	}
    else
	{
	bdos(LIST,n-256);
	bdos(LIST,1);
	}
}


crlf(n)		/* printer carriage-return-linefeed */
int n;
{
int i;
for(i=0; i<n; i++)
    {
    bdos(LIST,10);
    bdos(LIST,13);
    }
}


margin(n)	/* printer left-margin */
int n;
{
int i;
for(i=0; i<n; i++)
    bdos(LIST,' ');
}

clmar(n)
int n;
{
crlf(1);
margin(n);
}
