[net.sources] Source Code Shar File 1-of-1

awpaeth@watcgl.UUCP (Alan W. Paeth) (01/13/87)

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by watcgl!awpaeth on Mon Jan 12 21:46:03 EST 1987
# Contents:  README starchart.l Makefile starchart.h starchart.c starchartdsp.c
#	starchartpic.c starcharttek.c
 
echo x - README
sed 's/^@//' > "README" <<'@//E*O*F README//'
Installation instructions:

[1]
Get the four pieces of the reduced Yale Star Catalog from net.sources
and save in this directory under the name "yale.star". You may choose
another directory, name, or path conventions for this large file, but
then you will have to change the #define constant near the beginning of
starchart.c.

Fine points
-----
The yale stuff was posted as five articles, each under 50K:

(1) Intro (2) Data 1-of-4 (3) Data 1-of-4 [SIC] (4) Data 3-of-4 (5) Data 4-of-4

Posting (2) and (3) have different subject headers, as they give the
correct limiting magnitude for each dataset.

Sites without much disk space may truncate the file at any point, as the
data is sorted in order of increasing intensity (as the programs expect)

User's with copies of the Yale Data may reformat into the condensed format.
This is described in the first posting, which is the overview of the data.
-----

[2]
Do a "make all" to compile the three versions of the program. They are
described in the man page "starchart.l". All compile using starchart.c as
the mainline, with device driver specifics in modules of appropriate name.

[3]
You may now try "man test" to make an Orion pic file similar to the one
posted to the net last week. Or you may test by outputting to the display,
as described in the EXAMPLE section of the man page.

[4]
You can now delete the original shar file, plus this file.


NOTES:

Tty display users (*sigh*) may which to alter "stardsp" to output to the
display using an appropriate number of of rows and columns on the screen.
(Presently 31x79 for a 32x80 display. 23x79 is a bit sparse). Find the
ROWS and COLS #defines in starchartdsp.c and update. Or be really ambitious
and recode them as run time variables.

Tektroniks users may wish to alter scaling parameters based on the actual
physical dimensions of the display raster, to get the cleanest possible star
glyphs on output. The #defines XSCALE and YSCALE are the ratio (I've reduced
them to LCD) between your device X (or Y) coordinates, and true Tektroniks
coordinates (X=1024, Y=768). XSCALEI and YSCALEI are their inverses.

Pic file users: the #define PICFRAG can be adjusted downward (presently 8)
should your pic input overflow pic's buffers. This happens when a long
move,draw,draw,...,draw sequence happens. Smaler PICFRAGs make larger files,
by forming fragmented move,draw commands.

PostScript users: be patient. I've written a preliminary version, but need
to find a AppleWriter to test it on. The code is straightforward, the output
is nice and compact.
@//E*O*F README//
chmod u=rw,g=rw,o=r README
 
echo x - starchart.l
sed 's/^@//' > "starchart.l" <<'@//E*O*F starchart.l//'
@.TH starchart LOCAL 12/1/87
@.UC
@.SH NAME
stardsp, starpic, startek \- print astronomical star charts using Yale database
@.SH SYNOPSIS
These programs generate star charts based on data extracted from the Yale
public domain star catalog.
Output is to the terminal 
@.RB ( stardsp ),
Unix PIC file
@.RB ( starpic )
or in Tektronix
vector format
@.RB ( startek ).
Star data is optionally overlayed with other cosmic objects, such as planets.
@.SH EXAMPLES 
@.nf
# Orion: the belt lies near 5h40m in RA, just below the CE.
stardsp 5.6 -4.1 11.2 "Orion & belt" | more
@.fi
@.SH DESCRIPTION
The starchart center is specified by two parameters: floats defining Right
Ascension [0.0 to 24.0 hours] and Declination [-90.0 to +90.0 degrees].
An optional third parameter defines the N/S range of the output window, in
degrees of declination.
An optional fourth parameter gives a title.
@.PP
The software reads data from a local file
@.RB ( yale.star )
and optional planetary file
@.RB ( planet.star )
and clips to a rectangular (in RA and DEC) window.
Objects within this window are projected onto the output media, and displayed
using the appropriate glyphs.
Present implementations draw two viewports: a "master" chart plus a
"thumbnail" overview with low limiting magnitude.
Their location and the limiting magnitude is specified by records in
the device driver, allowing the chart layout be tuned on a per-device basis.
The output is annotated with viewport boundaries, a legend and axis labels.
@.PP
Sanson's sinusoidal projection is used to map coordinates.
This projection preserves both area and linearity in Declination (y axis).
It gives good conformality (angle correctness) near the equator, so it is
useful along the Ecliptic.
Lines of RA converge at the poles (unlike cylindrical projections),
though Cassiopeia and the Dipper reproduce well.
@.SH BUGS
No testing for bogus ranges and scales which may wrap the poles.
The present implementation expects
@.B yale.star
sorted by decreasing magnitude so that output is sequential, and then cuts off
below a limiting magnitude.
For more detailed charts spatial sorting is more appropriate.
@.SH AUTHOR
Alan Paeth, University of Waterloo (AWPaeth@watCGL)
@//E*O*F starchart.l//
chmod u=rw,g=r,o=r starchart.l
 
