[comp.sources.misc] v09i042: ephem, v4.8, 5 of 5

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (11/28/89)

Posting-number: Volume 9, Issue 42
Submitted-by: ecd@umn-cs.cs.umn.edu@ncs-med.UUCP (Elwood C. Downey)
Archive-name: ephem2/part05

# This is a "shell archive" file; run it with sh.
# This is file 5.
echo x sel_fld.c
cat > sel_fld.c << 'xXx'
#include <stdio.h>
#include "screen.h"

/* table of the fields, with flags indicating which menu(s) they are on and
 * whether pickable for changing or plotting.
 * N.B. type must be long enough to hold 16 bits.
 */
static int fields[] = {
    rcfpack (R_ALTM,	C_ALTM,		F_MMNU|F_CHG),
    rcfpack (R_DAWN,	C_DAWN,		F_MMNU|F_CHG),
    rcfpack (R_DAWN,	C_DAWNV,	F_MMNU|F_PLT),
    rcfpack (R_DUSK,	C_DUSK,		F_MMNU|F_CHG),
    rcfpack (R_DUSK,	C_DUSKV,	F_MMNU|F_PLT),
    rcfpack (R_EPOCH,	C_EPOCHV,	F_MMNU|F_CHG),
    rcfpack (R_HEIGHT,	C_HEIGHTV,	F_MMNU|F_CHG|F_PLT),
    rcfpack (R_JD,	C_JDV,		F_MMNU|F_CHG|F_PLT),
    rcfpack (R_JUPITER,	C_ALT,		F_MNU1|F_PLT),
    rcfpack (R_JUPITER,	C_AZ,		F_MNU1|F_PLT),
    rcfpack (R_JUPITER,	C_DEC,		F_MNU1|F_PLT),
    rcfpack (R_JUPITER,	C_EDIST,	F_MNU1|F_PLT),
    rcfpack (R_JUPITER,	C_ELONG,	F_MNU1|F_PLT),
    rcfpack (R_JUPITER,	C_HLAT,		F_MNU1|F_PLT),
    rcfpack (R_JUPITER,	C_HLONG,	F_MNU1|F_PLT),
    rcfpack (R_JUPITER,	C_MAG,		F_MNU1|F_PLT),
    rcfpack (R_JUPITER,	C_MARS,		F_MNU3|F_PLT),
    rcfpack (R_JUPITER,	C_MERCURY,	F_MNU3|F_PLT),
    rcfpack (R_JUPITER,	C_MOON,		F_MNU3|F_PLT),
    rcfpack (R_JUPITER,	C_NEPTUNE,	F_MNU3|F_PLT),
    rcfpack (R_JUPITER,	C_OBJ,		F_MMNU|F_CHG),
    rcfpack (R_JUPITER,	C_OBJX,		F_MNU3|F_PLT),
    rcfpack (R_JUPITER,	C_PHASE,	F_MNU1|F_PLT),
    rcfpack (R_JUPITER,	C_PLUTO,	F_MNU3|F_PLT),
    rcfpack (R_JUPITER,	C_RA,		F_MNU1|F_PLT),
    rcfpack (R_JUPITER,	C_RISEAZ,	F_MNU2|F_PLT),
    rcfpack (R_JUPITER,	C_RISETM,	F_MNU2|F_PLT),
    rcfpack (R_JUPITER,	C_SATURN,	F_MNU3|F_PLT),
    rcfpack (R_JUPITER,	C_SDIST,	F_MNU1|F_PLT),
    rcfpack (R_JUPITER,	C_SETAZ,	F_MNU2|F_PLT),
    rcfpack (R_JUPITER,	C_SETTM,	F_MNU2|F_PLT),
    rcfpack (R_JUPITER,	C_SIZE,		F_MNU1|F_PLT),
    rcfpack (R_JUPITER,	C_SUN,		F_MNU3|F_PLT),
    rcfpack (R_JUPITER,	C_TRANSALT,	F_MNU2|F_PLT),
    rcfpack (R_JUPITER,	C_TRANSTM,	F_MNU2|F_PLT),
    rcfpack (R_JUPITER,	C_TUP,		F_MNU2|F_PLT),
    rcfpack (R_JUPITER,	C_URANUS,	F_MNU3|F_PLT),
    rcfpack (R_JUPITER,	C_VENUS,	F_MNU3|F_PLT),
    rcfpack (R_LAT,	C_LATV,		F_MMNU|F_CHG|F_PLT),
    rcfpack (R_LD,	C_LD,		F_MMNU|F_PLT|F_CHG),
    rcfpack (R_LON,	C_LON,		F_MMNU|F_CHG),
    rcfpack (R_LON,	C_LONV,		F_MMNU|F_PLT),
    rcfpack (R_LONG,	C_LONGV,	F_MMNU|F_CHG|F_PLT),
    rcfpack (R_LST,	C_LSTV,		F_MMNU|F_CHG|F_PLT),
    rcfpack (R_LT,	C_LT,		F_MMNU|F_CHG|F_PLT),
    rcfpack (R_MARS,	C_ALT,		F_MNU1|F_PLT),
    rcfpack (R_MARS,	C_AZ,		F_MNU1|F_PLT),
    rcfpack (R_MARS,	C_DEC,		F_MNU1|F_PLT),
    rcfpack (R_MARS,	C_EDIST,	F_MNU1|F_PLT),
    rcfpack (R_MARS,	C_ELONG,	F_MNU1|F_PLT),
    rcfpack (R_MARS,	C_HLAT,		F_MNU1|F_PLT),
    rcfpack (R_MARS,	C_HLONG,	F_MNU1|F_PLT),
    rcfpack (R_MARS,	C_JUPITER,	F_MNU3|F_PLT),
    rcfpack (R_MARS,	C_MAG,		F_MNU1|F_PLT),
    rcfpack (R_MARS,	C_MERCURY,	F_MNU3|F_PLT),
    rcfpack (R_MARS,	C_MOON,		F_MNU3|F_PLT),
    rcfpack (R_MARS,	C_NEPTUNE,	F_MNU3|F_PLT),
    rcfpack (R_MARS,	C_OBJ,		F_MMNU|F_CHG),
    rcfpack (R_MARS,	C_OBJX,		F_MNU3|F_PLT),
    rcfpack (R_MARS,	C_PHASE,	F_MNU1|F_PLT),
    rcfpack (R_MARS,	C_PLUTO,	F_MNU3|F_PLT),
    rcfpack (R_MARS,	C_RA,		F_MNU1|F_PLT),
    rcfpack (R_MARS,	C_RISEAZ,	F_MNU2|F_PLT),
    rcfpack (R_MARS,	C_RISETM,	F_MNU2|F_PLT),
    rcfpack (R_MARS,	C_SATURN,	F_MNU3|F_PLT),
    rcfpack (R_MARS,	C_SDIST,	F_MNU1|F_PLT),
    rcfpack (R_MARS,	C_SETAZ,	F_MNU2|F_PLT),
    rcfpack (R_MARS,	C_SETTM,	F_MNU2|F_PLT),
    rcfpack (R_MARS,	C_SIZE,		F_MNU1|F_PLT),
    rcfpack (R_MARS,	C_SUN,		F_MNU3|F_PLT),
    rcfpack (R_MARS,	C_TRANSALT,	F_MNU2|F_PLT),
    rcfpack (R_MARS,	C_TRANSTM,	F_MNU2|F_PLT),
    rcfpack (R_MARS,	C_TUP,		F_MNU2|F_PLT),
    rcfpack (R_MARS,	C_URANUS,	F_MNU3|F_PLT),
    rcfpack (R_MARS,	C_VENUS,	F_MNU3|F_PLT),
    rcfpack (R_MERCURY,	C_ALT,		F_MNU1|F_PLT),
    rcfpack (R_MERCURY,	C_AZ,		F_MNU1|F_PLT),
    rcfpack (R_MERCURY,	C_DEC,		F_MNU1|F_PLT),
    rcfpack (R_MERCURY,	C_EDIST,	F_MNU1|F_PLT),
    rcfpack (R_MERCURY,	C_ELONG,	F_MNU1|F_PLT),
    rcfpack (R_MERCURY,	C_HLAT,		F_MNU1|F_PLT),
    rcfpack (R_MERCURY,	C_HLONG,	F_MNU1|F_PLT),
    rcfpack (R_MERCURY,	C_JUPITER,	F_MNU3|F_PLT),
    rcfpack (R_MERCURY,	C_MAG,		F_MNU1|F_PLT),
    rcfpack (R_MERCURY,	C_MARS,		F_MNU3|F_PLT),
    rcfpack (R_MERCURY,	C_MOON,		F_MNU3|F_PLT),
    rcfpack (R_MERCURY,	C_NEPTUNE,	F_MNU3|F_PLT),
    rcfpack (R_MERCURY,	C_OBJ,		F_MMNU|F_CHG),
    rcfpack (R_MERCURY,	C_OBJX,		F_MNU3|F_PLT),
    rcfpack (R_MERCURY,	C_PHASE,	F_MNU1|F_PLT),
    rcfpack (R_MERCURY,	C_PLUTO,	F_MNU3|F_PLT),
    rcfpack (R_MERCURY,	C_RA,		F_MNU1|F_PLT),
    rcfpack (R_MERCURY,	C_RISEAZ,	F_MNU2|F_PLT),
    rcfpack (R_MERCURY,	C_RISETM,	F_MNU2|F_PLT),
    rcfpack (R_MERCURY,	C_SATURN,	F_MNU3|F_PLT),
    rcfpack (R_MERCURY,	C_SDIST,	F_MNU1|F_PLT),
    rcfpack (R_MERCURY,	C_SETAZ,	F_MNU2|F_PLT),
    rcfpack (R_MERCURY,	C_SETTM,	F_MNU2|F_PLT),
    rcfpack (R_MERCURY,	C_SIZE,		F_MNU1|F_PLT),
    rcfpack (R_MERCURY,	C_SUN,		F_MNU3|F_PLT),
    rcfpack (R_MERCURY,	C_TRANSALT,	F_MNU2|F_PLT),
    rcfpack (R_MERCURY,	C_TRANSTM,	F_MNU2|F_PLT),
    rcfpack (R_MERCURY,	C_TUP,		F_MNU2|F_PLT),
    rcfpack (R_MERCURY,	C_URANUS,	F_MNU3|F_PLT),
    rcfpack (R_MERCURY,	C_VENUS,	F_MNU3|F_PLT),
    rcfpack (R_MOON,	C_ALT,		F_MNU1|F_PLT),
    rcfpack (R_MOON,	C_AZ,		F_MNU1|F_PLT),
    rcfpack (R_MOON,	C_DEC,		F_MNU1|F_PLT),
    rcfpack (R_MOON,	C_EDIST,	F_MNU1|F_PLT),
    rcfpack (R_MOON,	C_ELONG,	F_MNU1|F_PLT),
    rcfpack (R_MOON,	C_JUPITER,	F_MNU3|F_PLT),
    rcfpack (R_MOON,	C_MAG,		F_MNU1|F_PLT),
    rcfpack (R_MOON,	C_MARS,		F_MNU3|F_PLT),
    rcfpack (R_MOON,	C_MERCURY,	F_MNU3|F_PLT),
    rcfpack (R_MOON,	C_NEPTUNE,	F_MNU3|F_PLT),
    rcfpack (R_MOON,	C_OBJ,		F_MMNU|F_CHG),
    rcfpack (R_MOON,	C_OBJX,		F_MNU3|F_PLT),
    rcfpack (R_MOON,	C_PHASE,	F_MNU1|F_PLT),
    rcfpack (R_MOON,	C_PLUTO,	F_MNU3|F_PLT),
    rcfpack (R_MOON,	C_RA,		F_MNU1|F_PLT),
    rcfpack (R_MOON,	C_RISEAZ,	F_MNU2|F_PLT),
    rcfpack (R_MOON,	C_RISETM,	F_MNU2|F_PLT),
    rcfpack (R_MOON,	C_SATURN,	F_MNU3|F_PLT),
    rcfpack (R_MOON,	C_SDIST,	F_MNU1|F_PLT),
    rcfpack (R_MOON,	C_SETAZ,	F_MNU2|F_PLT),
    rcfpack (R_MOON,	C_SETTM,	F_MNU2|F_PLT),
    rcfpack (R_MOON,	C_SIZE,		F_MNU1|F_PLT),
    rcfpack (R_MOON,	C_SUN,		F_MNU3|F_PLT),
    rcfpack (R_MOON,	C_TRANSALT,	F_MNU2|F_PLT),
    rcfpack (R_MOON,	C_TRANSTM,	F_MNU2|F_PLT),
    rcfpack (R_MOON,	C_TUP,		F_MNU2|F_PLT),
    rcfpack (R_MOON,	C_URANUS,	F_MNU3|F_PLT),
    rcfpack (R_MOON,	C_VENUS,	F_MNU3|F_PLT),
    rcfpack (R_NEPTUNE,	C_ALT,		F_MNU1|F_PLT),
    rcfpack (R_NEPTUNE,	C_AZ,		F_MNU1|F_PLT),
    rcfpack (R_NEPTUNE,	C_DEC,		F_MNU1|F_PLT),
    rcfpack (R_NEPTUNE,	C_EDIST,	F_MNU1|F_PLT),
    rcfpack (R_NEPTUNE,	C_ELONG,	F_MNU1|F_PLT),
    rcfpack (R_NEPTUNE,	C_HLAT,		F_MNU1|F_PLT),
    rcfpack (R_NEPTUNE,	C_HLONG,	F_MNU1|F_PLT),
    rcfpack (R_NEPTUNE,	C_JUPITER,	F_MNU3|F_PLT),
    rcfpack (R_NEPTUNE,	C_MAG,		F_MNU1|F_PLT),
    rcfpack (R_NEPTUNE,	C_MARS,		F_MNU3|F_PLT),
    rcfpack (R_NEPTUNE,	C_MERCURY,	F_MNU3|F_PLT),
    rcfpack (R_NEPTUNE,	C_MOON,		F_MNU3|F_PLT),
    rcfpack (R_NEPTUNE,	C_OBJ,		F_MMNU|F_CHG),
    rcfpack (R_NEPTUNE,	C_OBJX,		F_MNU3|F_PLT),
    rcfpack (R_NEPTUNE,	C_PHASE,	F_MNU1|F_PLT),
    rcfpack (R_NEPTUNE,	C_PLUTO,	F_MNU3|F_PLT),
    rcfpack (R_NEPTUNE,	C_RA,		F_MNU1|F_PLT),
    rcfpack (R_NEPTUNE,	C_RISEAZ,	F_MNU2|F_PLT),
    rcfpack (R_NEPTUNE,	C_RISETM,	F_MNU2|F_PLT),
    rcfpack (R_NEPTUNE,	C_SATURN,	F_MNU3|F_PLT),
    rcfpack (R_NEPTUNE,	C_SDIST,	F_MNU1|F_PLT),
    rcfpack (R_NEPTUNE,	C_SETAZ,	F_MNU2|F_PLT),
    rcfpack (R_NEPTUNE,	C_SETTM,	F_MNU2|F_PLT),
    rcfpack (R_NEPTUNE,	C_SIZE,		F_MNU1|F_PLT),
    rcfpack (R_NEPTUNE,	C_SUN,		F_MNU3|F_PLT),
    rcfpack (R_NEPTUNE,	C_TRANSALT,	F_MNU2|F_PLT),
    rcfpack (R_NEPTUNE,	C_TRANSTM,	F_MNU2|F_PLT),
    rcfpack (R_NEPTUNE,	C_TUP,		F_MNU2|F_PLT),
    rcfpack (R_NEPTUNE,	C_URANUS,	F_MNU3|F_PLT),
    rcfpack (R_NEPTUNE,	C_VENUS,	F_MNU3|F_PLT),
    rcfpack (R_NSTEP,	C_NSTEPV,	F_MMNU|F_CHG),
    rcfpack (R_OBJX,	C_ALT,		F_MNU1|F_PLT),
    rcfpack (R_OBJX,	C_AZ,		F_MNU1|F_PLT),
    rcfpack (R_OBJX,	C_DEC,		F_MNU1|F_CHG|F_PLT),
    rcfpack (R_OBJX,	C_ELONG,	F_MNU1|F_PLT),
    rcfpack (R_OBJX,	C_JUPITER,	F_MNU3|F_PLT),
    rcfpack (R_OBJX,	C_MARS,		F_MNU3|F_PLT),
    rcfpack (R_OBJX,	C_MERCURY,	F_MNU3|F_PLT),
    rcfpack (R_OBJX,	C_MOON,		F_MNU3|F_PLT),
    rcfpack (R_OBJX,	C_NEPTUNE,	F_MNU3|F_PLT),
    rcfpack (R_OBJX,	C_OBJ,		F_MMNU|F_CHG),
    rcfpack (R_OBJX,	C_PLUTO,	F_MNU3|F_PLT),
    rcfpack (R_OBJX,	C_RA,		F_MNU1|F_CHG|F_PLT),
    rcfpack (R_OBJX,	C_RISEAZ,	F_MNU2|F_PLT),
    rcfpack (R_OBJX,	C_RISETM,	F_MNU2|F_PLT),
    rcfpack (R_OBJX,	C_SATURN,	F_MNU3|F_PLT),
    rcfpack (R_OBJX,	C_SETAZ,	F_MNU2|F_PLT),
    rcfpack (R_OBJX,	C_SETTM,	F_MNU2|F_PLT),
    rcfpack (R_OBJX,	C_SUN,		F_MNU3|F_PLT),
    rcfpack (R_OBJX,	C_TRANSALT,	F_MNU2|F_PLT),
    rcfpack (R_OBJX,	C_TRANSTM,	F_MNU2|F_PLT),
    rcfpack (R_OBJX,	C_TUP,		F_MNU2|F_PLT),
    rcfpack (R_OBJX,	C_URANUS,	F_MNU3|F_PLT),
    rcfpack (R_OBJX,	C_VENUS,	F_MNU3|F_PLT),
    rcfpack (R_PLOT,	C_PLOT,		F_MMNU|F_CHG),
    rcfpack (R_PLUTO,	C_ALT,		F_MNU1|F_PLT),
    rcfpack (R_PLUTO,	C_AZ,		F_MNU1|F_PLT),
    rcfpack (R_PLUTO,	C_DEC,		F_MNU1|F_PLT),
    rcfpack (R_PLUTO,	C_EDIST,	F_MNU1|F_PLT),
    rcfpack (R_PLUTO,	C_ELONG,	F_MNU1|F_PLT),
    rcfpack (R_PLUTO,	C_HLAT,		F_MNU1|F_PLT),
    rcfpack (R_PLUTO,	C_HLONG,	F_MNU1|F_PLT),
    rcfpack (R_PLUTO,	C_JUPITER,	F_MNU3|F_PLT),
    rcfpack (R_PLUTO,	C_MAG,		F_MNU1|F_PLT),
    rcfpack (R_PLUTO,	C_MARS,		F_MNU3|F_PLT),
    rcfpack (R_PLUTO,	C_MERCURY,	F_MNU3|F_PLT),
    rcfpack (R_PLUTO,	C_MOON,		F_MNU3|F_PLT),
    rcfpack (R_PLUTO,	C_NEPTUNE,	F_MNU3|F_PLT),
    rcfpack (R_PLUTO,	C_OBJ,		F_MMNU|F_CHG),
    rcfpack (R_PLUTO,	C_OBJX,		F_MNU3|F_PLT),
    rcfpack (R_PLUTO,	C_PHASE,	F_MNU1|F_PLT),
    rcfpack (R_PLUTO,	C_RA,		F_MNU1|F_PLT),
    rcfpack (R_PLUTO,	C_RISEAZ,	F_MNU2|F_PLT),
    rcfpack (R_PLUTO,	C_RISETM,	F_MNU2|F_PLT),
    rcfpack (R_PLUTO,	C_SATURN,	F_MNU3|F_PLT),
    rcfpack (R_PLUTO,	C_SDIST,	F_MNU1|F_PLT),
    rcfpack (R_PLUTO,	C_SETAZ,	F_MNU2|F_PLT),
    rcfpack (R_PLUTO,	C_SETTM,	F_MNU2|F_PLT),
    rcfpack (R_PLUTO,	C_SIZE,		F_MNU1|F_PLT),
    rcfpack (R_PLUTO,	C_SUN,		F_MNU3|F_PLT),
    rcfpack (R_PLUTO,	C_TRANSALT,	F_MNU2|F_PLT),
    rcfpack (R_PLUTO,	C_TRANSTM,	F_MNU2|F_PLT),
    rcfpack (R_PLUTO,	C_TUP,		F_MNU2|F_PLT),
    rcfpack (R_PLUTO,	C_URANUS,	F_MNU3|F_PLT),
    rcfpack (R_PLUTO,	C_VENUS,	F_MNU3|F_PLT),
    rcfpack (R_PRES,	C_PRESV,	F_MMNU|F_CHG|F_PLT),
    rcfpack (R_SATURN,	C_ALT,		F_MNU1|F_PLT),
    rcfpack (R_SATURN,	C_AZ,		F_MNU1|F_PLT),
    rcfpack (R_SATURN,	C_DEC,		F_MNU1|F_PLT),
    rcfpack (R_SATURN,	C_EDIST,	F_MNU1|F_PLT),
    rcfpack (R_SATURN,	C_ELONG,	F_MNU1|F_PLT),
    rcfpack (R_SATURN,	C_HLAT,		F_MNU1|F_PLT),
    rcfpack (R_SATURN,	C_HLONG,	F_MNU1|F_PLT),
    rcfpack (R_SATURN,	C_JUPITER,	F_MNU3|F_PLT),
    rcfpack (R_SATURN,	C_MAG,		F_MNU1|F_PLT),
    rcfpack (R_SATURN,	C_MARS,		F_MNU3|F_PLT),
    rcfpack (R_SATURN,	C_MERCURY,	F_MNU3|F_PLT),
    rcfpack (R_SATURN,	C_MOON,		F_MNU3|F_PLT),
    rcfpack (R_SATURN,	C_NEPTUNE,	F_MNU3|F_PLT),
    rcfpack (R_SATURN,	C_OBJ,		F_MMNU|F_CHG),
    rcfpack (R_SATURN,	C_OBJX,		F_MNU3|F_PLT),
    rcfpack (R_SATURN,	C_PHASE,	F_MNU1|F_PLT),
    rcfpack (R_SATURN,	C_PLUTO,	F_MNU3|F_PLT),
    rcfpack (R_SATURN,	C_RA,		F_MNU1|F_PLT),
    rcfpack (R_SATURN,	C_RISEAZ,	F_MNU2|F_PLT),
    rcfpack (R_SATURN,	C_RISETM,	F_MNU2|F_PLT),
    rcfpack (R_SATURN,	C_SDIST,	F_MNU1|F_PLT),
    rcfpack (R_SATURN,	C_SETAZ,	F_MNU2|F_PLT),
    rcfpack (R_SATURN,	C_SETTM,	F_MNU2|F_PLT),
    rcfpack (R_SATURN,	C_SIZE,		F_MNU1|F_PLT),
    rcfpack (R_SATURN,	C_SUN,		F_MNU3|F_PLT),
    rcfpack (R_SATURN,	C_TRANSALT,	F_MNU2|F_PLT),
    rcfpack (R_SATURN,	C_TRANSTM,	F_MNU2|F_PLT),
    rcfpack (R_SATURN,	C_TUP,		F_MNU2|F_PLT),
    rcfpack (R_SATURN,	C_URANUS,	F_MNU3|F_PLT),
    rcfpack (R_SATURN,	C_VENUS,	F_MNU3|F_PLT),
    rcfpack (R_SRCH,	C_SRCH,		F_MMNU|F_CHG|F_PLT),
    rcfpack (R_STPSZ,	C_STPSZV,	F_MMNU|F_CHG),
    rcfpack (R_SUN,	C_ALT,		F_MNU1|F_PLT),
    rcfpack (R_SUN,	C_AZ,		F_MNU1|F_PLT),
    rcfpack (R_SUN,	C_DEC,		F_MNU1|F_PLT),
    rcfpack (R_SUN,	C_EDIST,	F_MNU1|F_PLT),
    rcfpack (R_SUN,	C_HLAT,		F_MNU1|F_PLT),
    rcfpack (R_SUN,	C_HLONG,	F_MNU1|F_PLT),
    rcfpack (R_SUN,	C_JUPITER,	F_MNU3|F_PLT),
    rcfpack (R_SUN,	C_MAG,		F_MNU1|F_PLT),
    rcfpack (R_SUN,	C_MARS,		F_MNU3|F_PLT),
    rcfpack (R_SUN,	C_MERCURY,	F_MNU3|F_PLT),
    rcfpack (R_SUN,	C_MOON,		F_MNU3|F_PLT),
    rcfpack (R_SUN,	C_NEPTUNE,	F_MNU3|F_PLT),
    rcfpack (R_SUN,	C_OBJ,		F_MMNU|F_CHG),
    rcfpack (R_SUN,	C_OBJX,		F_MNU3|F_PLT),
    rcfpack (R_SUN,	C_PLUTO,	F_MNU3|F_PLT),
    rcfpack (R_SUN,	C_RA,		F_MNU1|F_PLT),
    rcfpack (R_SUN,	C_RISEAZ,	F_MNU2|F_PLT),
    rcfpack (R_SUN,	C_RISETM,	F_MNU2|F_PLT),
    rcfpack (R_SUN,	C_SATURN,	F_MNU3|F_PLT),
    rcfpack (R_SUN,	C_SETAZ,	F_MNU2|F_PLT),
    rcfpack (R_SUN,	C_SETTM,	F_MNU2|F_PLT),
    rcfpack (R_SUN,	C_SIZE,		F_MNU1|F_PLT),
    rcfpack (R_SUN,	C_TRANSALT,	F_MNU2|F_PLT),
    rcfpack (R_SUN,	C_TRANSTM,	F_MNU2|F_PLT),
    rcfpack (R_SUN,	C_TUP,		F_MNU2|F_PLT),
    rcfpack (R_SUN,	C_URANUS,	F_MNU3|F_PLT),
    rcfpack (R_SUN,	C_VENUS,	F_MNU3|F_PLT),
    rcfpack (R_TEMP,	C_TEMPV,	F_MMNU|F_CHG|F_PLT),
    rcfpack (R_TZN,	C_TZN,		F_MMNU|F_CHG),
    rcfpack (R_TZONE,	C_TZONEV,	F_MMNU|F_CHG),
    rcfpack (R_UD,	C_UD,		F_MMNU|F_PLT|F_CHG),
    rcfpack (R_URANUS,	C_ALT,		F_MNU1|F_PLT),
    rcfpack (R_URANUS,	C_AZ,		F_MNU1|F_PLT),
    rcfpack (R_URANUS,	C_DEC,		F_MNU1|F_PLT),
    rcfpack (R_URANUS,	C_EDIST,	F_MNU1|F_PLT),
    rcfpack (R_URANUS,	C_ELONG,	F_MNU1|F_PLT),
    rcfpack (R_URANUS,	C_HLAT,		F_MNU1|F_PLT),
    rcfpack (R_URANUS,	C_HLONG,	F_MNU1|F_PLT),
    rcfpack (R_URANUS,	C_JUPITER,	F_MNU3|F_PLT),
    rcfpack (R_URANUS,	C_MAG,		F_MNU1|F_PLT),
    rcfpack (R_URANUS,	C_MARS,		F_MNU3|F_PLT),
    rcfpack (R_URANUS,	C_MERCURY,	F_MNU3|F_PLT),
    rcfpack (R_URANUS,	C_MOON,		F_MNU3|F_PLT),
    rcfpack (R_URANUS,	C_NEPTUNE,	F_MNU3|F_PLT),
    rcfpack (R_URANUS,	C_OBJ,		F_MMNU|F_CHG),
    rcfpack (R_URANUS,	C_OBJX,		F_MNU3|F_PLT),
    rcfpack (R_URANUS,	C_PHASE,	F_MNU1|F_PLT),
    rcfpack (R_URANUS,	C_PLUTO,	F_MNU3|F_PLT),
    rcfpack (R_URANUS,	C_RA,		F_MNU1|F_PLT),
    rcfpack (R_URANUS,	C_RISEAZ,	F_MNU2|F_PLT),
    rcfpack (R_URANUS,	C_RISETM,	F_MNU2|F_PLT),
    rcfpack (R_URANUS,	C_SATURN,	F_MNU3|F_PLT),
    rcfpack (R_URANUS,	C_SDIST,	F_MNU1|F_PLT),
    rcfpack (R_URANUS,	C_SETAZ,	F_MNU2|F_PLT),
    rcfpack (R_URANUS,	C_SETTM,	F_MNU2|F_PLT),
    rcfpack (R_URANUS,	C_SIZE,		F_MNU1|F_PLT),
    rcfpack (R_URANUS,	C_SUN,		F_MNU3|F_PLT),
    rcfpack (R_URANUS,	C_TRANSALT,	F_MNU2|F_PLT),
    rcfpack (R_URANUS,	C_TRANSTM,	F_MNU2|F_PLT),
    rcfpack (R_URANUS,	C_TUP,		F_MNU2|F_PLT),
    rcfpack (R_URANUS,	C_VENUS,	F_MNU3|F_PLT),
    rcfpack (R_UT,	C_UTV,		F_MMNU|F_PLT|F_CHG),
    rcfpack (R_VENUS,	C_ALT,		F_MNU1|F_PLT),
    rcfpack (R_VENUS,	C_AZ,		F_MNU1|F_PLT),
    rcfpack (R_VENUS,	C_DEC,		F_MNU1|F_PLT),
    rcfpack (R_VENUS,	C_EDIST,	F_MNU1|F_PLT),
    rcfpack (R_VENUS,	C_ELONG,	F_MNU1|F_PLT),
    rcfpack (R_VENUS,	C_HLAT,		F_MNU1|F_PLT),
    rcfpack (R_VENUS,	C_HLONG,	F_MNU1|F_PLT),
    rcfpack (R_VENUS,	C_JUPITER,	F_MNU3|F_PLT),
    rcfpack (R_VENUS,	C_MAG,		F_MNU1|F_PLT),
    rcfpack (R_VENUS,	C_MARS,		F_MNU3|F_PLT),
    rcfpack (R_VENUS,	C_MERCURY,	F_MNU3|F_PLT),
    rcfpack (R_VENUS,	C_MOON,		F_MNU3|F_PLT),
    rcfpack (R_VENUS,	C_NEPTUNE,	F_MNU3|F_PLT),
    rcfpack (R_VENUS,	C_OBJ,		F_MMNU|F_CHG),
    rcfpack (R_VENUS,	C_OBJX,		F_MNU3|F_PLT),
    rcfpack (R_VENUS,	C_PHASE,	F_MNU1|F_PLT),
    rcfpack (R_VENUS,	C_PLUTO,	F_MNU3|F_PLT),
    rcfpack (R_VENUS,	C_RA,		F_MNU1|F_PLT),
    rcfpack (R_VENUS,	C_RISEAZ,	F_MNU2|F_PLT),
    rcfpack (R_VENUS,	C_RISETM,	F_MNU2|F_PLT),
    rcfpack (R_VENUS,	C_SATURN,	F_MNU3|F_PLT),
    rcfpack (R_VENUS,	C_SDIST,	F_MNU1|F_PLT),
    rcfpack (R_VENUS,	C_SETAZ,	F_MNU2|F_PLT),
    rcfpack (R_VENUS,	C_SETTM,	F_MNU2|F_PLT),
    rcfpack (R_VENUS,	C_SIZE,		F_MNU1|F_PLT),
    rcfpack (R_VENUS,	C_SUN,		F_MNU3|F_PLT),
    rcfpack (R_VENUS,	C_TRANSALT,	F_MNU2|F_PLT),
    rcfpack (R_VENUS,	C_TRANSTM,	F_MNU2|F_PLT),
    rcfpack (R_VENUS,	C_TUP,		F_MNU2|F_PLT),
    rcfpack (R_VENUS,	C_URANUS,	F_MNU3|F_PLT),
    rcfpack (R_WATCH,	C_WATCH,	F_MMNU|F_CHG),
};
#define	NFIELDS (sizeof(fields)/sizeof(fields[0]))

