v13i025: Starchart package, Patch2

Rich Salz rsalz at bbn.com
Tue Feb 9 07:25:45 AEST 1988


Submitted-by: "Alan W. Paeth" <awpaeth at watcgl.waterloo.edu>
Posting-number: Volume 13, Issue 25
Archive-name: starchart/patch2

[  The starchart software was posted in Volume 12.  **MAKE SURE TO UNPACK
   THIS IN A SEPARATE DIRECTORY or you will wipe out existing files!**  --r$ ]

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# Contents:  starchart.1 starchart.c starchart.h stariris.c staruplot.c
 
echo x - starchart.1
sed 's/^@//' > "starchart.1" <<'@//E*O*F starchart.1//'
@.TH STARCHART LOCAL 9/22/87
@.SH NAME
stardsp, starpic, starpost, staruplot, startek, stariris, starhp, starlaser \- print astronomical star charts using Yale database.
@.SH SYNOPSIS
@.B star*
RA DE [ scale title maglim lbllim ]
@.br
or
@.br
@.BI \-c\  constellation ...
@.br
or
@.br
@.BI \-r\  Ra
@.BI \-d\  Dl
[
@.BI \-s\  scale
@.BI \-t\  title
@.BI \-m\  maglim
@.BI \-l\  lbllim
@.BI \-g\  grklim
@.BI \-a\  (annotate)
@.BI \-o\  (objects)
@.BI \-b\  (bigchart)
@.BI \-f\  ephem.star...
@.BI \-y\  yale.star
@.BI \-n\  messier.star
@.BI \-w\  planet.star
]
@.SH DESCRIPTION
These programs generate star charts based on data extracted from the Yale
public domain star catalog.
Output is to the terminal 
@.RI ( stardsp ),
Unix PIC file format
@.RI ( starpic ),
PostScript format
@.RI ( starpost ),
Unix Plot(5) format
@.RI ( staruplot ),
Tektronix vector format
@.RI ( startek ),
Silicon Graphics Iris format
@.RI ( stariris ),
Hewlett-Packard terminal vector format
@.RI (starhp)
or in Hewlett-Packard Laserjet printer format
@.RI ( starlaser ).
@.PP
Star data is optionally overlayed with other cosmic objects, such as planets.
If limiting magnitudes are properly set and the Messier database is available,
Messier objects and some NGC objects are also printed.
@.PP
The starchart center is specified by two parameters: Right
Ascension [0.00 to 24.00 hours] and Declination [-90.00 to +90.00 degrees].
An optional third parameter defines the N/S range of the output window, in
degrees of declination.  Digits after decimal point are taken as minutes:
object positions can therefore be taken directly from a star catalog.
@.PP
An optional fourth parameter gives a title.
This conforms to the 'old' Yale star chart format.
Two new parameters can be added after title,
defining the magnitude limit and label printing magnitude limit.
These are discussed below.
All parameters can be given by using options,
which offers more flexibility.
Parameters are:
@.TP
@.B \-r
Right ascension.
@.TP
@.B \-d
Declination.
@.TP
@.B \-s
Scale.
@.TP
@.B \-t
Title. All these work as described above. Additional switches:
@.TP
@.B \-m
Star limiting magnitude. This sets limits on the faintest stars displayed
on the ``master'' view. Default limits are device driver dependent (more below).
The ``thumbnail'' finder view is set to a related limit.
@.TP
@.B \-l
Label limiting magnitude. The new Yale database contains both a small set of
familiar names (for stars and special objects), plus an extensive list of
labels (Greek Bayer letter or Flamsteed numbers). Star names (including planet
names) always print for this small set. To avoid clutter, the labels may be
omitted below a cut-off magnitude by specifying this value.
@.TP
@.B \-g
Greek/Flamsteed annotation magnitude. Labels printed for stars dimmer than
this value will use a Bayer or numerical label in favor of a proper name.
The default (2.05) includes nearly all well-known proper names including
Polaris, and excludes but a small number (such as Algol). Large values
generate charts full of obscure Arabian names, small (zero or negative) values
produce non-verbose charts, eg. ``a'', in Greek where possible, instead of
``Sirius''.
@.TP
@.B \-c
A three or four character mnemonic follows, which is a search string for a
matching line-item entry in the file
@.IR con.locs .
If found, then the
initial values for Ra, Decl, Scale and Title are taken from that file.
Because the command line is parsed from left to right, subsequent switches
might change the scale, title, or otherwise fine-tune the new defaults.
@.TP
@.B \-f
A list of files follow, each containing ephemerides in the .star format, which
will overlay the output. This is also useful for generating constellation
boundaries, Milky Way isophots, and planet or satellite tracks. (The .star
format additionally includes records for vector and text annotation). Files
are processed sequentially. Thus, order may take on meaning for devices which
provide a 2-1/2D page description, such as PostScript.
@.TP
@.B \-b
This switch provides a single full-page of output, without a thumbnail-sized
finder chart. The legend placard is replaced with a single line banner giving
title, right ascension, declination and limiting magnitude. This mode is
useful for the construction of atlas pages. Because the page depicts the same
vertical scale in degrees of declination, the output will cover a slightly
reduced extent in right ascention.
@.TP
@.B \-a
This switch provides annotation-only (text) output: all stars and non-stellar
objects are omitted (including objects normally rendered by using alpha
characters). Borders and legends are left undisturbed. This feature is useful
in separating output detail, as when making (color) overhead transparencies.
@.TP
@.B \-o
This switch provides object-only output, and is the complement of the
above switch. When both switches appear together, all output is displayed.
This resembles the default case (neither switch), except in that case object
and annotation detail are written together. Here the software makes two
consecutive passes through all datasets and arranges output detail to be
written with all cosmic objects prefacing all related text annotations.
This is useful in providing data for PostScript files in which rendering
happens in a 2-1/2D back-to-front order, thus providing for a cleaner
overlaying of output.
@.TP
@.B \-y \-w \-p
These switches allow for the redefinition of the files yale.star, messier.star
and planet.star, respectively.
@.PP
@.SH OUTPUT
The 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.
In all cases, the output is annotated with viewport boundaries, a legend and
axis labels. Variations are described for the
@.B \-a \-o
and
@.B -b
switches, above.
@.PP
Objects are drawn in glyphs defined by each display driver. Vector-only
devices rely on the parent module ``starimages.c'' to provide shape tables;
other devices plot special characters (stardsp or starpic) or private symbols
(PostScript). The latter additionally provides distinctions between object
subclasses, e.g. planetary vs diffuse nebula. The code provides for this
generally, creation of new glyphs.
@.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 EXAMPLES 
@.nf
# Sagittarius: a nice bunch of Messier objects.
starpost -c sgr -a -o -t Sagittarius >sag.ps
@.sp
# Orion: the belt lies near 5h40m in RA, just below the CE.
stardsp 5.32 -5 12 "Trapezium (Orion)" 8 5 | more
@.fi
@.SH FILES
@.nf
@.ta \w'messier.star    'u
yale.star	stellar information (mandatory)
messier.star	Messier objects (optional)
planet.star	Planets (optional)
con.locs	default mnemonic locations
@.fi
@.br
@.sp
These default paths can be easily changed in the Makefile.
@.SH BUGS
The present implementation expects
@.I 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 might be more appropriate.
No cutoff is performed for other .star files.
@.PP
If <minutes> part of the parameters is greater than 59 it is silently
truncated to 59.
@.PP
All .star file coordinates are for epoch E2000.0.
The Messier objects in
@.I messier.star
were taken from precessed E1975.0 data.
The additional NGC objects were taken from data in the star atlas by
@.I Norton
and precessed from E1950.0.
Descriptions and accurate magnitude values of all Messier objects were taken
from the 1988 edition of the Royal Astronomical Society of Canada (RASC)
handbook.
@.SH FUTURE EXTENTIONS
A
@.B \-p
switch will provide polar plotting; early code attempts using Stereographic
projection have lacked the ability to draw the horizon lines and tick
marks correctly. This and other extensions are discussed at the end of
``starchart.c'', and is suggested reading for anyone wishing to enhance
the software.
@.SH AUTHOR/EDITOR
Alan Paeth, University of Waterloo (AWPaeth at watCGL)
@.SH MAJOR CONTRIBUTORS
Petri Launiainen (pl at intrin.FI)
@.br
Jyrki Yli-Nokari (jty at intrin.FI)
@.br
Robert Tidd (inp at violet.berkeley.edu)
@.br
Craig Counterman (ccount at royal.mit.edu)
@//E*O*F starchart.1//
chmod u=r,g=r,o=r starchart.1
 
