[comp.sources.misc] v11i005: ephem, 4 of 7

ecd@cs.umn.edu@ncs-med.UUCP (Elwood C. Downey) (03/11/90)

Posting-number: Volume 11, Issue 5
Submitted-by: ecd@cs.umn.edu@ncs-med.UUCP (Elwood C. Downey)
Archive-name: ephem4.12/part04

# This is the first line of a "shell archive" file.
# This means it contains several files that can be extracted into
# the current directory when run with the sh shell, as follows:
#    sh < this_file_name
# This is file 4.
echo x plot.c
sed -e 's/^X//' << 'EOFxEOF' > plot.c
X/* code to support the plotting capabilities.
X * idea is to let the operator name a plot file and mark some fields for
X * logging. then after each screen update, the logged fields are written to
X * the plot file. later, the file may be plotted (very simplistically by 
X * ephem, for now anyway, or by some other program entirely.).
X * 
X * format of the plot file is one line per coordinate: label,x,y
X * if z was specified, it is a fourth field.
X * x,y,z are plotted using %g format.
X */
X
X#include <stdio.h>
X#include <math.h>
X#include "screen.h"
X
Xextern char *strcpy();
Xextern errno;
Xextern char *sys_errlist[];
X#define	errsys	(sys_errlist[errno])
X
X#define	TRACE(x)	{FILE *fp = fopen("trace","a"); fprintf x; fclose(fp);}
X
X#define	MAXPLTLINES	10	/* max number of labeled lines we can track.
X				 * note we can't store more than NFLOGS fields
X				 * anyway (see flog.c).
X				 */
X#define	FNLEN		(14+1)	/* longest filename; plus 1 for \0 */
X
Xstatic char plt_filename[FNLEN] = "ephem.plt";	/* default plot file name */
Xstatic FILE *plt_fp;		/* the plot file; == 0 means don't plot */
X
X/* store the label and rcfpack()s for each line to track. */
Xtypedef struct {
X    char pl_label;
X    int pl_rcpx, pl_rcpy, pl_rcpz;
X} PltLine;
Xstatic PltLine pltlines[MAXPLTLINES];
Xstatic int npltlines;		/* number of pltlines[] in actual use */
X
Xstatic int plt_in_polar;	/*if true plot in polar coords, else cartesian*/
Xstatic int pltsrchfld;		/* set when the Search field is to be plotted */
X
X/* picked the Plot label:
X * if on, just turn it off.
X * if off, turn on, define fields or select name of file to plot and do it.
X * TODO: more flexibility, more relevance.
X */
Xplot_setup()
X{
X	if (plt_fp)
X	    plt_turn_off();
X	else {
X	    static char *chcs[4] = {
X		"Select fields", "Display a plot file", (char *)0,
X		"Begin plotting"
X	    };
X	    int ff = 0;
X    ask:
X	    chcs[2] = plt_in_polar ? "Polar coords" : "Cartesian coords";
X	    switch (popup(chcs, ff, npltlines > 0 ? 4 : 3)) {
X	    case 0: plt_select_fields(); break;
X	    case 1: plt_file(); break;
X	    case 2: plt_in_polar ^= 1; ff = 2; goto ask;
X	    case 3: plt_turn_on(); break;
X	    }
X	}
X}
X
X/* write the active plotfields to the current plot file, if one is open. */
Xplot()
X{
X	if (plt_fp) {
X	    PltLine *plp;
X	    double x, y, z;
X	    if (!srch_ison() && pltsrchfld) {
X		/* if searching is not on but we are plotting the search
X		 * funtion we must evaluate and log it ourselves here and now.
X		 * plt_turn_on() insured there is a good function to eval.
X		 * N.B. if searching IS on, we rely on main() having called
X		 * srch_eval() BEFORE plot() so it is already evaluated.
X		 */
X		double e;
X		char errmsg[128];
X		if (execute_expr (&e, errmsg) < 0) {
X		    f_msg (errmsg);
X		    plt_turn_off();
X		    return;
X		} else
X		    flog_log (R_SRCH, C_SRCH, e);
X	    }
X	    /* plot in order of original selection */
X	    for (plp = pltlines; plp < &pltlines[npltlines]; plp++) {
X		if (flog_get (plp->pl_rcpx, &x) == 0 
X			&& flog_get (plp->pl_rcpy, &y) == 0) {
X		    fprintf (plt_fp, "%c,%.12g,%.12g", plp->pl_label, x, y);
X		    if (flog_get (plp->pl_rcpz, &z) == 0)
X			fprintf (plt_fp, ",%.12g", z);
X		    fprintf (plt_fp, "\n");
X		}
X	    }
X	}
X}
X
Xplot_prstate (force)
Xint force;
X{
X	static last;
X	int this = plt_fp != 0;
X
X	if (force || this != last) {
X	    f_string (R_PLOT, C_PLOTV, this ? " on" : "off");
X	    last = this;
X	}
X}
X
Xplot_ison()
X{
X	return (plt_fp != 0);
X}
X
Xstatic
Xplt_reset()
X{
X	PltLine *plp;
X
X	for (plp = &pltlines[npltlines]; --plp >= pltlines; ) {
X	    (void) flog_delete (plp->pl_rcpx);
X	    (void) flog_delete (plp->pl_rcpy);
X	    (void) flog_delete (plp->pl_rcpz);
X	    plp->pl_rcpx = plp->pl_rcpy = plp->pl_rcpz = 0;
X	}
X	npltlines = 0;
X	pltsrchfld = 0;
X}
X
X/* let operator select the fields he wants to plot.
X * register them with flog and keep rcfpack() in pltlines[] array.
X * as a special case, set pltsrchfld if Search field is selected.
X */
Xstatic
Xplt_select_fields()
X{
X	static char hlp[] = "move and RETURN to select a field, or q to quit";
X	static char sry[] = "Sorry; can not log any more fields.";
X	int r = R_UT, c = C_UTV; /* TODO: start where main was? */
X	int sf = rcfpack (R_SRCH, C_SRCH, 0);
X	char buf[64];
X	int rcp;
X	int i;
X
X	plt_reset();
X	for (i = 0; i < MAXPLTLINES; i++) {
X	    sprintf (buf, "select x field for line %d", i+1);
X	    rcp = sel_fld (r, c, alt_menumask()|F_PLT, buf, hlp);
X	    if (!rcp)
X		break;
X	    if (flog_add (rcp) < 0) {
X		f_msg (sry);
X		break;
X	    }
X	    pltlines[i].pl_rcpx = rcp;
X	    if (rcp == sf)
X		pltsrchfld = 1;
X
X	    sprintf (buf, "select y field for line %d", i+1);
X	    r = unpackr (rcp); c = unpackc (rcp);
X	    rcp = sel_fld (r, c, alt_menumask()|F_PLT, buf, hlp);
X	    if (!rcp) {
X		(void) flog_delete (pltlines[i].pl_rcpx);
X		break;
X	    }
X	    if (flog_add (rcp) < 0) {
X		(void) flog_delete (pltlines[i].pl_rcpx);
X		f_msg (sry);
X		break;
X	    }
X	    pltlines[i].pl_rcpy = rcp;
X	    if (rcp == sf)
X		pltsrchfld = 1;
X
X	    sprintf (buf, "select z field for line %d", i+1);
X	    r = unpackr (rcp); c = unpackc (rcp);
X	    rcp = sel_fld (r, c, alt_menumask()|F_PLT, buf, hlp);
X	    if (rcp) {
X		if (flog_add (rcp) < 0) {
X		    (void) flog_delete (pltlines[i].pl_rcpx);
X		    (void) flog_delete (pltlines[i].pl_rcpy);
X		    f_msg (sry);
X		    break;
X		}
X		pltlines[i].pl_rcpz = rcp;
X		if (rcp == sf)
X		    pltsrchfld = 1;
X		r = unpackr (rcp); c = unpackc (rcp);
X	    }
X
X	    do {
X		sprintf (buf, "enter a one-character label for line %d: ", i+1);
X		f_prompt (buf);
X	    } while (read_line (buf, 1) != 1);
X	    pltlines[i].pl_label = *buf;
X	}
X	npltlines = i;
X}
X
Xstatic
Xplt_turn_off ()
X{
X	fclose (plt_fp);
X	plt_fp = 0;
X	plot_prstate(0);
X}
X
X/* turn on plotting.
X * establish a file to use (and thereby set plt_fp, the plotting_is_on flag).
X * also check that there is a srch function if it is being plotted.
X */
Xstatic
Xplt_turn_on ()
X{
X	int sf = rcfpack(R_SRCH, C_SRCH, 0);
X	char fn[FNLEN], fnq[64];
X	char *optype;
X	int n;
X	PltLine *plp;
X
X	/* insure there is a valid srch function if we are to plot it */
X	for (plp = &pltlines[npltlines]; --plp >= pltlines; )
X	    if ((plp->pl_rcpx == sf || plp->pl_rcpy == sf || plp->pl_rcpz == sf)
X		    && !prog_isgood()) {
X		f_msg ("Plotting search function but it is not defined.");
X		return;
X	    }
X
X	/* prompt for file name, giving current as default */
X	sprintf (fnq, "file to write <%s>: ", plt_filename);
X	f_prompt (fnq);
X	n = read_line (fn, sizeof(fn)-1);
X
X	/* leave plotting off if type END.
X	 * reuse same fn if just type \n
X	 */
X	if (n < 0)
X	    return;
X	if (n > 0)
X	    strcpy (plt_filename, fn);
X
X	/* give option to append if file already exists */
X	optype = "w";
X	if (access (plt_filename, 2) == 0) {
X	    while (1) {
X		f_prompt ("files exists; append or overwrite (a/o)?: ");
X		n = read_char();
X		if (n == 'a') {
X		    optype = "a";
X		    break;
X		}
X		if (n == 'o')
X		    break;
X	    }
X	}
X
X	/* plotting is on if file opens ok */
X	plt_fp = fopen (plt_filename, optype);
X	if (!plt_fp) {
X	    char buf[NC];
X	    sprintf (buf, "can not open %s: %s", plt_filename, errsys);
X	    f_prompt (buf);
X	    (void)read_char();
X	}
X	plot_prstate (0);
X}
X
X/* ask operator for a file to plot. if it's ok, do it.
X */
Xstatic
Xplt_file ()
X{
X	char fn[FNLEN], fnq[64];
X	FILE *pfp;
X	int n;
X
X	/* prompt for file name, giving current as default */
X	sprintf (fnq, "file to read <%s>: ", plt_filename);
X	f_prompt (fnq);
X	n = read_line (fn, sizeof(fn)-1);
X
X	/* forget it if type END.
X	 * reuse same fn if just type \n
X	 */
X	if (n < 0)
X	    return;
X	if (n > 0)
X	    strcpy (plt_filename, fn);
X
X	/* do the plot if file opens ok */
X	pfp = fopen (plt_filename, "r");
X	if (pfp) {
X	    if (plt_in_polar)
X		plot_polar (pfp);
X	    else
X		plot_cartesian (pfp);
X	    fclose (pfp);
X	} else {
X	    char buf[NC];
X	    sprintf (buf, "can not open %s: %s", plt_filename, errsys);
X	    f_prompt (buf);
X	    (void)read_char();
X	}
X}
X
X/* plot the given file on the screen in cartesian coords.
X * TODO: add z tags somehow
X * N.B. do whatever you like but redraw the screen when done.
X */
Xstatic
Xplot_cartesian (pfp)
XFILE *pfp;
X{
X	static char fmt[] = "%c,%lf,%lf";
X	double x, y;	/* N.B. be sure these match what scanf's %lf wants*/
X	double minx, maxx, miny, maxy;
X	char buf[128];
X	int npts = 0;
X	char c;
X
X	/* find ranges and number of points */
X	while (fgets (buf, sizeof(buf), pfp)) {
X	    sscanf (buf, fmt, &c, &x, &y);
X	    if (npts++ == 0) {
X		maxx = minx = x;
X		maxy = miny = y;
X	    } else {
X		if (x > maxx) maxx = x;
X		else if (x < minx) minx = x;
X		if (y > maxy) maxy = y;
X		else if (y < miny) miny = y;
X	    }
X	}
X
X#define	SMALL	(1e-10)
X	if (npts < 2 || fabs(minx-maxx) < SMALL || fabs(miny-maxy) < SMALL)
X	    f_prompt ("At least two different points required to plot.");
X	else {
X	    /* read file again, this time plotting */
X	    rewind (pfp);
X	    c_erase();
X	    while (fgets (buf, sizeof(buf), pfp)) {
X		int row, col;
X		sscanf (buf, fmt, &c, &x, &y);
X		row = NR-(int)((NR-1)*(y-miny)/(maxy-miny)+0.5);
X		col =  1+(int)((NC-1)*(x-minx)/(maxx-minx)+0.5);
X		if (row == NR && col == NC)
X		    col--;	/* avoid lower right scrolling corner */
X		f_char (row, col, c);
X	    }
X
X	    /* label axes */
X	    f_double (1, 1, "%.2g", maxy);
X	    f_double (NR-1, 1, "%.2g", miny);
X	    f_double (NR, 1, "%.2g", minx);
X	    f_double (NR, NC-10, "%.2g", maxx);
X	}
X
X	/* hit any key to resume... */
X	(void) read_char();
X	redraw_screen (2);	/* full redraw */
X}
X
X/* plot the given file on the screen in polar coords.
X * first numberic field in plot file is r, second is theta in degrees.
X * TODO: add z tags somehow
X * N.B. do whatever you like but redraw the screen when done.
X */
Xstatic
Xplot_polar (pfp)
XFILE *pfp;
X{
X	static char fmt[] = "%c,%lf,%lf";
X	double r, th;	/* N.B. be sure these match what scanf's %lf wants*/
X	double maxr;
X	char buf[128];
X	int npts = 0;
X	char c;
X
X	/* find ranges and number of points */
X	while (fgets (buf, sizeof(buf), pfp)) {
X	    sscanf (buf, fmt, &c, &r, &th);
X	    if (npts++ == 0)
X		maxr = r;
X	    else
X		if (r > maxr)
X		    maxr = r;
X	}
X
X	if (npts < 2)
X	    f_prompt ("At least two points required to plot.");
X	else {
X	    /* read file again, this time plotting */
X	    rewind (pfp);
X	    c_erase();
X	    while (fgets (buf, sizeof(buf), pfp)) {
X		int row, col;
X		double x, y;
X		sscanf (buf, fmt, &c, &r, &th);
X		x = r * cos(th/57.2958);	/* degs to rads */
X		y = r * sin(th/57.2958);
X		row = NR-(int)((NR-1)*(y+maxr)/(2.0*maxr)+0.5);
X		col =  1+(int)((NC-1)*(x+maxr)/(2.0*maxr)/ASPECT+0.5);
X		if (row == NR && col == NC)
X		    col--;	/* avoid lower right scrolling corner */
X		f_char (row, col, c);
X	    }
X
X	    /* label radius */
X	    f_double (NR/2, NC-10, "%.4g", maxr);
X	}
X
X	/* hit any key to resume... */
X	(void) read_char();
X	redraw_screen (2);	/* full redraw */
X}
EOFxEOF
len=`wc -c < plot.c`
if expr $len != 10712 > /dev/null
then echo Length of plot.c is $len but it should be 10712.
fi
echo x popup.c
sed -e 's/^X//' << 'EOFxEOF' > popup.c
X/* put up a one-line menu consisting of the given fields and let op move
X * between them with the same methods as sel_fld().
X * return index of which he picked, or -1 if hit END.
X */
X
X#include <stdio.h>
X#include "screen.h"
X
X#define	FLDGAP	2	/* inter-field gap */
X#define	MAXFLDS	32	/* max number of fields we can handle */
X
Xstatic char pup[] = "Select: ";
X
X/* put up an array of strings on prompt line and let op pick one.
X * start with field fn.
X * N.B. we do not do much error/bounds checking.
X */
Xpopup (fields, fn, nfields)
Xchar *fields[];
Xint fn;
Xint nfields;
X{
X	int fcols[MAXFLDS];	/* column to use for each field */
X	int i;
X
X	if (nfields > MAXFLDS)
X	    return (-1);
X
X    again:
X	/* erase the prompt line; we are going to take it over */
X	c_pos (R_PROMPT, C_PROMPT);
X	c_eol();
X
X	/* compute starting column for each field */
X	fcols[0] = sizeof(pup);
X	for (i = 1; i < nfields; i++)
X	    fcols[i] = fcols[i-1] + strlen (fields[i-1]) + FLDGAP;
X
X	/* draw each field, with comma after all but last */
X	c_pos (R_PROMPT, 1);
X	fputs (pup, stdout);
X	for (i = 0; i < nfields; i++) {
X	    c_pos (R_PROMPT, fcols[i]);
X	    printf (i < nfields-1 ? "%s," : "%s", fields[i]);
X	}
X
X	/* let op choose one now; begin at fn.
X	 */
X	i = fn;
X	while (1) {
X	    c_pos (R_PROMPT, fcols[i]);
X	    switch (read_char()) {
X	    case END: return (-1);
X	    case REDRAW: redraw_screen(2); goto again;
X	    case VERSION: version(); goto again;
X	    case '\r': return (i);
X	    case 'h':
X		if (--i < 0)
X		    i = nfields - 1;
X		break;
X	    case 'l':
X		if (++i >= nfields)
X		    i = 0;
X		break;
X	    }
X	}
X}
EOFxEOF
len=`wc -c < popup.c`
if expr $len != 1578 > /dev/null
then echo Length of popup.c is $len but it should be 1578.
fi
echo x precess.c
sed -e 's/^X//' << 'EOFxEOF' > precess.c
X#include <stdio.h>
X#include <math.h>
X#include "astro.h"
X
X/* corrects ra and dec, both in radians, for precession from epoch 1 to epoch 2.
X * the epochs are given by their modified JDs, mjd1 and mjd2, respectively.
X * N.B. ra and dec are modifed IN PLACE.
X */
Xprecess (mjd1, mjd2, ra, dec)
Xdouble mjd1, mjd2;	/* initial and final epoch modified JDs */
Xdouble *ra, *dec;	/* ra/dec for mjd1 in, for mjd2 out */
X{
X	static double lastmjd1, lastmjd2;
X	static double m, n, nyrs;
X	double dra, ddec;	/* ra and dec corrections */
X
X	if (mjd1 != lastmjd1 || mjd2 != lastmjd2) {
X	    double t1, t2; /* Julian centuries of 36525 days since Jan .5 1900*/
X	    double m1, n1; /* "constants" for t1 */
X	    double m2, n2; /* "constants" for t2 */
X	    t1 = mjd1/36525.;
X	    t2 = mjd2/36525.;
X	    m1 = 3.07234+(1.86e-3*t1);
X	    n1 = 20.0468-(8.5e-3*t1);
X	    m2 = 3.07234+(1.86e-3*t2);
X	    n2 = 20.0468-(8.5e-3*t2);
X	    m = (m1+m2)/2;	/* average m for the two epochs */
X	    n = (n1+n2)/2;	/* average n for the two epochs */
X	    nyrs = (mjd2-mjd1)/365.2425;
X	    lastmjd1 = mjd1;
X	    lastmjd2 = mjd2;
X	}
X
X	dra = (m+(n*sin(*ra)*tan(*dec)/15))*7.272205e-5*nyrs;
X	ddec = n*cos(*ra)*4.848137e-6*nyrs;
X	*ra += dra;
X	*dec += ddec;
X	/* added by ECD */
X	if (*dec > PI/2) {
X	    *dec = PI - *dec;
X	    *ra += PI;
X	} else if (*dec < -PI/2) {
X	    *dec = -PI - *dec;
X	    *ra += PI;
X	}
X	range (ra, 2*PI);
X}
EOFxEOF
len=`wc -c < precess.c`
if expr $len != 1385 > /dev/null
then echo Length of precess.c is $len but it should be 1385.
fi
echo x reduce.c
sed -e 's/^X//' << 'EOFxEOF' > reduce.c
X#include <math.h>
X#include "astro.h"
X
X/* convert those orbital elements that change from epoch mjd0 to epoch mjd.
X */
Xreduce_elements (mjd0, mjd, inc0, ap0, om0, inc, ap, om)
Xdouble mjd0;	/* initial epoch */
Xdouble mjd;	/* desired epoch */
Xdouble inc0;	/* initial inclination, rads */
Xdouble ap0;	/* initial argument of perihelion, as an mjd */
Xdouble om0;	/* initial , rads */
Xdouble *inc;	/* desired inclination, rads */
Xdouble *ap;	/* desired epoch of perihelion, as an mjd */
Xdouble *om;	/* desired , rads */
X{
X	double t0, t1;
X	double tt, tt2, t02, tt3;
X	double eta, th, th0;
X	double a, b;
X	double dap;
X	double cinc, sinc;
X	double ot, sot, cot, ot1;
X	double seta, ceta;
X
X	t0 = mjd0/365250.0;
X	t1 = mjd/365250.0;
X
X	tt = t1-t0;
X	tt2 = tt*tt;
X        t02 = t0*t0;
X	tt3 = tt*tt2;
X        eta = (471.07-6.75*t0+.57*t02)*tt+(.57*t0-3.37)*tt2+.05*tt3;
X        th0 = 32869.0*t0+56*t02-(8694+55*t0)*tt+3*tt2;
X        eta = degrad(eta/3600.0);
X        th0 = degrad((th0/3600.0)+173.950833);
X        th = (50256.41+222.29*t0+.26*t02)*tt+(111.15+.26*t0)*tt2+.1*tt3;
X        th = th0+degrad(th/3600.0);
X	cinc = cos(inc0);
X        sinc = sin(inc0);
X	ot = om0-th0;
X	sot = sin(ot);
X        cot = cos(ot);
X	seta = sin(eta);
X        ceta = cos(eta);
X	a = sinc*sot;
X        b = ceta*sinc*cot-seta*cinc;
X	ot1 = atan(a/b);
X        if (b<0) ot1 += PI;
X        b = sinc*ceta-cinc*seta*cot;
X        a = -1*seta*sot;
X	dap = atan(a/b);
X        if (b<0) dap += PI;
X
X        *ap = ap0+dap;
X	range (ap, 2*PI);
X        *om = ot1+th;
X	range (om, 2*PI);
X
X        if (inc0<.175)
X	    *inc = asin(a/sin(dap));
X	else
X	    *inc = 1.570796327-asin((cinc*ceta)+(sinc*seta*cot));
X}
EOFxEOF
len=`wc -c < reduce.c`
if expr $len != 1647 > /dev/null
then echo Length of reduce.c is $len but it should be 1647.
fi
echo x refract.c
sed -e 's/^X//' << 'EOFxEOF' > refract.c
X#include <stdio.h>
X#include <math.h>
X#include "astro.h"
X
X/* correct the true altitude, ta, for refraction to the apparent altitude, aa,
X * each in radians, given the local atmospheric pressure, pr, in mbars, and
X * the temperature, tr, in degrees C.
X */
Xrefract (pr, tr, ta, aa)
Xdouble pr, tr;
Xdouble ta;
Xdouble *aa;
X{
X	double r;	/* refraction correction*/
X
X        if (ta >= degrad(15.)) {
X	    /* model for altitudes at least 15 degrees above horizon */
X            r = 7.888888e-5*pr/((273+tr)*tan(ta));
X	} else if (ta > degrad(-5.)) {
X	    /* hairier model for altitudes at least -5 and below 15 degrees */
X	    double a, b, tadeg = raddeg(ta);
X	    a = ((2e-5*tadeg+1.96e-2)*tadeg+1.594e-1)*pr;
X	    b = (273+tr)*((8.45e-2*tadeg+5.05e-1)*tadeg+1);
X	    r = degrad(a/b);
X	} else {
X	    /* do nothing if more than 5 degrees below horizon.
X	     */
X	    r = 0;
X	}
X
X	*aa  =  ta + r;
X}
X
X/* correct the apparent altitude, aa, for refraction to the true altitude, ta,
X * each in radians, given the local atmospheric pressure, pr, in mbars, and
X * the temperature, tr, in degrees C.
X */
Xunrefract (pr, tr, aa, ta)
Xdouble pr, tr;
Xdouble aa;
Xdouble *ta;
X{
X	double err;
X	double appar;
X	double true;
X
X	/* iterative solution: search for the true that refracts to the
X	 *   given apparent.
X	 * since refract() is discontinuous at -5 degrees, there is a range
X	 *   of apparent altitudes between about -4.5 and -5 degrees that are
X	 *   not invertable (the graph of ap vs. true has a vertical step at
X	 *   true = -5). thus, the iteration just oscillates if it gets into
X	 *   this region. if this happens the iteration is forced to abort.
X	 *   of course, this makes unrefract() discontinuous too.
X	 */
X	true = aa;
X	do {
X	    refract (pr, tr, true, &appar);
X	    err = appar - aa;
X	    true -= err;
X	} while (fabs(err) >= 1e-6 && true > degrad(-5));
X
X	*ta = true;
X}
EOFxEOF
len=`wc -c < refract.c`
if expr $len != 1857 > /dev/null
then echo Length of refract.c is $len but it should be 1857.
fi
echo x riset.c
sed -e 's/^X//' << 'EOFxEOF' > riset.c
X#include <stdio.h>
X#include <math.h>
X#include "astro.h"
X
X/* given the true geocentric ra and dec of an object, in radians, the observer's
X *   latitude in radians, and a horizon displacement correction, dis, in radians
X *   find the local sidereal times and azimuths of rising and setting, lstr/s
X *   and azr/s, in radians, respectively.
X * dis is the vertical displacement from the true position of the horizon. it
X *   is positive if the apparent position is higher than the true position.
X *   said another way, it is positive if the shift causes the object to spend
X *   longer above the horizon. for example, atmospheric refraction is typically
X *   assumed to produce a vertical shift of 34 arc minutes at the horizon; dis
X *   would then take on the value +9.89e-3 (radians). On the other hand, if
X *   your horizon has hills such that your apparent horizon is, say, 1 degree
X *   above sea level, you would allow for this by setting dis to -1.75e-2
X *   (radians).
X * status: 0: normal; 1: never rises; -1: circumpolar; 2: trouble.
X */
Xriset (ra, dec, lat, dis, lstr, lsts, azr, azs, status)
Xdouble ra, dec;
Xdouble lat, dis;
Xdouble *lstr, *lsts;
Xdouble *azr, *azs;
Xint *status;
X{
X	static double lastlat = 0, slat = 0, clat = 1.0;
X	double dec1, sdec, cdec, tdec;
X	double psi, spsi, cpsi;
X	double h, dh, ch;	/* hr angle, delta and cos */
X
X	/* avoid needless sin/cos since latitude doesn't change often */
X        if (lat != lastlat) {
X	    clat = cos(lat);
X	    slat = sin(lat);
X	    lastlat = lat;
X	}
X
X	/* can't cope with objects very near the celestial pole nor if we 
X	 * are located very near the earth's poles.
X	 */
X	cdec = cos(dec);
X        if (fabs(cdec*clat) < 1e-10) {
X	    /* trouble */
X	    *status = 2;
X	    return;
X	}
X
X        cpsi = slat/cdec;
X        if (cpsi>1.0) cpsi = 1.0;
X        else if (cpsi<-1.0) cpsi = -1.0;
X        psi = acos(cpsi);
X	spsi = sin(psi);
X
X        dh = dis*spsi;
X	dec1 = dec + (dis*cpsi);
X        sdec = sin(dec1);
X	tdec = tan(dec1);
X
X        ch = (-1*slat*tdec)/clat;
X
X        if (ch < -1) {
X	    /* circumpolar */
X	    *status = -1;
X	    return;
X	}
X        if (ch > 1) {
X	    /* never rises */
X	    *status = 1;
X	    return;
X	}
X
X        *status = 0;
X	h = acos(ch)+dh;
X
X        *lstr = 24+radhr(ra-h);
X	*lsts = radhr(ra+h);
X	range (lstr, 24.0);
X	range (lsts, 24.0);
X
X	*azr = acos(sdec/clat);
X	range (azr, 2*PI);
X        *azs = 2*PI - *azr;
X}
EOFxEOF
len=`wc -c < riset.c`
if expr $len != 2388 > /dev/null
then echo Length of riset.c is $len but it should be 2388.
fi
echo x riset_c.c
sed -e 's/^X//' << 'EOFxEOF' > riset_c.c
X/* find rise and set circumstances, ie, riset_cir() and related functions. */
X
X#include <stdio.h>
X#include <math.h>
X#include "astro.h"
X#include "circum.h"
X#include "screen.h"	/* just for SUN and MOON */
X
X#define	TRACE(x)	{FILE *fp = fopen("trace","a"); fprintf x; fclose(fp);}
X
X#define	STDREF	degrad(34./60.)	/* nominal horizon refraction amount */
X#define	TWIREF	degrad(18.)	/* twilight horizon displacement */
X
X/* find where and when a body, p, will rise and set and
X *   its transit circumstances. all times are local, angles rads e of n.
X * return 0 if just returned same stuff as previous call, else 1 if new.
X * status is set from the RS_* #defines in circum.h.
X * also used to find astro twilight by calling with dis of 18 degrees.
X */
Xriset_cir (p, np, hzn, ltr, lts, ltt, azr, azs, altt, status)
Xint p;		/* one of the body defines in astro.h or screen.h */
XNow *np;
Xint hzn;	/* STDHZN or ADPHZN or TWILIGHT */
Xdouble *ltr, *lts; /* local rise and set times */
Xdouble *ltt;	/* local transit time */
Xdouble *azr, *azs; /* local rise and set azimuths, rads e of n */
Xdouble *altt;	/* local altitude at transit */
Xint *status;	/* one or more of the RS_* defines */
X{
X	typedef struct {
X	    Now l_now;
X	    double l_ltr, l_lts, l_ltt, l_azr, l_azs, l_altt;
X	    int l_hzn;
X	    int l_status;
X	} Last;
X	/* must be in same order as the astro.h/screen.h #define's */
X	static Last last[NOBJ];
X	Last *lp;
X	int new;
X
X	lp = last + p;
X	if (same_cir (np, &lp->l_now) && same_lday (np, &lp->l_now)
X						&& lp->l_hzn == hzn) {
X	    *ltr = lp->l_ltr;
X	    *lts = lp->l_lts;
X	    *ltt = lp->l_ltt;
X	    *azr = lp->l_azr;
X	    *azs = lp->l_azs;
X	    *altt = lp->l_altt;
X	    *status = lp->l_status;
X	    new = 0;
X	} else {
X	    *status = 0;
X	    iterative_riset (p, np, hzn, ltr, lts, ltt, azr, azs, altt, status);
X	    lp->l_ltr = *ltr;
X	    lp->l_lts = *lts;
X	    lp->l_ltt = *ltt;
X	    lp->l_azr = *azr;
X	    lp->l_azs = *azs;
X	    lp->l_altt = *altt;
X	    lp->l_status = *status;
X	    lp->l_hzn = hzn;
X	    lp->l_now = *np;
X	    new = 1;
X	}
X	return (new);
X}
X
Xstatic
Xiterative_riset (p, np, hzn, ltr, lts, ltt, azr, azs, altt, status)
Xint p;
XNow *np;
Xint hzn;
Xdouble *ltr, *lts, *ltt;	/* local times of rise, set and transit */
Xdouble *azr, *azs, *altt;/* local azimuths of rise, set and transit altitude */
Xint *status;
X{
X#define	MAXPASSES	6
X	double lstr, lsts, lstt; /* local sidereal times of rising/setting */
X	double mjd0;		/* mjd estimates of rise/set event */
X	double lnoon;		/* mjd of local noon */
X	double x;		/* discarded tmp value */
X	Now n;			/* just used to call now_lst() */
X	double lst;		/* lst at local noon */
X	double diff, lastdiff;	/* iterative improvement to mjd0 */
X	int pass;
X	int rss;
X
X	/* first approximation is to find rise/set times of a fixed object
X	 * in its position at local noon.
X	 */
X	lnoon = mjd_day(mjd - tz/24.0) + (12.0 + tz)/24.0; /*mjd of local noon*/
X	n.n_mjd = lnoon;
X	n.n_lng = lng;
X	now_lst (&n, &lst);	/* lst at local noon */
X	mjd0 = lnoon;
X	stationary_riset (p,mjd0,np,hzn,&lstr,&lsts,&lstt,&x,&x,&x,&rss);
X    chkrss:
X	switch (rss) {
X	case  0:  break;
X	case  1: *status = RS_NEVERUP; return;
X	case -1: *status = RS_CIRCUMPOLAR; goto transit;
X	default: *status = RS_ERROR; return;
X	}
X
X	/* find a better approximation to the rising circumstances based on
X	 * more passes, each using a "fixed" object at the location at
X	 * previous approximation of the rise time.
X	 */
X	lastdiff = 1000.0;
X	for (pass = 1; pass < MAXPASSES; pass++) {
X	    diff = (lstr - lst)*SIDRATE; /* next guess at rise time wrt noon */
X	    if (diff > 12.0)
X		diff -= 24.0*SIDRATE;	/* not tomorrow, today */
X	    else if (diff < -12.0)
X		diff += 24.0*SIDRATE;	/* not yesterday, today */
X	    mjd0 = lnoon + diff/24.0;	/* next guess at mjd of rise */
X	    stationary_riset (p,mjd0,np,hzn,&lstr,&x,&x,azr,&x,&x,&rss);
X	    if (rss != 0) goto chkrss;
X	    if (fabs (diff - lastdiff) < 0.25/60.0)
X		break; 			/* converged to better than 15 secs */
X	    lastdiff = diff;
X	}
X	if (pass == MAXPASSES)
X	    *status |= RS_NORISE;	/* didn't converge - no rise today */
X	else {
X	    *ltr = 12.0 + diff;
X	    if (p != MOON &&
X		    (*ltr <= 24.0*(1.0-SIDRATE) || *ltr >= 24.0*SIDRATE))
X		*status |= RS_2RISES;
X	}
X
X	/* find a better approximation to the setting circumstances based on
X	 * more passes, each using a "fixed" object at the location at
X	 * previous approximation of the set time.
X	 */
X	lastdiff = 1000.0;
X	for (pass = 1; pass < MAXPASSES; pass++) {
X	    diff = (lsts - lst)*SIDRATE; /* next guess at set time wrt noon */
X	    if (diff > 12.0)
X		diff -= 24.0*SIDRATE;	/* not tomorrow, today */
X	    else if (diff < -12.0)
X		diff += 24.0*SIDRATE;	/* not yesterday, today */
X	    mjd0 = lnoon + diff/24.0;	/* next guess at mjd of set */
X	    stationary_riset (p,mjd0,np,hzn,&x,&lsts,&x,&x,azs,&x,&rss);
X	    if (rss != 0) goto chkrss;
X	    if (fabs (diff - lastdiff) < 0.25/60.0)
X		break; 			/* converged to better than 15 secs */
X	    lastdiff = diff;
X	}
X	if (pass == MAXPASSES)
X	    *status |= RS_NOSET;	/* didn't converge - no set today */
X	else {
X	    *lts = 12.0 + diff;
X	    if (p != MOON &&
X		    (*lts <= 24.0*(1.0-SIDRATE) || *lts >= 24.0*SIDRATE))
X		*status |= RS_2SETS;
X	}
X
X    transit:
X	/* find a better approximation to the transit circumstances based on
X	 * more passes, each using a "fixed" object at the location at
X	 * previous approximation of the transit time.
X	 */
X	lastdiff = 1000.0;
X	for (pass = 1; pass < MAXPASSES; pass++) {
X	    diff = (lstt - lst)*SIDRATE; /*next guess at transit time wrt noon*/
X	    if (diff > 12.0)
X		diff -= 24.0*SIDRATE;	/* not tomorrow, today */
X	    else if (diff < -12.0)
X		diff += 24.0*SIDRATE;	/* not yesterday, today */
X	    mjd0 = lnoon + diff/24.0;	/* next guess at mjd of set */
X	    stationary_riset (p,mjd0,np,hzn,&x,&x,&lstt,&x,&x,altt,&rss);
X	    if (fabs (diff - lastdiff) < 0.25/60.0)
X		break; 			/* converged to better than 15 secs */
X	    lastdiff = diff;
X	}
X	if (pass == MAXPASSES)
X	    *status |= RS_NOTRANS;	/* didn't converge - no transit today */
X	else {
X	    *ltt = 12.0 + diff;
X	    if (p != MOON &&
X		    (*ltt <= 24.0*(1.0-SIDRATE) || *ltt >= 24.0*SIDRATE))
X		*status |= RS_2TRANS;
X	}
X}
X
Xstatic
Xstationary_riset (p, mjd0, np, hzn, lstr, lsts, lstt, azr, azs, altt, status)
Xint p;
Xdouble mjd0;
XNow *np;
Xint hzn;
Xdouble *lstr, *lsts, *lstt;
Xdouble *azr, *azs, *altt;
Xint *status;
X{
X	extern void bye();
X	double dis;
X	Now n;
X	Sky s;
X
X	switch (hzn) {
X	case STDHZN:
X	    /* nominal atmospheric refraction.
X	     * then add nominal moon or sun semi-diameter, as appropriate.
X	     */
X	    dis = STDREF;
X	    break;
X	case TWILIGHT:
X	    if (p != SUN) {
X		f_msg ("Non-sun twilight bug!");
X		bye();
X	    }
X	    dis = TWIREF;
X	    break;
X	default:
X	    /* horizon displacement is refraction plus object's semi-diameter */
X	    unrefract (pressure, temp, 0.0, &dis);
X	    dis = -dis;
X	    n = *np;
X	    n.n_mjd = mjd0;
X	    (void) body_cir (p, 0.0, &n, &s);
X	    dis += degrad(s.s_size/3600./2.0);
X	}
X
X	switch (p) {
X	case SUN:
X	    if (hzn == STDHZN)
X		dis += degrad (32./60./2.);
X	    fixedsunriset (mjd0,np,dis,lstr,lsts,lstt,azr,azs,altt,status);
X	    break;
X	case MOON:
X	    if (hzn == STDHZN)
X		dis += degrad (32./60./2.);
X	    fixedmoonriset (mjd0,np,dis,lstr,lsts,lstt,azr,azs,altt,status);
X	    break;
X	default:
X	    if (hzn == STDHZN) {
X		/* assume planets have negligible diameters.
X		 * also, need to set s if hzn was STDHZN.
X		 */
X		n = *np;
X		n.n_mjd = mjd0;
X		(void) body_cir (p, 0.0, &n, &s);
X	    }
X	    riset (s.s_ra, s.s_dec, lat, dis, lstr, lsts, azr, azs, status);
X	    transit (s.s_ra, s.s_dec, np, lstt, altt);
X	}
X}
X
X/* find the local rise/set sidereal times and azimuths of an object fixed
X * at the ra/dec of the sun on the given mjd time as seen from lat.
X * times are for the upper limb. dis should account for refraction and
X *   sun's semi-diameter; we add corrections for nutation and aberration.
X */
Xstatic
Xfixedsunriset (mjd0, np, dis, lstr, lsts, lstt, azr, azs, altt, status)
Xdouble mjd0;
XNow *np;
Xdouble dis;
Xdouble *lstr, *lsts, *lstt;
Xdouble *azr, *azs, *altt;
Xint *status;
X{
X	double lsn, rsn;
X	double deps, dpsi;
X	double r, d;
X
X	/* find ecliptic position of sun at mjd */
X	sunpos (mjd0, &lsn, &rsn);
X
X	/* allow for nutation and 20.4" light travel time */
X	nutation (mjd0, &deps, &dpsi);
X        lsn += dpsi;
X        lsn -= degrad(20.4/3600.0);
X
X	/* convert ecliptic to equatorial coords */
X	ecl_eq (mjd0, 0.0, lsn, &r, &d);
X
X	/* find circumstances for given horizon displacement */
X	riset (r, d, lat, dis, lstr, lsts, azr, azs, status);
X	transit (r, d, np, lstt, altt);
X}
X
X/* find the local sidereal rise/set times and azimuths of an object fixed
X * at the ra/dec of the moon on the given mjd time as seen from lat.
X * times are for the upper limb. dis should account for refraction and moon's
X *    semi-diameter; we add corrections for parallax, and nutation.
X * accuracy is to nearest minute.
X */
Xstatic
Xfixedmoonriset (mjd0, np, dis, lstr, lsts, lstt, azr, azs, altt, status)
Xdouble mjd0;
XNow *np;
Xdouble dis;
Xdouble *lstr, *lsts, *lstt;
Xdouble *azr, *azs, *altt;
Xint *status;
X{
X	double lam, bet, hp;
X	double deps, dpsi;
X	double r, d;
X	double ha;
X
X	/* find geocentric ecliptic location and equatorial horizontal parallax
X	 * of moon at mjd.
X	 */
X	moon (mjd0, &lam, &bet, &hp);
X
X	/* allow for nutation */
X	nutation (mjd0, &deps, &dpsi);
X        lam += dpsi;
X
X	/* convert ecliptic to equatorial coords */
X	ecl_eq (mjd0, bet, lam, &r, &d);
X
X	/* find local sidereal times of rise/set times/azimuths for given
X	 * equatorial coords, allowing for
X	 * .27249*sin(hp)   parallax (hp is radius of earth from moon;
X	 *                  .27249 is radius of moon from earth where
X	 *                  the ratio is the dia_moon/dia_earth).
X	 * hp               nominal angular earth radius. subtract because
X	 *                  tangential line-of-sight makes moon appear lower
X	 *                  as move out from center of earth.
X	 */
X	dis += .27249*sin(hp) - hp;
X	riset (r, d, lat, dis, lstr, lsts, azr, azs, status);
X
X	/* account for parallax on the meridian (0 hour-angle).
X	 * TODO: is this really right? other stuff too? better way?? help!
X	 */
X	ta_par (0.0, d, lat, height, hp, &ha, &d);
X	transit (r+ha, d, np, lstt, altt);
X}
X
X/* find when and how hi object at (r,d) is when it transits. */
Xstatic
Xtransit (r, d, np, lstt, altt)
Xdouble r, d;	/* ra and dec, rads */
XNow *np;	/* for refraction info */
Xdouble *lstt;	/* local sidereal time of transit */
Xdouble *altt;	/* local, refracted, altitude at time of transit */
X{
X	*lstt = radhr(r);
X	*altt = PI/2 - lat + d;
X	if (*altt > PI/2)
X	    *altt = PI - *altt;
X	refract (pressure, temp, *altt, altt);
X}
EOFxEOF
len=`wc -c < riset_c.c`
if expr $len != 10652 > /dev/null
then echo Length of riset_c.c is $len but it should be 10652.
fi
echo x sel_fld.c
sed -e 's/^X//' << 'EOFxEOF' > sel_fld.c
X#include <stdio.h>
X#include "screen.h"
X
X/* table of the fields, with flags indicating which menu(s) they are on and
X * whether pickable for changing or plotting.
X * N.B. type must be long enough to hold 16 bits.
X */
Xstatic int fields[] = {
X    rcfpack (R_ALTM,	C_ALTM,		F_MMNU|F_CHG),
X    rcfpack (R_DAWN,	C_DAWN,		F_MMNU|F_CHG),
X    rcfpack (R_DAWN,	C_DAWNV,	F_MMNU|F_PLT),
X    rcfpack (R_DUSK,	C_DUSK,		F_MMNU|F_CHG),
X    rcfpack (R_DUSK,	C_DUSKV,	F_MMNU|F_PLT),
X    rcfpack (R_EPOCH,	C_EPOCHV,	F_MMNU|F_CHG),
X    rcfpack (R_HEIGHT,	C_HEIGHTV,	F_MMNU|F_CHG|F_PLT),
X    rcfpack (R_JD,	C_JDV,		F_MMNU|F_CHG|F_PLT),
X    rcfpack (R_JUPITER,	C_ALT,		F_MNU1|F_PLT),
X    rcfpack (R_JUPITER,	C_AZ,		F_MNU1|F_PLT),
X    rcfpack (R_JUPITER,	C_DEC,		F_MNU1|F_PLT),
X    rcfpack (R_JUPITER,	C_EDIST,	F_MNU1|F_PLT),
X    rcfpack (R_JUPITER,	C_ELONG,	F_MNU1|F_PLT),
X    rcfpack (R_JUPITER,	C_HLAT,		F_MNU1|F_PLT),
X    rcfpack (R_JUPITER,	C_HLONG,	F_MNU1|F_PLT),
X    rcfpack (R_JUPITER,	C_MAG,		F_MNU1|F_PLT),
X    rcfpack (R_JUPITER,	C_MARS,		F_MNU3|F_PLT),
X    rcfpack (R_JUPITER,	C_MERCURY,	F_MNU3|F_PLT),
X    rcfpack (R_JUPITER,	C_MOON,		F_MNU3|F_PLT),
X    rcfpack (R_JUPITER,	C_NEPTUNE,	F_MNU3|F_PLT),
X    rcfpack (R_JUPITER,	C_OBJ,		F_MMNU|F_CHG),
X    rcfpack (R_JUPITER,	C_OBJX,		F_MNU3|F_PLT),
X    rcfpack (R_JUPITER,	C_PHASE,	F_MNU1|F_PLT),
X    rcfpack (R_JUPITER,	C_PLUTO,	F_MNU3|F_PLT),
X    rcfpack (R_JUPITER,	C_RA,		F_MNU1|F_PLT),
X    rcfpack (R_JUPITER,	C_RISEAZ,	F_MNU2|F_PLT),
X    rcfpack (R_JUPITER,	C_RISETM,	F_MNU2|F_PLT),
X    rcfpack (R_JUPITER,	C_SATURN,	F_MNU3|F_PLT),
X    rcfpack (R_JUPITER,	C_SDIST,	F_MNU1|F_PLT),
X    rcfpack (R_JUPITER,	C_SETAZ,	F_MNU2|F_PLT),
X    rcfpack (R_JUPITER,	C_SETTM,	F_MNU2|F_PLT),
X    rcfpack (R_JUPITER,	C_SIZE,		F_MNU1|F_PLT),
X    rcfpack (R_JUPITER,	C_SUN,		F_MNU3|F_PLT),
X    rcfpack (R_JUPITER,	C_TRANSALT,	F_MNU2|F_PLT),
X    rcfpack (R_JUPITER,	C_TRANSTM,	F_MNU2|F_PLT),
X    rcfpack (R_JUPITER,	C_TUP,		F_MNU2|F_PLT),
X    rcfpack (R_JUPITER,	C_URANUS,	F_MNU3|F_PLT),
X    rcfpack (R_JUPITER,	C_VENUS,	F_MNU3|F_PLT),
X    rcfpack (R_LAT,	C_LATV,		F_MMNU|F_CHG|F_PLT),
X    rcfpack (R_LD,	C_LD,		F_MMNU|F_PLT|F_CHG),
X    rcfpack (R_LON,	C_LON,		F_MMNU|F_CHG),
X    rcfpack (R_LON,	C_LONV,		F_MMNU|F_PLT),
X    rcfpack (R_LONG,	C_LONGV,	F_MMNU|F_CHG|F_PLT),
X    rcfpack (R_LST,	C_LSTV,		F_MMNU|F_CHG|F_PLT),
X    rcfpack (R_LT,	C_LT,		F_MMNU|F_CHG|F_PLT),
X    rcfpack (R_MARS,	C_ALT,		F_MNU1|F_PLT),
X    rcfpack (R_MARS,	C_AZ,		F_MNU1|F_PLT),
X    rcfpack (R_MARS,	C_DEC,		F_MNU1|F_PLT),
X    rcfpack (R_MARS,	C_EDIST,	F_MNU1|F_PLT),
X    rcfpack (R_MARS,	C_ELONG,	F_MNU1|F_PLT),
X    rcfpack (R_MARS,	C_HLAT,		F_MNU1|F_PLT),
X    rcfpack (R_MARS,	C_HLONG,	F_MNU1|F_PLT),
X    rcfpack (R_MARS,	C_JUPITER,	F_MNU3|F_PLT),
X    rcfpack (R_MARS,	C_MAG,		F_MNU1|F_PLT),
X    rcfpack (R_MARS,	C_MERCURY,	F_MNU3|F_PLT),
X    rcfpack (R_MARS,	C_MOON,		F_MNU3|F_PLT),
X    rcfpack (R_MARS,	C_NEPTUNE,	F_MNU3|F_PLT),
X    rcfpack (R_MARS,	C_OBJ,		F_MMNU|F_CHG),
X    rcfpack (R_MARS,	C_OBJX,		F_MNU3|F_PLT),
X    rcfpack (R_MARS,	C_PHASE,	F_MNU1|F_PLT),
X    rcfpack (R_MARS,	C_PLUTO,	F_MNU3|F_PLT),
X    rcfpack (R_MARS,	C_RA,		F_MNU1|F_PLT),
X    rcfpack (R_MARS,	C_RISEAZ,	F_MNU2|F_PLT),
X    rcfpack (R_MARS,	C_RISETM,	F_MNU2|F_PLT),
X    rcfpack (R_MARS,	C_SATURN,	F_MNU3|F_PLT),
X    rcfpack (R_MARS,	C_SDIST,	F_MNU1|F_PLT),
X    rcfpack (R_MARS,	C_SETAZ,	F_MNU2|F_PLT),
X    rcfpack (R_MARS,	C_SETTM,	F_MNU2|F_PLT),
X    rcfpack (R_MARS,	C_SIZE,		F_MNU1|F_PLT),
X    rcfpack (R_MARS,	C_SUN,		F_MNU3|F_PLT),
X    rcfpack (R_MARS,	C_TRANSALT,	F_MNU2|F_PLT),
X    rcfpack (R_MARS,	C_TRANSTM,	F_MNU2|F_PLT),
X    rcfpack (R_MARS,	C_TUP,		F_MNU2|F_PLT),
X    rcfpack (R_MARS,	C_URANUS,	F_MNU3|F_PLT),
X    rcfpack (R_MARS,	C_VENUS,	F_MNU3|F_PLT),
X    rcfpack (R_MERCURY,	C_ALT,		F_MNU1|F_PLT),
X    rcfpack (R_MERCURY,	C_AZ,		F_MNU1|F_PLT),
X    rcfpack (R_MERCURY,	C_DEC,		F_MNU1|F_PLT),
X    rcfpack (R_MERCURY,	C_EDIST,	F_MNU1|F_PLT),
X    rcfpack (R_MERCURY,	C_ELONG,	F_MNU1|F_PLT),
X    rcfpack (R_MERCURY,	C_HLAT,		F_MNU1|F_PLT),
X    rcfpack (R_MERCURY,	C_HLONG,	F_MNU1|F_PLT),
X    rcfpack (R_MERCURY,	C_JUPITER,	F_MNU3|F_PLT),
X    rcfpack (R_MERCURY,	C_MAG,		F_MNU1|F_PLT),
X    rcfpack (R_MERCURY,	C_MARS,		F_MNU3|F_PLT),
X    rcfpack (R_MERCURY,	C_MOON,		F_MNU3|F_PLT),
X    rcfpack (R_MERCURY,	C_NEPTUNE,	F_MNU3|F_PLT),
X    rcfpack (R_MERCURY,	C_OBJ,		F_MMNU|F_CHG),
X    rcfpack (R_MERCURY,	C_OBJX,		F_MNU3|F_PLT),
X    rcfpack (R_MERCURY,	C_PHASE,	F_MNU1|F_PLT),
X    rcfpack (R_MERCURY,	C_PLUTO,	F_MNU3|F_PLT),
X    rcfpack (R_MERCURY,	C_RA,		F_MNU1|F_PLT),
X    rcfpack (R_MERCURY,	C_RISEAZ,	F_MNU2|F_PLT),
X    rcfpack (R_MERCURY,	C_RISETM,	F_MNU2|F_PLT),
X    rcfpack (R_MERCURY,	C_SATURN,	F_MNU3|F_PLT),
X    rcfpack (R_MERCURY,	C_SDIST,	F_MNU1|F_PLT),
X    rcfpack (R_MERCURY,	C_SETAZ,	F_MNU2|F_PLT),
X    rcfpack (R_MERCURY,	C_SETTM,	F_MNU2|F_PLT),
X    rcfpack (R_MERCURY,	C_SIZE,		F_MNU1|F_PLT),
X    rcfpack (R_MERCURY,	C_SUN,		F_MNU3|F_PLT),
X    rcfpack (R_MERCURY,	C_TRANSALT,	F_MNU2|F_PLT),
X    rcfpack (R_MERCURY,	C_TRANSTM,	F_MNU2|F_PLT),
X    rcfpack (R_MERCURY,	C_TUP,		F_MNU2|F_PLT),
X    rcfpack (R_MERCURY,	C_URANUS,	F_MNU3|F_PLT),
X    rcfpack (R_MERCURY,	C_VENUS,	F_MNU3|F_PLT),
X    rcfpack (R_MOON,	C_ALT,		F_MNU1|F_PLT),
X    rcfpack (R_MOON,	C_AZ,		F_MNU1|F_PLT),
X    rcfpack (R_MOON,	C_DEC,		F_MNU1|F_PLT),
X    rcfpack (R_MOON,	C_EDIST,	F_MNU1|F_PLT),
X    rcfpack (R_MOON,	C_ELONG,	F_MNU1|F_PLT),
X    rcfpack (R_MOON,	C_JUPITER,	F_MNU3|F_PLT),
X    rcfpack (R_MOON,	C_MAG,		F_MNU1|F_PLT),
X    rcfpack (R_MOON,	C_MARS,		F_MNU3|F_PLT),
X    rcfpack (R_MOON,	C_MERCURY,	F_MNU3|F_PLT),
X    rcfpack (R_MOON,	C_NEPTUNE,	F_MNU3|F_PLT),
X    rcfpack (R_MOON,	C_OBJ,		F_MMNU|F_CHG),
X    rcfpack (R_MOON,	C_OBJX,		F_MNU3|F_PLT),
X    rcfpack (R_MOON,	C_PHASE,	F_MNU1|F_PLT),
X    rcfpack (R_MOON,	C_PLUTO,	F_MNU3|F_PLT),
X    rcfpack (R_MOON,	C_RA,		F_MNU1|F_PLT),
X    rcfpack (R_MOON,	C_RISEAZ,	F_MNU2|F_PLT),
X    rcfpack (R_MOON,	C_RISETM,	F_MNU2|F_PLT),
X    rcfpack (R_MOON,	C_SATURN,	F_MNU3|F_PLT),
X    rcfpack (R_MOON,	C_SDIST,	F_MNU1|F_PLT),
X    rcfpack (R_MOON,	C_SETAZ,	F_MNU2|F_PLT),
X    rcfpack (R_MOON,	C_SETTM,	F_MNU2|F_PLT),
X    rcfpack (R_MOON,	C_SIZE,		F_MNU1|F_PLT),
X    rcfpack (R_MOON,	C_SUN,		F_MNU3|F_PLT),
X    rcfpack (R_MOON,	C_TRANSALT,	F_MNU2|F_PLT),
X    rcfpack (R_MOON,	C_TRANSTM,	F_MNU2|F_PLT),
X    rcfpack (R_MOON,	C_TUP,		F_MNU2|F_PLT),
X    rcfpack (R_MOON,	C_URANUS,	F_MNU3|F_PLT),
X    rcfpack (R_MOON,	C_VENUS,	F_MNU3|F_PLT),
X    rcfpack (R_NEPTUNE,	C_ALT,		F_MNU1|F_PLT),
X    rcfpack (R_NEPTUNE,	C_AZ,		F_MNU1|F_PLT),
X    rcfpack (R_NEPTUNE,	C_DEC,		F_MNU1|F_PLT),
X    rcfpack (R_NEPTUNE,	C_EDIST,	F_MNU1|F_PLT),
X    rcfpack (R_NEPTUNE,	C_ELONG,	F_MNU1|F_PLT),
X    rcfpack (R_NEPTUNE,	C_HLAT,		F_MNU1|F_PLT),
X    rcfpack (R_NEPTUNE,	C_HLONG,	F_MNU1|F_PLT),
X    rcfpack (R_NEPTUNE,	C_JUPITER,	F_MNU3|F_PLT),
X    rcfpack (R_NEPTUNE,	C_MAG,		F_MNU1|F_PLT),
X    rcfpack (R_NEPTUNE,	C_MARS,		F_MNU3|F_PLT),
X    rcfpack (R_NEPTUNE,	C_MERCURY,	F_MNU3|F_PLT),
X    rcfpack (R_NEPTUNE,	C_MOON,		F_MNU3|F_PLT),
X    rcfpack (R_NEPTUNE,	C_OBJ,		F_MMNU|F_CHG),
X    rcfpack (R_NEPTUNE,	C_OBJX,		F_MNU3|F_PLT),
X    rcfpack (R_NEPTUNE,	C_PHASE,	F_MNU1|F_PLT),
X    rcfpack (R_NEPTUNE,	C_PLUTO,	F_MNU3|F_PLT),
X    rcfpack (R_NEPTUNE,	C_RA,		F_MNU1|F_PLT),
X    rcfpack (R_NEPTUNE,	C_RISEAZ,	F_MNU2|F_PLT),
X    rcfpack (R_NEPTUNE,	C_RISETM,	F_MNU2|F_PLT),
X    rcfpack (R_NEPTUNE,	C_SATURN,	F_MNU3|F_PLT),
X    rcfpack (R_NEPTUNE,	C_SDIST,	F_MNU1|F_PLT),
X    rcfpack (R_NEPTUNE,	C_SETAZ,	F_MNU2|F_PLT),
X    rcfpack (R_NEPTUNE,	C_SETTM,	F_MNU2|F_PLT),
X    rcfpack (R_NEPTUNE,	C_SIZE,		F_MNU1|F_PLT),
X    rcfpack (R_NEPTUNE,	C_SUN,		F_MNU3|F_PLT),
X    rcfpack (R_NEPTUNE,	C_TRANSALT,	F_MNU2|F_PLT),
X    rcfpack (R_NEPTUNE,	C_TRANSTM,	F_MNU2|F_PLT),
X    rcfpack (R_NEPTUNE,	C_TUP,		F_MNU2|F_PLT),
X    rcfpack (R_NEPTUNE,	C_URANUS,	F_MNU3|F_PLT),
X    rcfpack (R_NEPTUNE,	C_VENUS,	F_MNU3|F_PLT),
X    rcfpack (R_NSTEP,	C_NSTEPV,	F_MMNU|F_CHG),
X    rcfpack (R_OBJX,	C_ALT,		F_MNU1|F_PLT),
X    rcfpack (R_OBJX,	C_AZ,		F_MNU1|F_PLT),
X    rcfpack (R_OBJX,	C_DEC,		F_MNU1|F_PLT),
X    rcfpack (R_OBJX,	C_EDIST,	F_MNU1|F_PLT),
X    rcfpack (R_OBJX,	C_ELONG,	F_MNU1|F_PLT),
X    rcfpack (R_OBJX,	C_HLAT,		F_MNU1|F_PLT),
X    rcfpack (R_OBJX,	C_HLONG,	F_MNU1|F_PLT),
X    rcfpack (R_OBJX,	C_JUPITER,	F_MNU3|F_PLT),
X    rcfpack (R_OBJX,	C_MAG,		F_MNU1|F_PLT),
X    rcfpack (R_OBJX,	C_MARS,		F_MNU3|F_PLT),
X    rcfpack (R_OBJX,	C_MERCURY,	F_MNU3|F_PLT),
X    rcfpack (R_OBJX,	C_MOON,		F_MNU3|F_PLT),
X    rcfpack (R_OBJX,	C_NEPTUNE,	F_MNU3|F_PLT),
X    rcfpack (R_OBJX,	C_OBJ,		F_MMNU|F_CHG),
X    rcfpack (R_OBJX,	C_PHASE,	F_MNU1|F_PLT),
X    rcfpack (R_OBJX,	C_PLUTO,	F_MNU3|F_PLT),
X    rcfpack (R_OBJX,	C_RA,		F_MNU1|F_PLT),
X    rcfpack (R_OBJX,	C_RISEAZ,	F_MNU2|F_PLT),
X    rcfpack (R_OBJX,	C_RISETM,	F_MNU2|F_PLT),
X    rcfpack (R_OBJX,	C_SATURN,	F_MNU3|F_PLT),
X    rcfpack (R_OBJX,	C_SDIST,	F_MNU1|F_PLT),
X    rcfpack (R_OBJX,	C_SETAZ,	F_MNU2|F_PLT),
X    rcfpack (R_OBJX,	C_SETTM,	F_MNU2|F_PLT),
X    rcfpack (R_OBJX,	C_SUN,		F_MNU3|F_PLT),
X    rcfpack (R_OBJX,	C_TRANSALT,	F_MNU2|F_PLT),
X    rcfpack (R_OBJX,	C_TRANSTM,	F_MNU2|F_PLT),
X    rcfpack (R_OBJX,	C_TUP,		F_MNU2|F_PLT),
X    rcfpack (R_OBJX,	C_URANUS,	F_MNU3|F_PLT),
X    rcfpack (R_OBJX,	C_VENUS,	F_MNU3|F_PLT),
X    rcfpack (R_PLOT,	C_PLOT,		F_MMNU|F_CHG),
X    rcfpack (R_PLUTO,	C_ALT,		F_MNU1|F_PLT),
X    rcfpack (R_PLUTO,	C_AZ,		F_MNU1|F_PLT),
X    rcfpack (R_PLUTO,	C_DEC,		F_MNU1|F_PLT),
X    rcfpack (R_PLUTO,	C_EDIST,	F_MNU1|F_PLT),
X    rcfpack (R_PLUTO,	C_ELONG,	F_MNU1|F_PLT),
X    rcfpack (R_PLUTO,	C_HLAT,		F_MNU1|F_PLT),
X    rcfpack (R_PLUTO,	C_HLONG,	F_MNU1|F_PLT),
X    rcfpack (R_PLUTO,	C_JUPITER,	F_MNU3|F_PLT),
X    rcfpack (R_PLUTO,	C_MAG,		F_MNU1|F_PLT),
X    rcfpack (R_PLUTO,	C_MARS,		F_MNU3|F_PLT),
X    rcfpack (R_PLUTO,	C_MERCURY,	F_MNU3|F_PLT),
X    rcfpack (R_PLUTO,	C_MOON,		F_MNU3|F_PLT),
X    rcfpack (R_PLUTO,	C_NEPTUNE,	F_MNU3|F_PLT),
X    rcfpack (R_PLUTO,	C_OBJ,		F_MMNU|F_CHG),
X    rcfpack (R_PLUTO,	C_OBJX,		F_MNU3|F_PLT),
X    rcfpack (R_PLUTO,	C_PHASE,	F_MNU1|F_PLT),
X    rcfpack (R_PLUTO,	C_RA,		F_MNU1|F_PLT),
X    rcfpack (R_PLUTO,	C_RISEAZ,	F_MNU2|F_PLT),
X    rcfpack (R_PLUTO,	C_RISETM,	F_MNU2|F_PLT),
X    rcfpack (R_PLUTO,	C_SATURN,	F_MNU3|F_PLT),
X    rcfpack (R_PLUTO,	C_SDIST,	F_MNU1|F_PLT),
X    rcfpack (R_PLUTO,	C_SETAZ,	F_MNU2|F_PLT),
X    rcfpack (R_PLUTO,	C_SETTM,	F_MNU2|F_PLT),
X    rcfpack (R_PLUTO,	C_SIZE,		F_MNU1|F_PLT),
X    rcfpack (R_PLUTO,	C_SUN,		F_MNU3|F_PLT),
X    rcfpack (R_PLUTO,	C_TRANSALT,	F_MNU2|F_PLT),
X    rcfpack (R_PLUTO,	C_TRANSTM,	F_MNU2|F_PLT),
X    rcfpack (R_PLUTO,	C_TUP,		F_MNU2|F_PLT),
X    rcfpack (R_PLUTO,	C_URANUS,	F_MNU3|F_PLT),
X    rcfpack (R_PLUTO,	C_VENUS,	F_MNU3|F_PLT),
X    rcfpack (R_PRES,	C_PRESV,	F_MMNU|F_CHG|F_PLT),
X    rcfpack (R_SATURN,	C_ALT,		F_MNU1|F_PLT),
X    rcfpack (R_SATURN,	C_AZ,		F_MNU1|F_PLT),
X    rcfpack (R_SATURN,	C_DEC,		F_MNU1|F_PLT),
X    rcfpack (R_SATURN,	C_EDIST,	F_MNU1|F_PLT),
X    rcfpack (R_SATURN,	C_ELONG,	F_MNU1|F_PLT),
X    rcfpack (R_SATURN,	C_HLAT,		F_MNU1|F_PLT),
X    rcfpack (R_SATURN,	C_HLONG,	F_MNU1|F_PLT),
X    rcfpack (R_SATURN,	C_JUPITER,	F_MNU3|F_PLT),
X    rcfpack (R_SATURN,	C_MAG,		F_MNU1|F_PLT),
X    rcfpack (R_SATURN,	C_MARS,		F_MNU3|F_PLT),
X    rcfpack (R_SATURN,	C_MERCURY,	F_MNU3|F_PLT),
X    rcfpack (R_SATURN,	C_MOON,		F_MNU3|F_PLT),
X    rcfpack (R_SATURN,	C_NEPTUNE,	F_MNU3|F_PLT),
X    rcfpack (R_SATURN,	C_OBJ,		F_MMNU|F_CHG),
X    rcfpack (R_SATURN,	C_OBJX,		F_MNU3|F_PLT),
X    rcfpack (R_SATURN,	C_PHASE,	F_MNU1|F_PLT),
X    rcfpack (R_SATURN,	C_PLUTO,	F_MNU3|F_PLT),
X    rcfpack (R_SATURN,	C_RA,		F_MNU1|F_PLT),
X    rcfpack (R_SATURN,	C_RISEAZ,	F_MNU2|F_PLT),
X    rcfpack (R_SATURN,	C_RISETM,	F_MNU2|F_PLT),
X    rcfpack (R_SATURN,	C_SDIST,	F_MNU1|F_PLT),
X    rcfpack (R_SATURN,	C_SETAZ,	F_MNU2|F_PLT),
X    rcfpack (R_SATURN,	C_SETTM,	F_MNU2|F_PLT),
X    rcfpack (R_SATURN,	C_SIZE,		F_MNU1|F_PLT),
X    rcfpack (R_SATURN,	C_SUN,		F_MNU3|F_PLT),
X    rcfpack (R_SATURN,	C_TRANSALT,	F_MNU2|F_PLT),
X    rcfpack (R_SATURN,	C_TRANSTM,	F_MNU2|F_PLT),
X    rcfpack (R_SATURN,	C_TUP,		F_MNU2|F_PLT),
X    rcfpack (R_SATURN,	C_URANUS,	F_MNU3|F_PLT),
X    rcfpack (R_SATURN,	C_VENUS,	F_MNU3|F_PLT),
X    rcfpack (R_SRCH,	C_SRCH,		F_MMNU|F_CHG|F_PLT),
X    rcfpack (R_STPSZ,	C_STPSZV,	F_MMNU|F_CHG),
X    rcfpack (R_SUN,	C_ALT,		F_MNU1|F_PLT),
X    rcfpack (R_SUN,	C_AZ,		F_MNU1|F_PLT),
X    rcfpack (R_SUN,	C_DEC,		F_MNU1|F_PLT),
X    rcfpack (R_SUN,	C_EDIST,	F_MNU1|F_PLT),
X    rcfpack (R_SUN,	C_HLONG,	F_MNU1|F_PLT),
X    rcfpack (R_SUN,	C_JUPITER,	F_MNU3|F_PLT),
X    rcfpack (R_SUN,	C_MAG,		F_MNU1|F_PLT),
X    rcfpack (R_SUN,	C_MARS,		F_MNU3|F_PLT),
X    rcfpack (R_SUN,	C_MERCURY,	F_MNU3|F_PLT),
X    rcfpack (R_SUN,	C_MOON,		F_MNU3|F_PLT),
X    rcfpack (R_SUN,	C_NEPTUNE,	F_MNU3|F_PLT),
X    rcfpack (R_SUN,	C_OBJ,		F_MMNU|F_CHG),
X    rcfpack (R_SUN,	C_OBJX,		F_MNU3|F_PLT),
X    rcfpack (R_SUN,	C_PLUTO,	F_MNU3|F_PLT),
X    rcfpack (R_SUN,	C_RA,		F_MNU1|F_PLT),
X    rcfpack (R_SUN,	C_RISEAZ,	F_MNU2|F_PLT),
X    rcfpack (R_SUN,	C_RISETM,	F_MNU2|F_PLT),
X    rcfpack (R_SUN,	C_SATURN,	F_MNU3|F_PLT),
X    rcfpack (R_SUN,	C_SETAZ,	F_MNU2|F_PLT),
X    rcfpack (R_SUN,	C_SETTM,	F_MNU2|F_PLT),
X    rcfpack (R_SUN,	C_SIZE,		F_MNU1|F_PLT),
X    rcfpack (R_SUN,	C_TRANSALT,	F_MNU2|F_PLT),
X    rcfpack (R_SUN,	C_TRANSTM,	F_MNU2|F_PLT),
X    rcfpack (R_SUN,	C_TUP,		F_MNU2|F_PLT),
X    rcfpack (R_SUN,	C_URANUS,	F_MNU3|F_PLT),
X    rcfpack (R_SUN,	C_VENUS,	F_MNU3|F_PLT),
X    rcfpack (R_TEMP,	C_TEMPV,	F_MMNU|F_CHG|F_PLT),
X    rcfpack (R_TZN,	C_TZN,		F_MMNU|F_CHG),
X    rcfpack (R_TZONE,	C_TZONEV,	F_MMNU|F_CHG),
X    rcfpack (R_UD,	C_UD,		F_MMNU|F_PLT|F_CHG),
X    rcfpack (R_URANUS,	C_ALT,		F_MNU1|F_PLT),
X    rcfpack (R_URANUS,	C_AZ,		F_MNU1|F_PLT),
X    rcfpack (R_URANUS,	C_DEC,		F_MNU1|F_PLT),
X    rcfpack (R_URANUS,	C_EDIST,	F_MNU1|F_PLT),
X    rcfpack (R_URANUS,	C_ELONG,	F_MNU1|F_PLT),
X    rcfpack (R_URANUS,	C_HLAT,		F_MNU1|F_PLT),
X    rcfpack (R_URANUS,	C_HLONG,	F_MNU1|F_PLT),
X    rcfpack (R_URANUS,	C_JUPITER,	F_MNU3|F_PLT),
X    rcfpack (R_URANUS,	C_MAG,		F_MNU1|F_PLT),
X    rcfpack (R_URANUS,	C_MARS,		F_MNU3|F_PLT),
X    rcfpack (R_URANUS,	C_MERCURY,	F_MNU3|F_PLT),
X    rcfpack (R_URANUS,	C_MOON,		F_MNU3|F_PLT),
X    rcfpack (R_URANUS,	C_NEPTUNE,	F_MNU3|F_PLT),
X    rcfpack (R_URANUS,	C_OBJ,		F_MMNU|F_CHG),
X    rcfpack (R_URANUS,	C_OBJX,		F_MNU3|F_PLT),
X    rcfpack (R_URANUS,	C_PHASE,	F_MNU1|F_PLT),
X    rcfpack (R_URANUS,	C_PLUTO,	F_MNU3|F_PLT),
X    rcfpack (R_URANUS,	C_RA,		F_MNU1|F_PLT),
X    rcfpack (R_URANUS,	C_RISEAZ,	F_MNU2|F_PLT),
X    rcfpack (R_URANUS,	C_RISETM,	F_MNU2|F_PLT),
X    rcfpack (R_URANUS,	C_SATURN,	F_MNU3|F_PLT),
X    rcfpack (R_URANUS,	C_SDIST,	F_MNU1|F_PLT),
X    rcfpack (R_URANUS,	C_SETAZ,	F_MNU2|F_PLT),
X    rcfpack (R_URANUS,	C_SETTM,	F_MNU2|F_PLT),
X    rcfpack (R_URANUS,	C_SIZE,		F_MNU1|F_PLT),
X    rcfpack (R_URANUS,	C_SUN,		F_MNU3|F_PLT),
X    rcfpack (R_URANUS,	C_TRANSALT,	F_MNU2|F_PLT),
X    rcfpack (R_URANUS,	C_TRANSTM,	F_MNU2|F_PLT),
X    rcfpack (R_URANUS,	C_TUP,		F_MNU2|F_PLT),
X    rcfpack (R_URANUS,	C_VENUS,	F_MNU3|F_PLT),
X    rcfpack (R_UT,	C_UTV,		F_MMNU|F_PLT|F_CHG),
X    rcfpack (R_VENUS,	C_ALT,		F_MNU1|F_PLT),
X    rcfpack (R_VENUS,	C_AZ,		F_MNU1|F_PLT),
X    rcfpack (R_VENUS,	C_DEC,		F_MNU1|F_PLT),
X    rcfpack (R_VENUS,	C_EDIST,	F_MNU1|F_PLT),
X    rcfpack (R_VENUS,	C_ELONG,	F_MNU1|F_PLT),
X    rcfpack (R_VENUS,	C_HLAT,		F_MNU1|F_PLT),
X    rcfpack (R_VENUS,	C_HLONG,	F_MNU1|F_PLT),
X    rcfpack (R_VENUS,	C_JUPITER,	F_MNU3|F_PLT),
X    rcfpack (R_VENUS,	C_MAG,		F_MNU1|F_PLT),
X    rcfpack (R_VENUS,	C_MARS,		F_MNU3|F_PLT),
X    rcfpack (R_VENUS,	C_MERCURY,	F_MNU3|F_PLT),
X    rcfpack (R_VENUS,	C_MOON,		F_MNU3|F_PLT),
X    rcfpack (R_VENUS,	C_NEPTUNE,	F_MNU3|F_PLT),
X    rcfpack (R_VENUS,	C_OBJ,		F_MMNU|F_CHG),
X    rcfpack (R_VENUS,	C_OBJX,		F_MNU3|F_PLT),
X    rcfpack (R_VENUS,	C_PHASE,	F_MNU1|F_PLT),
X    rcfpack (R_VENUS,	C_PLUTO,	F_MNU3|F_PLT),
X    rcfpack (R_VENUS,	C_RA,		F_MNU1|F_PLT),
X    rcfpack (R_VENUS,	C_RISEAZ,	F_MNU2|F_PLT),
X    rcfpack (R_VENUS,	C_RISETM,	F_MNU2|F_PLT),
X    rcfpack (R_VENUS,	C_SATURN,	F_MNU3|F_PLT),
X    rcfpack (R_VENUS,	C_SDIST,	F_MNU1|F_PLT),
X    rcfpack (R_VENUS,	C_SETAZ,	F_MNU2|F_PLT),
X    rcfpack (R_VENUS,	C_SETTM,	F_MNU2|F_PLT),
X    rcfpack (R_VENUS,	C_SIZE,		F_MNU1|F_PLT),
X    rcfpack (R_VENUS,	C_SUN,		F_MNU3|F_PLT),
X    rcfpack (R_VENUS,	C_TRANSALT,	F_MNU2|F_PLT),
X    rcfpack (R_VENUS,	C_TRANSTM,	F_MNU2|F_PLT),
X    rcfpack (R_VENUS,	C_TUP,		F_MNU2|F_PLT),
X    rcfpack (R_VENUS,	C_URANUS,	F_MNU3|F_PLT),
X    rcfpack (R_WATCH,	C_WATCH,	F_MMNU|F_CHG),
X};
X#define	NFIELDS (sizeof(fields)/sizeof(fields[0]))
X
X/* let op select a field by moving around and hitting RETURN, or until see END.
X * also allow moving directly to a planet row using its name.
X * only allow fields with the given flag mask.
X * return the rcfpack()'d field, or 0 if typed END.
X * N.B. we might also exit() entirely by calling bye() if op types QUIT.
X */
Xsel_fld (r, c, flag, prmpt, help)
Xint r, c;	/* inial row, col */
Xint flag;
Xchar *prmpt, *help;
X{
X	extern void bye();
X	char *lastp;
X	int ch;
X
X	lastp = 0;
X	while (1) {
X	    if (lastp != prmpt) {
X		lastp = prmpt;
X		f_prompt (lastp);
X	    }
X	    c_pos (r, c);
X	    switch (ch = read_char()) {
X	    case REDRAW:
X		redraw_screen(2);	/* redraw all from scratch */
X		lastp = 0;
X		break;
X	    case VERSION:
X		version();
X		lastp = 0;
X		break;
X	    case HELP:
X		f_msg (help);
X		lastp = 0;
X		break;
X	    case QUIT:
X		f_prompt ("Exit ephem? (y) ");
X		if (read_char() == 'y')
X		    bye();	/* never returns */
X		lastp = 0;
X		break;
X	    case END:
X		return (0);
X	    case '\r':
X		return (rcfpack (r, c, 0));
X	    default:
X		move_cur (ch, flag, &r, &c);
X		break;
X	    }
X	}
X}
X
X/* move cursor to next field in given direction: hjkl, or directly to a
X * field, and set *rp and *cp.
X * limit eligible fields to those with given flag mask.
X */
Xstatic
Xmove_cur (dirchar, flag, rp, cp)
Xchar dirchar;
Xint flag;
Xint *rp, *cp;
X{
X	int curr = *rp, curc = *cp;
X	int f, newf, *fp;
X	int d, newd;
X
X    wrapped:
X	newf = 0;
X	newd = 1000;
X
X	switch (dirchar) {
X	case 'h': /* left */
X	    /* go to next field to the left, or wrap.  */
X	    for (fp = fields+NFIELDS; --fp >= fields; ) {
X		f = *fp;
X		if (tstpackf(f,flag) && unpackr(f) == curr) {
X		    d = curc - unpackc(f);
X		    if (d > 0 && d < newd) {
X			newf = f;
X			newd = d;
X		    }
X		}
X	    }
X	    if (!newf) {
X		curc = NC;
X		goto wrapped;
X	    }
X	    break;
X
X	case 'j': /* down */
X	    /* go to closest field on next row down with anything on it,
X	     * or wrap.
X	     */
X	    for (fp = fields+NFIELDS; --fp >= fields; ) {
X		f = *fp;
X		if (tstpackf(f,flag)) {
X		    d = unpackr(f) - curr;
X		    if (d > 0 && d < newd) {
X			newf = f;
X			newd = d;
X		    }
X		}
X	    }
X	    if (newf) {
X		/* now find the field closest to current col on that row */
X		newf = nearestfld (unpackr(newf), curc, flag);
X	    } else {
X		curr = 0;
X		goto wrapped;
X	    }
X	    break;
X
X	case 'k': /* up */
X	    /* go to closest field on next row up with anything on it, 
X	     * or wrap.
X	     */
X	    for (fp = fields+NFIELDS; --fp >= fields; ) {
X		f = *fp;
X		if (tstpackf(f,flag)) {
X		    d = curr - unpackr(f);
X		    if (d > 0 && d < newd) {
X			newf = f;
X			newd = d;
X		    }
X		}
X	    }
X	    if (newf) {
X		/* now find the field closest to current col on that row */
X		newf = nearestfld (unpackr(newf), curc, flag);
X	    } else {
X		curr = NR+1;
X		goto wrapped;
X	    }
X	    break;
X
X	case 'l': /* right */
X	    /* go to next field to the right, or wrap.  */
X	    for (fp = fields+NFIELDS; --fp >= fields; ) {
X		f = *fp;
X		if (tstpackf(f,flag) && unpackr(f) == curr) {
X		    d = unpackc(f) - curc;
X		    if (d > 0 && d < newd) {
X			newf = f;
X			newd = d;
X		    }
X		}
X	    }
X	    if (!newf) {
X		curc = 0;
X		goto wrapped;
X	    }
X	    break;
X
X	/* handy shorthands directly to a given spot.
X	 * calling nearestfld() automatically allows for which menu
X	 *   is up now and what is pickable.
X	 * N.B. using nearestfld() can be too aggressive. it will try
X	 *   other fields entirely if one you intend is not eligible.
X	 */
X	case 'S': newf = nearestfld (R_SUN, 1, flag); break;
X	case 'M': newf = nearestfld (R_MOON, 1, flag); break;
X	case 'e': newf = nearestfld (R_MERCURY, 1, flag); break;
X	case 'v': newf = nearestfld (R_VENUS, 1, flag); break;
X	case 'm': newf = nearestfld (R_MARS, 1, flag); break;
X	case cntrl('j'): newf = nearestfld (R_JUPITER, 1, flag); break;
X	case 's': newf = nearestfld (R_SATURN, 1, flag); break;
X	case 'u': newf = nearestfld (R_URANUS, 1, flag); break;
X	case 'n': newf = nearestfld (R_NEPTUNE, 1, flag); break;
X	case 'p': newf = nearestfld (R_PLUTO, 1, flag); break;
X	case 'x': newf = nearestfld (R_OBJX, 1, flag); break;
X	case 'd': newf = nearestfld (R_UD, C_UD, flag); break;
X	case 'o': newf = nearestfld (R_EPOCH, C_EPOCHV, flag); break;
X	case 'z': newf = nearestfld (R_STPSZ, C_STPSZV, flag); break;
X	}
X
X	if (newf > 0) {
X	    *rp = unpackr(newf);
X	    *cp = unpackc(newf);
X	}
X}
X
X/* return the nearest field with given flag mask, either way, on this row,
X * else -1 if none.
X */
Xstatic int
Xnearestfld (r, c, flag)
Xint r, c, flag;
X{
X	int nf, f, *fp;
X	int d, d0;
X
X	nf = 0;
X	d0 = 1000;
X
X	for (fp = fields+NFIELDS; --fp >= fields; ) {
X	    f = *fp;
X	    if (tstpackf(f,flag) && unpackr(f) == r) {
X		d = abs(c - unpackc(f));
X		if (d < d0) {
X		    nf = f;
X		    d0 = d;
X		}
X	    }
X	}
X	return (nf ? nf : -1);
X}
EOFxEOF
len=`wc -c < sel_fld.c`
if expr $len != 21267 > /dev/null
then echo Length of sel_fld.c is $len but it should be 21267.
fi
echo x sex_dec.c
sed -e 's/^X//' << 'EOFxEOF' > sex_dec.c
X/* given hours (or degrees), hd, minutes, m, and seconds, s, 
X * return decimal hours (or degrees), *d.
X * in the case of hours (angles) < 0, only the first non-zero element should
X *   be negative.
X */
Xsex_dec (hd, m, s, d)
Xint hd, m, s;
Xdouble *d;
X{
X	int sign = 1;
X
X	if (hd < 0) {
X	    sign = -1;
X	    hd = -hd;
X	} else if (m < 0) {
X	    sign = -1;
X	    m = -m;
X	} else if (s < 0) {
X	    sign = -1;
X	    s = -s;
X	}
X
X	*d = (((double)s/60.0 + (double)m)/60.0 + (double)hd) * sign;
X}
X
X/* given decimal hours (or degrees), d.
X * return nearest hours (or degrees), *hd, minutes, *m, and seconds, *s, 
X * each always non-negative; *isneg is set to 1 if d is < 0, else to 0.
X */
Xdec_sex (d, hd, m, s, isneg)
Xdouble d;
Xint *hd, *m, *s, *isneg;
X{
X	double min;
X
X	if (d < 0) {
X	    *isneg = 1;
X	    d = -d;
X	} else
X	    *isneg = 0;
X
X	*hd = (int)d;
X	min = (d - *hd)*60.;
X	*m = (int)min;
X	*s = (int)((min - *m)*60. + 0.5);
X
X	if (*s == 60) {
X	    if ((*m += 1) == 60) {
X		*hd += 1;
X		*m = 0;
X	    }
X	    *s = 0;
X	}
X	/* no  negative 0's */
X	if (*hd == 0 && *m == 0 && *s == 0)
X	    *isneg = 0;
X}
X
X/* insure 0 <= *v < r.
X */
Xrange (v, r)
Xdouble *v, r;
X{
X	while (*v <  0) *v += r;
X	while (*v >= r) *v -= r;
X}
EOFxEOF
len=`wc -c < sex_dec.c`
if expr $len != 1194 > /dev/null
then echo Length of sex_dec.c is $len but it should be 1194.
fi