/* let op select a field by moving around and hitting RETURN, or until see END.
 * also allow moving directly to a planet row using its name.
 * only allow fields with the given flag mask.
 * return the rcfpack()'d field, or 0 if typed END.
 * N.B. we might also exit() entirely by calling bye() if op types QUIT.
 */
sel_fld (r, c, flag, prmpt, help)
int r, c;	/* inial row, col */
int flag;
char *prmpt, *help;
{
	extern void bye();
	char *lastp;
	int ch;

	lastp = 0;
	while (1) {
	    if (lastp != prmpt) {
		lastp = prmpt;
		f_prompt (lastp);
	    }
	    c_pos (r, c);
	    switch (ch = read_char()) {
	    case REDRAW:
		redraw_screen(2);	/* redraw all from scratch */
		lastp = 0;
		break;
	    case VERSION:
		version();
		lastp = 0;
		break;
	    case HELP:
		f_prompt (help);
		(void) read_char();
		lastp = 0;
		break;
	    case QUIT:
		bye();	/* probably never returns */
		break;
	    case END:
		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, or directly to a
 * planet row, and set *rp and *cp.
 * 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;

    wrapped:
	newf = 0;
	newd = 1000;

	switch (dirchar) {
	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 = NC;
		goto wrapped;
	    }
	    break;

	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) {
		/* now find the field closest to current col on that row */
		newf = nearestfld (unpackr(newf), curc, flag);
	    } else {
		curr = 0;
		goto wrapped;
	    }
	    break;

	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) {
		/* now find the field closest to current col on that row */
		newf = nearestfld (unpackr(newf), curc, flag);
	    } else {
		curr = NR+1;
		goto wrapped;
	    }
	    break;

	case 'l': /* 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 = 0;
		goto wrapped;
	    }
	    break;

	/* shorthands directly to a given planet row */
	case 'S': newf = nearestfld (R_SUN, 1, flag); break;
	case 'M': newf = nearestfld (R_MOON, 1, flag); break;
	case 'e': newf = nearestfld (R_MERCURY, 1, flag); break;
	case 'v': newf = nearestfld (R_VENUS, 1, flag); break;
	case 'm': newf = nearestfld (R_MARS, 1, flag); break;
	case cntrl('j'): newf = nearestfld (R_JUPITER, 1, flag); break;
	case 's': newf = nearestfld (R_SATURN, 1, flag); break;
	case 'u': newf = nearestfld (R_URANUS, 1, flag); break;
	case 'n': newf = nearestfld (R_NEPTUNE, 1, flag); break;
	case 'p': newf = nearestfld (R_PLUTO, 1, flag); break;
	}

	*rp = unpackr(newf);
	*cp = unpackc(newf);
}