echo x - Makefile
sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//'
CFLAGS = -O

stardsp: starchart.c starchartdsp.c
	cc $(CFLAGS) starchart.c starchartdsp.c -lIkonas -lm -o ./stardsp

starpic: starchart.c starchartpic.c
	cc $(CFLAGS) starchart.c starchartpic.c -lIkonas -lm -o ./starpic

startek: starchart.c starcharttek.c
	cc $(CFLAGS) starchart.c starcharttek.c -lIkonas -lm -o ./startek

test: starpic
	./starpic 5.6 -4 10 "Orion" >orion.pic

all:	stardsp\
	starpic\
	startek
@//E*O*F Makefile//
chmod u=rw,g=rw,o=r Makefile
 
echo x - starchart.h
sed 's/^@//' > "starchart.h" <<'@//E*O*F starchart.h//'
typedef struct
    {
    float racen, dlcen, scale;
    float north, south, east, west;
    float maglim;
    int wx, wy, ww, wh;
    float yscale;
    } mapblock, *map;

extern mapblock master, thumbnail;
@//E*O*F starchart.h//
chmod u=rw,g=rw,o=r starchart.h
 
echo x - starchart.c
sed 's/^@//' > "starchart.c" <<'@//E*O*F starchart.c//'
/*
 * starchart.c - draw yale star catalog on binary output device
 *
 * (c) copyright 1987 by Alan Paeth (awpaeth@watcgl)
 */

#include <stdio.h>
#include <math.h>
#include <strings.h>
#include "starchart.h"

#define STARFILE "yale.star"	/* consider using ABSOLUTE paths here */
#define PLANETFILE "planet.star"

#define DCOS(x) (cos((x)*3.14159265354/180.0))
#define MAX(a,b) ((a)>(b)?(a):(b))

double max(), modup(), moddown();

main(argc, argv)
    int argc;
    char *argv[];
    {
    double thumbscale;
    vecopen();
    chartparms(&master, atof(argv[1]), atof(argv[2]), atof(argv[3]));
    thumbscale = MAX( atof(argv[3]) * 1.2, 10.0);
    chartparms(&thumbnail, atof(argv[1]), atof(argv[2]), thumbscale);
    chartall(&master);
    chartall(&thumbnail);
    chartlegend(&master, (argc >= 5) ? argv[4] : "LEGEND");
    vecclose();
    exit(0);
    }

chartparms(chart, ra, decl, scl)
    double ra, decl, scl;
    map chart;
    {
    double adj, xscale;
    chart->racen = ra * 360.0 / 24.0;
    chart->dlcen = decl;
    chart->scale = scl;
    if (chart->scale == 0.0) chart->scale = 15.0;

    chart->north = (chart->dlcen + chart->scale / 2.0);
    chart->south = (chart->dlcen - chart->scale / 2.0);
/*
 * xscale is other than chart->scale in order to widen the horizontal viewing
 * area, which otherwise shrinks near the poles under Sanson's projection
 * this happens in polar maps which do not span the celestial equator
 */
    adj = 1.0;
    if (chart->north * chart->south > 0.0)
	adj = max(DCOS(chart->north), DCOS(chart->south));
    xscale = chart->scale/adj;

    chart->east  = (chart->racen + xscale*chart->ww/chart->wh / 2.0);
    chart->west  = (chart->racen - xscale*chart->ww/chart->wh / 2.0);
    chart->yscale = chart->wh / chart->scale;
    }