echo x - starchart.c
sed 's/^@//' > "starchart.c" <<'@//E*O*F starchart.c//'
/*
 * starchart.c -- version 2, September 1987
 *		revision 2.1 December, 1987
 *
 * (c) copyright 1987 by Alan Paeth (awpaeth at watcgl)
 */

/*
 ! Version 2 modification authors:
 !
 !   [a] Petri Launiainen, pl at intrin.FI (with Jyrki Yli-Nokari, jty at intrin.FI)
 !   [b] Bob Tidd, inp at VIOLET.BERKELEY.EDU
 !   [c] Alan Paeth, awpaeth at watcgl
 !
 ! Changes and Additions:
 !
 !a   [1] STARFILE, PLANETFILE, etc. path designations are now in the Makefile
 !ac  [2] Fractional Ra and Decl values are now hh.mm and mm.ss (base 60)
 !a   [3] Command syntax now allows flags as well as old style (arg placement)
 !ab  [4] Extended Yale database (courtesy B. Tidd) also supported on input
 !bc  [5] Greek+Flamsteed numbers now appear as a hardcopy annotation
 !bc  [6] Constellation file finds ra,dl,scale from command line pattern
 !c   [7] New symbols for Nebulae, Galaxies and Clusters added (based on [4])
 !c   [8] Double star indications added (provisions for variable stars) ([4])
 !a   [9] Limiting magnitude flags for stars and labels allowed
 !c  [10] Legend column reformatted to contain additional symbols [4]
 !a  [11] Internal symbol compiler created for raster glyph creation
 !c  [12] add Yale records for "moveto"/"drawto" and text annotations
 !c  [13] added -f file.star to add ephemeride data
 !
 ! Bug Fixes:
 !
 !a   [1] no more core dumps (on SysV) when given bad command line parameters
 !c   [2] Negative RA indications now "wrap" to 24hrs, etc.
 !bc  [3] Mag values *rounded* to nearest unit value (common Atlas convention)
 !c   [4] Removed any device dependent subroutines (eg. getopt).
 !
 ! Final integration by the original author [c].
 ! Questions, suggestions, and fixes should be e-mailed to him.
 */

 /* Version 2.1 patches
 !
 ! patched December, 1987 by Alan Paeth (awpaeth at watcgl),
 ! based on revisions by Craig Counterman (ccount at royal.mit.edu)
 ! et al.
 !
 ! [1] clipping of scaling, ra and decl now takes place
 ! [2] negative magnitude bug fixed; plus format change to yale.star
 ! [3] string arrays ras[2] changed to ras[20] (typo in "chartlegend()")
 ! [4] scanf now uses %f and floats exclusively (for IRIS and sysV)
 ! [5] bigmaster facility added for full-page output
 ! [6] multiple .star files now accepted by -f flag
 ! [7] the -y flag allows overriding of default yale.star dataset
 ! [8] the -n flag allows overriding of default messier.star dataset
 ! [9] the -w flag allows overriding of default planet.star dataset
 ![10] the -a and -o flags allow for separate/sorted object/annotation detail
 ![11] the -g flag sets a mag limit for star proper names, else use codes
 */

#include <stdio.h>
#include <math.h>
#ifndef SYSV
#include <strings.h>
#else
#include <string.h>
#endif
#include <ctype.h>
#include "starchart.h"

/*
 * default datasets are local, unless defined in Makefile
 */

#ifndef STARFILE
#define STARFILE	"./yale.star"
#endif

#ifndef PLANETFILE
#define PLANETFILE	"./planet.star"
#endif

#ifndef MESSFILE
#define MESSFILE	"./messier.star"
#endif

#ifndef CONSTFILE
#define CONSTFILE	"./con.locs"
#endif


#define DCOS(x) (cos((x)*3.14159265354/180.0))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define FALSE 0
#define TRUE 1

#define MAXUFILES 10	/* Maximum number of user supplied files */
#define THUMBDIFF 2.5	/* thumbnail mag lim is brighter */
#define THUMBMAX 5.0	/* but no lower than this value */
#define THUMBRATIO 1.2	/* and scaled by this size (yet is already wider) */
#define THUMBDEG 10.0	/* but this is the floor on finder scale */
#define FSIZESML 8	/* point size for star designation */
#define FSIZELRG 10	/* point size for other object annotations */

float max(), modup(), moddown();
float ftod(), htod();
/* double atof(); */		/* possible system compatability problem */

/* globals */