/* return the nearest field with given flag mask, either way, on this row,
 * else -1 if none.
 */
static int
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 x sex_dec.c
cat > sex_dec.c << 'xXx'
/* given hours (or degrees), hd, minutes, m, and seconds, s, 
 * return decimal hours (or degrees), *d.
 * in the case of hours (angles) < 0, only the first non-zero element should
 *   be negative.
 */
sex_dec (hd, m, s, d)
int hd, m, s;
double *d;
{
	int sign = 1;

	if (hd < 0) {
	    sign = -1;
	    hd = -hd;
	} else if (m < 0) {
	    sign = -1;
	    m = -m;
	} else if (s < 0) {
	    sign = -1;
	    s = -s;
	}

	*d = ((s/60.0 + m)/60.0 + hd) * sign;
}

/* given decimal hours (or degrees), d.
 * return nearest hours (or degrees), *hd, minutes, *m, and seconds, *s, 
 * each always non-negative; *isneg is set to 1 if d is < 0, else to 0.
 */
dec_sex (d, hd, m, s, isneg)
double d;
int *hd, *m, *s, *isneg;
{
	double min;

	if (d < 0) {
	    *isneg = 1;
	    d = -d;
	} else
	    *isneg = 0;

	*hd = (int)d;
	min = (d - *hd)*60.;
	*m = (int)min;
	*s = (int)((min - *m)*60. + 0.5);

	if (*s == 60) {
	    if ((*m += 1) == 60) {
		*hd += 1;
		*m = 0;
	    }
	    *s = 0;
	}
	/* no  negative 0's */
	if (*hd == 0 && *m == 0 && *s == 0)
	    *isneg = 0;
}