chartlegend(chart, title)
    map chart;
    char *title;
    {
    char tstr[20], tstr2[20];
    vecsize(14);
    vecsyms(100, 220, title);
    vecsize(10);
    vecsyms( 20, 200, "= = = = = = = = = = = =");
    vecsyms( 20, 180, "Right Ascension:");
    rastr(tstr, chart->racen);
    sprintf(tstr2, " %s", tstr);
    vecsyms(260, 180, tstr2);
    vecsyms( 20, 160, "Declination:");
    declstr(tstr, chart->dlcen);
    vecsyms(260, 160, tstr);
    vecsyms( 20, 140, "Chart Scale:");
    sprintf(tstr, "%.3f", chart->scale);
    sprintf(tstr2, " %s", tstr);
    vecsyms(260, 140, tstr2);
    vecsyms( 20,  20, "= = = = = = = = = = = =");

    vecsyms(115, 110, "<1.0");
    vecsyms(115,  80, "<2.0");
    vecsyms(115,  50, "<3.0");
    vecsyms(260, 110, "<4.0");
    vecsyms(260,  80, "<5.0");
    vecsyms(260,  50, ">5.0");

    drawstar( 65, 110, 0);
    drawstar( 65,  80, 1);
    drawstar( 65,  50, 2);
    drawstar(240, 110, 3);
    drawstar(240,  80, 4);
    drawstar(240,  50, 5);
    }

readstar(file, lat, lon, mag, code, subcode, label)
    FILE *file;
    double *lat, *lon, *mag;
    char *code, *subcode, *label;
    {
#define LINELEN 40
    char sbuf[LINELEN];
    double rah, ram, ras, dld, dlm, dl, inten;
    fgets(sbuf, LINELEN, file);
    if (feof(file)) return(1);
/*
 * sscanf of floats is TOOO slow:
 *     sscanf(sbuf, "%2f%2f%2f%c%2f%2f%c%3f%c%c%s", ... );
 * use alternate:
 */
#define F2(i) ((double)((sbuf[i]-'0')*10+sbuf[i+1]-'0'))
#define F3(i) ((double)((sbuf[i]-'0')*100+(sbuf[i+1]-'0')*10+sbuf[i+2]-'0'))
    rah = F2(0);
    ram = F2(2);
    ras = F2(4);
    dld = F2(7);
    dlm = F2(9);
    inten = F3(12);
    code[0] = sbuf[15];
    subcode[0] = sbuf[16];
    label[0] = '\0';
    strncat(label, &sbuf[17], strlen(&sbuf[17])-1);
#define DLDEGSEC 3600.0
#define DLMINSEC 60.0
#define RAHRSSEC 54000.0
#define RAMINSEC 900.0
#define RASECSEC 15.0
    *lon = (RAHRSSEC*rah + RAMINSEC*ram + RASECSEC*ras)/DLDEGSEC;
    dl = (DLDEGSEC*dld + DLMINSEC*dlm)/DLDEGSEC;
    *lat = (sbuf[6]  == '-') ? -dl : dl;
    *mag = ((sbuf[11] == '-') ? -inten : inten)/100.0;
    return(0);
    }

xform(chart, lat, lon, xloc, yloc)
    map chart;
    double lat, lon;
    int *xloc, *yloc;
    {
 /*
  * This is Sanson's Sinusoidal projection. Its properties:
  *   (1) area preserving
  *   (2) preserves linearity along y axis (declination/azimuth)
  */
    *xloc = chart->wx+chart->ww/2 + (chart->racen-lon)*chart->yscale*DCOS(lat);
    *yloc = chart->wy + (int)((lat - chart->south) * chart->yscale);
    }

chartall(chart)
    map chart;
    {
#define READMODE "r"
#define OPENFAIL 0
    FILE *sfile, *pfile;
    if ((sfile = fopen(STARFILE, READMODE)) == OPENFAIL)
	die("open fail on %s", STARFILE);
    chartoutline(chart);
    chartgrid(chart);
    chartobjects(chart, sfile);
    fclose(sfile);
    if ((pfile = fopen(PLANETFILE, READMODE)) != OPENFAIL)
	{
	chartobjects(chart, pfile);
	fclose(pfile);
	}
    }

