
/*
     plot2tek.c : Plot Unix plot files on Tektronix 410x terminal

	 By Joel Swank April, 1988

	 */
#include <stdio.h>
#include "4107.h"

FILE *input;

/* scaling factors */

long xscale, yscale;  /* width, height of output device */
long xmult, ymult;  /* width, height on 410x Screen */
long xoff, yoff;	  /* offset to lower left corner  */

/* linemode constants */

char *lmodestr[] = { "dotted",
                     "solid",
                     "longdashed",
                     "shortdashed",
                     "dotdashed" };

short lmode[] = { 1, 2, 4, 3, 2 };


main(argc,argv)
int argc;
char *argv[];
{

struct IntuiMessage	*msg;
int cmd, i;
long x,y, r;
long r1, r2;
long x1,y1,x2,y2;
char textbuf[100], *p;
 
/*************************************************
     Init defaults
*************************************************/

xscale = 3120;
yscale = 3120;
xmult = 4096;
ymult = 4096;
xoff = 0;
yoff = 0;

 
/*************************************************
     Interrogate command line 
*************************************************/

if (argc == 1)
	{
	fprintf(stderr,"Usage:plot2tek plotfile\n");
	exit(2);
	}

while (*argv[1] == '-') 
	{
	p = (char *) &*argv[1];
	p++;		/* point to the option chars */
	switch (*p)
		{
		case 'x':		/* x size value */
			xmult = atol(++p);
			break;

		case 'y':		/* y size value */
			ymult = atol(++p);
			break;

		default:
			fprintf(stderr,"plot2tek:Invalid option %s\n",argv[1]);
			exit(27);
		}
	argc--;
	argv++;
	}

if (argc == 1 || argc >2)
	{
	fprintf(stderr,"plot2tek:Exactly One filename required\n");
	exit(2);
	}


if ((input = fopen(argv[1],"r")) == NULL)
	{
	fprintf(stderr,"plot2tek: %s: open failed\n",argv[1]);
	exit(3);
	}

 code(TEK);
 
/*************************************************
     MAIN Drawing loop
*************************************************/

while ((cmd = getc(input)) != EOF)
	{
	switch (cmd)
		{
		case 'm':	/* move x,y */
			get_xy(&x,&y);
			mov(x,y);
			break;
		case 'n':	/* draw x,y */
			get_xy(&x,&y);
			drw(x,y);
			break;
		case 'p':	/* point x,y */
			get_xy(&x,&y);
			mov(x,y);
			drw(x,y);
			break;
		case 'l':	/* line xs,ys, xe,ye */
			get_xy(&x,&y);
			mov(x,y);
			get_xy(&x,&y);
			drw(x,y);
			break;
		case 'a':	/* arc xc,yc, xs,ys, xe,ye */
			get_xy(&x,&y);    /* get center */
			get_xy(&x1,&y1);  /* get start point */
			get_xy(&x2,&y2);  /* get end point */
			arc(x, y, x1, y1, x2, y2);  /* draw counterclockwise  */
			mov(x2,y2);
			break;
		case 't':	/* Text string\n   */
			get_txt(textbuf);
			gtext(textbuf);
			break;
		case 'c':	/* circle xc,yc, r */
			get_xy(&x,&y);
			get_int(&r);
			r1 = r*xmult/xscale;
			r2 = r*ymult/yscale;
			mov(x-r1,y-r2);
			circle(x+r1,y+r2,x-r1,y-r2);
			break;
		case 'f':	/* linemode string\n   */
			get_txt(textbuf);
			for (i=0; i<5; i++)
				{
				if (0 == strcmp(textbuf,lmodestr[i]))
					{
					linestyle(lmode[i]);
					break;
					}
				}
			break;
		case 's':	/* space xlo,ylo, xhi,yhi */
			get_int(&xoff);
			get_int(&yoff);
			get_int(&xscale);
			get_int(&yscale);
			xscale = xscale - xoff;
			yscale = yscale - yoff;
			break;
		case 'e':	/* erase */
			page();
			break;
		}
	}
 linestyle(0);
 code(ANSI);
}


/*************************************************
     Parameter input routines
*************************************************/


/*
 * input a pair of 16 bit ints, scale and clip to screen,
 * and return them as longs
 *
 */

get_xy(x,y)
register long *x, *y;
{
	get_int(x);
	*x = (*x-xoff)*xmult/xscale;
	get_int(y);
	*y = (*y-yoff)*ymult/yscale;
}

/*
 * input a 16 bit int and return as a long
 */

get_int(num)
long *num;
{
	register short hi, lo;
	lo =  getc(input);
	hi = ( getc(input)) << 8;
	*num = (long) lo + hi;
}

/*
 * input a text string delimited by newline,
 * return to buffer delimited by a null.
 */

get_txt(str)
char *str;
{
	register int cmd;
	while ((cmd = getc(input)) != '\n')
		*str++ = cmd;
	*str = '\0';
}

/*
 * arc and integer sqrt routines.
 * lifted from sunplot program by:

Sjoerd Mullender
Dept. of Mathematics and Computer Science
Free University
Amsterdam
Netherlands

Email: sjoerd@cs.vu.nl
If this doesn't work, try ...!seismo!mcvax!cs.vu.nl!sjoerd or
...!seismo!mcvax!vu44!sjoerd or sjoerd%cs.vu.nl@seismo.css.gov.

 *
 */

long
isqrt(n)
long n;
{
	long a, b, c;

	a = n;
	b = n;
	if (n > 1) {
		while (a > 0) {
			a = a >> 2;
			b = b >> 1;
		}
		do {
			a = b;
			c = n / b;
			b = (c + a) >> 1;
		} while ((a - c) < -1 || (a - c) > 1);
	}
	return b;
}


arc(x, y, x1, y1, x2, y2)
long x, y, x1, y1, x2, y2;
{
	register long a1 = x1 - x, b1 = y1 - y, a2 = x2 - x, b2 = y2 - y;
	register long c1 = a1 * y - b1 * x, c2 = a2 * y - b2 * x;
	register long r2 = a1 * a1 + b1 * b1;
	register long i, sqrt;

	for (i = isqrt(r2 >> 1); i >= 0; i -= 1) {
		sqrt = isqrt(r2 - i * i);
		setcir(x + i, y + sqrt, a1, b1, c1, a2, b2, c2);
		setcir(x + i, y - sqrt, a1, b1, c1, a2, b2, c2);
		setcir(x - i, y + sqrt, a1, b1, c1, a2, b2, c2);
		setcir(x - i, y - sqrt, a1, b1, c1, a2, b2, c2);
		setcir(x + sqrt, y + i, a1, b1, c1, a2, b2, c2);
		setcir(x + sqrt, y - i, a1, b1, c1, a2, b2, c2);
		setcir(x - sqrt, y + i, a1, b1, c1, a2, b2, c2);
		setcir(x - sqrt, y - i, a1, b1, c1, a2, b2, c2);
	}
}

static setcir(x, y, a1, b1, c1, a2, b2, c2)
long x, y, a1, b1, c1, a2, b2, c2;
{
	if (a1 * y - b1 * x >= c1 && a2 * y - b2 * x <= c2)
		{
		mov(x, y);
		drw(x, y);
		}
}