/* insure 0 <= *v < r.
 */
range (v, r)
double *v, r;
{
	while (*v <  0) *v += r;
	while (*v >= r) *v -= r;
}
xXx
echo x srch.c
cat > srch.c << 'xXx'
/* this file contains functions to support iterative ephem searches.
 * we support several kinds of searching and solving algorithms.
 * values used in the evaluations come from the field logging flog.c system.
 * the expressions being evaluated are compiled and executed from compiler.c.
 */

#include <stdio.h>
#include <math.h>
#include "screen.h"

static int (*srch_f)();
static int srch_tmscalled;
static char expbuf[NC];		/* [0] == '\0' when expression is invalid */
static double tmlimit = 1./60.;	/* search accuracy, in hrs; def is one minute */


srch_setup()
{
	int srch_minmax(), srch_solve0(), srch_binary();
	static char *chcs[] = {
	    "Find extreme", "Find 0", "Binary", "New function", "Accuracy",
	    "Stop"
	};
	int fn;

	/* let op select algorithm, edit, set accuracy
	 * or stop if currently searching
	 * algorithms require a function.
	 */
	fn = 0;
    ask:
	switch (popup(chcs, fn, srch_f ? 6 : 5)) {
	case 0: if (expbuf[0] == '\0')
		    set_function();
		srch_f = expbuf[0] ? srch_minmax : 0;
		break;
	case 1: if (expbuf[0] == '\0')
		    set_function();
		srch_f = expbuf[0] ? srch_solve0 : 0;
		break;
	case 2: if (expbuf[0] == '\0')
		    set_function();
		srch_f = expbuf[0] ? srch_binary : 0;
		break;
	case 3: srch_f = 0; set_function(); fn = 3; goto ask;
	case 4: srch_f = 0; set_accuracy(); fn = 4; goto ask;
	case 5: srch_f = 0; srch_prstate(0); return;
	default: return;
	}

	/* new search */
	srch_tmscalled = 0;
	srch_prstate (0);
}

