This is main.c in view mode; [Download] [Up]
/* main "ephem" program. * ------------------------------------------------------------------- * Copyright (c) 1990,1991,1992 by Elwood Charles Downey * * Permission is granted to make and distribute copies of this program * free of charge, provided the copyright notice and this permission * notice are preserved on all copies. All other rights reserved. * ------------------------------------------------------------------- * set options. * init screen and circumstances. * enter infinite loop updating screen and allowing operator input. */ #include <stdio.h> #include <ctype.h> #include <signal.h> #include <setjmp.h> #include <math.h> #ifdef VMS #include <stdlib.h> #endif #ifdef NeXT # include <stdlib.h> #endif #include "astro.h" #include "circum.h" #include "screen.h" extern char *strncpy(); extern char *getenv(); /* shorthands for fields of a Now structure, now. * first undo the ones for a Now pointer from circum.h. */ #undef mjd #undef lat #undef lng #undef tz #undef temp #undef pressure #undef height #undef epoch #undef tznm #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 epoch now.n_epoch #define tznm now.n_tznm static jmp_buf fpe_err_jmp; /* used to recover from SIGFPE */ static char *cfgfile; /* !0 if -c used */ static char cfgdef[] = "ephem.cfg"; /* default configuration file name */ static Now now; /* where when and how, right now */ static double tminc; /* hrs to inc time by each loop; RTC means use clock */ static int nstep; /* steps to go before stopping */ static int spause; /* secs to pause between steps */ static int optwi; /* set when want to display dawn/dusk/len-of-night */ static int oppl; /* mask of (1<<planet) bits; set when want to show it */ main (ac, av) int ac; char *av[]; { void bye(); void on_fpe(); 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 q to run"; static char hlp[] = "arrow keys move to field; any key stops running; ^d exits; ^l redraws"; int fld = rcfpack(R_NSTEP, C_NSTEPV, 0); /* initial cursor loc */ int sflag = 0; /* not silent, by default */ int one = 1; /* use a variable so optimizer doesn't get disabled */ int srchdone = 0; /* true when search funcs say so */ int newcir = 2; /* set when circumstances change - means don't tminc */ 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("-c but no config file"); cfgfile = *++av; break; case 'd': /* set alternate database file name */ if (--ac <= 0) usage("-d but no database file"); obj_setdbfilename (*++av); break; default: usage("Bad - option"); } } if (!sflag) credits(); /* fresh screen. * crack config file, THEN args so args may override. */ c_erase(); read_cfgfile (); read_fieldargs (ac, av); /* set up to clean up screen and tty if interrupted. * also set up to stop if get floating error. */ (void) signal (SIGINT, bye); (void) signal (SIGFPE, on_fpe); /* update screen forever (until QUIT) */ while (one) { /* if get a floating error, longjmp() here and stop looping */ if (setjmp (fpe_err_jmp)) nstep = 0; else { nstep -= 1; /* recalculate everything and update all the fields */ redraw_screen (newcir); mm_newcir (0); /* let searching functions change tminc and check for done */ srchdone = srch_eval (mjd, &tminc) < 0; print_tminc(0); /* to show possibly new search increment */ /* update plot and listing files, now that all fields are up * to date and search function has been evaluated. */ plot(); listing(); /* handle spause if we are really looping */ if (nstep > 0) slp_sync(); } /* stop loop to allow op to change parameters: * if a search evaluation converges (or errors out), * or if steps are done, * or if op hits any key. */ newcir = 0; if (srchdone || nstep <= 0 || (chk_char()==0 && read_char()!=0)) { int nfld; /* update screen with the current stuff if stopped during * unattended plotting or listing since last redraw_screen() * didn't. */ if ((plot_ison() || listing_ison()) && nstep > 0) redraw_screen (1); /* return nstep to default of 1 */ if (nstep <= 0) { nstep = 1; print_nstep (0); } /* change fields until END. * update all time fields if any are changed * and print NEW CIRCUMSTANCES if any have changed. * QUIT causes bye() to be called and we never return. */ while(nfld = sel_fld(fld,alt_menumask()|F_CHG,prmpt,hlp)) { if (chg_fld ((char *)0, &nfld)) { mm_now (&now, 1); mm_newcir(1); newcir = 1; } fld = nfld; } if (nstep > 1) f_prompt (freerun); } /* increment time only if op didn't change cirumstances */ if (!newcir) inc_mjd (&now, tminc); } return (0); } /* read in ephem's configuration file, if any. * if errors in file, call usage() (which exits). * if use -d, require it; else try $EPHEMCFG and ephem.cfg but don't * complain if can't find these since, after all, one is not required. * skip all lines that doesn't begin with an alpha char. */ static read_cfgfile() { char buf[128]; FILE *fp; char *fn; /* open the config file. * only REQUIRED if used -d option. * if succcessful, fn points to file name. */ if (cfgfile) { fn = cfgfile; fp = fopen (fn, "r"); if (!fp) { (void) sprintf (buf, "Can not open %s", fn); usage (buf); /* does not return */ } } else { fn = getenv ("EPHEMCFG"); if (!fn) fn = cfgdef; } fp = fopen (fn, "r"); if (!fp) return; /* oh well; after all, it's not required */ while (fgets (buf, sizeof(buf), fp)) { if (!isalpha(buf[0])) continue; buf[strlen(buf)-1] = '\0'; /* discard trailing \n */ if (crack_fieldset (buf) < 0) { char why[NC]; (void) sprintf (why, "Bad field spec in %s: %s\n", fn, buf); usage (why); } } (void) fclose (fp); } /* draw all the stuff on the screen, using the current menu. * if how_much == 0 then just update fields that need it; * if how_much == 1 then redraw all fields; * if how_much == 2 then erase the screen and redraw EVERYTHING. */ redraw_screen (how_much) int how_much; { if (how_much == 2) c_erase(); /* print the single-step message if this is the last loop */ if (nstep < 1) print_updating(); if (how_much == 2) { mm_borders(); mm_labels(); srch_prstate(1); plot_prstate(1); listing_prstate(1); } /* if just updating changed fields while plotting or listing * unattended then suppress most screen updates except * always show nstep to show plot loops to go and * always show tminc to show search convergence progress. */ print_nstep(how_much); print_tminc(how_much); print_spause(how_much); if (how_much == 0 && (plot_ison() || listing_ison()) && nstep > 0) f_off(); /* print all the time-related fields */ mm_now (&now, how_much); if (optwi) mm_twilight (&now, how_much); /* print stuff on bottom menu */ print_alt (how_much); f_on(); } /* clean up and exit. */ void bye() { c_erase(); byetty(); exit (0); } /* this gets called when a floating point error occurs. * we force a jump back into main() with looping terminated. */ static void on_fpe() { extern void longjmp(); (void) signal (SIGFPE, on_fpe); f_msg ("Floating point error has occurred - computations aborted."); longjmp (fpe_err_jmp, 1); } usage(why) char *why; { /* don't advertise -s (silent) option */ c_erase(); f_string (1, 1, why); f_string (2, 1, "usage: [-c <configfile>] [-d <database>] [field=value ...]\r\n"); byetty(); exit (1); } /* Process the field specs from the command line. * if trouble call usage() (which exits). */ static read_fieldargs (ac, av) int ac; /* number of such specs */ char *av[]; /* array of strings in form <field_name value> */ { while (--ac >= 0) { char *fs = *av++; if (crack_fieldset (fs) < 0) { char why[NC]; (void) sprintf (why, "Bad command line spec: %.*s", sizeof(why)-26, fs); usage (why); } } } /* process a field spec in buf, either from config file or argv. * return 0 if recognized ok, else -1. */ static crack_fieldset (buf) char *buf; { #define ARRAY_SIZ(a) (sizeof(a)/sizeof((a)[0])) #define MAXKW 6 /* longest keyword, not counting trailing 0 */ /* N.B. index of item is its case value, below. * N.B. if add an item, keep it no longer than MAXKW chars. */ static char keywords[][MAXKW+1] = { /* 0 */ "LAT", /* 1 */ "LONG", /* 2 */ "UT", /* 3 */ "UD", /* 4 */ "TZONE", /* 5 */ "TZNAME", /* 6 */ "HEIGHT", /* 7 */ "NSTEP", /* 8 */ "PAUSE", /* 9 */ "STPSZ", /* 10 */ "TEMP", /* 11 */ "PRES", /* 12 */ "EPOCH", /* 13 */ "JD", /* 14 */ "OBJX", /* 15 */ "OBJY", /* 16 */ "PROPTS", /* 17 */ "MENU" }; int i; int l; int f; for (i = 0; i < ARRAY_SIZ(keywords); i++) if (strncmp (keywords[i], buf, l = strlen(keywords[i])) == 0) { buf += l+1; /* skip keyword and its subsequent delimiter */ break; } switch (i) { case 0: f = rcfpack (R_LAT,C_LATV,0); (void) chg_fld (buf, &f); break; case 1: f = rcfpack (R_LONG,C_LONGV,0), (void) chg_fld (buf, &f); break; case 2: f = rcfpack (R_UT,C_UTV,0), (void) chg_fld (buf, &f); break; case 3: f = rcfpack (R_UD,C_UD,0), (void) chg_fld (buf, &f); break; case 4: f = rcfpack (R_TZONE,C_TZONEV,0), (void) chg_fld (buf, &f); break; case 5: f = rcfpack (R_TZN,C_TZN,0), (void) chg_fld (buf, &f); break; case 6: f = rcfpack (R_HEIGHT,C_HEIGHTV,0), (void) chg_fld (buf, &f); break; case 7: f = rcfpack (R_NSTEP,C_NSTEPV,0), (void) chg_fld (buf, &f); break; case 8: f = rcfpack (R_PAUSE,C_PAUSEV,0), (void) chg_fld (buf, &f); break; case 9: f = rcfpack (R_STPSZ,C_STPSZV,0), (void) chg_fld (buf, &f); break; case 10: f = rcfpack (R_TEMP,C_TEMPV,0), (void) chg_fld (buf, &f); break; case 11: f = rcfpack (R_PRES,C_PRESV,0), (void) chg_fld (buf, &f); break; case 12: f = rcfpack (R_EPOCH,C_EPOCHV,0), (void) chg_fld (buf, &f); break; case 13: f = rcfpack (R_JD,C_JDV,0), (void) chg_fld (buf, &f); break; case 14: (void) obj_filelookup (OBJX, buf); break; case 15: (void) obj_filelookup (OBJY, buf); break; case 16: if (buf[-1] != '+') optwi = oppl = 0; while (*buf) switch (*buf++) { case 'T': optwi = 1; break; case 'S': oppl |= (1<<SUN); break; case 'M': oppl |= (1<<MOON); break; case 'e': oppl |= (1<<MERCURY); break; case 'v': oppl |= (1<<VENUS); break; case 'm': oppl |= (1<<MARS); break; case 'j': case 'J': oppl |= (1<<JUPITER); break; case 's': oppl |= (1<<SATURN); break; case 'u': oppl |= (1<<URANUS); break; case 'n': oppl |= (1<<NEPTUNE); break; case 'p': oppl |= (1<<PLUTO); break; case 'x': oppl |= (1<<OBJX); obj_on(OBJX); break; case 'y': oppl |= (1<<OBJY); obj_on(OBJY); break; } break; case 17: if (strncmp (buf, "DATA", 4) == 0) altmenu_init (F_MNU1); else if (strncmp (buf, "RISET", 5) == 0) altmenu_init (F_MNU2); else if (strncmp (buf, "SEP", 3) == 0) altmenu_init (F_MNU3); else if (strncmp (buf, "JUP", 3) == 0) altmenu_init (F_MNUJ); break; default: return (-1); } return (0); } /* react to the field at *fld 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. * we might also change *fld if we want to change the current cursor location. * return 1 if we change a field that invalidates any of the times or * to update all related fields. */ static chg_fld (bp, fld) char *bp; int *fld; { char buf[NC]; int deghrs = 0, mins = 0, secs = 0; int new = 0; /* switch on just the row/col portion */ switch (unpackrc(*fld)) { case rcfpack (R_ALTM, C_ALTM, 0): if (altmenu_setup() == 0) { print_updating(); alt_erase(); print_alt(2); } break; case rcfpack (R_JD, C_JDV, 0): if (!bp) { static char p[] = "Julian Date (or n for Now): "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } if (bp[0] == 'n' || bp[0] == 'N') time_fromsys (&now); else mjd = atof(bp) - 2415020L; set_t0 (&now); new = 1; break; case rcfpack (R_UD, C_UD, 0): if (!bp) { static char p[] = "utc date (m/d/y, or year.d, or n for Now): "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } if (bp[0] == 'n' || bp[0] == 'N') time_fromsys (&now); else { if (decimal_year(bp)) { double y = atof (bp); year_mjd (y, &mjd); } else { double day, newmjd0; int month, year; mjd_cal (mjd, &month, &day, &year); /* init with now */ f_sscandate (bp, &month, &day, &year); cal_mjd (month, day, year, &newmjd0); /* if don't give a fractional part to days * then retain current hours. */ if ((long)day == day) mjd = newmjd0 + mjd_hr(mjd)/24.0; else mjd = newmjd0; } } set_t0 (&now); new = 1; break; case rcfpack (R_UT, C_UTV, 0): if (!bp) { static char p[] = "utc time (h:m:s, or n for Now): "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } if (bp[0] == 'n' || bp[0] == 'N') time_fromsys (&now); else { double newutc = (mjd-mjd_day(mjd)) * 24.0; f_dec_sexsign (newutc, °hrs, &mins, &secs); f_sscansex (bp, °hrs, &mins, &secs); sex_dec (deghrs, mins, secs, &newutc); mjd = mjd_day(mjd) + newutc/24.0; } set_t0 (&now); new = 1; break; case rcfpack (R_LD, C_LD, 0): if (!bp) { static char p[] = "local date (m/d/y, or year.d, n for Now): "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } if (bp[0] == 'n' || bp[0] == 'N') time_fromsys (&now); else { if (decimal_year(bp)) { double y = atof (bp); year_mjd (y, &mjd); mjd += tz/24.0; } else { double day, newlmjd0; int month, year; mjd_cal (mjd-tz/24.0, &month, &day, &year); /* now */ f_sscandate (bp, &month, &day, &year); cal_mjd (month, day, year, &newlmjd0); /* if don't give a fractional part to days * then retain current hours. */ if ((long)day == day) mjd = newlmjd0 + mjd_hr(mjd-tz/24.0)/24.0; else mjd = newlmjd0; mjd += tz/24.0; } } set_t0 (&now); new = 1; break; case rcfpack (R_LT, C_LT, 0): if (!bp) { static char p[] = "local time (h:m:s, or n for Now): "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } if (bp[0] == 'n' || bp[0] == 'N') time_fromsys (&now); else { double newlt = (mjd-mjd_day(mjd)) * 24.0 - tz; range (&newlt, 24.0); f_dec_sexsign (newlt, °hrs, &mins, &secs); f_sscansex (bp, °hrs, &mins, &secs); sex_dec (deghrs, mins, secs, &newlt); mjd = mjd_day(mjd-tz/24.0) + (newlt + tz)/24.0; } set_t0 (&now); new = 1; break; case rcfpack (R_LST, C_LSTV, 0): if (!bp) { static char p[] = "local sidereal time (h:m:s, or n for Now): "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } if (bp[0] == 'n' || bp[0] == 'N') time_fromsys (&now); else { double lst, utc; now_lst (&now, &lst); f_dec_sexsign (lst, °hrs, &mins, &secs); f_sscansex (bp, °hrs, &mins, &secs); sex_dec (deghrs, mins, secs, &lst); lst -= radhr(lng); /* convert to gst */ range (&lst, 24.0); gst_utc (mjd_day(mjd), lst, &utc); mjd = mjd_day(mjd) + utc/24.0; } set_t0 (&now); new = 1; break; case rcfpack (R_TZN, C_TZN, 0): if (!bp) { static char p[] = "timezone abbreviation (3 char max): "; f_prompt (p); if (read_line (buf, 3) <= 0) break; bp = buf; } (void) strncpy (tznm, bp, sizeof(tznm)-1); new = 1; break; case rcfpack (R_TZONE, C_TZONEV, 0): if (!bp) { static char p[] = "hours behind utc: "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } f_dec_sexsign (tz, °hrs, &mins, &secs); f_sscansex (bp, °hrs, &mins, &secs); sex_dec (deghrs, mins, secs, &tz); new = 1; break; case rcfpack (R_LONG, C_LONGV, 0): if (!bp) { static char p[] = "longitude (+ west) (d:m:s): "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } f_dec_sexsign (-raddeg(lng), °hrs, &mins, &secs); f_sscansex (bp, °hrs, &mins, &secs); sex_dec (deghrs, mins, secs, &lng); lng = degrad (-lng); /* want - radians west */ new = 1; break; case rcfpack (R_LAT, C_LATV, 0): if (!bp) { static char p[] = "latitude (+ north) (d:m:s): "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } f_dec_sexsign (raddeg(lat), °hrs, &mins, &secs); f_sscansex (bp, °hrs, &mins, &secs); sex_dec (deghrs, mins, secs, &lat); lat = degrad (lat); new = 1; break; case rcfpack (R_HEIGHT, C_HEIGHTV, 0): if (!bp) { static char p[] = "height above sea level (ft): "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } if (sscanf (bp, "%lf", &height) == 1) { height /= 2.093e7; /*convert ft to earth radii above sea level*/ new = 1; } break; case rcfpack (R_NSTEP, C_NSTEPV, 0): if (!bp) { static char p[] = "number of steps to run: "; f_prompt (p); if (read_line (buf, 8) <= 0) break; bp = buf; } (void) sscanf (bp, "%d", &nstep); print_nstep (0); break; case rcfpack (R_PAUSE, C_PAUSEV, 0): if (!bp) { static char p[] = "seconds to pause between steps: "; f_prompt (p); if (read_line (buf, 8) <= 0) break; bp = buf; } (void) sscanf (bp, "%d", &spause); print_spause (0); break; case rcfpack (R_TEMP, C_TEMPV, 0): if (!bp) { static char p[] = "temperature (deg.F): "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } if (sscanf (bp, "%lf", &temp) == 1) { temp = 5./9.*(temp - 32.0); /* want degs C */ new = 1; } break; case rcfpack (R_PRES, C_PRESV, 0): if (!bp) { static char p[] = "atmos pressure (in. Hg; 0 for no refraction correction): "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } if (sscanf (bp, "%lf", &pressure) == 1) { pressure *= 33.86; /* want mBar */ new = 1; } break; case rcfpack (R_EPOCH, C_EPOCHV, 0): if (!bp) { static char p[] = "epoch (year, or e for Equinox of Date): "; f_prompt (p); if (read_line (buf, PW-strlen(p)) <= 0) break; bp = buf; } if (bp[0] == 'e' || bp[0] == 'E') epoch = EOD; else { double e; e = atof(bp); year_mjd (e, &epoch); } new = 1; break; case rcfpack (R_STPSZ, C_STPSZV, 0): if (!bp) { static char p[] = "step size increment (h:m:s, or <x>d for x days, or r for RTC): "; f_prompt (p); if (read_line (buf, PW-sizeof(p)) <= 0) break; bp = buf; } if (bp[0] == 'r' || bp[0] == 'R') tminc = RTC; else { int last = strlen (bp) - 1; if (bp[last] == 'd') { /* ends in d so treat as a number of days */ double x; if (sscanf (bp, "%lf", &x) == 1) tminc = x * 24.0; } else { if (tminc == RTC) deghrs = mins = secs = 0; else f_dec_sexsign (tminc, °hrs, &mins, &secs); f_sscansex (bp, °hrs, &mins, &secs); sex_dec (deghrs, mins, secs, &tminc); } } print_tminc(0); set_t0 (&now); break; case rcfpack (R_PLOT, C_PLOT, 0): plot_setup(); if (plot_ison()) new = 1; break; case rcfpack (R_LISTING, C_LISTING, 0): listing_setup(); if (listing_ison()) new = 1; break; case rcfpack (R_WATCH, C_WATCH, 0): watch (&now, tminc, oppl); /* set new reference time to what watch left it. * no need to set new since watch just did a redraw. */ set_t0 (&now); 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) { print_updating(); mm_twilight (&now, 1); } else { f_blanks (R_DAWN, C_DAWNV, 5); f_blanks (R_DUSK, C_DUSKV, 5); f_blanks (R_LON, C_LONV, 5); } break; case rcfpack (R_SRCH, C_SRCH, 0): srch_setup(); if (srch_ison()) new = 1; break; case rcfpack (R_SUN, C_OBJ, 0): toggle_body (SUN); break; case rcfpack (R_SUN, C_CONSTEL, 0): if (oppl & (1<<SUN)) constellation_msg (SUN, &now); break; case rcfpack (R_MOON, C_OBJ, 0): toggle_body (MOON); break; case rcfpack (R_MOON, C_CONSTEL, 0): if (oppl & (1<<MOON)) constellation_msg (MOON, &now); break; case rcfpack (R_MERCURY, C_OBJ, 0): toggle_body (MERCURY); break; case rcfpack (R_MERCURY, C_CONSTEL, 0): if (oppl & (1<<MERCURY)) constellation_msg (MERCURY, &now); break; case rcfpack (R_VENUS, C_OBJ, 0): toggle_body (VENUS); break; case rcfpack (R_VENUS, C_CONSTEL, 0): if (oppl & (1<<VENUS)) constellation_msg (VENUS, &now); break; case rcfpack (R_MARS, C_OBJ, 0): toggle_body (MARS); break; case rcfpack (R_MARS, C_CONSTEL, 0): if (oppl & (1<<MARS)) constellation_msg (MARS, &now); break; case rcfpack (R_JUPITER, C_OBJ, 0): toggle_body (JUPITER); break; case rcfpack (R_JUPITER, C_CONSTEL, 0): if (oppl & (1<<JUPITER)) constellation_msg (JUPITER, &now); break; case rcfpack (R_JUPITER, C_XTRA, 0): if (oppl & (1<<JUPITER)) { print_updating(); alt_erase(); altmenu_init (F_MNUJ); print_alt (2); *fld = rcfpack(R_NSTEP, C_NSTEPV, 0); } break; case rcfpack (R_SATURN, C_OBJ, 0): toggle_body (SATURN); break; case rcfpack (R_SATURN, C_CONSTEL, 0): if (oppl & (1<<SATURN)) constellation_msg (SATURN, &now); break; case rcfpack (R_URANUS, C_OBJ, 0): toggle_body (URANUS); break; case rcfpack (R_URANUS, C_CONSTEL, 0): if (oppl & (1<<URANUS)) constellation_msg (URANUS, &now); break; case rcfpack (R_NEPTUNE, C_OBJ, 0): toggle_body (NEPTUNE); break; case rcfpack (R_NEPTUNE, C_CONSTEL, 0): if (oppl & (1<<NEPTUNE)) constellation_msg (NEPTUNE, &now); break; case rcfpack (R_PLUTO, C_OBJ, 0): toggle_body (PLUTO); break; case rcfpack (R_PLUTO, C_CONSTEL, 0): if (oppl & (1<<PLUTO)) constellation_msg (PLUTO, &now); break; case rcfpack (R_OBJX, C_OBJ, 0): /* this might change which columns are used so erase all when * returns and redraw if still on. */ obj_setup (OBJX); alt_nobody (OBJX); if (obj_ison (OBJX)) { oppl |= 1 << OBJX; print_updating(); alt_body (OBJX, 1, &now); } else oppl &= ~(1 << OBJX); /* already erased; just clear flag */ break; case rcfpack (R_OBJX, C_CONSTEL, 0): if (oppl & (1<<OBJX)) constellation_msg (OBJX, &now); break; case rcfpack (R_OBJY, C_OBJ, 0): /* this might change which columns are used so erase all when * returns and redraw if still on. */ obj_setup (OBJY); alt_nobody (OBJY); if (obj_ison (OBJY)) { oppl |= 1 << OBJY; print_updating(); alt_body (OBJY, 1, &now); } else oppl &= ~(1 << OBJY); /* already erased; just clear flag */ break; case rcfpack (R_OBJY, C_CONSTEL, 0): if (oppl & (1<<OBJY)) constellation_msg (OBJY, &now); break; } return (new); } static print_tminc(force) int force; { static double last = -123.456; /* anything unlikely */ if (force || tminc != last) { if (tminc == RTC) f_string (R_STPSZ, C_STPSZV, " RT CLOCK"); else if (fabs(tminc) >= 24.0) f_double (R_STPSZ, C_STPSZV, "%6.4g dy", tminc/24.0); else f_signtime (R_STPSZ, C_STPSZV, tminc); last = tminc; } } /* print stuff on bottom menu */ static print_alt (howmuch) int howmuch; { if (howmuch == 2) alt_labels(); if (alt_menumask() == F_MNUJ) altj_display (howmuch, &now); else { int p; for (p = nxtbody(-1); p != -1; p = nxtbody(p)) if (oppl & (1<<p)) alt_body (p, howmuch, &now); } } print_updating() { f_prompt ("Updating..."); } static print_nstep(force) int force; { static int last; if (force || nstep != last) { char buf[16]; (void) sprintf (buf, "%8d", nstep); f_string (R_NSTEP, C_NSTEPV, buf); last = nstep; } } static print_spause(force) int force; { static int last; if (force || spause != last) { char buf[16]; (void) sprintf (buf, "%8d", spause); f_string (R_PAUSE, C_PAUSEV, buf); last = spause; } } /* if not plotting/listing/searching then sleep spause seconds. * if time is being based on the real-time clock, sync on the next * integral multiple of spause seconds after the minute. * check for keyboard action once each second to let it break out early. */ slp_sync() { extern long time(); if (spause > 0 && !plot_ison() && !srch_ison() && !listing_ison()) { int n; if (tminc == RTC) { long t; (void) time (&t); n = spause - (t % spause); } else n = spause; while (--n >= 0) if (chk_char() == 0) break; else (void) sleep (1); } } static toggle_body (p) int p; { if ((oppl ^= (1<<p)) & (1<<p)) { print_updating(); alt_body (p, 1, &now); } else alt_nobody (p); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.