char *progname;			/* program name for errors */
float ra, de, sc;		/* global chart attributes */
char *title;
char *starfile = STARFILE;
char *planetfile = PLANETFILE;
char *messfile = MESSFILE;
char *constfile = CONSTFILE;
char *userfile[MAXUFILES];	/* potential .star file of user ephemerides */
int nufiles = 0;		/* number of userfiles */
int bigflag = FALSE;		/* chart page only, no thumbnail or legend */
int annodetail, objdetail;	/* flags to control output */
int annoswitch, objswitch;	/* switches as seen on command line */
float olat, olon;		/* save areas for track clipping */		

/* the code */

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

    commandline(argc, argv);
/*
 * copy command line defaults into all possible charts
 */
    thumbnail.lbllim = bigmaster.lbllim = master.lbllim;
    thumbnail.maglim = bigmaster.maglim = master.maglim;
    thumbnail.gklim = bigmaster.gklim  = master.gklim;
/*
 * drawing order:
 *
 * (1) chart outlines
 * (2) stars a/o
 * (3) annotations
 * (4) legend
 */
    vecopen();
    chartparms(&master, sc);
    chartparms(&bigmaster, sc);
/*
 * thumbnail gets fine-tuned scale and brighter limiting magnitude
 */
    chartparms(&thumbnail, MAX(sc * THUMBRATIO, THUMBDEG));
    thumbnail.maglim = MIN(THUMBMAX, master.maglim - THUMBDIFF);
/*
 * background stuff
 */
    annodetail = TRUE;		/* no omissions on background */
    objdetail = TRUE;
    if (bigflag) chartbackground(&bigmaster);
    else
	{
	chartbackground(&master);
	chartbackground(&thumbnail);
	}
/*
 * main drawing
 */
    chartpasses = (annoswitch && objswitch) ? 2 : 1;
    if (!annoswitch && !objswitch) annoswitch = objswitch = TRUE; /* default */
    for(chartcount=0; chartcount<chartpasses; chartcount++)
	{
/*
 * set detail control flags from command line switches and pass number
 */
	annodetail = annoswitch;
	objdetail =  objswitch;
	if ((chartpasses == 2) && (chartcount == 0)) annodetail = FALSE;
	if ((chartpasses == 2) && (chartcount == 1)) objdetail = FALSE;
/*
 * drawing
 */
	if (bigflag) chartall(&bigmaster);
	else
	    {
	    chartall(&master);
	    chartall(&thumbnail);
	    }
/*
 * (mini)legend
 */
	annodetail = TRUE;	/* legend has no omissions */
	objdetail = TRUE;
	if (bigflag) chartbanner(&bigmaster);
	else chartlegend(&master);
	}
    vecclose();
    exit(0);
    }

commandline(argc, argv)
    char *argv[];
    {
    int j;
    static char *usage =
"\nusage:\tstar* [ Ra Dcl Scale Title Maglim Labellim ]\nor\tstar* [ -r Ra -d Dcl -s Scale -t Title -m Maglim -l Labellim -f x.star ]\nor\tstar*  [ -c con (3 or 4 letters chosen from con.locs) -l ... ]";
    progname = argv[0];
    title = NULL;
    annoswitch = objswitch = FALSE;
    ra = 0.0;
    de = 0.0;
    sc = 0.0;
/*
 * check command line style
 */
    if (argc == 1) die("No arguments - %s", usage);
    if  ( (argv[1][0] == '-') && isalpha(argv[1][1]) )
	{
/*
 * new style command line (using flags)
 */
	for (j=1; j<argc; j++)
	    {
	    if (argv[j][0] != '-') die("unknown argument - %s", argv[j]);
	    switch (argv[j][1])
		{
		case 'c':	/* could be -c con or -c con con.locs */
		    if (((j+2) < argc) && (argv[j+2][0] != '-'))
			{
			constfile = argv[j+2];
			findconst(argv[++j]);
			j++;
			}
		    else findconst(argv[++j]);
		    break;
		case 'r': ra = htod(argv[++j]); break;
		case 'd': de = htod(argv[++j]); break;
		case 's': sc = atof(argv[++j]); break;
		case 'l': master.lbllim = (float)(atof(argv[++j])); break;
		case 'm': master.maglim = (float)(atof(argv[++j])); break;
		case 'g': master.gklim  = (float)(atof(argv[++j])); break;
		case 't': title = argv[++j]; break;
		case 'f': userfile[nufiles++] = argv[++j];
			  if (nufiles >= MAXUFILES) die("too many -f files");
			  break;
		case 'u': die("%s", usage); break;
		case 'y': starfile = argv[++j]; break;
		case 'n': messfile = argv[++j]; break;
		case 'w': planetfile = argv[++j]; break;
/*		case 'p': polarmode = TRUE; break; */	/* someday! */
		case 'b': bigflag = TRUE; break;
		case 'a': annoswitch = TRUE; break;
		case 'o': objswitch = TRUE; break;
		default:  die("unknown switch - %s", argv[j]); break;
		}
	    if (j == argc) die("trailing command line flag - %s", argv[j-1]);
	    }
	}
    else
	{
/*
 * old style command line (position dependent)
 */
	switch (argc)
	    {
	    case 7: master.maglim = atof(argv[6]);
	    case 6: master.lbllim = atof(argv[5]);
	    case 5: title = argv[4];
	    case 4: sc = atof(argv[3]);
	    case 3: de = htod(argv[2]);
	    case 2: ra = htod(argv[1]); break;
	    default: die("too many arguments - %s", usage);
	    }
	}
    }

float ftod(x)
    float x;
    {
    int full;
    full = x;
    return(full + (x-full)*100.0/60.0);
    }

float htod(s)
    char *s;
    {
/*
 * htod(str) reads floating point strings of the form {+-}hh.{mm} thus
 * allowing for fractional values in base 60 (ie, degrees/minutes).
 */
/*
    float x, sign;
    int full, frac;
    char *t;
    t = s-1;
    while(*++t)
	{
	if ((*t == ' ') || (*t = '\t') || (*t == '\n')) break;
	if ( ( (*t<'0') || (*t>'9') ) && (*t!='.') && (*t!='+') && (*t!='-'))
	    die("non-digit in dd.mm style numeric argument: %s", s);
	}
    if (s == NULL) return 0.0;
    full = frac = 0;
    sign = 1.0;
    if (*s == '-')
	{
	sign = -1.0;
	s++;
	}
    else if (*s == '+') s++;
    while (*s && *s != '.') full = 10 * full + *s++ - '0';
    if (*s++ == '.')
	{
	if (*s) frac = 10 * (*s++ - '0');
	if (*s) frac += *s++ - '0';
	if (frac > 59) frac = 59;
	}
    x = (float) full + ((float) frac) / 60.0;
    return sign * x;
*/
    return(ftod(atof(s)));
    }