/* if searching is in effect call the search type function.
 * it might modify *tmincp according to where it next wants to eval.
 * (remember tminc is in hours, not days).
 * if searching ends for any reason it is also turned off.
 * also, flog the new value.
 * return 0 if caller can continue or -1 if it is time to stop.
 */
srch_eval(mjd, tmincp)
double mjd;
double *tmincp;
{
	char errbuf[128];
	int s;
	double v;

	if (!srch_f)
	    return (0);

	if (execute_expr (&v, errbuf) < 0) {
	    srch_f = 0;
	    f_msg (errbuf);
	} else {
	    s = (*srch_f)(mjd, v, tmincp);
	    if (s < 0)
		srch_f = 0;
	    (void) flog_log (R_SRCH, C_SRCH, v);
	    srch_tmscalled++;
	}

	srch_prstate (0);
	return (s);
}

/* print state of searching. */
srch_prstate (force)
int force;
{
	int srch_minmax(), srch_solve0(), srch_binary();
	static (*last)();

	if (force || srch_f != last) {
	    f_string (R_SRCH, C_SRCHV,
		    srch_f == srch_minmax   ? "Extrema" :
		    srch_f == srch_solve0   ? " Find 0" :
		    srch_f == srch_binary ?   " Binary" :
					      "    off");
	    last = srch_f;
	}
}

srch_ison()
{
	return (srch_f != 0);
}

/* display current expression. then if type in at least one char make it the
 * current expression IF it compiles ok.
 * TODO: editing?
 */
static
set_function()
{
	static char prompt[] = "Function: ";
	char newexp[NC];
	int s;

	f_prompt (prompt);
	fputs (expbuf, stdout);
	c_pos (R_PROMPT, sizeof(prompt));

	s = read_line (newexp, PW-sizeof(prompt));
	if (s >= 0) {
	    char errbuf[NC];
	    if (s > 0 && compile_expr (newexp, errbuf) < 0)
		f_msg (errbuf);
	    else
		strcpy (expbuf, newexp);
	}
}

static
set_accuracy()
{
	static char p[] = "Desired accuracy (         hrs): ";
	int hrs, mins, secs;
	char buf[NC];

	f_prompt (p);
	f_time (R_PROMPT, C_PROMPT+18, tmlimit); /* place in blank spot */
	c_pos (R_PROMPT, sizeof(p));
	if (read_line (buf, PW-sizeof(p)) > 0) {
	    f_dec_sexsign (tmlimit, &hrs, &mins, &secs);
	    f_sscansex (buf, &hrs, &mins, &secs);
	    sex_dec (hrs, mins, secs, &tmlimit);
	}
}

/* use successive paraboloidal fits to find when expression is at a
 * local minimum or maximum.
 */