chartobjects(chart, file)
    map chart;
    FILE *file;
    {
    double lat, lon, mag;
    char code[1], subcode[1], label[100];
    int xloc, yloc;
    for(;;)
	{
	if (readstar(file, &lat, &lon, &mag, code, subcode, label)) break;
	if (mag > chart->maglim) break;
	if ((chart->west < 0.0) && (lon>180.0)) lon -= 360.0;
	if ((chart->east > 360.0) && (lon<180.0)) lon += 360.0;
	if ( (lon >= chart->west) && (lon <= chart->east) &&
	     (lat >= chart->south) && (lat <= chart->north) )
	    {
	    xform(chart, lat, lon, &xloc, &yloc);
	    if (code[0] == 'S') drawstar(xloc, yloc, (int)(mag));
	    if (code[0] == 'P') drawP(xloc, yloc);
	    if (strlen(label))
		{
		vecsize(10);
		vecsyms(xloc+8, yloc, label);
		}
	    }
	}
    }

/*
 * Chart Construction
 */

chartgrid(chart)
    map chart;
    {
    charthgrid(chart, 15.0, 18);
    charthgrid(chart, 5.0, 12);
    charthgrid(chart, 1.0, 6);
    chartvgrid(chart, 10.0, 18);
    chartvgrid(chart, 5.0 , 12);
    chartvgrid(chart, 1.0, 6);
    }

chartoutline(chart)
    map chart;
    {
    double start, inc;
    int xloc, xloc2, yloc, yloc2, div, i;

    xform(chart, chart->south, chart->west, &xloc,  &yloc);
    xform(chart, chart->south, chart->east, &xloc2, &yloc2);
    vecmovedraw(xloc, yloc, xloc2, yloc2);
    xform(chart, chart->north, chart->west, &xloc,  &yloc);
    xform(chart, chart->north, chart->east, &xloc2, &yloc2);
    vecmovedraw(xloc, yloc, xloc2, yloc2);

    inc = (chart->north - chart->south);
    div = (int)(inc);
    if (div < 1) div = 1;
    inc /= div;
    start = chart->south;
    xform(chart, start, chart->west, &xloc, &yloc);
    vecmove(xloc, yloc);
    for (i=0; i < div; i++)
	{
	start += inc;
	xform(chart, start, chart->west, &xloc, &yloc);
	vecdraw(xloc, yloc);
	}
    start = chart->south;
    xform(chart, start, chart->east, &xloc, &yloc);
    vecmove(xloc, yloc);
    for (i=0; i < div; i++)
	{
	start += inc;
	xform(chart, start, chart->east, &xloc, &yloc);
	vecdraw(xloc, yloc);
	}
    }

rastr(str, ra)
    char *str;
    double ra;
    {
    int hrs, min;
    hrs = (int)(ra/15.0);
    min = (int)((ra - hrs * 15.0) * 4.0);
    sprintf(str, "%02dh", hrs);
    if (min) sprintf(str, "%s%02dm", str, min);
    }

declstr(str, dl)
    char *str;
    double dl;
    {
    int deg, min;
    if (dl == 0.0) sprintf(str, "%s", " ");
    else if (dl > 0.0) sprintf(str, "%s", "+");
	else
	{
	sprintf(str, "%s", "-");
	dl = -dl;
	}
    deg = (int)(dl);
    min = (int)((dl - deg) * 60.0);
    sprintf(str, "%s%02dd", str, deg);
    if (min) sprintf(str, "%s%02dm", str, min);
    }

charthgrid(chart, inc, hgt)
    map chart;
    double inc;
    {
#define HTICKLIM 2
#define HTEXTLIM 80
    double start, stop, ra;
    int xloc, xloc2, yloc, xloc3, yloc3;
    start = modup(chart->west, inc);
    stop = moddown(chart->east, inc);
    xform(chart, chart->south, start, &xloc, &yloc);
    xform(chart, chart->south, start+inc, &xloc2, &yloc);
    if (xloc - xloc2 > HTICKLIM)
	for (ra = start; ra <= stop; ra += inc)
	    {
	    xform(chart, chart->south, ra, &xloc3, &yloc3);
	    vecmovedraw(xloc3, yloc3-hgt, xloc3, yloc3);
	    if (xloc - xloc2 > HTEXTLIM)
		{
		char tstr[20];
		rastr(tstr, ra);
		vecsize(10);
		vecsyms(xloc3+2, yloc-17, tstr);
		}
	    }
    }

