home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume7
/
ephem
/
part02
< prev
next >
Wrap
Text File
|
1989-06-03
|
61KB
|
2,378 lines
Newsgroups: comp.sources.misc
From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
Subject: v07i010: astronomical ephemeris - 2 of 3
Keywords: ephemeris astro
Organization: Dimensional Medicine, Inc. Minnetonka, MN.
Reply-To: ecd@ncs-med.UUCP (Elwood C. Downey)
Posting-number: Volume 7, Issue 10
Submitted-by: ecd@ncs-med.UUCP (Elwood C. Downey)
Archive-name: ephem/part02
#!/bin/sh
echo extracting main.c
cat > main.c << 'xXx'
/* main program.
*/
#include <stdio.h>
#include <math.h>
#include "astro.h"
#include "circum.h"
#include "screen.h"
extern char *strchr(), *malloc();
static char *cfgfile = "ephem.cfg"; /* default config filename */
/* value for standard and my adaptive rise/set refraction model.
*/
#define STDREF degrad(50.0/60.0) /* 34(ref)+16(semi-diam) arc mins */
static float dis = STDREF; /* sun displacement for rise/set refraction */
static Now now; /* where and when, right now */
static float epoch; /* ra/dec display precession epoch, or EOD */
static float tminc; /* hrs to inc time by each loop; RTC means use clock */
static int newtm; /* when op sets his own time don't auto inc first step*/
static int nstep; /* steps to go before stopping */
static int ops, opm; /* print options flags; 1 if want it */
static int optwi, opsrs, opmrs;
static int oppl[PLUTO+1];
/* info about the misc obj to be displayed at the bottom line */
static int opobj; /* 1 while wanting to use object */
static float obj_ra, obj_dec, obj_epoch; /* location of object */
static char obj_name[C_RA-C_OBJ];
/* shorthands into now */
#define mjd now.n_mjd
#define lat now.n_lat
#define lng now.n_lng
#define tz now.n_tz
#define temp now.n_temp
#define pressure now.n_pressure
#define height now.n_height
#define tznm now.n_tznm
main (ac, av)
int ac;
char *av[];
{
static char ssrun[] = "Updating...";
static char freerun[] =
"Running... press any key to stop to make changes.";
static char prmpt[] =
"Move to another field, RETURN to change this field, ? for help, or ESC to run";
static char hlp[] =
"arrow keys move to field; any key stops running; ^d exits; ^l redraws";
int curr = R_NSTEP, curc = C_NSTEPV; /* must start somewhere */
int sflag = 0;
int i;
int one = 1; /* use a variable so masscomp optimizer not disabled */
while ((--ac > 0) && (**++av == '-')) {
char *s;
for (s = *av+1; *s != '\0'; s++)
switch (*s) {
case 's': /* no credits "silent" (don't publish this) */
sflag++;
break;
case 'c': /* set name of config file to use */
if (--ac <= 0) usage();
cfgfile = *++av;
break;
default:
usage();
}
}
if (ac > 0)
usage();
/* unbuffered stdout; avoid fflush(stdout) hassle. */
setbuf (stdout, (char *)0);
/* make sure we can read the config file. try adding .cfg too. */
if (access (cfgfile, 4) < 0) {
if (strchr (cfgfile, '.') == 0) {
/* no . so try it with .cfg suffix */
char *cf = malloc (strlen(cfgfile)+4+1); /* .cfg + 0 */
sprintf (cf, "%s.cfg", cfgfile);
cfgfile = cf;
}
if (access (cfgfile, 4) < 0) {
printf ("Can not read config file: %s\n", cfgfile);
exit (1);
}
}
/* init the screen and all the globals */
if (!sflag)
credits();
pr_erase();
pr_labels();
borders();
read_cfgfile (cfgfile);
newtm = 0;
/* update screen forever (until QUIT) */
while (one) {
if (nstep <= 1)
pr_prompt (ssrun);
/* print all the time-related fields */
pr_now (&now);
/* print solar system body info */
if (opsrs) pr_sunrs (&now, dis);
if (opmrs) pr_moonrs (&now);
if (optwi) pr_twilight (&now);
if (ops) pr_sun (&now, epoch);
if (opm) pr_moon (&now, epoch);
for (i = MERCURY; i <= PLUTO; i++)
if (oppl[i]) pr_planet (i, &now, epoch);
/* print the misc obj */
if (opobj) pr_obj (obj_ra, obj_dec, obj_epoch, &now, epoch);
/* now everything is up-to-date; decrement nstep */
pr_newcir(0);
plot();
if (nstep > 0) nstep -= 1;
prnstep ();
/* change parameters after steps are done or when op hits a key.
*/
if (nstep == 0 || (chk_char()==0 && read_char()!=0)) {
if (nstep == 0) {
nstep = 1;
prnstep ();
}
while (1) {
int fld = sel_fld (curr, curc, F_VIS|F_CHG, prmpt, hlp);
if (fld == 0)
break;
chg_fld ((char *)0, fld);
pr_now (&now);
curr = unpackr (fld);
curc = unpackc (fld);
}
if (nstep > 1)
pr_prompt (freerun);
}
/* increment time if op didn't enter his own */
if (newtm)
newtm = 0;
else
inc_mjd (&now, tminc);
}
return (0);
}
/* clean up and exit
* TODO: ask "are you sure?" ?
*/
bye()
{
pr_erase();
byetty();
exit (0);
}
static
usage()
{
/* don't advertise -s (silent) option */
printf ("usage: [-c <configfile>]\n");
exit (1);
}
/* read cfg file, fn, if present */
static
read_cfgfile(fn)
char *fn;
{
char buf[256];
FILE *fp;
fp = fopen (fn, "r");
if (!fp)
return;
while (fgets (buf, sizeof(buf), fp)) {
buf[strlen(buf)-1] = '\0'; /* no trailing \n */
if (strncmp ("SITE", buf, 4) == 0)
pr_string (R_TITLE, C_TITLE-strlen(buf+5)/2, buf+5);
else if (strncmp ("LAT", buf, 3) == 0)
chg_fld (buf+4, rcfpack (R_LAT,C_LATV,0));
else if (strncmp ("LONG", buf, 4) == 0)
chg_fld (buf+5, rcfpack (R_LONG,C_LONGV,0));
else if (strncmp ("UT", buf, 2) == 0)
chg_fld (buf+3, rcfpack (R_UT,C_UTV,0));
else if (strncmp ("UD", buf, 2) == 0)
chg_fld (buf+3, rcfpack (R_UD,C_UD,0));
else if (strncmp ("TZONE", buf, 5) == 0)
chg_fld (buf+6, rcfpack (R_TZONE,C_TZONEV,0));
else if (strncmp ("TZNAME", buf, 6) == 0)
chg_fld (buf+7, rcfpack (R_TZN,C_TZN,0));
else if (strncmp ("HEIGHT", buf, 6) == 0)
chg_fld (buf+7, rcfpack (R_HEIGHT,C_HEIGHTV,0));
else if (strncmp ("NSTEP", buf, 5) == 0)
chg_fld (buf+6, rcfpack (R_NSTEP,C_NSTEPV,0));
else if (strncmp ("STPSZ", buf, 5) == 0)
chg_fld (buf+6, rcfpack (R_STPSZ,C_STPSZV,0));
else if (strncmp ("TEMP", buf, 4) == 0)
chg_fld (buf+5, rcfpack (R_TEMP,C_TEMPV,0));
else if (strncmp ("PRES", buf, 4) == 0)
chg_fld (buf+5, rcfpack (R_PRES,C_PRESV,0));
else if (strncmp ("EPOCH", buf, 5) == 0)
chg_fld (buf+6, rcfpack (R_EPOCH,C_EPOCH,0));
else if (strncmp ("OBJN", buf, 4) == 0)
chg_fld (buf+5, rcfpack (R_OBJ,C_OBJ,0)); /*must be first*/
else if (strncmp ("OBJRA", buf, 5) == 0)
chg_fld (buf+6, rcfpack (R_OBJ,C_RA,0));
else if (strncmp ("OBJDEC", buf, 6) == 0)
chg_fld (buf+7, rcfpack (R_OBJ,C_DEC,0));
else if (strncmp ("PROPTS", buf, 6) == 0) {
char *bp = buf+7;
while (*bp)
switch (*bp++) {
case 'T': optwi = 1; break;
case 'S': ops = opsrs = 1; break;
case 'M': opm = opmrs = 1; break;
case 'e': oppl[MERCURY] = 1; break;
case 'v': oppl[VENUS] = 1; break;
case 'a': oppl[MARS] = 1; break;
case 'j': oppl[JUPITER] = 1; break;
case 's': oppl[SATURN] = 1; break;
case 'u': oppl[URANUS] = 1; break;
case 'n': oppl[NEPTUNE] = 1; break;
case 'p': oppl[PLUTO] = 1; break;
}
}
}
fclose (fp);
}
/* change the field at rcpk according to the optional string input at bp.
* if bp is != 0 use it, else issue read_line() and use buffer.
* then sscanf the buffer and update the corresponding (global) variable(s)
* or do whatever a pick at that field should do.
*/
static
chg_fld (bp, rcpk)
char *bp;
int rcpk;
{
char buf[NC];
int deghrs = 0, mins = 0, secs = 0;
/* switch on just the row/col portion */
switch (rcpk & ((1<<F_SHFT)-1)) {
case rcfpack (R_UD, C_UD, 0):
if (!bp) {
static char p[] = "utc date (m/d/y, or NOW): ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
float fday, newmjd0;
int month, day, year;
mjd_cal ((float)mjd, &month, &fday, &year); /* init with now */
day = (int)fday; /* ignore partial days */
sscansex (bp, &month, &day, &year);
cal_mjd (month, (float)day, year, &newmjd0);
mjd = newmjd0 + mjd_hr(mjd)/24.0;
}
newtm = 1;
set_t0 (&now);
pr_newcir(1);
break;
case rcfpack (R_UT, C_UTV, 0):
if (!bp) {
static char p[] = "utc time (h:m:s, or NOW): ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
float newutc = (mjd-mjd_day(mjd)) * 24.0;
dec_sexsign (newutc, °hrs, &mins, &secs);
sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &newutc);
mjd = mjd_day(mjd) + newutc/24.0;
}
newtm = 1;
set_t0 (&now);
pr_newcir(1);
break;
case rcfpack (R_LD, C_LD, 0):
if (!bp) {
static char p[] = "local date (m/d/y, or NOW): ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
float fday, newlmjd0;
int month, day, year;
mjd_cal ((float)(mjd-tz/24.0), &month, &fday, &year); /* now */
day = (int)fday; /* ignore partial days */
sscansex (bp, &month, &day, &year);
cal_mjd (month, (float)day, year, &newlmjd0);
mjd = newlmjd0 + mjd_hr(mjd)/24.0;
mjd += newlmjd0 - mjd_day(mjd-tz/24.0);
}
newtm = 1;
set_t0 (&now);
pr_newcir(1);
break;
case rcfpack (R_LT, C_LT, 0):
if (!bp) {
static char p[] = "local time (h:m:s, or NOW): ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
float newlt = (mjd-mjd_day(mjd)) * 24.0 - tz;
range (&newlt, 24.0);
dec_sexsign (newlt, °hrs, &mins, &secs);
sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &newlt);
mjd = mjd_day(mjd-tz/24.0) + (newlt + tz)/24.0;
}
newtm = 1;
set_t0 (&now);
pr_newcir(1);
break;
case rcfpack (R_TZN, C_TZN, 0):
if (!bp) {
static char p[] = "timezone abbreviation (3 char max): ";
pr_prompt (p);
if (read_line (buf, 3) <= 0)
return;
bp = buf;
}
strcpy (tznm, bp);
break;
case rcfpack (R_TZONE, C_TZONEV, 0):
if (!bp) {
static char p[] = "hours behind utc: ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
dec_sexsign (tz, °hrs, &mins, &secs);
sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &tz);
pr_newcir(1);
break;
case rcfpack (R_LONG, C_LONGV, 0):
if (!bp) {
static char p[] = "longitude (+ west) (d:m:s): ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
dec_sexsign (-raddeg(lng), °hrs, &mins, &secs);
sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &lng);
lng = degrad (-lng); /* want - radians west */
pr_newcir(1);
break;
case rcfpack (R_LAT, C_LATV, 0):
if (!bp) {
static char p[] = "latitude (+ north) (d:m:s): ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
dec_sexsign (raddeg(lat), °hrs, &mins, &secs);
sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &lat);
lat = degrad (lat);
pr_newcir(1);
break;
case rcfpack (R_HEIGHT, C_HEIGHTV, 0):
if (!bp) {
static char p[] = "height above sea level (ft): ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
sscanf (bp, "%f", &height);
sprintf (buf, "%5g ft", height);
pr_string (R_HEIGHT, C_HEIGHTV, buf);
height /= 2.093e7; /* convert ft to earth radii above sea level */
pr_newcir(1);
break;
case rcfpack (R_NSTEP, C_NSTEPV, 0):
if (!bp) {
static char p[] = "number of steps to run: ";
pr_prompt (p);
if (read_line (buf, 8) <= 0)
return;
bp = buf;
}
sscanf (bp, "%d", &nstep);
prnstep ();
break;
case rcfpack (R_TEMP, C_TEMPV, 0):
if (!bp) {
static char p[] = "temperatue (deg.F): ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
sscanf (bp, "%f", &temp);
sprintf (buf, "%6g F", temp);
pr_string (R_TEMP, C_TEMPV, buf);
temp = 5./9.*(temp - 32.0); /* want degs C */
pr_newcir(1);
break;
case rcfpack (R_PRES, C_PRESV, 0):
if (!bp) {
static char p[] =
"atmos pressure (in. Hg; 0 for no refraction correction): ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
sscanf (bp, "%f", &pressure);
sprintf (buf, "%5.2f in", pressure);
pr_string (R_PRES, C_PRESV, buf);
pressure *= 33.86; /* want mBar */
pr_newcir(1);
break;
case rcfpack (R_EPOCH, C_EPOCH, 0):
if (!bp) {
static char p[] = "epoch (year, or EOD for no precession): ";
pr_prompt (p);
if (read_line (buf, PW-strlen(p)) <= 0)
return;
bp = buf;
}
if (bp[0] == 'e' || bp[0] == 'E') {
epoch = EOD;
sprintf (buf, "(Epoch of date)");
} else {
float e;
sscanf (bp, "%f", &e);
sprintf (buf, "(Epoch %6.1f) ", e);
cal_mjd (1, 1.0, (int)e, &epoch); /* convert to mjd */
epoch += (e - (int)e)*365.24;
}
pr_string (R_EPOCH, C_EPOCH, buf);
pr_newcir(1);
break;
case rcfpack (R_STPSZ, C_STPSZV, 0):
if (!bp) {
static char p[] =
"step size increment (h:m:s, or <x>D, or RTC): ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
if (bp[0] == 'r' || bp[0] == 'R') {
pr_string (R_STPSZ, C_STPSZV, "RT CLOCK");
tminc = RTC;
} else {
int last = strlen (bp) - 1;
if (bp[last] == 'd' || bp[last] == 'D') {
/* ends in d so treat as decimal number of days */
float x;
sscanf (bp, "%g", &x);
tminc = x * 24.0;
pr_float (R_STPSZ, C_STPSZV, "%5g dy", x);
} else {
if (tminc == RTC)
deghrs = mins = secs = 0;
else
dec_sexsign (tminc, °hrs, &mins, &secs);
sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &tminc);
pr_time (R_STPSZ, C_STPSZV, tminc);
}
}
set_t0 (&now);
break;
case rcfpack (R_PLOT, C_PLOT, 0):
plt_pk_label();
break;
case rcfpack (R_PLOT, C_PLOTV, 0):
plt_pk_onoff();
break;
case rcfpack (R_DAWN, C_DAWN, 0):
case rcfpack (R_DUSK, C_DUSK, 0):
case rcfpack (R_LON, C_LON, 0):
if (optwi ^= 1)
pr_twilight (&now);
else {
pr_blanks (R_DAWN, C_DAWNV, 5);
pr_blanks (R_DUSK, C_DUSKV, 5);
pr_blanks (R_LON, C_LONV, 5);
}
break;
case rcfpack (R_SUNR, C_SUNR, 0):
case rcfpack (R_SUNS, C_SUNS, 0):
case rcfpack (R_LOD, C_LOD, 0):
if (opsrs ^= 1) {
if (!bp) {
static char p[] =
"standard or adaptive refraction model (s/a)? ";
do {
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) < 0)
return;
} while (*buf != 's' && *buf != 'a');
bp = buf;
}
dis = (*bp == 'a') ? ADPREF : STDREF;
pr_sunrs (&now, dis);
} else {
pr_blanks (R_SUNR, C_SUNRT, 14);
pr_blanks (R_SUNS, C_SUNST, 14);
pr_blanks (R_LOD, C_LODV, 5);
}
break;
case rcfpack (R_MOONR, C_MOONR, 0):
case rcfpack (R_MOONS, C_MOONS, 0):
if (opmrs ^= 1)
pr_moonrs (&now);
else {
pr_blanks (R_MOONR, C_MOONRT, 14);
pr_blanks (R_MOONS, C_MOONST, 14);
}
break;
case rcfpack (R_SUN, C_OBJ, 0):
if (ops ^= 1)
pr_sun (&now, epoch);
else
pr_noplanet (R_SUN);
break;
case rcfpack (R_MOON, C_OBJ, 0):
if (opm ^= 1)
pr_moon (&now, epoch);
else
pr_noplanet (R_MOON);
break;
case rcfpack (R_MERCURY, C_OBJ, 0):
if (oppl[MERCURY] ^= 1)
pr_planet (MERCURY, &now, epoch);
else
pr_noplanet (R_MERCURY);
break;
case rcfpack (R_VENUS, C_OBJ, 0):
if (oppl[VENUS] ^= 1)
pr_planet (VENUS, &now, epoch);
else
pr_noplanet (R_VENUS);
break;
case rcfpack (R_MARS, C_OBJ, 0):
if (oppl[MARS] ^= 1)
pr_planet (MARS, &now, epoch);
else
pr_noplanet (R_MARS);
break;
case rcfpack (R_JUPITER, C_OBJ, 0):
if (oppl[JUPITER] ^= 1)
pr_planet (JUPITER, &now, epoch);
else
pr_noplanet (R_JUPITER);
break;
case rcfpack (R_SATURN, C_OBJ, 0):
if (oppl[SATURN] ^= 1)
pr_planet (SATURN, &now, epoch);
else
pr_noplanet (R_SATURN);
break;
case rcfpack (R_URANUS, C_OBJ, 0):
if (oppl[URANUS] ^= 1)
pr_planet (URANUS, &now, epoch);
else
pr_noplanet (R_URANUS);
break;
case rcfpack (R_NEPTUNE, C_OBJ, 0):
if (oppl[NEPTUNE] ^= 1)
pr_planet (NEPTUNE, &now, epoch);
else
pr_noplanet (R_NEPTUNE);
break;
case rcfpack (R_PLUTO, C_OBJ, 0):
if (oppl[PLUTO] ^= 1)
pr_planet (PLUTO, &now, epoch);
else
pr_noplanet (R_PLUTO);
break;
case rcfpack (R_OBJ, C_OBJ, 0):
if (!bp) {
static char p[] = "object name (or RETURN for none): ";
pr_prompt (p);
if (read_line (buf, sizeof(obj_name)-1) < 0)
return;
bp = buf;
} else
bp[sizeof(obj_name)-1] = '\0';
if (bp[0] == '\0') {
opobj = 0;
pr_blanks (R_OBJ, C_OBJ, sizeof(obj_name)-1);
/* pr_noplanet (R_OBJ); NO: writes on low-right of screen */
pr_blanks (R_OBJ, C_RA, 80-1-C_RA+1);
} else {
opobj = 1;
pr_blanks (R_OBJ, C_OBJ, sizeof(obj_name)-1);
strncpy (obj_name, bp, sizeof(obj_name)-1);
pr_string (R_OBJ, C_OBJ, bp);
obj_epoch = 0.0;
obj_ra = 0.0;
obj_dec = 0.0;
}
break;
case rcfpack (R_OBJ, C_RA, 0):
if (!opobj)
break;
if (!bp) {
static char p[] = "ra (current epoch, h:m:s): ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
dec_sexsign (radhr(obj_ra), °hrs, &mins, &secs);
sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &obj_ra);
pr_ra (R_OBJ, C_RA, obj_ra);
obj_ra = hrrad (obj_ra);
obj_epoch = epoch == EOD ? mjd : epoch;
pr_obj (obj_ra, obj_dec, obj_epoch, &now, epoch);
break;
case rcfpack (R_OBJ, C_DEC, 0):
if (!opobj)
break;
if (!bp) {
static char p[] = "dec (current epoch, d:m:s): ";
pr_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
return;
bp = buf;
}
dec_sexsign (raddeg(obj_dec), °hrs, &mins, &secs);
sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &obj_dec);
obj_dec = degrad (obj_dec);
obj_epoch = epoch == EOD ? mjd : epoch;
pr_obj (obj_ra, obj_dec, obj_epoch, &now, epoch);
break;
}
}
static
prnstep()
{
char buf[16];
sprintf (buf, "%8d", nstep);
pr_string (R_NSTEP, C_NSTEPV, buf);
}
/* crack a line of the form X:X:X or X/X/X into its components.
* only change those fields that are specified:
* eg: ::10 only changes *s
* 10 only changes *d
* 10:0 changes *d and *m
* if see '-' anywhere, first non-zero component will be made negative.
*/
static
sscansex (bp, d, m, s)
char *bp;
int *d, *m, *s;
{
char c;
register int *p = d;
int *nonzp = 0;
int sawneg = 0;
int innum = 0;
while (c = *bp++)
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (!innum) {
*p = 0;
innum = 1;
}
*p = *p*10 + (c - '0');
if (*p && !nonzp)
nonzp = p;
break;
case ':': case '/':
/* advance to next component */
p = (p == d) ? m : s;
innum = 0;
break;
case '-':
sawneg = 1;
break;
}
if (sawneg && nonzp)
*nonzp = -*nonzp;
}
/* just like dec_sex() but makes the first non-zero element negative if
* x is negative (instead of returning a sign flag).
*/
static
dec_sexsign (x, h, m, s)
float x;
int *h, *m, *s;
{
int n;
dec_sex (x, h, m, s, &n);
if (n) {
if (*h)
*h = -*h;
else if (*m)
*m = -*m;
else
*s = -*s;
}
}
xXx
echo extracting plot.c
cat > plot.c << 'xXx'
/* code to support the plotting capabilities. */
#include <stdio.h>
#include "screen.h"
extern errno;
extern char *sys_errlist[];
#define UNDEFFL 1e38 /* magic float value to mean undefined */
/* number of simultaneous lines we can track/plot */
#define MAXPLTLINES 4
#define FNLEN (14+1) /* longest filename; plus 1 for \0 */
static char plt_filename[FNLEN] = "ephem.plt";
static FILE *plt_fp; /* == 0 means don't plot too */
/* a PlotField is a field location and a value stored there.
* a PlotLine is a label and two or three PlotFields:
* [0] is the x coord, [1] the y, and [2], if not UNDEFFL/blank, is z.
*/
typedef struct {
int pf_rcpack;
float pf_val;
} PlotField;
typedef struct {
char pl_label;
PlotField pl_x, pl_y, pl_z;
} PlotLine;
static PlotLine plotline[MAXPLTLINES];
static int npltlines; /* actual number of plotline[]s in use */
/* picked the Plot label:
* if on, select fields to plot.
* if off, select name of file to plot.
*/
plt_pk_label()
{
if (plt_fp)
plt_select_fields();
else
plt_file();
}
/* pick the plot on/off field:
* if on, turn off.
* if off, turn on, using current set of plot fields.
*/
plt_pk_onoff()
{
if (plt_fp)
plt_turn_off();
else
plt_turn_on();
}
/* save value for r/c, if plot file open and r/c is in plotfield[].
* don't quit if see one since a field could be used more than once; time
* is a frequent example.
*/
plt_val (r, c, value)
int r, c;
float value;
{
PlotLine *plp;
int rcp;
if (plt_fp) {
plp = &plotline[npltlines];
rcp = rcfpack (r, c, 0);
while (--plp >= plotline) {
if (plp->pl_x.pf_rcpack == rcp)
plp->pl_x.pf_val = value;
if (plp->pl_y.pf_rcpack == rcp)
plp->pl_y.pf_val = value;
if (plp->pl_z.pf_rcpack == rcp)
plp->pl_z.pf_val = value;
}
}
}
/* write the active plotfields to the current plot file, if one is open. */
plot ()
{
PlotLine *plp;
if (plt_fp)
for (plp = &plotline[npltlines]; --plp >= plotline; ) {
fprintf (plt_fp, "%c,%g,%g", plp->pl_label,
plp->pl_x.pf_val, plp->pl_y.pf_val);
if (plp->pl_z.pf_val != UNDEFFL)
fprintf (plt_fp, ",%g", plp->pl_z.pf_val);
fprintf (plt_fp, "\n");
}
}
static
plt_init()
{
PlotLine *plp = &plotline[MAXPLTLINES];
while (--plp >= plotline) {
plp->pl_x.pf_rcpack = plp->pl_y.pf_rcpack = 0;
plp->pl_x.pf_val = plp->pl_y.pf_val = 0.0;
plp->pl_z.pf_val = UNDEFFL;
}
npltlines = 0;
}
static
plt_select_fields()
{
static char hlp[] = "use arrow keys to select variable, or ESC to quit";
static int pltr = R_UT, pltc = C_UTV; /* start somewhere... */
int i;
plt_init();
for (i = 0; i < MAXPLTLINES; i++) {
char buf[64];
int fld;
sprintf (buf, "select x field for line %d", i+1);
fld = sel_fld (pltr, pltc, F_VIS|F_PLT, buf, hlp);
pltr = unpackr (fld); pltc = unpackc (fld);
if (!fld)
break;
plotline[i].pl_x.pf_rcpack = fld;
sprintf (buf, "select y field for line %d", i+1);
fld = sel_fld (pltr, pltc, F_VIS|F_PLT, buf, hlp);
pltr = unpackr (fld); pltc = unpackc (fld);
if (!fld)
break;
plotline[i].pl_y.pf_rcpack = fld;
sprintf (buf, "select z field for line %d", i+1);
fld = sel_fld (pltr, pltc, F_VIS|F_PLT, buf, hlp);
pltr = unpackr (fld); pltc = unpackc (fld);
if (fld)
plotline[i].pl_z.pf_rcpack = fld;
do {
sprintf (buf, "select one-character label for line %d: ", i+1);
pr_prompt (buf);
fld = read_line (buf, 1);
} while (fld != 1);
plotline[i].pl_label = *buf;
}
npltlines = i;
}
static
plt_turn_off ()
{
fclose (plt_fp);
plt_fp = 0;
pr_string (R_PLOT, C_PLOTV, "off");
}
static
plt_turn_on ()
{
char fn[FNLEN], fnq[64];
char *optype;
int n;
/* prompt for file name, giving current as default */
sprintf (fnq, "file to write <%s>: ", plt_filename);
pr_prompt (fnq);
n = read_line (fn, sizeof(fn)-1);
/* leave plotting off if type ESC.
* reuse same fn if just type \n
*/
if (n < 0)
return;
if (n > 0)
strcpy (plt_filename, fn);
/* give option to append if file already exists */
optype = "w";
if (access (plt_filename, 2) == 0) {
while (1) {
pr_prompt ("append or overwrite (a/o)?: ");
n = read_line (fn, 1);
if (n < 0)
return;
if (fn[0] == 'a') {
optype = "a";
break;
}
if (fn[0] == 'o')
break;
}
}
/* plotting is on if file opens ok */
plt_fp = fopen (plt_filename, optype);
if (plt_fp)
pr_string (R_PLOT, C_PLOTV, "on ");
else {
char buf[NC];
sprintf(buf,"can not open %s: %s",plt_filename,sys_errlist[errno]);
pr_prompt (buf);
(void)read_char();
}
}
static
plt_file ()
{
char fn[FNLEN], fnq[64];
FILE *pfp;
int n;
/* prompt for file name, giving current as default */
sprintf (fnq, "file to read <%s>: ", plt_filename);
pr_prompt (fnq);
n = read_line (fn, sizeof(fn)-1);
/* forget it if type ESC.
* reuse same fn if just type \n
*/
if (n < 0)
return;
if (n > 0)
strcpy (plt_filename, fn);
/* do the plot if file opens ok */
pfp = fopen (plt_filename, "r");
if (pfp) {
plot_it (pfp);
fclose (pfp);
} else {
char buf[NC];
sprintf(buf,"can not open %s: %s",plt_filename,sys_errlist[errno]);
pr_prompt (buf);
(void)read_char();
}
}
/* TODO: add z somehow
* N.B. DON'T use pr_X() since they will be remembered over screen.
*/
static
plot_it (pfp)
FILE *pfp;
{
static char fmt[] = "%c,%g,%g";
float x, y; /* N.B. most sscanf("%g")'s need ptrs to double */
float minx, maxx, miny, maxy;
char buf[128];
int first = 1;
char c;
/* find ranges and number of points */
while (fgets (buf, sizeof(buf), pfp)) {
sscanf (buf, fmt, &c, &x, &y);
if (first) {
maxx = minx = x;
maxy = miny = y;
first = 0;
} else {
if (x > maxx) maxx = x;
else if (x < minx) minx = x;
if (y > maxy) maxy = y;
else if (y < miny) miny = y;
}
}
#define SMALL (1e-10)
if (first == 1 || fabs(minx-maxx) < SMALL || fabs(miny-maxy) < SMALL) {
c_erase();
c_pos (1,1); printf ("Nothing in file or range too small...");
} else {
/* read file again, this time plotting */
rewind (pfp);
c_erase();
while (fgets (buf, sizeof(buf), pfp)) {
int row, col;
sscanf (buf, fmt, &c, &x, &y);
row = NR-(int)((NR-1)*(y-miny)/(maxy-miny)+0.5);
col = 1+(int)((NC-1)*(x-minx)/(maxx-minx)+0.5);
if (row == NR && col == NC)
col--; /* avoid lower right scrolling corner */
c_pos (row, col);
putchar (c);
}
/* label axes */
c_pos (1,1); printf ("%.2g", maxy);
c_pos (NR-1,1); printf ("%.2g", miny);
c_pos (NR,1); printf ("%.2g", minx);
c_pos (NR,NC-10); printf ("%.2g", maxx);
}
/* hit any key to resume... */
(void) read_char();
pr_redraw();
}
xXx
echo extracting pr.c
cat > pr.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
#include "circum.h"
#include "screen.h"
/* shorthands into np */
#define mjd np->n_mjd
#define lat np->n_lat
#define lng np->n_lng
#define tz np->n_tz
#define temp np->n_temp
#define pressure np->n_pressure
#define height np->n_height
#define tznm np->n_tznm
/* display once-only labels. */
pr_labels()
{
pr_string (R_PLOT, C_PLOT, "Plot");
pr_string (R_PLOT, C_PLOTV, "off");
pr_string (R_JD, C_JD, "JD");
pr_string (R_LST, C_LST, "LST");
pr_string (R_TZN, C_TZN, "LT");
pr_string (R_UT, C_UT, "UTC");
pr_string (R_TZONE, C_TZONE, "TZ");
pr_string (R_LAT, C_LAT, "Lat");
pr_string (R_LONG, C_LONG, "Long");
pr_string (R_TEMP, C_TEMP, "Temp");
pr_string (R_PRES, C_PRES, "AtmPr");
pr_string (R_LOD, C_LOD, "DayLn");
pr_string (R_LON, C_LON, "NiteLn");
pr_string (R_NSTEP, C_NSTEP, "NStep");
pr_string (R_STPSZ, C_STPSZ, "StpSz");
pr_string (R_HEIGHT, C_HEIGHT, "Elev");
pr_string (R_DUSK, C_DUSK, "Dusk");
pr_string (R_SUNR, C_SUNR, "SRis");
pr_string (R_MOONR, C_MOONR, "MRis");
pr_string (R_DAWN, C_DAWN, "Dawn");
pr_string (R_SUNS, C_SUNS, "SSet");
pr_string (R_MOONS, C_MOONS, "MSet");
/* planet column headings */
pr_string (R_PLANTAB, C_OBJ, "Ob");
pr_string (R_PLANTAB, C_RA, "R.A.");
pr_string (R_PLANTAB, C_DEC, "Dec");
pr_string (R_PLANTAB, C_HLONG,"Helio");
pr_string (R_PLANTAB+1, C_HLONG,"Long");
pr_string (R_PLANTAB, C_HLAT, "Helio");
pr_string (R_PLANTAB+1, C_HLAT, "Lat");
pr_string (R_PLANTAB, C_AZ, "Az");
pr_string (R_PLANTAB+1, C_AZ, "Deg E");
pr_string (R_PLANTAB, C_ALT, "Alt");
pr_string (R_PLANTAB+1, C_ALT, "Deg Up");
pr_string (R_PLANTAB, C_EDIST,"Ea Dst");
pr_string (R_PLANTAB+1, C_EDIST,"AU(mi)");
pr_string (R_PLANTAB, C_SDIST,"Sn Dst");
pr_string (R_PLANTAB+1, C_SDIST,"AU");
pr_string (R_PLANTAB, C_ELONG,"Elong");
pr_string (R_PLANTAB+1, C_ELONG,"Deg E");
pr_string (R_PLANTAB, C_SIZE, "Size");
pr_string (R_PLANTAB+1, C_SIZE, "ArcS");
pr_string (R_PLANTAB, C_MAG, "VMag");
pr_string (R_PLANTAB, C_PHASE,"Phs");
pr_char (R_PLANTAB+1, C_PHASE,'%');
/* object names */
pr_string (R_SUN, C_OBJ, "Su");
pr_string (R_MOON, C_OBJ, "Mo");
pr_string (R_MERCURY, C_OBJ, "Me");
pr_string (R_VENUS, C_OBJ, "Ve");
pr_string (R_MARS, C_OBJ, "Ma");
pr_string (R_JUPITER, C_OBJ, "Ju");
pr_string (R_SATURN, C_OBJ, "Sa");
pr_string (R_URANUS, C_OBJ, "Ur");
pr_string (R_NEPTUNE, C_OBJ, "Ne");
pr_string (R_PLUTO, C_OBJ, "Pl");
}
/* display dawn/dusk times
*/
pr_twilight (np)
Now *np;
{
float dusk, dawn;
float tmp;
int status;
twilight_cir (np, &dawn, &dusk, &status);
switch (status) {
case -1: /* sun never sets today */
case 1: /* sun never rises today */
case 2: /* can not find where sun is! */
pr_blanks (R_DAWN, C_DAWNV, 5);
pr_blanks (R_DUSK, C_DUSKV, 5);
pr_blanks (R_LON, C_LONV, 5);
return;
default: /* all ok */
;
}
/* print times in local tz */
tmp = dawn - tz; range (&tmp, 24.0);
pr_mtime (R_DAWN, C_DAWNV, tmp);
tmp = dusk - tz; range (&tmp, 24.0);
pr_mtime (R_DUSK, C_DUSKV, tmp);
tmp = dawn - dusk; range (&tmp, 24.0);
pr_mtime (R_LON, C_LONV, tmp);
}
/* display sun's rise/set times, and length of day.
*/
pr_sunrs (np, dis)
Now *np;
float dis;
{
float utcr, utcs, azr, azs;
float tmp;
int status;
sunrs_cir (np, dis, &utcr, &utcs, &azr, &azs, &status);
switch (status) {
case -1: /* sun never sets today */
pr_string (R_SUNR, C_SUNRT, "Circumpolar ");
pr_blanks (R_SUNS, C_SUNST, 14);
pr_blanks (R_LOD, C_LODV, 5);
return;
case 1: /* sun never rises today */
pr_string (R_SUNR, C_SUNRT, "Never rises ");
pr_blanks (R_SUNS, C_SUNST, 14);
pr_blanks (R_LOD, C_LODV, 5);
return;
case 2: /* can not find where sun is! */
pr_string (R_SUNR, C_SUNRT, "?Error? ");
pr_blanks (R_SUNS, C_SUNST, 14);
pr_blanks (R_LOD, C_LODV, 5);
return;
default: /* all ok */
;
}
/* use local tz */
tmp = utcr - tz; range (&tmp, 24.0);
pr_mtime (R_SUNR, C_SUNRT, tmp);
/* possible sunrise error near utc midnight if status is -2 */
pr_char (R_SUNR, C_SUNRT+5, status==-2 ? '?' : ' ');
pr_char (R_SUNR, C_SUNRT+6, '@');
pr_angle (R_SUNR, C_SUNRAZ, azr);
tmp = utcs - tz; range (&tmp, 24.0);
pr_mtime (R_SUNS, C_SUNST, tmp);
/* possible sunset error near utc midnight if status is -3 */
pr_char (R_SUNS, C_SUNST+5, status==-3 ? '?' : ' ');
pr_char (R_SUNS, C_SUNST+6, '@');
pr_angle (R_SUNS, C_SUNSAZ, azs);
pr_mtime (R_LOD, C_LODV, utcs - utcr);
}
/* display moon's rise/set times
*/
pr_moonrs (np)
Now *np;
{
float utcr, utcs, azr, azs;
float tmp;
int status;
moonrs_cir (np, &utcr, &utcs, &azr, &azs, &status);
switch (status) {
case -1: /* never sets (circumpolar) */
pr_string (R_MOONR, C_MOONRT, "Circumpolar ");
pr_blanks (R_MOONS, C_MOONST, 14);
return;
case 1: /* moon never rises today */
pr_string (R_MOONR, C_MOONRT, "Never rises ");
pr_blanks (R_MOONS, C_MOONST, 14);
return;
case 2: /* can not find where moon is! */
pr_string (R_MOONR, C_MOONRT, "?Error? ");
pr_blanks (R_MOONS, C_MOONST, 14);
return;
default: /* all ok */
;
}
/* use local tz */
tmp = utcr - tz; range (&tmp, 24.0);
pr_mtime (R_MOONR, C_MOONRT, tmp);
/* possible moonrise error near midnight if status is -2 */
pr_char (R_MOONR, C_MOONRT+5, status==-2 ? '?' : ' ');
pr_char (R_MOONR, C_MOONRT+6, '@');
pr_angle (R_MOONR, C_MOONRAZ, azr);
tmp = utcs - tz; range (&tmp, 24.0);
pr_mtime (R_MOONS, C_MOONST, tmp);
/* possible moonset error near midnight if status is -3 */
pr_char (R_MOONS, C_MOONST+5, status==-3 ? '?' : ' ');
pr_char (R_MOONS, C_MOONST+6, '@');
pr_angle (R_MOONS, C_MOONSAZ, azs);
}
/* print sun's info now */
pr_sun (np, epoch)
Now *np;
float epoch;
{
Sky sky;
sun_cir (np, &sky);
if (epoch != EOD)
precess ((float)mjd, epoch, &sky.s_ra, &sky.s_dec);
pr_ra (R_SUN, C_RA, sky.s_ra);
pr_angle (R_SUN, C_DEC, sky.s_dec);
pr_angle (R_SUN, C_HLONG, sky.s_hlong);
pr_angle (R_SUN, C_HLAT, sky.s_hlat);
pr_angle (R_SUN, C_AZ, sky.s_az);
pr_angle (R_SUN, C_ALT, sky.s_alt);
pr_float (R_SUN, C_EDIST, "%6.4f", sky.s_edist);
pr_float (R_SUN, C_SIZE, "%4.0f", sky.s_size);
pr_float (R_SUN, C_MAG, "%4.0f", sky.s_mag);
}
/* print moon's info now */
pr_moon (np, epoch)
Now *np;
float epoch;
{
Sky sky;
moon_cir (np, &sky);
if (epoch != EOD)
precess ((float)mjd, epoch, &sky.s_ra, &sky.s_dec);
pr_ra (R_MOON, C_RA, sky.s_ra);
pr_angle (R_MOON, C_DEC, sky.s_dec);
pr_angle (R_MOON, C_AZ, sky.s_az);
pr_angle (R_MOON, C_ALT, sky.s_alt);
pr_float (R_MOON, C_EDIST, "%6.0f", sky.s_edist/1.609344); /* km->m */
pr_float (R_MOON, C_SDIST, "%6.4f", sky.s_sdist);
pr_float (R_MOON, C_ELONG, "%6.1f", sky.s_elong);
pr_float (R_MOON, C_SIZE, "%4.0f", sky.s_size);
pr_float (R_MOON, C_MAG, "%4.0f", sky.s_mag);
pr_float (R_MOON, C_PHASE, "%3.0f", sky.s_phase);
}
pr_planet (p, np, epoch)
int p;
Now *np;
float epoch;
{
Sky sky;
int row = R_PLANTAB+4 + p;
planet_cir (p, np, &sky);
if (epoch != EOD)
precess ((float)mjd, epoch, &sky.s_ra, &sky.s_dec);
pr_ra (row, C_RA, sky.s_ra);
pr_angle (row, C_DEC, sky.s_dec);
pr_angle (row, C_HLONG, sky.s_hlong);
pr_angle (row, C_HLAT, sky.s_hlat);
pr_angle (row, C_AZ, sky.s_az);
pr_angle (row, C_ALT, sky.s_alt);
pr_float (row, C_EDIST,(sky.s_edist>=10.0)?"%6.3f":"%6.4f",sky.s_edist);
pr_float (row, C_SDIST,(sky.s_sdist>=10.0)?"%6.3f":"%6.4f",sky.s_sdist);
pr_float (row, C_ELONG, "%6.1f", sky.s_elong);
pr_float (row, C_SIZE, "%4.1f", sky.s_size);
pr_float (row, C_MAG, "%4.1f", sky.s_mag);
pr_float (row, C_PHASE, "%3.0f", sky.s_phase);
}
/* print all the time/date/where related stuff */
pr_now (np)
Now *np;
{
char str[32];
double lmjd = mjd - tz/24.0;
float lst;
sprintf (str, "%14.5f", (double)mjd + 2415020L);
pr_string (R_JD, C_JDV, str);
pr_time (R_UT, C_UTV, (float)mjd_hr(mjd));
pr_date (R_UD, C_UD, (float)mjd_day(mjd));
pr_time (R_TZONE, C_TZONEV, tz);
sprintf (str, "%-3.3s", tznm); pr_string (R_TZN, C_TZN, str);
pr_time (R_LT, C_LT, (float)mjd_hr(lmjd));
pr_date (R_LD, C_LD, (float)mjd_day(lmjd));
now_lst (np, &lst);
pr_time (R_LST, C_LSTV, lst);
pr_gangle (R_LONG, C_LONGV, -lng); /* + west */
pr_gangle (R_LAT, C_LATV, lat);
/* print the calendar for local day, if new month/year. */
pr_calendar ((float)mjd_day(mjd-tz/24.0));
}
static
pr_calendar (jd)
float jd;
{
static char *mnames[] = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
};
static int last_m, last_y;
char str[64];
int m, y;
float d;
int f, nd;
int r;
float jd0;
/* get m/d/y. do nothing if still same month */
mjd_cal (jd, &m, &d, &y);
if (m == last_m && y == last_y)
return;
last_m = m;
last_y = y;
/* find day of week of first day of month */
cal_mjd (m, 1.0, y, &jd0);
mjd_dow (jd0, &f);
if (f < 0) {
/* can't figure it out - too hard before Gregorian */
int i;
for (i = 8; --i >= 0; )
pr_string (R_CAL+i, C_CAL, " ");
return;
}
/* print header */
pr_blanks (R_CAL, C_CAL, 20);
sprintf (str, "%s %4d", mnames[m-1], y);
pr_string (R_CAL, C_CAL + (20 - (strlen(mnames[m-1]) + 5))/2, str);
pr_string (R_CAL+1, C_CAL, "Su Mo Tu We Th Fr Sa");
/* find number of days in this month */
mjd_dpm (jd0, &nd);
/* print the calendar */
for (r = 0; r < 6; r++) {
char row[7*3+1], *rp = row;
int c;
for (c = 0; c < 7; c++) {
int i = r*7+c;
if (i < f || i >= f + nd)
sprintf (rp, " ");
else
sprintf (rp, "%2d ", i-f+1);
rp += 3;
}
pr_string (R_CAL+2+r, C_CAL, row);
}
/* over print the new and full moons for this month.
* TODO: don't really know which dates to use here (see moonnf())
* so try several to be fairly safe. have to go back to 4/29/1988
* to find the full moon on 5/1 for example.
*/
pr_nfmoon (jd0-3, m, f);
pr_nfmoon (jd0+15, m, f);
}
static
pr_nfmoon (jd, m, f)
float jd;
int m, f;
{
static char nm[] = "NM", fm[] = "FM";
float dm;
int mm, ym;
float jdn, jdf;
int di;
moonnf (jd, &jdn, &jdf);
mjd_cal (jdn, &mm, &dm, &ym);
if (m == mm) {
di = dm + f - 1;
pr_string (R_CAL+2+di/7, C_CAL+3*(di%7), nm);
}
mjd_cal (jdf, &mm, &dm, &ym);
if (m == mm) {
di = dm + f - 1;
pr_string (R_CAL+2+di/7, C_CAL+3*(di%7), fm);
}
}
/* print info about object */
pr_obj(ra, dec, e, np, epoch)
float ra, dec, e;/* object'a ra, dec, epoch */
Now *np; /* now info */
float epoch; /* desired print epoch */
{
Sky sky;
/* fill sky as much as possible for object at ra/dec@EOD now */
obj_cir (ra, dec, e, np, &sky);
if (epoch != EOD)
precess ((float)mjd, epoch, &sky.s_ra, &sky.s_dec);
pr_ra (R_OBJ, C_RA, sky.s_ra);
pr_angle (R_OBJ, C_DEC, sky.s_dec);
pr_angle (R_OBJ, C_ALT, sky.s_alt);
pr_angle (R_OBJ, C_AZ, sky.s_az);
}
xXx
echo extracting pr0.c
cat > pr0.c << 'xXx'
/* basic print routines.
*/
#include <stdio.h>
#include <math.h>
#include "astro.h"
#include "screen.h"
/* the pr_ functions draw on the screen and in here so we can redraw
* the screen via pr_redraw.
*/
static char screen_shadow[NR][NC];
pr_newcir (y)
int y;
{
static char ncmsg[] = "NEW CIRCUMSTANCES";
static char nomsg[] = " ";
static int last_y = -1;
if (y != last_y) {
pr_string (R_NEWCIR, C_NEWCIR, y ? ncmsg : nomsg);
last_y = y;
}
}
/* draw n blanks at the given cursor position. */
pr_blanks (r, c, n)
int r, c, n;
{
char bl[NC+1];
sprintf (bl, "%*s", n, "");
pr_string (r, c, bl);
}
/* erase the planet info on the given row */
pr_noplanet (r)
int r;
{
pr_blanks (r, C_RA, 80-C_RA+1);
}
/* print the given value, v, in "sexadecimal" format at [r,c]
* ie, in the form A:m.P, where A is a digits wide, P is p digits.
* if p == 0, then no decimal point either.
*/
pr_sexad (r, c, a, p, mod, v)
int r, c;
int a, p; /* left space, min precision */
int mod; /* don't let whole portion get this big */
float v;
{
char astr[32], str[32];
int dec;
float frac;
int visneg;
plt_val (r, c, v);
if (v >= 0.0)
visneg = 0;
else {
visneg = 1;
v = -v;
}
dec = v;
frac = (v - dec)*60.0;
sprintf (str, "59.%.*s5", p, "999999999");
if (frac >= atof (str)) {
dec += 1;
frac = 0.0;
}
dec %= mod;
if (dec == 0 && visneg)
strcpy (str, "-0");
else
sprintf (str, "%d", visneg ? -dec : dec);
sprintf (astr, "%*s:%0*.*f", a, str, p == 0 ? 2 : p+3, p, frac);
pr_string (r, c, astr);
}
/* print the given value, t, in sexagesimal format at [r,c]
* ie, in the form T:mm:ss, where T is nd digits wide.
* N.B. we assume nd >= 2.
*/
pr_sexag (r, c, nd, t)
int r, c, nd;
float t;
{
char tstr[32];
int h, m, s;
int tisneg;
plt_val (r, c, t);
dec_sex (t, &h, &m, &s, &tisneg);
if (h == 0 && tisneg)
sprintf (tstr, "%*s-0:%02d:%02d", nd-2, "", m, s);
else
sprintf (tstr, "%*d:%02d:%02d", nd, tisneg ? -h : h, m, s);
pr_string (r, c, tstr);
}
/* print angle ra, in radians, in ra hours as hh:mm.m at [r,c]
* N.B. we assume ra is >= 0.
*/
pr_ra (r, c, ra)
int r, c;
float ra;
{
pr_sexad (r, c, 2, 1, 24, radhr(ra));
}
/* print time, t, as hh:mm:ss */
pr_time (r, c, t)
int r, c;
float t;
{
pr_sexag (r, c, 2, t);
}
/* print time, t, as hh:mm */
pr_mtime (r, c, t)
int r, c;
float t;
{
pr_sexad (r, c, 2, 0, 24, t);
}
/* print angle, a, in rads, as degress at [r,c] in form ddd:mm */
pr_angle(r, c, a)
int r, c;
float a;
{
pr_sexad (r, c, 3, 0, 360, raddeg(a));
}
/* print angle, a, in rads, as degress at [r,c] in form dddd:mm:ss */
pr_gangle(r, c, a)
int r, c;
float a;
{
pr_sexag (r, c, 4, raddeg(a));
}
/* print the given modified Julian date, jd, as the starting date at [r,c]
* in the form mm/dd/yyyy.
*/
pr_date (r, c, jd)
int r, c;
float jd;
{
char dstr[32];
int m, y;
float d;
mjd_cal (jd, &m, &d, &y);
/* shadow to the plot subsystem as years
* TODO: make this monotonically increasing
*/
plt_val (r, c, y + (m-1 + (d-1)/30.4)/12.0);
sprintf (dstr, "%2d/%02d/%04d", m, (int)(d), y);
pr_string (r, c, dstr);
}
pr_char (row, col, c)
int row, col;
char c;
{
c_pos (row, col);
putchar (c);
screen_shadow[row-1][col-1] = c;
}
pr_string (r, c, s)
int r, c;
char *s;
{
c_pos (r, c);
fputs (s, stdout);
strncpy (&screen_shadow[r-1][c-1], s, strlen(s));
}
pr_float (r, c, fmt, f)
int r, c;
char *fmt;
float f;
{
char str[80];
sprintf (str, fmt, f);
pr_string (r, c, str);
plt_val (r, c, f);
}
pr_erase()
{
int r, c;
char *rp;
c_erase();
for (r = 0; r < NR; r++) {
rp = screen_shadow[r];
for (c = 0; c < NC; c++)
rp[c] = ' ';
}
}
/* redraw entire screen from the screen_shadow
* N.B. might have '\0's in array; print them as ' '
* N.B. don't write in lower right corner of screen to avoid scroll.
*/
pr_redraw()
{
int r, c;
char ch;
int nc;
char *rp;
c_erase();
for (r = 0; r < NR; r++) {
rp = screen_shadow[r];
c_pos (r+1,1);
/* set nc <= index of last non-blank char */
for (nc = NC; --nc >= 0; ) {
ch = rp[nc];
if (ch != ' ' && ch != '\0')
break;
}
/* draw chars with index 0..nc */
for (c = 0; c <= nc; c++) {
ch = *rp++;
if (ch == '\0')
ch = ' ';
putchar (ch);
}
}
}
pr_prompt (p)
char *p;
{
int c;
c_pos (R_PROMPT, C_PROMPT);
c_eol ();
for (c = C_PROMPT-1; c < NC; c++)
screen_shadow[R_PROMPT-1][c] = ' ';
pr_string (R_PROMPT, C_PROMPT, p);
}
xXx
echo extracting screen.h
cat > screen.h << 'xXx'
/* screen layout details */
/* size of screen */
#define NR 24
#define NC 80
#define LGAP 5 /* gap between field name and value in left column */
#define GAP 6 /* gap between field name and value in other columns */
/* location of the various fields */
#define R_TITLE 1
#define C_TITLE (NC/2)
#define R_PROMPT 2
#define C_PROMPT 1
#define R_NEWCIR 3
#define C_NEWCIR ((NC-17)/2) /* 17 is length of the message */
#define R_JD 4
#define C_JD 1
#define C_JDV (C_JD+LGAP)
#define R_LST 4
#define C_LST 28
#define C_LSTV (C_LST+GAP)
#define R_UT 5
#define C_UT 1
#define C_UTV (C_UT+LGAP)
#define R_UD R_UT
#define C_UD (C_UT+14)
#define R_TZN 6
#define C_TZN 1
#define R_LT R_TZN
#define C_LT (C_TZN+LGAP)
#define R_LD R_TZN
#define C_LD (C_TZN+14)
#define R_LAT 5
#define C_LAT 28
#define C_LATV (C_LAT+4)
#define R_LONG 5
#define C_LONG 44
#define C_LONGV (C_LONG+4)
#define R_TZONE 4
#define C_TZONE 44
#define C_TZONEV (C_TZONE+GAP)
#define R_HEIGHT 8
#define C_HEIGHT 28
#define C_HEIGHTV (C_HEIGHT+GAP)
#define R_TEMP 8
#define C_TEMP 44
#define C_TEMPV (C_TEMP+GAP)
#define R_PRES 9
#define C_PRES 28
#define C_PRESV (C_PRES+GAP)
#define R_NSTEP 7
#define C_NSTEP 44
#define C_NSTEPV (C_NSTEP+GAP)
#define R_STPSZ 7
#define C_STPSZ 28
#define C_STPSZV (C_STPSZ+GAP)
#define R_LOD 9
#define C_LOD 44
#define C_LODV (C_LOD+GAP+3)
#define R_LON 10
#define C_LON 44
#define C_LONV (C_LON+GAP+3)
#define R_PLOT 10
#define C_PLOT 28
#define C_PLOTV (C_PLOT+GAP)
#define R_CAL 3
#define C_CAL 60
#define RS_TGAP (LGAP+3)
#define RS_AZGAP 16
#define R_SUNR 7
#define C_SUNR 1
#define C_SUNRT (C_SUNR+RS_TGAP)
#define C_SUNRAZ (C_SUNR+RS_AZGAP)
#define R_SUNS 8
#define C_SUNS 1
#define C_SUNST (C_SUNS+RS_TGAP)
#define C_SUNSAZ (C_SUNS+RS_AZGAP)
#define R_MOONR 9
#define C_MOONR 1
#define C_MOONRT (C_MOONR+RS_TGAP)
#define C_MOONRAZ (C_MOONR+RS_AZGAP)
#define R_MOONS 10
#define C_MOONS 1
#define C_MOONST (C_MOONS+RS_TGAP)
#define C_MOONSAZ (C_MOONS+RS_AZGAP)
#define R_DAWN 6
#define C_DAWN 28
#define C_DAWNV (C_DAWN+GAP+3)
#define R_DUSK 6
#define C_DUSK 44
#define C_DUSKV (C_DUSK+GAP+3)
/* planet info table */
#define R_PLANTAB 12
#define R_EPOCH (R_PLANTAB+1)
#define C_EPOCH C_RA
#define R_SUN (R_PLANTAB+2)
#define R_MOON (R_PLANTAB+3)
#define R_MERCURY (R_PLANTAB+4)
#define R_VENUS (R_PLANTAB+5)
#define R_MARS (R_PLANTAB+6)
#define R_JUPITER (R_PLANTAB+7)
#define R_SATURN (R_PLANTAB+8)
#define R_URANUS (R_PLANTAB+9)
#define R_NEPTUNE (R_PLANTAB+10)
#define R_PLUTO (R_PLANTAB+11)
#define R_OBJ (R_PLANTAB+12)
#define C_OBJ 1
#define C_RA 4
#define C_DEC 12
#define C_HLONG 19
#define C_HLAT 26
#define C_AZ 33
#define C_ALT 40
#define C_EDIST 47
#define C_SDIST 54
#define C_ELONG 61
#define C_SIZE 68
#define C_MAG 73
#define C_PHASE 78
#define PW (NC-C_PROMPT+1) /* total prompt line width */
#define F_SHFT 12 /* shift to flags fields */
#define F_CHG (1<<F_SHFT) /* field may be picked for changing */
#define F_PLT (2<<F_SHFT) /* field may be picked for plotting */
#define F_VIS (4<<F_SHFT) /* field is visible (may be picked period) */
#define rcfpack(r,c,f) ((f) | ((r) << 7) | (c))
#define unpackr(p) (((p)>>7)&0x1f)
#define unpackc(p) ((p)&0x7f)
#define tstpackf(p,f) (((p)&(f))==(f))
xXx
echo extracting sel_lfd.c
cat > sel_fld.c << 'xXx'
#include "screen.h"
#define cntrl(x) ((x) & 037)
#define ESC cntrl('[') /* char to exit input mode */
#define QUIT cntrl('d') /* char to exit program */
#define HELP '?' /* char to give help message */
#define REDRAW cntrl('l') /* char to redraw (like vi) */
#define VERSION cntrl('v') /* char to display version number */
/* table of the fields pickable for changing or plotting */
int fields[] = {
rcfpack (R_DAWN, C_DAWN, F_VIS|F_CHG),
rcfpack (R_DAWN, C_DAWNV, F_VIS|F_PLT),
rcfpack (R_DUSK, C_DUSK, F_VIS|F_CHG),
rcfpack (R_DUSK, C_DUSKV, F_VIS|F_PLT),
rcfpack (R_EPOCH, C_EPOCH, F_VIS|F_CHG|F_PLT),
rcfpack (R_HEIGHT, C_HEIGHTV, F_VIS|F_CHG|F_PLT),
rcfpack (R_JUPITER, C_ALT, F_VIS|F_PLT),
rcfpack (R_JUPITER, C_AZ, F_VIS|F_PLT),
rcfpack (R_JUPITER, C_DEC, F_VIS|F_PLT),
rcfpack (R_JUPITER, C_EDIST, F_VIS|F_PLT),
rcfpack (R_JUPITER, C_ELONG, F_VIS|F_PLT),
rcfpack (R_JUPITER, C_HLAT, F_VIS|F_PLT),
rcfpack (R_JUPITER, C_HLONG, F_VIS|F_PLT),
rcfpack (R_JUPITER, C_MAG, F_VIS|F_PLT),
rcfpack (R_JUPITER, C_OBJ, F_VIS|F_CHG),
rcfpack (R_JUPITER, C_PHASE, F_VIS|F_PLT),
rcfpack (R_JUPITER, C_RA, F_VIS|F_PLT),
rcfpack (R_JUPITER, C_SDIST, F_VIS|F_PLT),
rcfpack (R_JUPITER, C_SIZE, F_VIS|F_PLT),
rcfpack (R_LAT, C_LATV, F_VIS|F_CHG|F_PLT),
rcfpack (R_LD, C_LD, F_VIS|F_PLT|F_CHG),
rcfpack (R_LOD, C_LODV, F_VIS|F_CHG|F_PLT),
rcfpack (R_LON, C_LONV, F_VIS|F_CHG|F_PLT),
rcfpack (R_LONG, C_LONGV, F_VIS|F_CHG|F_PLT),
rcfpack (R_LT, C_LT, F_VIS|F_CHG|F_PLT),
rcfpack (R_MARS, C_ALT, F_VIS|F_PLT),
rcfpack (R_MARS, C_AZ, F_VIS|F_PLT),
rcfpack (R_MARS, C_DEC, F_VIS|F_PLT),
rcfpack (R_MARS, C_EDIST, F_VIS|F_PLT),
rcfpack (R_MARS, C_ELONG, F_VIS|F_PLT),
rcfpack (R_MARS, C_HLAT, F_VIS|F_PLT),
rcfpack (R_MARS, C_HLONG, F_VIS|F_PLT),
rcfpack (R_MARS, C_MAG, F_VIS|F_PLT),
rcfpack (R_MARS, C_OBJ, F_VIS|F_CHG),
rcfpack (R_MARS, C_PHASE, F_VIS|F_PLT),
rcfpack (R_MARS, C_RA, F_VIS|F_PLT),
rcfpack (R_MARS, C_SDIST, F_VIS|F_PLT),
rcfpack (R_MARS, C_SIZE, F_VIS|F_PLT),
rcfpack (R_MERCURY, C_ALT, F_VIS|F_PLT),
rcfpack (R_MERCURY, C_AZ, F_VIS|F_PLT),
rcfpack (R_MERCURY, C_DEC, F_VIS|F_PLT),
rcfpack (R_MERCURY, C_EDIST, F_VIS|F_PLT),
rcfpack (R_MERCURY, C_ELONG, F_VIS|F_PLT),
rcfpack (R_MERCURY, C_HLAT, F_VIS|F_PLT),
rcfpack (R_MERCURY, C_HLONG, F_VIS|F_PLT),
rcfpack (R_MERCURY, C_MAG, F_VIS|F_PLT),
rcfpack (R_MERCURY, C_OBJ, F_VIS|F_CHG),
rcfpack (R_MERCURY, C_PHASE, F_VIS|F_PLT),
rcfpack (R_MERCURY, C_RA, F_VIS|F_PLT),
rcfpack (R_MERCURY, C_SDIST, F_VIS|F_PLT),
rcfpack (R_MERCURY, C_SIZE, F_VIS|F_PLT),
rcfpack (R_MOON, C_ALT, F_VIS|F_PLT),
rcfpack (R_MOON, C_AZ, F_VIS|F_PLT),
rcfpack (R_MOON, C_DEC, F_VIS|F_PLT),
rcfpack (R_MOON, C_EDIST, F_VIS|F_PLT),
rcfpack (R_MOON, C_ELONG, F_VIS|F_PLT),
rcfpack (R_MOON, C_MAG, F_VIS|F_PLT),
rcfpack (R_MOON, C_OBJ, F_VIS|F_CHG),
rcfpack (R_MOON, C_PHASE, F_VIS|F_PLT),
rcfpack (R_MOON, C_RA, F_VIS|F_PLT),
rcfpack (R_MOON, C_SDIST, F_VIS|F_PLT),
rcfpack (R_MOON, C_SIZE, F_VIS|F_PLT),
rcfpack (R_MOONR, C_MOONR, F_VIS|F_CHG),
rcfpack (R_MOONR, C_MOONRAZ, F_VIS|F_PLT),
rcfpack (R_MOONR, C_MOONRT, F_VIS|F_PLT),
rcfpack (R_MOONS, C_MOONS, F_VIS|F_CHG),
rcfpack (R_MOONS, C_MOONSAZ, F_VIS|F_PLT),
rcfpack (R_MOONS, C_MOONST, F_VIS|F_PLT),
rcfpack (R_NEPTUNE, C_ALT, F_VIS|F_PLT),
rcfpack (R_NEPTUNE, C_AZ, F_VIS|F_PLT),
rcfpack (R_NEPTUNE, C_DEC, F_VIS|F_PLT),
rcfpack (R_NEPTUNE, C_EDIST, F_VIS|F_PLT),
rcfpack (R_NEPTUNE, C_ELONG, F_VIS|F_PLT),
rcfpack (R_NEPTUNE, C_HLAT, F_VIS|F_PLT),
rcfpack (R_NEPTUNE, C_HLONG, F_VIS|F_PLT),
rcfpack (R_NEPTUNE, C_MAG, F_VIS|F_PLT),
rcfpack (R_NEPTUNE, C_OBJ, F_VIS|F_CHG),
rcfpack (R_NEPTUNE, C_PHASE, F_VIS|F_PLT),
rcfpack (R_NEPTUNE, C_RA, F_VIS|F_PLT),
rcfpack (R_NEPTUNE, C_SDIST, F_VIS|F_PLT),
rcfpack (R_NEPTUNE, C_SIZE, F_VIS|F_PLT),
rcfpack (R_NSTEP, C_NSTEPV, F_VIS|F_CHG),
rcfpack (R_OBJ, C_ALT, F_VIS|F_PLT),
rcfpack (R_OBJ, C_AZ, F_VIS|F_PLT),
rcfpack (R_OBJ, C_DEC, F_VIS|F_CHG|F_PLT),
rcfpack (R_OBJ, C_OBJ, F_VIS|F_CHG),
rcfpack (R_OBJ, C_RA, F_VIS|F_CHG|F_PLT),
rcfpack (R_PLOT, C_PLOT, F_VIS|F_CHG),
rcfpack (R_PLOT, C_PLOTV, F_VIS|F_CHG),
rcfpack (R_PLUTO, C_ALT, F_VIS|F_PLT),
rcfpack (R_PLUTO, C_AZ, F_VIS|F_PLT),
rcfpack (R_PLUTO, C_DEC, F_VIS|F_PLT),
rcfpack (R_PLUTO, C_EDIST, F_VIS|F_PLT),
rcfpack (R_PLUTO, C_ELONG, F_VIS|F_PLT),
rcfpack (R_PLUTO, C_HLAT, F_VIS|F_PLT),
rcfpack (R_PLUTO, C_HLONG, F_VIS|F_PLT),
rcfpack (R_PLUTO, C_MAG, F_VIS|F_PLT),
rcfpack (R_PLUTO, C_OBJ, F_VIS|F_CHG),
rcfpack (R_PLUTO, C_PHASE, F_VIS|F_PLT),
rcfpack (R_PLUTO, C_RA, F_VIS|F_PLT),
rcfpack (R_PLUTO, C_SDIST, F_VIS|F_PLT),
rcfpack (R_PLUTO, C_SIZE, F_VIS|F_PLT),
rcfpack (R_PRES, C_PRESV, F_VIS|F_CHG|F_PLT),
rcfpack (R_SATURN, C_ALT, F_VIS|F_PLT),
rcfpack (R_SATURN, C_AZ, F_VIS|F_PLT),
rcfpack (R_SATURN, C_DEC, F_VIS|F_PLT),
rcfpack (R_SATURN, C_EDIST, F_VIS|F_PLT),
rcfpack (R_SATURN, C_ELONG, F_VIS|F_PLT),
rcfpack (R_SATURN, C_HLAT, F_VIS|F_PLT),
rcfpack (R_SATURN, C_HLONG, F_VIS|F_PLT),
rcfpack (R_SATURN, C_MAG, F_VIS|F_PLT),
rcfpack (R_SATURN, C_OBJ, F_VIS|F_CHG),
rcfpack (R_SATURN, C_PHASE, F_VIS|F_PLT),
rcfpack (R_SATURN, C_RA, F_VIS|F_PLT),
rcfpack (R_SATURN, C_SDIST, F_VIS|F_PLT),
rcfpack (R_SATURN, C_SIZE, F_VIS|F_PLT),
rcfpack (R_STPSZ, C_STPSZV, F_VIS|F_CHG),
rcfpack (R_SUN, C_ALT, F_VIS|F_PLT),
rcfpack (R_SUN, C_AZ, F_VIS|F_PLT),
rcfpack (R_SUN, C_DEC, F_VIS|F_PLT),
rcfpack (R_SUN, C_EDIST, F_VIS|F_PLT),
rcfpack (R_SUN, C_HLAT, F_VIS|F_PLT),
rcfpack (R_SUN, C_HLONG, F_VIS|F_PLT),
rcfpack (R_SUN, C_MAG, F_VIS|F_PLT),
rcfpack (R_SUN, C_OBJ, F_VIS|F_CHG),
rcfpack (R_SUN, C_RA, F_VIS|F_PLT),
rcfpack (R_SUN, C_SIZE, F_VIS|F_PLT),
rcfpack (R_SUNR, C_SUNR, F_VIS|F_CHG),
rcfpack (R_SUNR, C_SUNRAZ, F_VIS|F_PLT),
rcfpack (R_SUNR, C_SUNRT, F_VIS|F_PLT),
rcfpack (R_SUNS, C_SUNS, F_VIS|F_CHG),
rcfpack (R_SUNS, C_SUNSAZ, F_VIS|F_PLT),
rcfpack (R_SUNS, C_SUNST, F_VIS|F_PLT),
rcfpack (R_TEMP, C_TEMPV, F_VIS|F_CHG|F_PLT),
rcfpack (R_TZN, C_TZN, F_VIS|F_CHG),
rcfpack (R_TZONE, C_TZONEV, F_VIS|F_CHG),
rcfpack (R_UD, C_UD, F_VIS|F_PLT|F_CHG),
rcfpack (R_URANUS, C_ALT, F_VIS|F_PLT),
rcfpack (R_URANUS, C_AZ, F_VIS|F_PLT),
rcfpack (R_URANUS, C_DEC, F_VIS|F_PLT),
rcfpack (R_URANUS, C_EDIST, F_VIS|F_PLT),
rcfpack (R_URANUS, C_ELONG, F_VIS|F_PLT),
rcfpack (R_URANUS, C_HLAT, F_VIS|F_PLT),
rcfpack (R_URANUS, C_HLONG, F_VIS|F_PLT),
rcfpack (R_URANUS, C_MAG, F_VIS|F_PLT),
rcfpack (R_URANUS, C_OBJ, F_VIS|F_CHG),
rcfpack (R_URANUS, C_PHASE, F_VIS|F_PLT),
rcfpack (R_URANUS, C_RA, F_VIS|F_PLT),
rcfpack (R_URANUS, C_SDIST, F_VIS|F_PLT),
rcfpack (R_URANUS, C_SIZE, F_VIS|F_PLT),
rcfpack (R_UT, C_UTV, F_VIS|F_PLT|F_CHG),
rcfpack (R_VENUS, C_ALT, F_VIS|F_PLT),
rcfpack (R_VENUS, C_AZ, F_VIS|F_PLT),
rcfpack (R_VENUS, C_DEC, F_VIS|F_PLT),
rcfpack (R_VENUS, C_EDIST, F_VIS|F_PLT),
rcfpack (R_VENUS, C_ELONG, F_VIS|F_PLT),
rcfpack (R_VENUS, C_HLAT, F_VIS|F_PLT),
rcfpack (R_VENUS, C_HLONG, F_VIS|F_PLT),
rcfpack (R_VENUS, C_MAG, F_VIS|F_PLT),
rcfpack (R_VENUS, C_OBJ, F_VIS|F_CHG),
rcfpack (R_VENUS, C_PHASE, F_VIS|F_PLT),
rcfpack (R_VENUS, C_RA, F_VIS|F_PLT),
rcfpack (R_VENUS, C_SDIST, F_VIS|F_PLT),
rcfpack (R_VENUS, C_SIZE, F_VIS|F_PLT),
};
#define NFIELDS (sizeof(fields)/sizeof(fields[0]))
/* let op select a field by moving around and hitting RETURN, or until see ESC.
* only allow fields with the given flag mask.
* return the rcfpack()'d field, or 0 if typed ESC.
* N.B. we might also exit() entirely by calling bye() of op types QUIT.
*/
sel_fld (r, c, flag, prmpt, help)
int r, c; /* inial row, col */
int flag;
char *prmpt, *help;
{
char *lastp;
int ch;
lastp = 0;
while (1) {
if (lastp != prmpt) {
lastp = prmpt;
pr_prompt (lastp);
}
c_pos (r, c);
switch (ch = read_char()) {
case REDRAW:
pr_redraw();
lastp = 0;
break;
case VERSION:
version();
lastp = 0;
break;
case HELP:
pr_prompt (help);
(void) read_char(); /* hit any key to continue */
lastp = 0;
break;
case QUIT:
bye(); /* probably never returns */
break;
case ESC:
return (0);
case '\r':
return (rcfpack (r, c, 0));
default:
move_cur (ch, flag, &r, &c);
break;
}
}
}
/* move cursor to next field in given direction: hjkl.
* limit eligible fields to those with given flag mask.
*/
static
move_cur (dirchar, flag, rp, cp)
char dirchar;
int flag;
int *rp, *cp;
{
int curr = *rp, curc = *cp;
int f, newf, *fp;
int d, newd;
newf = 0;
newd = 1000;
switch (dirchar) {
case 'h': case 'H': /* left */
/* go to next field to the left, or wrap. */
for (fp = fields+NFIELDS; --fp >= fields; ) {
f = *fp;
if (tstpackf(f,flag) && unpackr(f) == curr) {
d = curc - unpackc(f);
if (d > 0 && d < newd) {
newf = f;
newd = d;
}
}
}
if (newf)
curc = unpackc(newf);
else {
curc = NC;
move_cur (dirchar, flag, &curr, &curc);
}
break;
case 'j': case 'J': /* down */
/* go to closest field on next row down with anything on it,
* or wrap.
*/
for (fp = fields+NFIELDS; --fp >= fields; ) {
f = *fp;
if (tstpackf(f,flag)) {
d = unpackr(f) - curr;
if (d > 0 && d < newd) {
newf = f;
newd = d;
}
}
}
if (newf) {
newf = nearestfld (unpackr(newf), curc, flag);
curr = unpackr(newf);
curc = unpackc(newf);
} else {
curr = 0;
move_cur (dirchar, flag, &curr, &curc);
}
break;
case 'k': case 'K': /* up */
/* go to closest field on next row up with anything on it,
* or wrap.
*/
for (fp = fields+NFIELDS; --fp >= fields; ) {
f = *fp;
if (tstpackf(f,flag)) {
d = curr - unpackr(f);
if (d > 0 && d < newd) {
newf = f;
newd = d;
}
}
}
if (newf) {
newf = nearestfld (unpackr(newf), curc, flag);
curr = unpackr(newf);
curc = unpackc(newf);
} else {
curr = NR+1;
move_cur (dirchar, flag, &curr, &curc);
}
break;
case 'l': case 'L': /* right */
case ' ': /* space also goes right */
/* go to next field to the right, or wrap. */
for (fp = fields+NFIELDS; --fp >= fields; ) {
f = *fp;
if (tstpackf(f,flag) && unpackr(f) == curr) {
d = unpackc(f) - curc;
if (d > 0 && d < newd) {
newf = f;
newd = d;
}
}
}
if (newf)
curc = unpackc(newf);
else {
curc = 0;
move_cur (dirchar, flag, &curr, &curc);
}
break;
}
*rp = curr;
*cp = curc;
}
/* return the nearest field with given flag mask, either way, on this row,
* else -1 if none.
*/
static
nearestfld (r, c, flag)
int r, c, flag;
{
int nf, f, *fp;
int d, d0;
nf = 0;
d0 = 1000;
for (fp = fields+NFIELDS; --fp >= fields; ) {
f = *fp;
if (tstpackf(f,flag) && unpackr(f) == r) {
d = abs(c - unpackc(f));
if (d < d0) {
nf = f;
d0 = d;
}
}
}
return (nf ? nf : -1);
}
xXx
echo extracting time.c
cat > time.c << 'xXx'
#include <stdio.h>
#include <time.h>
#include "astro.h"
#include "circum.h"
/* shorthands into np */
#define mjd np->n_mjd
#define lat np->n_lat
#define lng np->n_lng
#define tz np->n_tz
#define temp np->n_temp
#define pressure np->n_pressure
#define height np->n_height
#define tznm np->n_tznm
static long c0;
static double mjd0;
/* save current mjd and corresponding system clock for use by inc_mjd().
* this establishes the base correspondence between the mjd and system clock.
*/
set_t0 (np)
Now *np;
{
mjd0 = mjd;
time (&c0);
}
/* fill in n_mjd/tz/tznm from system clock */
time_fromsys (np)
Now *np;
{
extern long timezone;
extern int daylight;
extern char *tzname[2];
extern struct tm *gmtime();
struct tm *tp;
long c;
float day, hr;
tzset();
tz = timezone/3600;
strncpy (tznm, tzname[daylight?1:0], sizeof(tznm)-1);
tznm[sizeof(tznm)-1] = '\0'; /* insure string is terminated */
time (&c);
tp = gmtime (&c);
cal_mjd (tp->tm_mon+1, (float)tp->tm_mday, tp->tm_year+1900, &day);
sex_dec (tp->tm_hour, tp->tm_min, tp->tm_sec, &hr);
mjd = (double)day + hr/24.0;
}
inc_mjd (np, inc)
Now *np;
float inc;
{
if (inc == RTC) {
long c;
time (&c);
mjd = mjd0 + (c - c0)/SPD;
} else
mjd += inc/24.0;
/* round to nearest whole second.
* without this, you can get fractional days so close to .5 but
* not quite there that mjd_hr() can return 24.0
*/
rnd_second (&mjd);
}
xXx
echo extracting version.c
cat > version.c << 'xXx'
/* N.B. edit this any time something is changed.
* keep a running history too:
* 2.0 9/13/1988 add version ^v option
* 2.1 9/14/1988 moon phase always >= 0 to match planets convention
* 2.2 9/20/1988 more caution in aaha_aux() guarding acos() arg range
* 2.3 9/23/1988 exchange Altitude/Elevation titles (no code changes)
* 2.4 10/31/1988 add credits banner, -s turns it off; savings time fix.
* 2.5 12/26/1988 remove trace capability; add screen shadowing: ^l.
* 2.6 12/28/1988 twilight defined as 18 rather than 15 degrees below horizon
* 2.7 12/30/1988 add version to credits.
* 3.0 12/31/1988 add graphing; add version to credits.
* 3.1 1/1/1989 user def. graph labels; nstep/stpsz control; genuine c_eol
* 3.2 1/3/1989 if set date/time then time does not inc first step
* 3.3 1/6/1989 add z to plot files (still don't plot it however)
* 3.4 1/22/1989 calendar and all rise/set times based on local date, not utc
* 3.5 2/2/1989 sunrise/set times based on actual sun size and pressure/temp
* 3.6 2/7/1989 try adding .cfg suffix if can't find config file
* 3.7 2/13/1989 change to ^d to quit program.
* 3.8 3/2/1989 shorten displayed precision, add heliocentric lat/long
* 3.9 4/5/1989 discard leading termcap delay digits, for now
* 3.10 4/27/1989 allow caps for moving cursor around too
* 3.11 5/16/1989 local time prompt said utc; add NiteLn; check for bad plot
* files; couldn't plot dayln or niteln.
*/
#include "screen.h"
static char vmsg[] = "Version 3.11 May 16, 1989";
version()
{
pr_prompt (vmsg);
(void) read_char(); /* hit any key to continue */
}
static char *cre[] = {
"Ephem - computerized ephemeris",
vmsg,
"by Elwood Downey",
"",
"Many formulas and tables are based, with permission, on material found in",
"\"Astronomy with your Personal Computer\"",
"by Dr. Peter Duffett-Smith, Cambridge University Press, 1985",
"",
"type any key to continue..."
};
credits()
{
int r = 10; /* first row of credits message */
int l;
pr_erase();
for (l = 0; l < sizeof(cre)/sizeof(cre[0]); l++)
pr_string (r++, (NC - strlen(cre[l]))/2, cre[l]);
(void) read_char(); /* wait for any char to continue */
}
xXx