static
srch_minmax(mjd, v, tmincp)
double mjd;
double v;
double *tmincp;
{
	static double base;
	static double x1, x2, x3; /* keep in increasing order */
	static double y1, y2, y3;
	double xm, a, b;

	if (srch_tmscalled == 0) {
	    base = mjd;
	    x1 = 0.0;
	    y1 = v;
	    return (0);
	}
	mjd -= base;
	if (srch_tmscalled == 1) {
	    /* put in one of first two slots */
	    if (mjd < x1) {
	        x2 = x1;  y2 = y1;
		x1 = mjd; y1 = v;
	    } else {
		x2 = mjd; y2 = v;
	    }
	    return (0);
	}
	if (srch_tmscalled == 2 || fabs(mjd - x1) < fabs(mjd - x3)) {
	    /* closer to x1 so discard x3.
	     * or if it's our third value we know to "discard" x3.
	     */
	    if (mjd > x2) {
		x3 = mjd; y3 = v;
	    } else {
		x3 = x2;  y3 = y2;
		if (mjd > x1) {
		    x2 = mjd; y2 = v;
		} else {
		    x2 = x1;  y2 = y1;
		    x1 = mjd; y1 = v;
		}
	    }
	    if (srch_tmscalled == 2)
		return (0);
	} else {
	    /* closer to x3 so discard x1 */
	    if (mjd < x2) {
		x1 = mjd;  y1 = v;
	    } else {
		x1 =  x2;  y1 = y2;
		if (mjd < x3) {
		    x2 = mjd; y2 = v;
		} else {
		    x2 =  x3; y2 = y3;
		    x3 = mjd; y3 = v;
		}
	    }
	}

#ifdef TRACEMM
	{ char buf[NC];
	  sprintf (buf, "x1=%g y1=%g x2=%g y2=%g x3=%g y3=%g",
						x1, y1, x2, y2, x3, y3);
	  f_msg (buf);
	}
#endif
	a = y1*(x2-x3) - y2*(x1-x3) + y3*(x1-x2);
	if (fabs(a) < 1e-10) {
	    /* near-0 zero denominator, ie, curve is pretty flat here,
	     * so assume we are done enough.
	     * signal this by forcing a 0 tminc.
	     */
	    *tmincp = 0.0;
	    return (-1);
	}
	b = (x1*x1)*(y2-y3) - (x2*x2)*(y1-y3) + (x3*x3)*(y1-y2);
	xm = -b/(2.0*a);
	*tmincp = (xm - mjd)*24.0;
	return (fabs (*tmincp) < tmlimit ? -1 : 0);
}

/* use secant method to solve for time when expression passes through 0.
 */
static
srch_solve0(mjd, v, tmincp)
double mjd;
double v;
double *tmincp;
{
	static double x0, x1;	/* x(n-1) and x(n) */
	static double y0, y1;	/* y(n-1) and y(n) */
	double x2;		/* x(n+1) */
	double df;		/* y(n) - y(n-1) */

	switch (srch_tmscalled) {
	case 0: x0 = mjd; y0 = v; return(0);
	case 1: x1 = mjd; y1 = v; break;
	default: x0 = x1; y0 = y1; x1 = mjd; y1 = v; break;
	}

	df = y1 - y0;
	if (fabs(df) < 1e-10) {
	    /* near-0 zero denominator, ie, curve is pretty flat here,
	     * so assume we are done enough.
	     * signal this by forcing a 0 tminc.
	     */
	    *tmincp = 0.0;
	    return (-1);
	}
	x2 = x1 - y1*(x1-x0)/df;
	*tmincp = (x2 - mjd)*24.0;
	return (fabs (*tmincp) < tmlimit ? -1 : 0);
}

/* binary search for time when expression changes from its initial state.
 * if the change is outside the initial tminc range, then keep searching in that
 *    direction by tminc first before starting to divide down.
 */
static
srch_binary(mjd, v, tmincp)
double mjd;
double v;
double *tmincp;
{
	static double lb, ub;		/* lower and upper bound */
	static int initial_state;
	int this_state = v >= 0.5;

#define	FLUNDEF	-9e10

	if (srch_tmscalled == 0) {
	    if (*tmincp >= 0.0) {
		/* going forwards in time so first mjd is lb and no ub yet */
		lb = mjd;
		ub = FLUNDEF;
	    } else {
		/* going backwards in time so first mjd is ub and no lb yet */
		ub = mjd;
		lb = FLUNDEF;
	    }
	    initial_state = this_state;
	    return (0);
	}

	if (ub != FLUNDEF && lb != FLUNDEF) {
	    if (this_state == initial_state)
		lb = mjd;
	    else
		ub = mjd;
	    *tmincp = ((lb + ub)/2.0 - mjd)*24.0;
#ifdef TRACEBIN
	    { char buf[NC];
	      sprintf (buf, "lb=%g ub=%g tminc=%g mjd=%g is=%d ts=%d",
			    lb, ub, *tmincp, mjd, initial_state, this_state);
	      f_msg (buf);
	    }
#endif
	    /* signal to stop if asking for time change less than TMLIMIT */
	    return (fabs (*tmincp) < tmlimit ? -1 : 0);
	} else if (this_state != initial_state) {
	    /* gone past; turn around half way */
	    if (*tmincp >= 0.0)
		ub = mjd;
	    else
		lb = mjd;
	    *tmincp /= -2.0;
	    return (0);
	} else {
	    /* just keep going, looking for first state change but we keep
	     * learning the lower (or upper, if going backwards) bound.
	     */
	    if (*tmincp >= 0.0)
		lb = mjd;
	    else
		ub = mjd;
	    return (0);
	}
}
xXx
echo x sun.c
cat > sun.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"

/* given the modified JD, mjd, return the true geocentric ecliptic longitude
 *   of the sun for the mean equinox of the date, *lsn, in radians, and the
 *   sun-earth distance, *rsn, in AU. (the true ecliptic latitude is never more
 *   than 1.2 arc seconds and so may be taken to be a constant 0.)
 * if the APPARENT ecliptic longitude is required, correct the longitude for
 *   nutation to the true equinox of date and for aberration (light travel time,
 *   approximately  -9.27e7/186000/(3600*24*365)*2*pi = -9.93e-5 radians).
 */
sunpos (mjd, lsn, rsn)
double mjd;
double *lsn, *rsn;
{
	double t, t2;
	double ls, ms;    /* mean longitude and mean anomoay */
	double s, nu, ea; /* eccentricity, true anomaly, eccentric anomaly */
	double a, b, a1, b1, c1, d1, e1, h1, dl, dr;

	t = mjd/36525.;
	t2 = t*t;
	a = 100.0021359*t;
	b = 360.*(a-(int)a);
	ls = 279.69668+.0003025*t2+b;
	a = 99.99736042000039*t;
	b = 360*(a-(int)a);
	ms = 358.47583-(.00015+.0000033*t)*t2+b;
	s = .016751-.0000418*t-1.26e-07*t2;
	anomaly (degrad(ms), s, &nu, &ea);
	a = 62.55209472000015*t;
	b = 360*(a-(int)a);
	a1 = degrad(153.23+b);
	a = 125.1041894*t;
	b = 360*(a-(int)a);
	b1 = degrad(216.57+b);
	a = 91.56766028*t;
	b = 360*(a-(int)a);
	c1 = degrad(312.69+b);
	a = 1236.853095*t;
	b = 360*(a-(int)a);
	d1 = degrad(350.74-.00144*t2+b);
	e1 = degrad(231.19+20.2*t);
	a = 183.1353208*t;
	b = 360*(a-(int)a);
	h1 = degrad(353.4+b);
	dl = .00134*cos(a1)+.00154*cos(b1)+.002*cos(c1)+.00179*sin(d1)+
								.00178*sin(e1);
	dr = 5.43e-06*sin(a1)+1.575e-05*sin(b1)+1.627e-05*sin(c1)+
					    3.076e-05*cos(d1)+9.27e-06*sin(h1);
	*lsn = nu+degrad(ls-ms+dl);
	*rsn = 1.0000002*(1-s*cos(ea))+dr;
	range (lsn, 2*PI);
}
xXx
echo x time.c
cat > time.c << 'xXx'
/* I have tried to provide two ways to set the time, timezone etc.
 * one works on our ibm-pc and at&t systems, one works on our BSD 4.2 vax.
 * I hope at least one works for you!
 * #define TZA	for the at&t method
 * #define TZB	for the BSD method
 */
#define	TZB

#include <stdio.h>
#include <time.h>
#include "astro.h"
#include "circum.h"

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 struct tm *gmtime();
	struct tm *gmt;
	long c;
	double day, hr;

#ifdef TZA
	extern long timezone;
	extern int daylight;
	extern char *tzname[2];

	tzset();
	tz = timezone/3600;
	strncpy (tznm, tzname[daylight?1:0], sizeof(tznm)-1);
