allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (06/04/89)
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