chartparms(chart, scl)
    float scl;
    map chart;
    {
    float maxdl, adj, xscale;
/*
 * check for bogus ra or decl
 */
    if ((ra >= 24.0) || (ra <    0.0)) die("right ascension out of range");
    if ((de >= 90.0) || (ra <= -90.0)) die("declination out of range");
/*
 * record chart location
 */
    chart->racen = ra * 360.0 / 24.0;
    chart->dlcen = de;
    chart->scale = scl;
    if (chart->scale == 0.0) chart->scale = 15.0;
/*
 * check for pole wrapping and do a potential clip
 */
    maxdl = (90.0 - chart->dlcen)*2.0;
    if (chart->scale > maxdl) chart->scale = maxdl;
/*
 * locate chart limits
 */
    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)
    map chart;
    {
    char ras[20], dls[20], outstr[40];
    if (!title) title = "LEGEND";
    rastr(ras, chart->racen);
    declstr(dls, chart->dlcen);
    sprintf(outstr, "(%s,%s lim: %2.1f)", ras, dls, chart->maglim);
/*
 * there are reports that large point sizes (eg "16", below) cause characters
 * to overlap on some (pic?) output devices. To fix, set values to "10".
 */
    pvecsize(16); pvecsyms(65, 220, title);
    pvecsize(10); pvecsyms(65, 185, outstr);

    pdrawStar( 65, 150, 0, 'S', NULL);
    pvecsize(12);
    pvecsyms(  95, 150,"<0.5");
    if (chart->maglim >= 0.5)
	{
	pdrawStar(230, 150, 1, 'S', NULL);
	pvecsize(10);
	pvecsyms( 260, 150,"<1.5");
	}
    if (chart->maglim >= 1.5)
	{
	pdrawStar( 65, 125, 2, 'S', NULL);
	pvecsize( 9);
	pvecsyms(  95, 125,"<2.5");
	}
    if (chart->maglim >= 2.5)
	{
	pdrawStar(230, 125, 3, 'S', NULL);
	pvecsize( 8);
	pvecsyms(260, 125,"<3.5");
	}
    if (chart->maglim >= 3.5)
	{
	pdrawStar( 65, 100, 4, 'S', NULL);
	pvecsize( 7);
	pvecsyms(  95, 100,"<4.5");
	}
    if (chart->maglim > 4.5)
	{
	pdrawStar(230, 100, 5, 'S', NULL);
	pvecsize( 6);
	pvecsyms(260, 100,">4.5");
	}

    pvecsize(10); pvecsyms( 95,75,"double");   pdrawStar( 65,75, 2, 'D', NULL);
    pvecsize(10); pvecsyms(260,75,"variable"); pdrawStar(230,75, 2, 'V', NULL);
    pvecsize(10); pvecsyms( 95,50,"planet");   pdrawPlan( 65,50, 1, 'S', NULL);
    pvecsize(10); pvecsyms(260,50,"galaxy");   pdrawGalx(230,50, 1, 'E', NULL);
					       pdrawGalx(205,50, 1, 'S', NULL);
    pvecsize(10); pvecsyms( 95,25,"nebula");   pdrawNebu( 65,25, 1, 'D', NULL);
					       pdrawNebu( 40,25, 1, 'P', NULL);
    pvecsize(10); pvecsyms(260,25,"cluster");  pdrawClus(230,25, 1, 'O', NULL);
					       pdrawClus(205,25, 1, 'G', NULL);
    }

chartbanner(chart)
    map chart;
    {
    char ras[20], dls[20], outstr[100];
    if (!title) title = "LEGEND";
    rastr(ras, chart->racen);
    declstr(dls, chart->dlcen);
    pvecsize(8);
    sprintf(outstr, "%s: %s,%s lim: %2.1f", title, ras, dls, chart->maglim);
    pvecsyms(15, 15, outstr);
    }

readstar(file, lat, lon, mag, code, subcode, color, label, name)
    FILE *file;
    float *lat, *lon, *mag;
    char *code, *subcode, *color, *label, *name;
    {
#define LINELEN 80
    char sbuf[LINELEN+1], *ptr;
    float rah, ram, ras, dld, dlm, dl, inten;
    int len, i;
/*
 * file formats:
 * new
064509-1643-14SDA1a CMASirius
051432-0812015SDB8b ORIRigel
 * old
064509-1643-146SSSirius
051432-08120015SSRigel
 */
    fgets(sbuf, LINELEN, file);
    if (feof(file)) return(1);
/*
 * sscanf of floats is TOOO slow:
 *     sscanf(sbuf, "%2f%2f%2f%c%2f%2f ... );
 * use alternate:
 */
#define F2(i) ((float)((sbuf[i]-'0')*10+sbuf[i+1]-'0'))
#define F3(i) ((float)((sbuf[i]-'0')*100+(sbuf[i+1]-'0')*10+sbuf[i+2]-'0'))
#define F4(i) ((float)((sbuf[i]-'0')*1000+(sbuf[i+1]-'0')*100+(sbuf[i+2])-'0')*10+sbuf[i+3]-'0')
    rah = F2(0);
    ram = F2(2);
    ras = F2(4);
    dld = F2(7);
    dlm = F2(9);
/*
 * common code
 */
#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;
    if  (isdigit(sbuf[14]))
	{
/*
 * old reduced Yale catalog
 */
	inten = F3(12);
	if (sbuf[11] == '0' || sbuf[11] == '+') *mag = inten/100.0;
	else if (sbuf[11] == '-') *mag = -inten/100.0;
	else *mag = F4(11)/1000.0;	/* new feature for stars >= 10.0 mag */
	if (sbuf[11] != 0)
	code[0] = sbuf[15];
	subcode[0] = sbuf[16];
	color [0] = '\0'; strcpy (color, "  "); /* set unknowns to blanks */
	label [0] = '\0';
	name [0] = '\0'; strncat (name, &sbuf[17], strlen (&sbuf [17]) - 1);
	}
    else
	{
/*
 * new reduced Yale catalog
 */
	*mag = ((sbuf[11] == '-') ? -F2(12)/10.0 : F3(11))/100.0;
	code[0] = sbuf[14];	/* let's get Sirius */
	subcode[0] = sbuf[15];
	color [0] = '\0';
	label [0] = '\0';
	name [0] = '\0';
	switch (code[0])
	    {
	    case 'C':
	    case 'N':
	    case 'G':
/*
 * name vs label:
 *
 * A "name" is a common English term for a star or cosmic object (eg Polaris,
 * Pleiades). A label is an official designation for such an object (eg
 * alpha-Ursa Minor, M45). For stars, labels are taken from the two column
 * Bayer/Flamsteed field in the new reduced label format and the proper name
 * from the "name" field (the label field might also include the three letter
 * IAU constellation designation, but at present these are ignored)
 *
 * For non-stellar objects, the Bayer and IAU fields are typically blank (and
 * always ignored), and the "name" field consists of the designation followed
 * by an optional proper name, or perhaps just an annotation, the latter
 * flagged by a leading "," and ignored by the software. For instance, the
 * entry "m45 Pleiades" forms a label "m45" and a name "Pleiades", but the
 * entry "m6  ,butterfly shape" forms merely the label "m6".
 *
 * At the present, the charting software which is supplied this data on a call
 * to "readstar" will print names in favor of labels.
 */
/*
 * extract Messier number and name
 */
		strcpy (color, "  ");
		ptr = &sbuf[23];
		i = 0;
		while (isalnum (*ptr)) label[i++] = *ptr++;

		label[i] = '\0';
		i = 0;
		while (*ptr == ' ') ptr++;
		while (*ptr != ',' && *ptr != '\n' && *ptr)
		    name[i++] = *ptr++;
		name[i] = '\0';
		break;
	default:
/*
 * extract color, label and name
 */
		strncat (color, &sbuf[16], 2);
		strncat (label, &sbuf[18], strlen (&sbuf [18]) - 1);
		if  ((len = strlen (label)) > 5)
			{
			strncat (name, &label[5], len - 5);
			label [5] = '\0';
			}
	    }
	}
    return(0);
    }