#endif
#ifdef TZB
	extern char *timezone();
	struct timeval timev;
	struct timezone timez;

	gettimeofday (&timev, &timez);
	tz = timez.tz_minuteswest/60;
	if (timez.tz_dsttime)
	    tz -= 1.0;
	strncpy (tznm, timezone(timez.tz_minuteswest, timez.tz_dsttime),
								sizeof(tznm)-1);
#endif
	tznm[sizeof(tznm)-1] = '\0';	/* insure string is terminated */

	time (&c);
	gmt = gmtime (&c);

	cal_mjd (gmt->tm_mon+1, (double)gmt->tm_mday, gmt->tm_year+1900, &day);
	sex_dec (gmt->tm_hour, gmt->tm_min, gmt->tm_sec, &hr);
	mjd = day + hr/24.0;
}

inc_mjd (np, inc)
Now *np;
double 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 x utc_gst.c
cat > utc_gst.c << 'xXx'
#include "astro.h"

/* given a modified julian date, mjd, and a universally coordinated time, utc,
 * return greenwich mean siderial time, *gst.
 */
utc_gst (mjd, utc, gst)
double mjd;
double utc;
double *gst;
{
	double tnaught();
	static double lastmjd;
	static double t0;

	if (mjd != lastmjd) {
	    t0 = tnaught (mjd);
	    lastmjd = mjd;
	}
	*gst = (1.0/SIDRATE)*utc + t0;
	range (gst, 24.0);
}

/* given a modified julian date, mjd, and a greenwich mean siderial time, gst,
 * return universally coordinated time, *utc.
 */
gst_utc (mjd, gst, utc)
double mjd;
double gst;
double *utc;
{
	double tnaught();
	static double lastmjd;
	static double t0;

	if (mjd != lastmjd) {
	    t0 = tnaught (mjd);
	    range (&t0, 24.0);
	    lastmjd = mjd;
	}
	*utc = gst - t0;
	range (utc, 24.0);
	*utc *= SIDRATE;
}

static double
tnaught (mjd)
double mjd;	/* julian days since 1900 jan 0.5 */
{
	double dmjd;
	int m, y;
	double d;
	double t, t0;

	mjd_cal (mjd, &m, &d, &y);
	cal_mjd (1, 0., y, &dmjd);
	t = dmjd/36525;
	t0 = 6.57098e-2 * (mjd - dmjd) - 
	     (24 - (6.6460656 + (5.1262e-2 + (t * 2.581e-5))*t) -
		   (2400 * (t - (((double)y - 1900)/100))));
	return (t0);
}
xXx
echo x version.c
cat > version.c << 'xXx'
/* N.B. please increment version and date and note each change. */

#include "screen.h"

static char vmsg[] = "Version 4.8  November 22, 1989";

/*
 * 4.8 10/28/89 use doubles everywhere
 *     10/31/89	add direct planet row selection codes.
 *     11/2/89  improve compiler's fieldname parser.
 *     11/3/89	switch from ESC to q for "go on" (CBREAK ESC not very portable)
 *     11/6/89	allow plotting the search function too.
 *     11/8/89  suppress screen updates while plotting and nstep > 1.
 *     11/9/89	fix bug prohibiting plotting venus' sdist and objx's transit.
 *     11/9/89	add option to plot in polar coords.
 *     11/12/89	fix bug related to updating timezone name when it is changed.
 *     11/21/89 fix bug in when to print info about object-x
 *     11/21/89	increase MAXPLTLINES to 10 (to ease plotting all planet seps)
 *     11/22/89 allow setting fields from command line too.
 * 4.7 10/13/89 start adding general searching feature. start with flogging.
 *     10/17/89 add compiler, first menu ideas, get binary srch working.
 *     10/18/89 add parabolic-extrema and secant-0 solvers.
 *     10/23/89 finish up new idea of one-line control and set-up "popup" menus.
 * 4.6 10/29/89 improve transit circumstances by iterating as with rise/set.
 *		allow changing lst.
 *		show Updating message at better times.
 *		avoid overstrikes while watching and add trails option.
 *		allow for Turbo-C 2.0 printf bug using %?.0f".
 * 4.5  9/24/89 add third table of all mutual planet angular distances.
 * 4.4  9/21/89 add second planet table with rise/set times.
 *		all rise/set times may now use standard or adaptive horizons.
 * 4.3   9/6/89 NM/FM calendar overstikes now use local time (was ut).
 *		display elongation of object x.
 *		better handling of typo when asking for refraction model.
 * 4.2	7/24/89	specify 7 digits to plot file (not just default to 6)
 * 4.1  7/18/89 use buffered output and fflush in read_char().
 * 4.0   7/8/89	add simple sky and solarsystem plotting (and rearrange fields)
 *		change mars' .cfg mnemonic from a to m.
 *		clean up nstep/NEW CIR handling
 *		quit adding our own .cfg suffixes, but...
 *		add looking for $HOME/.ephemrc (Ronald Florence)
 *		drop -b
 *		no longer support SITE
 * 3.17 6/15/89 misspelt temperature prompt; sun -/= bug. (Mike McCants)
 *		change sun() to sunpos() for sake of Sun Microsystems.
 * 3.16  6/9/89 allow JD to be set and plotted.
 *		c_clear (LATTIC_C) should use J not j (Alex Pruss)
 *		support SIGINT (Ronald Florence)
 * 3.15  6/8/89 forget SIMPLETZ: now TZA and TZB.
 * 3.14  6/6/89 add back borders but allow turning off via -b
 * 3.13 5/26/89 fix Day/Nite picking loc bug.
 * 3.12 5/25/89 add SIMPLETZ option to time.c for systems w/o tzset()
 *		files; couldn't plot dayln or niteln.
 * 3.11 5/16/89 local time prompt said utc; add NiteLn; check for bad plot
 * 3.10 4/27/89 allow caps for moving cursor around too
 * 3.9   4/5/89 discard leading termcap delay digits, for now
 * 3.8   3/2/89 shorten displayed precision, add heliocentric lat/long
 * 3.7  2/13/89 change to ^d to quit program.
 * 3.6   2/7/89 try adding .cfg suffix if can't find config file
 * 3.5   2/2/89 sunrise/set times based on actual sun size and pressure/temp
 * 3.4  1/22/89 calendar and all rise/set times based on local date, not utc
 * 3.3   1/6/89 add z to plot files (still don't plot it however)
 * 3.2   1/3/89 if set date/time then time does not inc first step
 * 3.1   1/1/89 user def. graph labels; nstep/stpsz control; genuine c_eol
 * 3.0 12/31/88 add graphing; add version to credits.
 * 2.7 12/30/88 add version to credits.
 * 2.6 12/28/88 twilight defined as 18 rather than 15 degrees below horizon
 * 2.5 12/26/88 remove trace capability; add screen shadowing: ^l.
 * 2.4 10/31/88 add credits banner, -s turns it off; savings time fix.
 * 2.3  9/23/88 exchange Altitude/Elevation titles (no code changes)
 * 2.2  9/20/88 more caution in aaha_aux() guarding acos() arg range
 * 2.1  9/14/88 moon phase always >= 0 to match planets convention
 * 2.0  9/13/88 add version ^v option
 */

version()
{
	f_msg (vmsg);
}

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, (c) 1985",
"",
"type any key to continue..."
};
credits()
{
	int r = 10;	/* first row of credits message */
	int l;

	c_erase();
	for (l = 0; l < sizeof(cre)/sizeof(cre[0]); l++)
	    f_string (r++, (NC - strlen(cre[l]))/2, cre[l]);
	(void) read_char();	/* wait for any char to continue */
}
xXx
echo x watch.c
cat > watch.c << 'xXx'
/* these functions allow you to watch the sky or the solar system via a
 * simple character-graphics representation on the screen. 
 * the interaction starts by using the current time. then control with
 *    END returns to table form; or
 *    RETURN advances time by one StpSz; or
 *    d|D advances once by 24 hours (1 day); or
 *    h|H advances once by 1 hour; or
 *    any other key keeps advancing by StpSz until any key.
 */

#include <stdio.h>
#include <math.h>
#include "astro.h"
#include "circum.h"
#include "screen.h"

#define	TROW	(R_PROMPT+1)	/* time/date row */
#define	TCOL	C_PROMPT
#define	TGAP	(C_UD-C_UTV)