chartvgrid(chart, inc, wid)
    map chart;
    double inc;
    {
#define VTICKLIM 2
#define VTEXTLIM 20
    double start, stop, dl;
    int xloc, yloc, yloc2, xloc3, yloc3;
    start = modup(chart->south, inc);
    stop = moddown(chart->north, inc);
    xform(chart, start, chart->west, &xloc, &yloc);
    xform(chart, start+inc, chart->west, &xloc, &yloc2);
    if (yloc2 - yloc > VTICKLIM)
	for (dl = start; dl <= stop; dl += inc)
	    {
	    xform(chart, dl, chart->west, &xloc3, &yloc3);
	    vecmovedraw(xloc3, yloc3, xloc3+wid, yloc3);
	    if (yloc2 - yloc > VTEXTLIM)
		{
		char tstr[20];
		declstr(tstr, dl);
		vecsize(10);
		vecsyms(xloc3+24, yloc3, tstr);
		}
	    }
    }

/*
 * General Utilities
 */

double max(a, b)
    double a, b;
    {
    if (a>b) return(a);
    return(b);
    }

double modup(a, b)
    double a, b;
    {
    double new;
    new = ((double)((int)(a/b))*b);
    if (new >= a) return(new);
    return(new += b);
    }

double moddown(a, b)
    double a, b;
    {
    double new;
    new = ((double)((int)(a/b))*b);
    if (new <= a) return(new);
    return (new -= b);
    }

die(a,b)
    char *a, *b;
    {
    fprintf(stderr,"Error: ");
    fprintf(stderr,a,b);
    fprintf(stderr,"\n");
    exit(1);
    }
@//E*O*F starchart.c//
chmod u=rw,g=rw,o=r starchart.c
 
echo x - starchartdsp.c
sed 's/^@//' > "starchartdsp.c" <<'@//E*O*F starchartdsp.c//'
/*
 * TTY Display driver for startchart.c mainline
 */

#include <stdio.h>
#include <ctype.h>
#include "starchart.h"

#define MAX(a,b) ((a)>(b)?(a):(b))
#define ROWS 31
#define COLS 79

/*
 * Chart parameters (limiting magnitude and window x,y,w,h)
 */

mapblock thumbnail =	{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
			3.0, 420, 35, 480, 195, 0.0 };

mapblock master =	{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
			4.9, 20, 265, 880, 500, 0.0 };

/*
 * Generic Star Drawing Stuff
 */

static int oldx, oldy, scrx, scry;
static char **linevec;

vecopen()
   {
   int i;
   linevec = (char**)(calloc(ROWS, sizeof(char*)));
   for (i=0; i<ROWS; i++) linevec[i] = (char*)(calloc(COLS, sizeof(char)));
   }

vecclose()
    {
    int i, j, k;
    char c;
    for (i=0; i<ROWS; i++)
	{
	for (j=COLS-1; j>0; j--) if (linevec[i][j]) break;
	for (k=0; k<=j; k++) putchar((c=linevec[i][k]) ? c : ' ');
	putchar('\n');
	free(linevec[i]);
	}
    fflush(stdout);
    free(linevec);
    }

vecsize(points)
    int points;
    {
    }

vecmove(x, y)
    {
    oldx = x;
    oldy = y;
    scrx = x*COLS/1024;
    scry = (768-y)*ROWS/768;
    }

vecdraw(x, y)
    {
    int dx, dy, savex, savey, i, steps;
    char c;
    savex = oldx;
    savey = oldy;
    dx = x-oldx;
    dy = y-oldy;
    c = (abs(dx) > abs(dy)) ? '-' : '|';
    steps = MAX(MAX(abs(dx),abs(dy))/12, 1);
    for(i=0; i<=steps; i++)
	{
	vecmove(savex+i*dx/steps,savey+i*dy/steps);
	sym(c);
	}
    }