xform(chart, lat, lon, xloc, yloc)
    map chart;
    float 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;
    {
/*
 * we might "die" after drawing the borders, but we want stars to overlay
 * the border for imaging software which may handle the bottom-up 2-1/2D
 * order of printing correctly (eg PostScript).
 */
    int i;
    if (!chartfile(chart, starfile)) die("open fail on %s", starfile);
    chartfile(chart, planetfile);
    chartfile(chart, messfile);
    for (i = 0; i < nufiles; i++)
	{
	if (!chartfile(chart,userfile[i])) die("open fail on %s", userfile[i]);
	}
    }

chartfile(chart, filename)
    map chart;
    char *filename;
    {
#define READMODE "r"
#define OPENFAIL 0
    FILE *sfile;
    if ((sfile = fopen(filename, READMODE)) == OPENFAIL) return(0);
    chartobjects(chart, sfile);
    fclose(sfile);
    return(1);
    }

chartobjects(chart, file)
    map chart;
    FILE *file;
    {
    float lat, lon, mag;
    char code[1], subcode[1], label[100], name [100], color [3], *ptr;
    int xloc, yloc, staronly, smallflag, vecmode, gkflag;

    for(;;)
	{
	if (readstar(file,&lat,&lon,&mag,code,subcode,color,label,name)) break;
	if ((mag > chart->maglim) && (code[0] == 'S')) 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) &&
	       (mag <= chart->maglim) )
	    || (code[0] == 'V') )	/* no spatial preclip on vector data */
	    {
	    xform(chart, lat, lon, &xloc, &yloc);
	    smallflag = vecmode = staronly = gkflag = 0;
	    switch(code[0])
		{
    case 'S':	pdrawStar(xloc,yloc,(int)(mag+0.5),subcode[0],color);
		staronly = 1;
		break;
    case 'P':	pdrawPlan(xloc, yloc,(int)(mag+0.5),subcode[0],color);
		break;
    case 'N':	pdrawNebu(xloc, yloc,(int)(mag+0.5),subcode[0],color);
		break;
    case 'G':	pdrawGalx(xloc, yloc,(int)(mag+0.5),subcode[0],color);
		break;
    case 'C':	pdrawClus(xloc, yloc,(int)(mag+0.5),subcode[0],color);
		break;
    case 'I':	break;		/* invisible */
    case 'V':	vecmode = 1;	/* vector: check subcodes */
		if (subcode[0] == 'M') /* move */
		    {
		    olat = lat;
		    olon = lon;
		    }
		else			/* draw */
		    {
		    float lat1, lon1, lat2, lon2;
		    if (clip(chart->north, chart->south, chart->west,
				chart->east, olon, olat, lon, lat,
				&lon1, &lat1, &lon2, &lat2))
			{
			xform(chart, lat1, lon1, &xloc, &yloc);
			pvecmove(xloc, yloc);
			xform(chart, lat2, lon2, &xloc, &yloc);
			switch (subcode[0])
			    {
		case 'D':   pvecdrawdot(xloc, yloc); break;
		case 'H':   pvecdrawhyph(xloc,yloc); break;
		case 'S':   /* solid */
		default:    pvecdraw(xloc, yloc); break;
			    }
			}
		    olat = lat;
		    olon = lon;
		    }
		break;
		}
/*
 * pick up object name or label if (star<limit), (nonstar), and (not vector)
 */
	    if (((mag < chart->lbllim) || !staronly) && !vecmode)
		{
		ptr = NULL;
/*
 * if star is too "dark", mask off any proper name, so only label can appear.
 */
		if (staronly && (mag > chart->gklim)) *name = '\0';
/*
 * choose any proper name in favor of label
 */
		if (*name != '\0') ptr = name;
		else if (*label != '\0')
		    {
		    ptr = label;
			{
			if (staronly)	/* star: Gk char(s) or Roman digits */
			    {
			    smallflag = 1;
			    ptr[2] = '\0'; /* snuff the IAU designation */
			    if(!isdigit(ptr[0]))
			        {		/* is Bayer (Greek) */
			        gkflag = 1;
			        if (ptr[1] == ' ') ptr[1] = '\0';
			        }
			    }
			}
		    }
		if  (ptr != NULL)
		    {
		    pvecsize( smallflag ? FSIZESML : FSIZELRG);
/*
 * vecsyms* --
 * some x offset present to avoid overstriking corresponding object. Note
 * that some bias is already precent (obj is center-align, text is left align)
 */
		    if (gkflag) pvecsymsgk(xloc+10, yloc, ptr);
		    else pvecsyms(xloc+10, yloc, ptr);
		    }
		}
	    }
	}
    }

/*
 * Chart Construction
 */