#define	SKYACC	3600.	/* desired sky plot accuracy, in arc seconds */
#define	SSACC	3600.	/* desired solar system plot accuracy, in arc secs */

/* single-character tag for each body.
 * order must match the #defines in astro.h and screen.h additions.
 */
static char body_tags[] = "evmjsunpSM?";

/* multiple and single loop prompts */
static char frprompt[] = "Running... press any key to stop.";
static char qprompt[]  =
"q to quit, RETURN/h/d to step by StpSz/hour/day, or any other to freerun";

/* used to record and then erase last plotted chars */
typedef struct {
    int l_r, l_c;
} LastDraw;

static int trails;	/* !0 if want to leave trails */

watch (np, tminc, wbodies)
Now *np;	/* time now and on each step */
double tminc;	/* hrs to increment time by each step */
int wbodies;	/* each bit is !=0 if want that body */
{
	static char *flds[3] = {
	    "Night sky", "Solar system"
	};
	int fn = 0;

    ask:
	flds[2] = trails ? "Leave trails" : "No trails";
	switch (popup (flds, fn, 3)) {
	case 0: watch_sky (np, tminc, wbodies); break;
	case 1: watch_solarsystem (np, tminc, wbodies); break;
	case 2: trails ^= 1; fn = 2; goto ask;	/* toggle trails and repeat */
	default: break;
	}
}

/* full night sky view.
 * north is at left and right of screen south at center.
 * 0 elevation is at bottom of screen, zenith at the top.
 */
static
watch_sky (np, tminc, wbodies)
Now *np;	/* time now and on each step */
double tminc;	/* hrs to increment time by each step */
int wbodies;	/* each bit is !=0 if want */
{
	static char title[] = "Sky at ";
	int tcol = sizeof(title)+1;
	double tminc0 = tminc;	/* remember the original */
	LastDraw last[20], *lp;
	int nlast = 0;
	int once = 1;
	double lmjd;
	Sky s;
	int p;

	set_objx_tag();
	c_erase();
	f_string (TROW, TCOL, title);

	while (1) {
	    if (once)
		print_updating();

	    /* unless we want trails,
	     * erase any previous tags (in same order as written)
	     */
	    if (!trails)
		for (lp = last; --nlast >= 0; lp++)
		    f_char (lp->l_r, lp->l_c, ' ');
	    nlast = 0;

	    /* print LOCAL time and date we will be using */
	    lmjd = np->n_mjd - np->n_tz/24.0;
	    f_time (TROW, tcol, mjd_hr(lmjd));
	    f_date (TROW, tcol+TGAP, mjd_day(lmjd));

	    /* print desired stuff */
	    for (p = nxtbody(-1); p != -1; p = nxtbody(p))
		if (wbodies & (1<<p)) {
		    (void) body_cir (p, SKYACC, np, &s);
		    if (s.s_alt >= 0) {
			draw_sky (s.s_alt, s.s_az, body_tags[p], last, nlast);
			nlast++;
		    }
		}

	    if (once || (chk_char()==0 && read_char()!=0)) {
		if (readwcmd (tminc0, &tminc, &once) < 0)
		    break;
	    }

	    /* advance time */
	    inc_mjd (np, tminc);
	}

	redraw_screen(2);
}

/* solar system view, "down from the top", first point of aries to the right.
 * always include earth.
 */
static
watch_solarsystem (np, tminc, wbodies)
Now *np;	/* time now and on each step */
double tminc;	/* hrs to increment time by each step */
int wbodies;
{
	/* max au of each planet from sun; in astro.h #defines order */
	static double auscale[] = {.38, .75, 1.7, 5.2, 11., 20., 31., 39.};
	static char title[] = "Solar System at ";
	int tcol = sizeof(title)+1;
	double tminc0 = tminc;	/* remember the original */
	LastDraw last[20], *lp;
	int nlast = 0;
	int once = 1;
	double lmjd;
	double scale;
	Sky s;
	int p;

	/* set screen scale: largest au we will have to plot */
	scale = 0.;
	for (p = MERCURY; p <= PLUTO; p++)
	    if (wbodies & (1<<p))
		scale = auscale[p];
	if (scale < 1.)
	    scale = 1.;

	c_erase();
	f_string (TROW, TCOL, title);

	while (1) {
	    if (once)
		print_updating();

	    /* unless we want trails,
	     * erase any previous tags (in same order as written).
	     */
	    if (!trails)
		for (lp = last; --nlast >= 0; lp++)
		    f_char (lp->l_r, lp->l_c, ' ');
	    nlast = 0;

	    /* print LOCAL time and date we will be using */
	    lmjd = np->n_mjd - np->n_tz/24.0;
	    f_time (TROW, tcol, mjd_hr(lmjd));
	    f_date (TROW, tcol+TGAP, mjd_day(lmjd));

	    /* print desired stuff */
	    for (p = MERCURY; p <= PLUTO; p++)
		if (wbodies & (1<<p)) {
		    (void) body_cir (p, SSACC, np, &s);
		    draw_ss (s.s_sdist, s.s_hlong, body_tags[p], scale,
								last, nlast);
		    nlast++;
		}
	    /* fake a sun at center and add earth */
	    draw_ss (0., 0., 'S', scale, last, nlast);
	    nlast++;
	    (void) body_cir (SUN, SSACC, np, &s);
	    draw_ss (s.s_edist, s.s_hlong, 'E', scale, last, nlast);
	    nlast++;

	    if (once || (chk_char()==0 && read_char()!=0)) {
		if (readwcmd (tminc0, &tminc, &once) < 0)
		    break;
	    }

	    /* advance time */
	    inc_mjd (np, tminc);
	}

	redraw_screen(2);
}

static
set_objx_tag()
{
	char n[MAXOBJXNM+1];

	objx_get ((double *)0, (double *)0, (double *)0, n);
	body_tags[OBJX] = n[0] > ' ' ? n[0] : '?';
}

static
draw_sky (alt, az, tag, last, nlast)
double alt, az;
char tag;
LastDraw last[];
int nlast;
{
	int r, c;

	r = NR - (int)(alt*2/PI*(NR-1) + 0.5);
	c = (int)(az/2.0/PI*(NC-1) + 0.5) + 1;
	addlast (last, nlast, r, c);
	f_char (last[nlast].l_r, last[nlast].l_c, tag);
}

static
draw_ss (dist, angle, tag, scale, last, nlast)
double dist, angle;
char tag;
double scale;
LastDraw last[];
int nlast;
{
	double rad = dist / scale;
	int r, c;

	r = NR - (int)((NR-1)/2*(1.0+rad*sin(angle)) + 0.5);
	c = 1 + (int)((NC-1)/2*(1.0+rad*cos(angle)/ASPECT) + 0.5);
	addlast (last, nlast, r, c);
	f_char (last[nlast].l_r, last[nlast].l_c, tag);
}

/* add r,c to last[nlast] but possibly move column to avoid overlapps */
static
addlast (last, nlast, r, c)
LastDraw last[];
int nlast;
int r, c;
{
	LastDraw *lp;

    search:
	for (lp = last + nlast; --lp >= last; )
	    if (lp->l_r == r && lp->l_c == c) {
		if (++c > NC)
		    c = 1;
		goto search;
	    }

	last[nlast].l_r = r;
	last[nlast].l_c = c;
}

/* see what the op wants to do now and update prompt/times accordingly.
 * return -1 if we are finished, else 0.
 */
static int
readwcmd (tminc0, tminc, once)
double tminc0;
double *tminc;
int *once;
{
	f_prompt (qprompt);

	switch (read_char()) {
	case END: 	/* back to table */
	    return (-1);
	case '\r':	/* one StpSz step */
	    *tminc = tminc0;
	    *once = 1;
	    break;
	case 'd':	/* one 24-hr step */
	    *tminc = 24.0;
	    *once = 1;
	    break;
	case 'h':	/* one 1-hour step */
	    *tminc = 1.0;
	    *once = 1;
	    break;
	default:		/* free-run */
	    *once = 0;
	    f_prompt (frprompt);
	}
	return (0);
}
xXx
echo x ephem.cfg
cat > ephem.cfg << 'xXx'
UT NOW
LONG 93:42:8
LAT 44:50:37
HEIGHT 800
TEMP 40
PRES 29.5
STPSZ RTC
PROPTS TSMevmjsunp
EPOCH EOD
NSTEP 1
OBJN Or
OBJRA 6:0:0
OBJDEC 0:0:0
xXx