vecsyms(x, y, s)
    char *s;
    {
    char c;
    vecmove(x, y);
    while(c = *s++)
	{
	sym(c);
	scrx++;
	}
    }

vecmovedraw(x1, y1, x2, y2)
    {
    vecmove(x1, y1);
    vecdraw(x2, y2);
    }

drawP(x, y)
    {
    vecsyms(x, y, "P");
    }

drawstar(x, y, mag)
    {
    switch (mag)
	{
	case -1: draw0(x, y); break;
	case  0: draw0(x, y); break;
	case  1: draw1(x, y); break;
	case  2: draw2(x, y); break;
	case  3: draw3(x, y); break;
	case  4: draw4(x, y); break;
	default: draw5(x, y); break;
	}
    }

draw0(x, y)
    {
    vecsyms(x, y, "O");
    }

draw1(x, y)
    {
    vecsyms(x, y, "*");
    }

draw2(x, y)
    {
    vecsyms(x, y, "o");
    }

draw3(x, y)
    {
    vecsyms(x, y, "~");
    }

draw4(x, y)
    {
    vecsyms(x, y, ",");
    }

draw5(x, y)
    {
    vecsyms(x, y, ".");
    }

char overwrite(under, over)
    char under, over;
    {
    if (over == under) return(over);
    if (!under) return(over);
    if (!over) return(under);
    if (isspace(under)) return(over);
    if (isspace(over)) return(under);
    if (isalnum(under) && !isalnum(over)) return(under);
    if (!isalnum(under) && isalnum(over)) return(over);
    if ((under == '-') && (over == '|')) return('+');
    if ((under == '|') && (over == '-')) return('+');
    if ((under == '+') && (over == '-')) return('+');
    if ((under == '+') && (over == '|')) return('+');
    if ((under == '-') && (over == '+')) return('+');
    if ((under == '|') && (over == '+')) return('+');
    if ((under == ',') && (over == '.')) return(';');
    if ((under == '.') && (over == ',')) return(';');
    if ((under == '.') && (over == '.')) return(':');
    if ((under == '|') && (over == '.')) return('!');
    if ((under == '|') && (over == ',')) return('!');
    if ((under == '.') && (over == '|')) return('!');
    if ((under == ',') && (over == '|')) return('!');
    if ((under == '-') && (over == '~')) return('=');
    if ((under == '~') && (over == '-')) return('=');
    return(over);
    }

sym(c)
    char c;
    {
    if ( (scrx >= 0) && (scrx < COLS) && (scry >= 0) && (scry < ROWS) )
	linevec[scry][scrx] = overwrite(linevec[scry][scrx], c );
    }
@//E*O*F starchartdsp.c//
chmod u=rw,g=rw,o=r starchartdsp.c
 
echo x - starchartpic.c
sed 's/^@//' > "starchartpic.c" <<'@//E*O*F starchartpic.c//'
/*
 * Unix Pic file format driver for startchart.c mainline
 */

#include <stdio.h>
#include "starchart.h"

#define PICFRAG 8	/* split long "move,draw,...,draw" strings for pic */

/*
 * Chart parameters (limiting magnitude and window x,y,w,h)
 */

mapblock thumbnail =	{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
			3.2, 480, 0, 480, 240, 0.0 };

mapblock master =	{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
			8.0, 0, 370, 960, 960, 0.0 };

/*
 * Generic Star Drawing Stuff
 */

static int oldps, dcount;

#define PICSCALE (1.0/160.0) /* roughly 6.5/1024.0 */

float conv(i)
    {
    return(i*PICSCALE);
    }

vecsize(newps)
    int newps;
    {
    if (newps != oldps) printf("\n.ps %d", newps);
    oldps = newps;
    }

 vecopen()
   {
   printf(".nf\n.ll 6.75i\n.po 0.75i\n.RT\n.PS");
   vecsize(10);
   printf("\n.tl'Database: \\fIYale Star Catalog\\fP'\\s18\\fBStarChart\\fP\\s0'Software: \\fIAWPaeth@watCGL\\fP'");
   printf("\n.ll 7.25i");
   }

vecclose()
    {
    printf("\n.PE\n");
    fflush(stdout);
    }