chartbackground(chart)
    map chart;
    {
    chartoutline(chart);
    chartgrid(chart);
    }

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;
    {
    float 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);
    pvecmovedraw(xloc, yloc, xloc2, yloc2);
    xform(chart, chart->north, chart->west, &xloc,  &yloc);
    xform(chart, chart->north, chart->east, &xloc2, &yloc2);
    pvecmovedraw(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);
    pvecmove(xloc, yloc);
    for (i=0; i < div; i++)
	{
	start += inc;
	xform(chart, start, chart->west, &xloc, &yloc);
	pvecdraw(xloc, yloc);
	}
    start = chart->south;
    xform(chart, start, chart->east, &xloc, &yloc);
    pvecmove(xloc, yloc);
    for (i=0; i < div; i++)
	{
	start += inc;
	xform(chart, start, chart->east, &xloc, &yloc);
	pvecdraw(xloc, yloc);
	}
    }

rastr(str, ras)
    char *str;
    float ras;
    {
    int hrs, min;
    if (ras <   0.0) ras += 360.0;
    if (ras > 360.0) ras -= 360.0;
    hrs = (int)(ras/15.0);
    min = (int)((ras - hrs * 15.0) * 4.0);
    sprintf(str, "%2dh", hrs);
    if (min) sprintf(str, "%s%02dm", str, min);
    }

declstr(str, dl)
    char *str;
    float 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;
    float inc;
    {
#define HTICKLIM 2
#define HTEXTLIM 80
    float start, stop, ras;
    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 (ras = start; ras <= stop; ras += inc)
	    {
	    xform(chart, chart->south, ras, &xloc3, &yloc3);
	    pvecmovedraw(xloc3, yloc3-hgt, xloc3, yloc3);
	    if (xloc - xloc2 > HTEXTLIM)
		{
		char tstr[20];
		rastr(tstr, ras);
		pvecsize(10);
		pvecsyms(xloc3+2, yloc-17, tstr);
		}
	    }
    }

chartvgrid(chart, inc, wid)
    map chart;
    float inc;
    {
#define VTICKLIM 2
#define VTEXTLIM 20
    float 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);
	    pvecmovedraw(xloc3, yloc3, xloc3+wid, yloc3);
	    if (yloc2 - yloc > VTEXTLIM)
		{
		char tstr[20];
		declstr(tstr, dl);
		pvecsize(10);
		pvecsyms(xloc3+24, yloc3, tstr);
		}
	    }
	}
    }

/*
 * General Utilities
 */

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

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

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

die(a,b)
    char *a, *b;
    {
    fprintf(stderr,"%s: ", progname);
    fprintf(stderr,a,b);
    fprintf(stderr,"\n");
    exit(1);
    }

#define LINELEN 80
static char legend[LINELEN];

findconst(tag)
char *tag;
     {
/*
 * lookup "con.locs" for a matching tag, and then substitute initial values
 * for ra, decl, scale, and label. File layout follows:
 *
 * com  13    25   10   Coma Bereneces
 * cor  15.45 28   10   Corona Borealis
 * 0....+....1....+....2....+....3
 */
    char *newline;
    FILE *cfile;
    int taglen;
    char cbuf[LINELEN+1];

    if ((cfile = fopen(constfile, "r")) == NULL)
	die("open fail on %s", constfile);
    taglen = strlen(tag);
    if ((taglen < 3) || (taglen > 4))
	die("constellation name must be three or four characters");
    for (;;)
	{
	fgets(cbuf, LINELEN, cfile);
	if (ferror(cfile)) die("read error in %s", constfile);
	if (feof(cfile)) break;
	if (strncmp(tag, cbuf, taglen) == 0)	/* FOUND */
	    {	
	    if (4!=sscanf(cbuf,"%*5s%f%f%f %[^\n]", &ra, &de, &sc, legend))
		die("bogus line in constellation file: %s", cbuf);
	    ra    = ftod(ra);
	    de    = ftod(de);
	    if ((newline=index(legend, '\n')) != 0) *newline = '\0';
	    title = legend;
	    return;
	    }
	}
    die("Constellation '%s' not found", tag);
    }

/*
 * intercept vector and text functions
 * (used for omission of detail, but generally useful for clipping, etc.)
 */

pvecsize(points)
    int points;
    {
    vecsize(points);
    }

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

pvecdrawdot(x, y)
    {
    if (objdetail) vecdrawdot(x, y);
    }

pvecdrawhyph(x, y)
    {
    if (objdetail) vecdrawhyph(x, y);
    }

pvecdraw(x, y)
    {
    if (objdetail) vecdraw(x, y);
    }

pvecsyms(x, y, s)
    char *s;
    {
    if (annodetail) vecsyms(x, y, s);
    }

pvecmovedraw(x, y, x2, y2)
    {
    if (objdetail) vecmovedraw(x, y, x2, y2);
    }

pdrawPlan(x, y, mag, type, color)
    char type, *color;
    {
    if (objdetail) drawPlan(x, y, mag, type, color);
    }

pdrawStar(x, y, mag, type, color)
    char type, *color;
    {
    if (objdetail) drawStar(x, y, mag, type, color);
    }

pdrawGalx(x, y, mag, type, color)
    char type, *color;
    {
    if (objdetail) drawGalx(x, y, mag, type, color);
    }

pdrawNebu(x, y, mag, type, color)
    char type, *color;
    {
    if (objdetail) drawNebu(x, y, mag, type, color);
    }

pdrawClus(x, y, mag, type, color)
    char type, *color;
    {
    if (objdetail) drawClus(x, y, mag, type, color);
    }

pvecsymsgk(str, x, y)
    char *str;
    {
    if (annodetail) vecsymsgk(str, x, y);
    }

/*
 * clipping extentions (awpaeth at watcgl)
 */

#define TOPFLAG 8
#define BOTTOMFLAG 4
#define LEFTFLAG 2
#define RIGHTFLAG 1