vecmove(x, y)
    {
    dcount = 0;
    printf("\nline from %.3fi,%.3fi", conv(x), conv(y));
    }

vecdraw(x, y)
    {
    dcount++;
    printf(" to %.3fi,%.3fi", conv(x), conv(y));
    if (dcount > PICFRAG) vecmove(x,y);	/* must fragment long pic commands */
    }

vecsyms(x, y, s)
    char *s;
    {
    printf("\n\"\\ %s\" ljust at %.3fi,%.3fi", s, conv(x), conv(y));
    }

vecmovedraw(x1, y1, x2, y2)
    {
    vecmove(x1, y1);
    vecdraw(x2, y2);
    }

drawP(x, y)
    {
    vecsize(10);
    vecsyms(x, y, "P");
    }

drawstar(x, y, mag)
    {
    switch (mag)
	{
	case -1: draw0(x, y); break;
	case  0: draw0(x, y); break;
	case  1: draw1(x, y); break;
	case  2: draw2(x, y); break;
	case  3: draw3(x, y); break;
	case  4: draw4(x, y); break;
	default: draw5(x, y); break;
	}
    }

vecsymcen(x, y, s)
    char *s;
    {
    printf("\n\"%s\" at %.3fi,%.3fi", s, conv(x), conv(y));
    }

draw0(x, y)
    {
    vecsize(18);
    vecsymcen(x, y, "\\o'\\(bu+'");
    }

draw1(x, y)
    {
    vecsize(16);
    vecsymcen(x, y, "\\(bu");
    }

draw2(x, y)
    {
    vecsize(12);
    vecsymcen(x, y, "\\o'\\(bu+'");
    }

draw3(x, y)
    {
    vecsize(10);
    vecsymcen(x, y, "\\(bu");
    }

draw4(x, y)
    {
    vecsize(8);
    vecsymcen(x, y, "\\o'\\(bu+'");
    }

draw5(x, y)
    {
    vecsize(6);
    vecsymcen(x, y, "\\(bu");
    }
@//E*O*F starchartpic.c//
chmod u=rw,g=rw,o=r starchartpic.c
 
echo x - starcharttek.c
sed 's/^@//' > "starcharttek.c" <<'@//E*O*F starcharttek.c//'
/*
 * Tektroniks driver for startchart.c mainline
 */

#include <stdio.h>
#include "starchart.h"

/*
 * Chart parameters (limiting magnitude and window x,y,w,h)
 */

mapblock thumbnail =	{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
			3.2, 420, 35, 480, 195, 0.0 };

mapblock master =	{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
			8.0, 20, 265, 880, 500, 0.0 };

/*
 * Generic Star Drawing Stuff
 */

vecopen()
   {
   tekclear();
   }

vecclose()
    {
    tekmove(0,0);
    tekalpha();
    fflush(stdout);
    }

vecsize(points)
    int points;
    {
    }

vecmove(x, y)
    {
    tekmove(x, y);
    }

vecdraw(x, y)
    {
    tekdraw(x, y);
    }

vecsym(x, y, s)
    char s;
    {
    tekmove(x, y-11); /* center character strings */
    tekalpha();
    printf("%c",s);
    }

vecsyms(x, y, s)
    char *s;
    {
    tekmove(x, y-11); /* center character strings */
    tekalpha();
    printf(s);
    }

vecmovedraw(x1, y1, x2, y2)
    {
    tekmove(x1, y1);
    tekdraw(x2, y2);
    fflush(stdout);
    }

#define XSCALE 15/8
#define YSCALE 8/5
#define XSCALEI 8/15
#define YSCALEI 5/8

drawlen(x, y, dx, dy, len)
    {
    vecmovedraw((x*XSCALEI+dx)*XSCALE, (y*YSCALEI+dy)*YSCALE,
	(x*XSCALEI+dx+len-1)*XSCALE+1, (y*YSCALEI+dy)*YSCALE);
    }

drawP(x, y)
    {
    drawlen(x, y, -1, -2, 3); /*   ***   */
    drawlen(x, y, -2, -1, 1); /*  *   *  */
    drawlen(x, y,  2, -1, 1);
    drawlen(x, y, -2,  0, 1); /*  * * *  */
    drawlen(x, y,  0,  0, 1);
    drawlen(x, y,  2,  0, 1);
    drawlen(x, y, -2,  1, 1); /*  *   *  */
    drawlen(x, y,  2,  1, 1);
    drawlen(x, y, -1,  2, 3); /*   ***   */
    }