int clip(top, bottom, left, right, ix1, iy1, ix2, iy2, ox1, oy1, ox2, oy2)
    float top, bottom, left, right, ix1, iy1, ix2, iy2, *ox1, *oy1, *ox2,*oy2;
    {
    int c, c1, c2;
    float x, y;

    c1 = c2 = 0;
    if (ix1 < left) c1 |= LEFTFLAG; else if (ix1 > right) c1 |= RIGHTFLAG;
    if (iy1 < bottom) c1 |= BOTTOMFLAG; else if (iy1 > top) c1 |= TOPFLAG;
    if (ix2 < left) c2 |= LEFTFLAG; else if (ix2 > right) c2 |= RIGHTFLAG;
    if (iy2 < bottom) c2 |= BOTTOMFLAG; else if (iy2 > top) c2 |= TOPFLAG;

    while (c1 || c2)
	{
	if (c1 & c2) return(0);	/* bitwise AND, not statement AND */
	c = c1 ? c1 : c2;
	
	if (c & LEFTFLAG)
	    y = iy1 + (iy2 - iy1) * ( (x = left) - ix1) / (ix2 - ix1);
	else if (c & RIGHTFLAG)
	    y = iy1 + (iy2 - iy1) * ( (x = right) - ix1) / (ix2 - ix1);
	else if (c & TOPFLAG)	
	    x = ix1 + (ix2 - ix1) * ( (y = top) - iy1) / (iy2 - iy1);
	else if (c & BOTTOMFLAG)	
	    x = ix1 + (ix2 - ix1) * ( (y = bottom) - iy1) / (iy2 - iy1);
	
	if (c == c1)
	    {
	    ix1 = x;
	    iy1 = y;
	    c1 = 0;
	    if (x < left) c1 |= LEFTFLAG; else if (x > right) c1 |= RIGHTFLAG;
	    if (y < bottom) c1 |= BOTTOMFLAG; else if (y > top) c1 |= TOPFLAG;
	    }
	else
	    {
	    ix2 = x;
	    iy2 = y;
	    c2 = 0;
	    if (x < left) c2 |= LEFTFLAG; else if (x > right) c2 |= RIGHTFLAG;
	    if (y < bottom) c2 |= BOTTOMFLAG; else if (y > top) c2 |= TOPFLAG;
	    }
	}
/*  if ((ix1 == ix2) && (iy1 == iy2)) return(0); */	/* no motion */
    *ox1 = ix1;
    *oy1 = iy1;
    *ox2 = ix2;
    *oy2 = iy2;
    return(1);
    }

/*
 !--------------------------------------------------------------------------
 ! Future Development
 !
 ! Here is my "wish" list of items not added in this version (#2). I have
 ! intentionally included it here with the source code in an attempt to direct
 ! the course of further software development.
 !
 ! It is strongly suggested that all software extentions which will be re-
 ! posted to the general public be first forwarded to the current developer
 ! (presently the author) in an effort to avoid a multiplicity of dissimilar,
 ! but "cannonical" versions.
 !
 ! It is hoped that this will simplify the task of coordinating the eventual
 ! reintegration of new features created by such a large software community.
 ! Wishes are listed in rough order of simplicity and evolution.
 !
 !
 ! Software:
 !
 ! [0] add glyphs for double stars/variable stars + Greek on bitmap devices.
 ! [1] write better PostScript macros.
 !**partially done
 ! [2] integrate a "boundary.star" to draw constellation boundaries.
 ! [3] rewrite "moonphase" to add ra/decl information, merge into "planet.c".
 ! [4] break yale.star into constellation files (and remove "cons" field).
 ! [5] write "orbit.c" for asteroid overlays.
 ! [6] add a polar plot facility (round window?) for high declinations
 !**two previous attempts - success will be met when the output includes
 !**both proper frame boundaries and tick marks, and when the underlying
 !**code uses (and sensibly extends) the functions "xform" and chartparms, etc.
 ! [7] rework planet.star to give planet tracks for a range of dates.
 !**rumored to exist
 !
 ! Database additions:
 !
 ! [1'] convert a larger database (9th-10th mag) into Yale format.
 ! [2'] Milky Way isophots
 ! [3'] Ecliptic track (dotted line vectors)
 ! [4'] IAU Constellation boundaries (see [2])
 !
 ! (comments)
 !
 ! [0] Is best facilitated by revising the image compiler in "starimages.c".
 ! [1] Would allow nice glyphs for non-stellar objects, scaled continuously
 !     to the right size. The code already provides a "halo" feature when
 !     generating stars in bright to dim (large to small) order, following
 !     a common aesthetic convention in many atlases. Variable stars are
 !     given rings, bars pass through double stars, etc., but a more
 !     comprehensive set of glyphs would be nice.
 !
 !     Starchart now allows user specified generation of text and vectors,
 !     which are useful for giving planet tracks across a range of dates, plus
 !     constellation boundaries, and possibly shapes of moon phases ([2], [3]).
 ! [2] I have access to such a database from UC Santa Cruz, and will request
 !     it once proven software is available. It would then be reworked into
 !     the "yale.star" format, using the move/draw commands of.
 ! [3] Burgess' book "Celestial Basic" gives routines for this, but lacks the
 !     precision of the work by Meesus (see planet.man). Done correctly, one
 !     should be able to check for eclipses, transits and occultations (this
 !     will require that "moonphase" know the user's geocentric latitude and
 !     longitude, due to the libration of the moon owing to parallax). This
 !     advanced version would print the profile of the moon's limb, with
 !     terminator. The "basic" version would just give a planet symbol.
 ! [4] Break-down by constellation would be a simple conceptual organization.
 !     It is also helpful to users requiring detailed finder charts of select
 !     regions. At the very least, the thirteen files for ecliptic-based
 !     constellation (~the Zodiac) would be quite helpful. The three character
 !     constellation field in the "label" field of the newer (but still
 !     reduced) version of yale.star would then go.
 ! [5] I have already produced tables of Keplerian elements for asteroids
 !     to the 10th mag. I also have code to read the data and solve for various
 !     related values (e.g. eccentric anomoly from mean anomoly). Left are
 !     the routines to find earth's position, plus the spherical trig needed
 !     to convert this into Ra and Decl. This would best be integrated into
 !     "planet.c", which already does the latter. Interested parties should
 !     e-mail me for the files "orbit.c" and "asteroids.el".
 ! [6] xcen and ycen would be ignored, and scale would give the limit of
 !     declination (90.0-scale). Provisions to choose which pole needed, too.
 !     I believe stereographic projection would be the best, being both
 !     conformal and preserving of circles (as circles of new radii).
 ! [7] A complete rework would probably also place moon and asteroid calcs
 !     here, in addition to generating "track" output records.
 !
 ! [1'] Electronic databases to the 10th mag rumored to exist, containing on
 !	the order of 40000 stars. Don't ask me where to find them.
 ! [2'] No idea where to find
 ! [3'] Should not be too hard
 */
@//E*O*F starchart.c//
chmod u=r,g=r,o=r starchart.c
 
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, lbllim, gklim;
    int wx, wy, ww, wh;
    float yscale;
    } mapblock, *map;

extern mapblock master, thumbnail, bigmaster;
@//E*O*F starchart.h//
chmod u=r,g=r,o=r starchart.h
 
echo x - stariris.c
sed 's/^@//' > "stariris.c" <<'@//E*O*F stariris.c//'
/*
 * IRIS driver for startchart.c mainline
 *
 * Tim Pointing, DCIEM
 * <decvax!utzoo!dciem!tim>
 */

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

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


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

mapblock bigmaster =	{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
			 8.0, 3.0, 2.05, 20,  65, 880, 700, 0.0 };

mapblock thumbnail =	{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
			 3.2, 1.0, 2.05, 420, 35, 480, 195, 0.0 };