drawstar(x, y, mag)
    {
    switch (mag)
	{
	case -1: draw0(x, y); break;
	case  0: draw0(x, y); break;
	case  1: draw1(x, y); break;
	case  2: draw2(x, y); break;
	case  3: draw3(x, y); break;
	case  4: draw4(x, y); break;
	default: draw5(x, y); break;
	}
    }

draw0(x, y)
    {
    drawlen(x, y, -2, -3, 5); /*   *****   */
    drawlen(x, y, -3, -2, 7); /*  *******  */
    drawlen(x, y, -3, -1, 3); /*  *** ***  */
    drawlen(x, y,  1, -1, 3); /*  **   **  */
    drawlen(x, y, -3,  0, 2); /*  *** ***  */
    drawlen(x, y,  2,  0, 2); /*  *******  */
    drawlen(x, y,  1,  1, 3); /*   *****   */
    drawlen(x, y, -3,  1, 3);
    drawlen(x, y, -3,  2, 7);
    drawlen(x, y, -2,  3, 5);
    }

draw1(x, y)
    {
    drawlen(x, y, -1, -2, 3); /*   ***   */
    drawlen(x, y, -2, -1, 5); /*  *****  */
    drawlen(x, y, -2,  0, 5); /*  *****  */
    drawlen(x, y, -2,  1, 5); /*  *****  */
    drawlen(x, y, -1,  2, 3); /*   ***   */
    }

draw2(x, y)
    {
    drawlen(x, y,  0, -2, 1); /*    *    */
    drawlen(x, y, -1, -1, 3); /*   ***   */
    drawlen(x, y, -2,  0, 5); /*  *****  */
    drawlen(x, y, -1,  1, 3); /*   ***   */
    drawlen(x, y,  0,  2, 1); /*    *    */
    }

draw3(x, y)
    {
    drawlen(x, y, -1, -1, 3); /*   ***   */
    drawlen(x, y, -1,  0, 3); /*   ***   */
    drawlen(x, y, -1,  1, 3); /*   ***   */
    }

draw4(x, y)
    {
    drawlen(x, y,  0, -1, 1); /*    *    */
    drawlen(x, y, -1,  0, 3); /*   ***   */
    drawlen(x, y,  0,  1, 1); /*    *    */
    }

draw5(x, y)
    {
    drawlen(x, y,  0,  0, 1); /*    *    */
    }

/*
 * Low Level Tektronix Plotting Routines
 */

#define	GS	035
#define	US	037
#define ESC	033
#define FF	014

static int oldHiY = 0, oldLoY = 0, oldHiX = 0;

tekplot()	/* switch to plot mode */
    {
    putchar(GS);
    putchar('@');
    oldHiY = oldLoY = oldHiX = 0;
    }

tekalpha()	/* switch to alpha mode */
    {
    putchar(US);
    fflush(stdout);
    }

tekclear()
    {
    putchar(ESC);
    putchar(FF);
    fflush(stdout);
    }

tekmove(x, y)	/* move to (x,y) */
    {
    putchar(GS);
    tekdraw(x, y);
    }

tekdraw(x, y)	/* draw to (x,y) */
    {
    int hiY, loY, hiX, loX;
    if (x < 0) x = 0;
    if (y < 0) y = 0;
    if (x > 1023) x = 1023;
    if (y > 767) y = 767;

    hiY = 0040 | (y>>5 & 037),
    loY = 0140 | (y    & 037),
    hiX = 0040 | (x>>5 & 037),
    loX = 0100 | (x    & 037);

    if (hiY != oldHiY) putchar(hiY);
    if (loY != oldLoY || hiX != oldHiX) putchar(loY);
    if (hiX != oldHiX) putchar(hiX);
    putchar(loX);

    oldHiY = hiY;
    oldLoY = loY;
    oldHiX = hiX;
    }
@//E*O*F starcharttek.c//
chmod u=rw,g=rw,o=r starcharttek.c
 
exit 0