/*
 * Generic Star Drawing Stuff
 */

vecopen()
   {
   keepaspect(1,1);
   getport();
   ortho(0., 1023., 0., 1023.);
   reshapeviewport();
   color(BLACK);
   clear();
   makeobj(1);
   color(BLACK);
   clear();
   color(WHITE);
   }

vecclose()
    {
    int x;
    closeobj(1);
    callobj(1);
    while(qread(&x))
	{
	ortho(0., 1023., 0., 1023.);
	reshapeviewport();
	callobj(1);
	}
    }

vecsize(points)
    int points;
    {
    }

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

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

vecdrawhyph(x, y)
    {
    draw2i(x, y);
    }

vecdrawdot(x, y)
    {
    draw2i(x, y);
    }

vecsyms(x, y, s)
    char *s;
    {
    color(WHITE);
    cmov2i(x, y-5); /* center character strings */
    charstr(s);
    color(WHITE);
    }

vecsymsgk(x, y, s)
    char *s;
    {
    vecsyms(x, y, s);
    }

vecmovedraw(x1, y1, x2, y2)
    {
    move2i(x1, y1);
    draw2i(x2, y2);
    }

drawlen(x, y, dx, dy, len)
    {
    vecmovedraw(x+dx, y+dy, x+dx+len, y+dy);
    }
/*
 * presently in conflict with stariamges.c
 */
 
#ifdef FIXED

drawPlan(x, y, mag, type, col)
    char type, *col;
    {
    color(YELLOW);
    switch(type)
	{
	case ('S'<<8)|('o'):	/* Sol */
		pnt2i(x, y);
		circi(x, y, 5);
		break;
	case ('M'<<8)|('e'):	/* Mercury */
		circi(x, y+1, 3);
		move2i(x, y-2);
		draw2i(x, y-5);
		move2i(x-2, y-4);
		draw2i(x+2, y-4);
		move2i(x-1, y+3);
		draw2i(x-2, y+5);
		move2i(x+1, y+3);
		draw2i(x+2, y+5);
		break;
	case ('V'<<8)|('e'):	/* Venus */
		circi(x, y+1, 3);
		move2i(x, y-2);
		draw2i(x, y-5);
		move2i(x-2, y-4);
		draw2i(x+2, y-4);
		break;
	case ('M'<<8)|('a'):	/* Mars */
		circi(x-2, y-2, 3);
		move2i(x, y);
		draw2i(x+3, y+3);
		draw2i(x+1, y+3);
		move2i(x+3, y+3);
		draw2i(x+3, y+1);
		break;
	case ('J'<<8)|('u'):	/* Jupiter */
		arci(x-2, y+2, 2, 3150, 1350);
		move2(x-.6, y+.6);
		draw2i(x-3, y-1);
		draw2i(x+1, y-1);
		move2i(x, y-2);
		draw2i(x, y+4);
		break;
	case ('S'<<8)|('a'):	/* Saturn */
		move2i(x-2, y+3);
		draw2i(x, y+3);
		move2i(x-1, y+3);
		draw2i(x-1, y-3);
		move2i(x-1, y+1);
		draw2i(x, y+1);
		draw2i(x+2, y);
		draw2i(x+2, y-1);
		draw2i(x+1, y-2);
		draw2i(x+1,y-3);
		break;
	case ('U'<<8)|('r'):	/* Uranus */
		circi(x, y-3, 3);
		pnt2i(x, y-3);
		move2i(x, y);
		draw2i(x, y+3);
		draw2i(x-1, y+2);
		move2i(x, y+3);
		draw2i(x+1, y+2);
		break;
	case ('N'<<8)|('e'):	/* Neptune */
		arci(x, y+3, 3, 1800, 3600);
		move2i(x, y+3);
		draw2i(x, y-6);
		move2i(x-2, y-5);
		draw2i(x+2, y-5);
		break;
	default:
		circi(x, y, 4);
		move2i(x, y-5);
		draw2i(x, y+5);
		move2i(x-5, y);
		draw2i(x+5, y);
		break;
	}
    color(WHITE);
    }

drawStar(x, y, mag, type, col)
char type, *col;
    {
    if (mag > 9) mag = 9;
    if (mag < 4)
	{
	color(WHITE);
	circfi(x, y, (int)((4-mag)/2));
	}
    else
	{
	color(31 - (mag-4)*3);
	pnt2i(x,y);
	}
    color(WHITE);
    }

drawNebu(x, y, mag, type, col)
    char type, *col;
    {
    }

drawGalx(x, y, mag, type, col)
    char type, *col;
    {
    }

drawClus(x, y, mag, type, col)
    char type, *col;
    {
    }

#endif
@//E*O*F stariris.c//
chmod u=r,g=r,o=r stariris.c
 
echo x - staruplot.c
sed 's/^@//' > "staruplot.c" <<'@//E*O*F staruplot.c//'
/*
 * Plotter Display driver for starchart.c mainline (UNIX Plot(5) style output)
 *
 * Sjoerd Mullender <sjoerd at cs.vu.nl>
 * Free University, Amsterdam
 */

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

#define SOLID		1
#define DOTTED		2
#define DASHED		3

static int mode = 0;

/*
 * 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, 1.0, 2.05, 420, 35, 480, 195, 0.0 };

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

mapblock bigmaster=	{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
			8.0, 3.0, 2.05, 20,  65, 880, 700, 0.0 };

vecopen()
    {
    openpl();
    space(0, 0, 1024, 768);
    erase();
    }

vecclose()
    {
    closepl();
    }

vecsize(points)
    int points;
    {
    }

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

vecdrawdot(x, y)
    {
    if (mode != DOTTED) linemod("dotted");
    mode = DOTTED;
    cont(x, y);
    }

vecdrawhyph(x, y)
    {
    if (mode != DASHED) linemod("shortdashed");
    mode = DASHED;
    cont(x, y);
    }

vecdraw(x, y)
    {
    if (mode != SOLID) linemod("solid");
    mode = SOLID;
    cont(x, y);
    }

vecsyms(x, y, s)
    char *s;
    {
    move(x, y);
    label(s);
    }

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

vecsymsgk(x, y, str)
    char *str;
    {
    vecsyms(x, y, str);
    }

drawlen(x, y, dx, dy, len)
    {
    move(x + dx, y + dy);
    cont(x + dx + len - 1, y + dy);
    }
@//E*O*F staruplot.c//
chmod u=r,g=r,o=r staruplot.c
 
exit 0
-- 
For comp.sources.unix stuff, mail to sources at uunet.uu.net.



More information about the Comp.sources.unix mailing list