#!/bin/sh
# This is a shell archive (produced by GNU shar 4.0).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1998-12-23 23:35 PST by <cruiser1@eve>.
# Source directory was `/sp6/cruiser1/540'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
# 397535 -rw-r--r-- Helpfile.540
#   1326 -rw-r--r-- Makefile
#    778 -rw-r--r-- README.1ST
#  14700 -rw-r--r-- README.540
#  14714 -rw-r--r-- Update.540
#  48352 -rw-r--r-- astrolog.c
#   4196 -rw-r--r-- astrolog.dat
#   2092 -rw-r--r-- astrolog.def
#  50005 -rw-r--r-- astrolog.h
#  91166 -rw-r--r-- astrolog.rc
#  30138 -rw-r--r-- calc.c
#  46020 -rw-r--r-- charts0.c
#  48646 -rw-r--r-- charts1.c
#  29610 -rw-r--r-- charts2.c
#  25364 -rw-r--r-- charts3.c
#  20770 -rw-r--r-- data.c
#  16447 -rw-r--r-- data2.c
#  23600 -rw-r--r-- extern.h
#  27795 -rw-r--r-- general.c
#  22619 -rw-r--r-- intrpret.c
#  22959 -rw-r--r-- io.c
#   1179 -rw-r--r-- makefile.bgi
#    984 -rw-r--r-- makefile.cfg
#   1352 -rw-r--r-- makefile.com
#   1480 -rw-r--r-- makefile.msc
#   4774 -rw-r--r-- makefile.win
#  21696 -rw-r--r-- matrix.c
#  43215 -rw-r--r-- placalc.c
#  15662 -rw-r--r-- placalc.h
#  35451 -rw-r--r-- placalc2.c
#  24666 -rw-r--r-- resource.h
#  55456 -rw-r--r-- wdialog.c
#  44609 -rw-r--r-- wdriver.c
#  31760 -rw-r--r-- xcharts0.c
#  40811 -rw-r--r-- xcharts1.c
#  27339 -rw-r--r-- xcharts2.c
#  27797 -rw-r--r-- xdata.c
#  20948 -rw-r--r-- xdevice.c
#  26099 -rw-r--r-- xgeneral.c
#  51783 -rw-r--r-- xscreen.c
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo 'WARNING: not restoring timestamps'
fi
rm -f 1231235999 $$.touch
#
# ============= Helpfile.540 ==============
if test -f 'Helpfile.540' && test X"$1" != X"-c"; then
  echo 'x - skipping Helpfile.540 (File already exists)'
else
  echo 'x - extracting Helpfile.540 (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Helpfile.540' &&
--
X
X AAAAA    SSSSS   TTTTTTT  RRRRRR    OOOOO   L         OOOOO    GGGGG
A     A  S     S     T     R     R  O     O  L        O     O  G     G
A     A  S           T     R     R  O     O  L        O     O  G
AAAAAAA   SSSSS      T     RRRRRR   O     O  L        O     O  G  GGGG
A     A        S     T     R   R    O     O  L        O     O  G     G
A     A  S     S     T     R    R   O     O  L        O     O  G     G
A     A   SSSSS      T     R     R   OOOOO   LLLLLLL   OOOOO    GGGGG
X
X                         **  VERSION 5.40  **
X
X
Helpfile for Astrolog version 5.40 (December 1998):
X
X     This file contains a complete list of all the features available
in Astrolog 5.40, and documentation on how to use each option. The
file is divided into eight sections:
X
1) A summary of all the main features which are accessed via command
line switches and parameters, along with the single key press
commands that can be given to an X Window or PC graphics screen to
change the display in various ways (assuming graphics are compiled
in) is listed.
X
2) The list of command switches and keys is repeated, but after each
option is given a full description of the details of the feature.
X
3) Details of default settings, in compile time options, and in the
default configuration file, are described, along with using Astrolog
files in general.
X
4) Descriptions of things that appear in Astrolog text displays are
described. This consists of describing how to enter chart information
into the program, and how to interpret what is seen in the standard
main display.
X
5) Next is a description of the different graphic chart displays and
how they are organized, and the X Windows features in general.
(Looking for a quick display to prove Astrolog was worth downloading
and/or compiling? With graphics try: "astrolog -Xn -XG"!)
X
6) Then are discussed the program's graphics features for PC's, how
to use them, the ways they are different from X Windows, and the best
way to use them if running the DOS version under Microsoft Windows.
X
7) Then is discussed Astrolog for Windows, and a description of the
easy to use menu and dialog interface it offers.
X
8) Finally is a section on compiling Astrolog if you have the source
code files, as opposed to an executable ready to run, as well as how
to compile and run Astrolog on the Macintosh.
X
--
X
IMPORTANT NOTICE: The graphics database and chart display routines
used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
(Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
Permission is granted to freely use and distribute these routines
provided one doesn't sell, restrict, or profit from them in any way.
Modification is allowed provided these notices remain with any
altered or edited versions of the program.
X
The main planetary calculation routines used in this program have
been Copyrighted and the core of this program is basically a
conversion to C of the routines created by James Neely as listed in
Michael Erlewine's 'Manual of Computer Programming for Astrologers',
available from Matrix Software. The copyright gives us permission to
use the routines for personal use but not to sell them or profit from
them in any way.
X
The PostScript code within the core graphics routines are programmed
and Copyright (C) 1992-1993 by Brian D. Willoughby. Conditions are
identical to those above.
X
The extended accurate ephemeris databases and formulas are from the
calculation routines in the program "Placalc" and are programmed and
Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
The use of that source code is subject to regulations made by
Astrodienst Zurich, and the code is not in the public domain. This
copyright notice must not be changed or removed by any user of this
program.
X
X
************************
LIST OF COMMAND SWITCHES
************************
X
Astrolog (version 5.40) command switches:
X -H: Display this help list.
X -Hc: Display program credits and copyrights.
X -HC: Display names of zodiac signs and houses.
X -HO: Display available planets and other celestial objects.
X -HA: Display available aspects, their angles, and present orbs.
X -HF: Display names of astronomical constellations.
X -HS: Display information about planets in the solar system.
X -HI: Display meanings of signs, houses, planets, and aspects.
X -He: Display all info tables together (-Hc-H-Y-HX-HC-HO-HA-HF-HS-HI).
X -Q: Prompt for more command switches after display finished.
X -Q0: Like -Q but prompt for additional switches on startup.
X -M <1-48>: Run the specified command switch macro.
X -M0 <1-48> <string>: Define the specified command switch macro.
X -Y: Display help list of less commonly used command switches.
X
Switches which determine the type of chart to display:
X -v: Display list of object positions (chosen by default).
X -v0: Like -v but express velocities relative to average speed.
X -w [<rows>]: Display chart in a graphic house wheel format.
X -w0 [..]: Like -w but reverse order of objects in houses 4..9.
X -g: Display aspect and midpoint grid among planets.
X -g0: Like -g but flag aspect configurations (e.g. Yod's) too.
X -g0: For comparison charts, show midpoints instead of aspects.
X -ga: Like -g but indicate applying instead of difference orbs.
X -gp: Like -g but generate parallel and contraparallel aspects.
X -a: Display list of all aspects ordered by influence.
X -a0: Like -a but display aspect summary too.
X -a[0]a: Like -a but indicate applying and separating orbs.
X -a[0]p: Like -a but do parallel and contraparallel aspects.
X -m: Display all object midpoints in sorted zodiac order.
X -m0: Like -m but display midpoint summary too.
X -ma: Like -m but show aspects from midpoints to planets as well.
X -Z: Display planet locations with respect to the local horizon.
X -Z0: Like -Z but express coordinates relative to polar center.
X -Zd: Search day for object local rising and setting times.
X -S: Display x,y,z coordinate positions of planets in space.
X -l: Display Gauquelin sectors for each planet in chart.
X -l0: Like -l but approximate sectors using Placidus cusps.
X -j: Display astrological influences of each object in chart.
X -j0: Like -j but include influences of each zodiac sign as well.
X -L [<step>]: Display astro-graph locations of planetary angles.
X -L0 [..]: Like -L but display list of latitude crossings too.
X -K: Display a calendar for given month.
X -Ky: Like -K but display a calendar for the entire year.
X -d [<step>]: Print all aspects and changes occurring in a day.
X -dm: Like -d but print all aspects for the entire month.
X -dy: Like -d but print all aspects for the entire year.
X -dY <years>: Like -d but search within a number of years.
X -dp <month> <year>: Print aspects within progressed chart.
X -dpy <year>: Like -dp but search for aspects within entire year.
X -dpY <year> <years>: Like -dp but search within number of years.
X -dp[y]n: Search for progressed aspects in current month/year.
X -D: Like -d but display aspects by influence instead of time.
X -E: Display planetary ephemeris for given month.
X -Ey: Display planetary ephemeris for the entire year.
X -EY <years>: Display planetary ephemeris for a number of years.
X -e: Print all charts together (i.e. -v-w-g0-a-m-Z-S-j0-L0-K-d-D-E).
X -t <month> <year>: Compute all transits to natal planets in month.
X -tp <month> <year>: Compute progressions to natal in month for chart.
X -tr <month> <year>: Compute all returns in month for chart.
X -t[p]y: <year>: Compute transits/progressions for entire year.
X -t[p]Y: <year> <years>: Compute transits for a number of years.
X -t[py]n: Compute transits to natal planets for current time now.
X -T <month> <day> <year>: Display transits ordered by influence.
X -Tp <month> <day> <year>: Print progressions instead of transits.
X -T[p]n: Display transits ordered by influence for current date.
X -P [<parts>]: Display list of Arabic parts and their positions.
X -P0 [<parts>]: Like -P but display formulas with terms reversed.
X -P[z,n,f]: Order parts by position, name, or formula.
X -I [<columns>]: Print interpretation of selected charts.
X
Switches which affect how the chart parameters are obtained:
X -n: Compute chart for this exact moment using current time.
X -n[d,m,y]: Compute chart for start of current day, month, year.
X -z [<zone>]: Change the default time zone (for -d-E-t-q options).
X -z0 [<offset>]: Change the default daylight time setting.
X -zl <long> <lat>: Change the default longitude & latitude.
X -zt <time>: Set only the time of current chart.
X -zd <date>: Set only the day of current chart.
X -zm <month>: Set only the month of current chart.
X -zy <year>: Set only the year of current chart.
X -zi <name> <place>: Set name and place strings of current chart.
X -q <month> <date> <year> <time>: Compute chart with defaults.
X -qd <month> <date> <year>: Compute chart for noon on date.
X -qm <month> <year>: Compute chart for first of month.
X -qy <year>: Compute chart for first day of year.
X -qa <month> <date> <year> <time> <zone> <long> <lat>:
X     Compute chart automatically given specified data.
X -qb <month> <date> <year> <time> <daylight> <zone> <long> <lat>:
X     Like -qa but takes additional parameter for daylight offset.
X -qj <day>: Compute chart for time of specified Julian day.
X -i <file>: Compute chart based on info in file.
X -i[2,3,4] <file>: Load chart info into chart slots 2, 3, or 4.
X -o <file> [..]: Write parameters of current chart to file.
X -o0 <file> [..]: Like -o but output planet/house positions.
X -os <file>, > <file>: Redirect output of text charts to file.
X
Switches which affect what information is used in a chart:
X -R [<obj1> [<obj2> ..]]: Restrict specific bodies from displays.
X -R0 [<obj1> ..]: Like -R but restrict everything first.
X -R1 [<obj1> ..]: Like -R0 but unrestrict and show all objects.
X -R[C,u,U]: Restrict all minor cusps, all uranians, or stars.
X -RT[0,1,C,u,U] [..]: Restrict transiting planets in -t lists.
X -RA [<asp1> ..]: Restrict aspects by giving them negative orbs.
X -C: Include angular and non-angular house cusps in charts.
X -u: Include transneptunian/uranian bodies in charts.
X -U: Include locations of fixed background stars in charts.
X -U[z,l,n,b]: Order by azimuth, altitude, name, or brightness.
X -A <0-18>: Specify the number of aspects to use in charts.
X -Ao <aspect> <orb>: Specify maximum orb for an aspect.
X -Am <planet> <orb>: Specify maximum orb allowed to a planet.
X -Ad <planet> <orb>: Specify orb addition given to a planet.
X -Aa <aspect> <angle>: Change the actual angle of an aspect.
X
Switches which affect how a chart is computed:
X -b: Use ephemeris files for more accurate location computations.
X -b0: Like -b but display locations to the nearest second too.
X -c <value>: Select a different default system of houses.
X     (0 = Placidus, 1 = Koch, 2 = Equal, 3 = Campanus,
X     4 = Meridian, 5 = Regiomontanus, 6 = Porphyry, 7 = Morinus,
X     8 = Topocentric, 9 = Alcabitius, 10 = Equal (MC),
X     11 = Neo-Porphyry, 12 = Whole, 13 = Vedic, 14 = None.)
X -s [..]: Compute a sidereal instead of the normal tropical chart.
X -sr: Compute right ascension locations relative to equator.
X -s[z,h,d]: Display locations as in zodiac, hours/minutes, or degrees.
X -h [<objnum>]: Compute positions centered on specified object.
X -p <month> <day> <year>: Cast 2ndary progressed chart for date.
X -p0 <month> <day> <year>: Cast solar arc chart for date.
X -p[0]n: Cast progressed chart based on current date now.
X -pd <days>: Set no. of days to progress / day (default 365.25).
X -x <1-360>: Cast harmonic chart based on specified factor.
X -1 [<objnum>]: Cast chart with specified object on Ascendant.
X -2 [<objnum>]: Cast chart with specified object on Midheaven.
X -3: Display objects in their zodiac decan positions.
X -f: Display houses as sign positions (flip them).
X -G: Compute houses based on geographic location only.
X -J: Display wheel charts in Vedic format.
X -9: Display objects in their zodiac navamsa positions.
X -F <objnum> <sign> <deg>: Force object's position to be value.
X -+ [<days>]: Cast chart for specified no. of days in the future.
X -- [<days>]: Cast chart for specified no. of days in the past.
X -+[m,y] [<value>]: Cast chart for no. of months/years in future.
X
Switches for relationship and comparison charts:
X -r <file1> <file2>: Compute a relationship synastry chart.
X -rc <file1> <file2>: Compute a composite chart.
X -rm <file1> <file2>: Compute a time space midpoint chart.
X -r[c,m]0 <file1> <file2> <ratio1> <ratio2>: Weighted chart.
X -rd <file1> <file2>: Print time span between files' dates.
X -rb <file1> <file2>: Display biorhythm for file1 at time file2.
X -r0 <file1> <file2>: Keep the charts separate in comparison.
X -rp[0] <file1> <file2>: Like -r0 but do file1 progr. to file2.
X -rt <file1> <file2>: Like -r0 but treat file2 as transiting.
X -r[3,4]: Make graphics wheel chart tri-wheel or quad-wheel.
X -y <file>: Display current house transits for particular chart.
X -y[b,d,p,t] <file>: Like -r0 but compare to current time now.
X
Switches to access graphics options:
X -k: Display text charts using Ansi characters and color.
X -k0: Like -k but only use special characters, not Ansi color.
X -V <25,43,50>: Start up with text mode set to number of rows.
X -X: Create a graphics chart instead of displaying it as text.
X -Xb: Create bitmap file instead of putting graphics on screen.
X -Xb[n,c,v,a,b]: Set bitmap file output mode to X11 normal,
X     compacted, very compact, Ascii (bmtoa), or Windows bmp.
X -Xp: Create PostScript stroke graphic instead of bitmap file.
X -Xp0: Like -Xp but create complete instead of encapsulated file.
X -XM[0]: Create Windows metafile stroke graphic instead of bitmap.
X -Xo <file>: Write output bitmap or graphic to specified file.
X -XB: Display X chart on root instead of in a separate window.
X -Xm: Create monochrome graphic instead of one in color.
X -Xr: Create chart graphic in reversed colors (white background).
X -Xw <hor> [<ver>], -ge[..]: Change the size of chart graphic.
X -Xs <100,200,300,400>: Change the size of map or characters by %.
X -Xi: Create chart graphic in slightly modified form.
X -Xt: Inhibit display of chart info at bottom of graphic.
X -Xu: Inhibit display of a border around graphic.
X -Xl: Inhibit labeling of object points in chart graphic.
X -Xj: Don't clear screen between chart updates, drawing trails.
X -X1 <object>: Rotate wheel charts so object is at left edge.
X -X2 <object>: Rotate wheel charts so object is at top edge.
X -Xd <name>, -di[..] <name>: Open X window on specified display.
X -XW: Simply create an image of the world map.
X -XW0: Like -XW but do a non-rectangular Mollewide projection.
X -XG [<degrees>]: Display the image of the world as a globe.
X -XP: Like -XG but create the globe from a polar projection.
X -XF: Display maps as constellations on the celestial sphere.
X -Xn [<mode>]: Start up chart or globe display in animation mode.
X -HX: Display list of key press options for screen graphics.
X -W <value>: Run given Windows menu command internally.
X -WN <1-32000>: Set animation update delay in milliseconds.
X -WM <1-48> <text>: Set Windows menu text for macro command.
X -Wn: Don't redraw screen until user forces update.
X
--
X
Astrolog (version 5.40) obscure command switches:
X -Y: Display this help list.
X -Yn: Compute location of true instead of mean node.
X -Yd: Display dates in D/M/Y instead of M/D/Y format.
X -Yt: Display times in 24 hour instead of am/pm format.
X -YC: Automatically ignore insignificant house cusp aspects.
X -Y8: Clip text charts at the rightmost (e.g. 80th) column.
X -YQ <rows>: Pause text scrolling after a page full has printed.
X -Yo: Output chart info and position files in old style format.
X -Yc: Angular cusp objects are house positions instead of angles.
X -Yz <min>: Forward clock by amount for current moment charts.
X -Yl <1-36>: Toggle plus zone status of sector for sector chart.
X -YP <-1,0,1>: Set how Arabic parts are computed for night charts.
X -Yb <days>: Set number of days to span for biorhythm chart.
X -YE <obj> <semi-major axis> <eccentricity (3)> <inclination (3)>
X     <perihelion (3)> <ascending node (3)> <time offset (3)>
X     Change orbit of object to be the given elements.
X -YR <obj1> <obj2> <flag1>..<flag2>: Set restrictions for object range.
X -YRT <obj1> <obj2> <flag1>..<flag2>: Transit restrictions for range.
X -YR0 <flag1> <flag2>: Set restrictions for sign, direction changes.
X -YRZ <rise> <zenith> <set> <nadir>: Set restrictions for -Zd chart.
X -YAo <asp1> <asp2> <orb1>..<orb2>: Set aspect orbs for range.
X -YAm <obj1> <obj2> <orb1>..<orb2>: Set max planet orbs for range.
X -YAd <obj1> <obj2> <orb1>..<orb2>: Set planet orb additions for range.
X -YAa <asp1> <asp2> <ang1>..<ang2>: Set planet aspect angles for range.
X -Yj <obj1> <obj2> <inf1>..<inf2>: Set influences for object range.
X -YjC <cusp1> <cusp2> <inf1>..<inf2>: Set influences for house cusps.
X -YjA <asp1> <asp2> <inf1>..<inf2>: Set influences for aspect range.
X -YjT <obj1> <obj2> <inf1>..<inf2>: Set transit influences for range.
X -Yj0 <inf1> <inf2> <inf3> <inf4>: Set influences given to planets
X     in ruling sign, exalted sign, ruling house, exalted house.
X -YJ <obj> <sign> <cosign>: Set sign planet rules and co-rules.
X -YJ0 <obj> <sign>: Set zodiac sign given planet exalts in.
X -YI <obj> <string>: Customize interpretation for object.
X -YIa <sign> <string>: Customize interpretation adjective for sign.
X -YIv <sign> <string>: Customize interpretation verb for sign.
X -YIC <house> <string>: Customize interpretation for house.
X -YIA <asp> <string>: Customize interpretation for aspect.
X -YIA0 <asp> <string>: Customize aspect interpretation statement.
X -YkC <fir> <ear> <air> <wat>: Customize element colors.
X -YkA <asp1> <asp2> <col1>..<col2>: Customize aspect colors.
X -Yk0 <1..7> <1..7> <col1>..<col2>: Customize 'rainbow' colors.
X -Yk <0..8> <0..8> <col1>..<col2>: Customize 'general' colors.
X -YXG <0-2><0-2><0-2><0-3>: Select among different graphic glyphs
X     for Capricorn, Uranus, Pluto, and Lilith.
X -YXg <cells>: Set number of cells for graphic aspect grid.
X -YXf <val>: Set usage of actual system fonts in graphic file.
X -YXp <-1,0,1>: Set paper orientation for PostScript files.
X -YXp0 <hor> <ver>: Set paper size for PostScript files.
X -YX <hi-res> <lo-res>: Set modes to use for PC screen graphics.
X -0[o,i,q,X]: Disallow file output, input, exiting, and graphics.
X -;: Ignore rest of command line and treat it as a comment.
X
--
X
Astrolog graphics screen key press options (version 5.40):
X Press 'H' or '?' to display this list of key options.
X Press 'p' to toggle pause status on or off.
X Press 'x' to toggle fg/bg colors on screen.
X Press 'm' to toggle color/monochrome display on screen.
X Press 'i' to toggle status of the minor chart modification.
X Press 't' to toggle header info on current chart on screen.
X Press 'b' to toggle drawing of a border around the chart.
X Press 'l' to toggle labeling of object points in chart.
X Press 'j' to toggle not clearing screen between chart updates.
X Press 'v' to display current chart positions on text screen.
X Press 'R', 'C', 'u', 'U' to toggle restriction status of minor
X       objects, minor house cusps, uranian planets, and stars.
X Press 'c' to toggle relationship comparison chart mode.
X Press 's', 'h', 'f', 'g', 'z', 'y' to toggle status of sidereal
X       zodiac, heliocentric charts, domal charts, decan charts,
X       vedic format wheel charts, and navamsa charts.
X Press 'O' and 'o' to recall/store a previous chart from memory.
X Press 'B' to dump current window contents to root background.
X Press 'B' to resize chart display to full size of screen.
X Press 'Q' to resize chart display to a square.
X Press '<' and '>' to decrease/increase the scale size of the
X       glyphs and the size of world map.
X Press '[' and ']' to decrease/increase tilt in globe display.
X Press '+' and '-' to add/subtract a day from current chart.
X Press 'n' to set chart information to current time now.
X Press 'N' to toggle animation status on or off. Charts will
X       be updated to current status and globe will rotate.
X Press '!'-'(' to begin updating current chart by adding times.
X       !: seconds, @: minutes, #: hours, $: days, %: months,
X       ^: years, &: years*10, *: years*100, (: years*1000.
X Press 'r' to reverse direction of time-lapse or animation.
X Press '1'-'9' to set rate of animation to 'n' degrees, etc.
X Press '1'-'9' to determine section of chart to show if clipped.
X Press 'V','A','Z','S','M','K','J','L','E','W','G','P' to switch to
X       normal (-v), grid (-g), local (-Z), space (-S), sector (-l),
X       calendar (-K), dispositor (-j), astro-graph (-L), ephemeris
X       (-E), world map (-XW), globe (-XG), and polar (-XP) modes.
X Press 'Y' to switch to biorhythm relation chart mode.
X Press '0' to toggle between -Z,-Z0 & -XW,-XW0 & -E,-Ey modes.
X Press 'F' to toggle between world and constellation map modes.
X Press 'F1'..'F12' [plus Shift,Ctrl,Alt] to run macros 1..48.
X Press 'space' to force redraw of current graphics display.
X Press 'del' to clear the graphics screen and not redraw.
X Press 'tab' to toggle between graphics resolutions.
X Press 'enter' to input a command line of general switches.
X Press 'q' to terminate graphics and the program.
X
X Left   mouse button: Draw line strokes on chart in window.
X Middle mouse button: Print coordinates of pointer on world map.
X Right  mouse button: Terminate the window and program.
X
X
**********************************
DESCRIPTION OF EACH COMMAND SWITCH
**********************************
X
X     Astrolog allows command line switches to be invoked with either
the leading dash ("-") standard to Unix users, or a leading slash
("/") that PC users are more accustomed to. Not only that, but the
leading character is actually optional. For example, the command
"astrolog -i chartfile -R -u -U -Z -Xs 300 -Xi -XB" can be done as
"astrolog /i chartfile /r /u /U /Z /Xs 300", or can be abbreviated as
just "astrolog i chartfile R u U Z Xs 300 Xi XB". (This is subject to
a couple of minor limitations, in that one can't have the -1 or -3
option follow a -R restriction list of numbers, since the "-1" will
be considered a number.)
X
X     Many switches in their standard form are technically a "toggle"
instead of a "set" for the particular feature in question. For
example, "astrolog -v -g -g" will only result in the -v chart being
printed; an aspect grid won't, because the first -g turned it on
while the second -g turned it off again. This can be useful, in say
the -e everything switch. If you want all of Astrolog's charts except
the astro-graph, you can do "astrolog -e -L", where the -e turns
everything on and the -L turns the astro-graph chart, already on
because of -e, off. In another example, to get a chart with only the
stars in it, one can do "astrolog -R0 -RU", where the -R0 restricts
everything, and the -RU unrestricts all the stars. The various -X
switches which set a mode in graphics are also toggles - a
combination like "-Xr -Xr" which with one instance will just go into
reverse video mode, will remain out of it because the first -Xr put
you in and the second toggled you back out.
X
X     Command switch flags may actually be forced on or off regardless
of their current setting with special character prefixes. Many
switches (such as -s) represent on/off flags and their setting is
toggled when the switch is encountered. However this alone doesn't
allow one to force the setting to be a value, as we don't know if it
needs to be toggled or not. Prefixing any flag switch with '_' will
reset its state even if already off, while prefixing with '=' will
always make it on. For example, putting "_s" on a command line will
always set tropical zodiac, while "=s" will always set sidereal. The
standard '-' and '/' prefixes, along with no prefix at all, always
toggle the current setting. This is useful for configuration files
where we want to set various flags to particular values. There's one
more obscure switch prefix which is ':', which doesn't affect the
setting at all, but still affects any subsetting parameters. For
example, ":I 80" won't affect the interpretation setting at all, but
will still set the default screen width to 80 columns. This is
slightly simpler than the "-I 80 -I" double toggle hack that would
have to be done to do such a thing otherwise.
X
X     The various static help listings that may be generated, such as
the lists from -H, -HO, -HI, and so on, may be combined with each
other and even the actual charts. For convenience the program will
terminate right away and not prompt for chart info if the only thing
specified is one of the tables, e.g. just "-H" will print the help
list and exit, but "-H -i file -g" will print the help list followed
by an aspect grid chart.
X
X     In the command list below, greater than/less than symbols ('<'
and '>') are used to denote a command switch parameter to be replaced
by the appropriate value, brackets ('[' and ']') are used to denote
an optional parameter, and commas are used to separate either/or
choices. For example, the specification of the -I switch is "-I
[<columns>]", meaning that one can specify the -I switch, followed a
parameter for the number of screen columns, but that this extra
parameter is optional. The specification of the -Xs switch is "-Xs
<100,200,300,400>", meaning it can be used as either "-Xs 100", "-Xs
200", "-Xs 300", or "-Xs 400". An ellipsis ('..') generally refers to
a variable length list of values or an abbreviation for something
already indicated in related switches.
X
X     Correct parsing of strings is done on the command line (and in
files since they are technically command lines) in addition to when
the user is being prompted for data within the program. For example,
to do the natal chart for the alt.astrology newsgroup using the -qa
switch, one may enter the intuitive "-qa Jul 29 1991ad 6:23pm -10
151e13 33s52". The items may be entered in other standard and
simpler forms as well, such as just "-qa 7 29 1991 18.23 -10 -151.13
-33.52".
X
X     Any command switch that takes an index number as a parameter may
have it specified by its actual name instead of a hard to remember
value. For example, the switch sequence "-c 1 -R 6 -A 5 -F 7 10 0"
may also be entered as the more understandable "-c Koch -R Jupiter -A
Sextile -F Saturn Capricorn 0". Any string may be abbreviated to its
first three characters. Aspects should be based on their formal
abbreviations, e.g. "ssx" instead of "sem" for Semisextile.
(Presently only the first three characters are ever looked at, so
some star objects may still need to be specified as a number since
they have the same first three letters.)
X
--
X
Astrolog (version 5.40) command switches:
X
-H: Display this help list.
X
X  This option displays a list exactly like the one given above on the
X  screen. Note: Concerning the list itself, PC users are accustomed to
X  seeing command switches with a leading slash "/" instead of a dash
X  "-". To accommodate this, this list of options available does, if the
X  program has been compiled for a PC, display all the switches with a
X  leading "/" instead of a "-". (On Unix and other systems they will
X  be displayed with the standard leading "-".)
X
-Hc: Display program credits and copyrights.
X
X  This help switch displays a full page of credits, listing the names
X  of those who programmed Astrolog or parts of it, and important
X  copyright information and other legal items. Every time the program
X  is invoked, the -Hc switch is mentioned to use to see this info.
X
-HC: Display names of zodiac signs and houses.
X
X  The -HC switch will display a list of the 12 signs of the zodiac, and
X  the 12 houses, listing their standard and traditional names. This is
X  similar to switches like -HO or -HA below, in that it displays lists
X  of things (objects, aspects, or in this case the signs) that Astrolog
X  uses in its charts.
X
-HO: Display available planets and other celestial objects.
X
X  Similar to the -HA option below, the -HO option will list the planets
X  and other celestial objects used by the program, and their numbers as
X  recognized by the -R restrictions (mentioned later). This list will
X  also show the zodiac signs that planets rule, fall in, are exalted
X  in, and debilitated in. Stars are printed in the list along with
X  their azimuth, altitude, and brightness values. Note that this list
X  shows only those items that aren't restricted when its displayed; if
X  you want to show all 87 objects regardless of restriction status,
X  just use the -R1 switch to activate them all and combine it with -HO.
X
X  Concerning objects the program can do, Astrolog can do the position
X  of Lilith, often called the "Dark Moon". This Lilith is the point in
X  space of one focus of the Moon's elliptical orbit around the Earth
X  (Earth itself being in the other of the two), and not the asteroid or
X  hypothetical planet by the same name. Lilith is object number 17 in
X  Astrolog, and in graphics charts its glyph is a small circle with a
X  forward slash through it. If preferred, one can use the -YXG glyph
X  selection switch (described later) to choose the "European" version
X  of the glyph which is like the glyph for the Moon but smaller and
X  flipped horizontally.
X
X  Astrolog computes the position of Lilith as provided by the accurate
X  Placalc formula set. This means that the -b ephemeris switch (covered
X  later) needs to be in effect to get Lilith's positions. When the -b
X  setting is off, Astrolog will display the position of the South Node
X  for object 17 instead. We tweak the name of the object to be
X  "S.Node", change its rulerships and interpretation string
X  appropriately, and change the graphics glyph to be the standard
X  "upside down horseshoe" (a third glyph selectable via -YXG), although
X  we won't automatically update everything again if you toggle the -b
X  flag while the program is running.
X
X  Astrolog can do the position of the East Point as well, which is
X  technically the same as the position of the Ascendant at the equator
X  for whatever time. This is object number 20 in Astrolog, and its
X  graphics glyph is a simple "EP" abbreviation.
X
-HA: Display available aspects, their angles, and present orbs.
X
X  The -HA command switch gives a list of all 18 supported aspects,
X  their abbreviations as used in the aspect grids, their angles, and
X  their orbs. It will list the number of each aspect in addition to all
X  the other info (e.g. conjunct = 1, opposition = 2, etc.) so one can
X  see what number to pass to the -A switch when changing the number of
X  aspects used (see later). Finally, it will print a brief description
X  of what each aspect glyph looks like. This is in case one doesn't
X  know what aspects the weird symbols in the -g -X graphic displays are
X  referring to.
X
-HF: Display names of astronomical constellations.
X
X  This will display a text table of all the constellations, listing
X  their traditional names, their astronomical abbreviations as used in
X  the graphics above, their English meanings, and even their genitive
X  or possessive form (e.g. "Lyra" is the name of the constellation, but
X  the star Vega in it is called Alpha "Lyrae").
X
-HS: Display information about planets in the solar system.
X
X  This is a another static table which will display some astronomical
X  information about the main planets (and Earth's Moon) in a simple
X  form. For each planet is shown its distance from the Sun (or Earth)
X  in Astronomical Units (AU), its orbital period in Earth years, its
X  diameter relative to the Earth (Earth being 1), its rotational period
X  (i.e. day) in hours, its mass relative to the Earth (Earth being 1),
X  its average density with respect to water (water being 1), the tilt
X  of its axis with respect to its orbit, and finally the number of
X  known moons or satellites it has. This table also includes Chiron
X  and the four asteroids, at least for the distance from Sun, length of
X  year, and diameter fields.
X
-HI: Display meanings of signs, houses, planets, and aspects.
X
X  This will display the general meanings of each sign, each house, each
X  planet, and each aspect, on the screen. This shows more or less the
X  database the program uses to base its interpretations on (see the -I
X  switch setting for charts later).
X
-He: Display all info tables together (-Hc-H-Y-HX-HC-HO-HA-HF-HS-HI).
X
X  This switch will print out all ten of Astrolog's static table help
X  listings, like what -e does for actual charts. Specifically, this
X  will show the -Hc copyright screen, the -H switch list, the -Y
X  obscure switch list, the -HX graphics key press list, the -HC sign
X  and house list, the -HO object list, the -HA aspect list, the -HF
X  constellation list, the -HS planet information list, and the -HI core
X  interpretation list, for over 500 lines of informational output.
X
-Q: Prompt for more command switches after display finished.
X
X  Usually when Astrolog finishes printing the specified chart or
X  charts, or when we leave a graphics screen mode, the program will
X  terminate. However, sometimes one wants to display or work with lots
X  of charts or options, which would normally cause them to have to
X  invoke the program over and over again from their shell, using many
X  processes, and can be slow loading over and over from a slow disk.
X  Auto-termination is also bad when automatically starting up the
X  program in an X window or DOS box - once the program finishes, the
X  container will exit right away too, not allowing reading of the text
X  charts. The -Q switch causes the program to enter a looping mode
X  environment where (after the first chart is displayed) the user will
X  automatically be prompted to enter a new set of command switches
X  (using the no SWITCHES interface described later) which will be
X  processed. This will go on and the program will run until you enter
X  "." on a line for the switches to really terminate it.
X
X  Program errors which normally cause Astrolog to exit right away, will
X  (unless "fatal" errors) return the user back to this outer loop.
X  What's more is that being in the loop doesn't cause all the minor
X  program variables to be reset every time. The main things like what
X  info to use and what charts to display must be specified each time,
X  but minor modes (such as the present -x harmonic factor) won't, so
X  say specify -x 5 once, and you will be casting fifth harmonic charts
X  until you specify otherwise or exit the loop, not having to include
X  -x each time.
X
-Q0: Like -Q but prompt for additional switches on startup.
X
X  This is just like -Q above except that the user will first be
X  prompted for command switches right upon entering the program. Note
X  that these will be in addition to whatever else was on the command
X  line where the -Q0 itself was specified. This is mostly useful when
X  running on a Windows system (see later) where one can have -Q0 as a
X  default switch to pass to the program. Upon activation, the user will
X  be in a loop with Astrolog asking for switches right away before
X  proceeding to generate or prompt for any chart information.
X
-M <1-48>: Run the specified command switch macro.
-M0 <1-48> <string>: Define the specified command switch macro.
X
X  Astrolog has a feature to run "switch macros", or a whole command
X  line with one small switch. The -M switch takes one parameter, which
X  is the number of the macro to run. When encountered, the switches it
X  represents will be processed. This is similar to loading in a generic
X  command file with -i, except macros are limited to one command line.
X  Macros however don't require separate files, and may even call
X  command files themselves with -i.
X
X  The switch -M0 is the option that defines a macro. It takes two
X  parameters: the index of the macro to define, and a string
X  representing the command line to assign to it. (The command string
X  probably needs to be in quotes to ensure it's treated as one
X  parameter to -M0, instead of many items which will get processed
X  right away.) There are 48 macro slots available to define or run.
X  Macros may do anything and even call or define other macros. It's
X  possible to get in a infinite loop if you make a macro (or command
X  file) call or load itself; such cases aren't detected and will make
X  the program terminate with some unusual error.
X
X  Macros are very powerful and their uses are nearly endless. A bunch
X  can be defined in the astrolog.dat config file for your most common
X  switch sequences, hopefully preventing things such as batch files
X  that would have to be created otherwise. Suppose you often want to
X  see the transits of outer planets only to the house cusps in your
X  natal chart for the current month. The command line for this is "-i
X  yourchart -tn -RT0 6 7 8 9 10 -R0 -RC -C". You can assign this to the
X  tenth macro slot with: -M0 10 "-i yourchart -tn -RT0 jup sat ura nep
X  plu -R0 -RC -C". That line can be put in your astrolog.dat and you
X  can do this month's transits by just typing "astrolog -M 10". Here's
X  another example: Suppose you want a feature to bring up the chart of
X  the spouse of whoever's chart you are viewing at any time. You can
X  define a special macro, say in slot 5, in each of your chart info
X  files which does a -i on the file of their spouse, or does nothing if
X  they're unmarried. Now when in graphics mode, you can press 'F5'
X  anytime and Astrolog will bring up the spouse's chart! You could
X  define a bunch of macros to set various color sets or aspect orbs and
X  switch among them quickly using the function keys. You could even
X  make a simple chart database by having each chart file load the next
X  one in sequence in some macro, and then cycle through your charts by
X  running that macro in a -Q loop or from the graphics screen.
X
-Y: Display help list of less commonly used command switches.
X
X  This displays a list of available command switches, like the -H
X  option but showing only "less common" switches that would clutter
X  things up if they were in the main list, and are usually only
X  specified in configuration files. Hence almost all of those switches
X  begin with 'Y'.
X
--
X
Switches which determine the type of chart to display:
X
-v: Display list of object positions (chosen by default).
X
X  This is just a formal specification for the standard chart listing of
X  the planetary positions. One will get this chart by default if they
X  don't specify any other chart types, and they will get it along with
X  everything else in the -e option (see below). Although it isn't
X  necessary, it must be included if one wants this type of chart to be
X  displayed along with some of the other chart types described below.
X
-v0: Like -v but express velocities relative to average speed.
X
X  This switch is just like -v except that it modifies the planet
X  velocities fields slightly. (See later for a description of these
X  velocity fields.) The -v switch normally expresses velocity values
X  as an *absolute* quantity in degrees per day that the object appears
X  to have moved through the zodiac. This means that outer planets will
X  generally always have lower values, e.g. although a velocity of 0.010
X  degrees/day for fast moving Mercury means it's about to turn
X  retrograde, the same velocity value is normal for slow moving Pluto.
X  As it is useful to know when a planet is about to change direction,
X  the -v0 switch will divide the actual velocity values by how fast
X  each planet moves with respect to the Sun, meaning that all planets
X  will have an average *relative* velocity value of 1.000, and in all
X  cases, a velocity of 2.000 means the planet is moving twice as fast
X  as normal, and one of 0.010 means the planet is about to turn
X  retrograde.
X
X  Note: The -v0 switch which expresses planetary velocities relative to
X  average speed has a known incompatibility will cause some applying
X  vs. separating aspect orbs to be inverted, i.e. displayed as
X  applying when the reverse is true or vice versa. This affects app/sep
X  aspect grids and aspect lists (-ga, -ma, and -D charts, but not the
X  -T transit influence charts). This is because the velocities are used
X  to determine applying vs. separating to see if one planet is
X  overtaking another. The bug comes with the program thinking that, for
X  example, Pluto moving 2 times faster than normal, will soon overtake
X  Mars, slightly ahead of it in the zodiac, moving half normal speed.
X  When the values are expressed as absolute speed, it's apparent that
X  the outer planet Pluto always moves much slower than the more inner
X  planet Mars even when Mars is moving half normal speed. This problem
X  is at least not likely to come up much since only explicitly
X  combining -v0 with -ga, -ma, or -D will cause a problem.
X
-w [<rows>]: Display chart in a graphic house wheel format.
X
X  Display of the chart in a nice wheel format is supported using the -w
X  switch. (If one of the houses gets too "full" of planets, the planet
X  will be put at the beginning of the next house.) The same chart
X  header information as is at the top of the standard -v chart is
X  printed in the middle of the wheel. Some information in addition to
X  this is shown, which is: (1) the day of the week that the date falls
X  on, (2) the Universal Time (UT) of the time of the chart being cast
X  (like GMT in the 24 hour clock), (3) the sidereal time for the chart
X  cast, where sidereal time is vaguely similar to UT except 0:00 for it
X  is approximately when 0 Aries crosses the meridian, as opposed to
X  when the Sun crosses the Nadir for UT, (4) whether the zodiac system
X  is set to tropical or sidereal, and whether the planetary positions
X  are geocentric, heliocentric, or centered around some other body, and
X  (5) the Julian day corresponding to the date and time of the chart.
X  This chart will automatically exclude a house object from being
X  listed if its position is the same as the cusp composing the wheel.
X
X  Note that this switch takes an optional parameter to specify the size
X  in text rows of each house printed. By default this is four, but one
X  may increase (realize this will make the chart require more than 24
X  lines to print) or decrease (don't know why you would want to, but
X  you can) this value to their preference. The parameter may range from
X  1 to 10, and with this you can nicely generate a text wheel chart
X  with all 87 objects in it, without overflowing all the houses.
X
-w0 [..]: Like -w but reverse order of objects in houses 4..9.
X
X  In the -w text wheel option, the objects in each house are printed
X  from top to bottom in order from earliest in the house to latest. This
X  looks good except for in houses 5..8 where this would appear backwards
X  (e.g. a planet having just entered the 6th house from the 5th would be
X  displayed right under the Descendant.) Therefore the objects from
X  houses 4 through 9 are reversed and printed in order from bottom to
X  top, making a more flowing looking wheel chart. If however, one always
X  wants each house to be filled from its top to bottom regardless of
X  which house, replace the -w with the -w0 switch
X
-g: Display aspect and midpoint grid among planets.
X
X  Aspects and midpoint display are supported: Invoke as astrolog -g and
X  a rectangular grid showing the midpoint locations for each planet,
X  and showing if any aspects are present and how accurate they are, is
X  displayed. The planets are labeled down the main diagonal of the
X  grid, with the aspects to the lower left and the midpoints in the
X  upper right. This is of course often used along with the -A*
X  switches. Both the aspect orbs and midpoints are displayed to the
X  nearest minute, and on the main diagonal (or edges if a relationship
X  aspect grid) is displayed the sign and degree of the planet in
X  question in addition to the planet name itself.
X
-g0: Like -g but flag aspect configurations (e.g. Yod's) too.
X
X  Search through the aspect grid for major aspect configurations,
X  including Grand Trines, T-Squares, Grand Crosses, Yod's, Cradles, and
X  Stelliums, with the -g0 option. (In a Stellium, three objects must all
X  be conjunct with each other; while in a Cradle, four objects form
X  three sextiles forming a chain of sextiles half way around the
X  zodiac.) This option will produce the same aspect grid that -g
X  displays, but afterwards will go through the grid and list any of
X  these aspect configurations and what objects are forming them. (Of
X  course, to see any Yod's, one has to -A 6 or more so that Inconjuncts
X  will be included in the aspect grid.)
X
-g0: For comparison charts, show midpoints instead of aspects.
X
X  For relationship aspect grids, the -g0 switch will display a midpoint
X  grid instead of an aspect grid between the planets in the two charts
X  e.g. "-r0 chart1 chart2 -g0". (See later for descriptions of the
X  relationship charts.)
X
-ga: Like -g but indicate applying instead of difference orbs.
X
X  Ability to determine whether an aspect is applying or separating (is
X  about to happen or just happened) is included in the -g option.
X  Normally the aspect orbs are flagged as being '+' or '-' based on
X  whether they are greater or less than the exact amount (e.g. a 91
X  degree Square has a +1 degree orb while a 89 degree one a -1 orb.) If
X  one, however, invokes the -g option as -ga instead, an orb printed as
X  'a' will indicate an applying aspect while an orb with 's' a
X  separating one. (To estimate applying vs. separating, the program
X  examines the planetary positions and their relative velocities at the
X  time in question.)
X
-gp: Like -g but generate parallel and contraparallel aspects.
X
X  Astrolog can do parallel and contraparallel aspects. Two planets are
X  parallel when they have the same declination with respect to the
X  equator, and are contraparallel when their declinations are the same
X  amount but on opposite sides of the equatorial plane. The -gp switch
X  will turn on the aspect grid just like the -g option, but will also
X  set it so the grid contains parallel and contraparallel instead of
X  normal aspects. This feature works for the -g aspect and relationship
X  aspect grids, and the graphics versions of them. The graphic glyph
X  for the parallel aspect is two vertical parallel lines, while the
X  glyph for contraparallel are two sets of two lines crossing each
X  other, like a tic-tac-toe grid. In -gp affected charts, the parallel
X  takes the place of conjunction, and contraparallel the place of
X  opposition; all aspect orb settings affecting conjunction and
X  opposition will affect the -gp aspects in the same way. (Note that
X  the best orb for parallel aspects is only a degree or so, hence the
X  default conjunction orb will likely be too high, and should be
X  decreased with the -Ao switch for -gp grids.) The -A and -RA aspect
X  selection switches will also affect -gp, but all aspects beyond the
X  first two are ignored as only the parallel and the contraparallel
X  aspect are considered.
X
-a: Display list of all aspects ordered by influence.
X
X  Aspects may be displayed in a nice ordered list, instead of only in
X  the -g aspect grid. Use the -a switch and get a list of every aspect
X  from the aspect grid printed out one per line. The order in which
X  they are printed is based on the total "power" in the aspect, i.e.
X  the influence of the two planets in question, the aspect in question,
X  and the orb. The same info and data from the -j influence charts (see
X  later) are used here, so changing any default influences there will
X  affect this ordering. The two planets are printed, the aspect they
X  make, their orb, and then the power of the aspect used in ordering.
X  Any power number more than 10 is a very major aspect. An exact Sun
X  Moon conjunction can exceed 25. So, if you want to know, say, if that
X  exact Mars Jupiter conjunction is more powerful than that wide Sun
X  Moon sextile, try a -a chart and find out what Astrolog's opinion is.
X
-a0: Like -a but display aspect summary too.
X
X  This is just like the -a aspect list ordered by influence chart,
X  except that summary information will be displayed afterward. The sum
X  of all the aspect powers and their average is printed, the total
X  number of aspects of each type is printed, and the total number of
X  aspects to each planet is printed.
X
-a[0]a: Like -a but indicate applying and separating orbs.
X
X  This is a shorthand way to bring up the -a or -a0 sorted aspect
X  chart, with the aspect orbs shown as applying or separating, instead
X  of positive or negative offsets to the exact aspect size. This is
X  like how -ga does the same thing with the -g aspect grid switch. (To
X  get the functionality of -aa without this, one can use the -ga switch
X  itself along with -a, and then include -g by itself again, e.g. "-a
X  -ga -g", to toggle the aspect grid back off but leave the applying
X  vs. separating setting on!)
X
-a[0]p: Like -a but do parallel and contraparallel aspects.
X
X  The -a aspect list can be made to list all parallel and
X  contraparallel aspects if invoked as -ap or -a0p, turning on the same
X  flag as the -gp switch above. When in effect, the parallel aspect
X  setting will also affect -D and -T transit influence charts, having
X  them show their aspects in parallel too.
X
-m: Display all object midpoints in sorted zodiac order.
X
X  True midpoint charts are supported in addition to the midpoints that
X  can be seen in the -g aspect grid. Use the -m switch and get a list
X  of all midpoints printed out sorted in zodiac order. This will show
X  both the actual midpoint location, as well as the angular difference
X  between the two objects displayed to the nearest minute. So if you
X  want to see, say, if any important midpoint is close to your Sun,
X  this is a much easier chart to use than scrutinizing the
X  midpoint/aspect grid.
X
-m0: Like -m but display midpoint summary too.
X
X  This is just like the -m midpoint list ordered by zodiac position
X  chart, except that summary information for it will be displayed
X  afterward. The average number of degrees spanned between each planet
X  pair is printed, and the total number of midpoints in each zodiac
X  sign is printed.
X
-ma: Like -m but show aspects from midpoints to planets as well.
X
X  Aspects to midpoints are supported with the -ma switch. This feature
X  will do the same as the -m midpoint list chart, except in addition to
X  listing each midpoint, a sublist of each aspect in effect from a
X  natal planet to the position of that midpoint, will be shown after
X  it. The orb of the aspect will be printed too, where the orb will be
X  shown as either wide or narrow, or applying or separating, based on
X  the value of the -ga or -aa applying aspects setting.
X
-Z: Display planet locations with respect to the local horizon.
X
X  The text display switch -Z prints out where each object is on the
X  local horizon in terms of altitude and azimuth. For each object, the
X  following is displayed: Its altitude on the local horizon from +90
X  degrees (straight up) to -90 degrees (straight down), and its azimuth
X  from 0..360 degrees, where 0 = due east, 90 = north, 180 = west, 270 =
X  south. To make visualizing the azimuth easier, an "azimuth vector"
X  with a N/S component and a W/E component is displayed, e.g. (1.00s
X  0.33w) means that the object is mainly south, with its true angle
X  being formed by an vector component west that's 1/3 the strength of
X  the south component, i.e. the object is about 18 degrees west of
X  south. This along with the altitude should make it easy to physically
X  point to where any planet is at any moment, making it easy to locate
X  planets in the night sky. This feature can also be used to determine
X  the times that a planet rises and sets. Also displayed are altitude
X  and azimuth differences between each object and the Sun and Moon,
X  first showing the number of degrees that the Sun/Moon is "ahead" (or
X  farther east in the zodiac) of the object in question, and then the
X  number of degrees that the Sun/Moon is above the object in question.
X  This feature can be used to roughly predict eclipses! Both the Sun and
X  Moon span about 0.5 degrees in the sky, therefore if both the azimuth
X  and altitude differences are < 0.5 (or 1.0 if the difference is
X  between the Sun and Moon themselves) then the object in question is
X  probably being occulted somewhat by the Sun/Moon. Note that there are
X  three types of planetary position displays: Right ascension and
X  declination showing the object's position with respect to the stars,
X  longitude and latitude showing where on the Earth the object is
X  straight up (as in the astro-graph zenith locations), and finally
X  azimuth and altitude showing the positions of the object relative to
X  the local horizon.
X
-Z0: Like -Z but express coordinates relative to polar center.
X
X  This will do a text chart just like the -Z local horizon switch above
X  except that it will print the location of each planet in prime
X  vertical coordinates, instead of altitude and azimuth. Prime vertical
X  coordinates are measured with its "azimuth" around the 360 degree
X  circle, with 0 degrees due east on the local horizon, going down with
X  90 degrees straight down, 180 degrees due west and so on; declination
X  "altitudes" are measured with positive values toward the north and
X  negative toward the south.
X
-Zd: Search day for object local rising and setting times.
X
X  One can display the rising and setting times of the Sun, Moon, and
X  planets with this feature. Specifically, when this switch is
X  included, the program will, for the entire day specified in the chart
X  information, display whenever a planet rises (specifically conjuncts
X  the local horizon while in the eastern hemisphere), sets (conjuncts
X  horizon in west), reaches its zenith point (or specifically conjuncts
X  the meridian while in the southern hemisphere, i.e. is due south from
X  the observer), and reaches its nadir point (conjuncts meridian in
X  north). Note that some stars may be high or low enough that they will
X  never rise or set, but instead will just "zenith" or "nadir" twice in
X  a day as they spin around the pole.
X
-S: Display x,y,z coordinate positions of planets in space.
X
X  Solar system space based charts are available with the -S switch,
X  which give the astronomical positions of each planet in terms of x, y,
X  and z coordinates. Although not directly useful astrologically, it
X  does give one a good view of how the planets actually were positioned
X  at the time in question. For example, normal astrology doesn't make
X  the distinction between the four different "forms" of say, a Mercury
X  Venus Conjunction, i.e. they can either be Conjunct on the near side
X  of the Sun, Conjunct on the far side of the Sun, or one can be on one
X  side and the other on the other side. When the chart is actually
X  displayed, for each body the following information is printed: The
X  relative angle of the planet with respect to the central body, i.e.
X  its zodiac position converted to the appropriate number from 0..360.
X  This is followed by the x, y, and z coordinate positions of the
X  object, in astronomical units from the central body. The x-axis
X  increases in the direction of 0 degrees Aries (tropical zodiac), the
X  y-axis increases in the direction of 0 degrees Cancer, and the z-axis
X  is with respect to the Earth's orbit (meaning that the Sun and Earth
X  always have a z-axis value of 0.0). Finally the overall length from
X  the central body in AU is printed, which is just the diagonal as
X  indicated by the x, y, z vectors. (The Earth and Sun are of course
X  always about 1.0 AU from each other.) The Moon circles the Earth and
X  isn't a part of the solar system proper; therefore, it is never in
X  these charts. The -e everything option will include this chart in its
X  listing of all the chart displays. (Note that the Earth doesn't have
X  a formal object index of its own. Hence there's no real way to
X  directly restrict it from these -S space charts either in text or
X  graphics format. Only the -R0 (and -R1) restrict everything switches
X  will affect this body, as they do all the others.)
X
-l: Display Gauquelin sectors for each planet in chart.
X
X  Astrolog supports Gauquelin sector charts. These are based on the
X  work of Michael Gauquelin, with a sector chart basically a type of
X  wheel chart where the planets are placed in their appropriate
X  Gauquelin sector instead of zodiac sign at a given time. Sectors are
X  numbered from 1 to 36, and indicate proportions of time between
X  rising and setting. Sectors 1 through 18 are above the horizon, and
X  19 through 36 are below. When a planet rises it goes from sector 36
X  to 1, when 1/18th of the time until the moment it sets has passed it
X  enters sector 2, and so on. A sector chart can be thought of as
X  somewhat related to a standard wheel chart, except that it's "time
X  based" instead of "location based". In interpretation, certain
X  sectors are known to be powerful. These sectors are called plus zones
X  and are the sectors immediately before and a bit after the four
X  angles. For a more detailed account on interpretation, see books such
X  as Gauquelin's "Cosmic Influences on Human Behavior". To bring up a
X  sector chart, use the -l command switch.
X
X  The text mode version of this chart is similar to the standard -v
X  listing. The chart info time and place will be displayed, after
X  which, for each planet, the sector it's in will be displayed, with a
X  "+" indicating a plus zone, and a "-" indicating such is not the case
X  (where with colored text active plus zones will be in red and minus
X  dark green). Then as in the standard listing, the planet's house,
X  zodiac location, retrogradation status, equatorial latitude, and
X  velocity will be printed. Finally will be displayed two alternative
X  sector locations assuming systems where sectors go from 1 to 18, and
X  from 1 to 12 (where for example the beginning of sector 36 will map
X  to sector location 18.5, and 12.75, respectively). After this,
X  summary information will be displayed. The number and percentage of
X  planets that fall in plus zones (as well as the number and percentage
X  of plus zones period) will be printed, and for each of the 36
X  sectors, the number of planets that fall in it and whether it's a
X  plus zone will be indicated.
X
-l0: Like -l but approximate sectors using Placidus cusps.
X
X  Calculating correct Gauquelin sector positions is based on rising and
X  setting times, which require searches, hence computing the chart
X  takes quite a bit longer than regular wheels. It's like the -Zd
X  rising and setting list, where increasing the -d searching divisions
X  value increases the accuracy and calculation time here too. To cut
X  calculation time down to that of ordinary charts, one may do a
X  reasonable approximation of sector positions based on how far each
X  planet has progressed through a corresponding house (specifically
X  house cusps divided using Placidus). To compute charts in this fast
X  manner, invoke the -l switch as -l0.
X
-j: Display astrological influences of each object in chart.
X
X  Another chart type is available - interpretation of influences. This
X  is the simplest part of the general interpretation ability of the
X  program. What this part does is calculate the relative "power" of each
X  planet's placement, giving a general idea of the prominent areas of a
X  chart. When such a chart is printed, each planet is given a point
X  value, larger numbers indicating more strength. Each planet's strength
X  is divided between two fields: the positioning in and of itself, and
X  the power of the aspects it makes with the other planets. In addition
X  to each field, the total of these two areas is printed, as well as the
X  relative percentage of the planet in question with respect to all the
X  planets combined. Each planet gets a ranking for its positioning,
X  aspects, and total power as well, with the strongest getting #1, the
X  next strongest #2, etc. The -e option will include this chart along
X  with all the others as well in it's listing of all the chart displays.
X
X  To determine the strength of the positioning of a planet, various
X  things are taken into account: 1) The power of a planet in and of
X  itself, e.g. the Sun and Moon are more powerful then the other
X  planets. 2) The house placement of a planet, e.g. a planet in the 1st
X  house is more powerful than one in the 2nd. 3) Whether a planet is in
X  the sign it rules or is exalted in, e.g. Jupiter in Sag results in
X  more power to Jupiter. 4) Whether a planet is in the house
X  corresponding to the sign it rules or is exalted in, e.g. Jupiter in
X  the 9th house. 5) Planets get more power if the signs they rule are
X  occupied, e.g. a bunch of stuff in Aquarius gives more power to
X  Uranus. 6) Planets get more power if the houses they rule are
X  occupied, e.g. a bunch of stuff in the 11th house gives power to
X  Uranus. 7) Finally, planets get power according to what houses the
X  cusps of which fall in the signs they rule, i.e. the ruler of the
X  Ascendant (and to less extent the Midheaven, and so on) gets lots of
X  influence. Determining the strength of a planet's aspects is much
X  easier, and is basically composed of the sum of the strength of each
X  aspect the planet makes. Taken into account are: 1) The influence of
X  the planet being aspected to, e.g. Sun conjunct Jupiter gives more
X  influence to Jupiter than Mercury conjunct Jupiter would. The
X  planet's placement as described above plays a role, too, e.g. Venus
X  opposition Mars in Aries gives more influence to Venus that it would
X  be if Mars were in Taurus. 2) The influence of the aspect itself,
X  e.g. Oppositions are more powerful then Sextiles. 3) Finally the orb
X  of the aspect, i.e. exact aspects are more powerful than wide ones.
X  (The influence of the orb varies linearly from max power at exact to
X  zero power at the limit of the orb - sorry Maggie M. and Mark K. - no
X  complex aspect wave functions, at least for this version :)
X
X  Special thanks goes to Mark K. who initially presented this idea of
X  interpreting overall influences to me. I basically just took his
X  ideas, polished them a bit, and put it into the code. Interestingly,
X  while programming this feature, I had a dream about him, in which he
X  elaborated upon some of the ideas and even gave me suggestions for
X  some of the planets' default power values (astral visitation?) And,
X  while on the subject, I've had a couple of other Astrolog dreams; I
X  had one neat one while working on the -h feature (described later)
X  about a far distant future version of Astrolog that could actually
X  teleport one to the places which they cast charts for :)
X
-j0: Like -j but include influences of each zodiac sign as well.
X
X  The -j planet influences in a chart feature can be expanded to
X  include signs as well. Invoke it as -j0 instead of just -j, and in
X  addition to getting the influence of each planet in a chart, one will
X  get the influence of each sign in the chart as well. To determine
X  sign influence, we use the planet powers already determined; a sign
X  gets influence if: (1) There is a planet in it, (2) there is a planet
X  in the house it corresponds to, and (3) if any planet that rules or
X  co-rules it is in the chart. For example, with my 11th house Venus in
X  Sagittarius, for me: (1) Sagittarius gets more power because Venus is
X  in it, (2) Aquarius gets more power because Venus is in the 11th, and
X  (3) Libra and Taurus get power because Venus itself rules these
X  signs. The exact power given is based on the total influence of Venus
X  already determined. Any sign that has over about 175 points or 20% of
X  the total is a really powerful and a fundamental part of the psyche.
X  We also sum up the influences of all the signs (which will logically
X  total up to the sum of all the planets), and display the influence of
X  each element as well, and each mode as well, all this being perhaps a
X  more accurate version of the element table in the -v chart.
X
-L [<step>]: Display astro-graph locations of planetary angles.
X
X  The '-L' option will take the standard chart information and generate
X  the astro-graph positions of the planets. In other words, this does
X  the exact same thing that Jim Lewis' Astro*Carto*Graphy maps do. It
X  will display the longitude of where on the Earth at the time in
X  question each object was on the midheaven and on the nadir, and the
X  latitude of where the planets actually appeared at zenith. Also, for
X  latitude increments of 5 degrees, the longitude of where the objects
X  appeared on the ascendant and descendant is displayed. For text
X  screens, one can pass an optional parameter to this -L (or -L0) option
X  to change the default latitude step rate at which the Ascendant and
X  Descendant lines are computed. Again, this value is by default 5
X  degrees, although one can may increase or decrease it to any integer
X  (subject to the restriction that the number 160 is divisible by it.)
X
-L0 [..]: Like -L but display list of latitude crossings too.
X
X  Determination of latitude crossing points is included in the
X  astro-graph routines! The -L0 option will do the same thing as the -L
X  option, except that after displaying the longitude and latitude
X  locations of the Asc/Desc/MC/IC lines, it will then search among the
X  lines and display (in order from farthest North to farthest South) the
X  latitude of any points where lines cross each other. This includes the
X  curvy Asc/Desc lines crossing the straight MC/IC lines as well as
X  cases where different Asc/Desc lines cross themselves. And unlike Jim
X  Lewis' Astro*Carto*Graphy, Astrolog will also display the longitude of
X  the crossing (useful for Asc/Desc crossings) in addition to the
X  latitude (as well allowing more planetary bodies to be included in the
X  scan, and going farther North and South than Jim Lewis' printouts go.)
X  Note however, that there is presently a small (very rare) minor
X  omission glitch in the code, where if a crossing is within a couple of
X  degrees of 180 deg W/E, it may not be displayed.
X
-K: Display a calendar for given month.
X
X  The -K switch generates a simple calendar for the month specified in
X  the current chart. This is a standard type of chart generatable from
X  a date so the -e everything switch includes this -K chart along with
X  all the others. Note that this is technically a non-astrological
X  chart, but generic calendars are useful and easy to generate with all
X  of Astrolog's date determination features, so the option to create
X  them using Astrolog is included. The calendars are compact, with one
X  text row per week. The day specified in the current chart will be
X  highlighted in green assuming -k Ansi color is active, e.g. "-n -K"
X  will generate a chart for this month, with the number of today's date
X  highlighted.
X
-Ky: Like -K but display a calendar for the entire year.
X
X  The -Ky switch is just like -K except that it will generate a
X  calendar for the whole year. All twelve months will be displayed on
X  the screen, each just like the individual monthly calendars above but
X  printed in four rows of three months each.
X
-d [<step>]: Print all aspects and changes occurring in a day.
X
X  The -d option will take the standard chart information, and for the
X  day in question, display the exact times of all aspects that occur.
X  This is just like the aspects-per-day as displayed in Jim Maynard's
X  Celestial Guide books. (Displayed in local time as defined by the
X  default zone, with accuracy based on the searching divisions setting,
X  described below.) This will tell any time two planets make aspects
X  with each other, a planet changes its sign, or a planet goes
X  retrograde or direct. Both the -d (and -t listed later) options will
X  display the signs that any planets aspecting each other are in, in
X  addition to the aspect itself (e.g. instead of just "Jupiter Trine
X  Uranus", we have "Jupiter (Vir) Tri (Cap) Uranus". If a particular
X  object is going retrograde, then its sign will be displayed in
X  brackets instead of parentheses, and if an object is about to or has
X  just gone retrograde or direct, then its sign will be in <>'s.
X
X  This switch accepts an optional accuracy parameter, a value which
X  tells how many "segments" we should divide each day or whatever, when
X  doing these aspect searches. More segments is slower but can be more
X  accurate by a few minutes. This command line change of the step rate
X  can also be done for other charts such as the -t transit search by
X  using the switch toggle feature to turn -d off but still leave the
X  divisions value set, e.g. "-d 100 -d -t" will set the value to 100
X  but not actually display the -d chart. Or better yet just use the
X  colon switch prefix to not affect the -d setting at all, e.g. ":d 100
X  -t". In general, I suggest this value be set to 24 for Unix systems
X  and 8 for PC's, but it is easy to experiment to see what is best for
X  the speed of your computer. One may increase this value up to 2880
X  (if they don't mind the wait) which will mean a chart every 30
X  seconds for -d aspect in day charts and one every 15 minutes for -t
X  transit search charts.
X
-dm: Like -d but print all aspects for the entire month.
X
X  The -d option can search the entire month for aspects between planets
X  if one so desires. Specifying it as -dm instead of just -d will go
X  through the entire month instead of just the current day. (Combining
X  this one with -R allows searching for important aspects, sign
X  changes, etc.)
X
-dy: Like -d but print all aspects for the entire year.
X
X  The -d option can search the entire given year for events as well, if
X  it's specified as -dy instead of just -d or -dm.
X
-dY <years>: Like -d but search within a number of years.
X
X  The -d search may also do a range of years all at once. Invoke the
X  switch as -dY, and give a parameter indicating the number of years to
X  span, and it will be done, starting with the year in the current
X  chart. For example, to display the times of all New and Full moons
X  for the rest of the century (1998 through 2000), do "astrolog -n -dY
X  3 -R0 sun moo -A opp". (This is similar to the -EY and -tY features
X  which also allow doing a range of years in addition to a single year
X  or month.)
X
-dp <month> <year>: Print aspects within progressed chart.
X
X  Another progression feature allows determining aspect times of
X  progressed planets among themselves. The -dp <month> <year> switch
X  will, like the -d option, display times of aspects and sign changes,
X  for the time around the chart in question, except that they will be
X  progressed throughout the month specified. Progressed planets move
X  very slowly ("year for a day") so therefore there will usually be, if
X  any, only a couple of aspects in a given month. Also, since they move
X  so slow, the accuracy is cut down, so the dates given are probably
X  only accurate about to the nearest day, in spite of the times given
X  to the minute. Note that Astrolog can scan for aspects of: transiting
X  planets among themselves (-d switch), transiting planets to natal
X  planets (-T switch), progressed planets to natal planets (-Tp), and
X  progressed planets among themselves (-dp). Only thing Astrolog can't
X  directly do is do progressed planets to transiting planets, although
X  that may change in a future version :)
X
-dpy <year>: Like -dp but search for aspects within entire year.
X
X  Since progressed planets move so slow and only a few aspects in a
X  progressed chart will appear each month, one might want to instead
X  scan the whole year. To do this, use the -dpy switch, which takes
X  only one parameter for the year. This switch is consistent in format
X  to how with the -T and -E switches one specifies an entire year.
X
-dpY <year> <years>: Like -dp but search within number of years.
X
X  Related to above, the -dp option may also be done for a range of
X  years. Invoke the switch as -dpY, and pass in not only the year to
X  search within as with -dpy, but the number of years to scan from
X  then. For example, do display the times of all aspects within your
X  progressed chart for the next decade, do "astrolog -i yourchartfile
X  -dpY 1998 10".
X
-dp[y]n: Search for progressed aspects in current month/year.
X
X  The -dp progression event search option can be invoked as -dpn to
X  search the current month, or -dpyn to search the entire current year.
X  For example, if I want to search for the exact times of all aspects
X  in my natal chart, progressed to any time this month, I simply do "-i
X  mychartfile -dpn".
X
-D: Like -d but display aspects by influence instead of time.
X
X  This switch will display a chart listing all aspects in effect within
X  the chart in question, in order by influence based on their power
X  when transiting. This chart focuses upon and gives precedence to
X  aspects of outer planets with each other, as opposed to common inner
X  planet configurations. For example, at the time in early January
X  1994 the most influential aspects in effect were the Uranus Neptune
X  conjunction and the Saturn Pluto square. This chart is very much like
X  the format of the -a aspect list chart, except that we are using the
X  transit as opposed to natal influences of the planets. The -a chart
X  is most appropriate for a person's natal chart, in that the inner
X  planets are focused upon, such as a Sun Moon square will be near the
X  top of the list. This -D chart is more appropriate for times as
X  opposed to people, since it focuses upon rare outer planet
X  configurations. This chart is also very similar to the -T transit
X  influence chart, in that it shows the aspect, applying or separating
X  orb, and power of the event with its present orb, except that this
X  does influences of transiting planets among themselves as opposed to
X  aspects to a natal chart. If you want to see what major events are
X  coming up, and don't want things such as Uranus Neptune conjunctions
X  to "sneak by", use this chart and watch the configuration gradually
X  rise to the top of the list as its orb narrows over time. This chart
X  may be combined with others and is included in the -e everything switch.
X
-E: Display planetary ephemeris for given month.
X
X  The -E option will generate a quick ephemeris of the planet positions
X  each day for the month indicated in the given chart, as taken from
X  the standard interface. This is useful if you just want to see an
X  overview of what's happening some month in the sky. Any dots after a
X  planet location in the list indicate the planet was retrograde at the
X  time that day. For example, to see the ephemeris for someone's birth
X  month, one can do the convenient "-i chartfile -E", or to see the
X  ephemeris for this month, do "-n -E" (see -i and -n options later).
X  The -E text ephemeris switch may be combined with the -gp or -ap
X  parallel aspects feature to generate an ephemeris of ecliptic
X  latitudes (or equatorial declinations if the -sr flag is in effect)
X  instead of the normal zodiac longitudes.
X
X  Note: The ephemeris listings obtain the time (and time zone) to cast
X  each day's chart for (e.g. noon, midnight) from the chart information
X  given it, instead of always defaulting to something like midnight in
X  the default time zone. This is a bit more flexible since one may want
X  to specify a noon or 6:00am or whatever ephemeris which wouldn't be
X  possible otherwise. The -qm <month> <year> switch (see later) always
X  uses midnight for the time and the default for the time zone, so when
X  using this switch with -E, the results will be a midnight ephemeris
X  in this default zone. However, something like -i yourchart -E to do
X  an ephemeris for your birth month will display the positions each day
X  at your birthtime instead of at midnight.
X
-Ey: Display planetary ephemeris for the entire year.
X
X  To display an ephemeris for all twelve months in an entire year,
X  invoke the -E switch as -Ey. For example, to get an ephemeris for
X  all of last year, one can do "-qy 1995 -Ey" (see -qy and -qm options
X  below).
X
-EY <years>: Display planetary ephemeris for a number of years.
X
X  The -E ephemeris list feature may also do an ephemeris for a range of
X  years all at once. Invoke the switch as -EY, and pass a parameter
X  indicating the number of years to span with the ephemeris, and it
X  will be done, starting with the year in the current chart. For
X  example, to do an ephemeris for all this century from 1900 through
X  1999, do "astrolog -qy 1900 -EY 100".
X
-e: Print all charts together (i.e. -v-w-g0-a-m-Z-S-j0-L0-K-d-D-E).
X
X  There are thirteen main different formats of chart display available:
X  The standard listing of planet positions which you get without any
X  switches or with the -v option, the house wheel you get with -w, the
X  aspect/midpoint grid you get with -g, and the charts generated with
X  the -a, -m, -Z, -S, -j, -L, -K, -d, -D, and -E switches. The -e
X  "everything" option will display the chart in all thirteen of these
X  formats for about 1200 lines and 75K bytes of text! Note that one can
X  even include the -t and/or -T transit options below and include yet a
X  couple more chart formats in the list (however transits require a
X  time parameter to do transits for so they aren't really a single
X  chart display and hence aren't included in -e by default).
X
-t <month> <year>: Compute all transits to natal planets in month.
X
X  The '-t <month> <year>' option will scan the entire month specified,
X  and print out any transits that happen, in that month, to the planet
X  positions as listed in the current chart as taken from the standard
X  interface. There will be often be quite a few events, even though
X  fast moving objects like the Moon aren't looked at by default (unless
X  specified in the default parameter file or with the -RT switch), so
X  you might want to use this with the -R option to limit this to just
X  certain planets. The times are displayed in the local time zone, and
X  are generally accurate to within a half hour or so, where accuracy
X  can be increased by upping the value in the -d searching divisions
X  setting; try doing it for your birth month and your own chart - all
X  planets should conjunct their natal positions at about the time of
X  your birth. To determine transits to natal house cusps other than the
X  Asc and MC, i.e. when does a planet change house in your natal chart,
X  include the -C switch described elsewhere. See the -RT option, as
X  well as the -YC "smart cusps" default, described later, for options
X  which directly affect this feature.
X
X  Note that even transiting house cusps (and other fast moving objects
X  like the Part of Fortune, Vertex, and East Point) may be included in
X  these transit to natal searches. (To activate transiting cusp objects
X  use the -RT switch.) This allows one to determine the time of events
X  such as when the Ascendant today conjuncts your natal Sun. Note that
X  as the house cusps travel through all 360 degrees of the zodiac
X  during the day, a cusp will make a transit roughly 30 times as often
X  as even the fast moving Moon, the Moon itself making transits 12
X  times as often as planets like the Sun. So realize you may get a
X  flood of information, and hence probably do want to restrict all
X  planets and aspects you're not interested in. Note also that to get
X  accurate times for transiting cusp events, you probably want a high
X  value for the -d searching divisions setting (I recommend at least
X  200) which means longer calculations.
X
-tp <month> <year>: Compute progressions to natal in month for chart.
X
X  Determining dates of transits of progressed planets to natal planets
X  can be done with the -tp <month> <year> option. This is just like the
X  -t option, except that the exact aspects of progressed planets
X  (rather than transiting planets) to the planets in the chart are
X  displayed. Progressions occur much less often than transits, and
X  there will only be a few, if any, in a given month, so one might to
X  invoke this as -Tpy, as described below.
X
-tr <month> <year>: Compute all returns in month for chart.
X
X  This switch is a quick and convenient way to compute solar, lunar,
X  and other returns. As a return is when a transiting object conjuncts
X  its natal position, returns are findable using the generic -t transit
X  to natal search. However to only display returns with it and not
X  every transit, one has to restrict aspects to just the conjunction,
X  and restrict objects to just the one you're interested in. (But even
X  that will still show things in addition to returns if more than one
X  object is unrestricted, e.g. with just Sun and Moon you'll still get
X  Sun to Moon conjunctions and vice-versa.) The solution is this return
X  feature, which (without altering your aspect or object restrictions
X  any) works just like the -t switch, but displays only returns in the
X  transit list, i.e. conjunctions between a transiting planet and that
X  same planet in the natal chart.
X
-t[p]y: <year>: Compute transits/progressions for entire year.
X
X  To display transits for an entire year, invoke the -t switch as -ty
X  (-tpy for progressions), which only takes one parameter, the year.
X  For example, "-i chartfile -ty 1998".
X
-t[p]Y: <year> <years>: Compute transits for a number of years.
X
X  One may also search an arbitrary number of years at once for
X  transits. One uses the -tY <year> <years> switch like the -ty <year>
X  switch above, except that -tY takes an extra parameter for how many
X  years to search. For example, -tY 1998 10 will search the ten years
X  from 1998 through 2007 for whatever transits. With a negative value
X  for the years to scan, it will start that many years before the given
X  year, e.g. -tY 1998 -10000 will scan the previous 100 centuries for
X  transits, starting with 8002 B.C.! Note that this switch may also be
X  invoked as "-tYn <years>", in which case it will start from the
X  current year and be an equivalent shorthand to "-tY 1998 <years>" for
X  this year at least.
X
-t[py]n: Compute transits to natal planets for current time now.
X
X  This feature is a quick shorthand way to generate transits for the
X  current month. For example, instead of "astrolog -i chartfile -t 4
X  1998", one can do "astrolog -i chartfile -tn". To do transits for the
X  entire current year, invoke it as "-tyn".
X
-T <month> <day> <year>: Display transits ordered by influence.
X
X  The -T switch is a transit influence chart. Given a date, it will
X  take the transiting planets on that date, and determine how they
X  interact with the generic natal chart specified with -i or however.
X  The information will be printed as a list of transits, sorted in
X  order from most significant to least significant. For each transit in
X  effect, the transiting and natal planets (and the signs they are in)
X  are displayed, along with the aspect and the orb, and whether the
X  transit is applying and going to happen in the future, or just passed
X  exactness and the orb is separating. The computer computed power
X  value of each transit will be printed too - anything over 100 is a
X  very major transit. Any transit that's a return, i.e. a transiting
X  planet conjuncting the same one in the natal chart, will be flagged
X  with a capital "R" at the end of the line.
X
X  The things which affect how Astrolog computes the influence of a
X  transit are: The power of the object that's doing the transit, e.g.
X  transiting Pluto conjunct your natal Ascendant is much more powerful
X  than the transiting Moon conjunct your Ascendant. The power of the
X  object being transited affects the power too (but not as much as the
X  transiter) e.g. Jupiter transiting your Sun is more powerful than
X  Jupiter transiting an asteroid. Finally, the orb plays a role as
X  well, in that a transit that will be exact in a couple of days from
X  the given date passed to -y is more powerful than one won't be exact
X  for another month. Note that the power of a planet when transiting is
X  different than its influence in the natal chart: Although Sun
X  conjunct Moon is more powerful in a natal chart than Saturn conjunct
X  Moon, when transiting, Saturn transiting Moon is much more
X  influential than Sun transiting Moon. Hence there are two lists of
X  object influence values in the astrolog.dat file (described later)
X  that can be customized. There's the generic list of standard
X  influences (which have items like Sun, Moon, and Ascendant most
X  powerful), and a parallel list of transit influences (which have the
X  slower moving bodies the most powerful).
X
X  Related to the -tr switch above, the -T switch can be invoked as -Tr,
X  which is the same as the general transit influence chart, but will
X  only display aspects between a transiting planet and the same natal
X  planet. (Note unlike -tr it will include aspects other than the
X  conjunction.)
X
X  This switch is in compliment to the -t transit search list, and you
X  may find this one more useful. The -t chart prints the times when
X  a transit is exact, which is useful to know, but doesn't really help
X  when you want to know when a transit enters orb enough to be
X  significant, and it won't flag a major year long transit that will be
X  exact next month, listing it among a bunch of less significant
X  aspects for the following month. With -T, you can see a major transit
X  first enter orb at the bottom of the list, and then slowly rise to
X  the top as it becomes more exact through the days. And you can answer
X  the question as to which is more influential: say an exact transit of
X  Mars to a minor house cusp, or a major transit of Saturn to an angle
X  that's still a month away from exactness.
X
X  Also notice the resemblance between -T and the -r0 -a combination.
X  Both display aspects ordered by influence. In fact, "-i chart -Tn"
X  will look almost identical to "-y chart -a", except that -T is
X  designed and formated for doing transits to a particular chart.
X  (Doing -T will always use applying vs. separating orbs, generate
X  powers using the transit influences, and allow the transiting and
X  natal planets to be restricted separately with -RT and -R.) Astrolog
X  allows transit charts to be done between transiting planets and natal
X  planets, as well as charts among transiting planets to themselves,
X  both of which can be expressed as searches for exact times, or
X  displays of influences of each aspect at a particular time, as
X  summarized in the following organized list:
X
X  o -t switch: Display exact times of transits to natal planets.
X  o -T switch: Display influences  of transits to natal planets.
X  o -d switch: Display exact times of aspects among transiting planets.
X  o -D switch: Display influences  of aspects among transiting planets.
X
-Tp <month> <day> <year>: Print progressions instead of transits.
X
X  The -T transit influence switch can also (like the -t transit search)
X  display all aspects between progressed planets and natal planets in
X  influence order, if it's invoked as -Tp instead of just -T. This
X  works like -T in every way except that a switch combination like "-i
X  mychart -Tp 4 30 1998" will display aspects between my natal planets,
X  and those in my natal chart progressed to the end of the month, and
X  their influence and orbs at that time, instead of between my natal
X  planets and the actual positions of the planets at the end of March.
X
-T[p]n: Display transits ordered by influence for current date.
X
X  The -Tn switch is a shorthand way to pass the current date today and
X  time now to the -T switch. If you want to see what transits are most
X  affecting your natal chart presently, just do "-i yourchart -Tn".
X
-P [<parts>]: Display list of Arabic parts and their positions.
X
X  Astrolog has the ability to display the positions of 177 Arabic
X  parts! The "ARABIC" compile time option in astrolog.h may be
X  commented to leave this feature out if you don't want it. Display a
X  chart with the -P switch to show each part and its position, one per
X  line for the chart in question. The listing contains five columns:
X  First is the full name of the part, i.e. the part of whatever. Second
X  is its position in the zodiac (which will be shown to the nearest arc
X  second when the -b0 setting is active). Third is the house the
X  location falls in.
X
X  Fourth is the formula used to compute the part, given so one knows
X  what the program is doing and to aid in interpretation. The formula
X  is expressed in the form <term1> - <term2> + <term3>. Also included
X  is a flag indicating whether the formula should be flipped for night
X  births, i.e. charts where the Sun is below the horizon in houses 1
X  through 6. For night charts where the flip status is "Y", the real
X  calculation done is <term1> + <term2> - <term3>. Each <term> consists
X  of an "object" plus a "modifier". The object is usually given as the
X  abbreviation of a planet, or it may be a number from 1 to 12
X  indicating that house cusp. The object may also be "For" or "Spi"
X  meaning it's the position of the Part of Fortune or Part of Spirit,
X  or it may reference an actual degree in the zodiac. The modifier
X  indicates how to get the actual position of the term from the object.
X  It's usually blank meaning the term is just the position of the
X  object. It may be "H", meaning the term is the location of the house
X  the given object is in; it may also be "R", meaning the term is the
X  location of the planet ruling the house the given object is in; it
X  may be "D", meaning the term is the location of the planet that's the
X  dispositor of the given object, i.e. ruler of its position; or it may
X  be "&", meaning the term is 10 degrees beyond the position of the
X  given object.
X
X  The last column is the "type" of Arabic part. Most parts are normal
X  psychological indicators like the Part of Fortune, and don't have
X  anything listed here. Seven parts reference elements and weather and
X  are used for charts cast at the time of equinoxes, solstices, and New
X  and Full moons, and are indicated by "Evnt". 21 parts reference crops
X  and are parts used in the commodities market for prognostication, and
X  are indicated by "Comm". Finally 16 parts are specially used for
X  Horary questions and are indicated by "Hora".
X
X  The -P switch accepts an optional parameter to indicate how many of
X  the Arabic parts to show. When given, only the first 'n' parts will
X  be displayed. As the special part types are shown after all the
X  standard ones, this may be used to restrict parts you don't care
X  about. For example, "-P 161" will leave off the horary parts, "-P
X  140" will leave off the horary and crop parts, and "-P 133" will
X  leave off the horary, crop, and event parts. Related to this,
X  standard -R object restrictions will affect the parts shown; if a
X  planet is restricted, than any parts referencing it in its formula
X  will be left out.
X
-P0 [<parts>]: Like -P but display formulas with terms reversed.
X
X  If the -P switch is invoked as -P0 (or -Pz0, etc) the output will be
X  identical to before, except that the formula column will exchange the
X  positions of the second and third terms, i.e. instead of showing as
X  <term1> - <term2> + <term3>, -P0 will show <term1> + <term3> -
X  <term2>. This isn't too useful in itself, unless combined with -Pf
X  below, where -Pf and -Pf0 sort differently giving different terms
X  priority. Here's how to conceptualize formulas: if the planets were
X  rotated through the zodiac so that object2 is at the position of
X  object1, then the new position of object3 is the part. For example,
X  with the Part of Fortune being Asc - Sun + Moo, if you rotate your
X  chart so that the Sun is on the Asc, then the Moon's position is the
X  POF, Mercury's position is the Part of Commerce, its formula being
X  Asc - Sun + Mer, and so on. The default -Pf sorting allows one to
X  easily see, if one rotates this planet on the Asc, what parts
X  indicate the positions of the other planets. The -Pf0 ordering allows
X  one to easily see, where is the position of a particular planet,
X  after all rotations where some other planet is on the Asc.
X
-P[z,n,f]: Order parts by position, name, or formula.
X
X  As with the fixed stars, the Arabic part listing may also be sorted
X  in various useful orders. Invoke the -P switch as -Pz and they will
X  be displayed in order of position, with parts in Aries first and
X  Pisces last. Invoke it as -Pn and the parts will be sorted by name,
X  with the part of Accomplishment first and Worldliness last. Finally,
X  invoke it as -Pf and they will be ordered by formula, where the
X  ordering reflects the contents of each term, with Ascendant and early
X  planet terms first, and cusp and other special ones last. Note that
X  regardless of the ordering, passing a value to -P will still leave
X  off the same parts as in the standard display. Especially with -Pz
X  and -Pf, notice that several parts may have the same position. Some
X  formulas differ only in their night flip flag, meaning they will be
X  the same for day charts, while a few parts of different category
X  types can even have the same formula period.
X
-I [<columns>]: Print interpretation of selected charts.
X
X  The -I display an interpretation option is a powerful, expansive
X  feature to generate interpretations of many of Astrolog's charts.
X  Simply include the -I switch to get an interpretation of any
X  particular type of chart that the program would display otherwise.
X  If Astrolog doesn't support interpretations for it, the normal chart
X  will be shown instead.
X
X  For example, A brief interpretation of the meaning of the positioning
X  of each planet in its sign and house is supported when the -I switch
X  is invoked with -v (or by itself since -v is the default). If one
X  does this, then instead of the standard -v listing of planet
X  positions, the positions will be listed with a brief interpretation
X  of what they mean. I have to say that this is a pretty limited
X  version of interpretation, being nothing more than a combining of
X  phrases representing the planet, sign, and house in question;
X  nevertheless, people who aren't experts at interpreting charts might
X  find this to be of use (or at least amusing. :)
X
X  Another common interpretation one would want is the ability to give a
X  brief interpretation of each aspect in the aspect grid. When the -I
X  switch is combined with -g, the standard -g aspect grid will be
X  replaced with a list of each aspect occurring and a brief listing of
X  what it means. Again, this is mainly just a lookup of the general
X  meanings of each planet and the aspect in question, but still might
X  be found of interest by some. (Note: only the first 11 aspects, out
X  to the Bi-Quintile, will be considered.)
X
X  Synastry relationship charts may be interpreted too, with the -r -I
X  combination. Actually, they could be technically interpreted without
X  any special code, since the output of a synastry chart is a technical
X  "chart" with planet and house positions, but it would just be an
X  interpretation of Person2's planets in Person1's houses as if that
X  were a natal chart. This interpretation feature recognizes charts
X  generated with -r as synastry charts and interprets them
X  appropriately. For each of Person2's planets, the interpretation of
X  how and where it affects Person1 is displayed.
X
X  Eight more interpretations just as useful can be done: "-r0 person1
X  person2 -g -I" is a legal combination, and will display meanings of
X  aspects between planets in two charts in a relationship aspect grid.
X  "-i person -a -I" is legal, and will display the meanings of aspects
X  in a chart; this is like -g -I, but the aspect meanings are printed
X  in sorted order based on how powerful Astrolog thinks each aspect is,
X  so this is probably more useful. "-r0 person1 person2 -a -I" is legal,
X  and will display the meanings of aspects in a relationship aspect
X  list, like -r0 -g -I, but in the improved sorted order. "-d -I" is
X  legal, and will display the meanings of aspects among transiting
X  planets occurring during a day, as well as of sign and direction
X  changes. "-t -I" is legal, and will display the meanings of aspects
X  from transiting planets to natal ones. "-T -I" is also legal, and
X  will display the transit interpretations in sorted order by
X  influence. Finally, "-m -I" is a legal combination, which will do an
X  interpretation of a midpoint chart, printing each midpoint in the
X  same order as without the -I, but with each midpoint as an
X  interpretation sentence instead. Relationship midpoint charts may be
X  interpreted in the same manner using the "-r0 person1 person2 -m -I"
X  combination.
X
X  In displaying the interpretation text, the program will use the name
X  or title field of the chart (exactly as entered by the user or as
X  passed to the -zi switch) when referring to a person. If this field
X  is empty, the program will use the generic labels "this person",
X  "person1", or "person2" as appropriate.
X
X  This interpretation toggle switch accepts an optional parameter to
X  specify the number of screen columns in which to format the
X  interpretation paragraphs, i.e. what column to break lines at when
X  formatting and printing. One may change this from the default of 80
X  to accommodate narrower or wider screens or printers.
X
--
X
Switches which affect how the chart parameters are obtained:
X
-n: Compute chart for this exact moment using current time.
X
X  For those with systems who can handle time calls (If your system
X  errors on trying to compile them, simply comment out the #define TIME
X  line at the beginning), the program supports displaying the chart for
X  the time at the current moment! In other words, invoke as astrolog -n
X  and see where the planets are right now. (This is fun - the house
X  cusps change 1 minute about every 4 seconds!) You will need to change
X  the #defines for the default longitude and latitude in astrolog.h, or
X  else specify where you are explicitly by using the -zl switch to
X  change the default location. To figure out the time zone, the program
X  uses the default value in the astrolog.dat file or as defined in the
X  DEFAULT_ZONE constant set at compile time.
X
X  Note that the default time zone setting or passing values to -z,
X  won't affect the positions of the planets, as expected since they are
X  where they are "now" no matter how time is expressed. The default
X  zone is merely used to determine what to express the local time to
X  when displaying the current time. It is important however to realize
X  that the time zone setting on your system can affect the actual raw
X  time the program gets internally for "now". If the -n switch seems to
X  always generate times an hour or more off to what you have your time
X  zone set to, it's likely that your time zone environment variable is
X  uninitialized or set incorrectly. You will need to set the "TZ"
X  environment variable, setting it to a value such as "xxxnyyy", where
X  'n' is the hours your zone is before GMT, 'xxx' is a three character
X  string indicating the abbreviation of the zone (required, but doesn't
X  need to be set to anything more than 'xxx' if you prefer) and 'yyy'
X  is the abbreviation for the zone when/if ever in Daylight Time. For
X  example, if running Astrolog on a PC in Eastern Time, put the line
X  "set TZ=EST5EDT" in your AUTOEXEC.BAT file. Another way to correct
X  your "now" charts if they always seem to be off by a certain number
X  of hours is to use the -Yz switch (described later).
X
-n[d,m,y]: Compute chart for start of current day, month, year.
X
X  These switches are like the -n generate chart for current moment now
X  feature, except that they will respectively generate charts for the
X  midnight on the current day, midnight on the first of the current
X  month, and midnight on the first day of the current year.
X
-z [<zone>]: Change the default time zone (for -d-E-t-q options).
X
X  The -z <value> option can be used to change the default time zone to
X  the value in question. For example, you can force the -E ephemeris
X  and -t transit lists to be displayed at midnight GMT time instead of
X  the local time with "-z 0". If Daylight time is in effect, you should
X  set the separate Daylight time default below. Note that one can
X  technically get by without changing the Daylight setting, by
X  subtracting one from the time zone itself, e.g. for EST where the
X  time zone is "5", you can do "-z 4" or "-z EDT" during Daylight time
X  to properly display transits, aspects in day, and other lists in the
X  local DST zone.
X
X  Normally the -z switch takes an argument which will then become the
X  default time zone. If one, however, invokes it by itself, it will
X  subtract one hour from whatever the default time zone presently is.
X  This is useful since it is equivalent to adjusting any times printed
X  to Daylight time, i.e. it will add one hour to any times displayed.
X  Again, this is archaic as it's better to just use the -z0 switch
X  below. Without the -z0 setting, when entering the birth time for
X  charts, one would have to subtract one hour if Daylight time were in
X  effect, or subtract one hour from the time zone which will do the
X  same thing. For example, over here on the West Coast, I have my
X  default time zone compiled to be "8"; when Daylight time is in effect
X  here, I can do -z 7 or just -z to decrease the default time zone when
X  I make say a -t transit list, which will in effect add one hour to
X  the local times displayed, or in effect "Spring ahead" the clock for
X  me. (For a better way of adjusting Astrolog for Daylight time without
X  having to specify -z all the time, recompile the program, or add one
X  hour to times in your head, use the "defaults" file described later
X  to edit the default time zone or the Daylight setting.) Remember that
X  the -z (and -zl) switches should be before any other switches they
X  modify (such as -n) in order for the new default to take effect.
X
-z0 [<offset>]: Change the default daylight time setting.
X
X  This switch sets the contents of the default Daylight time setting,
X  and sets the value in the current chart as well, taking one optional
X  parameter. When present the parameter will be used for the Daylight
X  hour offset, which will almost always be 0 or 1, but can technically
X  be set to something else for Daylight offsets that "Spring ahead"
X  amounts other than one hour. When omitted, the -z0 switch will toggle
X  the Daylight setting on and off between 1 and 0.
X
-zl <long> <lat>: Change the default longitude & latitude.
X
X  Similar to the -z switch, the -zl option can be used to change the
X  default compile time world coordinates used in certain options, such
X  as the -n cast chart for right now switch. Note that both the -zl
X  default longitude and latitude, and the -z default zone switches
X  affect the time and location of the current chart in memory in
X  addition to the default setting. Confusion could result otherwise if
X  changing a default after chart info was already obtained, e.g. "-z
X  -n" would be different from "-n -z", where the latter wouldn't change
X  the zone for the chart because it was seen after the -n was processed
X  and the old zone used. The correct thing will happen regardless of
X  ordering. This means you can easily do a relocated chart with this
X  -zl switch, e.g. "-i yourchart -zl 122W20 47N36" will cast your chart
X  relocated to Seattle.
X
-zt <time>: Set only the time of current chart.
X
X  This simple switch will set the time and only the time of the current
X  chart in memory to the given value. For example, to cast a chart for
X  3:00pm today, do "-n -zt 3:00pm". Without this one would have to cast
X  a whole new chart using the -q switch and respecify the month, day,
X  and year. Note that placement of this switch is important, as any
X  other switch after it which also sets a time will clobber the
X  setting, e.g. "-zt 3:00pm -i chartfile" will be the same as just "-i
X  chartfile" because the file has its own time value.
X
-zd <date>: Set only the day of current chart.
X
X  This is just like the -zt switch above except that it takes one
X  parameter for and sets the day of the current chart. For example, to
X  see the aspects taking place on the 15th of the current month, do "-n
X  -zd 15 -d", which does the chart for the current month and year but
X  the day scanned is the 15th instead of the current day.
X
-zm <month>: Set only the month of current chart.
X
X  This simple switch will set the month and only the month of the
X  current chart in memory to the given value. For example, to display
X  an ephemeris chart for July of this year, do "-n -zm July -E".
X
-zy <year>: Set only the year of current chart.
X
X  This is just like the -zm switch above expect it will set the year
X  and only the year of the current chart in memory to the given value.
X  For example, to display a chart for your birthday next year, do "-i
X  yourchart -zy 1999".
X
-zi <name> <place>: Set name and place strings of current chart.
X
X  This switch sets on the command line the contents of the name and
X  city string fields of the current chart. Note that this switch is
X  actually put into present style chart info switch files generated
X  with -o to reload the name fields. You can convert an old style file
X  created before version 4.20 to new style and add in the name fields
X  for it with: -i file -zi "the name" "the city" -o file. (Note that
X  you may also want to correct the time or time zone if Daylight time
X  was in effect though.)
X
-q <month> <date> <year> <time>: Compute chart with defaults.
X
X  The -q <month> <date> <year> <time> option takes the four parameters
X  and casts a chart for the time in question. The time zone and
X  location are taken from the default compiled values. This is just yet
X  another useful shorthand way to quickly make a chart. Note that the
X  -qa option which takes all seven chart parameters can be duplicated
X  with -q along with the -z <zone> and -l <long> <lat> options.
X
-qd <month> <date> <year>: Compute chart for noon on date.
X
X  The -q <month> <day> <year> option can be used to cast a quick chart
X  for 12 noon on a particular date, using the default longitude and
X  latitude, and time zone. One example where this is useful is with the
X  -d option, e.g. to see the times of exact aspects on a particular
X  date, like your next birthday, your finals, etc, without having to
X  specify unnecessary data. Note that this is just like the -q switch
X  except that -q requires a specific time on the day in question as well.
X
-qm <month> <year>: Compute chart for first of month.
-qy <year>: Compute chart for first day of year.
X
X  A quick chart cast for midnight on the first of a month can be
X  generated with the two parameter -qm <month> <year> switch. A chart
X  cast for midnight on the first of January of a year can be generated
X  with the one parameter -qy <year> switch. Both of these use the
X  default time zone and location. These switches are most useful for
X  charts that don't require all the standard information. For example,
X  to get an ephemeris for December, 2000, do "astrolog -qm 12 2000" and
X  avoid having to enter in a day, hour, or location that wouldn't have
X  any effect. These options are in similar to the -qd <month> <day>
X  <year> switch above that will do a chart for noon on the given date,
X  and the -q <month> <day> <year> <time> switch that takes a time as well.
X
-qa <month> <date> <year> <time> <zone> <long> <lat>:
Compute chart automatically given specified data.
X
X  Normally one generates a new chart by entering the data coordinates
X  interactively. A fast typist familiar with the program might prefer
X  to give all the info at once, which can be done with this option.
X  Simply list the seven parameters above, in the exact format as they
X  would be given to the program were the user being prompted for them.
X  (Note that it's probably better to use the -qb switch below because
X  of its extra parameter; the -qa switch will automatically assume
X  Daylight time is off.)
X
-qb <month> <date> <year> <time> <daylight> <zone> <long> <lat>:
Like -qa but takes additional parameter for daylight offset.
X
X  This switch is just like the -qa switch above except that it takes
X  one extra parameter for the Daylight Saving time flag. In order, the
X  eight parameters for -qb are Month, Day, Year, Time, Daylight offset,
X  Time Zone, Longitude, and Latitude. (Like -zi this switch is also put
X  into chart info files by -o.)
X
-qj <day>: Compute chart for time of specified Julian day.
X
X  This switch will automatically cast a chart for the given Julian Day.
X  Unlike the other -q switches which take standard months, days, and
X  years, this switch takes one parameter for the Julian Day (which may
X  be fractional to specify a time within the day in question). For
X  example, another way to cast a chart for Midnight, GMT, on New Year's
X  day of 1994 is with "-qj 2449353.5". (Julian Day 0 refers to Noon
X  GMT, January 1, 4712 BC.)
X
X  Known bug: If the extended Placalc formulas aren't compiled into the
X  program it will have to use an older version of the Julian day
X  conversion routines which will result in these -qj charts giving
X  incorrect results for dates in the Julian Calendar, i.e. before
X  October 1582, which can be seen by casting a chart with -qj
X  specifying a day less than 2299161.5, in which case the Julian Day
X  displayed for the date of the chart cast will be ten days greater
X  than what was passed to it.
X
-i <file>: Compute chart based on info in file.
X
X  See the -o option below.
X
X  Note that there is a "virtual file" named "set" which can be passed
X  to the -i and -r switches. Instead of looking for an actual disk
X  file, this represents the "last" set of chart information dealt with,
X  and is useful to avoid having to manually enter information in
X  certain cases. (Other "virtual files" Astrolog can use are "now"
X  which means the current time at the default location, and "tty" which
X  means prompt the user for the info.)
X
X  This is best used within a -Q loop. For example, you first manually
X  enter the time for a chart and it's displayed. Now, this time in the
X  loop, you want the same chart in an aspect grid, and don't want to
X  have to enter the data again or create a file to read from. Entering
X  "-i set" will use this chart info no matter how it was entered. For
X  graphics charts this "last" chart will be set to the initial chart or
X  whatever animation situation was saved via the 'o' key. Perhaps the
X  most useful ability of the "set" chart however is that it will set
X  itself to times that appear in -t and -d transit and aspect in day
X  searches. For example, if you want to cast a chart for the New Moon
X  the other January, first do a combination like "-qd 1 11 1994 -d -R0
X  1 2 -A 1", which will scan the 11th for Conjunctions involving the
X  Sun and Moon, and display the time. Before, to get a New Moon chart
X  one would then have to manually specify the time displayed. Now, just
X  "-i set" will bring it up!
X
X  The initial contents of the "previous" chart, i.e. what you get by
X  directly doing something like "astrolog -i set" are initialized to
X  the astrological "chart" for the release of this version 5.40
X  of the program itself, which is the time of the Winter Solstice,
X  specifically for 5:57pm PST (8 hours before GMT) on Monday, December
X  21, 1998 for here in Seattle, WA (122W20, 47N36).
X
X  This is one more "virtual file" that's obscure and only useful in
X  certain circumstances, named "nul" which may be passed to the -i file
X  input or -r switches which take chart info files for parameters. The
X  file "nul" means to not change the chart info parameters any, but
X  rather leave them with whatever current settings they may have or
X  were set to before. This is mainly useful with the -r switches if you
X  don't want to have to create two actual files to pass in, or use the
X  virtual file "tty" and have to enter in data interactively. For
X  example, to see what your biorhythm is like for the beginning of
X  December, do "astrolog -qm 12 1998 -rb nul yourchart" on the command
X  line and no further input is needed.
X
-i[2,3,4] <file>: Load chart info into chart slots 2, 3, or 4.
X
X  If the -i chart file load switch is invoked as -i2, it will do the
X  same thing as -i except put the chart info into the "second" chart
X  slot, for use with relationship charts. This does not enter or leave
X  any relationship chart mode. One can set what chart info each wheel
X  ring in the tri-wheel and quad-wheel charts will contain by putting a
X  number after the -i switch to load the chart info from a file into
X  that slot, where -i3 will load into the third slot, and -i4 into the
X  fourth (where -i2 will again load into the second, and -i1 or just -i
X  into the first).
X
-o <file> [..]: Write parameters of current chart to file.
X
X  The program supports directing chart information to, and reading
X  output from, data files. The '-o' option will dump all the birth data
X  (the date and location, not the planet positions) to the specified
X  file. The '-i' option will cast the chart based on the info in the
X  file. (This allows you to put your birth data into a specific file,
X  and cast your chart whenever you want to after that without having to
X  reenter your birth data all the time.)
X
X  Another file output feature, the ability to concatenate "comment
X  lines" at the end of a data file, is included with both the -o and
X  -o0 options, as you may wish to say keep track of info other than the
X  program supported name and city. After scanning the filename, the
X  -o[0] option will then write any parameter that follows it at the end
X  of the file, until a parameter beginning with a '-' or '/' (the next
X  obvious command switch) is reached. For example: -o <file> "Birth
X  certificate" Family, will add extra info indicating the source of my
X  birth data, and a general category for the chart, in two separate
X  lines at the end of the file. (On most systems, quotes can be used to
X  allow spaces within one parameter.)
X
-o0 <file> [..]: Like -o but output planet/house positions.
X
X  Ability to write the actual sign and house positions of a chart to a
X  file (instead of just the time and place) has been implemented via
X  the -o0 <file> option. This option can be used interchangeably with
X  the -o output to file switch. The information written includes the
X  zodiac position of all unrestricted objects, their retrograde
X  velocity, latitude, and distance, as well as the positions of the
X  house cusps. (The chart name strings as set with the -zi switch are
X  written out too of course.) This file information can easily be
X  passed into another program, and can be read back into Astrolog with
X  the -i option. The -i option will automatically determine which type
X  the file is, and will either use the given positions, or else
X  calculate them as needed. (Note that some switches, such as the -c
X  house system selection, will have no effect for this file type.)
X  Check an example of one of these files to see the precise format (a
X  zodiac position is recorded as three numbers: degree in sign, sign as
X  number 1 through 12 or three letter abbreviation, and floating point
X  minute within the degree.) When the files are read back in, they will
X  be flagged as "having no space or time" like the composite charts in
X  the chart header displays.
X
X  This file format can allow one to do things such as transits to
X  composite charts (send the composite chart to file with -o0 option
X  and then read in the file with -i when using the -t switch)
X  composites between two composite charts (use -rc between two
X  composite charts sent to a file) and even, if one is willing to do a
X  small amount of editing, to do transits to midpoints or the 0 degrees
X  Aries point. Note that one can easily edit the positions in the -o0
X  position file to be whatever they like, so one could replace some
X  unimportant object (e.g. the vertex) with 0 degrees Aries or an
X  important midpoint value. Note that trying to still use the -o time
X  and space output with a chart in memory that doesn't have space/time
X  will confuse the program; it will either say it can't make the file
X  or else will output the time/space of the most recent parameter file
X  it read in.
X
X  Note for old style -o0 position files created before version 4.20
X  that aren't based on command lines (see -Yo switch later): the
X  positions of the eight uranians may be output to those planet
X  position files in addition to the 20 main objects, but only if the
X  uranians are actually calculated with -u in effect. Hence those
X  position files can be of two different lengths, but the program will
X  be able to read in both formats, leaving the uranians uninitialized
X  at zero Aries if they aren't also in the file.
X
-os <file>, > <file>: Redirect output of text charts to file.
X
X  This switch, given a file, will output the contents of a text chart
X  to that file. This is just like output redirection (i.e. "> textfile"
X  at the end of a command line) except that it's implemented within the
X  program. Hence unlike output redirection it will work from within a
X  -Q loop, from the File Run menu in Microsoft Windows, and on systems
X  whose shells don't allow redirection at all. This also has the
X  advantage in that prompts and user messages won't be sent to the
X  file, hence things can be done such as "astrolog -os textfile", where
X  the program will still prompt you on the screen for the chart info,
X  but the chart itself will still go to the file.
X
X  The -os switch may also be expressed as ->, which is included as a
X  convenience with its similarity to the ">" output redirection
X  featured in many shells. As with all switches, one may leave off the
X  dash and invoke it as just ">". When just ">" is included on the
X  command line, the system's own output redirection will tend to be
X  used. This switch allows one to also include ">" when prompted for
X  command lines within the program, or when running from MS Windows,
X  where the shell plays no part.
X
--
X
Switches which affect what information is used in a chart.
X
-R [<obj1> [<obj2> ..]: Restrict specific bodies from displays.
X
X  The ability to restrict the transit (-t) and daily aspect (-d) scans
X  to just certain bodies has been implemented with the -R switch. Using
X  -R by itself will prevent the asteroids, Chiron, Lilith, the Part of
X  Fortune, East Point, and the Vertex from being in any of the charts.
X  One may also give a list of one or more numbers representing planets
X  to be ignored (e.g. 1 = Sun, 2 = Moon, 3 = Mercury, etc) or specify
X  planet abbreviations directly, so that a complete custom setup can be
X  obtained (e.g. "-R 1 2 3 4 5" or "-R sun moo mer ven mar" will cause
X  all of the inner planets to be ignored). More than one -R switch can
X  be combined (e.g. -R -R 16 will cause the asteroids, etc, and the
X  North Node to be ignored; the first -R gets rid of the asteroids,
X  etc, and the second one deletes the North Node.) Also, specifying the
X  same particular body more than once will cause it to be included
X  again, or in other words, -R <objectnum> complements the status of
X  whether it is to be ignored or not (e.g. -R -R 15 will cause all of
X  the asteroids, etc, excluding Vesta, to be ignored; the first -R
X  makes causes the asteroids to be ignored, and specifying Vesta in the
X  second -R makes it reappear.)
X
X  Note that Astrolog will compute charts faster when objects are
X  restricted, since it doesn't bother to compute locations that aren't
X  needed or used. For example, the search of a year for a Solar Return
X  (-i chart -ty year -R0 sun -RT0 sun) is about twice as fast than when
X  the restrictions are omitted, since we're only looking at Sun locations.
X
-R0 [<obj1> ..]: Like -R but restrict everything first.
X
X  The -R0 option will cause ALL of the bodies to be ignored, which is
X  useful if you are looking for just the transits/aspects of a few
X  planets (e.g. -R0 6 7 will cause everything but Jupiter and Saturn to
X  be ignored.) Combining all these methods can cause whatever you are
X  looking for in transits and aspects to be quickly found without having
X  to wade through lots of stuff you aren't interested in.
X
-R1 [<obj1> ..]: Like -R0 but unrestrict and show all objects.
X
X  This will unconditionally UN-restrict all planets and other objects
X  used by the program, a compliment to the -R0 switch above which
X  restricts everything. Note that this will also set modes, in that it
X  does automatically activate the -C, -u, and -U sets of objects.
X
-R[C,u,U]: Restrict all minor cusps, all uranians, or stars.
X
X  These three switches are similar to the -R0 option in that they
X  initially restrict objects, i.e. all the minor cusps, Uranians, and
X  stars, (described below) respectively from appearing. For example, if
X  you want to include only the star Sirius in an X window chart without
X  having to also include all the other stars (or having to enter a very
X  long restriction list), do: "astrolog -U -RU 48 -X", which will
X  include the stars, and then restrict them all except Sirius, before
X  making the chart.
X
-RT[0,1,C,u,U] [..]: Restrict transiting planets in -t lists.
X
X  Transiting planets may be restricted from charts independently of
X  those planets being transited to. In -T charts, the -R option only
X  affects the natal planets. To restrict transiting planets, one must
X  use the -RT option. The -RT option is exactly like -R, and any
X  subswitches of -R can be used with -RT as long as the 'T' immediately
X  follows the 'R'. For example, -RT by itself restricts transiting
X  asteroids from appearing in -T charts, -RT0 restricts all transiting
X  bodies, -RTu restricts the Uranians, and so on. This is a really
X  useful feature, and allows one to pretty much be able to generate
X  exactly and only those transits one is interested in. For example, if
X  you want to see if anything is transiting your natal Jupiter or natal
X  Saturn this month, do: "astrolog -i yourchart -T 3 1993 -R0 6 7". If
X  you want to see if Chiron is transiting anything this year (excluding
X  asteroids), do: "astrolog -i yourchart -Ty 1993 -RT0 11 -R". If you
X  are only interested in transits of outer planets to your Sun or Moon,
X  do: "astrolog -i yourchart -T 3 1993 -RT0 6 7 8 9 10 -R0 1 2", and so
X  on. By default, only the transiting Moon is restricted. To get it
X  back, merely unrestrict it with "-RT 2". These default transit
X  restrictions are in the astrolog.dat defaults file described later,
X  and are right after the standard restriction table, both of which may
X  be modified however you please.
X
-RA [<asp1> ..]: Restrict aspects by giving them negative orbs.
X
X  The -RA switch will restrict the given aspect or list of aspects from
X  appearing in charts, like how the -R switch does for objects.
X  Technically, an aspect will be restricted if it's given a negative
X  orb. The -RA switch just gives the specified aspects negative orbs,
X  and is a shorthand for having to explicitly use the -Ao orb setting
X  switch. (This means that -RA won't toggle an already restricted
X  aspect back on however.)
X
-C: Include angular and non-angular house cusps in charts.
X
X  This option must be indicated to include the 12 actual house cusps
X  (i.e. Ascendant, et al) in the various chart options, such as the -g
X  aspect grids, -t transit searches, the graphics wheel chart, etc.
X  This option of course won't have any effect on certain charts where
X  only physical bodies are shown (e.g. -Z, -S, -L) or where all house
X  cusps are already indicated in the chart (e.g. -v, -w). The house
X  cusps technically have actual object indexes like the planets, and
X  are objects 21 through 32 in order (add 20 to a house to get its
X  index). You can deal with and restrict these individually for
X  transit and other charts, e.g. to turn on just the Ascendant and MC,
X  do "-C -RC 21 30" Concerning rulerships, each cusp object is set to
X  "rule" the sign corresponding to it (e.g. Ascendant "rules" Aries)
X  while each cusp "exalts in" the next sign after it of the same
X  element (e.g. Ascendant "exalts in" Leo).
X
-u: Include transneptunian/uranian bodies in charts.
X
X  Display the locations of the "Uranian" planets with the -u switch.
X  Transneptunian or Uranian planets are an interesting subset of
X  astrology which includes various objects alleged to be beyond Pluto.
X  (Do: astrolog -u -O to list the eight Uranian bodies.) Anyway,
X  Astrolog will display the zodiac positions of these planets as well if
X  one includes this option, and will print their positions after the
X  main planets, or include them in the other chart types.
X
-U: Include locations of fixed background stars in charts.
X
X  Astrolog has the ability to display the positions of 47 of the
X  brightest and most important stars in the sky. To include these stars
X  in a chart, use the -U "universe" option. The 43 brightest stars,
X  i.e. all those with apparent magnitude values < 2.0 are included, in
X  addition to four dimmer "stars" which are considered significant,
X  i.e.: Polaris the North star, the Pleiades (specifically the star
X  Pleione within it) star cluster (home of our extraterrestrial
X  cousins), Zeta Reticuli (home of the Grey aliens), and the Andromeda
X  (M31) Galaxy (closest galaxy to our own Milky Way, and home to
X  various extraterrestrial hierarchies.) One bright star is called
X  "Orion", which is formally Alnilam, the middle star of Orion's belt.
X  Since stars are fixed in the sky, they will never change position in
X  the -s sidereal zodiac, although they will slowly precess forward in
X  the normal tropical zodiac. The -R restriction option can be used to
X  determine which stars are actually included, although the -U option
X  still needs to be included to get any stars at all. (With on screen
X  graphics, the stars are labeled by three letter abbreviations, and
X  are colored according to their brightness: orange for stars brighter
X  than (less than) magnitude 1.0, and dark red for the dimmer remaining
X  stars with magnitudes greater than this value.)
X
-U[z,l,n,b]: Order by azimuth, altitude, name, or brightness.
X
X  In the -v standard chart, -Z horizon chart, and in the -O object list,
X  where all the stars are printed sequentially, it can sometimes be
X  confusing to locate the star you want among 42 others. The -U option
X  can be modified to sort the stars in various ways. If one uses -Ub
X  instead of just -U, the stars will be listed in order from brightest
X  to dimmest. Doing -Un instead of -U will alphabetize the stars by
X  name. -Ul will sort them by their altitude from highest in the sky to
X  lowest, while -Uz will sort them by their zodiac position. Note that
X  any star ordering will have no visible effect in X windows, and one
X  must still use the default ordering when passing numbers to the -R
X  option to restrict various stars.
X
-A <0-18>: Specify the number of aspects to use in charts.
X
X  If you like many aspects, or only desire the major ones, to be
X  included in the aspect grids, specifying -A <number> will limit or
X  extend the number of aspects (e.g. -A 2 will make charts with only
X  conjunctions and oppositions listed in them, while -A 18 will include
X  all 18 aspects that Astrolog supports.)
X
-Ao <aspect> <orb>: Specify maximum orb for an aspect.
X
X  Change the default orbs of the various aspects with the -Ao <aspect>
X  <orb> switch. Do you not like the 7 degree orbs for conjunctions that
X  are in there by default? Given an aspect number and an orb value,
X  the orb used for that particular aspect is updated accordingly.
X  Non-integer orb values are allowed of course. Use negative orb values
X  to completely eliminate an aspect from ever appearing. For example:
X  astrolog -Ao 2 4 -Ao 4 -1 narrows the orb for Oppositions, and
X  completely eliminates Trines, leaving all the other aspects at the
X  default values. Note that for very wide orbs more than one aspect may
X  apply for a particular angle, in which case the more fundamental
X  aspect is chosen. Also for wide aspects the fractional value of the
X  orb may be lost in the -g text grid (due to too many characters) and
X  their might be some slight overlap in the X window -g cells.
X
-Am <planet> <orb>: Specify maximum orb allowed to a planet.
X
X  Ability to explicitly specify maximum orbs that any aspect can make
X  to a particular planet is supported with the -Am switch. This is used
X  for objects like the North Node which require narrower orbs than what
X  the aspects themselves normally allow. The -Am switch takes two
X  parameters: the first to indicate the index of the object, and the
X  second to indicate what the maximum orb allowed to it will be. By
X  default, the only objects with restriction are the Node, Part of
X  Fortune, Vertex, and stars, which allow a 2 degree max orb to them.
X  With this option, one can change these limits or impose restrictions
X  for other planets too. The astrolog.dat file (described later) will
X  read in these default planet orbs for the first 20 objects.
X
-Ad <planet> <orb>: Specify orb addition given to a planet.
X
X  Ability to widen an aspect orb for any planet is supported with the
X  -Ad switch. This is used for objects like the Sun and Moon for which
X  one might want wider orbs to them than what the aspects themselves
X  allow. Like the -Am switch, this -Ad switch takes two parameters: the
X  first to indicate the object, and the second to indicate how much
X  wider orbs allowed to it will be. By default, the only objects which
X  have orbs widened for them are the Sun and Moon, each of which adds
X  one degree to the orb of any aspect to it. With this option, one can
X  change these additions or allow other objects to have them, too. The
X  astrolog.dat file will also read in defaults for these orb additions
X  for the first 20 planets. (Note that these object orb additions can
X  be added to a negative orb for an aspect making it valid, so if you
X  really want to restrict an aspect with -Ao, it should be a large
X  enough negative value so that the sum of any additions between two
X  objects won't make it go positive.)
X
-Aa <aspect> <angle>: Change the actual angle of an aspect.
X
X  This option is used to change the actual angle of a particular
X  aspect. This is useful if one wants to search for some unusual angle
X  not already available in Astrolog's aspects or accessible through the
X  -x harmonic charts. For example, if I want to know when any planet
X  enters a 2.5 degree orb of any planet in my natal chart, I would do a
X  transit search along with "-Aa 1 2.5", where "1" is the index of the
X  conjunction aspect, and "2.5" means the "conjunction" is now exact
X  when any two objects are 2 degrees and 30 minutes apart.
X
--
X
Switches which affect how a chart is computed:
X
-b: Use ephemeris files for more accurate location computations.
X
X  Astrolog has a set of calculation routines which are much more
X  accurate than the standard Matrix software routines that are usually
X  used by default. One may choose between these calculation methods
X  with the -b switch. With -b, Sun through Pluto, the North Node,
X  Chiron, and the four asteroids will be computed more accurately
X  (although it will take slightly longer). The other uranians, stars,
X  and house cusps are always generated with the Matrix routines.
X
X  This advanced calculation uses ephemeris files for some planets which
X  must be in a directory specified at compile time or covered by one of
X  the environment variables in order to be found. The advanced routines
X  are valid based on how many of the ephemeris files one has. With all
X  of them, the formulas will cover and deliver accurate positions for
X  nearly 8500 years from -5260 BC through 3237 AD! There are 95
X  ephemeris files total. Each file covers a range of 100,000 days, or
X  about 273 years. Altogether they take up 4.8 megabytes of disk space,
X  but each segment of 273 years only takes up 150K. For each time
X  segment, there is an ephemeris file named "LRZ5_n" containing the
X  positions of Jupiter through Pluto (at 80 day increments), a file
X  "CHI_n" containing the positions of Chiron, and a file "CPJV_n"
X  containing the positions of the four asteroids. The 'n' refers to the
X  span of Julian Days covered by it (divided by 100000). For example,
X  Julian Days 1,200,000 through 1,300,000 are in the files "LRZ5_12",
X  "CHI_12", and "CPJV_12" (the 'm' character in some files refers to
X  negative/minus Julian Days). You don't need all the files to use -b,
X  just those that cover the dates you want to use. If you try to use -b
X  with a date not covered by an available ephemeris file, an warning
X  message will be printed and the Matrix positions will be used. The
X  files "LRZ5_24", "CHI_24", and "CPJV_24" cover the years 1859 through
X  2131 AD, which is good for most modern purposes and only take up 150K
X  of space. (These three files are included in the standard zip archive
X  release file of Astrolog. For Unix users who want any ephemeris
X  files, and PC users who want to cover more years, the complete set of
X  files is at anonymous FTP sites such as ftp.magitech.com.) The
X  following is a list of the precise dates covered by each ephemeris file:
X
X  Files LRZ5_m2 / CPJV_m2 / CHI_m2 cover Jun  6, -5260 BC - Mar 20, -4986 BC.
X  Files LRZ5_m1 / CPJV_m1 / CHI_m1 cover Mar 20, -4986 BC - Jan  1, -4712 BC.
X  Files LRZ5_0  / CPJV_0  / CHI_0  cover Jan  1, -4712 BC - Oct 14, -4439 BC.
X  Files LRZ5_1  / CPJV_1  / CHI_1  cover Oct 14, -4439 BC - Jul 28, -4165 BC.
X  Files LRZ5_2  / CPJV_2  / CHI_2  cover Jul 28, -4165 BC - May 10, -3891 BC.
X  Files LRZ5_3  / CPJV_3  / CHI_3  cover May 10, -3891 BC - Feb 21, -3617 BC.
X  Files LRZ5_4  / CPJV_4  / CHI_4  cover Feb 21, -3617 BC - Dec  4, -3344 BC.
X  Files LRZ5_5  / CPJV_5  / CHI_5  cover Dec  4, -3344 BC - Sep 17, -3070 BC.
X  Files LRZ5_6  / CPJV_6  / CHI_6  cover Sep 17, -3070 BC - Jun 30, -2796 BC.
X  Files LRZ5_7  / CPJV_7  / CHI_7  cover Jun 30, -2796 BC - Apr 13, -2522 BC.
X  Files LRZ5_8  / CPJV_8  / CHI_8  cover Apr 13, -2522 BC - Jan 25, -2248 BC.
X  Files LRZ5_9  / CPJV_9  / CHI_9  cover Jan 25, -2248 BC - Nov  7, -1975 BC.
X  Files LRZ5_10 / CPJV_10 / CHI_10 cover Nov  7, -1975 BC - Aug 21, -1701 BC.
X  Files LRZ5_11 / CPJV_11 / CHI_11 cover Aug 21, -1701 BC - Jun  3, -1427 BC.
X  Files LRZ5_12 / CPJV_12 / CHI_12 cover Jun  3, -1427 BC - Mar 17, -1153 BC.
X  Files LRZ5_13 / CPJV_13 / CHI_13 cover Mar 17, -1153 BC - Dec 28,  -880 BC.
X  Files LRZ5_14 / CPJV_14 / CHI_14 cover Dec 28,  -880 BC - Oct 11,  -606 BC.
X  Files LRZ5_15 / CPJV_15 / CHI_15 cover Oct 11,  -606 BC - Jul 24,  -332 BC.
X  Files LRZ5_16 / CPJV_16 / CHI_16 cover Jul 24,  -332 BC - May  7,   -58 BC.
X  Files LRZ5_17 / CPJV_17 / CHI_17 cover May  7,   -58 BC - Feb 18,   216 AD.
X  Files LRZ5_18 / CPJV_18 / CHI_18 cover Feb 18,   216 AD - Dec  1,   489 AD.
X  Files LRZ5_19 / CPJV_19 / CHI_19 cover Dec  1,   489 AD - Sep 14,   763 AD.
X  Files LRZ5_20 / CPJV_20 / CHI_20 cover Sep 14,   763 AD - Jun 27,  1037 AD.
X  Files LRZ5_21 / CPJV_21 / CHI_21 cover Jun 27,  1037 AD - Apr 10,  1311 AD.
X  Files LRZ5_22 / CPJV_22 / CHI_22 cover Apr 10,  1311 AD - Jan 31,  1585 AD.
X  Files LRZ5_23 / CPJV_23 / CHI_23 cover Jan 31,  1585 AD - Nov 16,  1858 AD.
X  Files LRZ5_24 / CPJV_24 / CHI_24 cover Nov 16,  1858 AD - Aug 31,  2132 AD. *
X  Files LRZ5_25 / CPJV_25 / CHI_25 cover Aug 31,  2132 AD - Jun 16,  2406 AD.
X  Files LRZ5_26 / CPJV_26 / CHI_26 cover Jun 16,  2406 AD - Mar 31,  2680 AD.
X  Files LRZ5_27 / CPJV_27 / CHI_27 cover Mar 31,  2680 AD - Jan 14,  2954 AD.
X  Files LRZ5_28 / CPJV_28 / CHI_28 cover Jan 14,  2954 AD - Oct 30,  3227 AD.
X  Files LRZ5_29 / CPJV_29          cover Oct 30,  3227 AD - Aug 15,  3501 AD.
X
X  Astrolog uses the formulas from the "Placalc" program package to
X  generate its precise positions. Placalc's accuracy is about the same
X  as Mark Pottenger's "CCRS" routines, and those used in Nova (it even
X  fixes some accuracy problems Nova has, in some of its earlier
X  versions at least). Placalc's integrated outer planet positions
X  represent the standard of the Nautical Almanac, the international
X  astronomical standard, as published in the Astronomical Almanac, for
X  its computations as computed before 1984. (Since 1984 the standard
X  has been the DE200 integrations by JPL.) The Sun's position
X  implements the Newcomb theory for all terms > 0.01", the positions of
X  Mercury through Mars are done to all terms > 0.05", while "Brown's
X  improved lunar ephemeris" is used such that the Moon is within 3" of
X  DE200. For the asteroids, at the conclusion of the integration
X  process computing their files, the uncertainty error had reached
X  8.0E-11 AU after CPJV_29, and 4.9E-10 AU after CPJV_m2. Placalc's
X  fraction of second precision, is of course much more accurate when
X  compared to the Matrix positions, which are only accurate to about
X  one minute (and several degrees for Chiron, as well as the four
X  asteroids) for this century only. For example, at 1800 AD, the Matrix
X  positions for the outer planets are off by 2 degrees, and about 1
X  degree for 2100; by 1500 AD, Matrix is off by 14 degrees for Pluto
X  while Chiron is barely in the right hemisphere any more.
X
X  There is a flag to "Use ephemeris files" in the astrolog.dat file,
X  which when set, will always use the Placalc routines and is the same
X  as just including -b all the time, in which case -b will toggle them
X  back off. There is a compile time option #define PLACALC in the
X  astrolog.h which can be commented out to disable the -b switch and
X  the new formulas. Note that because the asteroid ephemeris files were
X  first introduced in a version after those for the other planets,
X  meaning one may not yet have CPJV_n files for dates they have the
X  other files for, there is an "undocumented" switch called -ba, which
X  is like -b but will still compute the asteroids using the Matrix
X  formulas.
X
X  Note that this calculation method is not compatible with allowing the
X  -v0 switch to express planetary velocities relative to average speed
X  work with it, and nor will central planetary bodies other than the
X  Sun or Earth (standard Geo and Helio centric charts) via -h work. It
X  will however display velocities for the Moon and the Node, which
X  aren't available with the Matrix routines.
X
X  Special thanks goes to Dr. Alois Treindl who kindly allowed his
X  formulas to be used in Astrolog. Mr. Treindl is the founder and owner
X  of Astrodienst Zurich, second largest astrological computer service
X  in Europe, and is well known for his work with Liz Greene. Astrolog
X  basically treats his Placalc routines as a library which we link
X  into, in that code that knows about both programs is kept to a minimum.
X
X  Special thanks also to Mr. Paul Schlyter, of the Swedish Amateur
X  Astronomer's Society (SAAF, or in Swedish: Svensk Amat|rAstronomisk
X  F|rening), for providing the ephemeris files for the four asteroids,
X  by writing a utility which does the integration process to determine
X  the positions, and that conveniently outputs files in the Placalc
X  format. Note that the requirements for use of these asteroid files
X  are similar to that of the rest of Astrolog, in that they are freely
X  available for non-commercial use but unavailable for commercial use.
X
-b0: Like -b but display locations to the nearest second too.
X
X  The ability to display zodiac positions to the nearest degree second
X  is supported with the -b0 switch. Normally all positions are
X  displayed just to the minute (which was all that is useful due to the
X  accuracy available in the Matrix formulas). With the Placalc routines
X  accurate to within seconds, this switch, in addition to turning on
X  the more accurate formulas like just -b above does, will also turn on
X  the more accurate display.
X
X  When this setting is on, the planet and house positions in the -w
X  text wheel chart, and the sidebar positions in graphic wheel charts,
X  will be to the nearest second. The -Z local space chart will display
X  the altitude and azimuth to the nearest second, while the other three
X  vector columns will be displayed with an extra digit of precision.
X  The -S orbital position chart will have all five of its columns
X  displayed to an extra four digits of precision. The -L0 astro-graph
X  chart with latitude crossings will display the latitude crossing
X  intersections to the nearest second.
X
X  Finally the standard -v listing will display the zodiac positions and
X  latitudes to the nearest second, and the velocity values will have
X  an extra four digits of precision. Note however this doesn't leave
X  room to the right anymore for the house cusp positions and element
X  table normally shown. They will be left out for -b0, however when
X  the -C switch is in effect, the house cusp positions will be
X  displayed in their own separate rows, which normally isn't ever done
X  since there's always the list to the side. (One more thing is that
X  -b0 combined with -v will display an extra column at the end showing
X  the decan positions of each object, allowing viewing of each planet
X  alongside its decan without having to actually change positions with
X  the -3 switch.)
X
-c <value>: Select a different default system of houses.
(0 = Placidus, 1 = Koch, 2 = Equal, 3 = Campanus,
4 = Meridian, 5 = Regiomontanus, 6 = Porphyry, 7 = Morinus,
8 = Topocentric, 9 = Alcabitius, 10 = Equal (MC),
11 = Neo-Porphyry, 12 = Whole, 13 = Vedic, 14 = None.)
X
X  Fifteen different house systems are supported in the program: Invoke
X  as astrolog -c <number> to change the system from the default of
X  Placidus. Note that certain house systems (i.e. Placidus and Koch)
X  aren't defined for locations inside the Ant/arctic circle. If the
X  user attempts to cast a chart using them with a latitude beyond about
X  66 degrees N or S, the program will display a warning, and then
X  change the latitude of the chart being computed to the closest legal
X  latitude allowed (i.e. move it from the pole to the edge of the
X  Arctic or Antarctic circle) during the computation of the chart.
X  Certain house systems are still defined at extreme latitudes (inside
X  the Arctic or Antarctic circles) but have the condition where the
X  natural formulas for the MC and Asc at those locations would put the
X  Asc in the 180 degrees before instead of after the MC. In such a case
X  Astrolog preserves the Midheaven, and flips the Ascendant if need be
X  to ensure the other house cusps will remain sane.
X
X  House system number 10 is the Midheaven based Equal house system. This
X  is just like the more common standard Equal house system (-c 2)
X  except that we start with the 10th cusp being the same as the MC and
X  disassociate the 1st cusp from the Ascendant, instead of starting
X  with the 1st cusp being the same as the Ascendant and disassociating
X  the 10th cusp from the MC.
X
X  House index 11 is the Neo-Porphyry system of house division. This is
X  a new system similar to Porphyry houses except that it's "smooth"
X  around the zodiac with the MC/Asc difference being spread in a
X  continuous sinusoidal manner from expanded to compressed quadrants.
X
X  House index 12 is the Whole system of houses, where the first cusp is
X  at zero degrees of the sign of the Ascendant, and the others are all
X  at the beginning of the succeeding signs. This is basically the same
X  as the Equal system with all positions shifted back to the start of
X  their sign. Thanks to Andy Gray for telling me about this system and
X  how it's computed.
X
X  House index 13 is the Vedic system of houses, or more specifically
X  the modern India style of Equal houses. In this system, each house
X  covers 30 degrees, and the Ascendant is always in the middle of the
X  first house, i.e. the 1st cusp is always 15 degrees before the
X  Ascendant. (For contrast, the ancient or traditional India style of
X  equal houses are already supported in Astrolog by the Whole house
X  system above, where the first house cusp is always the start of the
X  sign the Ascendant is in.)
X
X  House system 14 refers to no houses at all, or in other words where
X  the Ascendant will always be 0 degrees Aries, the Nadir 0 degrees
X  Cancer, etc, which is useful for the extended chart animations as
X  described later, where having houses at all can tend to get in the
X  way; one can even observe the precession of the equinoxes with this
X  system if used in conjunction with the -s sidereal chart option.
X
-s [..]: Compute a sidereal instead of the normal tropical chart.
X
X  With this option, the chart will be just like the normal charts as
X  most commonly used in Western astrology, except that all the zodiac
X  positions will be shifted (to be about 24 degrees earlier). This is
X  because the option casts sidereal charts which are based on the
X  positions of the fixed stars (i.e. Aries starts at the constellation
X  Aries) rather than the seasons (i.e. Aries starts at the Spring or
X  Vernal Equinox.) Due to the "precession of the equinoxes" the
X  position of the Sun at the Equinoxes has been gradually happening at
X  an earlier point in the sidereal zodiac each year (taking about 2100
X  years change signs.)
X
X  This switch accepts an optional parameter of an offset for the start
X  of the zodiac. This value, when non-zero, will be added to all zodiac
X  positions, and effectively allows one to choose any starting point
X  for the sidereal (or tropical) zodiac, which is useful for Hindu or
X  other systems whose sidereal zodiacs have zero Aries at a different
X  location than the standard Fagan-Bradley sidereal zodiac the program
X  uses by default. For example, "-s 10.5" will add 10 degrees and 30
X  minutes to all zodiac positions. This value is initialized to a
X  zodiac offset value setting in the astrolog.dat initialization file,
X  which is by default zero.
X
-sr: Compute right ascension locations relative to equator.
X
X  This will display planetary positions relative to the Earth's equator
X  instead of the ecliptic i.e. Earth's orbit. This is the way more
X  commonly used in astronomy, and results in real right ascension
X  notation, especially when combined with the -s sidereal zodiac and
X  -sh hours and minutes display format. This switch makes the
X  declination values in the standard -v listing also relative to the
X  equator, instead of the ecliptic latitude displayed by default, where
X  "Declination" will be printed at the head of the column instead of
X  "Latitude". (Without this the only way to get such information is
X  from the zenith latitudes in the -L astro-graph chart which show the
X  same thing.) Note that this setting isn't fully integrated with all
X  of Astrolog's charts; specifically it will distort the values in the
X  -Z local horizon, -S orbit, and -L astro-graph charts which assume
X  ecliptic positions, and hence -sr shouldn't be combined with these
X  options.
X
-s[z,h,d]: Display locations as in zodiac, hours/minutes, or degrees.
X
X  For astronomers out there, the -sh switch will express all planetary
X  positions in the right ascension hours/minutes format instead of the
X  sign/degrees/minutes astrologers are accustomed to. This will affect
X  how the objects are listed in the -v display, and how star azimuths
X  are displayed in the -HO list. For example, 0 degrees Aries is
X  represented as 0 hr, 0 min; 0 Cancer goes to 6 hr, 0 min, and so on
X  through the 24 hour clock. The -sd switch will cause zodiac
X  positions to be displayed as a simple degree value in the 360 degree
X  circle. To return to the default of displaying as a degree within a
X  zodiac sign, use the -sz switch.
X
-h [<objnum>]: Compute positions centered on specified object.
X
X  Normal astrology charts are based on the positions of the planets
X  relative to the Earth. However, this option allows seeing of the
X  zodiac positions with respect to the Sun's (or any other planet's)
X  point of view. The -h option when invoked by itself will display a
X  heliocentric chart: the Sun in the original listing will be replaced
X  with the Earth's position as seen from the Sun in the heliocentric
X  chart, with the other planets' positions modified accordingly. For
X  bodies other than the Sun, the option takes a parameter to indicate
X  which planet to center the chart on, e.g. do -h 5 to cast a Mars
X  centered chart. (Moon centered charts aren't allowed; in fact, note
X  that when the -b ephemeris setting is off, the -h option won't ever
X  affect the Moon, which will always be displayed as seen from the
X  Earth, no matter what the center body is set to, since it's not a
X  formal planet.) Note also that the Earth has its own object index,
X  which is position number zero, meaning 0 is a valid value to pass to
X  switches that take an object like -R. Charts such as the local
X  horizon chart which don't include the central planet, will
X  automatically leave it out even if that planet is unrestricted.
X
-p <month> <day> <year>: Cast 2ndary progressed chart for date.
X
X  A secondary progression chart for a particular date can be cast using
X  the '-p <month> <date> <year>' command switch. (Note: I'm not sure if
X  the house cusps are progressed correctly for all methods of
X  computation, but they are reasonably close to what is expected using
X  most of them.) The precise time within the given day progressed to
X  is midnight in the default time zone.
X
X  Hackers note: this setting to progress charts to the specified time,
X  may be turned off by invoking the -p switch as "_p" with the
X  underscore reset prefix. Unlike the standard -p switch, _p take no
X  parameters. This is a command switch trick only useful when doing
X  multiple charts in a -Q loop, or when passing extra command lines to
X  a graphics screen with the return key or through macros.
X
-p0 <month> <day> <year>: Cast solar arc chart for date.
X
X  Solar arc progressions are supported in addition to secondaries.
X  Invoke the -p <month> <day> <year> switch as -p0 instead, and a chart
X  will be generated with all planets and house cusps progressed forward
X  an amount equal in degrees to the number of years that have passed
X  between the specified date and the chart in question. The -pd option
X  here (see below) specifies the number of days that have to pass per
X  zodiac degree to progress forward; by default this is 365.25. To
X  generate a solar arc chart for the current moment now, invoke the -pn
X  switch as -p0n.
X
-p[0]n: Cast progressed chart based on current date now.
X
X  The -pn switch is like the -p <month> <date> <year> switch except that
X  (like the -n switch) it assumes the current moment now to cast the
X  progressed chart to. This is just another shorthand convenience to see
X  what ones progressed chart is like presently; just do: astrolog -i
X  file -pn.
X
-pd <days>: Set no. of days to progress / day (default 365.25).
X
X  User definable progression rates can be specified with this option.
X  When using the -p progression option, Astrolog assumes you want the
X  standard "year for a day" rate of progressions. By passing different
X  values to the -pd switch, one can change the default "365.25 days for
X  a day" to any value they want for some less often used method of
X  progression. For example, one can do "-pd 7 -pn" to do a week for a
X  day, "-pd -365.25 -pn" to get negative year for day progressions, and
X  so on. For tertiary progressions, do "-pd 29.530588". (Note that "-pd
X  1 -p..." would be the same as if no progression were done at all.)
X
-x <value>: Cast harmonic chart based on specified factor.
X
X  Harmonic charts (i.e. where all the planet positions are multiplied
X  by a factor and the chart recast) are supported via the "-x" option
X  (e.g. "-x 3" will make all trines conjunct in the chart displayed.)
X  The parameter passed in may range anywhere from 1 (i.e. no harmonic
X  factor) to 30000 for those who want to explore extreme harmonics.
X
-1 [<objnum>]: Cast chart with specified object on Ascendant.
X
X  The -1 <obj> option can be used to change the houses to force a
X  particular object to be on the ascendant. This is useful in casting
X  Solar charts or for when the time of birth is not exactly known. For
X  example -1 2 will case a normal chart, but the house cusps will be
X  rotated so that the moon is on the ascendant.
X
-2 [<objnum>]: Cast chart with specified object on Midheaven.
X
X  Just as the -1 option is used to cast a chart with an object on the
X  Ascendant, the -2 <object> switch will cast a chart with the
X  specified object on the Midheaven. The house cusps will be rotated so
X  that the object in question is conjunct the 10th house cusp. As with
X  the -1 option, if <object> is not specified, the Sun will be assumed
X  by default.
X
-3: Display objects in their zodiac decan positions.
X
X  Decan displays are supported in Astrolog, and one can display a decan
X  influenced chart with the -3 switch. The decan theory is that each
X  sign in the zodiac can be divided into three parts: The first 10
X  degrees (i.e. the first decan) is mainly influenced by the sign in
X  question, the second 10 degrees (second decan) although still
X  influenced by the sign in question is also somewhat influenced by the
X  next sign of the same element, while the last decan is influenced by
X  the third sign of the same element. The -3 switch applied to a chart
X  will move each object into the sign of its decan. For example, if the
X  Sun is at 29 degrees Aquarius and the Moon at 5 degrees Virgo, in the
X  resulting chart, the Sun will go to Libra (26 degrees) and the Moon
X  will remain in Virgo (although be at 15 degrees now since it was
X  previously in the middle of the first decan of Virgo.)
X
-f: Display houses as sign positions (flip them).
X
X  The -f option can be used to "flip" the signs and houses, i.e. display
X  the house as a sign position and vice versa. For example having the
X  Sun at 26 degrees Scorpio, 2/3 way though the 10th house, will cause
X  the resulting Sun under the -f option to be at 20 degrees Capricorn,
X  26/30th the way through the 8th house. This can be used to determine
X  how far a planet is through a particular house, as well as for domal
X  chart analysis that Mark Kenski has informed me about. Domal analysis
X  is based on the fact that for synastry comparisons, for example, a
X  planet in Gemini and one in the 3rd house can be considered related in
X  a way similar to a conjunction.
X
-G: Display houses based on geographic location only.
X
X  This switch generates a special type of locational analysis chart,
X  called a geodetic chart, in which the house cusps are computed from a
X  different source, i.e. as a function of only the longitude and
X  latitude. This basically gives every spot on the planet a different
X  unique set of house cusps, and can be used to analyze the
X  characteristics of different areas, and their influence on you if you
X  insert your own planets in the houses. This type of chart was
X  described in the January 1992 issue of Dell Horoscope magazine, from
X  which I learned how to generate these charts. Basically, the Midheaven
X  is approximately the longitude value converted from degrees into the
X  appropriate zodiac sign; for example 0 degrees E goes to 0 degrees
X  Aries, 30 degrees E goes to 0 degrees Taurus, etc.
X
-J: Display wheel charts in Vedic format.
X
X  Astrolog can display wheel charts in Hindu or Vedic format. This will
X  affect both the text -w wheels and the graphic wheels. A Vedic format
X  wheel is identical to a standard Western wheel except: (1) The signs
X  and houses increase as you go clockwise instead of counterclockwise,
X  so the entire wheel is flipped over. (2) The chart is rotated so the
X  left edge is always the start of Aquarius instead of the Ascendant,
X  putting Pisces in the upper left corner, meaning the Ascendant is
X  placed wherever in the wheel is appropriate. For Vedic astrology one
X  will probably prefer to combine this with the -w house focused wheel
X  chart switch so all the houses are the same size, or even display
X  that chart in text mode so the wheel will be a square.
X
-9: Display objects in their zodiac navamsa positions.
X
X  This command switch will display the chart in the navamsa format used
X  in Vedic astrology. The navamsa or marriage chart is formed by
X  applying a formula to each planet position to get a resulting new
X  location. This is similar in operation to the -3 decan feature,
X  however this divides each sign into ninths. Specifically, to convert
X  a position, see which ninth of a sign a planet falls in, e.g.  a
X  planet from 0 degrees 0' to 3 degrees 20' of a sign is in the first
X  ninth, a planet from 3 degrees 20' to 6 degrees 40' is in the second
X  ninth, and so on. Take that number, and count one less than that many
X  signs ahead in the zodiac to get the resulting sign. The starting
X  sign should be Aries if the original sign was Fire, Capricorn if the
X  original sign was Earth, Libra if the original sign was Air, and
X  Cancer if the original sign was Water. A formal navamsa chart only
X  considers signs, hence only the sign of each planet will be changed;
X  the degree within each sign will be unaffected.
X
-F <objnum> <sign> <deg>: Force object's position to be value.
X
X  The -F option is used to force a particular object's position to
X  always be a particular location in the zodiac. This feature can be
X  used as an easy way to manually include things Astrolog normally
X  doesn't in various charts. For example, this can be used to force the
X  position of some minor thing, like the Vertex, to always be the
X  location of whatever you prefer, like the 0 degrees Aries point, or
X  an important midpoint. Then you can do an aspect grid, transit
X  search, or whatever, and calculate aspects to midpoints or transits
X  over midpoints. The -F switch takes three arguments: first is the
X  index of the object to replace, next is the sign from 1..12 to force
X  it to be, and third is the degree within the sign. For example, if I
X  want to see if anything is making an exact aspect today with my Sun
X  Moon midpoint at 6Sag28, I could do "astrolog -n -d -F 16 9 6.28",
X  which would replace the North Node with my Sun Moon midpoint in the
X  aspect search.
X
-+ [<days>]: Cast chart for specified no. of days in the future.
X
X  The -+ <#ofdays> option will cast a normal chart, but one for #ofdays
X  in the future (or past if a negative value is given). One use for
X  this is in combination with the -n and -d options. For instance, I
X  often invoke the program as "astrolog -n -d" to see the exact times
X  of today's aspects. However, just before midnight I might want to
X  see what's going to happen in the following day, so I would do
X  "astrolog -n -d -+ 1" to see the exact times for tomorrow's aspects.
X  The #ofdays parameter is optional, and will default to one if left
X  off, so the above command can be done as just "astrolog -n -d -+".
X
X  Note that for such a chart, the chart header will show the correct
X  date of the actual new chart, instead of the original one. For
X  example, today (9-11), if I do "astrolog -n -+ 2" I will get the
X  chart for two days from now, and the chart header will display 9-13.
X  This has some special uses. For example, if you want to know what the
X  date was/will be when you are 10000 days old, do "astrolog -i
X  yourchart -+ 10000" and see what the date in the resulting chart
X  header is.
X
-- [<days>]: Cast chart for specified no. of days in the past.
X
X  This "dash minus" option is just like the "dash plus" (-+) option
X  described above, except it subtracts instead of adds the specified
X  number of days from any chart cast. This is only for convenience, in
X  that "-- 1" is the same as "-+ -1".
X
-+[m,y] [<value>]: Cast chart for no. of months/years in future.
X
X  The -+m switch is just like the -+ switch above except that it will
X  add one month (30 days) to whatever chart instead of one day. The
X  -+y switch will add one year (365 days) to whatever chart. The --
X  "dash minus" switch is extended in a similar manner, in that --m and
X  --y will do as expected. These switches also have the optional
X  parameter to specify how many months or years to move forward or back.
X
--
X
Switches for relationship and comparison charts:
X
-r <file1> <file2>: Compute a relationship synastry chart.
X
X  Computing the relationship between two charts is supported. Invoke the
X  program as 'astrolog -r <file_of_person1> <file_of_person2>' and the
X  program will give you the relationship between the two charts. In
X  other words, the program will use the positions of person2's planets
X  and person1's houses. Use this with the -w option to get a wheel chart
X  and you can do synastry. Note that transits can be computed with this
X  by comparing your chart with the positions of the planets at the
X  current moment (as in -n switch). To make this easier, you may specify
X  the filename "now" for any file and the computer will use the current
X  planet positions instead of looking for a like named file. (e.g.
X  'astrolog -r me now' will compute transits for file 'me'.)
X
X  Hackers note: if the -r switch is invoked as "_r" with the underscore
X  reset prefix, whatever relationship mode will be canceled. Unlike the
X  standard -r switches, _r takes no file parameters. This is a command
X  switch trick only useful when doing multiple charts in a -Q loop, or
X  when passing extra command lines to a graphics screen with the return
X  key or through macros. Astrolog's -r relationship chart switches set
X  relationship chart mode, and without this there's no easy way to
X  return to single chart mode. Yes when a graphics screen is up, the
X  'c' key will toggle relationship comparison mode, but that's not
X  available from the command line.
X
-rc <file1> <file2>: Compute a composite chart.
X
X  The '-r' option can be used to generate composite relationship
X  charts. Simply invoke it as '-rc <person1> <person2>' instead of
X  just -r and a composite chart (i.e. composed of the midpoints of the
X  planets, etc. of the two charts in question) will be generated.
X  (Note: when the house cusps in the two charts are nearly 180 degrees
X  apart, simply taking the midpoints of all the cusps may result in
X  them being out of order in the resulting composite. In such a case we
X  give priority to the composite midheaven, and invert the midpoints of
X  any of the other cusps or the Ascendant by 180 degrees if leaving
X  them that way would have things out of order.)
X
-rm <file1> <file2>: Compute a time space midpoint chart.
X
X  Time-space midpoint relationship charts are supported: Doing "-rm
X  chart1 chart2" will calculate the time and location exactly half way
X  between the times and locations as indicated in the two files. Unlike
X  all other types of relationship charts, this one actually exists in
X  space and time, and therefore can be treated like a single chart and
X  can be output to a file with the -o option.
X
-r[c,m]0 <file1> <file2> <ratio1> <ratio2>: Weighted chart.
X
X  The -rc composite and -rm time-space midpoint relationship charts may
X  be weighted to give more influence to one of the charts. When the
X  switches are invoked as -rc0 or -rm0 they accept two additional
X  parameters which are the ratio weights to give to the two chart files
X  in question. For example, the sequence "-rm person1 person2 2 1" will
X  still do a time space midpoint chart, but the time and location that
X  the chart is cast for will be biased at a 2:1 ratio toward person1,
X  i.e. will be 2/3 of the way from person2's chart info closer to
X  person1's info.
X
X  Note that the -rc0 switch can be used to generate multiple composite
X  charts between more than two people! A composite chart between two
X  people can already be done and saved to a file with "-rc person1
X  person2 -o0 composite12". A third person can now be merged in by
X  doing a composite between it and the composite of the first two, but
X  giving the first result a 2:1 ratio because two charts have already
X  gone into it, by "-rc0 composite12 person3 2 1 -o0 composite123". A
X  fourth person can then be merged in at a higher ratio with "-rc0
X  composite123 person4 3 1 -o0 composite1234" and so on. Actually this
X  method won't always generate a 100% correct multiple composite chart
X  in cases where the objects are spread out over 180 degrees and the
X  initial composites put the current midpoint in the wrong half, e.g.
X  if the Suns of person1 through person3 are 1Can, 29Sag, and 0Ari,
X  then the true composite Sun is at 0Ari, but composite12 is at 0Lib
X  and hence the final composite is at 0Leo or 0Sag, in the wrong
X  "quadrant" biased toward the earlier results. Still the results are
X  useful and the method can be used with -rm0 to get the correct
X  average between multiple chart locations.
X
-rd <file1> <file2>: Print time span between files' dates.
X
X  One useful non-astrological function in the program is the ability to
X  determine how much time has passed between two dates, with the -rd
X  switch. As with the -rb option below, this is considered a
X  relationship "chart" because it requires the input of two different
X  dates, and when -rd is in effect, again the standard -v planet
X  position listing will be replaced by a line telling how much time has
X  passed in the interval. The time difference is expressed in seven
X  ways: to the nearest year, month, week, hour, minute, and second.
X  For example, "-rd person1 person2", will display how many years,
X  days, etc person1 is older than person2 (or the other day around).
X  Want to say know how many years older your mother is than you? Just
X  do "-rd momchart yourchart". Want to find out how many days old you
X  will be on Jan. 1, 2000? Do "-rd yourchart tty", and type in the
X  first date of the next millennium, and see what you get!
X
-rb <file1> <file2>: Display biorhythm for file1 at time file2.
X
X  Biorhythm charts are supported by Astrolog with the -rb switch.
X  Although not directly related to Astrology, the concepts are similar,
X  and adding this didn't require much extra code, and since some are
X  interested in this, I felt I'd add it in. The biorhythm theory says
X  that we have three main types of energy: Physical, Emotional, and
X  Intellectual. These three run in continuous wave cycles from high to
X  low, each of which repeats about every 30 days or so. Therefore, a
X  biorhythm chart for a particular day should describe how much energy
X  one has or how they are feeling in this area. Now, Astrolog considers
X  biorhythm charts as a type of relationship chart, because in order to
X  generate one, two dates or charts are needed: the birth date of the
X  person, and the date to cast their chart for. Technically the program
X  will replace the standard -v listing of planet positions with the
X  biorhythm chart when -rb is in effect. As an example, "-rb file1
X  file2" will cast the chart for the birthday signified by chart1 or
X  chart2 (whichever is older) for the date in the other file. Remember
X  that one can substitute the pseudo filename 'tty' to mean get the
X  chart info from the terminal instead.
X
X  The actual biorhythm chart itself will display, for the day in
X  question, what the percentages of the physical, emotional, and
X  intellectual cycles are, as numbers from -100% (low ebb) to +100%
X  (happy and full of energy). In addition, the biorhythm percentages for
X  the seven days before (T-7 days) and the seven days after (T+7 days)
X  the date in question will be listed, too, so one can see if the
X  cycles are rising or falling. Finally, as a cute way to help in
X  interpretation, the program prints the appropriate smiley, medium, or
X  sad face after each percentage. (BTW, it takes over 58 years for all
X  three cycles together to synchronize and repeat themselves.)
X
-r0 <file1> <file2>: Keep the charts separate in comparison.
X
X  There is a distinction between any of the above types of particular
X  relationship charts and the actual comparison between two separate
X  charts. The -r0 option is used to generate actual comparison charts.
X  For example, combining -r0 with the -g switch will cause a full grid
X  chart of the aspects between all the planets of the two charts (with
X  person1's planets on the vertical axis and person2's on the
X  horizontal) to be displayed. (Unfortunately, if all 20 of the
X  default objects are left unrestricted here, the grid will exceed 80
X  columns, unless the -Y8 80 column clip feature (described later) is
X  turned on.) The -r0 option can also be used with the -X switch to
X  generate true relationship wheel charts, (described later). The -r0
X  option will act like the -r synastry option in certain displays that
X  can't compare two charts; for example, '-r0 -v' will act the same as
X  just '-r -v'. (Note: the "-t file" current transit option is
X  basically a shorthand way of doing "-r0 file now".)
X
X  Comparison relationship charts may also be generated for the -m
X  midpoint and -a aspect list options. Combining -m with -r0 will
X  yield an ordered list of all midpoints between all combinations of
X  one planet from chart1 and another planet from chart2. Combining -a
X  with -r0 will yield a list of all aspects between planets in the two
X  charts, in order based on what Astrolog think their influences are.
X  So, if you really want to know if your Sun widely trining your SO's
X  Moon, will override the effect of your Saturn closely squaring their
X  Mars, do "astrolog -r0 yourchart sochart -a" and see the influence
X  given to each aspect.
X
-rp[0] <file1> <file2>: Like -r0 but do file1 progr. to file2.
X
X  This switch is a form of the -r0 relationship comparison charts. This
X  switch, given two files, will compare the natal chart in file1, to
X  the chart of this natal chart progressed to the time specified in
X  file2. This is a shorthand way to the commonly desired comparison of
X  a progressed chart to a natal one. The -y switch may be invoked as
X  -yp <file> which will automatically compare the chart to the current
X  time now. For example, to get a dual graphic wheel chart with your
X  natal planets in the inner wheel, and your current progressed chart
X  on the outer wheel, simply do "-yp yourchart now -X". (There is no
X  easy way to do this otherwise, short of using -o0 position files,
X  since the -p progression switch will affect all charts.) The -rp
X  switch may also be invoked as -rp0, which will do the same thing but
X  as a solar arc progression instead of a secondary progression.
X
-rt <file1> <file2>: Like -r0 but treat file2 as transiting.
X
X  The -rt switch will behave exactly like the existing -r0 chart
X  comparison option but with one difference: transit restrictions will
X  affect the second chart. With -r0, both charts are treated as natal
X  charts and hence the normal -R restrictions apply to both, but one
X  may want to have different sets of planets active in the two charts,
X  such as in a wheel chart where transiting planets are being compared
X  to natal. The -y switch which is like the -r0 switch but assumes the
X  current moment now for the second chart, may be done as -yt in the
X  same way. For example, to do a graphic bi-wheel showing your complete
X  natal chart in the inner wheel, and only the current transiting outer
X  planets on the outer wheel, do "astrolog -yt yourchart -X -RT0 jup
X  sat ura nep plu".
X
-r[3,4]: Make graphics wheel chart tri-wheel or quad-wheel.
X
X  Astrolog can do tri-wheel and quad-wheel graphics charts. These are
X  like the standard and bi-wheel charts, but with a third and/or fourth
X  ring of planets. The standard or first chart in memory is placed on
X  the outer wheel, next in is the second chart in memory, where the
X  third and/or fourth charts are on the inside. (Note this is different
X  from the bi-wheel graphic which has the first chart on the inside and
X  the second on the outside.) The house cusps and the graphic sidebar
X  if showing will correspond to the info in the first ring. There is
X  never any aspect display in the middle of the wheel, but when the -Xi
X  alternate chart display flag is set, the program will draw dotted
X  lines from each planet in the outer rings to the inner one, as is
X  always done in the bi-wheel chart. The -r3 switch, taking no
X  parameters, puts one in tri-wheel mode, and the -r4 switch puts on in
X  quad-wheel mode. (You can also do -r2 to enter bi-wheel mode, and -r1
X  or _r to return to the standard single wheel.) 
X
-y <file>: Display current house transits for particular chart.
X
X  The command switch '-y <file>' can be used as a shortcut way to
X  compute the current transits for the chart in <file> (unless the TIME
X  features are compiled out), which saves you from having to mention
X  the "now" in the -r0 option.
X
-y[b,d,p,t] <file>: Like -r0 but compare to current time now.
X
X  The -y option is extended based on the -rb and -rd features. The -yb
X  <file> switch will display the person indicated in file's biorhythm
X  for today. The -yd <file> switch will display how many months, days,
X  etc old the person in the file is right now. Want to know how many
X  minutes old you are? Just do "-yd yourchart". Do the same command
X  again right away and see that you are now a couple seconds older than
X  the first time! There are also switches -yp[0] and -yt which similarly
X  behave like -rp[0] and -rt above but automatically compare to now.
X
--
X
Switches to access graphics options:
X
-k: Display text charts using Ansi characters and color.
X
X  With this option, the text charts may be displayed in color, as well
X  as with real graphics characters instead of with things like dashes
X  and pluses. This makes the text charts look almost as neat as their
X  color graphics counterparts. All that's needed is a terminal that
X  accepts Ansi escape sequences. You will get garbage if you include -k
X  on a non-Ansi terminal. (For this reason, the default for this flag
X  is off, although it can be made on all the time by setting the
X  appropriate flag in the astrolog.dat configuration file.) Most PC's
X  are in Ansi mode, so if you have a PC this should work. Include the
X  -k switch on the command line, and the program will display all
X  charts as before, but change the color appropriately for every part
X  of any chart printed! Just try a -w chart, a -g grid, or a -t list
X  and see the difference of how much easier it is to find a planet or
X  aspect among a large chart! I highly recommend this setting be made
X  on by default in the astrolog.dat file if your system will support
X  it, especially for PC users who display text charts on the screen
X  more often than they print one out.
X
X  Color isn't used randomly but is based on logic. Most colors are very
X  similar to the ones chosen in the color X charts. In general,
X  everything is based on the following rules for elements: Fire is Red,
X  Earth is Yellow, Air is Green, and Water is Blue. Zodiac signs and
X  positions are printed in the color of their element. Houses are
X  printed in the color of their corresponding sign. Planets are printed
X  in the color of the sign they rule. As for the other objects, we have
X  the following colors: Asteroids are in bright purple (magenta),
X  Uranians are in dim purple, and non-physical points like the Node,
X  Fortune, and Vertex are in a bluish gray (dark cyan). Stars are
X  either orange if they are bright (magnitude < 1.0) or a dark red if
X  dimmer. For aspects we have the following: Conjunctions are Yellow,
X  Oppositions are Blue, Squares are Red, Trines are Green, Sextiles are
X  Light Blue (Cyan). For the minor aspects we have magenta for
X  inconjunct/semisextile, orange for semisquare/sesquiquadrature, dark
X  cyan for all the quintiles, dark purple for all the septiles, and
X  dark red for all the noviles.
X
-k0: Like -k but only use special characters, not Ansi color.
X
X  This minor switch is just like the -k switch, however it only toggles
X  whether the high Ascii graphics characters are used, as opposed to -k
X  which toggles both that and whether Ansi colors are used. A system
X  with a black and white monitor may want to use high graphics but not
X  color, while a system with a foreign character set may prefer color
X  but not graphics characters.
X
-V <25,43,50>: Start up with text mode set to number of rows.
X
X  For PC's compiled with screen graphics, the -V switch will change the
X  text screen to have the specified number of rows, assuming the
X  hardware available supports it. Legal values are 25, 43, and 50. This
X  most useful as an initial parameter when running the program from
X  Microsoft Windows (see later) to give more text rows to work in, or
X  in the -Q loop mode (see later), as well as being another way of
X  getting to the functionality of the DOS "mode" command. Note that
X  for Astrolog builds made using the Borland compiler, only the 25 and
X  50 line modes are available; attempting to enter a 43 line mode will
X  go to 50 rows.
X
-X: Create a graphics chart instead of displaying it as text.
X
X  This is the general switch, which means display a chart in an X window
X  instead of on the screen in some form. For example, the command
X  'astrolog -i mychart -X' will open a new window and display the chart
X  in question in it. (Of course, all the other switches, e.g. -R, -c,
X  -1, etc, can be used to change what info is actually displayed.) If
X  you use the -L astro-graph switch in addition to this, the appropriate
X  Astro*Carto*Graphy map will come up in a window instead of the earlier
X  boring list of longitudes. (e.g. astrolog -i me -X -L) The -Z and -g
X  switches will produce their own chart types as well, although, of
X  course, only one type of chart can be in a window at any given time.
X
-Xb: Create bitmap file instead of putting graphics on screen.
X
X  This switch will cause a bitmap file to be produced and written to a
X  file instead of putting the graphics on the actual screen. This is
X  useful if you want to convert the graphics to different formats, e.g.
X  so they can be displayed on alternate systems, etc. Note that -Xb (or
X  any other -X<letter> switch) automatically assumes the -X switch
X  above, so 'astrolog -i file -Xb' is sufficient (and you don't also
X  have to include the -X).
X
X  Bitmap files may be generated at any size without running out of
X  memory. If any particular sized bitmap it too large to fit in memory
X  all at once, Astrolog will generate it in multiple stages, using
X  available memory to do one section at a time, writing each piece to
X  the file as we go along. (This is similar to the banding method often
X  used to print large images to printers.) For versions of PC Astrolog
X  before 4.20, there was barely enough memory in the 640K available to
X  generate even the standard 640x480 color bitmap. Now one will always
X  be able to do any size allowed, even the maximum of 2730 by 2730
X  yielding a file nearly four megabytes in size! We do however have to
X  draw the chart once for each band, so if a bitmap is done in two
X  stages, it will take nearly twice as long to generate. Larger bitmaps
X  require more stages and more time, but we can at least always make
X  them. This banding is only done for the Windows bitmap format; the
X  other formats still need to be done in one shot, however the other
X  formats are usually done on non-DOS systems where memory isn't
X  limited to 640K.
X
-Xb[n,c,v,a,b]: Set bitmap file output mode to X11 normal,
compacted, very compact, Ascii (bmtoa), or Windows bmp.
X
X  The bitmap file can be written in five different formats; by default
X  whatever format specified at compile time is used. One can change
X  this mode by putting an extra character on the command line after the
X  -Xb switch. Specifically, to override the compile time mode, use -Xbn
X  for a standard X11 bitmap, -Xbc for an X11 bitmap with some white
X  space removed, -Xbv for a very compact X11 bitmap (which may not be
X  able to be processed correctly by all X programs), -Xba for a one
X  character per pixel Ascii dump identical to the result generated from
X  the X11 bmtoa program, and finally -Xbb for the Windows .bmp bitmap
X  described below.
X
X  One of the available bitmap formats are the .bmp extension bitmap
X  files commonly used on PC's running under Microsoft Windows. If you
X  have a PC running Windows, you can set your root background to be one
X  of these monochrome Astrolog bitmaps by: use the -Xb option to create
X  a bitmap file, then rename it to have the extension .bmp and put it
X  in your Windows subdirectory, then go into Program Manager -> Control
X  Panels -> Desktop and select this file to be your "wallpaper". These
X  bitmap files may be generated in either color or black and white.
X  By default, all graphic charts will be in color, unless specified
X  otherwise. Color is most useful for these PC bitmaps (-Xbb), although
X  a color bitmap will take up more disk space. X11 bitmap files will
X  always be output in monochrome format, since color .xbm files don't
X  exist. A color Ascii file (-Xba) will have the color value of each
X  pixel converted to a hexadecimal number, instead of being in the
X  format generated by the Unix bmtoa utility in the case of monochrome
X  charts.
X
-Xp: Create PostScript stroke graphic instead of bitmap file.
-Xp0: Like -Xp but create complete instead of encapsulated file.
X
X  Astrolog can generate PostScript graphics files. PostScript is a
X  graphics format different from bitmaps in that it's based on
X  "strokes" as opposed to "pixels". With a stroke graphic, an image is
X  defined in terms of "circle here, line there, etc" instead of a large
X  array. This means PostScript graphics can be printed at any size
X  without losing accuracy or becoming "blocky", and look perfectly
X  smooth when printed to a laser printer. A PostScript file is also
X  about an order of magnitude smaller in size than a corresponding
X  bitmap file.
X
X  To generate a PostScript chart, use the -Xp switch. This will work
X  just like bitmap files for all Astrolog's graphics charts, in that
X  you will be prompted for a file to write the graphics to unless you
X  explicitly pass a file to the -Xo switch. The type of file generated
X  will be an encapsulated PostScript graphic (which are usually seen
X  with a .eps extension) meaning that it's made to be inserted into a
X  document and scaled and so on and printed from there. A true
X  independent PostScript file which can be sent directly to a printer
X  can be generated by specifying -Xp as -Xp0 instead. As with bitmaps,
X  it is recommended to include -Xm for a monochrome graphic unless you
X  have a color printer, and to include -Xr so the chart is black on a
X  white background (so that you don't cover 90% of the page with ink
X  when printing)!
X
X  There is a compile time option #define PS in the astrolog.h which can
X  be commented out to disable the -Xp switch and all PostScript
X  features. Note that on an X window system one may directly print out
X  a bitmap to a PostScript printer even without this internal support.
X  One simply brings up an Astrolog chart in an X window, or creates a
X  bitmap and displays that bitmap in a window using some other graphics
X  program, and then uses the Unix command "xdpr" to print it, with a
X  line such as "xdpr -P<postscriptprintername> -device ps", and then
X  clicking on the window to print it to the specified printer. Of
X  course, the native PostScript charts will look much smoother.
X
X  Special thanks goes to Mr. Brian D. Willoughby (who BTW also lives
X  really close to where I work, and who helped me restore the files on
X  my NeXT optical disk after it crashed thereby recovering my only
X  copies of Astrolog versions 1.00 through 2.00) who wrote the routines
X  and parts in the xgeneral.c file which deal with PostScript (e.g.
X  what's the PS command to draw a line, ellipse, filled rectangle,
X  etc.) Basically, if it's inside #ifdef PS, Brian likely gets credit
X  for it, for anything else (except the placalc.c file of course, and
X  the Matrix routines which are marked as so) I'm the one to blame. :)
X
-XM[0]: Create Windows metafile stroke graphic instead of bitmap.
X
X  -XM switch: Yet another graphics format, Astrolog can generate
X  Windows metafiles. Metafiles are those files (usually with extension
X  .wmf and often called "pictures" for users) that are frequently used
X  in Microsoft Windows for clipart and other such things. (Astrolog is
X  one of the few non-Windows programs which can generate metafiles
X  internally without relying on Windows itself.)
X
X  Like PostScript, metafiles are a "stroke" graphic format. Metafiles
X  are in binary format unlike the human readable Ascii text in
X  PostScript files, and hence are smaller in size for the same image.
X  Although the same chart generated in PostScript and metafile format
X  will more or less look the same, for PC and Windows users, metafiles
X  are preferred. (For Unix systems PostScript is preferred since there
X  aren't many Unix apps out there that know or care about Windows
X  metafiles, while PostScript is a standard used everywhere.) A
X  metafile can be inserted as a picture into Word, CorelDraw, and
X  pasted into Windows Write and many other applications. Unlike
X  PostScript, a metafile can be displayed on the screen in your
X  document, instead of like most EPS files which when displayed by
X  Windows just indicate that "this is an PostScript image" and have to
X  be printed to be seen. A metafile can actually be edited in MS Draw
X  and many other drawing applications where one may modify the Astrolog
X  chart, change colors, add text, and so on before printing!
X
X  Metafiles (and PostScript graphics) have the option to include actual
X  system fonts for text, as well as even zodiac sign, planet, and
X  aspect glyphs! This will look smoother than having Astrolog fake all
X  the characters with 45 degree line segments. There is a setting in
X  the astrolog.dat file which when set by the user will always use
X  system fonts instead of simulating them. If the -XM switch is invoked
X  as -XM0 instead, the status of this flag will be toggled for the
X  chart generated. (This switch can be used with PostScript charts by
X  specifying "-XM0 -Xp".) In the PostScript charts, the following
X  printer fonts are used: Courier for text, Times Roman for house
X  labels, and Astro for Sign, Planet, and Aspect glyphs.
X
X  For these metafiles, the following Windows TrueType fonts are used:
X  Courier-New for text, Times New Roman for house labels, Wingdings for
X  sign glyphs, and Astro-SemiBold for Planets and Aspect glyphs. All of
X  these fonts should be installed in your system already except likely
X  Astro-SemiBold. This font, created by Kenneth Hirst, is available
X  from the Magitech FTP site in the directory /pub/astrology/fonts in
X  the file 6ttfont.zip. It's also available at Kenneth Hirst's Web site
X  at http://ourworld.compuserve.com/homepages/kenneth_hirst/download.htm.
X  To install it on Windows, unzip this file, then go into the Windows
X  Control Panel and select the Fonts icon. Click on the Add button and
X  select the file "astro-se.ttf" that was in the zip archive, and the
X  font will be installed on your system. If it's not installed, the
X  planet and aspect glyphs will appear as letters. (Hack: If you can't
X  get access to the Astro font, but still want all the other fonts to
X  be included, one can set the value of the -YXf "use actual fonts"
X  setting in astrolog.dat to 2 instead of 1, which will cause only the
X  planet and aspect glyphs to be simulated by Astrolog.)
X
X  It is possible that a metafile using all the system fonts may print
X  perfectly to a PostScript printer, but an PS file itself won't find
X  the Astro font. This is because the Astro font may be installed on
X  your Windows system, but not on the printer itself, and because when
X  printing a metafile to a printer, Windows will conveniently
X  automatically embed the necessary font information in what it sends
X  to the printer if the font isn't already there. Note that one may
X  actually generate a PostScript chart from a metafile in Windows by
X  using the Print Manager (or the Setup dialog button available from
X  within those Windows host applications that use the standard Print
X  dialog) to set printing to be to an encapsulated PS file instead of
X  directly to a printer. Of course doing this won't likely be needed
X  since Astrolog can generate PS files natively.
X
X  Like bitmaps, creating metafiles is also efficient in how it uses
X  memory. Astrolog will attempt to allocate a large buffer for them,
X  and keep decreasing the amount until it succeeds. (Note that the
X  related PostScript charts don't need any memory buffers because
X  they're written to disk while being generated.) There is a compile
X  time option #define META in the astrolog.h which can be commented out
X  to disable the -XM switch and all metafile features.
X
-Xo <file>: Write output bitmap or graphic to specified file.
X
X  This switch is used in conjunction with the -Xb, -Xp, or -XM options,
X  to specify the name of the file to write the graphic image to. If
X  not included the program will prompt you for the filename before
X  writing to disk.
X
-XB: Display X chart on root instead of in a separate window.
X
X  For X window systems only, this switch will cause the chart graphics
X  to be displayed directly on the root window. This action occurs very
X  quickly since the program does not have to write a separate bitmap
X  file and call xsetroot -bitmap on it (although one could easily do
X  this if they want to). For example, one could put the line 'astrolog
X  -n -XB' in their .xsession file and whenever they log in, their
X  background will be set to a chart of the current state of the planets!
X
-Xm: Create monochrome graphic instead of one in color.
X
X  For systems without color monitors, the -Xm switch will create all
X  charts in monochrome B/W mode. One can still generate color bitmap
X  files on a monochrome system, just can't properly display them of
X  course.
X
-Xr: Create chart graphic in reversed colors (white background).
X
X  Normally the charts comes up white on a black background. To get the
X  chart or bitmap displayed in reverse video (black on white), use this
X  -Xr switch.
X
-Xw <hor> [<ver>], -ge[..]: Change the size of chart graphic.
X
X  The default graphic chart size is 480x480 units. This can be changed
X  with the -Xw switch. -Xw with one argument n will make an n by n
X  chart; -Xw with two arguments x and y will make an x by y image.
X  Note that this switch will not affect astro-graph or aspect grid
X  windows; to change the size of these use -Xs below.
X
X  For X window systems only, Astrolog accepts the standard -geometry
X  switch (which can be abbreviated as -geom or anything starting with
X  -ge). This is only an alias to this -Xw chart size switch, in that it
X  takes the same parameters in the same way. PC graphics charts may be
X  automatically sized to the dimensions of the screen by passing zero
X  to either or both parameters of the -Xw switch. (Without this, to
X  fill the screen or prevent clipping, one would have to find out the
X  dimensions of whatever graphics mode beforehand, or manually press
X  the 'B' key to do the same thing.) If -Xw is passed zero under X
X  Windows, it will use the compile time default window size.
X
-Xs <100,200,300,400>: Change the size of map or characters by %.
X
X  Note that the size of the planet and sign glyphs don't change when
X  you change the size of a graphics chart. This can cause problems for
X  very small charts where the glyphs overlap the rest of the chart and
X  for very large charts where there is lots of excess space. The -Xs
X  switch can be used to change the size of all glyphs. The valid values
X  that can be passed to it are 100, 200, 300, and 400 where 200 is the
X  default. Note that this switch is used to change the size of the
X  astro-graph (and aspect grid) graphic charts (because the world map
X  is sort of considered to be one giant glyph by the program.)
X
X  Astrolog has its own internal character set definitions for the
X  glyphs which it just draws at a higher scale based on the -Xs
X  setting. This can make glyphs at higher scales look slightly blocky.
X  To help prevent this, there's a second alternate "internal font" of
X  double sized glyphs for planets, signs, aspects, and house numbers,
X  which allow the 100% or small scale, and the 200% or medium scale
X  glyphs, to appear smooth to the nearest pixel. (The improved larger
X  glyphs are also used at the 400% or huge scale, and when printing.)
X
-Xi: Create chart graphic in slightly modified form.
X
X  Certain people have asked that some of the graphics charts be modified
X  in various minor ways, i.e. in either adding or removing certain
X  information. Rather than add a new hard to remember minor option for
X  each change, I have added one major switch which covers all the
X  charts. The -Xi switch will invoke this "induce/inhibit information"
X  option, and pressing the 'i' key in a window will accomplish the same
X  thing by toggling the mode's status. By default, all the charts are
X  as before, but when this bonus option is set, it affects each graphic
X  chart in a different way, as follows:
X
X o For the standard -v and relationship -r0 -v wheel charts, it will
X   inhibit the display of the aspect grid in the center - useful for
X   speed or when doing large time lapse animations when it would get in
X   the way.
X
X o For the -g aspect grid, it will flip the aspects and midpoints across
X   the center diagonal, i.e. the midpoints will be below it and the
X   aspects above it, instead of the other way around. For the -r0 -g
X   relationship aspect grid, the entire grid will be replaced with one
X   showing all midpoints between all the objects in the two charts.
X   Note: The -g0 switch when combined with -r0 will also generate a
X   relationship midpoint (as opposed to aspect with just -g) grid.
X   However, this will revert back to the aspect grid if both -Xi and -g0
X   are in effect with -r0.)
X
X o For the -Z horizon chart and -S space chart, it will, for the major
X   planets, increase the size of the "points" showing where each object
X   actually is, making a brighter "spot", for easier viewing; combine
X   this in the horizon chart with the 'l' key label inhibitor and get a
X   very realistic view of the night sky, with planets brighter and all.
X
X o For the -L astro-graph chart, this will eliminate the display of the
X   Ascendant, Descendant, and Nadir lines, leaving just the vertical
X   Midheaven lines and zenith points, for a remarkable increase in speed
X   and much less clutter when including many objects.
X
X o For the -XW world map display, this will show the Earth's ley line
X   locations by drawing them on top of the map. Familiar with ley lines?
X   They are lines of energy crossing the Earth. I was experimenting
X   earlier with the master ley line grids on the Earth (in the pattern of
X   an overlapped 20 sided Icosahedron and 12 sided Dodecahedron) and I
X   figured Astrolog with its world map would be an interesting program to
X   explore this with. Actually this is mainly a hack, and belongs more to
X   the field of dowsing than to astrology, but I figured I would leave it
X   in there for amusement and inspiration.
X
X   Hackers note: there is an interesting "bug/feature" that can arise
X   with the -XW as well as the -XG (and -XP, described below) switches:
X   These displays can be brought up in a window without having to
X   specify an actual chart. Now suppose one presses 'V', 'L', etc. to
X   bring up a chart - what will be displayed? The answer will be
X   whatever initial values were already there, and if you're curious,
X   it's set to be my own birth data: 11:01am PST (8 hours before GMT) on
X   Friday, November 19, 1971 in Seattle, WA (122W20 47N36). This info
X   can also be brought up by accessing the "-i nul" virtual chart
X   straight from the command line before any other switches.
X
X o For the -XP polar globe view, this will show the southern hemisphere
X   instead of the northern.
X
X o For the -XG globe display, it will display the zenith locations of all
X   planets (and stars if -U in effect) on the globe, i.e. where on the
X   Earth each object could be viewed by looking straight up. This on the
X   globe display is almost identical to the astro-graph chart without its
X   various lines, except of course that the projection of the world map
X   is different. It's also similar to the -Z horizon display, except that
X   it's free from the distortion of projecting the celestial sphere upon
X   a plane, so it has use to star gazers. However, animation mode here
X   will still only affect what part of the Earth is viewable, and won't
X   update the chart from which the zenith locations were obtained.
X
X o For the -E and -Ey graphical ephemeris displays, it will exclude
X   showing the Moon, which is commonly desired because its line moves
X   across the ephemeris chart so much faster than any of the other planets.
X
-Xt: Inhibit display of chart info at bottom of graphic.
X
X  Normally, at the bottom of any chart graphic is printed some header
X  information listing the date, time, and location of the chart in
X  question (unless the info is already being shown in a sidebar). One
X  can inhibit this display by specifying the -Xt switch.
X
-Xu: Inhibit display of a border around graphic.
X
X  This switch toggles off the border setting that is also interactively
X  toggled by pressing the 'b' key when a graphics screen is up. This
X  switch allows one to toggle the border for graphics files as well as
X  set the default for this in the astrolog.dat file.
X
-Xl: Inhibit labeling of object points in chart graphic.
X
X  This switch will inhibit labeling with glyphs or text abbreviations,
X  the spots indicating the positions of planets in the various graphics
X  charts. This is just the command line counterpart to the existing
X  functionality accessed by the 'l' key.
X
-Xj: Don't clear screen between chart updates, drawing trails.
X
X  This switch will toggle on a flag which will cause the graphics
X  screen to not be cleared on new chart draws. Pressing the 'j' key
X  interactively will toggle the same setting. This feature is used to
X  draw "jet trail" streaks on the screen for some charts, such as the
X  -S orbit and -Z local horizon. If you bring up one of these charts,
X  turn on the setting, and then animate forward, a "time exposure" can
X  be done showing the orbits of planets or an object's path across the
X  sky. (When this is active, entering animation won't automatically
X  jump to the flicker free mode on PC's, because that would make us
X  flip back and forth between two pages breaking the continuity of our
X  "streaks".)
X
-X1 <object>: Rotate wheel charts so object is at left edge.
X
X  Yet another graphics feature, this allows one to effectively rotate
X  one of the graphic wheel charts so that a particular object is hinged
X  to the left hand (east) edge of the chart. Given the -X1 switch with
X  the index value of an object, the wheel is drawn but always rotated
X  so that the object in question is at the left side of the chart. By
X  default we have the ascendant at the left edge, of course. This is
X  useful for tracking important planets so one knows where they are,
X  but yet doesn't distort the house cusps as the -1 switch does.
X
-X2 <object>: Rotate wheel charts so object is at top edge.
X
X  This is identical to the -X1 switch above except here we rotate the
X  entire graphic wheel so the object in question is always at the top
X  of the chart. Note that during a day, the degree difference between
X  the Ascendant and Midheaven varies in most house systems, so that
X  with the Ascendant hinged at the left edge, the Midheaven will wobble
X  back and forth near the top of the wheel. If you prefer, "-X2 18"
X  will fix the Midheaven at the top of the screen, and the chart will
X  be like before except the Ascendant will be the one to wobble near
X  the left edge of the chart.
X
-Xd <name>, -di[..] <name>: Open X window on specified display.
X
X  For X windows only, the -Xd <display> switch can be used to change
X  the display to bring the window up on. Normally, the X window will
X  always come up on the current display, but we can do things like
X  "astrolog -Xd machine:0.0" and have the window appear there. In
X  addition, the program will accept this string through the standard
X  "-display" (which can be abbreviated as "-disp" or anything starting
X  with "-di") switch common to most X11 applications.
X
-XW: Simply create an image of the world map.
X
X  Believe it or not, I painstakingly entered the data for the world map
X  used by the program by hand using an Atlas during a long week. If you
X  just want to see the map of the world by itself without any
X  astro-graph lines on it, use the -XW switch.
X
-XW0: Like -XW but do a non-rectangular Mollewide projection.
X
X  The -XW0 switch is just like the normal -XW switch in that it just
X  displays the world map and nothing else, except that this -XW0 map
X  generated will be in what's called the Mollewide projection, a good
X  looking form often used for maps of the world, as opposed to the
X  standard rectangular map projection used in -XW which distorts the
X  polar regions of the globe across the top and bottom of the screen.
X  (The Mollewide projection pinches the polar regions together,
X  generating a elliptical map, which is similar to the -XG globe
X  displays, but which shows the whole world instead of just half.)
X
-XG [<degrees>]: Display the image of the world as a globe.
X
X  Once we have the data for the map of the world, there are
X  several neat things we can do with it; for instance, with a little
X  trigonometry and clipping, we can bring up a view of a globe, which
X  is what the -XG switch does. An optional argument will specify a
X  rotation value in degrees to display different parts of the globe.
X  (The globe seems to look best for a -Xw window size of around 350.)
X
X  Note that the -XW and -XW0 maps can be animated like as this -XG
X  globe display can. Animation of these maps are done by shifting the
X  whole map to one side or the other. In fact, such a feature can be
X  used indirectly to shift one of the X window astro-graph charts
X  (which are drawn on the world map) from the normal case of having the
X  date line on the edges of the screen: Go into the world map or globe
X  display, animate it a bit, and then change graphic modes to display
X  the astro-graph chart, and it will be shifted by the corresponding
X  amount. (Note that animating the astro-graph screen itself will
X  change the chart info, not how the screen itself is done.) Because
X  the -XW world map, and -XP polar globe display, can be animated just
X  as the -XG general globe display can, the -XW and -XP switches accept
X  optional parameters on the command line that will specify what degree
X  (from 0 to 359) to start the map at, just like the -XG switch does.
X  In addition, the -XG option itself accepts a second optional
X  parameter, which is the starting angle for the globe's tilt, from -90
X  to +90 degrees.
X
-XP: Like -XG but create the globe from a polar projection.
X
X  The -XP option will generate a polar view of the Earth as a globe.
X  This is like the -XG globe option except that the view is always from
X  the top (or bottom). By default, the view is looking down on the north
X  pole with 0 deg W/E toward the bottom of the screen. (Animation mode
X  will cause the view to spin about the center of the screen.) To see a
X  view of the south pole hemisphere, go into the bonus information mode
X  described above ('i' key). Again, like with all the other X window
X  display modes, one can enter this display with a keystroke: press 'P'
X  in any Astrolog window and it will revert to this display.
X
-XF: Display maps as constellations on the celestial sphere.
X
X  A graphics chart showing all 88 of the astronomical constellations is
X  available with the -XF switch. When this mode is active, the -XW
X  world map and -XG and -XP globe chart modes will draw the outlines of
X  the constellations on the celestial sphere instead of continents on
X  the Earth. Pressing the 'F' key when a graphics screen is up will
X  toggle this setting on. (If you aren't already in one of the map
X  graphics modes, -XF and the 'F' key will switch to one.) The
X  constellation maps may be rotated, tilted, and animated and can do
X  everything else just like the world maps, and depict the sky as if
X  you were looking up at it from Earth. In the -Xi display modification
X  mode, the locations of the planets in the current chart will be shown
X  among the constellations. The constellations are labeled with their
X  correct abbreviations, and you can see the familiar image outlines
X  such as the Great Bear, Cygnus, and all the others, as well as the
X  constellations named after the twelve signs of the zodiac, and how
X  these astrological signs compare with their corresponding
X  constellations. I happen to have four planets in my own natal chart
X  in the constellation Ophiuchus, while there are several other
X  constellations very close to the ecliptic which planets (other than
X  the Sun) often enter, e.g. the Moon will technically be in Orion on
X  September 27th. As with Astrolog's map of the world, I entered the
X  data describing the irregular shape of each constellation myself, and
X  the boundaries are accurate although rounded to the nearest degree.
X  This is a unique feature that isn't in any astronomical programs that
X  I know of much less astrological! For a demo of this, do "astrolog -i
X  yourchartfile -XF -XG -Xi -Xn -U" and see a rotating celestial sphere
X  of the constellations and stars, and where the planets in your natal
X  chart are located within them.
X
-Xn [<mode>]: Start up chart or globe display in animation mode.
X
X  The -Xn [<value>] option can be used to start up an X window in
X  animation mode. It a window, one would have to explicitly press 'N' or
X  a shift+number key to start the window animation. Without a parameter
X  after -Xn, the option will start it up in continuous update to "now"
X  mode (which is like pressing 'N' in that any chart will be erased with
X  the current chart now.) The switch can accept parameters from 1..9,
X  corresponding to the animation rates obtained by pressing shift 1..9
X  in the window, i.e. update whatever chart is passed to it seconds,
X  minutes, hours, days, months, years, etc. later each time.
X
-HX: Display list of key press options for screen graphics.
X
X  This switch prints out the list of keys one can press when a graphics
X  screen is being displayed. This list may also be obtained by pressing
X  the '?' key interactively when graphics are actually up. With -HX,
X  this may be done anytime and be printed out or sent to a file like
X  all other Astrolog tables.
X
-W <value>: Run given Windows menu command internally.
X
X  For the Windows version only, this obscure switch allows one to
X  invoke a menu command from a command line, taking one numeric
X  parameter indicating the item to run. Values 40001 through 40229 are
X  valid menu commands, where the list of what number corresponds to
X  what command is in the resource.h source file. An example use of this
X  is to put "-W 40040" in your astrolog.dat file which will start the
X  program with the "Chart Resizes Window" setting on by default.
X  Another example is having "-W 40214" on the command line of the
X  program's icon to have the Chart Info dialog come up on startup.
X
-WN <1-32000>: Set animation update delay in milliseconds.
X
X  For the Windows version only, this switch specifies the animation
X  delay, taking one parameter indicating the number of milliseconds
X  between the start of screen updates. This is the same as the
X  "animation delay" edit control in the Graphics Settings dialog, and
X  exists here as a switch so one may set a default value for it in the
X  astrolog.dat file.
X
-WM <1-48> <text>: Set Windows menu text for macro command.
X
X  For the Windows version only, this switch allows one to customize the
X  menu text for the macro running commands, taking two parameters, the
X  macro from 1-48 whose menu item to change, and the new text to put on
X  the menu. An ampersand "&" may be used to put an underscore under
X  the character following it, which will be used as the standard
X  Windows menu shortcut for the command. For example, doing -WM 12
X  "Best friend's chart", will edit the last item on the "Edit Run Macro
X  (Normal Set)" submenu to read "Best friend's chart". After it will
X  still appear "F12" as this doesn't change the direct keyboard
X  shortcut. (One should of course also use the -M0 switch to assign a
X  macro to slot 12 here to actually display your friend's chart when
X  the macro is run.)
X
-Wn: Don't redraw screen until user forces update.
X
X  For the Windows version only, this switch toggles it so that the
X  window will not redraw its contents until you force an update (with
X  the Redraw Screen command or by pressing space). Normally the screen
X  updates after every command or whenever a section of the window gets
X  uncovered. However this constant redrawing may cause unwanted waiting
X  on a slower system, especially if one is tweaking various minor
X  settings in say a large transit search, and doesn't want to wait
X  after each modification.
X
--
X
Astrolog (version 5.40) obscure command switches:
X
-Y: Display help list of less commonly used command switches.
X
X  This switch was described in an earlier section.
X
-Yn: Compute location of true instead of mean node.
X
X  This switch allows you to set whether the North Node in Astrolog
X  (object number 16) is the Mean or the True node of the Moon. The mean
X  Node is the default, but toggling on the -Yn flag will do the True
X  node. (The default may also be set at compile time via the TRUENODE
X  #ifdef.)
X
-Yd: Display dates in D/M/Y instead of M/D/Y format.
X
X  This is a switch which determines whether dates are displayed in
X  Month/Day/Year order or in the more "European" Day/Month/Year format.
X  Toggling on or off this flag will specify the DMY or MDY format
X  everywhere in the program from text wheel charts to transit charts to
X  the chart info displayed in graphics charts.
X
-Yt: Display times in 24 hour instead of am/pm format.
X
X  This is another option which is just like the above except that it
X  affects how times are displayed throughout the program. When clear,
X  times will be printed in am/pm format, while when set they will be in
X  the more "European" 24 hour clock.
X
-YC: Automatically ignore insignificant house cusp aspects.
X
X  This option toggles on a useful flag to automatically prevent display
X  of irrelevant or redundant aspects involving house cusps, processing
X  them in a more intuitive manner. This affects charts such as -t
X  transit search lists, -T transit influence charts, and -a aspect
X  lists. First, aspects other than conjunctions to minor cusps will be
X  ignored, e.g. a sextile to the 12th house cusp is redundant and isn't
X  really useful, as we are more interested in the conjunction to the
X  2nd house. Minor aspects to the angles such as the Ascendant and
X  Midheaven are left alone. The setting also prevents redundant aspects
X  to two items that are always opposite each other, e.g. if a transit
X  list shows a trine to the Midheaven, it won't show a sextile to the
X  Descendant right next to it.
X
-Y8: Clip text charts at the rightmost (e.g. 80th) column.
X
X  This setting when active will stop printing lines of text within
X  charts if they're long enough to go beyond the right edge of the
X  screen. This can be used to prevent text from wrapping around the
X  screen to the next line. By default, with all objects unrestricted,
X  certain charts will have rows more than 80 columns wide, which can
X  break up the chart making it difficult to read, e.g. the -r0 -g
X  relationship aspect grid, the -E ephemeris listing, and the -L
X  astro-graph columns when uranians are included. With this option on
X  however, these and any other charts that can go beyond column 80,
X  will always be displayed on one line, with columns that would go
X  beyond the 80th not getting printed. Note that this setting can
X  actually clip at any column instead of just the 80th, where the
X  screen width value used is the same as used for interpretation
X  formatting, i.e. the optional parameter to the -I switch.
X
-YQ <rows>: Pause text scrolling after a page full has printed.
X
X  This feature gives you the option to have Astrolog automatically stop
X  whenever the screen gets filled with text and prompt before scrolling
X  to the next page. It takes one parameter to define the number of rows
X  to print before prompting the user to press return to continue. If
X  set to zero, the feature will be turned off and Astrolog will print
X  continuously until done. This helps those who may be concerned about
X  the program scrolling things off the screen before they can read it.
X  Without this one would have to press Ctrl-S to have the system pause
X  printing, send output to a file, or be on a system with scrollbars to
X  see everything. This feature is on by default and set to 24 lines,
X  although this can be changed easily in the astrolog.dat file. When
X  the program is paused, one can type a couple things before pressing
X  return: Entering 'q' will terminate the program, entering 'Q' will
X  turn off the feature and scroll until done, '8' will toggle the right
X  hand column clipping setting, and 'k' will toggle the Ansi color
X  setting.
X
-Yo: Output chart info and position files in old style format.
X
X  Astrolog can still read in all old style -o info and -o0 position
X  chart files generated by previous versions of the program without
X  problem. Not only that, but it will write out these old formats too
X  if the -Yo switch is put into effect. When set, it will output -o and
X  -o0 files exactly as in version 4.10 and before, in simple lists of
X  numbers in fixed fields instead of in generic command files.
X
-Yc: Angular cusp objects are house positions instead of angles.
X
X  This obscure switch determines whether the angular house cusp objects
X  (i.e. indexes 21, 24, 27, and 30) contain the position of their
X  respective house cusps, or the positions of the Ascendant, Nadir,
X  Descendant, and Midheaven. These positions are always the same except
X  for certain house systems, e.g. in the Equal house system the
X  position of the 10th cusp is different from the Midheaven. Normally
X  the angular house objects always contain the positions of the Asc,
X  MC, etc, however this feature gives the user the option to have the
X  objects' contents be the positions of the cusps as defined by the
X  house system in use.
X
-Yz <min>: Forward clock by amount for current moment charts.
X
X  This obscure switch, taking one parameter for the number of minutes,
X  allows one to offset forward or backward the time considered to be
X  the current moment now. This is useful if your -n now charts always
X  seem to be a few hours or whatever off, as seems to be the case on
X  certain Mac or Amiga systems. For example, if -n says it's 3:30pm
X  when it's really 1:30pm, doing "-Yz -120" will back up the clock
X  appropriately (and change the planetary positions slightly too). It's
X  important that this switch be used as a last resort instead of first,
X  where one should first check their system time, the system time zone
X  setting such as may be set with the TZ environment variable, and
X  Astrolog's default time zone. A line for this setting appears in the
X  default astrolog.dat file.
X
-Yl <1-36>: Toggle plus zone status of sector for sector chart.
X
X  This command switch is used with the -l sector charts and sets
X  whether a sector is a plus zone sector or not. Taking one parameter
X  of a sector number, it toggles the plus zone status of it. Like the
X  -R restriction switches, the "_" prefix may be used to make a sector
X  minus and the "=" prefix to make a sector plus.
X
-YP <-1,0,1>: Set how Arabic parts are computed for night charts.
X
X  This is an obscure option allowing one to force whether night chart
X  formula inverting is done in the -P Arabic part chart list, since
X  sources differ on which parts are best inverted. This option takes
X  one parameter, either -1, 0, or 1. Zero is the default setting,
X  meaning the program will invert only those parts that have the flip
X  flag set, for charts cast at night. If the setting is 1, then no
X  inverting will ever be done for any part, even in night charts. If
X  the setting is -1, then inverting will always be done for every part,
X  even in day charts. Note that the POF does appear both in the -P full
X  part list, as well as being the only part that's also a standard
X  object (object #18) meaning it's the only part one may automatically
X  do aspects or transits to. Note also that the -P list POF inverts for
X  night charts, meaning the standard object in the main list does too.
X
-Yb <days>: Set number of days to span for biorhythm chart.
X
X  This switch, taking one parameter, specifies how many days to include
X  in the biorhythm charts. It will control the number of days spanned
X  in the text biorhythm listing, and number of days plotted before and
X  after the given day in the graphic biorhythm chart.
X
-YE <obj> <semi-major axis> <eccentricity (3)> <inclination (3)>
<perihelion (3)> <ascending node (3)> <time offset (3)>
Change orbit of object to be the given elements.
X
X  This feature allows one to "define their own planets", by changing
X  the orbital elements of one of Astrolog's objects. This switch takes
X  17 parameters, which specify all the data needed for any elliptical
X  orbit around the Sun. The parameters are as follows: First is the
X  object to redefine; second is the semi-major axis of the new orbit,
X  in AU; next are three parameters for the eccentricity of the orbit's
X  ellipse; next are three parameters for the inclination of the orbit
X  with respect to the ecliptic, in degrees; next are three parameters
X  for the argument of perihelion, which is the "rotation" of the orbit
X  in degrees or how far away its perihelion is from zero Aries; next
X  are three parameters defining the ascending node, which is the "tilt"
X  of the orbit or how far away the point where the orbit intersects the
X  ecliptic is from zero Aries; finally are three parameters for the
X  "mean anomaly" which is basically where on the orbit the planet is at
X  a reference time and how fast it moves along it. Many of the above
X  element settings take three values when it seems like only one is
X  needed. The second and third values are used as linear and quadratic
X  error factors to the first, and can be zero unless every last bit of
X  accuracy that can be provided outside of ephemeris files is needed.
X  Note that these parameters basically replace the same elements as
X  used in the old Matrix formulas. This means the -YE switch settings
X  are ignored when the -b ephemeris flag is in effect. Note also that
X  the Matrix formulas have special error factors applied on top of
X  their main elements for Jupiter through Pluto, hence it's recommended
X  to only redefine asteroids, uranians, or inner planets. The following
X  example will roughly move Venus into Earth's orbit: "-YE 4 1 0 0 0 0
X  0 0 0 0 0 0 0 0 0 0 23000".
X
-YR <obj1> <obj2> <flag1>..<flag2>: Set restrictions for object range.
X
X  This is like the -R switch except that it explicitly sets the
X  restrictions for a range of Astrolog objects instead of just one. The
X  first two parameters specify the lower and upper object bounds, and
X  are followed by zero or one flag parameters to clear or set the
X  restriction status of each object within the range.
X
-YRT <obj1> <obj2> <flag1>..<flag2>: Transit restrictions for range.
X
X  This behaves exactly like the -YR switch above except it affects
X  transit restrictions, like how the -RT switch is to -R.
X
-YR0 <flag1> <flag2>: Set restrictions for sign, direction changes.
X
X  This sets the restriction status for sign and direction changes. It
X  takes two parameter flags, with the first setting for sign changes,
X  and the second direction changes. This affects the -d daily event
X  searches, and works like the -R restrictions but for all types of
X  these special events, instead of all aspects or all events containing
X  a particular object.
X
-YRZ <rise> <zenith> <set> <nadir>: Set restrictions for -Zd chart.
X
X  This switch allows one to determine which events appear in the -Zd
X  rising and setting time chart. It takes four parameters, which
X  respectively control whether rising events, zenith transit events,
X  setting events, and nadir transit events are included in the chart. A
X  zero value indicates to include that event, while a one means to
X  restrict it. For example, to include only rising and setting events
X  in the -Zd chart, do "-YRZ 0 1 0 1".
X
-YAo <asp1> <asp2> <orb1>..<orb2>: Set aspect orbs for range.
X
X  This is like -Ao but sets the orbs for a range of Astrolog aspects
X  instead of just one. The first two parameters specify the lower and
X  upper aspect index bounds, and are followed by a list of orb values
X  for each aspect in the range.
X
-YAm <obj1> <obj2> <orb1>..<orb2>: Set max planet orbs for range.
X
X  This is like -Am but sets the maximum aspect orbs allowed to a range
X  of objects instead of just one. Again, the first two parameters are
X  the lower and upper object indexes, followed by the list of max orb
X  values.
X
-YAd <obj1> <obj2> <orb1>..<orb2>: Set planet orb additions for range.
X
X  This is like -Ad but sets the planet orb addition values for a range
X  of objects instead of just one. Again, the first two parameters are
X  the bound indexes, and are followed by the list of planet orb
X  additions.
X
-YAa <asp1> <asp2> <ang1>..<ang2>: Set planet aspect angles for range.
X
X  This is like -Aa but sets the angles to use for a range of aspects
X  instead of just one. Again, the first two parameters are the bound
X  indexes, and are followed by a list of angle degree values for each
X  aspect in the range.
X
-Yj <obj1> <obj2> <inf1>..<inf2>: Set influences for object range.
X
X  This sets the powers or influences of the given range of planets,
X  when considered in a natal chart, as used in charts such as the -j
X  influence chart, -a aspect influence list, and -T transit influence
X  list.
X
-YjC <cusp1> <cusp2> <inf1>..<inf2>: Set influences for house cusps.
X
X  This sets the influences for the given range of houses, as used in
X  charts such as -j.
X
-YjA <asp1> <asp2> <inf1>..<inf2>: Set influences for aspect range.
X
X  This sets the influences for the given range of aspects, as used in
X  charts such as the -j influence chart, -a aspect influence list, and
X  -T and -D transit lists.
X
-YjT <obj1> <obj2> <inf1>..<inf2>: Set transit influences for range.
X
X  This sets the influences of the given range of planets, just like
X  -Yj, except here for when the planets are transiting, as used in
X  charts such as the -T transit and -D external planets influence lists.
X
-Yj0 <inf1> <inf2> <inf3> <inf4>: Set influences given to planets
in ruling sign, exalted sign, ruling house, exalted house.
X
X  This switch takes four parameters and sets respectively, the extra
X  influences given to a planet when it's in the sign it rules, when
X  it's in the sign it exalts in, when it's in the house corresponding
X  to the sign it rules, and when it's in the house corresponding to the
X  sign it exalts in. These values are used in examples such as the -j
X  influence chart.
X
-YJ <obj> <sign> <cosign>: Set sign planet rules and co-rules.
X
X  This switch allows one to customize the rulerships of a given planet.
X  It takes three parameters, the object to modify, the zodiac sign for
X  it to rule, and a second sign for it to co-rule. Pass in the value
X  zero to make a planet not rule any sign. For example, Jupiter by
X  default rules Sagittarius and co-rules Pisces. If you'd prefer it to
X  rule Cancer and not have a co-rulership, do "-YJ Jup Can 0".
X
-YJ0 <obj> <sign>: Set zodiac sign given planet exalts in.
X
X  Similar to the -YJ switch, this allows one to customize the zodiac
X  sign a given planet exalts in. It takes two parameters, the object to
X  modify, and the new sign to exalt in (with a zero value meaning no
X  exaltation). For example, to make Pluto exalt in Aries (and hence
X  implicitly be debilitated in the opposite sign Libra) do "-YJ0 Plu Ari".
X
-YI <obj> <string>: Customize interpretation for object.
-YIa <sign> <string>: Customize interpretation adjective for sign.
-YIv <sign> <string>: Customize interpretation verb for sign.
-YIC <house> <string>: Customize interpretation for house.
-YIA <asp> <string>: Customize interpretation for aspect.
-YIA0 <asp> <string>: Customize aspect interpretation statement.
X
X  You can customize the core phrases as used in Astrolog's
X  interpretations. All these switches take two parameters: the index of
X  the item to change, and the string to set it to. (You probably want
X  to enclose any strings in quotes so they are treated as a single
X  parameter and not split at the spaces.) The things that can be
X  changed and the switches to do them follow:
X
X o -YI <obj> <string>: This sets the meaning for the given planet or
X   object, i.e. the part of one's mind the planet represents. For
X   example, the default setting for Jupiter would be: -YI 6
X   "enthusiastic, faithful, wise, expansive, spontaneous nature".
X
X o -YIC <house> <string>: This sets the meaning for the given house,
X   i.e. the area of life that house represents. For example, the default
X   for the first house is: -YIC 1 "establishment of personal identity".
X
X o -YIa <sign> <string>: This sets the characteristics for the given
X   sign, i.e. adjectives describing it. For example, the default for
X   Gemini is: -YIa 3 "inquisitive, witty, perceptive, adaptable".
X
X o -YIv <sign> <string>: This sets the desires for the given sign, i.e.
X   verbs describing what something characterized by it seeks. For
X   example, the default for Virgo is: -YIv 6 "works toward perfection".
X
X o -YIA <asp> <string>: This sets the meaning for the given aspect, i.e.
X   the type of interaction going on when the aspect is in effect. For
X   example, the default for the Trine is: -YIA 4 "is in harmony with".
X   Special note for hackers: If the optional characters "%s" appear in
X   the given string anywhere, Astrolog will replace them with an
X   appropriate adverb indicating how strong the effect of the aspect is
X   (and include the trailing space). For example, the real default for
X   Trine is: -YIA 4 "is %sin harmony with", where the "%s" will is
X   replaced with "always ", "somewhat ", etc, as appropriate.
X
X o -YIA0 <asp> <string>: This sets the conclusion for the given aspect,
X   i.e. an additional sentence about it. For example, the default for
X   the Opposition is: -YIA0 5 "Adaptation is required by both sides".
X
-YkC <fir> <ear> <air> <wat>: Customize element colors.
-YkA <asp1> <asp2> <col1>..<col2>: Customize aspect colors.
-Yk0 <1..7> <1..7> <col1>..<col2>: Customize 'rainbow' colors.
-Yk <0..8> <0..8> <col1>..<col2>: Customize 'general' colors.
X
X  Astrolog can customize the colors as used for almost anything in the
X  program. A color may be set to any one of 16 values, represented by
X  the numbers 0 to 15, which are: 0 - Black, 1 - Maroon, 2 - DkGreen, 3
X  - Orange, 4 - DkBlue, 5 - Purple, 6 - DkCyan, 7 - LtGray, 8 - DkGray,
X  9 - Red, 10 - Green, 11 - Yellow, 12 - Blue, 13 - Magenta, 14 - Cyan,
X  15 - White. When entering a color as a parameter, use the correct
X  number above, or else type the color's name as printed above (which
X  may be abbreviated to the first three characters). The switches to
X  change color settings are below.
X
X o -YkC <col1> <col2> <col3> <col4> switch: This switch defines the
X   colors used for the four elements, and takes four parameters, for
X   fire, earth, air, and water, in that order. The colors used for
X   planets are based on the element of the sign they rule, so this
X   affects the colors of the main planets too. For example, to make
X   earth be green and air yellow, instead of the other way around as
X   Astrolog used to always force, do "-YkC 9 10 11 12" or "-YkC Red
X   Green Yellow Blue" or just "-YkC red gre yel blu".
X
X o -YkA <asp1> <asp2> <colors> switch: This defines the colors used for
X   a range of aspects. The first two parameters are the lower and upper
X   indexes of the aspects to modify, and are followed by one color
X   parameter for each aspect in the range. For example, to highlight
X   Trines by making them white and all the other major aspects dark
X   blue, do "-YkA 1 5 dkb dkb dkb whi dkb".
X
X o -Yk0 <val1> <val2> <colors> switch: This sets a range of colors used
X   other places in the program (excluding elements and aspects) whose
X   default colors are one of the colors of the rainbow. The first two
X   parameters are values from 1 to 7 indicating the lower and upper
X   bounds of the default colors to redefine, and are followed by new
X   actual colors to use instead. The seven indexes represent the colors
X   Red, Orange, Yellow, Green, Cyan, Blue, and Purple. For example, if
X   you want to change the color used for the Uranians from their default
X   of purple to orange, do "-Yk0 7 7 orange" and you've effectively
X   "redefined the color purple".
X
X o -Yk <val1> <val2> <colors> switch: Like -Yk0 above this also sets a
X   range of colors as used many places in the program, except this
X   allows one to redefine all the standard or obscure colors (i.e. the
X   other nine that aren't one of the rainbow colors covered above).
X   Again the first two parameters indicate the range of colors to change
X   which are from 0 to 8, and are followed by the new colors to use. The
X   nine indexes represent in order the colors Black, White, LtGray,
X   DkGray, Maroon, DkGreen, DkCyan, DkBlue, and Magenta. For example, to
X   change the highlight color as used in graphics charts to draw borders
X   and the like from LtGray to Yellow, do "-Yk 2 2 yellow". (Note that
X   you can use this to even "change" the colors Black and White to draw
X   graphics on whatever background color you want.)
X
-YXG <0-2><0-2><0-2><0-3>: Select among different graphic glyphs
for Capricorn, Uranus, Pluto, and Lilith.
X
X  Astrolog has the ability to choose between different common glyphs
X  for various astrological symbols. One may optionally display charts
X  with the "European" version of the Capricorn glyph, instead of the
X  more twisty "American" type glyph. One may display charts with the
X  "astronomical" version of the Uranus glyph using a dotted circle with
X  an ascending arrow, instead of the more astrological "Herschel" glyph
X  with the crescent bounded cross over a circle. One may display with
X  the "astronomical" version of the Pluto glyph as the "PL" initials,
X  instead of the more "astrological" version with the circle over
X  crescent over cross. Finally one may choose to display Lilith as a
X  small reversed crescent instead of as a circle with a line through
X  it. The -YXG switch changes the glyphs to use for these signs and
X  planets that may be drawn in more than one way. It takes one
X  parameter, a four digit number specifying the glyphs to use for
X  Capricorn (1000's place digit), Uranus (100's place), Pluto (10's
X  place), and Lilith (1's place). For each position, the digit "0"
X  means to leave a glyph alone, while "1" means set to what's generally
X  considered the "American" form, and "2" means to what's generally
X  considered a "European" form. (For Lilith only, one may also choose
X  the digit "3", which is the "U" shaped South Node glyph.) For
X  example, "-YXG 0120" leaves the glyphs for Capricorn and Lilith at
X  their present setting, sets Uranus to be the "Herschel" glyph, and
X  Pluto to be the astronomical "P" glyph. The default selection is
X  "1111", but many astrologers on the Eastern side of the Atlantic may
X  prefer "2222".
X
-YXg <cells>: Set number of cells for graphic aspect grid.
X
X  This sets the size of the graphic -g aspect and midpoint grids, i.e.
X  the number of cell rows and columns available to draw items in.
X  Aspect grids by default are always 20 by 20 cells (21 by 21 for the
X  -r0 relationship comparison grids counting the index row) to account
X  for the default number of objects active. If this size value is too
X  high (or objects are restricted), there will be unused rows at the
X  bottom, while if it's too low (or objects are added), rows will be
X  clipped off the bottom.
X
-YXf <val>: Set usage of actual system fonts in graphic file.
X
X  This sets whether or not actual system fonts (instead of Astrolog's
X  vector graphics) are used for glyphs and text in PostScript and
X  Windows metafile graphics files. Zero means no system fonts, while
X  one means use Courier, Wingdings for metafiles, and the Astro font.
X  (This can also be set to the hack value of two if you don't have the
X  Astro font, which means don't try to use this system font but do use
X  all the others.)
X
-YXp <-1,0,1>: Set paper orientation for PostScript files.
X
X  This allows one to set the page orientation for full PostScript
X  graphics files as generated with the -Xp0 switch. If the orientation
X  parameter value is positive, that means the chart will be printed in
X  portrait mode, while if negative, it will be in landscape mode. If
X  the orientation value is set to zero (the default), then the program
X  will decide based on the size of the current chart, with charts with
X  wider horizontal sizes (e.g. astro-graph charts and wheel charts with
X  sidebars) being in landscape, and charts with horizontal sizes less
X  than or equal to the vertical (e.g. aspect grids and wheel charts
X  without sidebars) being in portrait.
X
-YXp0 <hor> <ver>: Set paper size for PostScript files.
X
X  One may also choose the paper size of full -Xp0 PostScript graphics
X  charts. There are two parameters given which specify the horizontal
X  and vertical size in inches of the paper to be printed upon. By
X  default this is 8.5" x 11". If you have say 8.5" x 14" legal size or
X  A4 paper in your printer it can be used just as easily. (Note: It's
X  possible that at least some systems or drivers may clip all graphics
X  beyond 8.5" x 11", but excluding any external restrictions Astrolog's
X  PostScript should allow one to go beyond these limits.)
X
-YX <hi-res> <lo-res>: Set modes to use for PC screen graphics.
X
X  For PC's with graphics only, this sets the two graphics modes as used
X  when displaying charts on the screen. The two parameters specify the
X  mode number to use as the default "hi-resolution" mode, and the
X  "flicker-free" mode used for animations.
X
-0[o,i,q,X]: Disallow file output, input, exiting, and graphics.
X
X  This obscure switch is invoked in one of four forms: -0o, -0i, -0q,
X  or -0X, where more than one of the subswitches may be combined, e.g.
X  -0oiqX to do all four forms at once. Each subswitch disables a
X  section of the program. The four areas of file output, file input,
X  program termination, and graphics mode charts, may be respectively
X  turned off by the four subswitches above. Once a section is disabled,
X  it is that way permanently and can not be turned back on until the
X  program quits. Attempting to access a restricted feature will display
X  an appropriate error message or at least do nothing. This switch was
X  meant to be used when Astrolog is being run from a chart server, a
X  BBS, as a demo, or related situation. For example, if one set up
X  Astrolog on the Net to be able to receive chart requests including
X  arbitrary command lines where the result is e-mailed back to the
X  user, the administrator probably wants to prevent the client from
X  using the -o switch to create or potentially overwrite files on the
X  server, in which case -0o can be put in the astrolog.dat file to
X  prevent file output before the client gets a chance to do anything.
X  Similarly, -0i can be used to prevent the client from using -i to
X  read in private files on the server. If the server only e-mails text
X  back to the user, you probably don't want the server copy of the
X  program going into interactive graphics mode waiting for someone to
X  pass it keystrokes, in which case -0X can be used. Finally, -0q might
X  be useful in demo situations where people can play with the program
X  but you don't want them exiting it. In this last case, the only way
X  to stop the program is to kill the process; a Control-C should stop
X  the DOS or Unix versions, but you'll probably have to exit Windows to
X  terminate Astrolog if a -0q is done in the Windows version.
X
-;: Ignore rest of command line and treat it as a comment.
X
X  The -; "dash semicolon" switch when encountered causes all the rest
X  of the switches on a command line to be ignored and not processed.
X  This allows the semicolon (usually used by itself without the
X  optional dash prefix of course) to be used to begin comments and for
X  comment lines in the various command files.
X
--
X
Astrolog graphics screen key press options (version 5.40):
X
X     (Note: When a graphics chart is up, pressing a key which doesn't
do any of the operations below will sound a beep.)
X
Press 'H' or '?' to display this list of key options.
X
X  The most important key, of course. Pressing this will display a help
X  list of all the key presses available in the text screen from which
X  the window was invoked from.
X
Press 'p' to toggle pause status on or off.
X
X  Press this to pause all automatic updates to the window or screen.
X  This is mainly used to temporarily freeze any animation (see below)
X  so a particular chart can be looked at without interruption. When
X  animation is on but temporarily paused with this key, the mouse
X  (inactive for the purpose of scribbling during animation) will come
X  active again. Related to this, the number keys which set the rate of
X  animation, but for PC's scroll the chart when not in animation mode,
X  will do the scrolling instead of setting the rate when animation is
X  paused then.
X
Press 'x' to toggle fg/bg colors on screen.
X
X  Pressing this will invert the colors on the screen, or in other
X  words will do the same thing as the -Xr switch on the command line.
X
Press 'm' to toggle color/monochrome display on screen.
X
X  For color displays, pressing this key will toggle in and out of
X  monochrome mode.
X
Press 'i' to toggle status of the minor chart modification.
X
X  Pressing this key will toggle whether or not an alternate form of the
X  present chart should be displayed. See the -Xi switch described
X  earlier for more information on these alternate chart formats.
X
Press 't' to toggle header info on current chart on screen.
X
X  Pressing the 't' key will toggle whether or not the chart parameters
X  are printed at the bottom of the window or in a sidebar. This
X  corresponds to the -Xt switch mentioned earlier.
X
Press 'b' to toggle drawing of a border around the chart.
X
X  This key, when pressed when a graphics chart is being displayed, will
X  toggle whether or not a border is drawn around the graphic. Some
X  charts, such as aspect grids, will always have a border regardless of
X  the state of this flag, while others such as the globes will never
X  have one. Most charts however, such as the wheel charts will look
X  good either way and this key can be used to choose.
X
Press 'l' to toggle labeling of object points in chart.
X
X  Press the 'l' key in a window to inhibit the labeling of all planets
X  in the various charts. Instead of drawing the actual little point and
X  then the glyph near it (as well as sometimes a line from the glyph to
X  the dot), just the point is displayed. This mode is mainly useful for
X  the -Z horizon and -S space charts (and has little use for anything
X  else) when in cramped quarters or to get a more realistic view of how
X  the sky actually looks.
X
Press 'j' to toggle not clearing screen between chart updates.
X
X  This key toggles on the "jet trails / time exposure" flag which will
X  cause the graphics screen to not be cleared on new chart draws. See
X  the -Xj switch which affects the same setting for more info.
X
Press 'v' to display current chart positions on text screen.
X
X  Press this key to dump back to the text screen the list of where all
X  the planets currently being displayed in the window are. This display
X  is the same as produced with the -v switch, and is useful if one wants
X  text to show where everything in the chart is.
X
Press 'R', 'C', 'u', 'U' to toggle restriction status of minor
objects, minor house cusps, uranian planets, and stars.
X
X  Press the 'R' (restrict) key in an Astrolog graphics screen and the
X  chart will be redrawn with the restriction status of the asteroids
X  and other minor objects toggled. Pressing the 'C', 'u', and 'U' keys
X  in the window will toggle the restriction status of the four minor
X  house cusps, the uranian planets, and the fixed stars, respectively.
X  These keys compliment the 'R' key option and are the counterparts to
X  the -C, -u, -U, and -RC, -Ru, -RU switches. (Note that for the 'C',
X  'u', and 'U' keys, toggling their state off will automatically
X  restrict all the objects associated with them, while the 'R' key can
X  simultaneously restrict some and unrestrict other bodies.)
X
Press 'c' to toggle relationship comparison chart mode.
X
X  This key, when pressed when a graphics chart is being displayed, will
X  toggle the state of whether a relationship comparison chart (-r0) is
X  being shown. For example, pressing it when a wheel chart is up will
X  revert to a dual wheel chart showing two sets of planets, while
X  pressing it when an aspect grid is up will revert to a dual aspect
X  grid between the planets of two different charts. When going from a
X  comparison to a single chart, one of the charts will be used while
X  the other thrown away. When going from a single to a comparison, the
X  same chart information will be put in both (which won't be too useful
X  until they are made different through animation or other keypresses).
X
Press 's', 'h', 'f', 'g', 'z', 'y' to toggle status of sidereal
zodiac, heliocentric charts, domal charts, decan charts, vedic format
wheel charts, and navamsa charts.
X
X  Press the 's' key in the window to toggle whether or not the sidereal
X  vs. tropical zodiac is used. Press the 'h' key to toggle to a
X  heliocentric based chart or back again to a geocentric one. Press the
X  'f' key to toggle the status of whether or not the chart should be
X  modified to correspond to the appropriate domal chart (where the
X  house positions are represented as zodiac positions and vice versa).
X  Press the 'g' key to toggle the status of whether or not the chart
X  should be modified to correspond to a decan chart (where each sign is
X  divided in thirds representing the two other signs in its element).
X  Press the 'z' key to toggle whether wheel charts are displayed in
X  Vedic format. Press the 'y' key to toggle whether charts are
X  displayed in navamsa format or not. These keys of course correspond
X  the -s, -h, -f, -3, -J, and -9 options, respectively.
X
Press 'O' and 'o' to recall/store a previous chart from memory.
X
X  Have you ever animated your natal or some other chart to some far
X  distant future or past time, only then to wish you could somehow
X  easily get back in time to the original chart? You can, by pressing
X  the 'O' key in a window, which will recall to the screen previously
X  "saved" chart parameters (which are by default set to whatever you
X  started the window with.) Press the 'o' key to change this default
X  stored chart to be the chart that is presently in the window.
X
Press 'B' to dump current window contents to root background.
X
X  Press the 'B' key in an X window to dump whatever is currently being
X  displayed to the background root window. This is basically the
X  corresponding keypress to the -XB option.
X
Press 'B' to resize chart display to full size of screen.
X
X  For PC systems, the 'B' key does a different function that the
X  feature shown above. See PC graphics section for its description.
X
Press 'Q' to resize chart display to a square.
X
X  One can manually resize the Astrolog X Windows using a window manager
X  (except when a world map or aspect grid is displayed, in which case
X  any resizing will have no effect). Pressing the 'Q' key will
X  automatically resize any (non-world map) window to be a square. This
X  is useful, after resizing charts to approximately the size you want,
X  to make them precise squares. Note that for PC's, this will take EGA
X  and CGA mode pixel ratios into account, in that the horizontal and
X  vertical sizes may be made different in order that the actual display
X  looks square. This will also take into account wheel chart sidebars
X  and only resize the actual visible chart to a square when one is
X  being displayed to prevent distortion.
X
Press '<' and '>' to decrease/increase the scale size of the
glyphs and the size of world map.
X
X  This two keys will respectively decrease and increase the size of the
X  sign and planet glyphs (as well as resize the astro-graph and aspect
X  grid charts) through the three scale factors available. After resizing
X  the window, you will probably want to use these keys if the glyphs are
X  then too big or small for the new chart.
X
Press '[' and ']' to decrease/increase tilt in globe display.
X
X  '[', ']' keys: Not only can the globe display be rotated, but the
X  poles can be tilted down at various angles! (This basically makes the
X  -XP polar globe view option obsolete; it's still in there only for
X  backwards compatibility.) Press the '[' and ']' keys when the globe is
X  being displayed to respectively "pull down" and "push back up" the
X  angle of the polar axis from which the globe is viewed. Combining
X  this with the globe rotation allows one to move any point of the globe
X  to the center of the screen.
X
Press '+' and '-' to add/subtract a day from current chart.
X
X  These keys, when pressed when a graphics chart is being displayed,
X  will update the current chart forward or backward one day (actually
X  1..9 days based on the current animation rate). When animation mode
X  itself is active, these keys will jump by the current animation step,
X  instead of only an amount in days.
X
Press 'n' to set chart information to current time now.
X
X  This key, when pressed when a graphics chart is being displayed, will
X  change the current chart (or "outer" chart when a -r0 comparison
X  chart is up) to the current time and place now. This interactively
X  does the same as the -n command line switch. The only other way to
X  revert a graphics chart to the time "now" is to enter animation mode
X  via the 'N' key and then leave it, so this is a shortcut convenience.
X  (This feature is only available when the TIME compile time value is
X  uncommented of course.)
X
Press 'N' to toggle animation status on or off. Charts will
be updated to current status and globe will rotate.
X
X  Animation! This key will toggle in and out of a mode where the chart
X  is continually updated in the window. Entering the animation mode
X  will cause the chart being currently displayed to be replaced by the
X  chart for the exact moment at the time you are running the program.
X  Every second or two, the chart will be updated to reflect the new
X  current state of the planets and houses. For large window sizes, one
X  can actually see very minor changes in the chart every few seconds.
X  With the text 'T' mode in effect, the chart is basically an advanced
X  version of xclock, and makes a good window to be left running on
X  your display. If you are in the -XG globe display mode, pressing
X  the 'N' key will cause the globe to rotate for an impressive display!
X  Note that when a comparison relationship chart is up, animation will
X  forward the chart in the "second" slot rather than the "first". This
X  is more intuitive when animating bi-wheel transit to natal charts,
X  where the transiting, i.e. second, chart will be the one forwarded.
X
Press '!'-'(' to begin updating current chart by adding times.
!: seconds, @: minutes, #: hours, $: days, : months,
^: years, &: years*10, *: years*100, (: years*1000.
X
X  These nine keys (i.e. shift plus the number keys from 1..9) enter
X  into a different form of chart animation. Pressing them will cause the
X  current chart being displayed (i.e. it will not revert to the current
X  planet positions) to continually have a delta time added to it and be
X  recast and shown. Pressing '!' will have one second added to the chart
X  for every update (slow action unless you have a very fast system - the
X  animation will be even slower than for the 'N' key). Pressing '@' will
X  have one minute added to the chart each time, which makes for a nice
X  display (note that you will definitely want to be in the text 'T' mode
X  for these animations so you can see what times in the future these
X  charts are being cast for. Pressing '#" will have one hour added each
X  time (note that now the house cusps are starting to move quickly, so
X  you may want to switch to a different system of houses (such as the
X  Equal to keep the Midheaven from flopping back and forth) and/or use
X  -1 to put an object like the sun on the Ascendant.) Pressing '$' will
X  have one day added each time (now you will probably want to start
X  using -R to remove fast moving objects like the moon), and pressing
X  '%' will have one month added for each update of the window. The
X  final keys, shift 6..9 cause years, decades, centuries, and millennia
X  to be added each time, and tend to only be used to look for long range
X  actions (when will Neptune next enter Pisces, etc.) To exit these
X  animation modes, press the 'N' key.
X
Press 'r' to reverse direction of time-lapse or animation.
X
X  Press this to reverse the direction of any animation taking
X  place. For the '!'..'(' animation keys above, this will cause
X  negative times to be added to the chart, e.g. pressing '#'
X  then 'r' on a chart cast for noon will cause the next chart to
X  be displayed for 11am, then 10am, etc. For the Globe animation,
X  this will cause the rotation to reverse direction.
X
Press '1'-'9' to set rate of animation to 'n' degrees, etc.
X
X  The nine number keys are used to set the relative "rate" of
X  animation to "n" whatevers. For example, normally the "@" key means
X  add one minute to the chart for each update, but press "5" and now
X  we are adding 5 minutes each time. For the Globe animation,
X  by default the Earth rotates one degree each time; however, the
X  number keys can speed this up to nine degrees for each update.
X
Press '1'-'9' to determine section of chart to show if clipped.
X
X  For PC systems only, see the section on PC graphics for this
X  additional feature accessed through the number keys. Note when
X  pressing numbers to set the animation rate or the section of a PC
X  graphics screen to view, the numeric keypad will work for PC's even
X  if numlock isn't on. It would be annoying to press a number on the
X  keypad only to pass some random characters to Astrolog because you
X  forgot to turn on numlock.
X
Press 'V','A','Z','S','M','K','J','L','E','W','G','P' to switch to
normal (-v), grid (-g), local (-Z), space (-S), sector (-l),
calendar (-K), dispositor (-j), astro-graph (-L), ephemeris
(-E), world map (-XW), globe (-XG), and polar (-XP) modes.
X
X  There are basically twelve main modes in which the graphics screen
X  can be in: There are the nine main charts (wheel, aspect grid, local
X  sky, space view, Gauquelin sector, calendar, dispositor, astro-graph,
X  and ephemeris) as well as the three world displays (the simple map by
X  itself, the globe view, and the polar projection). These twelve keys
X  can be used to switch between these modes in the middle of program
X  execution. For example, you can bring up your own chart in a window,
X  then press 'L' to see the astro-graph chart for the same birth data.
X  Then you can press 'W' to just see the world map by itself, and 'G'
X  to see the globe view, after which you can press 'V' to return to
X  your original wheel chart.
X
Press '0' to toggle between -Z,-Z0 & -XW,-XW0 & -E,-Ey modes.
X
X  When graphics are up on the screen, pressing this key acts similar to
X  the mode changing keys above that switch between the different
X  graphic chart types. When pressed, the state of the program being
X  invoked with -Z vs. -Z0, as well as the state of -XW vs. -XW0, and
X  the state of -E vs. -Ey, will be reversed. In other words, if I am
X  viewing the -Z -X horizon chart, and I want to see the -Z0 -X sky
X  graphic, then I press '0' to go to it. Similarly, this key will flip
X  me back and forth between the -XW simple rectangular world map
X  display and the -XW0 Mollewide projection graphic, as well as the -E
X  monthly ephemeris and the -Ey yearly ephemeris. A bit of a hack, but
X  useful, and the only way to change these suboptions while the program
X  is running.
X
Press 'F' to toggle between world and constellation map modes.
X
X  This key toggles on the constellation charts where the map and globe
X  modes show the celestial sphere instead of the Earth's continents.
X  See the -XF switch which affects the same setting for complete info.
X
Press 'F1'..'F12' [plus Shift,Ctrl,Alt] to run macros 1..48.
X
X  For PC's, pressing the function keys F1 through F12 will execute
X  macros when graphics are being displayed. Pressing F1 through F12
X  will run macros 1 through 12. Pressing Shift+F1 through Shift+F12
X  will run macros 13 through 24. Control+F1 through Control+F12 will
X  run macros 25 through 36. Finally Alt+F1 through Alt+F12 will run
X  macros 37 through 48. Executing a macro that hasn't been defined yet
X  (either with a function key or the -M switch) will do nothing.
X
Press 'space' to force update of current graphics display.
X
X  When a graphics chart is up on the screen, pressing the space bar
X  will force a redraw of the chart. This is useful for say to cleanup
X  after one has scribbled on it with the mouse button features
X  (described below).
X
Press 'del' to clear the graphics screen and not redraw.
X
X  Pressing the delete key when a graphics screen is up will clear the
X  screen, but not redraw the chart right away unless animation mode is
X  on. This is most useful for the -Xj "timed exposure" streaks in
X  horizon and orbit charts if you want to start a new "jet trail" while
X  animating.
X
Press 'tab' to toggle between graphics resolutions.
X
X  This feature is only available on PC systems. See PC graphics section
X  for its description.
X
Press 'enter' to input a command line of general switches.
X
X  Pressing the return key when a graphics screen is up will pause and
X  prompt you for a command line. This command line will be processed
X  after which you will be returned back to the graphics state you left,
X  allowing the changing on the fly of any setting that isn't already
X  covered by pressing whatever key, without having to drop all the way
X  back to a -Q loop or out of the program altogether. This can be used
X  to redisplay the -H switch list too. (There are a couple of rare
X  things you can't do in the middle of graphics, e.g. you aren't
X  allowed to suddenly switch to one of the graphics file modes.)
X
Press 'q' to terminate the window and program.
X
X  Pressing this key will exit graphics mode or terminate the window
X  (and leave the Astrolog program itself.)
X
--
X
Left   mouse button: Draw line strokes on chart in window.
Middle mouse button: Print coordinates of pointer on world map.
Right  mouse button: Terminate the window and program.
X
X  Mouse buttons: Pressing the mouse buttons in the X Windows (or on the
X  screen for PC's) will do various functions. The left mouse button
X  acts as a pen that allows one to actually draw on the chart: press it
X  and drag the pointer to draw a line on the window - good for aiding
X  in analysis or in presentations. (Any scribbles one makes will
X  disappear the next time the chart window is updated, therefore this
X  drawing is disabled in animation mode.) The middle mouse button
X  (right button for PC's) will only work when the world map is shown,
X  i.e. in the -L astro-graph or -XW world map displays: press it and
X  get the approximate longitude and latitude of the place on the map
X  where the pointer is, printed in the main window (or have the current
X  chart's location set to this for PC's). For the four scale sizes of
X  100, 200, 300, and 400 percent, the accuracy is to the nearest
X  degree, 30 minutes, 20', and 15', respectively. So, if you want to
X  cast a chart for southern Madagascar, Africa, but don't know the
X  coordinates, click the middle button on the map for a good
X  approximation! Finally, the right button (middle button if any for
X  PC's) acts just like the 'q' key, and will terminate the program.
X
X  Note that for X Windows, pressing the middle mouse button when a
X  world map is up, in addition to displaying the longitude and latitude
X  of the point clicked on in the parent window, will also set the
X  current chart location to this point. This makes an easy interface
X  for doing chart relocation! Say you want to relocate your natal chart
X  to Tokyo, Japan. Just bring up your chart in graphics mode, press 'W'
X  to switch to the world map display, click middle button on Japan,
X  then return to the wheel chart and there your chart is, as if you had
X  been born at the same time but in Tokyo.
X
X  Control keys: Certain control keys can be pressed when a graphics
X  chart is up to set the color of the "pen" one can scribble on the
X  chart with using the left mouse button. (Who knows, maybe Astrolog
X  will contain a full featured drawing program someday. ;) Usually, the
X  scribbles are always in the gray highlight color. However, sixteen
X  control keys can be pressed to change the pen to sixteen different
X  colors, which are defined as follows: Ctrl-A is White, Ctrl-Z is
X  Black, Ctrl-R is Red, Ctrl-G is Green, Ctrl-B is blue, Ctrl-Y is
X  Yellow, Ctrl-O is Orange, Ctrl-L is Light gray, Ctrl-D is Dark gray,
X  Ctrl-V is Magenta (Valentine pink), Ctrl-U is Purple (pUrple), Ctrl-E
X  is Maroon (Dark red, next to 'R' on keyboard), Ctrl-F is Dark Green
X  (Forest green, next to 'G' on keyboard), Ctrl-N is Dark Blue (Navy
X  blue, next to 'B' on keyboard), Ctrl-J is Cyan, Ctrl-K is Dark Cyan
X  (Next to 'J' on keyboard).
X
X
*******************************
DATA ENTRY AND THE MAIN DISPLAY
*******************************
X
X     The main part of the program is executed simply by entering
"astrolog" (assuming that's the name of the executable), and the
program will ask you for all the birth info and will give the
planet/house positions. For example, for a chart in Seattle at the
Fall Equinox (for September 22rd, 1994 AD at 11:19pm Pacific Daylight
Time, 7 hours before GMT) for the ten prompts one would enter: Sep,
22, 1994, 11:19pm, PT, Y, 122W20, 47N36, Fall Equinox, Seattle, WA.
The program then calculates and displays the positions of all
planets, Chiron, the four main asteroids, as well as items like North
Node of the Moon, Lilith or the South Node, the Part of Fortune, the
Vertex, and the East Point. (The Uranian bodies and fixed stars can
also be listed if one includes the appropriate command switches
described earlier.)
X
X     Two of the chart info fields interactively prompted for above
are general text fields for the person's name or chart title, and the
name of the city or location the chart is cast for. When set the
contents of these fields will be displayed in the various charts,
such as the -v listing, the -w text wheel, and in the graphic wheel
chart sidebars. (You can prevent these two fields from being prompted
for by setting the -Yo old style info switch described earlier.)
X
X     Another field explicitly prompted for is whether Daylight Saving
time was in effect for the chart or not. (Without this one would have
to subtract one hour from the time or time zone to indicate if
Daylight time was in effect, which of course was limited in that it's
not always clear whether a given chart was for say 11am Standard
time, or really for noon Daylight.) As with the name and city
strings, you will not be interactively prompted for the Daylight
setting when the -Yo flag is active. Enter "0", "Y", or "S" for
Standard time, and "1", "N", or "D" for Daylight time (or War time).
An indication of Standard or Daylight time will be shown in the
headers of the -v listing and in the graphics charts.
X
--
X
X     The user interface where one manually inputs the chart
information is "smart" in various ways, as many of the chart info
fields may be entered in several formats and be parsed correctly:
X
X     Months may be entered as numbers from 1 to 12 or as their true
names. Case doesn't matter, and month names may be abbreviated to
their first three letters.
X
X     Year values may be entered with an optional "BC" or "AD" suffix.
(Periods may be interspersed, e.g. "b.c." is allowed.)  Years BC may
also be entered as negative years, but if you do this note that you
have to add one to the negative number since there's no formal year 0
BC or 0 AD, e.g. since 1BC is followed by 1AD, specifying "5BC" would
be the number "-4".
X
X     Time values may be entered with a "pm" or "am" (or just "p" and
"a") suffix (periods may be interspersed), or in the standard 24 hour
clock. The separator between hours and minutes may be a colon or a
decimal point. For example, 6:30pm may be entered as "18:30",
"6:30pm", or even "6.3p". 12:30am may be entered as "12.30a.m.",
"0:30", and so on.
X
X     Time zones may be entered as abbreviation strings, or numbers in
hours before GMT (negative numbers for after GMT). For example,
"EST", "PST", and "GMT" are allowed. Note that this setting is still
separate from the Daylight Time setting. In other words, strings such
as "EDT" or "EWT" may be entered, but that will only subtract one
hour from the time zone number, and not turn on or off the Daylight
setting. Hence it may be preferred to enter strings that don't imply
such an assumption, i.e. Astrolog also accepts general abbreviations
such as "ET" or "PT". For that matter, some one letter time zone
abbreviations are accepted, e.g. "E" or "P" for Eastern and Pacific.
When specifying half hour time zones as a number instead of using an
abbreviation, the correct way is as "n:30" or "n.30", since the
parameter is processed as hours and minutes, and not something like
"n.50", which will be treated as a fifty minute after the hour zone.
(If one does interactively enter a "n.5" zone, the program will
display a warning indicating that the input is unusual and not a half
hour zone.) Below is a table of all zone abbreviations Astrolog
accepts. Listed for each zone is its official name, its standard
abbreviation, its hours before GMT, and its standard meridian. For
some zones the program accepts special two and one letter shortcuts:
X
X  Time Zone Name           Abbrev.     Hours   Longit.
X  Hawaiian Standard Time   HST  HT  H  +10:30  157.5W
X  Central Alaska Time      CAT         +10     150  W
X  Alaska Hawaii Standard   AHS         +10     150  W
X  Hawaiian Daylight Time   HDT         + 9:30  157.5W
X  Alaska Hawaii Daylight   AHD         + 9     150  W
X  Yukon Standard Time      YST  YT  Y  + 9     135  W
X  Yukon Daylight Time      YDT         + 8     135  W
X  Pacific Standard Time    PST  PT  P  + 8     120  W
X  Pacific Daylight Time    PDT         + 7     120  W
X  Pacific War Time         PWT         + 7     120  W
X  Mountain Standard Time   MST  MT  M  + 7     105  W
X  Mountain Daylight Time   MDT         + 6     105  W
X  Mountain War Time        MWT         + 6     105  W
X  Central Standard Time    CST  CT  C  + 6      90  W
X  Central Daylight Time    CDT         + 5      90  W
X  Central War Time         CWT         + 5      90  W
X  Eastern Standard Time    EST  ET  E  + 5      75  W
X  Eastern Daylight Time    EDT         + 4      75  W
X  Eastern War Time         EWT         + 4      75  W
X  Atlantic Standard Time   AST  AT  A  + 4      60  W
X  Atlantic Daylight Time   ADT         + 3      60  W
X  Atlantic War Time        AWT         + 3      60  W
X  Brazil Standard Time     BST  BT  B  + 3      45  W
X  Brazil Daylight Time     BDT         + 2      45  W
X  West Africa Time         WAT         + 1      15  W
X  Greenwich Mean Time      GMT  GT  G    0       0
X  Western European Time    WET           0       0
X  Central European Time    CET         - 1      15  E
X  Eastern European Time    EET         - 2      30  E
X  Russia Zone 3            UZ3         - 4      60  E
X  Russia Zone 4            UZ4         - 5      75  E
X  Indian Standard Time     IST  IT  I  - 5:30   82.5E
X  Russia Zone 5            UZ5         - 6      90  E
X  North Sumatra Time       NST         - 6:30   97.5E
X  South Sumatra Time       SST         - 7     105  E
X  China Coast Time         CCT         - 8     120  E
X  Japan Standard Time      JST  JT  J  - 9     135  E
X  South Australian Time    SAS         - 9:30  142.5E
X  Guam Standard Time       GST         -10     150  E
X  Russia Zone 1            UZ1         -11     165  E
X  New Zealand Time         NZT  ZT  Z  -11:30  172.5E
X  International Date Line  IDL         -12     180  E
X  Local Mean Time          LMT  LT  L  Varies  Varies
X
X     Note: The special time zone setting "LMT" allows one to do
charts for times given in Local Mean Time. When encountered, the
actual time zone setting will be set just so, doing the "subtract
four minutes for every degree west of the time zone's standard
meridian" arithmetic, to make it work.
X
X     Longitude and latitude locations may be entered in the standard
<degree><direction><minute> notation, e.g. "122W20" or "33S52". The
direction specifier may also be put at the end of the string, with a
period or colon separator between degrees and minutes, e.g.
"122:20W" or "33.52S". The direction character may also be left off
altogether in which case positive values indicate western and
northern locations and negative eastern and southern, e.g. "122.20"
or "-33:52".
X
X     Note: One may enter seconds for times (and locations) as
fractional minutes by including more than two digits for the minute
after the decimal or colon separator. For example, "122:205" will be
treated as 122 degrees and 20.5 minutes west. To specify the time of
4:05am and 45 seconds, enter the time as "4:0575am".
X
X     Astrolog deals with the switchover from the Julian to the
present Gregorian calendar system when accepting input and printing
output. The calendar system changed (at least in Europe) from the
Julian to the Gregorian calendar in 1582 when October 4th was
followed the next day by October 15th. Throughout the program
Astrolog uses the Julian Calendar for date and leap year
specification for dates before 10/4/1582 and the Gregorian after. It
will properly handle the change even in the middle of months in
charts, e.g. in -K calendar charts, -E ephemeris charts, -dm aspect
search charts, and graphics animations, ten days will be skipped in
October 1582.
X
--
X
X     When the standard list of planetary positions is displayed, some
additional pieces of information are shown along with the planetary
locations: Whether or not each planet is in its ruling sign, or fall,
as well as the same information for houses, is shown. Planets in
their exalted and debilitated signs and houses are noted too. In
addition to the (R) indicating a planet in its ruling sign, and an
(F) for a planet in its fall, we have (e) if a planet is in its
exalting sign, and a (d) for a planet in its debilitating sign (which
is always opposite the exaltation, as how the fall is opposite the
ruler). An element table indicating the sum of the signs in each
element and mode and their totals is displayed in a grid form too.
X
X     Also in this main display, the total number of planets in each
of the hemispheres of the wheel, as well the number of objects in
yang/positive/masculine and yin/negative/feminine quality signs, are
counted. To the right of the element table, we have a column of
seven numbers labeled as follows: "+" is the number of "yang" objects
(i.e. in Fire or Air signs); "-" is the number of "yin" objects (i.e.
in Water or Earth signs); "M" is the number of objects above the
horizon (i.e. in the "Southern" hemisphere of the Midheaven); "N" is
the number of objects below the horizon (in the "Northern" hemisphere
of the Nadir); "A" is the number of objects in the Eastern half of
the sky (in the hemisphere of the Ascendant); and "D" is the number
of objects in the Western half of the sky (in the hemisphere of the
Descendant). Note that cusp objects are left out of hemisphere
counts (but still included in the other object summaries) as they
would skew things since they are always in a particular hemisphere.
Finally we have a field indicating the division of objects into the
first six and second six signs of the zodiac. The number of objects
in the first six signs of the zodiac will be printed, labeled by the
character "<". (The number in the second half isn't printed; just
subtract from the total if you want to know.) According to a book on
the Kaballah, the emphasis of the first six signs on the zodiac is on
"what's to learn", and the emphasis on the second six signs is on
"what's to share". Use or interpret this as you wish.
X
X     I have taken the liberty to define ruling and exalting signs for
the asteroids (and the rest of the first twenty objects that don't
already have them.) This won't affect much other than whether a 'R',
'F', 'e', or 'd' is displayed in the -v charts, but it will slightly
affect the powers given to these objects in the -j influence chart
since they can be in their ruling sign, etc. The -HO object list will
display the list of ruling and exalting signs (and the fall and
debilitating signs which are just opposite the above) for all these
objects in addition to the planets; however, I have listed them below:
X
X     Chiron, the compassionate, experienced healer, is most similar
in function to Pisces, hence Chiron rules here. Chiron expresses well
in caring, feeling, Cancer, hence Chiron exalts here. Ceres, goddess
of agriculture and representing the mothering, reproductive instinct,
is similar in function to Taurus, hence Ceres rules here. Ceres
expresses well in the nurturing, caring, sign of Cancer, hence Ceres
exalts here. Pallas Athena, mentally acute and unemotional, is most
similar in function to Virgo, hence Pallas rules here. Pallas
expresses well in practical, disciplined, introverted Capricorn,
hence Pallas exalts here. Juno, ability to sacrifice self-interests
to maintain a relationship, is most similar in function to
relationship oriented Libra, hence Juno rules here. Juno expresses
well in sociable, crowd pleasing Leo, hence Juno exalts here. Vesta,
with its orientation to directing hidden creative or sexual energy
without fear, is most similar in function to Scorpio, hence Vesta
rules here. Vesta expresses well in individualistic, quirky Aquarius,
hence Vesta exalts here.
X
X     The North Node, with its emphasis on being able to break from
the past routine and pursue the unfamiliar and personal growth, is
most similar in function to society questioning independent Aquarius,
hence it rules here. The Node expresses well in growth and sacrifice
oriented Virgo, hence the Node exalts here. The South Node's ruling
and exalting signs are set to be respectively Leo and Pisces, i.e.
the opposite of the North Node's. The Part of Fortune is calculated
based on the positions of the Sun, Moon, and Ascendant; if these
three objects are in their ruling signs, then the Fortune will fall
in Pisces, hence the Fortune should rule here. Similarly, if the Sun,
Moon, and Ascendant are all in their exalting signs, then the Fortune
will fall in Aquarius, hence the Fortune should exalt here. The
Vertex, being always near the Descendant, corresponds to Libra, and
hence has the same rulership and exaltation as Venus: Libra and
Pisces. The East Point, being always near the Ascendant, corresponds
to Mars, and hence has the same rulership and exaltation as Mars:
Aries and Capricorn. Lilith has the rulership of Scorpio and
exaltation in Pisces. House cusps and angles rule the sign
corresponding to them, e.g. Aries for the Ascendant, Taurus for the
2nd Cusp, and so on. House cusp objects exalt in the next sign of the
same element beyond the one they rule, e.g. Aries exalts in Leo.
X
X     Each uranian also has been assigned its own ruling and exalting
sign, meaning uranians in their rulership, etc, will be flagged as
such and have more or less influence and so on. I also came up with
these myself and used the interpretation strings to decide what the
most appropriate signs are. If you prefer other signs or no sign at
all for any of the rulerships, you can easily change them using the
-YJ switch described elsewhere. Specifically, Cupido rules Libra and
exalts in Gemini, Hades rules Scorpio and exalts in Virgo, Zeus rules
Leo and exalts in Aries, Kronos rules Capricorn and exalts in
Sagittarius, Apollon rules Sagittarius and exalts in Aquarius,
Admetos rules Virgo and exalts in Scorpio, Vulkanus rules Aries and
exalts in Leo, and finally Poseidon rules Sagittarius and exalts in
Pisces.
X
X     The standard chart listing of the planetary positions will also
include an additional field for the "velocity" of each planet. This
velocity value approximates how fast the planet is moving through the
zodiac with respect to the Earth (or whatever the central body is set
to) in degrees per day. This value of course, goes negative when a
planet goes retrograde. This is useful not only to get a feel for how
fast each planet moves through the zodiac, but to determine when a
planet is about to go retrograde or direct - the value approaches
zero when the planet changes direction.
X
X
**********************************************
FILES, DATA DEFAULTS, AND COMPILE TIME OPTIONS
**********************************************
X
X     Astrolog includes the ability to search an input file for
various default settings to use in the program. This allows one to
easily change major defaults without having to recompile the program,
which is useful if, say, one receives a compiled executable from a
friend who has a different configuration. The program looks for the
file "astrolog.dat" in the current directory, and if not there, looks
for it in the default directory (and in directories indicated by
environment variables if set). Parameters in this file will override
any defaults compiled into the program, although the highest priority
is still given to the command line options. Note one doesn't *have*
to have this file in order to run the program - if not found Astrolog
will still run as before using compile time defaults.
X
X     Astrolog.dat config files from versions 4.10 and before won't
work with version 5.40, because like the chart info files, the
astrolog.dat file is also a series of command switches (see below).
All the fixed astrolog.dat fields used in version 4.10 and before no
longer exist, since there are command switches to do the same things
as everything the old files could set and a whole lot more.
Attempting to use any old astrolog.dat file will cause the program to
complain that it's not in any valid format. If you have an old file,
delete it and modify the one included with this release to correspond
to your desired settings. Version 4.20 through 5.30 config files are
however fully compatible with 5.40 and don't need to be changed.
X
--
X
X     As of Astrolog version 4.20, all files are a series of command
switches that indicate the contents of the file and set the
appropriate things when executed. This is very powerful, extendable,
and general. Astrolog still has the ability to read and write the old
chart formats. This affects -o chart info files, -o0 chart position
files, and the astrolog.dat config file. In a sense there is no
difference between the three formats, just they are generated or read
in for different situations. Whenever any chart is read in, Astrolog
simply reads in the file a line at a time and processes the switches
as if they were on the command line or entered in a -Q loop.
X
X     The astrolog.dat config file is one of the files that is a
series of command lines. This change makes the astrolog.dat file much
more powerful and versatile than it would be otherwise. The file is
not in a fixed format with fields that have to be in a certain order.
You can move lines around, add as many lines as you want, or take
lines out without problem. These config files shouldn't become out of
date in future versions of the program either. Incompatibilities will
only arise if the syntax of a switch changes, and even then it's
obvious as to the small correction that needs to be made. It's
important to remember that any switch can be put in the astrolog.dat
file. For example, you can change the default behavior of the program
when invoked without any switches, by say putting "-n" in it, to make
the program always display the chart for now unless you specify
otherwise. You may want to put "-C" in it if you want the house cusps
to always be included in transit and other charts. If you are always
doing graphics charts, you can put "-X" in there somewhere so you
don't have to put it on the command line. Long or complicated
switches like new planet definitions, and color or interpretation
customizations, are good candidates to put in astrolog.dat so they
don't have to be retyped all the time.
X
X     The file as generated with the -o switch is also just a couple
of command lines to set the chart information appropriately. (Before
version 4.20, the older file format hadn't changed a bit since files
where first introduced in version 1.20!) Note that you can manually
add additional switches to any chart info file, to have per chart
settings. For example, if you are always displaying a particular
natal chart's aspect grid, you can put a "-g" in that particular file
so you don't have to include -g on the actual command line with the
"-i file". (Or you can put the "-g" in the astrolog.dat file and have
all charts come up by default in the aspect grid instead of the -v
listing.) Note also that the -i switch is technically a generic
command file reader. You can read any switch file with -i, and even
reload the astrolog.dat defaults with a line such as "-i astrolog.dat".
X
X     Since -i will read in and process any command file, you can make
your own arbitrary command files and read them in whenever you want.
You aren't limited to modifying just chart info files and
astrolog.dat. Say you like to use a narrower set of orbs for
transits. You can make a special file that just sets a bunch of orbs
using the -A switches, and then read it in via "-i narroworbfile" and
combine it with -t or whatever. Note that command files can even
process other command files inside of them. Remember that
astrolog.dat is just a special command file; the program basically
just does a "-i astrolog.dat" internally on startup.
X
X     -@ switch: All Astrolog switch files have to begin with the '@'
character, which identifies them as such. The switch files as
generated with -o and -o0, and the default astrolog.dat file, have a
couple numbers immediately following their '@' which indicate the
file type and version, included for potential backward compatibility
issues in the future. (For those interested, the first two digits
indicate file type, where "01" is a -o chart info file, "02" is a -o0
chart position file, and "03" is a configuration file like
astrolog.dat. The second two digits indicate file version: Chart info
files are "0102", because version 1 of a chart info file was the
pre-version 4.20 form. Chart position files are "0203" because
version 2 was the pre-version 4.20 form, and version 1 was the
pre-version 3.10 form of the old format. The astrolog.dat file is
"0308" because versions 1..7 were all the different old fixed field
versions of this dating back to when the config file was first
introduced.) Note that the '@' happens to technically be a switch
too, but is only dealt with internally by the program. If you make
any of your own command files to read in with -i, just be sure there
is a '@' character (better yet the sequence of characters "@0308" to
be like the default astrolog.dat) at its very beginning and
everything will work.
X
X     Chart position files as generated with the -o0 switch are much
improved over the format used in versions 4.10 and before. The zodiac
positions have an extra two digits of precision and the declinations
have an extra one digit. The newer files include the velocity of the
planet and its distance from the sun, so applying vs. separating
aspects and -S orbit charts work perfectly. (Before the data would be
lost.) These files may also include star positions unlike before, and
are more complete with respect to house cusps. The actual house array
is kept separate from the cusp object indexes, meaning that one for
example can reload charts in the Equal house system that disassociate
the Midheaven from the 10th cusp and remember both positions, and
even save a -r synastry chart with -o0 and remember both sets of
house cusps on reload.
X
X     -YF switch: As -o0 position files are a series of command lines,
there is a switch to set the actual positions of a planet. This is
the -YF switch which takes eight parameters, which are: the index of
the object to set the positions of, the degree within the sign of its
position, the zodiac sign of its position, the minute within the
degree of its position, the degree of its ecliptic declination, the
minute within the degree of the declination (which should always be
positive, e.g. for a declination of -10.5 degrees, the parameters
would be -10 and 30), the velocity in degrees per day (positive is
direct motion, negative retrograde), and finally the distance from
the Sun or central body in AU. This switch shouldn't really be used
outside of -o0 files as it causes the chart to be assumed to have no
time or space, but is described here for completeness. Note that
another advantage to the newer -o0 files is that you can again add
other switches to them (e.g. "-s" to indicate if it's a position file
for a tropical or sidereal zodiac chart), and rearrange or delete
lines without problem, unlike the older -o0 files which required all
the planets and in a fixed order.
X
X     Here's an example of one of the switch based command files,
specifically a chart info file with the newer name, city, and
Daylight fields in it. This is much easier to understand and modify
than older files, and is the info for my own natal chart consisting
of the three lines below:
X
@0102  ; Astrolog chart info.
/qb Nov 19 1971 11:01am ST +8:00 122:20W 47:36N
/zi "Walter D. Pullen" "Seattle, WA"
X
--
X
X     Astrolog 5.40 has several environment variables which may be set
to indicate directories where to find the various files it may look
for. Without them, the only place the program will look for chart
files, the astrolog.dat initialization file, and ephemeris files is
in the current directory and default directories set at compile time.
The program will look where all of these environment variables point,
if they are defined. The three environment variables are named
"ASTROLOG", "ASTR5.40", and "ASTR". On a PC you can set an
environment variable from the DOS prompt with a command such as "set
ASTROLOG=C:\PROGRAMS\ASTRO540\CHARTS". This command can be put in
your AUTOEXEC.BAT file to remain persistent. On a Unix system you can
set an environment variable from the shell with a command such as
"setenv ASTROLOG ~username/programs/astro540/charts". This line can
be put in your .cshrc file to remain persistent. Note that the
ASTR5.40 environment variable is version specific, i.e. the previous
version looked in one called ASTR5.30 instead. This allows one to
have a directory for version specific files such as the astrolog.dat
file, and have multiple versions of Astrolog on the system at once
without them conflicting with each other. (Note that Unix systems
running the ksh shell apparently don't acccept variables like
ASTR5.40 with periods in them, but they will accept the other two.)
I personally point ASTROLOG to my chart files directory, ASTR5.40 to
my astrolog.dat directory, and ASTR to my ephemeris directory,
although any file may be found with any of the variables.
Specifically, when Astrolog searches for a file, it will look in the
following directories, in order: The current directory, the ASTR5.40
environment variable directory, the ASTROLOG environment directory,
the ASTR dir, and finally the compile time default directory.
X
--
X
X     Some systems (for example, Mac's) don't directly accept
parameter switches on the command line (such as Astrolog is being
booted from a menu.) Therefore, such a limitation makes one unable to
access many program features in the normal way. If this is the case
with your system (or if you just don't like command line options),
then comment out the '#define SWITCHES' line at the beginning of the
astrolog.h file. If you do this, then the program will ignore any
switches and prompt you to enter them manually at the very beginning
of program execution. You just enter one line containing all the
parameters together, separated by one or more spaces, just like is
done when typing in the command line, or when in the -Q loop mode.
Astrolog will automatically parse the string and extract the
parameters, just like the operating system shell does.
X
X     Related to this, the "-." switch, when encountered on a command
line, will immediately terminate the program, ignoring any modes or
other command switches. This is the formal way how to really exit the
program when in the -Q loop (and really only useful in this case).
Remember, earlier it was said to enter "." for the command line to
exit the -Q mode. Astrolog internally interprets the "." as a switch
without a leading dash, i.e. "-.", which is a switch that will force
program termination.
X
--
X
X     I often use Astrolog to look at and compare files containing
charts of various people. I have many chart files, so I keep them in
a separate directory. Since it is always a pain to have to cd into
this special directory all the time, there is a DEFAULT_DIR string to
be set at compile time. Whenever the program reads in a chart file
with the -i option, it will first look in the current directory for
it. If it's not found there, Astrolog will then look for a file of
the same name in this special default directory (and in directories
indicated by environment variables if set).
X
X     A couple of other compile time option variables are in the
include file astrolog.h: For those people who don't like Placidus, a
default house system can be set by changing the value of
DEFAULT_SYSTEM to the value from 0 to 11 indicating what system to
use if the user doesn't explicitly specify one with -c or in
astrolog.dat. A few other compile time options are in astrolog.h
which can be used to leave out certain parts of the program which you
don't desire to have or just take up memory and make the executable
larger. The #define INTERPRET can be commented out to remove all the
-I interpretation routines and tables. The #define BIORHYTHM can be
commented out to remove the non-astrological -rb biorhythm text and
graphical charts. And the #define CONSTEL can be commented out to
remove the -XF constellation graphics and -HF text constellation
list. Finally, concerning the source code itself, all of Astrolog's
functions have full Ansi prototypes, which can be turned off for
older compilers by commenting out the PROTO #ifdef.
X
X     There is a special compile time variable dealing with graphics
(in addition to the "X11" and "MSG" / "BGI" ones) called "GRAPH". One
comments out the #define GRAPH line if they don't want any graphics
at all, and not just if they don't have X windows or PC screen
graphics. In other words, one can generate most of Astrolog's
graphics charts even if they don't have X windows or a PC with
graphics abilities. When GRAPH is defined, but X11 or MSG and BGI
aren't, the program will generate the charts, but just never try to
bring up a window; it will simply always assume that you are writing
a bitmap file. The bitmap file will contain a (unfortunately always
black and white for the X bitmap format) image of what would normally
be in the window, just as the -Xb switch does. One can then use
various graphics utilities to convert the image into something they
can display on their system if they can't do so using any of the
available bitmap modes. (Any system that can compile Astrolog should
be able to compile in all the non-screen graphics features as well.)
X
X     A bitmap output mode other than the Windows .bmp bitmaps and
standard ones that can be read with the Unix X11 xsetroot command is
allowed in the graphics routines. If one changes the BITMAPMODE
compile time option in astrolog.h to the character 'A' when
compiling, or invokes the -Xb switch as -Xba, then all bitmaps output
will be in a straight Ascii form, with one character corresponding to
each pixel. This format is identical to the result produced by the
Unix command bmtoa (when the chart is monochrome), and it can be
converted back into a bitmap with the Unix command atobm. Although
not as efficient spacewise, this is a simpler format, and is
recommended for those without screen capabilities who still want to
use Astrolog's graphics, if they want to write their own conversion
program.
X
X
*****************************************
DESCRIPTION OF X WINDOW GRAPHICS FEATURES
*****************************************
X
X     One of the most impressive features of Astrolog are its graphics
features available for X windows, which are generally accessed in the
program via the -X switch and derivatives of it on the command line.
There are seven different types of chart displays: A standard graphic
display of a wheel chart in a window (with glyphs, aspects in the
center, etc), graphic displays of the Astro-graph charts (which look
almost identical to the Astro*Carto*Graphy maps from Jim Lewis)
complete with all the labeled lines drawn on a map of the world (like
the -L option), aspect/midpoint grids showing the aspects and orbs in
effect between every body in a chart (like -g option), a local sky
chart showing where each planet is located on a map of the local
horizon area (as in -Z), a space chart showing an aerial view of the
solar system (as in -S), a dispositor graph chart showing planetary
rulership chains (accessed with -j), and a graphic ephemeris plotting
position vs. time (as in -E), in addition to a couple of
non-astrological charts such as calendar (-K) and biorhythm (-rb)
graphics. The X wheel and aspect grid charts can also displayed in a
different manner to accommodate relationship comparison charts
showing two sets of planets at once. There are also other commands
that can be given to the window once it is up and running, which can
do other things, such as continually update the window every few
seconds to the current status (i.e. an extended version of the -n
option) as well as other forms of animation. Note that the program is
still text based, and one can turn off all the X features by
commenting out the #define X11 in astrolog.h if they don't have X
windows.
X
X     Probably the only thing more impressive than the graphics
features are the graphics features displayed on color monitors.
(Charts displayed in color are *much* more eye catching than the
monochrome ones, in my opinion.) Here is how the colors have been
assigned for the various charts: Four colors have been allocated for
the four elements - Fire = Red, Earth = Brown, Air = Green, Water =
Blue. The various sign glyphs (and the corresponding house labels)
are in the color of their element. Planets are in the color of the
sign of their main ruler. Chiron and the four asteroids are Pink,
while the north node, and other non-physical objects like the fortune
and vertex are Blue Grey. Representations of the Ascendant/
Descendant/ Midheaven/ Nadir (in the astro-graph map lines and
elsewhere) are in the element color of the corresponding sign/house
that the angular lines refer to, i.e. Ascendant = Red, Midheaven =
Brown, Descendant = Green, Nadir = Blue. A few extra things have been
added for color wheel charts only: dark gray lines marking off each
house (in addition to the main lines on the horizon and meridian),
and each degree instead of every 5th degree being marked in dark gray
on the outer circle (every 5th degree being white). Aspects lines are
colored too, as follows: Conjunctions = Yellow, Sextiles = Light
Blue, Squares = Red, Trines = Green, Oppositions = Dark Blue. For the
minor aspects we have: Inconjuncts/Semisextiles = Pink, Semisquares/
Sesquiquadratures = Orange, (Bi/Semi)Quintiles = Blue Grey,
(Bi/Tri)Septiles = Maroon, (Bi/Quatro)Noviles = Violet.
X
X     For color terminals, the -XG globe display and -XW world map
display are done with the continents in different colors, also making
them look much better than monochrome maps. Each of the seven
continents is in a different color of the rainbow, and the colors are
chosen to correspond to the appropriate chakra (etheric energy vortex
along the human spine) that goes with each land mass. They are:
Africa - red - Root chakra, Australia - orange - Navel chakra, South
America - yellow - Solar plexus chakra, North America - green - Heart
chakra, Europe - blue - Throat chakra, Asia - indigo - Third Eye
chakra, Antarctica - violet - Crown chakra. Major lakes are colored
navy blue, of course.
X
--
X
-v -X: The graphic wheel charts have their graphic information
organized as follows: There's an outer circle showing the signs and
sign glyphs, inside of which is a smaller circle divided up into 5
degree increments to make determining exact degrees easier. Inside of
this is a circle divided up into the 12 houses labeled with numbers.
The entire chart is divided by two dashed lines through the
Ascendant/Descendant (which is always horizontal of course) and the
Midheaven/Nadir. Inside the house circle are the planet glyphs in
their appropriate positions. Small pointer lines run from each glyph
to just before single dots. These dots indicate the precise locations
in the zodiac of each object. The pointer lines (which are dashed if
the object is retrograde and solid otherwise) are necessary so as not
to have to draw planet glyphs on top of one another when planets are
conjunct. Inside the ring of the single dots, are the aspect lines
connecting these positions. Since the default number of aspects to
use is just the 5 majors, one can determine which aspect is in place
just by looking at the aspect line. The accuracy of the aspect is
determined by the dashedness of the line: A solid line means the orb
is < 2 degrees; a dashed line means the orb is 2 to 4 degrees; a
really dashed line mean the orb is 4 to 6 degrees, and so on.
X
-v0 -X: Astrolog's wheel charts will be labeled more extensively than
just having the chart header information displayed at the bottom of
the graphic like in other chart modes. The wheels will include full
information on time, place, the chart's name and city fields if
defined, house system, zodiac, central planet, element table info
(including the count of objects in angular, succeedent, and cadent
houses, and the count of objects in the first six "learning" signs
and the last six "sharing" signs), as well as the actual positions of
house cusps and planets as displayed in the wheel. All this
information is in a "sidebar" to the right of the wheel which
includes a listing not unlike the -v text chart. (Note that the size
of this sidebar is such that for the default 480x480 pixel chart
size, including the sidebar will make it 640x480, which perfectly
fills a VGA PC screen.)  If you want a simpler style wheel with just
the chart information at the bottom of the graphic, set the -v0 flag,
as in "-v0 -X" instead of "-v -X" or just "-X".
X
-w -X: A different way of formatting the graphical wheel charts
described above is available by combining the -w switch with -X.
Normally all of Astrolog's wheel charts are such that each zodiac
sign is the same size. Due to different house sizes in most systems
however, this makes the houses appear different sizes on the wheel,
so that the Midheaven won't be the exact top of the chart for
instance. Some users may instead prefer "house oriented" as opposed
to sign oriented wheel charts. Astrolog, with the -w -X combination,
will make each house be the same size on the screen, and will
compress or expand the signs instead (of course this means that such
things as exact squares may not be between objects exactly 90 degrees
apart on the circle any more). When graphics are displayed on the
screen, the '0' key will toggle between the two forms of wheel chart.
X
-L -X: The graphical astro-graph charts are organized as follows: A
map of the world is shown. The edges of the map are labeled with
ruler lines that are 5 degrees apart (with longer ruler lines for
more important longitudes and latitudes, like those that are
multiples of 10, 30, etc.) The equator is labeled with a dashed line.
The polar regions of the world aren't shown; the map shown ranges
from 60 degrees S latitude to 75 degrees N latitude. Note that each
pixel on the screen represents exactly one half a degree on the
world. (For -Xs 100 the ratio is one pixel to one degree, and for -Xs
400 the ratio is one pixel to 1/4 degree.) On this map are drawn the
lines indicating where on the world the various planets are angular
at the time in question. (Note: you might want to -R restrict some
objects because otherwise the map tends to get pretty cluttered with
lines.) As expected, Midheaven and Nadir lines are vertical, and the
Ascendant and Descendant lines are curved. Little square boxes on the
Midheaven lines indicate the exact zenith latitude location. Each
line is labeled at the top or the bottom of the screen, showing what
planet is in question and (sometimes) what angle is in question. All
Ascendant and Midheaven lines are labeled at the bottom of the
screen, and all Descendant and Nadir lines are labeled at the top.
Each line goes a bit beyond to the top or bottom of the world map,
and then another pointer segment (which is again dashed of the object
in question is retrograde) goes and points to the planet glyph. The
glyph for the Ascendant or Midheaven is under each of the glyphs at
the bottom of the screen, explicitly indicating whether the line is
an Ascendant or Midheaven line. At the top of the screen, however,
there are only the glyphs, but one can still determine whether these
lines are Descendant or Nadir lines based on whether they are curved
or not. Note that not all the Descendant lines are labeled; this is
because some of the Ascendant/Descendant lines actually connect near
the top of the screen and don't actually cross it. This graphic
astro-graph chart will display a small purple dot at the precise
point on the world map for which the chart in question is being
generated. This is useful to help see how close the various planetary
lines are to you, if you live in the middle of the continent or
someplace not easily determinable on the compact map of the world.
X
-L0 -X: Graphic astro-graph charts will be done slightly differently
if done by combining -L0 with -X. A thin horizontal line will be
drawn all across the map of the world at the latitude of the chart in
question. Normally, there's only a small dot at the precise location.
In astro-graph charts, intersections between lines anywhere at the
same latitude of a natal chart, even if any number of degrees away
longitudinally, will affect the person, in the same way but not as
stong as if they are directly under the instersection itself. This
small chart modification can make finding such intersections easier
in the graphics chart, just as -L0 for text charts actually lists the
latitudes of all crossings.
X
-g -X: Aspect grid graphics with the appropriate aspect glyphs can be
displayed by combining the -g option with the -X option (astrolog -g
-X). Both the split aspect/midpoint grids labeled down the diagonal,
as well as the relationship aspect grids between two charts (astrolog
-r0 <file1> <file2> -g -X) are supported. The aspect glyphs, objects,
and the signs in the grids are in their colors as defined earlier.
Like the astro-graph windows, these charts can't be resized in the
normal way unless one uses the '>' and '<' keys. For anything less
than the larger scale sizes (achieved with the switch -Xs 300, or by
pressing '>' within a window) all that will be displayed in each
aspect grid cell is the glyphs of the aspect in effect, the planet
being aspected, or the sign of the midpoint. However, once the
largest scale size is reached, there is room in each cell to display
the aspect orb to the nearest minute off of exact (with a plus or
minus sign indicating whether the actual angle is slightly greater
than or less than exact, or an 'a' or 's' if applying vs. separating
orbs are to be shown instead); the degree and minute in addition to
the sign for midpoints; and the degree and sign location for each
planet that's in the grid, as with the -g text charts.
X
-m -X: Combining the -m switch with -X will have the same result as
-g with -X, since the aspect grid shows both aspects and midpoints
separated by the grid diagonal. However, doing a relationship
midpoint chart (-r0 -m -X) will result in the relationship aspect
grid coming up but showing the midpoints instead of aspects, as
desired. The -r0 -m -X switch combination implicitly does the results
of the -g0 switch, which for relationship charts puts midpoints
instead of aspects in the grid.
X
-Z -X: The -Z local horizon feature can be displayed in an X window
as well (e.g. astrolog -Z -X), in which all the planets will be
displayed in a window depicting the sky. The small dot above or below
each glyph indicates exactly where each planet is. (Some of the
glyphs may be overlapping, although the program tries to cut down on
this.) There is a horizontal line dividing the window representing
the local horizon; planets above this line are visible, while planets
below it are set. There are three vertical lines dividing the window
as well: The middle line represents the due south direction, the one
to the left is due east, the one to the right is due west, and the
edges of the window are due north. (These directions are labeled in
the borders of the chart.) Like the standard chart display, this
window or graphic may be resized to any proportion. At any time one
can press the 'Z' key when a graphic is up to enter this display type
in that window.
X
-Z0 -X: An additional graphics chart is available through the -Z0
switch: local horizon charts suitable for stargazing. As we know, the
normal -Z switch generates a listing of the planets with respect to
the local horizon, and the -Z combined with the -X switch generates a
graphic image of the planets and stars on the local horizon. This
chart assumes one is facing due south, and is divided left to right
by the horizon line, with straight up being toward the top of the
screen and straight down toward the bottom. This is a good chart,
especially for noticing the rising and setting of planets and other
objects, but the fact that the meridian is split up causes distortion
when trying to view objects high up in the sky. Therefore, if one
combines this -Z0 switch with the -X switch, a differently oriented
local horizon chart will be displayed. Here, the zenith point
straight up is in the center of the screen, and the horizon line is a
surrounding circle. Due north is along the line from the center to
the top of the screen, due south is on the line from the center to
the bottom, east is to the left, and west is to the right. In other
words, this is just like what one would see if they were lying on
their back looking straight up with their feet to the south, so this
should be better for stargazing. Outside the circle marks what's
below the horizon, and the extreme corners of the screen mark the
nadir - what's straight down. As with the normal -Z graphic chart,
this one has the various axes marked at five degree increments.
X
-S -X: The -S switch can be combined with -X to give a graphics chart
of the solar system. This will be displayed as an aerial view of the
entire solar system, with 0 degrees Aries to the left of the screen,
0 degrees Cancer to the bottom, etc. Note that this chart includes
all possible planets, including the Earth (whose glyph is a cross
inside a circle). Whatever object is chosen to be the central body is
at the center of the screen, with all the others around it. This is a
fun chart to animate - watch the planets go around the Sun, and *see*
how they turn retrograde with respect to the Earth. In addition to
the bodies themselves, twelve spokes are drawn from the center body
to the edge of the screen, which delineate the zodiac with respect to
it. Note that the scale of the solar system is large; attempting to
fit all the planets out to Pluto on the screen at once will cause all
the inner planets to be crammed together near the middle of the
screen. To deal with this, the scale size as indicated with the -Xs
switch and the '<' and '>' keys will affect how much of the solar
system is viewed at once (in addition to the glyph sizes). For a
scale size of 400, the viewing region will have a radius of 1 AU
(just enough to cover out to the Earth's orbit). For a scale size of
300, the viewport will have a radius of 6 AU (about out to the orbit
of Jupiter; useful for viewing the inner planets). For a scale size
of 200 (default), it will have a radius of 30 AU (enough to include
Neptune, and Pluto most of the time). Finally, a scale size of 100
will result in a radius of 90 AU, enough to easily include the entire
solar system, as well as the orbits of the hypothetical Uranian
bodies beyond Pluto. Note that this chart (and its text version as
well) will usually leave the Earth's Moon out. The -b extended
Placalc formulas are required to be in effect (as well as either the
Sun or Earth being the central body) in order for the Moon to be able
to appear. At a 400% scale zoom with the Moon included as well, one
can actually get a feel for the relative distance of the Sun from the
Earth and the Moon from the Earth, although the chart will have to be
over 1000 pixels wide for the Moon to even appear one pixel away from
the Earth at all!
X
-l -X: The Gauquelin sector chart may be displayed in graphical form
by combining the -l switch with -X, where the 36 sectors will be
arranged in a wheel, with chart header info displayed at the bottom
or in a sidebar as with regular wheels. Each planet will be plotted
at its appropriate sector location, with plus zone sectors labeled in
red and minus in dark green, and aspects will be indicated in the
middle of the wheel. This chart also has the plus or minus zone
status of each sector indicated by a small plus or minus sign around
the outside border of the wheel. The sidebar in this graphic
Gauquelin sector wheel chart will to the right of each planet
position show the sector number the planet falls in. (Normally this
is just the glyph for the object in question like it is for the other
wheels.)
X
-j -X: Graphic dispositor charts are available by combining the -j
influence switch with -X. This is a another graphics chart format
that can also be switched to whenever screen graphics are up by
pressing the 'J' key. The dispositor of a planet is the planet that
rules the sign it's located in. For example, if you have Venus in
Aries, the dispositor for your Venus is Mars. A graph can be made
showing an arrow from each planet to its dispositor. A final
dispositor is a planet who is its own dispositor, i.e. in its ruling
sign with no arrows pointing away from it. There can also be two
planets in what's called mutual reception (or a reception loop of
more than two) if they are each other's dispositor, e.g. Venus in
Aries and Mars in Libra. Astrolog's dispositor chart will show four
subgraphs, one in each quadrant. Both a sign dispositor graph, as
described above, and a house dispositor graph, where each planet is
linked to the planet ruling the house it's in, are shown. In
addition, both types have the same information displayed in two
different useful formats: a wheel with the planets around the
perimeter, and in a hierarchy with final dispositors at the top and
the other planets stacked based on how many levels they are from
final ones. Final dispositors are circled in white, while those in
reception loops are circled in gray, and dispositor arrows within the
top level (i.e. in reception loops) are in white too instead of the
color of the planet for easy identification. For a demo of the
dispositors in your own chart, do "astrolog -i yourchartfile -j -X".
X
-K -X: Graphic calendar charts are available by combining the -K
calendar chart with -X. This is another graphics format that can be
switched to whenever screen graphics are up by pressing the 'K' key.
This shows a calendar for the month of the current chart, like the
corresponding text chart but in graphic format with boxes for each
day like a real calendar. The current day within the month will be
highlighted in green (if the -Xl label inhibitor flag isn't on). The
-Xi alternate display mode will put the date numbers in the middle of
their box instead of in the upper left corner. Finally the -Xt chart
info display flag for this particular chart will control how the date
numbers are justified in their box. The -Ky yearly calendar switch
may be combined with -X switch to generate a graphic calendar for the
entire year. When the graphic calendar for the year is drawn, the 12
individual months will be arranged in either a 2x6 grid, a 3x4 grid,
a 4x3 grid, or a 6x2 grid, based on the dimensions of the chart; for
example, a square chart will be drawn three months across by four
down, but a tall skinny chart will cause the calendar layout to be in
a 2x6 grid.
X
-E -X: A graphical planetary tracking chart is available by combining
the -E switch with -X. This "graphical ephemeris" will display the
sign degrees of the zodiac along the horizontal axis, and the days in
the given month along the vertical. The positions of the planets at
each day (at the time and zone from the current chart) are then
graphed. The result is a bunch of wavy lines that make it easy to see
all the planetary movements during the month. Wherever lines cross
there's a conjunction on the day indicated on the axis at the same
level as the crossing. Although this only looks at the month in the
given chart information, the actual day will be highlighted on the
vertical axis. Combining the -Ey yearly ephemeris instead with -X
will generate a graphical ephemeris showing the movements for the
entire year, with the months labeled along the vertical axis. In the
-r0 relationship comparison mode, this chart will have in addition to
the standard ephemeris lines for the first chart, dashed vertical
lines drawn at the positions of the planets in the second chart, at
the time the ephemeris is done for.
X
-r0 -X: True relationship wheel charts can be displayed in a window,
i.e. where the planets of both charts are displayed in separate rings
of the same wheel. Use the -r0 option to display this comparison
type. For example, for the command "astrolog -r0 person1 person2 -X",
the following is displayed: The signs and houses as in person1's
chart are drawn in the outermost part of the wheel. Inside this is a
ring of person2's planets as displayed in person1's houses, and
inside of this are person1's own planets. Finally at the very middle
is an aspect grid, which shows those aspects that are occurring
between the objects in the two charts. Basically this is just the
standard wheel chart for person1, except that person2's planets are
in an outer ring of objects and the aspect grid shows the aspects of
the relationship. Putting such a chart in animation mode only affects
person2's planets, so this is a great way to analyze transits: Doing
"astrolog -t yourchartfile -X" will show all your current transits,
and allow you to easily animate the transiting planets through your
natal signs and houses.
X
-rb -X: Graphical biorhythm charts are available by combining the -rb
(or -yb) switch with -X. This will make a graph of one's biorhythm
for the two weeks before and after the specified time, with days on
the horizontal axis and the Physical, Emotional, and Intellectual
percentages on the vertical. When any graphics chart is up, one may
press the 'Y' key to revert to a biorhythm chart. (Note that as this
is a relationship comparison chart, if you go to it from a graphics
mode only showing one chart, it will show the biorhythm for them at
their birth, and you will want to then animate or adjust it to get a
useful display.)
X
--
X
X     A couple of conveniences for the graphics features exist. Note
that the -Xo <graphicsfilename> option is only used in conjunction
with the -Xb write output to bitmap switch (or the -Xp or -XM
PostScript and metafile chart formats). Therefore, -Xo automatically
assumes -Xb is set. (Invoking -Xb itself without -Xo will have the
program prompt the user for the bitmap filename.) In other words,
astrolog -Xb -Xo 'file' is the same as just astrolog -Xo 'file'.
Astrolog includes its own appropriate X bitmap (a rainbow over an
opened Third Eye) if one iconifies its X window.
X
X     For X windows, one can animate a graphics chart on the root
background by combining -XB with the -Xn switch. This will be just
like the animations done in windows except the root is being used
instead. Astrolog can be run in the background this way to
continually update your root to the current chart representing the
present moment. Limitations with this are that since there's no
window, no keypresses can be processed so the program must be
manually terminated, and that the continual updates will be as CPU
intensive as the window animations are.
X
X     Hack: A fun thing to do is that a graphic wheel chart with -I
interpretation on (the interpretation setting normally doesn't affect
graphics in any way) will decorate the corners around the wheel! How
its decorated depends on the screen width setting in astrolog.dat or
passed to -I. If this value is even, a spider web design will be put
in each corner. If this value is odd, a moire pattern will be put in
each corner. The decoration looks best when the screen width is
around 79 or 80. The higher the value, the more dense the lines will
be in the "spider webs", or the less of the screen the moire will
cover. (Don't make the moire value too low or you will cover the
entire screen, which looks cool but doesn't aid reading the chart
any! :)
X
X
************************************
DESCRIPTION OF DOS GRAPHICS FEATURES
************************************
X
X     Astrolog's PC graphics charts look and feel and are displayed
just like the X window graphics already described. When compiling,
one has a choice between four options: (1) choose no graphics
abilities at all, (2) compile so that graphic chart bitmaps can be
generated and output to a file, (3) compile allowing file graphics in
addition to direct screen graphics in X windows, and (4) compile with
file graphics and direct graphics on the screen of a PC. The addition
of PC graphics in no way inhibits or affects the X window graphics
already in place; it's merely a matter of which compile time options
are set. Unix users don't need to look at this section.
X
X     Astrolog uses the Microsoft PC graphics library as defined in
the file graph.h included with their Visual C/C++ 1.52 "C" language
compiler. This file and the graphics.lib library is needed in order
to be able to compile with these graphics options set, just as the X
window libraries are needed to compile with those graphics included.
If unavailable, one can still access these PC graphics with the
library linked in, in the already compiled executable posted.
X
X     PC Astrolog is a DOS program and should be run from a DOS
prompt, outside of any Windows system. To generate a graphics chart
instead of a text one, include the -X switch just as one would do to
bring up an X window. The expected graphic chart will be displayed on
the screen unless the -Xb write bitmap to file switch is in effect.
The colors chosen for the graphics are basically identical to those
chosen in X window charts, and both of these in turn are based on the
Ansi colors used in the Ansi text charts.
X
X     Now, there are many various types of PC monitors and
resolutions. Astrolog will automatically try to determine and pick
the highest resolution mode available on your system, so this need
not be worried about.
X
X     The PC Astrolog charts may be animated in all the various ways,
and the animation will usually be flicker free! Now, PC's do have
limited memory, therefore there might not be room for more than one
page of graphics at the highest resolution. Hence, animation at the
highest (default) mode, may flicker; however, graphics at a slightly
lower resolution may take enough less memory to allow enough to do
flicker free animation. A special PC only feature for this has been
added: Pressing the 'tab' key while the PC graphics are up will try
to pick a lower resolution, where flicker free animation can be done.
Specifically, we'll toggle to a 640x350 EGA mode. On my own system,
the highest resolution I get is a 640x480 16 color VGA mode, however
the charts can't be animated without flicker. When I hit 'tab', I
drop from 480 lines of graphics to 350, but now the animation will be
perfectly smooth. The results with whatever graphics system you have
may be different.
X
X     The chart that comes up will use as many pixels as is defined by
the chart's size as specified with the -Xw and -Xs switches. The 'Q'
change chart size to square key works just as before. However, on PC
screens we will try to take in account the pixel size ratio. On EGA
screens where the pixels are long and narrow, meaning a true "square"
chart looks tall and thin, we compensate by increasing the horizontal
size of the chart. The 'B' key, which for X window graphics will
blast the current window contents to the root background, is a
meaningless feature for a PC. This key, for PC graphics systems, will
instead resize the chart to be the full size of the screen. Note
that some charts however (such as wheel charts without sidebars, -S
space charts, -Z0 sky charts, and -XG globes) are distorted unless
they are square. For these charts, the 'B' key will resize the chart
to be the largest square that will fit on the screen, i.e. will
automatically do what pressing 'B' followed by the 'Q' force to
square key would do. When the graphics mode is changed through
'tab', the chart size will also be modified to be the largest
"square" that will fit on the screen.
X
X     If the size of the chart is less than the size of the screen, it
will be displayed centered in the middle of the screen. If however
the chart size is greater than the screen size, then the chart will
take up the whole screen, and part of it will be clipped. By default
we show the upper left corner of the chart if this is the case. Now,
one can define and change which part of the chart gets shown. On PC's
the meaning of pressing the number keys have been enhanced. Normally,
number keys set the animation speed; they still do, but now only when
animation is actually being done. If not in animation, the number
keys from 1..9 will define which "quadrant" or area of the chart gets
shown. It's best to think of and use the number pad for this feature
(make sure num lock is on!) Pressing the '7' key, i.e. the upper left
number on the number pad, will set it so the default upper left part
of the chart is seen. Pressing the '3' key, on the lower right corner
of the pad, will show the lower right corner of charts larger than
the screen size. Pressing '5' will show the middle area of the chart,
with equal amounts of the chart clipped from left and right, and top
and bottom. Pressing '6' will show the right end of the chart,
vertically centered on the screen, and so on. Basically, we have a
simple implementation of something like scroll bars, allowing viewing
of all parts of the "window". One can generate and display on the
screen even the largest charts producible with Astrolog. Even on an
640x350 EGA, one can use this to generate and view all parts of a
300% scaled relationship aspect grid (883x883), or even a 300% scaled
world map display (1082x545)!
X
--
X
X     Astrolog has support for the mouse and the mouse buttons when
running graphics under DOS. Upon entering a graphics chart under
DOS, a mouse pointer will appear. Holding down the left mouse button
will allow you to scribble on the screen with the mouse as a pen, in
the highlight color, just like how for Unix the left button is used
to scribble in an X window. For PC's, the middle mouse button (if you
have one - most mice such as Microsoft mice don't) will exit graphics
mode and terminate the program, like pressing the 'q' key or like how
the right mouse button does for X windows. The right mouse button
does the same thing as the middle button for X: it will reset the
current chart location to that clicked on. It won't actually display
the new longitude and latitude, but you can easily see what it is by
observing the chart information at the bottom of a graphics chart, or
by pressing the 'v' key to see the whole chart and its location in
text mode.
X
X     The ability to use the mouse to sketch and scribble on the
charts is extended for PC's. The right mouse button (on those
non-world map charts where it doesn't already set the current
location) will draw a straight line to the mouse pointer from the
point where one last clicked the left button. Also, pressing ctrl-t
will draw a rectangle from the point of the last click to the current
mouse position. Finally, pressing ctrl-x will draw an ellipse
inscribed within the bounds from the last click point to the current
position. These are just more features to make Astrolog a better
graphics drawing program. :)
X
X     Not all PC systems have mice. There is a #define in astrolog.h
called "MOUSE". If commented out, then all mouse functionality will
be compiled out, even if compiling for Unix. Note that the mouse
pointer and all PC mouse functions are temporarily disabled when
running in an animation mode. If on a PC system a mouse isn't
installed on a system and Astrolog is run with mouse features
enabled, the mouse features will be ignored as if the functionality
weren't even compiled in.
X
X     [There's a minor known bug with the PC mouse features in the
program, which is that when in a flicker free graphics mode, the
mouse pointer will only appear half the time. (You can still scribble
and set location, just that the pointer won't be visible.) This is
due to the fact that a flicker free mode is actually two pages
switched back and forth between for smooth updates. If you don't see
and want your mouse here, the update generated by pressing spacebar
will revert you to the other page where the mouse pointer is.]
X
--
X
X     Although the DOS version of Astrolog is not a Windows program
and doesn't have direct support for it with menus and all (if you
want that, just get the Windows version) Astrolog nevertheless can be
run from the Windows environment, various features making this easier.
X
X     One can make a Program Manager icon which will run DOS Astrolog
in a DOS box. Using the -Q0 switch here will prompt the user for
whatever switches they want to use, as well as looping back when done
to allow additional switches to be specified much like invoking the
program over and over again from DOS. Upon exiting the program, the
DOS box will also terminate, and although not as elegant as a true
Windows interface with what it offers and all, this is just as if not
more usable than the DOS interface.
X
X     To make a Windows Program Manager icon for Astrolog, first click
in the program group you want the icon to appear in, then choose File
New, and click OK to make a new program item. In the dialog, for the
description field type something like "Astrolog 5.40". For the
command line field, type "C:\ASTROLOG\ASTROLOG.EXE /Q0", i.e.
whatever the path name is to the executable file, and you probably
want to include the /Q0. For the working directory field, type
"C:\ASTROLOG", i.e. just the path to the directory where the astrolog
files are. For the shortcut key you can leave it blank or press a key
like 'a', meaning that pressing Ctrl-Alt-A at any time when the
Program Manager is active will start the Astrolog program.
X
X     Then click on the change icon button, OK the warning, and from
the Change Icon dialog type "C:\ASTROLOG\ASTRLOG1.ICO" (again the
path to your Astrolog directory) in the filename field. This should
load in Astrolog's own Windows icon file included in the zip archive,
a yellow planet with red rings and two blue moons and stars around
it. Click OK twice and you should be back in your group with a nice
Astrolog icon that can be double clicked on to boot Astrolog whenever
you want.
X
X     You may also want to include "/V 43" or something similar along
with /Q0 for the command line field, if you want to have more than
just 25 rows in the DOS box to print the text charts in. One can also
create additional icons that have certain other switches or directly
display certain charts. For example, have another icon called
"Astrolog Now!" which has "/n /X /Q" for its switches. Double click
on this to see where the planets are right now. You can also use the
PIF editor utility (usually PIFEDIT.EXE in the Windows directory)
instead to create an astrolog.pif file. With the right system and
settings, you can specify a created .pif file instead of the Astrolog
executable directly, in the Program Manager icon, and run the program
in a window in real time along with your other Windows applications.
X
--
X
X     Finally, for PC's with graphics, the actual modes the program
enters when in the "normal" and the "flicker free animation" modes
can be customized and set in astrolog.dat. The values are the various
mode numbers defined in graph.h for the Microsoft library. By
default, the normal high-res mode is set to the value "-3", which
means a mode with the highest resolution, which is usually 640x480 16
color VGA. The default low-res animation mode is set to "16", which
corresponds to 640x350 16 color EGA (which on most systems is the
highest resolution allowing multiple pages meaning animation can be
done without flicker). Here is a complete table of the legal graphics
modes, with their index values to specify them, their screen pixel
resolution, their number of colors, and any comments as to what
hardware are required for them. It is not recommended to attempt to
enter a graphics mode here that your system doesn't support.
X
Num. Hor.   Ver. Col. Device.
X -3  640 x  480,  16 ("highest resolution" up to 640x480, usually #18)
X -2  320 x  200, 256 ("most colors", usually #19)
X -1  640 x  480,  16 (Alias for VGA mode #18)
X  4  320 x  200,   4 (MRES)
X  5  320 x  200,   4 (4 grays)
X  6  640 x  200,   2 (CGA)
X  8  720 x  348,   2 (Mono Hercules)
X 13  320 x  200,  16 (MRES)
X 14  640 x  200,  16 (CGA)
X 15  640 x  350,   2 (Mono EGA)
X 16  640 x  350,  16 (EGA, maybe just 4 colors)
X 17  640 x  480,   2 (Mono VGA)
X 18  640 x  480,  16 (VGA)
X 19  320 x  200, 256 (MRES)
X 64  640 x  400,   2 (Olivetti, 1 of 16 colors)
256  640 x  400, 256 (VESA SVGA)
257  640 x  480, 256 (VESA SVGA)
258  800 x  600,  16 (NEC MultiSync 3D)
259  800 x  600, 256 (NEC MultiSync 3D)
260 1024 x  768,  16 (NEC MultiSync 4D)
261 1024 x  768, 256 (NEC MultiSync 4D)
262 1280 x 1024,  16 (NEC MultiSync 5D)
263 1280 x 1024, 256 (NEC MultiSync 5D)
X
X
**********************************
DESCRIPTION OF MS WINDOWS FEATURES
**********************************
X
X     First, users of other versions of the program should find moving
to the Windows version of Astrolog easy and familiar. All the text
and graphics chart displays are available and look the same.  All
chart info and command files work and haven't changed format any. All
the command line switches are available and work and can even be
passed to the program while running to do things if you prefer, in
addition to the more user-friendly interface being available. All the
keypress commands one can press while an interactive graphics screen
was up are set as shortcuts for equivalent operations here.
Basically, additional features and a more user friendly interface are
presented, while all the other things are still available. :)
X
X     Not counting the About box and the standard Windows open file,
save file, and printing items, Astrolog 5.40 contains 16 dialogs, a
couple of which are also shared by more than one command. There are
nine top level menus not counting the system menu, which have among
them 114 different options, or 237 counting all second level
submenus! In using the dialogs, one should specify or enter the
appropriate settings, and then press "OK" for them to take effect, or
"Cancel" to discard any changes made. On pressing "OK", the program
will check all the fields for validity, and display an appropriate
error message and not close the dialog if anything is out of range,
giving a chance to correct or cancel. For numeric controls, note that
if the existing value is displayed with a decimal point in it,
floating point numbers are legal, while if there isn't one then
integers are required.
X
X     Every menu command has an accelerator, i.e. an underscore below
a letter, where when the menu is displayed one may press that letter
to select that option (pressing Alt plus the appropriate letter may
be used to pull down a top level menu). In addition every menu option
has a unique direct keyboard shortcut, where pressing the appropriate
key will invoke the command directly without having to pull down a
menu. To the right of each menu option is listed the key or key
combination that's its shortcut. Note that a capital letter here
means the shift key needs to be down, e.g. "Alt+o" means hold down
the Alt key and press "o", while "Alt+O" means hold down both the Alt
and Shift keys and then press "O".
X
X     Astrolog tries to be smart about what you're trying to do when
menu options are selected, and may automatically change settings to
make the appropriate thing happen. For example, as with the DOS and X
Windows versions, the charts in the Windows version can be divided
into "text mode" i.e. just text, and "graphics mode" charts, where
the first option on the View menu will switch between them. Charts
like transit lists only exist in text form, so when selected you'll
automatically leave graphics mode if in it; likewise, selecting most
any item on the Graphics menu will enter it as those settings have no
effect on text charts. Similarly, entering animation mode will
automatically turn on the flicker free updates setting, and so on.
X
X     As with Astrolog versions on other platforms, you can use the
mouse to draw on the window here too. Click and drag the left mouse
button to scribble lines. Doing a Shift+click will draw a straight
line from the location you last clicked to the current position.
Doing a Control+click will draw a rectangle with opposite corners at
the location last clicked and the current position. Doing
Control+Shift+click will draw an ellipse with opposite corners at the
two positions clicked. Finally, when the current display is either
the world map or an astro-graph chart, one may click the right mouse
button on the map to relocate the chart to the spot on the world
clicked upon, which will change the longitude and latitude of the
current chart info in memory.
X
X     The window that the charts are drawn in has horizontal and
vertical scrollbars on it. For charts that are just text, the
scrollbars may be used to shift the chart up or left to view any
characters that get written off the bottom or right edge of the
window. For charts that are graphics, if the chart is larger than the
window it's in, the scrollbars may be used to move around the
viewable portion of it, while if the chart is smaller than the
window, the scrollbars will control where in the window the chart is
drawn, e.g. centered, in upper left corner, etc. Note that it's most
common and logical to have the chart and window the same size, in
which case moving the scrollbars has no effect on the graphics chart.
Note that for text mode charts, there exists behavior such that if
the window has been scrolled down so that all the text is off the top
of the screen, the program will automatically scroll up and redraw
again, so the bottom 20 rows or so are visible.
X
X     Like other versions, Astrolog for Windows will read in and
process the contents of the astrolog.dat command file if available on
startup for default settings. Immediately after this the program will
process the contents of the Windows command line if any, i.e. any
command switches or parameters specified with either the program's
icon or given when running the program by typing in its path.
X
--
X
X     Astrolog for Windows is reasonably intuitive to use and do what
you want with even without referring to any documentation. Still for
completeness and detail, below is a quick rundown on all the menu
options. Where applicable, the command switch corresponding to the
menu command is given in brackets; one may look up the documentation
for that command switch in earlier sections for additional information.
X
File menu commands:
X
X  Open Chart...: This brings up the standard Windows open file dialog,
X  allowing one to select a chart info, chart position, or any other
X  Astrolog command file. This file will be loaded and processed, with
X  the new chart being displayed in the window. [This does the same as
X  the -i <file> command switch. Note that this ignores the various
X  Astrolog directory environment variables that -i can use.]
X
X  Open Chart #2...: This also brings up the Windows open dialog,
X  allowing one to select a chart file, however any chart time and
X  location settings will be put into the "second" chart slot, as used
X  in relationship charts. [This does the same as the -r <file1> <file2>
X  switch, just that it only sets the contents of <file2>.]
X
X  Save Chart Info...: This brings up the standard Windows save file
X  dialog, allowing one to enter a filename, which will be created and
X  the time and location of the current chart will be written to it.
X  Note that, as with all of Astrolog's Save dialogs, this will query
X  for a confirmation before overwriting or replacing existing files.
X  [This does the same as the -o <file> switch.]
X
X  Save Chart Positions...: This also brings up the Windows save dialog,
X  however here to the created file will be written the actual positions
X  of all the planets and house cusps, and no time or location info.
X  [This does the same as the -o0 <file> switch.]
X
X  Save Chart Text Output...: This allows one to save the actual text
X  displayed in a window for a text chart to a file as simple text.
X  [This does the same as the -os <file> switch.]
X
X  Save Chart Bitmap...: This saves the current graphics display to a
X  Windows bitmap file. [This does the same as the -Xb switch.]
X
X  Save Chart Picture...: This saves the current graphics display to a
X  Windows metafile file. [This does the same as the -XM switch.]
X
X  Save Chart PostScript...: This saves the current graphics display to
X  an encapsulated PostScript file. [This does the same as the -Xp switch.]
X
X  Save Settings...: This allows one to save settings made within the
X  program so they will automatically be in effect again the next time
X  the program is run. Without this, one can change settings such as the
X  house system, aspect orbs, etc, but they will go away upon exiting
X  the program. The way to make setting changes persistent is to edit
X  the astrolog.dat default settings file. This command has the program
X  automatically generate a new astrolog.dat file for you based on the
X  current state of the program. The standard Windows Save dialog will
X  be brought up as with all the other Save commands. The default
X  filename to save to will of course be astrolog.dat, to replace the
X  existing settings file. You can select a different name to save the
X  file to if you like, where the file will be a command switch file
X  like any other except it won't be read in automatically on startup
X  like astrolog.dat. Note this feature won't save every possible
X  program setting, such as the active chart being displayed, but it
X  will save most things; see the astrolog.dat file itself for what
X  exactly is saved. One can start the program, immediately do File Save
X  Settings, and create an astrolog.dat file virtually identical to the
X  one that was just read in.
X
X  Save As Wallpaper: This submenu allows one to easily set an Astrolog
X  graphics chart to be the background bitmap for the Windows desktop.
X  There two commands under this submenu are Tile Bitmap and Center
X  Bitmap. The first centers the Astrolog chart in the middle of the
X  screen, while the second tiles the chart across and down it. This
X  functionality can be done without this command, where one can do File
X  Save Bitmap to create a bitmap file, then go into the Windows control
X  panel desktop settings, and point the wallpaper bitmap to the file
X  created; but this command allows it do be done with a click of the
X  mouse, where a bitmap file called "ASTROLOG.BMP" will automatically
X  be created and saved in your Windows directory.
X
X  Print...: This feature allows one to directly print charts from
X  within the program. This command brings up the standard Windows Print
X  dialog, with the same look and feel and options available as when
X  printing from other Windows programs such as Write. The image printed
X  will be the exact chart that appears in the window. For graphics
X  charts, the printout will be a one page image of the display, scaled
X  to be as large as possible within the bounds of the page. The
X  window's horizontal and vertical scrollbars determine where in the
X  page the image is situated, e.g. if the vertical scrollbar is all the
X  way to the top, the image will be at the top of the page, if
X  centered, then it will be vertically centered, and so on. Note that
X  the colors in the window will be the colors on the paper, where you
X  probably want to have the Graphics Reverse Background setting active,
X  so the chart will be black on a white background and hence not waste
X  ink. For monochrome printers you also probably want to have the
X  Graphics Monochrome setting active, to prevent colors like yellow
X  coming out as a hard to see light gray. For text mode charts, the
X  printout will be on a white background regardless of what's in the
X  window. You may want to turn off the View Colored Text setting if you
X  don't have a color printer. The font size may be affected by the
X  Graphics Character Scale command settings. For the standard medium
X  character scale on a 8.5"x11" paper, there will be 70 rows to a page.
X  The text printout will be more than one page if there are more than
X  70 rows of output. Note that even with this feature available, one
X  may still want to use the program's clipboard and file features to
X  print from another program. Astrolog's Print command makes decisions
X  about layout, font, etc, for you; some may find this convenient, but
X  others may still prefer to import Astrolog output into a word
X  processing or desktop publishing program to have full control. The
X  graphics generated by printing a chart directly, and printing a chart
X  bitmap, metafile, or PostScript file, have slightly different
X  textures so one may prefer one format to another. Still, direct
X  printing is available to those of us who would like to use it.
X
X  Print Setup...: This brings up the standard Windows Print Setup
X  dialog, allowing one to select settings such as the printer to print
X  to, and whether the printed page will be oriented in portrait or
X  landscape mode. This dialog is also accessible from the Print dialog
X  itself via the "Setup..." button, but is also made available
X  separately here.
X
X  Exit: This terminates the program. Note that pressing Escape or
X  Control+C will also quit in addition to this and the command's "q"
X  shortcut key.
X
Edit menu commands:
X
X  Enter Command Line...: This brings up a dialog with one edit control,
X  in which one may enter a command line. This gives access to obscure
X  program features that don't have their own menu options yet, as well
X  as easy access to the command switches for those of us who like them.
X
X  Run Macro (Normal Set): This, along with the next three menu items of
X  "Run Macro (Shift Set)", "Run Macro (Control Set)", and "Run Macro
X  (Alt Set)", are submenus each of which contain 12 entries of the form
X  "Macro <1-48>". These run the appropriate command switch macro. See
X  the -M0 switch for information on how to define a macro. [This does
X  the same as the -M switch.]
X
X  Copy Text Output: This is like the File Save Chart Text Output
X  command except the text will be copied to the Windows clipboard.
X  After doing this one can run or switch to an application such as
X  Notepad, Write, or Word, and use their Edit Paste command to paste in
X  the chart text, which may then be printed, combined with other text,
X  and so on. Next to the Print command, this is the easiest way to
X  print Astrolog charts.
X
X  Copy Bitmap: This is like the File Save Chart Bitmap command except
X  the Windows bitmap will be copied to the clipboard, which may again
X  be pasted into another application.
X
X  Copy Picture: This is like the File Save Chart Picture command except
X  the Windows metafile will be copied to the clipboard. Note that when
X  printing to laser printers, the Picture format is recommended over
X  the Bitmap format because its output is free of any pixel blockiness.
X
X  Copy PostScript: This is like the File Save Chart PostScript command
X  except the PostScript file will be copied to the clipboard as simple text.
X
View menu commands:
X
X  Show Graphics: This toggles the current chart display between text
X  and graphics mode. Text charts are drawn in the window as simple text
X  such as might appear in a DOS box, while graphics charts are pretty
X  high resolution wheels and the like. [This does the same as the -X switch.]
X
X  Buffer Redraws: This option on the Window Settings submenu toggles
X  whether or not screen updates are smooth. When off, the screen clears
X  and the chart redraws as you watch, while when on, the program
X  "pauses" while the update is done behind the scenes where the new
X  chart is displayed all at once. Animation mode turns this setting on
X  to provide flicker free updates.
X
X  Redraw Screen: This option on the Window Settings submenu simply
X  redraws the current screen. Most often this is used to erase any
X  scribbles one may have added with the mouse buttons.
X
X  Clear Screen: This option on the Window Settings submenu simply
X  erases the screen leaving a blank window, where the next redraw will
X  bring the chart back. This can be used if one wants to draw on an
X  empty screen.
X
X  Hourglass On Redraw: This option on the Window Settings submenu
X  toggles whether or not the program puts up the hourglass wait cursor
X  while redrawing a chart. I've found it most natural to have this on
X  normally to know when the program is busy calculating, but off during
X  animations.
X
X  Chart Resizes Window: This option on the Window Settings submenu
X  toggles whether the window will resize when the chart size increases
X  or decreases. For example, if displaying a graphic aspect grid which
X  is a square chart, and one switches to the rectangular shaped
X  astro-graph map chart, this setting when on, will resize the window
X  to be the new rectangular shape. When off, the chart will either not
X  fill up the whole window or will overlap its edges, in which case the
X  scrollbars may be used to view all parts of the graphic. Note that
X  when the window size changes in this way, the program will
X  automatically move the window's location appropriately if the new
X  size would make the window appear partially off the screen edge.
X
X  Window Resizes Chart: This option on the Window Settings submenu
X  toggles whether the chart will resize whenever the window size is
X  increased or decreased. For example, when displaying the graphic
X  wheel chart, and one manually resizes the window to be larger, this
X  setting when on, will make the wheel bigger too so its fills the new
X  window. [FYI, the X Windows version of Astrolog always behaves as
X  though this and the above setting are both on.]
X
X  Size Chart To Window: This option on the Window Settings submenu does
X  a one time resize of the chart to fill the dimensions of the current
X  window. This is only relevant for graphics charts that don't already
X  have a forced fixed size, and for when the Window Resizes Chart
X  setting is off.
X
X  Size Window To Chart: This option on the Window Settings submenu does
X  a one time resize of the window to be the dimensions of the current
X  chart. This is only relevant for graphics charts and for when the
X  Chart Resizes Window setting is off.
X
X  Scroll Page Up, Scroll Page Down, Scroll to Beginning, Scroll to End:
X  These four commands on the Window Settings submenu allow one to
X  respectively: scroll the window up as if one clicked above the
X  thumbnail on the vertical scrollbar, scroll the window down as if one
X  clicked below the thumbnail on the vertical scrollbar, do the same
X  thing as if one scrolls to the far upper left, and do the same thing
X  as if one scrolls to the far bottom right. Note that one will
X  generally want to use the keyboard shortcuts for these commands (the
X  Page Up, Page Down, Home, and End keys) rather then select them from
X  the menu, but they're on the menu too just for convenience.
X
X  Colored Text: This toggles whether or not the characters in text
X  charts are multi-colored. Colored text is recommended on normally
X  because it looks nice, but should be turned off when copying text
X  output to the clipboard to remove the control characters which cause
X  the color changes. [This does the same as the -k switch.]
X
X  Set Colors...: This brings up the Customize Colors dialog. One may
X  use the various combo controls to change the colors used in graphics
X  and text charts, by selecting a color from a dropdown, or by entering
X  its name or abbreviation or index from 0-15. The Elements group
X  covers the colors used for the four elements. [This does the same as
X  the -YkC switch.] The Aspects group covers the colors used for the 18
X  aspects. [This does the same as the -YkA switch.] The Standard Color
X  Palette covers all other uses of color. [The sixteen settings here do
X  the same as the sixteen settings covered by the -Yk0 and -Yk switches.]
X
X  Show Interpretations: This toggles whether or not interpretations are
X  given for text charts. [This does the same as the -I switch.]
X
X  Print Nearest Second: This toggles whether or not all zodiac
X  positions are displayed to the nearest arc second as opposed to just
X  the arc minute. [This does the same as the "0" part of the -b0 switch.]
X
X  Applying Aspects: This toggles whether or not aspect orbs are
X  displayed in the form of about to happen or just happened, as opposed
X  to degrees narrow or degrees wide. [This does the same as the "a"
X  part of the -ga and -aa switches.]
X
X  Parallel Aspects: This toggles whether or not aspects in the
X  "vertical plane" are used, with the parallel and contraparallel
X  aspects shown as opposed to conjunction and opposition. [This does
X  the same as the "p" part of the -gp and -ap switches.]
X
Info menu commands:
X
X  Set Chart Info...: This brings up the generic Chart Info dialog,
X  which is the place for one to actually create a chart by specifying
X  the time and location in question. The dialog contains eight main
X  controls, for month, day, year, time, daylight flag, time zone,
X  longitude, and latitude. These have dropdowns from which one may
X  optionally choose common values. After this are two optional text
X  edit controls where one may enter the name and location for the
X  chart. The special button "Now" will copy the current time over all
X  the fields. The special button "Previous" will copy the contents of
X  the last chart cast over the fields. [The eight main combo controls
X  cover the same fields as the -qb switch. The two text controls cover
X  the same fields as the -zi switch. The "Now" button does the same as
X  the -n switch. The "Previous" button does the same as using the "-i
X  set" virtual file.]
X
X  Chart For Now: This sets the current chart information to the current
X  time now. [This does the same as the -n switch.]
X
X  Default Chart Info...: This brings up the Default Chart Info dialog,
X  where one may specify the default daylight setting, time zone,
X  longitude, latitude, and the correction factor to add to "now"
X  charts. These settings are used in commands such as "Chart For Now",
X  where the time obtained needs to be combined with some location to
X  make a complete chart. [The five controls in this dialog correspond
X  respectively to the -z0, -z, and the two parameters passed to the -zl
X  switches (except these switches change the current chart as well as
X  the default) and the -Yz switch]
X
X  Set Chart #2 Info...: This brings up a dialog identical to the
X  standard Chart Info dialog, except here the chart settings specified
X  are put into the "second" chart slot, as used in relationship charts.
X  This command is to "Set Chart Info", as the "Open Chart #2" command
X  is to "Open Chart". [This does the same as the -i2 switch.]
X
X  Charts #3 And #4...: This brings up a dialog giving one access to all
X  four chart slots, with buttons which will bring up the file open
X  dialogs to load chart info into each slot, and buttons allowing
X  access to the chart info dialogs to view or change the info in each
X  slot. This dialog also has a radio button group to indicate what type
X  of wheel and how many chart rings to display: a single wheel,
X  bi-wheel, tri-wheel, or quad-wheel. [This covers the same as the -r3
X  and -r4 switches, and the -i3 and -i4 switches.]
X
X  No Relationship Chart: This and the remaining eight commands on the
X  Info menu specify the current relationship chart mode if any, where
X  the currently active mode has a check mark by it. This first command
X  turns any relationship mode off, where just a single chart is shown,
X  with any "second" chart ignored. [This does the same as the -r switch
X  when invoked as _r.]
X
X  Comparison Chart: This sets the relationship chart mode to dual
X  comparison, where two charts are shown side by side, e.g. the wheel
X  chart becomes a bi-wheel, and aspect grids are between two sets of
X  planets. [This does the same as the -r0 switch, except it uses the
X  two charts already in memory as opposed to reading them from file.]
X
X  Synastry Chart: This does a synastry chart, a single chart consisting
X  of the second chart's planets in the first chart's houses. [This does
X  the same as the -r switch.]
X
X  Composite Chart: This does a composite chart, a single chart
X  consisting of all the midpoints between each object pair in the two
X  charts. [This does the same as the -rc switch.]
X
X  Time / Space Midpoint Chart: This does a midpoint relationship chart,
X  a single chart cast at the time and location half way between those
X  of the two charts. [This does the same as the -rm switch.]
X
X  Date Difference Chart: This displays the span of time between the two
X  charts, given in all units from the nearest second to the nearest
X  year. [This does the same as the -rd switch.]
X
X  Biorhythm Chart: This displays a biorhythm chart, for a person born
X  at the time in the earlier of the two charts, for the time in the
X  other chart. [This does the same as the -rb switch.]
X
X  Transit And Natal: This sets a mode identical to "Comparison Chart"
X  above except that the transit restrictions will apply to the second
X  chart and the natal restrictions to the first, instead of the natal
X  restriction set to both. [This does the same as the -rt switch.]
X
X  Progressed And Natal: This sets a mode like "Transit And Natal"
X  above, except that the second chart actually shown (outer ring in
X  wheel charts) will be a chart made by progressing the first chart to
X  the time in the second. [This does the same as the -rp switch.]
X
Setting menu commands:
X
X  Sidereal Zodiac: This toggles whether or not the chart is cast with
X  respect to the sidereal zodiac as opposed to the tropical. [This does
X  the same as the -s switch.]
X
X  Heliocentric: This toggles whether or not the chart is cast with
X  respect to the Sun for a heliocentric chart, as opposed to the Earth
X  in a standard geocentric chart. [This does the same as the -h switch
X  toggling between Sun and Earth centered charts.]
X
X  House System: This submenu allows one to select among fifteen systems
X  of house division to use. [This does the same as the -c switch.]
X
X  Solar Chart: This option on the House Settings submenu toggles
X  whether or not the houses are rotated to put the Sun on the Ascendant
X  for a solar chart. [This does the same as the -1 switch.]
X
X  Show Decans: This option on the House Settings submenu toggles
X  whether or not the planet positions are adjusted to put each object
X  in the sign corresponding to its decan. [This does the same as the -3
X  switch.]
X
X  Flip Signs & Houses: This option on the House Settings submenu
X  toggles whether or not planet and house positions are swapped with
X  respect to each other for a Domal chart. [This does the same as the
X  -f switch.]
X
X  Geodetic Houses: This option on the House Settings submenu toggles
X  whether or not house cusps are only computed based on the chart's
X  longitude for geodetic houses. [This does the same as the -G switch.]
X
X  Vedic Wheel Display: This option on the House Settings submenu
X  toggles whether wheel charts are displayed in Vedic format or not.
X  [This does the same as the -J switch.]
X
X  Show Navamsas: This option on the House Settings submenu toggles
X  whether or not the planet positions are adjusted to generate a
X  navamsa chart. [This does the same as the -9 switch.]
X
X  Aspect Settings...: This brings up the Aspect Settings dialog,
X  allowing one to set various things related to each aspect. For each
X  of the 18 aspects, there is: (1) A checkbox for whether the aspect is
X  to be included in charts at all, (2) an edit control specifying the
X  aspect's maximum orb, (3) an edit control specifying the aspect's
X  actual angle, and (4) an edit control specifying the aspect's
X  relative power for influence charts. In addition there are three
X  buttons: (1) "Restrict All" which automatically checks all aspects,
X  (2) "Unrestrict All" which unchecks them all, and (3) "Toggle Majors"
X  which inverts the status of the first five aspects. [The checkboxes
X  are a mixture of the -A and -RA switches. The orb fields do the same
X  as the -Ao or -YAo switches. The angle fields do the same as the -Aa
X  switch. The influence fields do the same as the -YjA switch.]
X
X  Object Settings...: This brings up the Object Settings dialog,
X  allowing one to set various things related to each planet. For each
X  of the first 20 objects, there is: (1) an edit control specifying the
X  maximum aspect orb allowed to that object, e.g. no more than a two
X  degree orb to the North Node, (2) an edit control specifying an
X  aspect orb addition allowed, e.g. widen all orbs by one degree for
X  the Sun, and (3) an edit control specifying the object's relative
X  power for influence charts. [The max orb fields do the same as the
X  -Am or -YAm switches. The orb addition fields do the same as the -Ad
X  or -YAd switches. The influence fields do the same as the -Yj switch.]
X
X  More Object Settings...: This brings up a dialog much like the Object
X  Settings dialog above, except this dialog is for the house cusp and
X  Uranian objects. Like the standard Object Settings dialog which is
X  for the first 20 objects, this dialog allows one to set the maximum
X  aspect orb allowed to, the orb addition factor for aspects concerning,
X  and the power influence value of, each cusp and Uranian object.
X
X  Restrictions...: This brings up the Object Restrictions dialog,
X  allowing one to specify whether each planet or other object is
X  included in charts, where each object has a checkbox, with checked
X  meaning restricted. In addition there are several buttons added for
X  convenience: (1) "Restrict All" which automatically checks all
X  objects, (2) "Unrestrict All" which unchecks them all, (3) "Toggle
X  Minors" which inverts the state of the asteroids and all the other
X  objects in the second set of ten, (4) "Toggle Cusps" which inverts
X  the state of the 12 cusp objects, (5) "Toggle Uran." which inverts
X  the eight Uranian planets, and (6) "Copy From Other Restriction Set"
X  which sets all items to be the state of those in the parallel transit
X  restriction set. [This dialog does the same as passing values to the
X  -R switch. The "Restrict All", "Unrestrict All", "Toggle Cusps", and
X  "Toggle Uran." buttons do the same as the -R0, -R1, -RC and -Ru
X  switches respectively.]
X
X  Include Minors: This toggles whether or not the asteroids and other
X  minor objects are included in charts. [This does the same as the -R
X  switch when invoked without any parameters.]
X
X  Include Cusps: This toggles whether or not house cusps are included
X  as objects in charts such as aspect grids and transit searches. [This
X  does the same as the -C switch.]
X
X  Include Uranians: This toggles whether or not the Transneptunian
X  planets are included in charts. [This does the same as the -u switch.]
X
X  Include Fixed Stars: This toggles whether or not stars are included
X  in charts. [This does the same as the -U switch.]
X
X  Star Restrictions...: This brings up the Star Restrictions dialog,
X  which is similar to the standard Restrictions dialog except it deals
X  with the fixed star or other deep space objects. Each of the 47 fixed
X  stars has a checkbox, where in addition there are two buttons: (1)
X  "Restrict All" which automatically checks all the star objects, and
X  (2) "Unrestrict All" which unchecks them all. [The "Restrict All" and
X  "Unrestrict All" buttons do the same as the -RU0 and -RU1 switches.]
X
X  Transit Restrictions...: This brings up the Transit Restrictions
X  dialog, which is identical the standard Restrictions dialog in every
X  way except it sets the status of the objects in the transit
X  restrictions array, as used in transit charts. The "Copy From Other
X  Restriction Set" button here copies all flags from the standard
X  restriction set. [The various operations here do the same as the -RT
X  switch and derivatives.]
X
X  Calculation Settings...: This brings up the Calculation Settings
X  dialog, used to set various common settings. These include: (1) An
X  edit control to specify the zodiac degree offset or ayanamsa [same as
X  the parameter passed to the -s switch]. This control has a dropdown
X  to allow quick selection of several common systems of sidereal
X  astrology. The values in it are 0.0 for Fagan Bradley, 0.883333 (or 0
X  degrees 53') for N.C. Lahiri, 0.983333 (or 0 degrees 59') for
X  Krishnamurti, and 2.333333 (or 2 degrees 20') for B.V. Raman. The
X  other settings changeable in this dialog are: (2) the number of
X  aspects to include in charts [same as the -A switch], (3) the
X  harmonic chart factor [same as -x switch], (4) the central planet,
X  e.g. geocentric, heliocentric, or some other planet [same as the
X  parameter passed to the -h switch], (5) a radio button group
X  specifying the solar chart setting, i.e. whether to rotate the house
X  cusps so an object is on the Ascendant or on the Midheaven, and an
X  edit control specifying which object to use when active [all this
X  does the same as the -1 and -2 switches], (6) the number of text
X  columns to use in interpretation paragraphs [same as the parameter
X  passed to the -I switch], (7) a checkbox indicating whether to
X  calculate planetary positions using ephemeris files for maximum
X  accuracy [same as -b switch], (8) a radio button group specifying how
X  to display zodiac positions, i.e. in the standard degree/sign/minute
X  notation, in hours/minutes, or just degrees [these items correspond
X  to the -sz, -sh, and -sd switches], and (9) a checkbox indicating
X  whether to display all planetary positions relative to Earth's
X  equator, as opposed to the ecliptic as is standard in astrology [same
X  as the -sr switch].
X
X  Obscure Settings...: This brings up the Obscure Settings dialog, used
X  to set various uncommon settings. These include: (1) A checkbox
X  indicating whether the North Node object is the True Node or the Mean
X  Node [same as -Yn switch], (2) a checkbox indicating the date display
X  format [same as -Yd switch], (3) a checkbox indicating the time
X  display format [same as -Yt switch], (4) a checkbox indicating
X  whether minor or equivalent aspects to house cusp objects are dropped
X  [same as -YC switch], (5) a checkbox indicating whether to leave off
X  the rightmost characters of text chart rows if they exceed the text
X  columns setting [same as -Y8 switch], (6) a checkbox indicating
X  whether to output chart info files in the old non-command switch
X  format used before version 4.20 [same as -Yo switch], (7) a checkbox
X  indicating whether the four angular cusp objects are set to the
X  positions of the actual house as defined by the current house system
X  [same as -Yc switch], (8) two checkboxes indicating whether to
X  include sign and direction changes in transit to transit searches
X  [same as -YR0 switch], (9) an edit control specifying the horizontal
X  and vertical number of cells to have in the graphic aspect grid chart
X  [same as -YXg switch], (10) a checkbox indicating whether metafile
X  and PostScript graphics files should use system as opposed to
X  simulated fonts for glyphs and other characters [same as -YXf switch],
X  (11) two edit controls specifying the horizontal and vertical paper
X  size in inches to use in PostScript charts [same as -YXp0 switch],
X  (12) a radio button group indicating how to orient the paper for
X  PostScript charts [same as -YXp switch], (13) four radio button pairs
X  allowing one to select between different glyphs to use for Capricorn,
X  Uranus, Pluto, and Lilith [same as -YXG switch], and finally (14)
X  four checkboxes to control whether the events of rising, zenith
X  transit, setting, and nadir transit appear in the rising and setting
X  chart [same as -YRZ switch].
X
Chart menu commands:
X
X  Standard List: This sets the current chart displayed to be the
X  standard default chart, i.e. a standard list of positions in text
X  mode and a wheel (or bi-wheel in comparison relationship mode) chart
X  in graphics mode. [This does the same as the -v switch.]
X
X  House Wheel: This sets the current chart displayed to be a house
X  emphasized wheel chart, i.e. a simple text wheel chart divided by
X  houses in text mode, and a wheel chart where all the houses are made
X  to be the same size in graphics mode. [This does the same as the -w
X  switch.]
X
X  Aspect Midpoint Grid: This sets the current chart displayed to be a
X  grid showing all aspects and all midpoints between each pair of
X  planets. It will show either aspects or midpoints in comparison
X  relationship mode. [This does the same as the -g switch.]
X
X  Aspect List: This sets the current display to be a list of all
X  aspects sorted by influence, and is a text mode only chart. [This
X  does the same as the -a switch.]
X
X  Midpoint List: This sets the current display to be a list of all
X  midpoints sorted by zodiac position, and is a text mode only chart.
X  [This does the same as the -m switch.]
X
X  Local Horizon: This sets the current display to show all the planets
X  and other objects as they appear relative to the local horizon or
X  sky, i.e. a list of altitude and azimuth values in text mode, and a
X  visual coordinate plot in graphics mode. [This does the same as the
X  -Z switch.]
X
X  Solar System Orbit: This sets the current display to show the orbital
X  positions of all the planets, i.e. a list of the x, y, and z
X  coordinates of each object relative to the sun (or current central
X  body) in text mode, and an aerial view of all the planets in their
X  orbits in graphics mode. [This does the same as the -S switch.]
X
X  Gauquelin Sectors: This sets the current display to show all the
X  planets as situated in the 36 Gauquelin sectors, along with their plus
X  zone status, i.e. a list of objects and locations in text mode, and a
X  sector wheel in graphics mode. [This does the same as the -l switch.]
X
X  Calendar: This sets the current display to be a simple calendar of
X  the month or year surrounding the time of the chart in question.
X  [This does the same as the -K switch.]
X
X  Influence: In text mode, this sets the current display to be a list
X  of the influence or power of each planet with respect to its
X  positioning and aspects. In graphics mode, this shows dispositor
X  graphs of the main planets for their sign and house placements. [This
X  does the same as the -j switch.]
X
X  Astro-Graph: This sets the current display to be an astro-graph
X  chart, showing where on the world each planet was rising, on the
X  Midheaven, etc. In text mode this lists the latitude and longitude of
X  each line at various intervals, and in graphics mode actually draws
X  and labels each line on a map of the world. [This does the same as
X  the -L switch.]
X
X  Ephemeris: This sets the current display to be an ephemeris chart,
X  i.e. a list of the zodiac positions of each planet over a range of
X  days (e.g. the month or year) surrounding the time of the chart in
X  question for text mode, and a plot of position vs. time for each
X  object in graphics mode. [This does the same as the -E switch.]
X
X  Arabic Parts: This sets the current display to be a list of the
X  positions of all Arabian part items for the given time, and is a text
X  mode only chart. [This does the same as the -P switch.]
X
X  Rising And Setting: This sets the current display to be a list of the
X  times during the day any planet rises, sets, and crosses the meridian
X  and nadir, and is a text mode only chart. [This does the same as the
X  -Zd switch.]
X
X  Transits...: This brings up the Transits dialog, used to create
X  various transit lists. The first thing to do when using this dialog
X  is to set the type of chart desired in the "transit type" radio
X  button group. The five choices here are (1) "transit to transit
X  hits", which will display exact times of aspects and other events
X  such as sign and direction changes over a range of time [same as -d
X  switch], (2) "transit to transit influence", which will display all
X  aspects between objects in the current chart ordered by significance
X  [same as -D switch], (3) "transit to natal hits", which will display
X  exact times of aspects made to natal planets from transiting planets
X  over a range of time [same as -t switch], (4) "transit to natal
X  influence", which will display all aspects between transiting and
X  natal objects for a given time ordered by significance [same as -T
X  switch], and (5) "none", which gets out of any transit chart mode.
X  The second thing to do is to be aware of the "progress instead of
X  transit" checkbox; when checked, all the transit charts will instead
X  be progressed charts, i.e. the transit types will be (1) progressed
X  to progressed hits [same as -dp switch], (2) progressed to progressed
X  influence [same as -D combined with -p], (3) progressed to natal hits
X  [same as -tp switch], and (4) progressed to natal influence [same as
X  -Tp switch]. Another checkbox named "display returns only", will when
X  checked affect the "transit to natal search" chart so that it only
X  shows returns, and affect the "transit to natal influence" chart so
X  that it only shows aspects between a transiting planet and the same
X  natal planet [same as the -tr and -Tr switches]. Now, for the
X  "transit to natal hits" and "transit to natal influence" charts, you
X  should set the values in the "do transits for" combo control group
X  (these controls are ignored for the transit to transit charts). There
X  are controls for "month", "day", "year", and "time" like those in the
X  Chart Info dialog, which here set the time for the transiting chart
X  (the natal chart settings should of course be set in Chart Info).
X  Pressing the "Now" button in the dialog will set these time values to
X  be that of the current moment. In addition, for the "transit to
X  transit hits" and "transit to natal hits" charts, you should select
X  from the "search for hits over" radio button group appropriately
X  (these controls are ignored for the transit influence charts). In
X  this group one may choose to scan over a single day, a month, year,
X  or range of years for aspects, where the time in question is that
X  surrounding the natal chart set in the Chart Info dialog for "transit
X  to transit hits", and is the time surrounding that in the "do
X  transits for" group in this dialog for "transit to natal hits". You
X  should note here that (1) when the "range of years" radio button is
X  selected, the number of years to scan over may entered in the "years
X  to span" edit control (with this setting being ignored otherwise),
X  (2) the shortest period "transit to natal hits" may be done for is a
X  single month, meaning that even if you select the "given day" radio
X  button in combination with this chart you'll get the "given month",
X  and (3) that some of the time settings in the "do transits for" group
X  are effectively ignored when doing "transit to natal hits" over a
X  large range, e.g. when doing the "given year", the values in the
X  "month", "day", and "time" controls don't affect the chart any. Also
X  for the two "hits" charts, you can change the value in the "searching
X  divisions" edit control, which determines at how narrow intervals to
X  cast charts for, with higher values giving more accurate times but
X  taking longer to compute [this is the same as the optional parameter
X  passed to the -d switch].
X
X  Progressions...: This brings up the Progressions dialog, which as its
X  name suggests allows one to do various forms of progressed charts.
X  The first thing to do when using this dialog is to set the "do
X  progression" checkbox appropriately [same as -p switch]. When
X  checked, all standard charts Astrolog calculates will be progressed;
X  when clear, all charts will be normal meaning the rest of the
X  settings in the dialog are ignored. Assuming this is checked, you
X  then want to set the values in the "progress chart to" combo control
X  group. There are controls for "month", "day", "year", and "time" like
X  those in the Chart Info dialog, which here set the time to progress
X  the natal chart to (the natal chart being of course set in Chart
X  Info). Pressing the "Now" button in the dialog will set these time
X  values to be that of the current moment. Next, you may set the values
X  in the "progression settings" control group to define the type of
X  progression to do. There is a radio button pair which one may use to
X  select between "secondary progression" or a "solar arc progression"
X  [same as -p0 switch]. Also there is a "degrees per day" combo control
X  which one may use to set the progression speed [same as -pd switch].
X  A number may be typed in, or one of several common values for this
X  setting may be selected from the dropdown: The number 365.25 here
X  gives the standard "year for a day" rate, while other values will do
X  tertiary progressions.
X
X  Chart Settings...: The brings up the Chart Setting Details dialog,
X  which defines various minor settings that go with and affect the
X  various displays. These include: (1) a checkbox indicating whether to
X  display planet velocity values relative to average speed in the text
X  mode standard chart list [same as -v0 switch], (2) an edit control
X  specifying the number of text rows to have in each house for the text
X  mode wheel chart [same as the parameter passed to the -w switch], (3)
X  a checkbox indicating whether the text house wheel chart lists
X  objects in Western houses four through nine in reverse order [same as
X  -w0 switch], (4) a checkbox indicating whether the text aspect grid
X  lists all aspect configurations (e.g. Grand Trines) after the grid
X  [same as -g0 switch], (5) a checkbox indicating whether the text
X  aspect list also gives a summary of the number of aspects of each
X  type and to each planet [same as -a0 switch], (6) a checkbox
X  indicating whether the text midpoint list also gives a summary of the
X  number of midpoints in each zodiac sign [same as -m0 switch], (7) a
X  checkbox indicating whether the text midpoint list also for each
X  midpoint gives a sublist of each aspect from a planet to it [same as
X  -ma switch], (8) a checkbox indicating whether the local horizon
X  chart is displayed with respect to the poles, where in text mode the
X  positions are given in prime vertical coordinates, and in graphics
X  mode centers the display around a view looking straight up as opposed
X
X  to at the horizon [same as -Z0 switch], (9) a checkbox indicating
X  whether the Gauquelin sector chart is computed as a fast
X  approximation based on Placidus cusps [same as -l0 switch], (10) a
X  checkbox indicating whether the text influence chart also lists the
X  influence of each sign in the chart after the influences of all the
X  planets [same as -j0 switch], (11) an edit control specifying the
X  degree interval at which longitude and latitude coordinates are given
X  for the curved Ascendant and Descendant lines in the text astro-graph
X  chart [same as the parameter passed to the -L switch], (12) a
X  checkbox indicating whether the text astro-graph chart also lists all
X  latitude crossings between lines [same as -L0 switch], (13) a
X  checkbox indicating whether the text calendar chart is for the entire
X  year as opposed to just the month surrounding the time in the current
X  chart, (14) an edit control specifying the number of Arabian parts to
X  include in the Arabic part chart [same as the parameter passed to the
X  -P switch], (15) a checkbox indicating whether to display the
X  formulas for the parts in the Arabic part chart in A+C-B as opposed
X  to A-B+C form [same as -P0 switch], (16) a radio button group which
X  determines in what order to sort the fixed star objects for charts
X  such as the standard text listing [same as the letter if any included
X  with the -U switch], and (17) a radio button group which determines
X  in what order to sort the parts in the Arabic part chart [same as the
X  letter if any included with the -P switch].
X
Graphics menu commands:
X
X  Show World Map: This sets the current chart displayed to be a simple
X  map of the world displayed in rectangular form. [This does the same
X  as the -XW switch.]
X
X  Show Globe: This sets the current display to be the map of the world
X  shown as the side view of a globe. Note that this chart looks cool in
X  animation mode because it rotates! [This does the same as the -XG switch.]
X
X  Show Polar Globe: This sets the current display to be the map of the
X  world shown as the top (or bottom) view of a globe. [This does the
X  same as the -XP switch.]
X
X  Show Constellations: This toggles whether or not the three map
X  displays above show in them the astronomical constellations instead
X  of the continents of the world. [This does the same as the -XF switch.]
X
X  Reverse Background: This toggles whether or not graphics charts are
X  displayed black on a white background as opposed to the standard
X  white on a black background. [This does the same as the -Xr switch.]
X
X  Monochrome: This toggles whether or not graphics charts are displayed
X  in just black and white monochrome mode as opposed to in the standard
X  selection of 16 VGA colors. [This does the same as the -Xm switch.]
X
X  Show Border: This toggles whether or not graphics charts are displayed
X  with borders around them. [This does the same as the -Xu switch.]
X
X  Show Chart Info: This toggles whether or not graphics displays have
X  the time and location of the chart in question printed at their base.
X  [This does the same as the -Xt switch.]
X
X  Show Info Sidebar: This toggles whether or not wheel charts are
X  displayed with an information sidebar to their right, listing the
X  positions of the houses and objects along with element table
X  summaries. [This does the same as the -v0 switch.]
X
X  Show Glyph Labels: This toggles whether or not glyphs are drawn for
X  planets and objects in graphics charts. Pretty much the only time
X  it's useful to ever turn this off is for the local horizon and orbit
X  charts, especially when doing a timed exposure animation of them.
X  [This does the same as the -Xl switch.]
X
X  Square Screen: This resizes both the graphics chart and the window to
X  be square shaped, and is useful for charts such as the wheel or
X  globes if they ever appear oblong and not circular shaped as they
X  should. For wheel charts with sidebars it will logically make it so
X  just the wheel part becomes square.
X
X  Character Scale: This submenu allows one to set the size of the
X  glyphs in graphics charts. For text mode charts, this setting will
X  affect the font size of the characters. There are four options on this
X  menu of "Small", "Medium", "Large", and "Huge", with medium being the
X  default. There are two more options on this menu labeled "Decrease"
X  and "Increase", which will move the setting down or up a notch (if
X  not already at an extreme). [For graphics these settings correspond
X  to the four percentage values that may be passed to the -Xs switch.]
X  Important note: I've found that some systems, when changing the size
X  of characters for text charts, don't seem to be able to load the
X  correct new font; if you notice characters overlapping each other at
X  small scales and the same size characters with lots of space between
X  them at large scales, opening up a DOS prompt seems to fix the problem.
X
X  Globe Tilt: This submenu allows one to change the angle or tilt of
X  the Earth in the globe chart. The three menu options here are:
X  "Decrease", which pulls the globe down 11.25 degrees or 1/8 of a
X  quadrant; "Increase", which pulls the globe up 11.25 degrees; and
X  "Set to Zero", which returns the globe to the standard zero degree
X  angle with the equator edge on. [This affects the same setting as the
X  second optional parameter passed to the -XG switch.]
X
X  Modify Display: This toggles whether or not each graphics chart is
X  displayed in a slightly modified form, e.g. for the globe display
X  this will plot all the planets at their zenith locations instead of
X  having just the world map itself. [This does the same as the -Xi
X  switch; see the documentation for this switch in an earlier section
X  for a list of how this setting affects each chart.]
X
X  Modify Chart: This option acts as a quick way to toggle several
X  settings associated with certain charts. Specifically, if in wheel
X  chart mode it will toggle between the standard wheel and the house
X  emphasized wheel. In addition, it will toggle the "horizon chart
X  displays with polar center" flag from the Chart Settings dialog, the
X  "world map in Mollewide projection" flag from the Graphics Settings
X  dialog, and whether ephemeris and calendar charts are displayed for
X  the year instead of just the month.
X
X  Scribble Color: This submenu allows one to select the color to use
X  when using the mouse to draw on the window. It has sixteen options,
X  one for each of the main colors.
X
X  Graphics Settings...: This brings up the Graphics Settings dialog,
X  used to set various additional settings not already covered by menu
X  options. These include: (1) Two edit controls specifying the
X  horizontal and vertical size of the graphics chart in pixels [same as
X  -Xw switch], (2) an edit control specifying the rotation in degrees
X  for the globe and world map charts [same as the first optional
X  parameter passed to the -XG switch], (3) an edit control specifying
X  the angular tilt in degrees for the globe chart [same as the second
X  optional parameter passed to the -XG switch], (4) a checkbox
X  indicating whether to display the world map chart in the oval shaped
X  Mollewide projection as opposed to just in rectangular form [same as
X  -XW0 switch], (5) an edit control specifying the time to delay
X  between doing screen updates when in animation mode [same as the
X  -WN switch], (6) a checkbox indicating whether the graphics screen
X  doesn't automatically update after setting changes or window expose
X  events, requiring the user to manually force redraws [same as the -Wn
X  switch], and (7) a radio button group specifying the "wheel chart
X  rotation", i.e. whether to rotate the entire wheel so an object is at
X  the left edge or at the top edge of the chart, and an edit control
X  specifying which object to use when active [all this does the same as
X  the -X1 and -X2 switches].
X
Animate menu commands:
X
X  Stop Animation: This stops any animation in effect, returning to a
X  static chart. Selecting this when animation is already off will
X  toggle it on to the "update to now" mode below. [This does the same
X  as the -Xn switch.]
X
X  Jump Rate: This submenu allows one to select the type of animation to
X  do. The first option, "Update To Now", sets it so the chart will be
X  continuously updated to the current moment, and will act as a
X  glorified astrological clock. The remaining nine options: "Seconds",
X  "Minutes", "Hours", "Days", "Months", "Years", "Decades",
X  "Centuries", and "Millennia", set it so whatever chart will step
X  forward or backward by the specified amount each update.
X
X  Jump Factor: This submenu allows one to select how many units of
X  whatever time rate the animation proceeds by. The nine options here
X  are the numbers one through nine, where for example if animation is
X  jumping by "Minutes" above, selecting "One" will progress the chart
X  by one minute each update, and selecting "Five" will progress by five
X  minutes each update. This setting is ignored when animation is set to
X  "update to now" or is off altogether.
X
X  Reverse Direction: This option toggles whether or not animation will
X  proceed backwards through time as opposed to forwards. This setting
X  has effect only when animation is on and set to an actual unit, i.e.
X  it's ignored when set to "update to now".
X
X  Pause Animation: This toggles whether or not any animation is paused.
X  Animation being paused is basically the same as animation being off
X  altogether, except that it's easy to unpause to continue animating,
X  without having to respecify the rate settings as would have to be
X  done were animation really turned off. Note that the pause key may be
X  used in addition to the "p" key as a keyboard shortcut to this command.
X
X  Timed Exposure: This toggles whether or not the screen is erased
X  between each update. When active, the screen won't be cleared meaning
X  progressive updates are drawn over the existing display. This is
X  generally only useful for charts such as the local horizon or solar
X  system (with glyph labels off) where this effect may be used to
X  create streaks showing the path of objects across the sky or through
X  their orbits. [This does the same as the -Xj switch.]
X
X  Step Forward: This moves the time of the current chart forward one
X  day, or rather the number of units set in the "Jump Rate" and "Jump
X  Factor" menus. [This is similar to the -+ switch.]
X
X  Step Backward: This moves the time of the current chart backward one
X  day, or rather the number of units set in the "Jump Rate" and "Jump
X  Factor" menus. [This is similar to the -- switch.]
X
X  Store Chart Info: This copies the time and location of the current
X  chart being displayed and remembers it in a special buffer. See below.
X
X  Recall Chart Info: This sets the current chart information to be that
X  in the special buffer above. [This does the same as using the "-i
X  set" virtual file.]
X
Help menu commands:
X
X  Help Documentation: This submenu allows one to access and even edit
X  Astrolog's documentation files online without having to leave the
X  program. The six commands on this menu are Open Defaults, which will
X  show the astrolog.dat default settings file; Open Summary, which will
X  show the very short file_id.diz program summary file; Open ReadMe,
X  which will show the short feature list and general program
X  information file Readme.540; Open Update, which will show the
X  Update.540 file listing the additions to the current version over the
X  previous one; and Open Helpfile, which will show the large
X  comprehensive documentation file Helpfile.540 you're reading now.
X  These files are viewed simply by having Windows spawn a session of
X  the Windows Notepad program, that has opened the file in question.
X  The Helpfile, due to its size, is opened by the Windows Write
X  program; when Write starts, you will probably want to clock on the
X  "No Conversion" button when asked if you want to convert the file to
X  Write format. The last command on the submenu is Open Homepage, which
X  will automatically visit the Astrolog Web site. This command will
X  start Internet Explorer or whatever Web browser your system has set
X  to interpret .URL extension files, and will have that browser open
X  the file astrolog.url in your astrolog program directory.
X
X  List Signs: This sets the current display to be a text listing of the
X  twelve signs and houses and information about them. [This does the
X  same as the -HC switch.]
X
X  List Objects: This sets the current display to be a text listing of
X  all the planets and other objects (that aren't restricted) which
X  Astrolog can compute the positions of, along with information about
X  their rulerships. [This does the same as the -HO switch.]
X
X  List Aspects: This sets the current display to be a text listing of
X  all eighteen aspects the program can deal with, and information about
X  them. [This does the same as the -HA switch.]
X
X  List Constellations: This sets the current display to be a text
X  listing of all 88 astronomical constellations the program displays in
X  the constellation map charts, and a little information about each
X  one. [This does the same as the -HF switch.]
X
X  List Planet Info: This sets the current display to be a text listing
X  of the planets in the solar system, with some astronomical data given
X  about each. [This does the same as the -HS switch.]
X
X  List General Meanings: This sets the current display to be a text
X  listing of the basic interpretation database used by the program,
X  giving the general meanings of each sign, house, planet, and aspect.
X  [This does the same as the -HI switch.]
X
X  List Switches: This sets the current display to be a text listing of
X  the main command switches that may be passed to the program, with a
X  one line description of each. [This does the same as the -H switch.]
X
X  List Obscure Switches: This sets the current display to be a text
X  listing of the remaining more obscure command switches not covered in
X  the list above. [This does the same as the -Y switch.]
X
X  List Keystrokes: This sets the current display to be a text listing
X  of the main shortcut keys ("main" being those that don't require the
X  Alt key and that exist in the DOS version as well) that one may press
X  to do various operations. [This does the same as the -HX switch.]
X
X  List Credits: This sets the current display to be a text listing of
X  the credits and copyrights for the program. [This does the same as
X  the -Hc switch.]
X
X  About...: This brings up the About Astrolog dialog which contains
X  static text also listing the credits and copyrights for the program.
X  [This again contains the same text that the -Hc switch display prints.]
X
X
**********************
COMPILING INSTRUCTIONS
**********************
X
X     Compiling Astrolog is very similar to the process of compiling
most other programs: First edit the top of the file astrolog.h,
commenting out any of the #define's which set various features that
aren't valid on your system or you don't want, and changing default
values and directories to your preference. (Just see the
self-explanatory section comments in this file.) Then in the same
manner, also edit these default parameter values in the astrolog.dat
file to your liking, at least the location and time zone values. (I
also really recommend turning on the Ansi color feature if your
system will support it - text charts look so much nicer in color!)
X
X     For Unix systems, just run the command 'make' in the directory
containing the Makefile. (You can also always compile by hand: "cc -O
-c *.c; cc -o astrolog *.o -lm -lX11" will do it; just make sure to
compile each source file and link them together at the end with the
math library, and if applicable the X11 library.)
X
X     It is possible to compile Astrolog on a VMS system, even with
its X windows functionality. There's an example of a simple VMS .COM
file in the source code distribution which can automatically compile
and link Astrolog on VMS, which should work for version 5.40,
although you might need to include "/noopt" after the CC's since some
compilers may cause the program to pass parameters incorrectly with
optimization on.
X
X     Compiling Astrolog on a PC for DOS is easy too. One can usually
do it by simply compiling each file in turn and then linking them all
together. In some cases you don't have to worry about explicitly
mentioning things like the math library if your environments are set
up properly. I used the command line version of the Microsoft Visual
C 1.51 compiler and its graphics.lib to generate the ready to run PC
executable. Note that the official PC executable for this
version has also been run through the utility pklite which compressed
the file size by more than half. If you have the nmake utility, the
makefile included in the zip archive will nicely compile and link
astrolog 5.40 on a PC, with properly set options and all. I compiled
under the Large memory model, with 16K bytes of stack space. The
default directory for chart info files, the astrolog.dat file, and
the ephemeris files in the official PC executable are all set to
C:\ASTROLOG, although this location will be overridden with several
environment variables if set. The time and location defaults are set
to my own area, but you can easily override them with your own values
in the astrolog.dat file.
X
X     To compile the Astrolog source code for Windows, the #define
WIN compile time flag needs to be uncommented in astrolog.h (this
should of course be commented for all other platforms). In addition,
the PC flag should be uncommented, while the flags for other graphics
libraries like MSG and BGI (and X11 of course) should be commented.
Pretty much all of the features in the features section need to be
on, e.g. INTERPRET, as well as some of the system settings like TIME
and MOUSE, as there are menu options that deal with them that won't
automatically disappear if they're disabled. The included file
astrolog.mak may be used as a project file or makefile. The
"official" Windows executable was compiled as a "16 bit" application
using Microsoft Visual C 1.52, and has been tested on Windows 3.1,
Windows 95, and Windows NT. Other Windows compilers should work,
provided they have a resource compiler which understands the standard
X.rc extension resources for menus and dialogs.
X
--
X
X     Astrolog may be compiled for DOS using the Borland Turbo C/C++
compiler, in addition to Microsoft C. Graphics support works too
using the Borland BGI graphics libraries. If you want to compile in
Borland graphics, uncomment the "#ifdef BGI" line in astrolog.h
(instead of the "#ifdef MSG" for the Microsoft graphics.lib). If you
don't want to compile in graphics, just make sure the "#ifdef PC"
line is uncommented (there are some #ifdef __TURBOC__ lines in the
sources to do non-graphical Borland specific things).
X
X     To actually compile, use the "makefile.bgi" makefile, and invoke
it with "make /f makefile.bgi" (or rename it to be just "makefile"
and run just "make"). Note that the file "makefile.cfg" is also
needed and is used during compilation by the main makefile. If you
are compiling in graphics, you will need to have object files for all
six of the BGI drivers in the directory you compile in. To make these
files, go into your BGI directory (e.g. "CD C:\BORLANDC\BGI") and do
the command "BGIOBJ /F <file>". Do this six times, where <file> is
"ATT", "CGA", "EGAVGA", "HERC", IBM8514", and finally "PC3270".
X
X     A Borland compile is fast and functionally identical to the
Microsoft compilations in nearly every respect except for the
astrolog.dat graphics mode indexes. The list of modes you can assign
to the "hi-res" and "lo-res" graphics modes as switched to via the
'tab' key don't apply to Borland compiles. For Borland graphics, there
are two options: a "hi-res" mode for whichever driver expressed using
negative values and zero, and a "lo-res" mode expressed by positive
values. Of course it's best to have the astrolog.dat graphics mode
settings set to "0" for "hi-res" and "1" for "lo-res" so Astrolog
does the expected thing and aligns with these two graphics modes
available. Note that for standard VGA, "hi-res" is a non-flicker
free 640x480 resolution, while "lo-res" is flicker free 640x350, as
with Microsoft, while the default Microsoft settings of "-3" and "16"
for the graphics mode nicely do the right thing for Borland builds too.
X
--
X
X     Astrolog is officially supported and runs on the Mac. The
standard ready to run Mac executable is distributed in a BinHex
4.0'ed self extracting archive. To unpack it, use a utility that can
un-BinHex such files to generate the self extracting archive, and
then double click the archive program to unpack the executable,
documentation, and other such files. I used CompactPro 1.34 to create
the Mac archive, a useful utility that can also BinHex and un-BinHex
files. The executable should run on most any 68K processor Mac, and
will run on PowerMacs in emulation mode. It requires 750K of heap to
run, with 1.5M preferred.
X
X     The Mac Astrolog executable has the same icon as the PC version,
a ringed planet with tilted red rings and surrounding stars, except
the planet body is tan (gray in four bit color mode) instead of
yellow. It and the other files are unpacked into their own "Astrolog
5.40" folder, where the folder's icon has the same ringed planet
overlaying it. When the program is actually run, you'll be prompted
to enter command switches in a terminal window. There aren't many
options available on the Mac menu bar, although you can File Quit and
copy selected text to the clipboard with it. The window doesn't have
scroll bars for when text runs off the top of the screen, but the -YQ
pager will prompt you to press return to continue scrolling if
needed, and the -os switch can be used to send all the output to a
file in your Astrolog folder. When the program terminates, the window
title will prompt you to press return one more time to exit before
the window actually goes away.
X
X     The program can read from the astrolog.dat file, and will use
the ephemeris files for very accurate calculations if -b is in
effect. These and chart info files are the same and fully compatible
with such files from PC and Unix versions. All files must however be
in the Astrolog folder for the program to find them. The -n chart for
now switch will work accurately provided the current time and zone
are set up correctly in the Control Panels. The -k Ansi text feature
does exist in Mac Astrolog, but the terminal won't be able to display
the control codes properly, so this isn't really useful unless the
output is sent to a file and later displayed in an environment that
understands the codes and can show the colored text.
X
X     Astrolog's source code can be compiled and run on the Macintosh
perfectly with no special modifications needed. In making the
official Mac executable, I used the compiler Symantec C/C++ 7.0 for
the Mac. When compiling, uncomment the "MAC" compile time option in
astrolog.h, turn on the "far data" flag in the compiler, and make
sure the ANSI library is set to be loaded. Other Astrolog compile
time option settings should be SWITCHES off, ENVIRON off, and PROTO
off. For Mac graphics, uncomment the "MACG" compile time setting in
astrolog.h, and make sure the MacTraps library is set to be loaded.
X
X     The Mac version of Astrolog also supports on-screen graphics, in
addition to the ability to create graphic bitmap, metafile, and
PostScript files on disk which may be viewed in another program. The
-X switch will bring up a separate window with the appropriate wheel
or whatever other chart displayed in it, and can press keys while the
window is up to change or alter the display. This makes the Mac
version more or less equivalent in functionality to the DOS and X
Windows versions, although a few things such as mouse scribbles on
the screen and flicker free updates aren't available yet. In the
source code, there's a compile time option in the astrolog.h file
called MACG. When set, it will compile in the Mac screen graphics.
When commented out, it will be like before. The MACG define is like
the MSG, BGI, and X11 compile time variables which turn on screen
graphics for other platforms.
X
--
X
O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O
*       Walter D. "Cruiser1" Pullen :)       !       Astara@msn.com       *
O Astrolog 5.40 homepage:  http://www.magitech.com/~cruiser1/astrolog.htm O
* "Who am I, What am I?  As I am, I am not.  But as we are, I AM.  And to *
O you my creation, My Perfect Love is your Perfect Freedom. And I will be O
* with you forever and ever, until the End, and then forever more." - GOD *
O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O
SHAR_EOF
  $shar_touch -am 1223232998 'Helpfile.540' &&
  chmod 0644 'Helpfile.540' ||
  echo 'restore of Helpfile.540 failed'
  shar_count="`wc -c < 'Helpfile.540'`"
  test 397535 -eq "$shar_count" ||
    echo "Helpfile.540: original size 397535, current size $shar_count"
fi
# ============= Makefile ==============
if test -f 'Makefile' && test X"$1" != X"-c"; then
  echo 'x - skipping Makefile (File already exists)'
else
  echo 'x - extracting Makefile (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
# Astrolog (Version 5.40) File: Makefile (Unix version)
#
# IMPORTANT NOTICE: The graphics database and chart display routines
# used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
# (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
# Permission is granted to freely use and distribute these routines
# provided one doesn't sell, restrict, or profit from them in any way.
# Modification is allowed provided these notices remain with any
# altered or edited versions of the program.
#
# First created 11/21/1991.
#
# This Makefile is included only for convenience. One could easily compile
# Astrolog on a Unix system by hand with the command:
# % cc -c -O *.c; cc -o astrolog *.o -lm -lX11
# Generally, all that needs to be done to compile once astrolog.h has been
# edited, is compile each source file, and link them together with the math
# library, and if applicable, the main X library.
#
NAME = astrolog
OBJ = astrolog.o data.o data2.o general.o io.o\
X calc.o matrix.o placalc.o placalc2.o\
X charts0.o charts1.o charts2.o charts3.o intrpret.o\
X xdata.o xgeneral.o xdevice.o xcharts0.o xcharts1.o xcharts2.o xscreen.o
# If you don't have X windows, delete the "-lX11" part from the line below:
LIBS = -lm -lX11
CFLAGS = -O
X
astrolog:: $(OBJ)
X	cc -o $(NAME) $(OBJ) $(LIBS)
X	strip $(NAME)
#
SHAR_EOF
  $shar_touch -am 1223232998 'Makefile' &&
  chmod 0644 'Makefile' ||
  echo 'restore of Makefile failed'
  shar_count="`wc -c < 'Makefile'`"
  test 1326 -eq "$shar_count" ||
    echo "Makefile: original size 1326, current size $shar_count"
fi
# ============= README.1ST ==============
if test -f 'README.1ST' && test X"$1" != X"-c"; then
  echo 'x - skipping README.1ST (File already exists)'
else
  echo 'x - extracting README.1ST (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'README.1ST' &&
* Astrolog 5.40 is a many featured and
customizable astrology chart calculation
program for DOS, Windows, Mac, and Unix,
used in 35+ countries on six continents.
It is 100% freeware and requires no
registration fee. :) The complete source
code is available. Astrolog features:
wheels, aspects, midpoints, relationship
charts, transits, progressions, some
interpretations, astro-graphy, local
horizon, constellations, planet orbits,
dispositors, various influence charts,
biorhythms, different zodiacs, central
planets, 15 house systems, 8400 year
ephemeris, asteroids, Uranians, fixed
stars, Arabic parts, script files and
macros, interactive PC & MS/X11 Windows
graphics, smooth animation of charts,
graphic files in PostScript, Windows
metafile, and bitmap formats, and more!
SHAR_EOF
  $shar_touch -am 1223232998 'README.1ST' &&
  chmod 0644 'README.1ST' ||
  echo 'restore of README.1ST failed'
  shar_count="`wc -c < 'README.1ST'`"
  test 778 -eq "$shar_count" ||
    echo "README.1ST: original size 778, current size $shar_count"
fi
# ============= README.540 ==============
if test -f 'README.540' && test X"$1" != X"-c"; then
  echo 'x - skipping README.540 (File already exists)'
else
  echo 'x - extracting README.540 (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'README.540' &&
--
X
X AAAAA    SSSSS   TTTTTTT  RRRRRR    OOOOO   L         OOOOO    GGGGG
A     A  S     S     T     R     R  O     O  L        O     O  G     G
A     A  S           T     R     R  O     O  L        O     O  G
AAAAAAA   SSSSS      T     RRRRRR   O     O  L        O     O  G  GGGG
A     A        S     T     R   R    O     O  L        O     O  G     G
A     A  S     S     T     R    R   O     O  L        O     O  G     G
A     A   SSSSS      T     R     R   OOOOO   LLLLLLL   OOOOO    GGGGG
X
X                         **  VERSION 5.40  **
X
X
Astrolog: currently used in over 35 countries on six continents!
X
--
X
Astrolog is relatively unique in astrology software for the following reasons:
X  (1) It's 100% freeware. :)
X  (2) It runs on multiple platforms, such as DOS, Windows, Mac, and Unix.
X  (3) The full source code is available.
X  (4) Features are accessible from the command line and from shell scripts.
X  (5) It offers many features not found in most other programs.
X
"The Best Freeware/Shareware Program of 1995 is Astrolog for Windows"
- American Astrology, March 1996
X
"One exceptionally good freeware program is available to astrologers -
good enough to be worthy of review with the main commercial programs.
This is Astrolog..." - The Mountain Astrologer, November 1995
X
"For a free program to have such a superb ephemeris with an 8000-year
range is incredible." - American Astrology, November 1994
X
--
X
A list of the main features in Astrolog:
X
Position calculation features:
X  Positions of Sun through Pluto and the house cusps.
X  Positions of Chiron and the four main asteroids.
X  Positions of True and Mean nodes, Part of Fortune, Vertex, and East Point.
X  Positions of Lilith.
X  Positions of the eight Uranian planets.
X  Positions of over 40 fixed stars.
X  Positions of over 170 Arabic parts and their formulas.
X  Option to use any or all of accurate 8400 year ephemeris.
X
Computation features:
X  Fourteen house systems.
X  Tropical and sidereal zodiac.
X  Specify zodiac starting position / ayanamsa.
X  Heliocentric and other planet centered charts.
X  Applying and separating aspects.
X  Parallel and contraparallel aspects.
X  Harmonic charts.
X  Solar charts with objects on Ascendant or Midheaven.
X  Decan positions.
X  Navamsa positions.
X  Specify your own positions for planets.
X  Positions relative to ecliptic or equator.
X  Local horizon positions in prime vertical coordinates.
X
Display formats:
X  Generic position listing.
X  Wheel charts.
X  Hindu or Vedic format wheel charts.
X  Aspect and midpoint grids.
X  List aspect configurations such as Yods.
X  List aspects sorted by influence.
X  List midpoints sorted by position.
X  Local horizon positions.
X  Times of planets rising and setting.
X  Solar system orbit charts.
X  Gauquelin sector charts.
X  Astro-graph charts.
X  List latitude crossings in astro-graph charts.
X  Generic monthly and yearly calendars.
X  Ephemeris tables.
X  Biorhythm charts.
X
Transit and progression features:
X  Secondary progressions and solar arc progressions.
X  Specify your own progression rate.
X  Times of exact aspects among transiting planets.
X  Times of planets changing sign or direction.
X  Times of lunar phases and season changes.
X  Times of exact aspects in a progressed chart.
X  Times of exact transit hits.
X  Times of transits to house cusps.
X  Times of solar, lunar, and other returns.
X  Times of exact transits from progressed planets.
X  List transits to natal planets within orb in influence order.
X  List aspects within orb among transiting planets in influence order.
X  Transits to composite and other no-time charts.
X
Relationship chart features:
X  Synastry charts.
X  Composite charts.
X  Time space midpoint charts.
X  Weighted relationship charts.
X  Display elapsed time between charts.
X  Aspect and midpoint grids between two charts.
X  Aspect and midpoint lists between two charts.
X  Automatic progressed to natal comparison chart.
X
Interpretation features:
X  Influence charts sorting planets and signs by power.
X  Interpret natal positions and natal aspects.
X  Interpret transits and midpoints.
X  Interpret transiting aspects and sign and direction changes.
X  Interpret aspects and midpoints between charts.
X  Interpret synastry charts.
X
Graphics features:
X  Graphic wheel chart.
X  Graphic bi-wheel comparison / transit chart.
X  Graphic tri-wheels and quad-wheels.
X  Graphic aspect / midpoint and relationship aspect / midpoint grids.
X  Graphic astro-graph chart on a map of the world.
X  Graphic local horizon, polar horizon, Gauquelin wheel, and orbit charts.
X  Graphic ephemeris tracking chart.
X  Graphic calendars and biorhythms.
X  Dispositor graph chart.
X  Plot positions among the astronomical constellations.
X  Smoothly animate charts through time at varying rates.
X  Continuously update chart to current moment now.
X  Animate a rotating globe.
X  Timed exposures for horizon and orbit charts.
X  Create PostScript graphic files.
X  Create graphic X11 and Windows bitmap files.
X  Create Windows metafiles.
X
Customization options:
X  Initialization file for default settings.
X  Choose what transiting and natal planets to include in charts.
X  Choose among 18 major and minor aspects, or define your own.
X  Specify aspect orbs.
X  Specify the maximum orb allowed to a planet.
X  Specify wider orbs for any planet.
X  Display zodiac positions to the nearest second.
X  DMY & MDY date formats and 24 hour & am/pm time formats.
X  Display locations in hours & minutes or 360 degree form.
X  Customize interpretation strings.
X  Customize colors.
X  Define your own orbital elements for planets.
X  Choose among graphic glyphs for certain signs and planets.
X  Specify influence of planets and planets when transiting.
X  Specify influence of houses and aspects.
X
Chart access features:
X  Quick charts for the current moment now.
X  Save and load chart time and place to file.
X  Save and load chart positions to file.
X  Save text output directly to file.
X  Relocate charts.
X  Cast a chart a specified time ahead of any chart.
X
System features:
X  Display text charts in Ansi color.
X  Paging for when text charts are more than a screenful.
X  Access environment variables.
X  Define macros for your most common operations.
X  Easy to use menu and dialog interface in the Windows version.
X
--
X
Astrolog system requirements:
X
For PC's, 640K of RAM and a reasonably recent version of DOS. A math
co-processor chip is recommended for best performance but not
required. Astrolog can take advantage of Ansi text, CGA, EGA, VGA,
and SVGA graphics but they are not required. The program will run on
8088 AT and XT systems and higher x86 processors. The DOS version of
Astrolog may be run from MS Windows in a DOS box.
X
For compiling the source code for PC's, the Microsoft C compiler
version C6 or later, or Borland Turbo C/C++ compiler version 3.0 or
later. Other compilers should work although one will probably have to
compile out the screen graphics sections.
X
For the Windows version, at least 2M of RAM and Windows 3.1 or later.
Astrolog for Windows will run under Windows for Workgroups, Windows
'95, and Windows NT. For compiling the Windows version, Microsoft
Visual C version 1.5 or later is recommended, although most any
Windows compiler should work provided it can compile resource files.
X
For Unix systems, some C compiler is required since ready to run
executables aren't available. Astrolog can take advantage of X11
Windows but they are not required.
X
Astrolog will compile and work on VMS systems, even with X Windows,
but this isn't officially tested. A .COM makefile script is included.
X
On the Macintosh Astrolog will compile and run with every feature
including some interactive graphics, using for example the Symantec
C/C++ 7.0 compiler for the Mac. It will run on any reasonably recent
68K Mac with 750K free, and will run on PowerMac's in emulation mode.
X
A few third party ports of Astrolog are publicly available. This
includes a port of Astrolog version 4.00 to OS/2 Presentation Manager
by David Serls, a port of Astrolog 2.25 to the Macintosh but with
interactive graphics by Pascal Lamboley, and a port to the Amiga by
Tobias Ferber.
X
--
X
Where to get Astrolog:
X
Astrolog's homepage at http://www.magitech.com/~cruiser1/astrolog.htm
which allows downloads using a Web interface of all the Astrolog
files at the Magitech FTP site below. This site also offers
information on the program, current bug lists, screen shots, and
links to related sites.
X
Astrolog's own Web domain at http://www.astrolog.org, where the page
http://www.astrolog.org/astrolog.htm is a mirror of the site above.
If one site ever happens to be down, the other site should work.
X
The anonymous FTP site ftp.magitech.com (or magitech.tcastle.is.net),
maintained by J.H. Trott. The directory /pub/astrology/astrolog
contains all executables, documentation, and source code, for DOS,
Windows, Unix, and the Mac. All ephemeris files are available in the
subdirectory /pub/astrology/astrolog/ephem.
X
The anonymous FTP site ftp.coast.net (and its mirrors such as
oak.oakland.edu). These are SimTel sites where the PC Astrolog files
may be found in /SimTel/msdos/entertn in the file ast54dos.zip, and
in /SimTel/win3/entertn in the files ast54win.zip and ast54src.zip.
X
The BBS "Astro Net-1" at US phone number 414-481-9976, maintained by
Carl Baewer. This is for PC's only, but has all DOS and Windows
executables, source, documentation, and ephemeris files. They do want
one to register first, but that and downloads are free minus any long
distance charges.
X
Several past versions of Astrolog have been posted to the Usenet
newsgroup comp.sources.misc and hence are available at many other FTP
sites archiving this group. Utilities such as archie can locate these
sites, such as ftp.uu.net. The latest Astrolog release for which this
was done is 4.10, in volume 32. (Older versions are in volumes 37,
30, and 28.) Note that those releases are only in Unix shell archive
format and have no binary files in them.
X
Right after a new release, the files for Astrolog may sometimes be
found on the Usenet newsgroup alt.astrology, while the Unix source
can sometimes be found on comp.sources.misc if the version in
question was submitted there, until the articles expire.
X
Note that the following anonymous FTP sites used to contain astrology
files but don't anymore: hilbert.maths.utas.edu.au, maintained by
Michael Bulmer, and ftp.u.washington.edu.
X
--
X
Astrolog files:
X
When accessing sites offering Astrolog, one may encounter various
files. Here is a list of them and what they contain, so one will know
which ones to actually download.
X
README.540 -
X  A summary of Astrolog and what it offers. What you're reading now.
X  A copy of this file is contained in ast54win.zip, ast54dos.zip,
X  ast54src.zip, ast54mac.hqx, and ast54unx.shr.
X
ast54win.zip -
X  A ready to run MS Windows executable and related files. For most
X  users, this is the only file needed. Pkunzip version 2.04 or later
X  required to unpack.
X
ast54dos.zip -
X  A ready to run DOS executable and related files. For most PC users,
X  this is the only file needed. Pkunzip version 2.04 or later is
X  required to unpack.
X
ast54src.zip -
X  The source code. Requires a C compiler to use and pkunzip again to
X  unpack.  Not required to run if you already have the executable above.
X
ast54mac.hqx -
X  A ready to run Macintosh executable and related files. This is just
X  like ast54dos.zip but for the Mac. BinHex 4.0 is required to unpack.
X
ast54unx.shr -
X  The source code and other useful files to run. Contains all of the
X  files in ast54src.zip, but in Unix shell archive format. Requires the
X  Bourne shell command sh or equivalent utility to unpack.
X
Helpfile.540 -
X  The complete documentation for all of Astrolog's features. A copy of
X  this file is contained in ast54win.zip, ast54dos.zip, ast54mac.hqx,
X  and ast54unx.shr.
X
Update.540 -
X  Additions made to version 5.40 over the version before. Only useful
X  if one is familiar with and upgrading from the previous version. A
X  copy of this file is contained in ast54dos.zip and ast54unx.shr.
X
History.540 -
X  Describes the history and additions made to each version of Astrolog
X  since its beginning. Generally only useful if one is upgrading from
X  several versions ago and wants to be updated on the past few releases.
X
LRZ5_xx, CHI_xx, CPJV_xx -
X  Ephemeris files. Not required but provide more accurate positions.
X  The files are in groups with xx being a number indicating the time
X  period covered. The three files LRZ5_24, CHI_24, and CPJV_24 cover
X  the current and 21st centuries. A copy of those three files are
X  contained in ast54win.zip, ast54dos.zip, and ast54mac.hqx.
X
pmastro.zip -
X  An older third party port of Astrolog 4.00 to OS/2 Presentation Manager.
X
--
X
IMPORTANT NOTICE: The graphics database and chart display routines
used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
(Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
Permission is granted to freely use and distribute these routines
provided one doesn't sell, restrict, or profit from them in any way.
Modification is allowed provided these notices remain with any
altered or edited versions of the program.
X
The main planetary calculation routines used in this program have
been Copyrighted and the core of this program is basically a
conversion to C of the routines created by James Neely as listed in
Michael Erlewine's 'Manual of Computer Programming for Astrologers',
available from Matrix Software. The copyright gives us permission to
use the routines for personal use but not to sell them or profit from
them in any way.
X
The PostScript code within the core graphics routines are programmed
and Copyright (C) 1992-1993 by Brian D. Willoughby. Conditions are
identical to those above.
X
The extended accurate ephemeris databases and formulas are from the
calculation routines in the program "Placalc" and are programmed and
Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
The use of that source code is subject to regulations made by
Astrodienst Zurich, and the code is not in the public domain. This
copyright notice must not be changed or removed by any user of this
program.
X
--
X
O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O
*       Walter D. "Cruiser1" Pullen :)       !       Astara@msn.com       *
O Astrolog 5.40 homepage:  http://www.magitech.com/~cruiser1/astrolog.htm O
* "Who am I, What am I?  As I am, I am not.  But as we are, I AM.  And to *
O you my creation, My Perfect Love is your Perfect Freedom. And I will be O
* with you forever and ever, until the End, and then forever more." - GOD *
O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O
SHAR_EOF
  $shar_touch -am 1223232998 'README.540' &&
  chmod 0644 'README.540' ||
  echo 'restore of README.540 failed'
  shar_count="`wc -c < 'README.540'`"
  test 14700 -eq "$shar_count" ||
    echo "README.540: original size 14700, current size $shar_count"
fi
# ============= Update.540 ==============
if test -f 'Update.540' && test X"$1" != X"-c"; then
  echo 'x - skipping Update.540 (File already exists)'
else
  echo 'x - extracting Update.540 (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Update.540' &&
####################  ASTROLOG 5.40 UPDATE FILE  #####################
X
Happy Winter Solstice everyone! This file describes the freeware
astrology software program Astrolog version 5.40 and the additions
and fixes made to it, over the previous version 5.30 which was
released over two years ago. I have not worked on the program as
often as before, so apologies for the delay. This update contains
Hindu or Vedic format wheel charts, and the standard assortment of
small bug fixes.
X
This release consists of the following files. If you are reading this
document as posted in the newsgroup alt.astrology, the first two of
these files may be found posted as separate articles:
X
1. "Update.540" - A text file describing new additions to Astrolog
X   5.40 made over the previous version (what you're reading now).
2. "Readme.540" - A text file describing Astrolog in general and what
X   the program offers and can do, for those interested in a summary.
3. "ast54win.zip" - A zip archive containing a Windows executable
X   ready to run on any Windows system, a configuration file, four icon
X   files, two URL files, three ephemeris files, a Readme, small summary
X   file, a comprehensive Helpfile manual, and this Update file.
4. "ast54dos.zip" - A zip archive containing a DOS executable ready
X   to run on PC's, config file, icon files, URL files, three ephemeris
X   files, a Readme, small summary file, Helpfile, and this Update file.
5. "ast54mac.hqx" - A BinHex 4.0'ed self extracting archive program
X   of the Macintosh executable, config file, three ephemeris files,
X   Readme, summary, Helpfile, a resource file, and this Update file.
6. "ast54src.zip" - A zip archive containing the source code and
X   makefiles (not necessary unless you want to compile the program
X   yourself).
7. "History.540" - A text file describing additions in all previous
X   releases (only useful if upgrading from more than one version ago).
X
The "Helpfile" consists of a large comprehensive documentation file
of all of Astrolog's features. The "config file" is a default
settings file called astrolog.dat (not necessary to have to run but
useful). The "icon files" are Microsoft Windows icons from the
Windows executable. The "URL files" are small Microsoft Windows text
files containing Web shortcuts to the Astrolog homepage. The "summary
file" is a file_id.diz like that included in many zip distributions,
briefly describing the program in whole. The "Update file" is again
this document. The "ephemeris files" are three binary files used for
more accurate calculations of planetary positions (again optional but
nice to have). The "source code" consists of 28 files (23 "C" program
files, four header #include files, and a resource script file). The
"makefiles" are six files: a generic makefile for Unix systems with
their "make" command, a project makefile for Microsoft Windows
compilers, a nmakefile for Microsoft DOS compilers, a makefile for
Borland PC compilers (with a second subfile to go with it), and a
command script for compiling on VMS systems.
X
All the files described above are available at the Astrolog 5.40
homepage at http://www.magitech.com/~cruiser1/astrolog.htm. This Web
page is mirrored at http://www.astrolog.org/astrolog.htm. (If one
site is down, the other should work.) All Astrolog files are also at
the alt.astrology anonymous FTP site at ftp.magitech.com in the
Astrolog directory /pub/astrology/astrolog. All of the ephemeris
files are already in the subdirectory /pub/astrology/Astrolog/ephem.
X
X
#####################  ASTROLOG 5.40 NEW FEATURES  #####################
X
Here are new additions to version 5.40 that weren't in 5.30 and before:
X
1. -J switch: Astrolog 5.40 can now display wheel charts in Hindu or
X   Vedic format. This will affect both the text -w wheels and the
X   graphic wheels. A Vedic format wheel is identical to a standard
X   Western wheel except: (1) The signs and houses increase as you go
X   clockwise instead of counterclockwise, so the entire wheel is flipped
X   over. (2) The chart is rotated so the left edge is always the start
X   of Aquarius instead of the Ascendant, putting Pisces in the upper
X   left corner, meaning the Ascendant is placed wherever in the wheel is
X   appropriate. For Vedic astrology one will probably prefer to combine
X   this with the -w house focused wheel chart switch so all the houses
X   are the same size, or even display that chart in text mode so the
X   wheel will be a square.
X
X   'z' key: Pressing the 'z' key while a graphics screen is displayed
X   will toggle whether wheel charts are displayed in the new Vedic
X   format.
X
2. -9 switch: This command switch will display the chart in the
X   Navamsa format used in Vedic astrology. The Navamsa or marriage chart
X   is formed by applying a formula to each planet position to get a
X   resulting new location. This is similar in operation to the -3 decan
X   feature, however this divides each sign into ninths. Specifically, to
X   convert a position, see which ninth of a sign a planet falls in, e.g.
X   a planet from 0 degrees 0' to 3 degrees 20' of a sign is in the first
X   ninth, a planet from 3 degrees 20' to 6 degrees 40' is in the second
X   ninth, and so on. Take that number, and count one less than that many
X   signs ahead in the zodiac to get the resulting sign. The starting
X   sign should be Aries if the original sign was Fire, Capricorn if the
X   original sign was Earth, Libra if the original sign was Air, and
X   Cancer if the original sign was Water. A formal Navamsa chart only
X   considers signs, hence only the sign of each planet will be changed;
X   the degree within each sign will be unaffected.
X
X   'y' key: Pressing the 'y' key while a graphics screen is displayed
X   will toggle whether charts are displayed in Navamsa format or not.
X
3. -c extension: The -c house selection switch has been extended to
X   allow a Vedic system of houses, or more specifically the modern India
X   style of equal houses. This is house system number 13, and can be
X   activated on the command line by including "-c 13" (or "-c ved").
X   Note that this moves the index number for the Null house system up
X   one. In this system, each house covers 30 degrees, and the Ascendant
X   is always in the middle of the first house, i.e. the 1st cusp is
X   always 15 degrees before the Ascendant. (For contrast, the ancient or
X   traditional India style of equal houses are already supported in
X   Astrolog by the Whole house system, where the first house cusp is
X   always the start of the sign the Ascendant is in.)
X
4. Dialog extension: The ayanamsa or zodiac degree offset field in
X   the Calculation Settings dialog in the Windows version has been
X   fitted with a dropdown to allow quick selection of several common
X   systems of sidereal astrology. The values in it are 0.0 for Fagan
X   Bradley, 0.883333 (or 0 degrees 53') for N.C. Lahiri, 0.983333 (or 0
X   degrees 59') for Krishnamurti, and 2.333333 (or 2 degrees 20') for
X   B.V. Raman.
X
5. -zm switch: This simple switch will set the month and only the month
X   of the current chart in memory to the given value. For example, to
X   display an ephemeris chart for July of this year, do "-n -zm July -E".
X
6. -zy switch: This is just like the -zm switch above expect it will
X   set the year and only the year of the current chart in memory to the
X   given value. For example, to display a chart for your birthday next
X   year, do "-i yourchart -zy 1999".
X
7. Improved glyphs: Astrolog now has higher resolution graphic glyphs
X   for sign symbols and house numbers. Before, some glyphs drawn at the
X   default 200% or medium scale and up would look slightly blocky. Now,
X   with a alternate "internal font" of double sized glyphs, the medium
X   ones are smooth to the nearest pixel like the small glyphs are. The
X   glyph for the Quintile aspect has also been improved. The better
X   glyphs are also used at the 400% or huge scale, and when printing.
X
8. Windows addition: The Documentation submenu of the Help menu in
X   the Windows version has a new "Open Homepage" command to
X   automatically visit the Astrolog homepage. This command will start
X   Internet Explorer or whatever Web browser your system has set to
X   interpret .URL extension files, and will have that browser open the
X   file astrolog.url in your astrolog directory.
X
--
X
Here's a summary of the four new command switches in Astrolog 5.40
that weren't in previous versions:
X
-zm <month>: Set only the month of current chart.
-zy <year>: Set only the year of current chart.
-J: Display wheel charts in Vedic format.
-9: Display objects in their zodiac navamsa positions.
X
Here's a summary of the four new menu commands in the Windows
version of Astrolog 5.40 that weren't in previous versions:
X
Setting - House System - Vedic
Setting - House Settings - Vedic Wheel Display
Setting - House Settings - Show Navamsas
Help - Documentation - Open Homepage
X
X
#####################  ASTROLOG 5.40 BUG FIXES  #####################
X
Here are problems with version 5.30, all of which have been corrected
in this release:
X
1. -EY bug: The multiple year ephemeris switch wouldn't update the
X   "next switch indicator" past the number of years parameter, so the
X   number of years to do the ephemeris for would also get treated as a
X   command switch, resulting in either unexpected looking charts or an
X   unexpected "unknown switch" error.
X
2. Computation fix: Charts cast at extreme latitudes (inside the
X   Arctic or Antarctic circles) could cause bogus looking charts with
X   overlapping houses. This would happen when the natural formulas for
X   the MC and Asc at those locations would put the Asc in the 180
X   degrees before instead of after the MC. Astrolog now preserves the
X   Midheaven, and flips the Ascendant if need be to ensure the other
X   house cusps will remain sane.
X
3. Edit - Copy Chart Text bug: In the Windows version, copying text
X   table list charts to the clipboard would only actually copy about the
X   first 90% of the text, clipping off the rest.
X
4. -YJ bug: The -YJ switch which allows changing what signs each
X   planet rules, wouldn't also update a reverse table which given a sign
X   indicates which planet rules it. This would cause -YJ to have
X   seemingly no effect on the sign list table, the influence chart, the
X   Arabic parts chart, and the dispositor graph.
X
5. -r0 limitation: The -r0 switch will now accept the virtual file
X   "nul" as its first parameter, so command sequences like "-q -r0 nul
X   now" will work and use the chart data from -q in the relationship
X   chart. Before the first chart slot would get overwritten by the data
X   for the second chart while internally processing the second chart.
X
6. Display glitch: The degree hatch marks on Windows graphic wheels
X   wouldn't line up exactly on the lower right with the circles they go
X   between.
X
7. File - Save Settings limitation: The astrolog.dat defaults file as
X   generated by the Windows version would only save out aspect orbs and
X   planet orb additions to the nearest degree, losing any fractional
X   part. These values are now to the nearest tenth of a degree like they
X   are in the Aspect Settings dialog.
X
X
#####################  ASTROLOG 5.40 PROGRAM CHANGES  #####################
X
As with every release, a few changes that aren't feature additions or
bug fixes were made to this version, where certain old assumptions
are no longer valid. A list of these (which aren't useful to be aware
of unless you have used previous versions of the program) follows:
X
1. -YP change: The -YP switch affecting whether Arabic parts have
X   their formulas inverted for night time charts, now also affects the
X   special Part of Fortune object in the main object list. Before, you
X   could only either never invert the Part of Fortune (the default) or
X   else always invert the Part of Fortune (even for day charts). The
X   special Part of Fortune object is now affected by "-YP 0" which means
X   the standard process of inverting just for night charts. As this is
X   the default setting, this means Astrolog 5.40 will compute the Part
X   of Fortune in the standard displays differently than previous
X   versions, for night charts.
X
2. Defaults dialog addition: The -Yz correction factor for "now"
X   charts switch has been added to the Default Chart Info dialog. This
X   is to make that feature more discoverable, as people asking why their
X   "now" charts are whatever number of hours off is the single most
X   common subject of Astrolog related e-mail I receive.
X
3. astrolog.dat change: The -Yz correction factor for "now" charts
X   has had its position in the default astrolog.dat settings file moved
X   closer to the top, again to make it more discoverable. It's now right
X   next to the line that turns on doing -n "now" charts themself.
X
4. Calculation improvement: Astrolog will no longer just display a
X   error and terminate the program if one tries to cast a chart inside
X   the Arctic or Antarctic circles using Placidus or Koch houses. (Those
X   systems of houses are not defined near the poles.) In such a case the
X   program will now change the latitude of the chart being computed to
X   the closest legal latitude allowed (i.e. move it from the pole to the
X   edge of the Arctic or Antarctic circle) during the computation of the
X   chart.
X
5. -r0 -g -X improvement: The graphic relationship aspect grid has
X   been improved so the outlines of the cells on the main diagonal are
X   highlighted in a slightly brighter color.
X
6. -M -X tweak: The sidebar in the graphic Gauquelin sector wheel
X   chart has been changed so that to the right of each planet position
X   is the sector number the planet falls in. Before this was just the
X   glyph for the object in question like it is for the other wheels.
X
7. Previous chart change: The initial contents of the "previous" chart
X   as accessed with "-i set" has been changed from the astrological
X   "chart" of version 5.30 of the program to the release of this version
X   5.40. This chart is now set to the time of the Winter Solstice,
X   specifically for 5:57pm PST (8 hours before GMT) on Monday, December
X   21, 1998 for here in Seattle, WA (122W20, 47N36).
X
--
X
O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O
*       Walter D. "Cruiser1" Pullen :)       !       Astara@msn.com       *
O Astrolog 5.40 homepage:  http://www.magitech.com/~cruiser1/astrolog.htm O
* "Who am I, What am I?  As I am, I am not.  But as we are, I AM.  And to *
O you my creation, My Perfect Love is your Perfect Freedom. And I will be O
* with you forever and ever, until the End, and then forever more." - GOD *
O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O*O
SHAR_EOF
  $shar_touch -am 1223232998 'Update.540' &&
  chmod 0644 'Update.540' ||
  echo 'restore of Update.540 failed'
  shar_count="`wc -c < 'Update.540'`"
  test 14714 -eq "$shar_count" ||
    echo "Update.540: original size 14714, current size $shar_count"
fi
# ============= astrolog.c ==============
if test -f 'astrolog.c' && test X"$1" != X"-c"; then
  echo 'x - skipping astrolog.c (File already exists)'
else
  echo 'x - extracting astrolog.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'astrolog.c' &&
/*
** Astrolog (Version 5.40) File: astrolog.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
/*
******************************************************************************
** Program Dispatch Procedures.
******************************************************************************
*/
X
/* Initialize the Ansi color arrays with the color to print each object in. */
X
void InitColors()
{
X  int i;
X
X  kObjA[0] = kElemA[eEar];
X  for (i = 1; i <= 10; i++)
X    kObjA[i] = kSignA(ruler1[i]);
X  for (i = 11; i <= 15; i++)
X    kObjA[i] = kMainA[8];
X  for (i = 16; i <= 20; i++)
X    kObjA[i] = kMainA[6];
X  for (i = 1; i <= cSign; i++)
X    kObjA[cuspLo+i-1] = kSignA(i);
X  for (i = uranLo; i <= uranHi; i++)
X    kObjA[i] = kRainbowA[7];
X  for (i = starLo; i <= starHi; i++)
X    kObjA[i] = rStarBright[i-oNorm] < 1.0 ? kRainbowA[2] : kMainA[4];
}
X
X
/* This is the dispatch procedure for the entire program. After all the   */
/* command switches have been processed, this routine is called to        */
/* actually call the various routines to generate and display the charts. */
X
void Action()
{
X  char sz[cchSzDef];
X  int i;
X
#ifdef WIN
X  is.fMult = fFalse;    /* Cleared here because no InitVariables routine. */
#endif
X  is.fSzPersist = is.fNoEphFile = fFalse;
X  is.cchRow = 0;
X  AnsiColor(kDefault);
X  InitColors();
X  if (fSouthNode) {
X    szObjName[oSou] = "S.Node";
#ifdef INTERPRET
X    szMindPart[oSou] =
X      "karmic past, and area of experience but little growth";
#endif
X    ruler1[oSou] = sLeo;
X  }
X  szAspectAbbrev[aCon] = us.fParallel ? "Par" : "Con";
X  szAspectAbbrev[aOpp] = us.fParallel ? "CPr" : "Opp";
X
X  /* First let's adjust the restriction status of the cusps, uranians, and */
X  /* fixed stars based on whether -C, -u, and -U switches are in effect.   */
X
X  if (!us.fCusp)
X    for (i = cuspLo; i <= cuspHi; i++)
X      ignore[i] = ignore2[i] = fTrue;
X  if (!us.fUranian)
X    for (i = uranLo; i <= uranHi; i++)
X      ignore[i] = ignore2[i] = fTrue;
X  if (!us.nStar)
X    for (i = starLo; i <= starHi; i++)
X      ignore[i] = ignore2[i] = fTrue;
X
X  /* If the -os switch is in effect, open a file and set a global to */
X  /* internally 'redirect' all screen output to.                     */
X
X  if (is.szFileScreen) {
X    is.S = fopen(is.szFileScreen, "w");
X    if (is.S == NULL) {
X      sprintf(sz, "File %s can not be created.", is.szFileScreen);
X      PrintError(sz);
X      is.S = stdout;
X    }
X  } else
X    is.S = stdout;
X
X  if (FPrintTables())    /* Print out any generic tables specified.        */
X    goto LDone;          /* If nothing else to do, we can exit right away. */
X  if (is.fMult) {
X    PrintL2();
X    is.fMult = fFalse;
X  }
X
X  /* If -+ or -- switches in effect, then add the specified delta value to */
X  /* the date and use that as a new date before proceeding to make chart.  */
X
X  if (us.dayDelta != 0) {
X    is.JD = (real)MdyToJulian(MM, DD+us.dayDelta, YY);
X    JulianToMdy(is.JD, &MM, &DD, &YY);
X  }
X
X  /* Here we either do a normal chart or some kind of relationship chart. */
X
X  if (!us.nRel) {
#ifndef WIN
X    /* If chart info not in memory yet, then prompt the user for it. */
X    if (!is.fHaveInfo && !FInputData(szTtyCore))
X      return;
X    CastChart(fTrue);
#else
X    if (wi.fCast) {
X      wi.fCast = fFalse;
X      CastChart(fTrue);
X    }
#endif
X    ciMain = ciCore;
X  } else
X    CastRelation();
#ifndef WIN
X  ciSave = ciMain;
#endif
X
#ifdef GRAPH
X  if (us.fGraphics)         /* If any of the X window switches in effect, */
X    FActionX();             /* then go make a graphics chart...           */
X  else
#endif
X    PrintChart(is.fProgress);    /* Otherwise print chart on text screen. */
X
X  if (us.fWriteFile)        /* If -o switch in effect, then write */
X    FOutputData();          /* the chart information to a file.   */
X
LDone:
X  if (is.S != stdout) /* If we were internally directing chart display to a */
X    fclose(is.S);     /* file as with the -os switch, close it here.        */
X
X  if (grid) {
X    DeallocateFar(grid);
X    grid = NULL;
X  }
}
X
X
#ifndef WIN
/* Reset a few variables to their default values they have upon startup of */
/* the program. We don't reset all variables, just the most volatile ones. */
/* This is called when in the -Q loop to reset things like which charts to */
/* display, but leave setups such as object restrictions and orbs alone.   */
X
void InitVariables()
{
X  us.fInterpret = us.fProgress = is.fHaveInfo = is.fMult = fFalse;
X  us.nRel = us.dayDelta = 0;
X  is.szFileScreen = NULL;
X  ClearB((lpbyte)&us.fListing,
X    (int)((lpbyte)&us.fLoop - (lpbyte)&us.fListing));
}
#endif
X
X
/*
******************************************************************************
** Command Switch Procedures.
******************************************************************************
*/
X
/* Given a string representing a command line (e.g. a macro string), go    */
/* parse it into its various switches and parameters, then go process them */
/* and change program settings. Basically a wrapper for other functions.   */
X
bool FProcessCommandLine(szLine)
char *szLine;
{
X  char szCommandLine[cchSzMax], *rgsz[MAXSWITCHES];
X  int argc, cb, fT;
X
X  if (szLine == NULL)
X    return fTrue;
X  if (Mon != -1)
X    ciCore = ciMain;
X  cb = CchSz(szLine)+1;
X  CopyRgb((byte *)szLine, (byte *)szCommandLine, cb);
X  argc = NParseCommandLine(szCommandLine, rgsz);
X  fT = FProcessSwitches(argc, rgsz);
X  ciMain = ciCore;
X  return fT;
}
X
X
/* Given string representing a command line, convert it to an "argv" format */
/* of an array of strings, one for each switch or parameter, i.e. exactly   */
/* like the format of the command line as given when the program starts.    */
X
int NParseCommandLine(szLine, argv)
char *szLine;
char **argv;
{
X  int argc = 1, fSpace = fTrue, fQuote = fFalse;
X  char *pch = szLine;
X
X  /* Split the entered line up into its individual switch strings. */
X  while (*pch >= ' ' || *pch == chTab) {
X    if (*pch == ' ' || *pch == chTab) {
X      if (fSpace)
X        /* Skip over the current run of spaces between strings. */
X        ;
X      else {
X        /* First space after a string, end parameter here. */
X        if (!fQuote) {
X          *pch = chNull;
X          fSpace = fTrue;
X        }
X      }
X    } else {
X      if (fSpace) {
X        /* First character after run of spaces, begin parameter here. */
X        if (argc >= MAXSWITCHES-1) {
X          PrintWarning("Too many items - rest of line ignored.");
X          break;
X        }
X        fQuote = (*pch == '"');
X        argv[argc++] = pch + fQuote;
X        fSpace = fFalse;
X      } else
X        /* Skip over the current string. */
X        if (fQuote && *pch == '"') {
X          *pch = chNull;
X          fSpace = fTrue;
X        }
X    }
X    pch++;
X  }
X  argv[0] = szAppNameCore;
X  argv[argc] = NULL;         /* Set last string in switch array to Null. */
X  return argc;
}
X
X
/* This routine is called by the main program to interactively prompt the  */
/* user for command switches and parameters, entered in the same format as */
/* they would be on a command line. This needs to be called with certain   */
/* systems which don't allow passing of a command line to the program,     */
/* or when -Q is in effect. The result of this routine is returned to the  */
/* main program which then processes it as done with a real command line.  */
X
int NPromptSwitches(line, argv)
char *line, *argv[MAXSWITCHES];
{
X  FILE *data;
X  char sz[cchSzDef];
X
X  data = is.S; is.S = stdout;
X  is.cchRow = 0;
X  AnsiColor(kWhite);
X  sprintf(sz, "** %s version %s ", szAppName, szVersionCore); PrintSz(sz);
X  sprintf(sz, "(See '%cHc' switch for copyrights and credits.) **\n",
X    chSwitch); PrintSz(sz);
X  AnsiColor(kDefault);
X  PrintSz("Enter all parameter options below. ");
X  sprintf(sz, "(Enter '%cH' for help. Enter '.' to exit.)\n", chSwitch);
X  PrintSz(sz);
X  is.S = data;
X  InputString("Input command line", line);
X  PrintL();
X  return NParseCommandLine(line, argv);
}
X
X
/* This subprocedure is like FProcessSwitches() below, except that we only */
/* process one switch, which we know to be one of the obscure -Y types.    */
X
int NProcessSwitchesRare(argc, argv, pos, fOr, fAnd, fNot)
int argc, pos;
bool fOr, fAnd, fNot;
char **argv;
{
X  int darg = 0, i, j, k;
X  real r;
X  char ch1, ch2;
X  OE oe;
X  lpbyte lpb;
X  int FPTR *lpn;
X  lpreal lpr;
#ifdef INTERPRET
X  char *sz;
#endif
X
X  ch1 = argv[0][pos+1]; ch2 = argv[0][pos+2];
X  switch (argv[0][pos]) {
X  case chNull:
X    SwitchF(us.fSwitchRare);
X    break;
X
X  case 'n':
X    SwitchF(us.fTrueNode);
X    break;
X
X  case 'd':
X    SwitchF(us.fEuroDate);
X    break;
X
X  case 't':
X    SwitchF(us.fEuroTime);
X    break;
X
X  case 'C':
X    SwitchF(us.fSmartCusp);
X    break;
X
X  case '8':
X    SwitchF(us.fClip80);
X    break;
X
X  case 'Q':
X    if (argc <= 1) {
X      ErrorArgc("YQ");
X      return tcError;
X    }
X    i = atoi(argv[1]);
X    if (i < 0) {
X      ErrorValN("YQ", i);
X      return tcError;
X    }
X    us.nScrollRow = i;
X    darg++;
X    break;
X
X  case 'o':
X    SwitchF(us.fWriteOld);
X    break;
X
X  case 'c':
X    SwitchF(us.fHouseAngle);
X    break;
X
X  case 'z':
X    if (argc <= 1) {
X      ErrorArgc("Yz");
X      return tcError;
X    }
X    us.lTimeAddition = atol(argv[1]);
X    darg++;
X    break;
X
X  case 'l':
X    if (argc <= 1) {
X      ErrorArgc("Yl");
X      return tcError;
X    }
X    i = atoi(argv[1]);
X    if (!FSector(i)) {
X      ErrorValN("Yl", i);
X      return tcError;
X    }
X    SwitchF(pluszone[i]);
X    darg++;
X    break;
X
#ifdef ARABIC
X  case 'P':
X    if (argc <= 1) {
X      ErrorArgc("YP");
X      return tcError;
X    }
X    i = atoi(argv[1]);
X    if (!FBetween(i, -1, 1)) {
X      ErrorValN("YP", i);
X      return tcError;
X    }
X    us.nArabicNight = i;
X    darg++;
X    break;
#endif
X
X  case 'b':
X    if (argc <= 1) {
X      ErrorArgc("Yb");
X      return tcError;
X    }
X    i = atoi(argv[1]);
X    if (!FValidBioday(i)) {
X      ErrorValN("Yb", i);
X      return tcError;
X    }
X    us.nBioday = i;
X    darg++;
X    break;
X
X  case 'E':
X    if (argc <= 17) {
X      ErrorArgc("YE");
X      return tcError;
X    }
X    i = NParseSz(argv[1], pmObject);
X    if (!FHelio(i)) {
X      ErrorValN("YE", i);
X      return tcError;
X    }
X    oe.sma = atof(argv[2]);
X    oe.ec0 = atof(argv[3]);  oe.ec1 = atof(argv[4]);  oe.ec2 = atof(argv[5]);
X    oe.in0 = atof(argv[6]);  oe.in1 = atof(argv[7]);  oe.in2 = atof(argv[8]);
X    oe.ap0 = atof(argv[9]);  oe.ap1 = atof(argv[10]); oe.ap2 = atof(argv[11]);
X    oe.an0 = atof(argv[12]); oe.an1 = atof(argv[13]); oe.an2 = atof(argv[14]);
X    oe.ma0 = atof(argv[15]); oe.ma1 = atof(argv[16]); oe.ma2 = atof(argv[17]);
X    rgoe[IoeFromObj(i)] = oe;
X    darg += 17;
X    break;
X
X  case 'R':
X    if (argc <= 2 + (ch1 == 'Z')*2) {
X      ErrorArgc("YR");
X      return tcError;
X    }
X    i = NParseSz(argv[1], pmObject); j = NParseSz(argv[2], pmObject);
X    if (ch1 == '0') {
X      us.fIgnoreSign = i != 0;
X      us.fIgnoreDir  = j != 0;
X      darg += 2;
X      break;
X    } else if (ch1 == 'Z') {
X      ignorez[0] = i != 0;
X      ignorez[1] = j != 0;
X      ignorez[2] = atoi(argv[3]) != 0;
X      ignorez[3] = atoi(argv[4]) != 0;
X      darg += 4;
X      break;
X    }
X    if (!FItem(i)) {
X      ErrorValN("YR", i);
X      return tcError;
X    }
X    if (!FItem(j) || j < i) {
X      ErrorValN("YR", j);
X      return tcError;
X    }
X    if (argc <= 3+j-i) {
X      ErrorArgc("YR");
X      return tcError;
X    }
X    lpb = ch1 == 'T' ? ignore2 : ignore;
X    for (k = i; k <= j; k++)
X      lpb[k] = atoi(argv[3+k-i]) != 0;
X    darg += 3+j-i;
X    break;
X
X  case 'A':
X    if (argc <= 2) {
X      ErrorArgc("YA");
X      return tcError;
X    }
X    k = ch1 == 'm' || ch1 == 'd' ? pmObject : pmAspect;
X    i = NParseSz(argv[1], k); j = NParseSz(argv[2], k);
X    k = ch1 == 'm' || ch1 == 'd' ? cObj : cAspect;
X    if (!FBetween(i, 1, k)) {
X      ErrorValN("YA", i);
X      return tcError;
X    }
X    if (!FBetween(j, 1, k) || j < i) {
X      ErrorValN("YA", j);
X      return tcError;
X    }
X    if (argc <= 3+j-i) {
X      ErrorArgc("YA");
X      return tcError;
X    }
X    lpr = ch1 == 'o' ? rAspOrb : (ch1 == 'm' ? rObjOrb :
X      (ch1 == 'd' ? rObjAdd : rAspAngle));
X    for (k = i; k <= j; k++)
X      lpr[k] = atof(argv[3+k-i]);
X    darg += 3+j-i;
X    break;
X
X  case 'j':
X    if (argc <= 2 + 2*(ch1 == '0')) {
X      ErrorArgc("Yj");
X      return tcError;
X    }
X    if (ch1 == '0') {
X      rObjInf[oNorm+1] = atof(argv[1]);
X      rObjInf[oNorm+2] = atof(argv[2]);
X      rHouseInf[cSign+1]  = atof(argv[3]);
X      rHouseInf[cSign+2]  = atof(argv[4]);
X      darg += 4;
X      break;
X    }
X    k = ch1 == 'C' ? pmSign : (ch1 == 'A' ? pmAspect : pmObject);
X    i = NParseSz(argv[1], k); j = NParseSz(argv[2], k);
X    k = ch1 == 'C' ? cSign : (ch1 == 'A' ? cAspect : cObj);
X    if (!FBetween(i, 1, k)) {
X      ErrorValN("Yj", i);
X      return tcError;
X    }
X    if (!FBetween(j, 1, k) || j < i) {
X      ErrorValN("Yj", j);
X      return tcError;
X    }
X    if (argc <= 3+j-i) {
X      ErrorArgc("Yj");
X      return tcError;
X    }
X    lpr = ch1 == 'C' ? rHouseInf : (ch1 == 'A' ? rAspInf :
X      (ch1 == 'T' ? rTransitInf : rObjInf));
X    for (k = i; k <= j; k++)
X      lpr[k] = atof(argv[3+k-i]);
X    darg += 3+j-i;
X    break;
X
X  case 'J':
X    if (argc <= 3 - (ch1 == '0')) {
X      ErrorArgc("YJ");
X      return tcError;
X    }
X    i = NParseSz(argv[1], pmObject);
X    if (!FNorm(i)) {
X      ErrorValN("YJ", i);
X      return tcError;
X    }
X    j = NParseSz(argv[2], pmSign);
X    if (!FBetween(j, 0, cSign)) {
X      ErrorValN("YJ", j);
X      return tcError;
X    }
X    if (ch1 != '0') {
X      k = NParseSz(argv[3], pmSign);
X      if (!FBetween(k, 0, cSign)) {
X        ErrorValN("YJ", k);
X        return tcError;
X      }
X      ruler1[i] = j;
X      ruler2[i] = k;
X      if (FBetween(i, 1, oMain) && j != 0)
X        rules[j] = i;
X    } else
X      exalt[i] = j;
X    darg += 3 - (ch1 == '0');
X    break;
X
#ifdef INTERPRET
X  case 'I':
X    if (argc <= 2) {
X      ErrorArgc("YI");
X      return tcError;
X    }
X    i = NParseSz(argv[1],
X      ch1 == 'A' ? pmAspect : (ch1 == chNull ? pmObject : pmSign));
X    j = ch1 == 'A' ? cAspect : (ch1 == chNull ? oNorm : cSign);
X    if (!FBetween(i, 1, j)) {
X      ErrorValN("YI", i);
X      return tcError;
X    }
X    if (ch1 == 'A' && ch2 == '0')
X      ch1 = '0';
X    sz = SzPersist(argv[2]);
X    switch (ch1) {
X    case 'A':    szInteract[i]  = sz; break;
X    case '0':    szTherefore[i] = sz; break;
X    case chNull: szMindPart[i]  = sz; break;
X    case 'C':    szLifeArea[i]  = sz; break;
X    case 'v':    szDesire[i]    = sz; break;
X    default:     szDesc[i]      = sz;
X    }
X    darg += 2;
X    break;
#endif
X
X  case 'k':
X    if (argc <= 2 + 2*(ch1 == 'C')) {
X      ErrorArgc("Yk");
X      return tcError;
X    }
X    if (ch1 == 'C') {
X      kElemA[eFir] = NParseSz(argv[1], pmColor) & 15;
X      kElemA[eEar] = NParseSz(argv[2], pmColor) & 15;
X      kElemA[eAir] = NParseSz(argv[3], pmColor) & 15;
X      kElemA[eWat] = NParseSz(argv[4], pmColor) & 15;
X      darg += 4;
X      break;
X    }
X    k = ch1 == 'A' ? pmAspect : 0;
X    i = NParseSz(argv[1], k); j = NParseSz(argv[2], k);
X    k = ch1 == 'A' ? cAspect : (ch1 == '0' ? 7 : 8);
X    if (!FBetween(i, ch1 != chNull, k)) {
X      ErrorValN("Yk", i);
X      return tcError;
X    }
X    if (!FBetween(j, ch1 != chNull, k) || j < i) {
X      ErrorValN("Yk", j);
X      return tcError;
X    }
X    if (argc <= 3+j-i) {
X      ErrorArgc("Yk");
X      return tcError;
X    }
X    lpn = ch1 == 'A' ? kAspA : (ch1 == '0' ? kRainbowA : kMainA);
X    for (k = i; k <= j; k++)
X      lpn[k] = NParseSz(argv[3+k-i], pmColor) & 15;
X    darg += 3+j-i;
X    break;
X
X  case 'F':
X    if (argc <= 8) {
X      ErrorArgc("YF");
X      return tcError;
X    }
X    i = NParseSz(argv[1], pmObject);
X    if (!FItem(i)) {
X      ErrorValN("YF", i);
X      return tcError;
X    }
X    r = Mod((real)(atoi(argv[2]) +
X      (NParseSz(argv[3], pmSign)-1)*30) + atof(argv[4])/60.0);
X    if (!FCusp(i))
X      planet[i] = r;
X    else {
X      j = Mod12(i-(cuspLo-1)+6);
X      if (FBetween(i, cuspLo-1+4, cuspLo-1+9)) {
X        chouse[i-(cuspLo-1)] = r;
X        chouse[j] = Mod(r + rDegHalf);
X      } else {
X        planet[i] = r;
X        planet[cuspLo-1+j] = Mod(r + rDegHalf);
X      }
X    }
X    j = atoi(argv[5]);
X    r = (j < 0 ? -1.0 : 1.0)*((real)abs(j) + atof(argv[6])/60.0);
X    planetalt[i] = Mod((r + rDegQuad) * 2.0) / 2.0 - rDegQuad;
X    ret[i] = RFromD(atof(argv[7]));
X    if (i <= oNorm)
X      SphToRec(atof(argv[8]), planet[i], planetalt[i],
X        &spacex[i], &spacey[i], &spacez[i]);
X    MM = -1;
X    darg += 8;
X    break;
X
#ifdef GRAPH
X  case 'X':
X    return NProcessSwitchesRareX(argc, argv, pos+1);
#endif
X
X  default:
X    ErrorSwitch(argv[0]);
X    return tcError;
X  }
X  return darg;    /* Return the value to be added to argc. */
}
X
X
/* Process a command switch line passed to the program. Read each entry in */
/* the argument list and set all the program modes and charts to display.  */
X
bool FProcessSwitches(argc, argv)
int argc;
char **argv;
{
X  int ich, i, j;
X  bool fNot, fOr, fAnd;
X  real rT;
X  char ch1, ch2, *pch;
X  CI ci;
X
X  argc--; argv++;
X  while (argc) {
X    ch1 = argv[0][0];
X    fNot = fOr = fAnd = fFalse;
X    switch (ch1) {
X    case '=': fOr  = fTrue; break;
X    case '_': fAnd = fTrue; break;
X    case ':':               break;
X    default:  fNot = fTrue; break;
X    }
X    ich = 1 + FChSwitch(argv[0][0]);    /* Leading dash? */
X    ch1 = argv[0][ich];
X    ch2 = ch1 == chNull ? chNull : argv[0][ich+1];
X    switch (argv[0][ich-1]) {
X
X    case 'H':
X      if (ch1 == 'c')
X        SwitchF(us.fCredit);
X      else if (ch1 == 'Y')
X        SwitchF(us.fSwitchRare);
#ifdef ISG
X      else if (ch1 == 'X')
X        SwitchF(us.fKeyGraph);
#endif
X      else if (ch1 == 'C')
X        SwitchF(us.fSign);
X      else if (ch1 == 'O')
X        SwitchF(us.fObject);
X      else if (ch1 == 'A')
X        SwitchF(us.fAspect);
X      else if (ch1 == 'F')
X        SwitchF(us.fConstel);
X      else if (ch1 == 'S')
X        SwitchF(us.fOrbitData);
X      else if (ch1 == 'I')
X        SwitchF(us.fMeaning);
X      else if (ch1 == 'e') {
X        SwitchF(us.fCredit); SwitchF(us.fSwitch); SwitchF(us.fSwitchRare);
X        SwitchF(us.fKeyGraph); SwitchF(us.fSign); SwitchF(us.fObject);
X        SwitchF(us.fAspect); SwitchF(us.fConstel); SwitchF(us.fOrbitData);
X        SwitchF(us.fMeaning);
X      } else
X        SwitchF(us.fSwitch);
X      break;
X
X    case 'Q':
X      if (ch1 == '0')
X        SwitchF(us.fLoopInit);
X      SwitchF(us.fLoop);
X      break;
X
X    case 'M':
X      i = (ch1 == '0');
X      if (argc <= 1+i) {
X        ErrorArgc("M");
X        return fFalse;
X      }
X      j = atoi(argv[1]);
X      if (!FValidMacro(j)) {
X        ErrorValN("M", j);
X        return fFalse;
X      }
X      j--;
X      if (i)
X        szMacro[j] = SzPersist(argv[2]);
X      else
X        FProcessCommandLine(szMacro[j]);
X      argc -= 1+i; argv += 1+i;
X      break;
X
X    case 'Y':
X      i = NProcessSwitchesRare(argc, argv, ich, fOr, fAnd, fNot);
X      if (i < 0)
X        return fFalse;
X      argc -= i; argv += i;
X      break;
X
X    /* Switches which determine the type of chart to display: */
X
X    case 'v':
X      if (ch1 == '0')
X        SwitchF(us.fVelocity);
X      SwitchF(us.fListing);
X      break;
X
X    case 'w':
X      if (ch1 == '0')
X        SwitchF(us.fWheelReverse);
X      if (argc > 1 && (i = atoi(argv[1]))) {
X        argc--; argv++;
X        if (!FValidWheel(i)) {
X          ErrorValN("w", i);
X          return fFalse;
X        }
X        us.nWheelRows = i;
X      }
X      SwitchF(us.fWheel);
X      break;
X
X    case 'g':
X      if (ch1 == '0' || ch2 == '0')
X        SwitchF(us.fGridConfig);
X      if (ch1 == 'a')
X        SwitchF(us.fAppSep);
X      else if (ch1 == 'p')
X        SwitchF(us.fParallel);
#ifdef X11
X      else if (ch1 == 'e') {
X        if (argc <= 1) {
X          ErrorArgc("geometry");
X          return fFalse;
X        }
X        gs.xWin = atoi(argv[1]);
X        if (argc > 2 && (gs.yWin = atoi(argv[2]))) {
X          argc--; argv++;
X        } else
X          gs.yWin = gs.xWin;
X        if (!FValidGraphx(gs.xWin)) {
X          ErrorValN("geometry", gs.xWin);
X          return fFalse;
X        }
X        if (!FValidGraphy(gs.yWin)) {
X          ErrorValN("geometry", gs.yWin);
X          return fFalse;
X        }
X        argc--; argv++;
X        break;
X      }
#endif
X      SwitchF(us.fGrid);
X      break;
X
X    case 'a':
X      SwitchF(us.fAspList);
X      if (ch1 == '0') {
X        SwitchF(us.fAspSummary);
X        ch1 = ch2;
X      }
X      if (ch1 == 'a')
X        SwitchF(us.fAppSep);
X      else if (ch1 == 'p')
X        SwitchF(us.fParallel);
X      break;
X
X    case 'm':
X      if (ch1 == '0' || ch2 == '0')
X        SwitchF(us.fMidSummary);
X      if (ch1 == 'a')
X        SwitchF(us.fMidAspect);
X      SwitchF(us.fMidpoint);
X      break;
X
X    case 'Z':
X      if (ch1 == '0')
X        SwitchF(us.fPrimeVert);
X      else if (ch1 == 'd')
X        SwitchF(us.fHorizonSearch);
X      SwitchF(us.fHorizon);
X      break;
X
X    case 'S':
X      SwitchF(us.fOrbit);
X      break;
X
X    case 'l':
X      if (ch1 == '0')
X        SwitchF(us.fSectorApprox);
X      SwitchF(us.fSector);
X      break;
X
X    case 'j':
X      if (ch1 == '0')
X        SwitchF(us.fInfluenceSign);
X      SwitchF(us.fInfluence);
X      break;
X
X    case 'L':
X      if (ch1 == '0')
X        SwitchF(us.fLatitudeCross);
X      if (argc > 1 && (i = atoi(argv[1]))) {
X        argc--; argv++;
X        if (!FValidAstrograph(i)) {
X          ErrorValN("L", i);
X          return fFalse;
X        }
X        us.nAstroGraphStep = i;
X      }
X      SwitchF(us.fAstroGraph);
X      break;
X
X    case 'K':
X      if (ch1 == 'y')
X        SwitchF(us.fCalendarYear);
X      SwitchF(us.fCalendar);
X      break;
X
X    case 'd':
X      if (ch1 == 'p') {
X        us.fSolarArc = (ch2 == '0');
X        if (us.fSolarArc)
X          ch2 = argv[0][ich++ + 1];
X        i = (ch2 == 'y') + 2*(ch2 == 'Y');
#ifdef TIME
X        j = i < 2 && (argv[0][ich+i+1] == 'n');
#else
X        j = fFalse;
#endif
X        if (!j && argc <= 2-(i&1)) {
X          ErrorArgc("dp");
X          return fFalse;
X        }
X        is.fProgress = us.fInDayMonth = fTrue;
X        DstT = us.dstDef; ZonT = us.zonDef;
X        LonT = us.lonDef; LatT = us.latDef;
#ifdef TIME
X        if (j)
X          GetTimeNow(&MonT, &DayT, &YeaT, &TimT, ZonT-DstT);
#endif
X        if (i) {
X          MonT = 0;
X          if (!j)
X            YeaT = NParseSz(argv[1], pmYea);
X          us.nEphemYears = i == 2 ? atoi(argv[2]) : 1;
X        } else {
X          if (!j) {
X            MonT = NParseSz(argv[1], pmMon);
X            YeaT = NParseSz(argv[2], pmYea);
X            if (!FValidMon(MonT)) {
X              ErrorValN("dp", MonT);
X              return fFalse;
X            }
X          }
X        }
X        if (!FValidYea(YeaT)) {
X          ErrorValN("dp", YeaT);
X          return fFalse;
X        }
X        if (!j) {
X          i = 2-(i&1);
X          argc -= i; argv += i;
X        }
X      } else if (ch1 == 'm' || ch1 == 'y' || ch1 == 'Y') {
X        if (ch1 == 'y')
X          us.nEphemYears = 1;
X        else if (ch1 == 'Y') {
X          if (argc <= 1) {
X            ErrorArgc("dY");
X            return fFalse;
X          }
X          i = atoi(argv[1]);
X          if (i < 1) {
X            ErrorValN("dY", i);
X            return fFalse;
X          }
X          us.nEphemYears = i;
X          argc--; argv++;
X        }
X        SwitchF(us.fInDayMonth);
X        MonT = (ch1 == 'm');
X      }
#ifdef X11
X      else if (ch1 == 'i') {    /* -display switch for X */
X        if (argc <= 1) {
X          ErrorArgc("display");
X          return fFalse;
X        }
X        gs.szDisplay = SzPersist(argv[1]);
X        argc--; argv++;
X        break;
X      }
#endif
X      else if (argc > 1 && (i = atoi(argv[1]))) {
X        if (!FValidDivision(i)) {
X          ErrorValN("d", i);
X          return fFalse;
X        }
X        us.nDivision = i;
X        argc--; argv++;
X      }
X      SwitchF(us.fInDay);
X      break;
X
X    case 'D':
X      SwitchF(us.fInDayInf);
X      break;
X
X    case 'E':
X      if (ch1 == 'Y' && argc <= 1) {
X        ErrorArgc("E");
X        return fFalse;
X      }
X      SwitchF(us.fEphemeris);
X      if (ch1 == 'y')
X        us.nEphemYears = us.fEphemeris ? 1 : 0;
X      else if (ch1 == 'Y') {
X        i = atoi(argv[1]);
X        if (i < 1) {
X          ErrorValN("EY", i);
X          return fFalse;
X        }
X        us.nEphemYears = i;
X        argc--; argv++;
X      }
X      break;
X
X    case 'e':
X      SwitchF(us.fListing); SwitchF(us.fWheel);
X      SwitchF(us.fGrid); SwitchF(us.fAspList); SwitchF(us.fMidpoint);
X      SwitchF(us.fHorizon); SwitchF(us.fOrbit); SwitchF(us.fSector);
X      SwitchF(us.fCalendar); SwitchF(us.fInfluence); SwitchF(us.fAstroGraph);
X      SwitchF(us.fInDay); SwitchF(us.fInDayInf);
X      SwitchF(us.fEphemeris);
X      SwitchF(us.fGridConfig); SwitchF(us.fInfluenceSign);
X      SwitchF(us.fLatitudeCross);
X      break;
X
X    case 't':
X      SwitchF(us.fTransit);
X      ZonT = us.zonDef; DstT = us.dstDef; LonT = us.lonDef; LatT = us.latDef;
X      if (ch1 == 'p') {
X        us.fSolarArc = (ch2 == '0');
X        if (us.fSolarArc)
X          ich++;
X        is.fProgress = fTrue;
X        ch1 = argv[0][++ich];
X      }
X      if (ch1 == 'r') {
X        is.fReturn = fTrue;
X        ch1 = argv[0][++ich];
X      }
X      if (i = (ch1 == 'y') + 2*(ch1 == 'Y'))
X        ch1 = argv[0][++ich];
#ifdef TIME
X      if (ch1 == 'n') {
X        GetTimeNow(&MonT, &DayT, &YeaT, &TimT, ZonT-DstT);
X        if (i == 1)
X          MonT = 0;
X        else if (i > 1) {
X          MonT = -1; DayT = NParseSz(argv[1], pmDay);
X        }
X        break;
X      }
#endif
X      if (argc <= 2 - (i & 1)) {
X        ErrorArgc("t");
X        return fFalse;
X      }
X      if (i) {
X        if (i == 1)
X          MonT = 0;
X        else {
X          MonT = -1; DayT = NParseSz(argv[2], pmDay);
X        }
X      } else {
X        MonT = NParseSz(argv[1], pmMon);
X        if (!FValidMon(MonT)) {
X          ErrorValN("t", MonT);
X          return fFalse;
X        }
X      }
X      YeaT = NParseSz(argv[2 - (i > 0)], pmYea);
X      argc -= 2 - (i & 1); argv += 2 - (i & 1);
X      break;
X
X    case 'T':
X      SwitchF(us.fTransitInf);
X      ZonT = us.zonDef; DstT = us.dstDef; LonT = us.lonDef; LatT = us.latDef;
X      if (ch1 == 'p') {
X        is.fProgress = fTrue;
X        ch1 = argv[0][++ich];
X      }
X      if (ch1 == 'r') {
X        is.fReturn = fTrue;
X        ch1 = argv[0][++ich];
X      }
#ifdef TIME
X      if (ch1 == 'n') {
X        GetTimeNow(&MonT, &DayT, &YeaT, &TimT, ZonT-DstT);
X        break;
X      }
#endif
X      if (argc <= 3) {
X        ErrorArgc("T");
X        return fFalse;
X      }
X      MonT = NParseSz(argv[1], pmMon);
X      DayT = NParseSz(argv[2], pmDay);
X      YeaT = NParseSz(argv[3], pmYea);
X      if (!FValidMon(MonT)) {
X        ErrorValN("T", MonT);
X        return fFalse;
X      } else if (!FValidDay(DayT, MonT, YeaT)) {
X        ErrorValN("T", DayT);
X        return fFalse;
X      } else if (!FValidYea(YeaT)) {
X        ErrorValN("T", YeaT);
X        return fFalse;
X      }
X      argc -= 3; argv += 3;
X      break;
X
#ifdef ARABIC
X    case 'P':
X      if (argc > 1 && (i = atoi(argv[1]))) {
X        argc--; argv++;
X        if (!FValidPart(i)) {
X          ErrorValN("P", i);
X          return fFalse;
X        }
X        us.nArabicParts = i;
X      }
X      if (ch1 == 'z' || ch1 == 'n' || ch1 == 'f') {
X        us.nArabic = ch1;
X        ch1 = ch2;
X      } else
X        SwitchF(us.nArabic);
X      if (ch1 == '0')
X        SwitchF(us.fArabicFlip);
X      break;
#endif
X
#ifdef INTERPRET
X    case 'I':
X      if (argc > 1 && (i = atoi(argv[1]))) {
X        argc--; argv++;
X        if (!FValidScreen(i)) {
X          ErrorValN("I", i);
X          return fFalse;
X        }
X        us.nScreenWidth = i;
X      }
X      SwitchF(us.fInterpret);
X      break;
#endif
X
X    /* Switches which affect how the chart parameters are obtained: */
X
#ifdef TIME
X    case 'n':
X      FInputData(szNowCore);
X      if (ch1 == 'd')
X        TT = 0.0;
X      else if (ch1 == 'm') {
X        DD = 1; TT = 0.0;
X      } else if (ch1 == 'y') {
X        MM = DD = 1; TT = 0.0;
X      }
X      break;
#endif
X
X    case 'z':
X      if (ch1 == '0') {
X        if (argc <= 1 || RParseSz(argv[1], pmZon) == rLarge) {
X          i = us.dstDef != 0.0;
X          SwitchF(i);
X          SS = us.dstDef = i ? 1.0 : 0.0;
X        } else {
X          SS = us.dstDef = RParseSz(argv[1], pmZon);
X          if (!FValidDst(us.dstDef)) {
X            ErrorValR("z0", us.dstDef);
X            return fFalse;
X          }
X          argc--; argv++;
X        }
X        break;
X      } else if (ch1 == 'l') {
X        if (argc <= 2) {
X          ErrorArgc("zl");
X          return fFalse;
X        }
X        OO = us.lonDef = RParseSz(argv[1], pmLon);
X        AA = us.latDef = RParseSz(argv[2], pmLat);
X        if (!FValidLon(us.lonDef)) {
X          ErrorValR("zl", us.lonDef);
X          return fFalse;
X        } else if (!FValidLat(us.latDef)) {
X          ErrorValR("zl", us.latDef);
X          return fFalse;
X        }
X        argc -= 2; argv += 2;
X        break;
X      } else if (ch1 == 't') {
X        if (argc <= 1) {
X          ErrorArgc("zt");
X          return fFalse;
X        }
X        rT = RParseSz(argv[1], pmTim);
X        if (!FValidTim(rT)) {
X          ErrorValR("zt", rT);
X          return fFalse;
X        }
X        TT = rT;
X        argc--; argv++;
X        break;
X      } else if (ch1 == 'd') {
X        if (argc <= 1) {
X          ErrorArgc("zd");
X          return fFalse;
X        }
X        i = NParseSz(argv[1], pmDay);
X        if (!FValidDay(i, MM, YY)) {
X          ErrorValN("zd", i);
X          return fFalse;
X        }
X        DD = i;
X        argc--; argv++;
X        break;
X      } else if (ch1 == 'm') {
X        if (argc <= 1) {
X          ErrorArgc("zm");
X          return fFalse;
X        }
X        i = NParseSz(argv[1], pmMon);
X        if (!FValidMon(i)) {
X          ErrorValN("zm", i);
X          return fFalse;
X        }
X        MM = i;
X        argc--; argv++;
X        break;
X      } else if (ch1 == 'y') {
X        if (argc <= 1) {
X          ErrorArgc("zy");
X          return fFalse;
X        }
X        i = NParseSz(argv[1], pmYea);
X        if (!FValidYea(i)) {
X          ErrorValN("zy", i);
X          return fFalse;
X        }
X        YY = i;
X        argc--; argv++;
X        break;
X      } else if (ch1 == 'i') {
X        if (argc <= 2) {
X          ErrorArgc("zi");
X          return fFalse;
X        }
X        ciCore.nam = SzPersist(argv[1]);
X        ciCore.loc = SzPersist(argv[2]);
X        argc -= 2; argv += 2;
X        break;
X      }
X      if (argc <= 1 || RParseSz(argv[1], pmZon) == rLarge)
X        ZZ -= 1.0;
X      else {
X        ZZ = us.zonDef = RParseSz(argv[1], pmZon);
X        if (!FValidZon(us.zonDef)) {
X          ErrorValR("z", us.zonDef);
X          return fFalse;
X        }
X        argc--; argv++;
X      }
X      break;
X
X    case 'q':
X      i = (ch1 == 'y' || ch1 == 'j') + 2*(ch1 == 'm') + 3*(ch1 == 'd') +
X        4*(ch1 == chNull) + 7*(ch1 == 'a') + 8*(ch1 == 'b');
X      if (argc <= i) {
X        ErrorArgc("q");
X        return fFalse;
X      }
X      is.fHaveInfo = fTrue;
X      if (ch1 == 'j') {
X        is.JD = atof(argv[1])+rRound;
X        TT = RFract(is.JD);
X        JulianToMdy(is.JD-TT, &MM, &DD, &YY);
X        TT = DegToDec(TT * 24.0);
X        SS = ZZ = 0.0; OO = us.lonDef; AA = us.latDef;
X      } else {
X        MM = i > 1 ? NParseSz(argv[1], pmMon) : 1;
X        DD = i > 2 ? NParseSz(argv[2], pmDay) : 1;
X        YY = NParseSz(argv[3-(i<3)-(i<2)], pmYea);
X        TT = i > 3 ? RParseSz(argv[4], pmTim) : (i < 3 ? 0.0 : 12.0);
X        SS = i > 7 ? RParseSz(argv[5], pmDst) : (i > 6 ? 0.0 : us.dstDef);
X        ZZ = i > 6 ? RParseSz(argv[5 + (i > 7)], pmZon) : us.zonDef;
X        OO = i > 6 ? RParseSz(argv[6 + (i > 7)], pmLon) : us.lonDef;
X        AA = i > 6 ? RParseSz(argv[7 + (i > 7)], pmLat) : us.latDef;
X        if (!FValidMon(MM)) {
X          ErrorValN("q", MM);
X          return fFalse;
X        } else if (!FValidDay(DD, MM, YY)) {
X          ErrorValN("q", DD);
X          return fFalse;
X        } else if (!FValidYea(YY)) {
X          ErrorValN("q", YY);
X          return fFalse;
X        } else if (!FValidTim(TT)) {
X          ErrorValR("q", TT);
X          return fFalse;
X        } else if (!FValidDst(SS)) {
X          ErrorValR("q", SS);
X          return fFalse;
X        } else if (!FValidZon(ZZ)) {
X          ErrorValR("a", ZZ);
X          return fFalse;
X        } else if (!FValidLon(OO)) {
X          ErrorValR("a", OO);
X          return fFalse;
X        } else if (!FValidLat(AA)) {
X          ErrorValR("a", AA);
X          return fFalse;
X        }
X      }
X      argc -= i; argv += i;
X      break;
X
X    case 'i':
X      if (us.fNoRead) {
X        ErrorArgv("i");
X        return tcError;
X      }
X      if (argc <= 1) {
X        ErrorArgc("i");
X        return fFalse;
X      }
X      ci = ciCore;
X      if (!FInputData(argv[1]))
X        return fFalse;
X      if (ch1 == '2') {
X        ciTwin = ciCore;
X        ciCore = ci;
X      } else if (ch1 == '3') {
X        ciThre = ciCore;
X        ciCore = ci;
X      } else if (ch1 == '4') {
X        ciFour = ciCore;
X        ciCore = ci;
X      }
X      argc--; argv++;
X      break;
X
X    case '>':
X      ch1 = 's';
X      /* Fall through */
X
X    case 'o':
X      if (us.fNoWrite) {
X        ErrorArgv("o");
X        return tcError;
X      }
X      if (argc <= 1) {
X        ErrorArgc("o");
X        return fFalse;
X      }
X      if (ch1 == 's') {
X        is.szFileScreen = SzPersist(argv[1]);
X        argc--; argv++;
X        break;
X      } else if (ch1 == '0')
X        SwitchF(us.fWritePos);
X      SwitchF(us.fWriteFile);
X      is.szFileOut = SzPersist(argv[1]);
X      if (is.fSzPersist) {
X        is.rgszComment = argv;
X        do {
X          argc--; argv++;
X          is.cszComment++;
X        } while (argc > 1 && !FChSwitch(argv[1][0]));
X      }
X      break;
X
X    /* Switches which affect what information is used in a chart: */
X
X    case 'R':
X      if (ch1 == 'A') {
X        while (argc > 1 && (i = NParseSz(argv[1], pmAspect)))
X          if (!FAspect(i)) {
X            ErrorValN("RA", i);
X            return fFalse;
X          } else {
X            rAspOrb[i] = -rDegHalf;
X            argc--; argv++;
X          }
X        break;
X      }
X      if (ch1 == 'T') {
X        pch = (char *)ignore2;
X        ch1 = argv[0][++ich];
X      } else
X        pch = (char *)ignore;
X      if (ch1 == '0')
X        for (i = 1; i <= cObj; i++)
X          pch[i] = fTrue;
X      else if (ch1 == '1') {
X        for (i = 1; i <= cObj; i++)
X          pch[i] = fFalse;
X        us.fCusp = us.fUranian = us.nStar = fTrue;
X      } else if (ch1 == 'C')
X        for (i = cuspLo; i <= cuspHi; i++)
X          SwitchF(pch[i]);
X      else if (ch1 == 'u')
X        for (i = uranLo; i <= uranHi; i++)
X          SwitchF(pch[i]);
X      else if (ch1 == 'U')
X        for (i = starLo; i <= starHi; i++)
X          SwitchF(pch[i]);
X      else if (argc <= 1 || (!NParseSz(argv[1], pmObject))) {
X        for (i = oChi; i <= oVes; i++)
X          SwitchF(pch[i]);
X        for (i = oLil; i <= oEP; i++)
X          SwitchF(pch[i]);
X      }
X      while (argc > 1 && (i = NParseSz(argv[1], pmObject)))
X        if (!FItem(i)) {
X          ErrorValN("R", i);
X          return fFalse;
X        } else {
X          SwitchF(pch[i]);
X          argc--; argv++;
X        }
X      break;
X
X    case 'C':
X      SwitchF(us.fCusp);
X      break;
X
X    case 'u':
X      SwitchF(us.fUranian);
X      break;
X
X    case 'U':
X      if (ch1 == 'z' || ch1 == 'l' || ch1 == 'n' || ch1 == 'b')
X        us.nStar = ch1;
X      else
X        SwitchF(us.nStar);
X      break;
X
X    case 'A':
X      if (ch1 != 'o' && ch1 != 'm' && ch1 != 'd' && ch1 != 'a') {
X        if (argc <= 1) {
X          ErrorArgc("A");
X          return fFalse;
X        }
X        i = NParseSz(argv[1], pmAspect);
X        if (!FValidAspect(i)) {
X          ErrorValN("A", i);
X          return fFalse;
X        }
X        us.nAsp = i;
X        argc--; argv++;
X      } else {
X        if (argc <= 2) {
X          ErrorArgc("A");
X          return fFalse;
X        }
X        i = NParseSz(argv[1], ch1 == 'o' || ch1 == 'a' ? pmAspect : pmObject);
X        if (i < 1 || i > (ch1 == 'o' || ch1 == 'a' ? cAspect : oNorm)) {
X          ErrorValN("A", i);
X          return fFalse;
X        }
X        rT = RParseSz(argv[2], 0);
X        if (rT < -rDegMax || rT > rDegMax) {
X          ErrorValR("A", rT);
X          return fFalse;
X        }
X        if (ch1 == 'o')
X          rAspOrb[i] = rT;
X        else if (ch1 == 'm')
X          rObjOrb[i] = rT;
X        else if (ch1 == 'd')
X          rObjAdd[i] = rT;
X        else
X          rAspAngle[i] = rT;
X        argc -= 2; argv += 2;
X      }
X      break;
X
X    /* Switches which affect how a chart is computed: */
X
X    case 'b':
X      if (ch1 == '0')
X        SwitchF(us.fSeconds);
X      else if (ch1 == 'a')
X        SwitchF(us.fPlacalcAst);
#ifdef PLACALC
X      SwitchF(us.fPlacalc);
#endif
X      is.fSeconds = us.fSeconds;
X      break;
X
X    case 'c':
X      if (argc <= 1) {
X        ErrorArgc("c");
X        return fFalse;
X      }
X      i = NParseSz(argv[1], pmSystem);
X      if (!FValidSystem(i)) {
X        ErrorValN("c", i);
X        return fFalse;
X      }
X      us.nHouseSystem = i;
X      argc--; argv++;
X      break;
X
X    case 's':
X      if (argc > 1 && ((rT = atof(argv[1])) != 0.0 || FNumCh(argv[1][0]))) {
X        if (!FValidOffset(rT)) {
X          ErrorValR("s", rT);
X          return fFalse;
X        }
X        argc--; argv++;
X        us.rZodiacOffset = rT;
X      }
X      if (ch1 == 'r')
X        SwitchF(us.fEquator);
X      else if (ch1 == 'h')
X        us.nDegForm = 1;
X      else if (ch1 == 'd')
X        us.nDegForm = 2;
X      else if (ch1 == 'z')
X        us.nDegForm = 0;
X      else
X        SwitchF(us.fSidereal);
X      break;
X
X    case 'h':
X      if (argc > 1 && (i = NParseSz(argv[1], pmObject))) {
X        argc--; argv++;
X      } else
X        i = FSwitchF(us.objCenter != 0);
X      if (!FValidCenter(i)) {
X        ErrorValN("h", i);
X        return fFalse;
X      }
X      us.objCenter = i;
X      break;
X
X    case 'p':
X      if (fAnd) {
X        us.fProgress = fFalse;
X        break;
X      }
X      us.fSolarArc = (ch1 == '0');
X      if (us.fSolarArc)
X        ch1 = (argv[0][++ich]);
X      us.fProgress = fTrue;
#ifdef TIME
X      if (ch1 == 'n') {
X        GetTimeNow(&Mon, &Day, &Yea, &Tim, us.zonDef - us.dstDef);
X        is.JDp = MdytszToJulian(Mon, Day, Yea, Tim, us.dstDef, us.zonDef);
X        break;
X      }
#endif
X      if (ch1 == 'd') {
X        if (argc <= 1) {
X          ErrorArgc("pd");
X          return fFalse;
X        }
X        us.rProgDay = atof(argv[1]);
X        if (us.rProgDay == 0.0) {
X          ErrorValR("pd", us.rProgDay);
X          return fFalse;
X        }
X        argc--; argv++;
X        break;
X      }
X      if (argc <= 3) {
X        ErrorArgc("p");
X        return fFalse;
X      }
X      Mon = NParseSz(argv[1], pmMon);
X      Day = NParseSz(argv[2], pmDay);
X      Yea = NParseSz(argv[3], pmYea);
X      if (!FValidMon(Mon)) {
X        ErrorValN("p", Mon);
X        return fFalse;
X      } else if (!FValidDay(Day, Mon, Yea)) {
X        ErrorValN("p", Day);
X        return fFalse;
X      } else if (!FValidYea(Yea)) {
X        ErrorValN("p", Yea);
X        return fFalse;
X      }
X      is.JDp = MdytszToJulian(Mon, Day, Yea, 0.0, us.dstDef, us.zonDef);
X      argc -= 3; argv += 3;
X      break;
X
X    case 'x':
X      if (argc <= 1) {
X        ErrorArgc("x");
X        return fFalse;
X      }
X      i = atoi(argv[1]);
X      if (!FValidHarmonic(i)) {
X        ErrorValN("x", i);
X        return fFalse;
X      }
X      us.nHarmonic = i;
X      argc--; argv++;
X      break;
X
X    case '1':
X      if (argc > 1 && (i = NParseSz(argv[1], pmObject))) {
X        argc--; argv++;
X      } else
X        i = oSun;
X      if (!FItem(i)) {
X        ErrorValN("1", i);
X        return fFalse;
X      }
X      us.objOnAsc = fAnd ? 0 : i;
X      break;
X
X    case '2':
X      if (argc > 1 && (i = NParseSz(argv[1], pmObject))) {
X        argc--; argv++;
X      } else
X        i = oSun;
X      if (!FItem(i)) {
X        ErrorValN("2", i);
X        return fFalse;
X      }
X      us.objOnAsc = fAnd ? 0 : -i;
X      break;
X
X    case '3':
X      SwitchF(us.fDecan);
X      break;
X
X    case 'f':
X      SwitchF(us.fFlip);
X      break;
X
X    case 'G':
X      SwitchF(us.fGeodetic);
X      break;
X
X    case 'J':
X      SwitchF(us.fVedic);
X      break;
X
X    case '9':
X      SwitchF(us.fNavamsa);
X      break;
X
X    case 'F':
X      if (argc <= 3) {
X        ErrorArgc("F");
X        return fFalse;
X      }
X      i = NParseSz(argv[1], pmObject);
X      if (!FItem(i)) {
X        ErrorValN("F", i);
X        return fFalse;
X      }
X      force[i] = (NParseSz(argv[2], pmSign)-1.0)*30.0+DecToDeg(atof(argv[3]));
X      if (force[i] < 0.0 || force[i] >= rDegMax) {
X        ErrorValR("F", force[i]);
X        return fFalse;
X      } else
X        force[i] += rDegMax;
X      argc -= 3; argv += 3;
X      break;
X
X    case '+':
X      if (argc > 1 && (i = atoi(argv[1])) != 0) {
X        argc--; argv++;
X      } else
X        i = 1;
X      us.dayDelta += i * (ch1 == 'y' ? 365 : (ch1 == 'm' ? 30 : 1));
X      break;
X
X    case chNull:
X      if (ich <= 1)
X        break;
X      /* Fall thorugh */
X
X    case '-':
X      if (argc > 1 && (i = atoi(argv[1])) != 0) {
X        argc--; argv++;
X      } else
X        i = 1;
X      us.dayDelta -= i * (ch1 == 'y' ? 365 : (ch1 == 'm' ? 30 : 1));
X      break;
X
X    /* Switches for relationship and comparison charts: */
X
X    case 'r':
X      if (fAnd) {
X        us.nRel = 0;
X        break;
X      } else if (FBetween(ch1, '1', '4')) {
X        us.nRel = -(int)(ch1-'1');
X        break;
X      }
X      i = 2 + 2*((ch1 == 'c' || ch1 == 'm') && ch2 == '0');
X      if (argc <= i) {
X        ErrorArgc("r");
X        return fFalse;
X      }
X      if (ch1 == 'c')
X        us.nRel = rcComposite;
X      else if (ch1 == 'm')
X        us.nRel = rcMidpoint;
X      else if (ch1 == 'd')
X        us.nRel = rcDifference;
#ifdef BIORHYTHM
X      else if (ch1 == 'b')
X        us.nRel = rcBiorhythm;
#endif
X      else if (ch1 == '0')
X        us.nRel = rcDual;
X      else if (ch1 == 't')
X        us.nRel = rcTransit;
X      else if (ch1 == 'p') {
X        us.nRel = rcProgress;
X        us.fSolarArc = (ch2 == '0');
X      } else
X        us.nRel = rcSynastry;
X      ci = ciCore;
X      ciCore = ciTwin;
X      if (!FInputData(argv[2]))
X        return fFalse;
X      ciTwin = ciCore;
X      ciCore = ci;
X      if (!FInputData(argv[1]))
X        return fFalse;
X      if (i > 2) {
X        us.nRatio1 = atoi(argv[3]);
X        us.nRatio2 = atoi(argv[4]);
X        if (us.nRatio1 == us.nRatio2)
X          us.nRatio1 = us.nRatio2 = 1;
X      }
X      argc -= i; argv += i;
X      break;
X
#ifdef TIME
X    case 'y':
X      if (argc <= 1) {
X        ErrorArgc("y");
X        return fFalse;
X      }
X      if (ch1 == 'd')
X        us.nRel = rcDifference;
#ifdef BIORHYTHM
X      else if (ch1 == 'b')
X        us.nRel = rcBiorhythm;
#endif
X      else if (ch1 == 't')
X        us.nRel = rcTransit;
X      else if (ch1 == 'p') {
X        us.nRel = rcProgress;
X        us.fSolarArc = (ch2 == '0');
X      } else
X        us.nRel = rcDual;
X      if (!FInputData(szNowCore))
X        return fFalse;
X      ciTwin = ciCore;
X      if (!FInputData(argv[1]))
X        return fFalse;
X      argc--; argv++;
X      break;
#endif
X
X    /* Switches to access graphics options: */
X
X    case 'k':
X      if (ch1 == '1') {
X        us.fAnsiColor = 2;
X        us.fAnsiChar  = 1;
X      } else {
X        if (ch1 != '0')
X          SwitchF(us.fAnsiColor);
X        SwitchF(us.fAnsiChar);
X      }
X      break;
X
#ifdef PCG
X    case 'V':
X      if (argc <= 1) {
X        ErrorArgc("V");
X        return fFalse;
X      }
X      i = atoi(argv[1]);
X      if (!FValidTextrows(i)) {
X        ErrorValN("V", i);
X        return fFalse;
X      }
X      gs.nTextRows = i;
X      argc--; argv++;
X      break;
#endif
X
#ifdef GRAPH
X    case 'X':
X      if (us.fNoGraphics) {
X        ErrorArgv("X");
X        return fFalse;
X      }
X      i = NProcessSwitchesX(argc, argv, ich, fOr, fAnd, fNot);
X      if (i < 0)
X        return fFalse;
X      SwitchF2(us.fGraphics);
X      argc -= i; argv += i;
X      break;
X
#ifdef WIN
X    case 'W':
X      i = NProcessSwitchesW(argc, argv, ich, fOr, fAnd, fNot);
X      if (i < 0)
X        return fFalse;
X      argc -= i; argv += i;
X      break;
#endif
#endif /* GRAPH */
X
X    case '0':
X      while (ch1 != chNull) {
X        switch (ch1) {
X        case 'o': us.fNoWrite    = fTrue; break;
X        case 'i': us.fNoRead     = fTrue; break;
X        case 'q': us.fNoQuit     = fTrue; break;
X        case 'X': us.fNoGraphics = fTrue; break;
X        }
X        ch1 = (argv[0][++ich]);
X      }
X      break;
X
X    case ';':    /* The -; switch means don't process the rest of the line. */
X      return fTrue;
X
X    case '@':    /* The -@ switch is just a system flag indicator no-op. */
X      break;
X
X    case '.':                /* "-." is usually used to exit the -Q loop. */
X      Terminate(tcForce);
X
X    case 'B':                /* For no useful reason, -B sounds a beep. */
#ifndef WIN
X      putchar(chBell);
#else
X      MessageBeep((UINT)-1);
#endif
X      break;
X
X    default:
X      ErrorSwitch(argv[0]);
X      return fFalse;
X    }
X    argc--; argv++;
X  }
X  return fTrue;
}
X
X
/*
******************************************************************************
** Main Program.
******************************************************************************
*/
X
#ifndef WIN
#ifndef NOMAIN
/* The main program, the starting point for Astrolog, follows. This routine */
/* basically consists of a loop, inside which we read a command line, and   */
/* go process it, before actually calling a routine to do the neat stuff.   */
X
#ifdef SWITCHES
void main(argc, argv)
int argc;
char **argv;
{
#else
void main()
{
X  int argc;
X  char **argv;
#endif
X  char szCommandLine[cchSzMax], *rgsz[MAXSWITCHES];
X
X  /* Read in info from the astrolog.dat file. */
X  is.S = stdout;
X  FProcessSwitchFile(DEFAULT_INFOFILE, NULL);
X
LBegin:
#ifdef PCG
X  if (gs.nTextRows > 0) {
X    PcSetTextRows(gs.nTextRows);
X    neg(gs.nTextRows);
X  }
#endif
X  if (us.fNoSwitches) {                             /* Go prompt for    */
X    argc = NPromptSwitches(szCommandLine, rgsz);    /* switches if we   */
X    argv = rgsz;                                    /* don't have them. */
X  }
X  is.szProgName = argv[0];
X  is.fSzPersist = fTrue;
X  if (FProcessSwitches(argc, argv)) {
X    if (!us.fNoSwitches && us.fLoopInit) {
X      us.fNoSwitches = fTrue;
X      goto LBegin;
X    }
#ifdef PCG
X    if (gs.nTextRows > 0) {
X      PcSetTextRows(gs.nTextRows);
X      neg(gs.nTextRows);
X    }
#endif
X    Action();
X  }
X  if (us.fLoop || us.fNoQuit) { /* If -Q in effect loop back and get switch */
X    PrintL2();                  /* info for another chart to display.       */
X    InitVariables();
X    us.fLoop = us.fNoSwitches = fTrue;
X    goto LBegin;
X  }
X  Terminate(tcOK);    /* The only standard place to exit Astrolog is here. */
}
#endif /* NOMAIN */
#endif /* WIN */
X
/* astrolog.c */
SHAR_EOF
  $shar_touch -am 1223232998 'astrolog.c' &&
  chmod 0644 'astrolog.c' ||
  echo 'restore of astrolog.c failed'
  shar_count="`wc -c < 'astrolog.c'`"
  test 48352 -eq "$shar_count" ||
    echo "astrolog.c: original size 48352, current size $shar_count"
fi
# ============= astrolog.dat ==============
if test -f 'astrolog.dat' && test X"$1" != X"-c"; then
  echo 'x - skipping astrolog.dat (File already exists)'
else
  echo 'x - extracting astrolog.dat (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'astrolog.dat' &&
@0308  ; Astrolog (5.40) default settings file astrolog.dat
X
-z0 0             ; Default Daylight time setting   [0 standard, 1 daylight]
-z +8:00          ; Default time zone               [hours before GMT      ]
-zl 122W20 47N36  ; Default longitude and latitude
X
-Yz 0   ; Time minute addition to be used when "now" charts are off.
;-n      ; Uncomment this line to start with the chart for "now".
X
_s      ; Zodiac selection          ["_s" is tropical, "=s" is sidereal]
:s 0    ; Zodiac offset value       [Change "0" to desired offset      ]
-A 5    ; Number of aspects         [Change "5" to desired number      ]
-c 0    ; House system              [Change "0" to desired system      ]
_k      ; Ansi color text           ["=k" is color, "_k" is normal     ]
:d 12   ; Searching divisions       [Change "12" to desired divisions  ]
_b0     ; Print zodiac seconds      ["_b0" to minute, "=b0" to second  ]
_b      ; Use ephemeris files       ["=b" uses them, "_b" doesn't      ]
=C      ; Show house cusp objects   ["_C" hides them, "=C" shows them  ]
:w 4    ; Wheel chart text rows     [Change "4" to desired wheel rows  ]
:I 80   ; Text screen columns       [Change "80" to desired columns    ]
-YQ 0   ; Text screen scroll limit  [Change "24" or set to "0" for none]
_Yd     ; European date format      ["_Yd" is MDY, "=Yd" is DMY        ]
_Yt     ; European time format      ["_Yt" is AM/PM, "=Yt" is 24 hour  ]
=YC     ; Smart cusp displays       ["=YC" is smart, "_YC" is normal   ]
_Y8     ; Clip text to end of line  ["=Y8" clips, "_Y8" doesn't clip   ]
X
X
; DEFAULT RESTRICTIONS:
X
-YR 1 10     0 0 0 0 0 0 0 0 0 0      ; Planets
-YR 11 20    0 0 0 0 0 0 0 0 0 0      ; Minor planets
-YR 21 32    0 1 1 1 1 1 1 1 1 0 1 1  ; House cusps
-YR 33 40    0 0 0 0 0 0 0 0          ; Uranians
X
; DEFAULT TRANSIT RESTRICTIONS:
X
-YRT 1 10    0 1 0 0 0 0 0 0 0 0      ; Planets
-YRT 11 20   0 0 0 0 0 0 0 1 1 1      ; Minor planets
-YRT 21 32   1 1 1 1 1 1 1 1 1 1 1 1  ; House cusps
-YRT 33 40   0 0 0 0 0 0 0 0          ; Uranians
X
-YR0 0 0  ; Restrict sign, direction changes
X
X
; DEFAULT ASPECT ORBS:
X
-YAo 1 5     7.0 7.0 7.0 7.0 6.0          ; Major aspects
-YAo 6 11    3.0 3.0 3.0 3.0 2.0 2.0      ; Minor aspects
-YAo 12 18   1.0 1.0 1.0 1.0 1.0 1.0 1.0  ; Obscure aspects
X
; DEFAULT MAX PLANET ASPECT ORBS:
X
-YAm 1 10    360 360 360 360 360 360 360 360 360 360
-YAm 11 20   360 360 360 360 360   2   2 360 360   2
-YAm 21 32   360 360 360 360 360 360 360 360 360 360 360 360
-YAm 33 40   360 360 360 360 360 360 360 360
X
; DEFAULT PLANET ASPECT ORB ADDITIONS:
X
-YAd 1 10    1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
-YAd 11 20   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
-YAd 21 32   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
X
X
; DEFAULT INFLUENCES:
X
-Yj 1 10    30 25 10 10 10 10 10 10 10 10        ; Planets
-Yj 11 20   5 5 5 5 5 5 5 5 5 5                  ; Minor planets
-Yj 21 32   20 10 10 10 10 10 10 10 10 15 10 10  ; Cusp objects
-Yj 33 40   3 3 3 3 3 3 3 3                      ; Uranians
X
-YjC 1 12   20 0 0 10 0 0 5 0 0 15 0 0  ; Houses
X
-YjA 1 5    1.0 0.8 0.8 0.6 0.6          ; Major aspects
-YjA 6 11   0.4 0.4 0.2 0.2 0.2 0.2      ; Minor aspects
-YjA 12 18  0.1 0.1 0.1 0.1 0.1 0.1 0.1  ; Obscure aspects
X
; DEFAULT TRANSIT INFLUENCES:
X
-YjT 1 10    10 4 8 9 20 30 35 40 45 50  ; Planets
-YjT 11 20   30 15 15 15 15 30 1 1 1 1   ; Minor planets
-YjT 33 40   50 50 50 50 50 50 50 50     ; Uranians
X
-Yj0 20 10 15 5 ; In ruling sign, exalted sign, ruling house, exalted house.
X
X
; DEFAULT COLORS:
X
-YkC 9 11 10 12                 ; Element colors
-YkA 1 18  11 12 9 10 14 13 13 3 3 6 6 6 1 5 5 1 1 5  ; Aspect colors
-Yk0 1 7   9 3 11 10 14 12 5    ; Rainbow colors
-Yk  0 8   0 15 7 8 1 2 6 4 13  ; Main colors
X
X
; GRAPHICS DEFAULTS:
X
_X              ; Graphics chart flag ["_X" is text, "=X" is graphics]
:Xw 480 480     ; Default X and Y resolution
:Xbb            ; Bitmap file type
:YXG 1111       ; Glyph selections
:YXg 20         ; Aspect grid cells
:YXf 0          ; Use actual fonts
:YXp 0          ; PostScript paper orientation
:YXp0 8.5 11.0  ; PostScript paper X and Y inch sizes
:YX -1 16       ; PC hi-res and lo-res graphics modes
X
; astrolog.dat
SHAR_EOF
  $shar_touch -am 1223232998 'astrolog.dat' &&
  chmod 0644 'astrolog.dat' ||
  echo 'restore of astrolog.dat failed'
  shar_count="`wc -c < 'astrolog.dat'`"
  test 4196 -eq "$shar_count" ||
    echo "astrolog.dat: original size 4196, current size $shar_count"
fi
# ============= astrolog.def ==============
if test -f 'astrolog.def' && test X"$1" != X"-c"; then
  echo 'x - skipping astrolog.def (File already exists)'
else
  echo 'x - extracting astrolog.def (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'astrolog.def' &&
; Astrolog (Version 5.40) File: astrolog.def
;
; IMPORTANT NOTICE: The graphics database and chart display routines
; used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
; (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
; Permission is granted to freely use and distribute these routines
; provided one doesn't sell, restrict, or profit from them in any way.
; Modification is allowed provided these notices remain with any
; altered or edited versions of the program.
;
; The main planetary calculation routines used in this program have
; been Copyrighted and the core of this program is basically a
; conversion to C of the routines created by James Neely as listed in
; Michael Erlewine's 'Manual of Computer Programming for Astrologers',
; available from Matrix Software. The copyright gives us permission to
; use the routines for personal use but not to sell them or profit from
; them in any way.
;
; The PostScript code within the core graphics routines are programmed
; and Copyright (C) 1992-1993 by Brian D. Willoughby
; (brianw@sounds.wa.com). Conditions are identical to those above.
;
; The extended accurate ephemeris databases and formulas are from the
; calculation routines in the program "Placalc" and are programmed and
; Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
; (alois@azur.ch). The use of that source code is subject to
; regulations made by Astrodienst Zurich, and the code is not in the
; public domain. This copyright notice must not be changed or removed
; by any user of this program.
;
; Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
; X Window graphics initially programmed 10/23-29/1991.
; PostScript graphics initially programmed 11/29-30/1992.
; Last code change made 4/11/1998.
;
NAME        ASTROLOG
DESCRIPTION "Astrolog 5.40 for MS Windows - By Walter D. Pullen"
EXETYPE     WINDOWS
STUB        'WINSTUB.EXE' 
CODE        PRELOAD MOVEABLE DISCARDABLE
DATA        PRELOAD MOVEABLE
HEAPSIZE    4096
EXPORTS     WndProc @1
X            DlgAbortProc @2
X
;
; astrolog.def
SHAR_EOF
  $shar_touch -am 1223232998 'astrolog.def' &&
  chmod 0644 'astrolog.def' ||
  echo 'restore of astrolog.def failed'
  shar_count="`wc -c < 'astrolog.def'`"
  test 2092 -eq "$shar_count" ||
    echo "astrolog.def: original size 2092, current size $shar_count"
fi
# ============= astrolog.h ==============
if test -f 'astrolog.h' && test X"$1" != X"-c"; then
  echo 'x - skipping astrolog.h (File already exists)'
else
  echo 'x - extracting astrolog.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'astrolog.h' &&
/*
** Astrolog (Version 5.40) File: astrolog.h
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
/*
** TO COMPILE: For most systems, especially Unix, DOS, and Macs, the only
** changes that should need to be made to the code are to edit or comment the
** #define's below to equal the particulars of your own system and locale:
**
** SYSTEM SECTION: These settings describe platform and hardware specifics.
** They are all required to be set properly or the program likely won't
** compile or run. Some of these are technically optional and can be
** commented out even if your system would normally support them, e.g.
** the X11 graphics can be disabled even if you are running X windows.
*/
X
/*#define PC /* Comment out this #define if you have a Unix, Mac, or other */
X           /* system that isn't a generic PC running DOS or MS Windows.  */
X
/*#define MAC /* Comment out this #define if you're not compiling for a Mac. */
X
#define X11 /* Comment out this #define if you don't have X windows, or */
X            /* else have them and don't wish to compile in X graphics.  */
X
/*#define WIN /* Comment out this #define if you don't have MS Windows, or */
X            /* else have them but want to compile a DOS version instead. */
X
/*#define MSG /* Comment out this #define if you don't have access to the     */
X            /* Microsoft C PC graphics library as in graph.h, or you do and */
X            /* have a PC and just don't wish to compile these graphics in.  */
X
/*#define BGI /* Comment out this #define if you don't have access to the  */
X            /* Borland C BGI graphics library for PC's in graphics.h, or */
X            /* you do and just don't wish to compile such graphics in.   */
X
/*#define MACG /* Comment out this #define if you don't have a Mac, or else  */
X             /* have one and don't wish to compile in Mac screen graphics. */
X
#define MOUSE /* Comment out this #define if you don't have a mouse, or    */
X              /* don't wish to compile in mouse tracking features. This is */
X              /* only valid if X11, WIN, MSG, BGI, or MACG above are set.  */
X
#define TIME /* Comment out this #define if your compiler can't take the  */
X             /* calls to the 'time' or 'localtime' functions as in time.h */
X
#define SWITCHES /* Comment out this #define if your system can not handle */
X                 /* parameters on the command line (such as Mac's).        */
X
#define ENVIRON /* Comment out this #define if your system doesn't have  */
X                /* environment variables or can't compile calls to them. */
X
/*#define ATOF /* Comment out this #define if you have a system in which  */
X             /* 'atof' and related functions aren't defined in stdio.h, */
X             /* such as most PC's, Linux, VMS compilers, and NeXT's.    */
X
/*#define PROTO /* Comment out this #define if you have an older compiler   */
X              /* which doesn't allow full Ansi function prototypes. This  */
X              /* is for programmers only and has no effect on executable. */
X
/*
** FEATURES SECTION: These settings describe features that are always
** available to be compiled into the program no matter what platform or
** hardware is available. Their settings are always optional.
*/
X
#define GRAPH /* Comment out this #define if you don't want any graphics   */
X              /* in the program. This switch allows at least generation of */
X              /* bitmap files and must be set if any of the more advanced  */
X              /* graphics feature additions are also compiled in.          */
X
#define PLACALC /* Comment out this #define if you don't want the more */
X                /* accurate calculation features and formulas to be    */
X                /* compiled into the program (as accessed with -b).    */
X
#define PS /* Comment out this #define if you don't want the ability to */
X           /* generate charts in the PostScript graphics format.        */
X
#define META /* Comment out this #define if you don't want the ability to  */
X             /* generate charts in the MS Windows metafile picture format. */
X
#define INTERPRET /* Comment out this #define if you don't want the ability */
X                  /* to display interpretations of the various chart types. */
X
#define ARABIC /* Comment out this #define if you don't want any chart     */
X               /* lists that include Arabic parts included in the program. */
X
#define CONSTEL /* Comment out this #define if you don't want any of the */
X                /* astronomical constellation charts in the program.     */
X
#define BIORHYTHM /* Comment out this #define if you don't want the    */
X                  /* non-astrological biorhythm charts in the program. */
X
/*
** DATA CONFIGURATION SECTION: These settings describe particulars of
** your own location and where the program looks for certain info. It is
** recommended that these values be changed appropriately, although the
** program will still run if they are left alone.
*/
X
#ifndef PC
#define DEFAULT_DIR "~/astrolog"
#else
#define DEFAULT_DIR "C:\\ASTROLOG"
#endif
X  /* Change this string to directory path program should look in for the  */
X  /* astrolog.dat default file, if one is not in the current directory or */
X  /* in the dirs indicated by environment variables. For PC systems, use  */
X  /* two backslashes instead of one forward one to divide subdirectories. */
X
#define CHART_DIR DEFAULT_DIR
X  /* This string is the directory the program looks in for chart info    */
X  /* files (-i switch) if not in the current directory. This is normally */
X  /* the default dir above but may be changed to be somewhere else.      */
X
#define EPHE_DIR DEFAULT_DIR
X  /* This string is the directory the program looks in for the ephemeris */
X  /* files as accessed with the -b switch. This is normally the default  */
X  /* dir above but may be changed to be somewhere else.                  */
X
#define DEFAULT_LONG 122.20 /* Change these values to the longitude west    */
#define DEFAULT_LAT   47.36 /* and latitude north of your current location. */
X                            /* Use negative values for east/southern areas. */
X
#define DEFAULT_ZONE 8.00 /* Change this number to the time zone of your */
X                          /* current location in hours before (west of)  */
X                          /* GMT. Use negative values for eastern zones. */
X
/*
** OPTIONAL CONFIGURATION SECTION: Although not necessary, one may like
** to change some of the values below: These constants affect some of
** the default parameters and other such things.
*/
X
#define DEFAULT_SYSTEM 0 /* Normally, Placidus houses are used (unless the */
X                         /* user specifies otherwise). If you want a       */
X                         /* different default system, change this number   */
X                         /* to a value from 0..9 (values same as in -c).   */
X
#define DEFAULT_ASPECTS 5 /* Default number of aspects to use in charts. */
X
#define DIVISIONS 12 /* Greater numbers means more accuracy but slower  */
X                     /* calculation, of exact aspect and transit times. */
X
#define DEFAULT_INFOFILE "astrolog.dat"
X  /* Name of file to look in for default program parameters (which will */
X  /* override the compile time values here, if the file exists).        */
X
#define ENVIRONALL "ASTROLOG"
#define ENVIRONVER "ASTR"
X  /* Name of environment variables to look in for chart, ephemeris, and  */
X  /* default files. The second name is a version specific variable which */
X  /* gets the current version appended to it before it is accessed.      */
X
#define WHEELCOLS 15   /* Affects width of each house in wheel display.    */
#define WHEELROWS 11   /* Max no. of objects that can be in a wheel house. */
#define SCREENWIDTH 80 /* Number of columns to print interpretations in.   */
#define MONTHSPACE 3   /* Number of spaces between each calendar column.   */
#define MAXINDAY 150   /* Max number of aspects or transits displayable.   */
#define MAXCROSS 750   /* Max number of latitude crossings displayable.    */
#define CREDITWIDTH 74 /* Number of text columns in the -Hc credit screen. */
#define MAXSWITCHES 32 /* Max number of switch parameters per input line.  */
#define PSGUTTER 9     /* Points of white space on PostScript page edge.   */
X
X
#ifdef GRAPH           /* For graphics, this char affects how bitmaps are */
#ifndef PC             /* written. 'N' is written like with the 'bitmap'  */
#define BITMAPMODE 'C' /* program, 'C' is compacted somewhat (files have  */
#else                  /* less spaces), and 'V' is compacted even more.   */
#define BITMAPMODE 'B' /* 'A' means write as rectangular Ascii text file. */
#endif                 /* 'B' means write as Windows bitmap (.bmp) file.  */
X
#ifdef MSG
#define DEFHIRESMODE _MAXRESMODE /* 'High-resolution' PC graphics mode. */
#define DEFLORESMODE _ERESCOLOR  /* 'Flicker-free' PC graphics mode.    */
#endif
#ifdef BGI
#define DEFHIRESMODE 0 /* Zero or less means a 'hi-res' mode of driver. */
#define DEFLORESMODE 1 /* One or more means a 'lo-res' mode of driver.  */
#endif
#endif /* GRAPH */
X
/*#define TRUENODE /* Comment out this #define if you'd prefer the 'Node'    */
X                 /* object to refer to the Mean North Node of the Moon by  */
X                 /* default as opposed to the True North Node of the Moon. */
X
/*
** By the time you reach here and the above values are customized as
** desired, Astrolog is ready to be compiled! Be sure to similarly
** change the values in the astrolog.dat file, which will override any
** corresponding compile time values here. Don't change any of the
** values in the section below unless you know what you're doing.
*/
X
#ifdef GRAPH
#define BITMAPX    2730 /* Maximum window size allowed */
#define BITMAPY    2730
#define BITMAPX1    180 /* Minimum window size allowed */
#define BITMAPY1    180
#define DEFAULTX    480 /* Default window size */
#define DEFAULTY    480
#define SIDESIZE    160 /* Size of wheel chart information sidebar.    */
#define MAXMETA 200000L /* Max bytes allowed in a metafile.            */
#define METAMUL      12 /* Metafile coordinate to chart pixel ratio.   */
#define PSMUL        11 /* PostScript coordinate to chart pixel ratio. */
#define CELLSIZE     14 /* Size for each cell in the aspect grid.      */
#define BIODAYS      14 /* Days to include in graphic biorhythms.      */
#define DEGINC        2 /* Number of degrees per segment for circles.  */
#define DEFORB      7.0 /* Min distance glyphs can be from each other. */
#define MAXSCALE    400 /* Max scale factor as passed to -Xs swtich.   */
#define TILTSTEP  11.25 /* Degrees to change when pressing '[' or ']'. */
#endif /* GRAPH */
X
#define chH    (char)(us.fAnsiChar ? 196 : '-')    /* Ansi and Ascii       */
#define chV    (char)(us.fAnsiChar ? 179 : '|')    /* characters used to   */
#define chC    (char)(us.fAnsiChar ? 197 : '|')    /* display text charts. */
#define chNW   (char)(us.fAnsiChar ? 218 : '+')
#define chNE   (char)(us.fAnsiChar ? 191 : '+')
#define chSW   (char)(us.fAnsiChar ? 192 : '+')
#define chSE   (char)(us.fAnsiChar ? 217 : '+')
#define chJN   (char)(us.fAnsiChar ? 193 : '-')
#define chJS   (char)(us.fAnsiChar ? 194 : '-')
#define chJW   (char)(us.fAnsiChar ? 180 : '|')
#define chJE   (char)(us.fAnsiChar ? 195 : '|')
#define chDeg0 (char)(us.fAnsiChar ? 248 : ' ')
#define chDeg1 (char)(us.fAnsiChar ? 248 : ':')
X
X
/*
** One shouldn't ever need to change anything below this line to compile.
*/
X
#define ASTROLOG
#define MATRIX
/*#define BETA /* Uncomment to compile in beta message on startup. */
#include <stdio.h>
#ifndef ATOF
#include <stdlib.h>
#endif
#include <math.h>
#ifdef PC
#include <malloc.h>
#endif
#ifdef TIME
#include <time.h>
#endif
X
#ifdef X11
#define ISG
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif
#ifdef WIN
#define ISG
#include "windows.h"
#include "commdlg.h"
#include "print.h"
#include "resource.h"
#endif
#ifdef MSG
#define ISG
#define PCG
#include <graph.h>
#include <conio.h>
#endif
#ifdef BGI
#define ISG
#define PCG
#include <graphics.h>
#include <conio.h>
#endif
#ifdef MACG
#define ISG
#endif
X
#ifdef PS
#define STROKE
#endif
#ifdef META
#define STROKE
#endif
#ifdef MOUSE
#ifdef PC
#include <dos.h>
#endif
#endif /* MOUSE */
X
X
/*
** Make sure only legal combinations of the graphics options are active.
*/
X
#ifdef MAC
#ifdef SWITCHES
"If 'MAC' is defined 'SWITCHES' must not be as well"
#endif
#ifdef ENVIRON
"If 'MAC' is defined 'ENVIRON' must not be as well"
#endif
#endif /* MAC */
X
#ifdef X11
#ifndef GRAPH
"If 'X11' is defined 'GRAPH' must be too"
#endif
#ifdef WIN
"If 'X11' is defined 'WIN' must not be as well"
#endif
#ifdef MSG
"If 'X11' is defined 'MSG' must not be as well"
#endif
#ifdef BGI
"If 'X11' is defined 'BGI' must not be as well"
#endif
#ifdef MACG
"If 'X11' is defined 'MACG' must not be as well"
#endif
#ifdef PC
"If 'X11' is defined 'PC' must not be as well"
#endif
#endif /* X11 */
X
#ifdef WIN
#ifndef GRAPH
"If 'WIN' is defined 'GRAPH' must be too"
#endif
#ifdef X11
"If 'WIN' is defined 'X11' must not be as well"
#endif
#ifdef MSG
"If 'WIN' is defined 'MSG' must not be as well"
#endif
#ifdef BGI
"If 'WIN' is defined 'BGI' must not be as well"
#endif
#ifdef MACG
"If 'WIN' is defined 'MACG' must not be as well"
#endif
#ifndef PC
"If 'WIN' is defined 'PC' must be too"
#endif
#endif /* WIN */
X
#ifdef MSG
#ifndef GRAPH
"If 'MSG' is defined 'GRAPH' must be too"
#endif
#ifdef X11
"If 'MSG' is defined 'X11' must not be as well"
#endif
#ifdef WIN
"If 'MSG' is defined 'WIN' must not be as well"
#endif
#ifdef BGI
"If 'MSG' is defined 'BGI' must not be as well"
#endif
#ifdef MACG
"If 'MSG' is defined 'MACG' must not be as well"
#endif
#ifndef PC
"If 'MSG' is defined 'PC' must be too"
#endif
#endif /* MSG */
X
#ifdef BGI
#ifndef GRAPH
"If 'BGI' is defined 'GRAPH' must be too"
#endif
#ifdef X11
"If 'BGI' is defined 'X11' must not be as well"
#endif
#ifdef WIN
"If 'BGI' is defined 'WIN' must not be as well"
#endif
#ifdef MSG
"If 'BGI' is defined 'MSG' must not be as well"
#endif
#ifdef MACG
"If 'BGI' is defined 'MACG' must not be as well"
#endif
#ifndef PC
"If 'BGI' is defined 'PC' must be too"
#endif
#endif /* BGI */
X
#ifdef MACG
#ifndef GRAPH
"If 'MACG' is defined 'GRAPH' must be too"
#endif
#ifndef MAC
"If 'MACG' is defined 'MAC' must be too"
#endif
#ifdef X11
"If 'MACG' is defined 'X11' must not be as well"
#endif
#ifdef WIN
"If 'MACG' is defined 'WIN' must not be as well"
#endif
#ifdef MSG
"If 'MACG' is defined 'MSG' must not be as well"
#endif
#ifdef BGI
"If 'MACG' is defined 'BGI' must not be as well"
#endif
#ifdef PC
"If 'MACG' is defined 'PC' must not be as well"
#endif
#endif /* MACG */
X
#ifdef MOUSE
#ifdef GRAPH
#ifndef ISG
"If 'MOUSE' is defined 'X11', 'WIN', 'MSG', 'BGI', or 'MACG' must be too"
#endif
#endif /* GRAPH */
#endif /* MOUSE */
X
#ifdef PS
#ifndef GRAPH
"If 'PS' is defined 'GRAPH' must be too"
#endif
#endif /* PS */
X
#ifdef META
#ifndef GRAPH
"If 'META' is defined 'GRAPH' must be too"
#endif
#endif /* META */
X
X
/*
******************************************************************************
** Program Constants.
******************************************************************************
*/
X
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE  1
#endif
#define fFalse FALSE
#define fTrue  TRUE
X
#define szAppNameCore "Astrolog"
#define szVersionCore "5.40"
#define szDateCore    "December, 1998"
#define szAddressCore \
X  "Astara@msn.com - http://www.magitech.com/~cruiser1/astrolog.htm"
#define szNowCore     "now"
#define szTtyCore     "tty"
#define szSetCore     "set"
#define szNulCore     "nul"
X
#define cchSzDef   80
#define cchSzMax   255
#define nDegMax    360
#define nDegHalf   180
#define yeaJ2G     1582
#define monJ2G     mOct
#define dayJ2G1    4
#define dayJ2G2    15
X
#define rPi        3.14159265358979323846
#define rPi2       (rPi*2.0)
#define rPiHalf    (rPi/2.0)
#define rDegMax    360.0
#define rDegHalf   180.0
#define rDegQuad   90.0
#define rDegRad    (rDegHalf/rPi)
#define rEpoch2000 (-24.736467)
#define rAxis      23.44578889
#define rSmall     (1.7453E-09)
#define rLarge     10000.0
#define rRound     0.5
X
#define chNull     '\0'
#define chEscape   '\33'
#define chBell     '\7'
#define chReturn   '\r'
#define chTab      '\t'
#define chDelete   '\b'
#define chBreak    '\3'
#define chRet      'R'
X
/* Array index limits */
X
#define cSign      12
#define cObj       87
#define cObjInt    uranHi
#define objMax     (cObj+1)
#define cAspect    18
#define cAspectInt 11
#define cSystem    15
#define cCnstl     88
#define cZone      69
#define cSector    36
#define cPart      177
#define cAspConfig 6
#define cWeek      7
#define cColor     16
#define xFont      6
#define yFont      10
#define xFontT     (xFont*gi.nScaleT)
#define yFontT     (yFont*gi.nScaleT)
#define xSideT     (SIDESIZE*gi.nScaleT)
X
/* Object array index values */
X
#define cPlanet oVes
#define cThing  oLil
#define oMain   10
#define oCore   20
#define cUran   8
#define cStar   47
#define cuspLo  21
#define cuspHi  32
#define uranLo  33
#define uranHi  40
#define oNorm   uranHi
#define starLo  41
#define starHi  cObj
X
/* Month index values */
X
#define mJan 1
#define mFeb 2
#define mMar 3
#define mApr 4
#define mMay 5
#define mJun 6
#define mJul 7
#define mAug 8
#define mSep 9
#define mOct 10
#define mNov 11
#define mDec 12
X
/* Elements */
X
#define eFir 0
#define eEar 1
#define eAir 2
#define eWat 3
X
/* Zodiac signs */
X
#define sAri 1
#define sTau 2
#define sGem 3
#define sCan 4
#define sLeo 5
#define sVir 6
#define sLib 7
#define sSco 8
#define sSag 9
#define sCap 10
#define sAqu 11
#define sPis 12
X
/* Objects */
X
#define oEar 0
#define oSun 1
#define oMoo 2
#define oMer 3
#define oVen 4
#define oMar 5
#define oJup 6
#define oSat 7
#define oUra 8
#define oNep 9
#define oPlu 10
#define oChi 11
#define oCer 12
#define oVes 15
#define oNod 16
#define oLil 17
#define oSou 17
#define oFor 18
#define oVtx 19
#define oEP  20
#define oAsc 21
#define oNad 24
#define oDes 27
#define oMC  30
#define oOri (starLo-1+10)
#define oAnd (starLo-1+47)
X
/* Aspects */
X
#define aDir -2
#define aSig -1
#define aCon 1
#define aOpp 2
#define aSqu 3
#define aTri 4
#define aSex 5
#define aInc 6
#define aSSx 7
#define aSSq 8
#define aSes 9
#define aQui 10
#define aBQn 11
X
/* Biorhythm cycle constants */
X
#define brPhy 23.0
#define brEmo 28.0
#define brInt 33.0
X
/* Relationship chart modes */
X
#define rcSynastry   1
#define rcComposite  2
#define rcMidpoint   3
#define rcDifference 4
#define rcBiorhythm  5
#define rcDual      -1
#define rcTriWheel  -2
#define rcQuadWheel -3
#define rcTransit   -4
#define rcProgress  -5
X
/* Aspect configurations */
X
#define acS  1
#define acGT 2
#define acTS 3
#define acY  4
#define acGC 5
#define acC  6
X
/* Graphics chart modes */
X
#define gWheel      1
#define gHouse      2
#define gGrid       3
#define gHorizon    4
#define gOrbit      5
#define gSector     6
#define gCalendar   7
#define gDisposit   8
#define gAstroGraph 9
#define gEphemeris 10
#define gWorldMap  11
#define gGlobe     12
#define gPolar     13
#define gBiorhythm 14
#ifdef WIN
#define gAspect    15
#define gMidpoint  16
#define gArabic    17
#define gSign      18
#define gObject    19
#define gHelpAsp   20
#define gConstel   21
#define gPlanet    22
#define gMeaning   23
#define gSwitch    24
#define gObscure   25
#define gKeystroke 26
#define gCredit    27
#define gRising    28
#define gTraTraHit 29
#define gTraTraInf 30
#define gTraNatHit 31
#define gTraNatInf 32
#endif
X
/* Colors */
X
#define kReverse -2
#define kDefault -1
#define kBlack   0
#define kMaroon  1
#define kDkGreen 2
#define kOrange  3
#define kDkBlue  4
#define kPurple  5
#define kDkCyan  6
#define kLtGray  7
#define kDkGray  8
#define kRed     9
#define kGreen   10
#define kYellow  11
#define kBlue    12
#define kMagenta 13
#define kCyan    14
#define kWhite   15
#define kNull    16
X
/* Arabic parts */
X
#define apFor 0
#define apSpi 1
X
/* Draw text formatting flags */
X
#define dtCent   0x0
#define dtLeft   0x1
#define dtBottom 0x2
#define dtErase  0x4
#define dtScale  0x8
#define dtTop    0x10
X
/* User string parse modes */
X
#define pmMon     1
#define pmDay     2
#define pmYea     3
#define pmTim     4
#define pmDst     5
#define pmZon     6
#define pmLon     7
#define pmLat     8
#define pmObject  9
#define pmAspect 10
#define pmSystem 11
#define pmSign   12
#define pmColor  13
X
/* PC mouse flags */
X
#define mfLeft   0x01
#define mfRight  0x02
#define mfMiddle 0x04
X
/* Termination codes */
X
#define tcError -1
#define tcOK    0
#define tcFatal 1
#define tcForce 2
X
#ifndef _ZRES256COLOR
#define _ZRES256COLOR 263
#endif
X
X
/*
******************************************************************************
** Macro Functions.
******************************************************************************
*/
X
#define BLo(w) ((byte)(w))
#define BHi(w) ((byte)((word)(w) >> 8 & 0xFF))
#define WLo(l) ((word)(dword)(l))
#define WHi(l) ((word)((dword)(l) >> 16 & 0xFFFF))
#define WFromBB(bLo, bHi) ((word)BLo(bLo) | (word)((byte)(bHi)) << 8)
#define LFromWW(wLo, wHi) ((dword)WLo(wLo) | (dword)((word)(wHi)) << 16)
#define LFromBB(b1, b2, b3, b4) LFromWW(WFromBB(b1, b2), WFromBB(b3, b4))
#ifndef WIN
#define RGB(bR, bG, bB) \
X  ((dword)((byte)(bR) | (word)(bG)<<8 | (dword)(byte)(bB)<<16))
#endif
#define RGBR(l) BLo(l)
#define RGBG(l) BHi(l)
#define RGBB(l) ((byte)((dword)(l) >> 16 & 0xFF))
#define ChHex(n) (char)((n) < 10 ? '0' + (n) : 'a' + (n) - 10)
#define VgaFromEga(x) NMultDiv((x), 480, 350)
#define VgaFromCga(x) NMultDiv((x), 480, 200)
X
#define Max(v1, v2) ((v1) > (v2) ? (v1) : (v2))
#define Min(v1, v2) ((v1) < (v2) ? (v1) : (v2))
#define NSgn(n) ((n) < 0 ? -1 : (n) > 0)
#define RSgn2(r) ((r) < 0.0 ? -1.0 : 1.0)
#define FBetween(v, v1, v2) ((v) >= (v1) && (v) <= (v2))
#define RFract(r) ((r) - RFloor(r))
#define ChCap(ch) ((ch) >= 'a' && (ch) <= 'z' ? (ch) - 'a' + 'A' : (ch))
#define ChUncap(ch) (FCapCh(ch) ? (ch) - 'A' + 'a' : (ch))
#define FCapCh(ch) ((ch) >= 'A' && (ch) <= 'Z')
#define FNumCh(ch) ((ch) >= '0' && (ch) <= '9')
#define NMultDiv(n1, n2, n3) ((int)((long)(n1) * (n2) / (n3)))
#define Ratio(v1, v2, v3) ((v1) + ((v2) - (v1)) * (v3))
#define ZFromS(s) ((real)(((s)-1)*30))
#define SFromZ(r) (((int)(r))/30+1)
#define RFromD(r) ((r)/rDegRad)
#define DFromR(r) ((r)*rDegRad)
#define GFromO(o) ((rDegMax - planet[o])/10.0)
#define RAbs(r) fabs(r)
#define RFloor(r) floor(r)
#define NFloor(r) ((int)RFloor(r))
#define RSqr(r) sqrt(r)
#define RSin(r) sin(r)
#define RCos(r) cos(r)
#ifndef PC
#define RTan(r) tan(r)
#else
/* The tangent function in some PC compilers returns a result the negative */
/* of what it should be when doing emulation for a non-math chip machine.  */
#define RTan(r) (sin(r)/cos(r))
#endif
#define RAtn(r) atan(r)
#define RAsin(r) asin(r)
#define RAcos(r) acos(r)
#define RSinD(r) RSin(RFromD(r))
#define RCosD(r) RCos(RFromD(r))
#define NSinD(nR, nD) ((int)((real)(nR)*RSinD((real)nD)))
#define NCosD(nR, nD) ((int)((real)(nR)*RCosD((real)nD)))
X
#define FItem(obj)    FBetween(obj, 0, cObj)
#define FNorm(obj)    FBetween(obj, 0, oNorm)
#define FCusp(obj)    FBetween(obj, cuspLo, cuspHi)
#define FAngle(obj)   (FCusp(obj) && (obj)%3 == 0)
#define FMinor(obj)   (FCusp(obj) && (obj)%3 != 0)
#define FUranian(obj) FBetween(obj, uranLo, uranHi)
#define FStar(obj)    FBetween(obj, starLo, starHi)
#define FObject(obj)  ((obj) <= oVes || (obj) >= uranLo)
#define FThing(obj)   ((obj) <= cThing || (obj) >= uranLo)
#define FHelio(obj)   (FNorm(obj) && FObject(obj) && (obj) != oMoo)
#define FAspect(asp)  FBetween(asp, 1, us.nAsp)
#define FSector(s)    FBetween(s, 1, cSector)
#define ChDst(dst)    (dst == 0.0 ? 'S' : (dst == 1.0 ? 'D' : 'A'))
#define ChDashF(f)    (f ? '=' : '_')
#define SzNumF(f)     (f ? "1 " : "0 ")
#define DayInYearHi(yea) (365-28+DayInMonth(2, yea))
#define FChSwitch(ch) \
X  ((ch) == '-' || (ch) == '/' || (ch) == '_' || (ch) == '=' || (ch) == ':')
X
#define FValidMon(mon) FBetween(mon, 1, 12)
#define FValidDay(day, mon, yea) ((day) >= 1 && (day) <= DayInMonth(mon, yea))
#define FValidYea(yea) FBetween(yea, -20000, 20000)
#define FValidTim(tim) ((tim) > -2.0 && (tim) < 24.0 && \
X  RFract(RAbs(tim)) < 0.60)
#define FValidDst(dst) FValidZon(dst)
#define FValidZon(zon) FBetween(zon, -24.0, 24.0)
#define FValidLon(lon) FBetween(lon, -rDegHalf, rDegHalf)
#define FValidLat(lat) FBetween(lat, -rDegQuad, rDegQuad)
#define FValidAspect(asp) FBetween(asp, 0, cAspect)
#define FValidSystem(n) FBetween(n, 0, cSystem-1)
#define FValidDivision(n) FBetween(n, 1, 2880)
#define FValidOffset(r) FBetween(r, -rDegMax, rDegMax)
#define FValidCenter(obj) \
X  (FBetween(obj, oEar, uranHi) && FObject(obj) && (obj) != oMoo)
#define FValidHarmonic(n) FBetween(n, 1, 30000)
#define FValidWheel(n) FBetween(n, 1, WHEELROWS)
#define FValidAstrograph(n) (n > 0 && 160%n == 0)
#define FValidPart(n) FBetween(n, 1, cPart)
#define FValidBioday(n) FBetween(n, 1, 199)
#define FValidScreen(n) FBetween(n, 20, 200)
#define FValidMacro(n) FBetween(n, 1, 48)
#define FValidTextrows(n) ((n) == 25 || (n) == 43 || (n) == 50)
#define FValidGlyphs(n) FBetween(n, 0, 2223)
#define FValidGrid(n) FBetween(n, 1, cObj)
#define FValidScale(n) (FBetween(n, 100, MAXSCALE) && (n)%100 == 0)
#define FValidGraphx(x) (FBetween(x, BITMAPX1, BITMAPX) || (x) == 0)
#define FValidGraphy(y) (FBetween(y, BITMAPY1, BITMAPY) || (y) == 0)
#define FValidRotation(n) FBetween(n, 0, nDegMax-1)
#define FValidTilt(n) FBetween(n, -rDegQuad, rDegQuad)
#define FValidColor(n) FBetween(n, 0, cColor - 1)
#define FValidBmpmode(ch) \
X  ((ch) == 'N' || (ch) == 'C' || (ch) == 'V' || (ch) == 'A' || (ch) == 'B')
#define FValidTimer(n) FBetween(n, 1, 32000)
X
#define chSig3(A) szSignName[A][0], szSignName[A][1], szSignName[A][2]
#define chObj3(A) szObjName[A][0], szObjName[A][1], szObjName[A][2]
#define chMon3(A) szMonth[A][0], szMonth[A][1], szMonth[A][2]
#define chDay3(A) szDay[A][0], szDay[A][1], szDay[A][2]
#define kSignA(s) kElemA[(s)-1 & 3]
#define kSignB(s) kElemB[(s)-1 & 3]
#define kModeA(m) kElemA[m <= 1 ? m : eWat]
#define szPerson  (ciMain.nam[0] ? ciMain.nam : "This person")
#define szPerson0 (ciMain.nam[0] ? ciMain.nam : "the person")
#define szPerson1 (ciMain.nam[0] ? ciMain.nam : "Person1")
#define szPerson2 (ciTwin.nam[0] ? ciTwin.nam : "Person2")
#define FIgnore(i) (ignore[i] || (i) == us.objCenter)
#define FIgnore2(i) (ignore2[i] || (i) == us.objCenter)
#define fSouthNode (!us.fPlacalc)
#define fNoTimeOrSpace (Mon == -1)
X
#define loop for (;;)
#define not(V) V = !(V)
#define neg(V) V = -(V)
#define PrintL() PrintCh('\n')
#define PrintL2() PrintSz("\n\n")
#define PrintF(sz) fprintf(file, sz)
#define PrintFSz() fprintf(file, sz)
#define SwapN(n1, n2) (n1)^=(n2)^=(n1)^=(n2)
#define FSwitchF(f) ((((f) | fOr) & !fAnd) ^ fNot)
#define SwitchF(f) f = FSwitchF(f)
#define SwitchF2(f) f = (((f) | (fOr || fNot)) & !fAnd)
#define SetCI(ci, M, D, Y, T, S, Z, O, A) \
X  ci.mon = M; ci.day = D; ci.yea = Y; \
X  ci.tim = T; ci.dst = S; ci.zon = Z; ci.lon = O; ci.lat = A
X
#ifndef PC
#define chDirSep '/'
#define chSwitch '-'
#define CONST
#define NPTR
#define FPTR
#define HPTR
#define AllocateNear(p, cb) (p) = (void *)malloc(cb)
#define AllocateFar(p, cb)  AllocateNear(p, cb)
#define AllocateHuge(p, cb) AllocateFar(p, cb)
#define DeallocateNear(p) free(p)
#define DeallocateFar(p)  DeallocateNear(p)
#define DeallocateHuge(p) DeallocateFar(p)
#ifndef MAC
#define ldTime 2440588L
#else
#define ldTime 2416481L
#endif
#define ARR
#else /* PC */
#define chDirSep '\\'
#define chSwitch '/'
#define CONST const
#define EXPORT _export
#ifndef WIN
#define NPTR near
#define FPTR far
#else
#define NPTR
#define FPTR
#endif
#define HPTR huge
#define AllocateNear(p, cb) (p) = malloc(cb)
#define AllocateFar(p, cb)  (p) = _fmalloc(cb)
#define AllocateHuge(p, cb) (p) = halloc(cb, sizeof(byte))
#define DeallocateNear(p) free(p)
#define DeallocateFar(p)  _ffree(p)
#define DeallocateHuge(p) hfree(p)
#define ldTime 2440588L
#ifndef __TURBOC__
#define ARR
#else
#define ARR far
#endif
#endif /* PC */
X
#ifdef GRAPH
#ifdef WIN
#define API FAR PASCAL
#define hdcNil ((HDC)NULL)
#endif
#ifdef MSG
#define xPcScreen gi.cfg.numxpixels
#define yPcScreen gi.cfg.numypixels
#define FValidResmode(n) FBetween(n, _MAXRESMODE, _ZRES256COLOR)
#define FEgaRes(res) (res == _ERESNOCOLOR || res == _ERESCOLOR)
#define FCgaRes(res) (res == _HRESBW || res == _HRES16COLOR)
#define PcMoveTo(x, y) _moveto(x, y)
#define PcLineTo(x, y) _lineto(x, y)
#define PcSetTextRows(n) _settextrows(gs.nTextRows)
#endif
#ifdef BGI
#define xPcScreen (getmaxx()+1)
#define yPcScreen (getmaxy()+1)
#define FValidResmode(n) FBetween(n, -500, 500)
#define FEgaRes(res) (yPcScreen == 350)
#define FCgaRes(res) (yPcScreen == 200)
#define PcMoveTo(x, y) moveto(x, y)
#define PcLineTo(x, y) lineto(x, y)
#define PcSetTextRows(n) if ((n) > 25) textmode(C4350)
#endif
X
/* Should an object in the outer wheel be restricted? */
#define FProper2(i) \
X  (!(us.nRel == rcTransit ? ignore2[i] : ignore[i]) && i != us.objCenter)
X
/* Are particular coordinates on the chart? */
#define FInRect(x, y, x1, y1, x2, y2) \
X  ((x) >= (x1) && (x) < (x2) && (y) >= (y1) && (y) < (y2))
#define FOnWin(X, Y) FInRect((X), (Y), 0, 0, gs.xWin, gs.yWin)
X
/* Get a coordinate based on chart radius, a fraction, and (co)sin value. */
#define POINT1(U, R, S) ((int)(((U)+1.4)*(R)*(S)))
#define POINT2(U, R, S) ((int)(((U)-0.3)*(R)*(S)))
X
/* Determine (co)sin factors based on zodiac angle and chart orientation. */
#define PX(A) RCosD(A)
#define PY(A) RSinD(A)
#define PZ(A) PlaceInX(A)
X
/* Compute Mollewide projection in pixel scale given latitude. */
#define NMollewide(y) \
X  ((int)(RSqr((real)(180L*nScl*180L*nScl - 4L*(y)*nScl*(y)*nScl))+rRound))
X
/* Do settings indicate the current chart should have the info sidebar? */
#define fSidebar ((gi.nMode == gWheel || gi.nMode == gHouse || \
X  gi.nMode == gSector) && gs.fText && !us.fVelocity)
X
/* Is the current chart most properly displayed as a square graphic? */
#define fSquare \
X  (gi.nMode == gWheel || gi.nMode == gHouse || gi.nMode == gGrid || \
X  (gi.nMode == gHorizon && us.fPrimeVert) || gi.nMode == gDisposit || \
X  gi.nMode == gOrbit || gi.nMode == gGlobe || gi.nMode == gPolar)
X
/* Does the current chart have to be displayed in a map rectangle? */
#define fMap \
X  (gi.nMode == gAstroGraph || gi.nMode == gWorldMap)
X
/* Do settings indicate the current chart should have an outer border? */
#define fDrawBorder \
X  ((gs.fBorder || gi.nMode == gGrid) && gi.nMode != gGlobe && \
X  gi.nMode != gPolar && (gi.nMode != gWorldMap || !gs.fMollewide))
X
/* Do settings indicate current chart should have chart info at its bottom? */
#define fDrawText \
X  (gs.fText && gi.nMode != gCalendar && gi.nMode != gWorldMap && \
X  gi.nMode != gGlobe && gi.nMode != gPolar && ((gi.nMode != gWheel && \
X  gi.nMode != gHouse && gi.nMode != gSector) || us.fVelocity))
#endif /* GRAPH */
X
X
/*
******************************************************************************
** Type Definitions.
******************************************************************************
*/
X
#define byte  unsigned char
#define word  unsigned short
#define dword unsigned long
#define word4 long
#define real  double
#define _char unsigned char
#define _int  unsigned int
#define bool  int
#define _bool char
#define lpbyte byte FPTR *
#define hpbyte byte HPTR *
#define lpreal real FPTR *
X
typedef struct _GridInfo {
X  byte  n[objMax][objMax];
X  short v[objMax][objMax];
} GridInfo;
X
typedef struct _CrossInfo {
X  real lat[MAXCROSS];
X  real lon[MAXCROSS];
X  int obj1[MAXCROSS];
X  int obj2[MAXCROSS];
} CrossInfo;
X
#ifdef GRAPH
#define KV unsigned long
#define KI int
#endif /* GRAPH */
X
typedef struct _UserSettings {
X
X  /* Chart types */
X  _bool fListing;       /* -v */
X  _bool fWheel;         /* -w */
X  _bool fGrid;          /* -g */
X  _bool fAspList;       /* -a */
X  _bool fMidpoint;      /* -m */
X  _bool fHorizon;       /* -Z */
X  _bool fOrbit;         /* -S */
X  _bool fSector;        /* -l */
X  _bool fInfluence;     /* -j */
X  _bool fAstroGraph;    /* -L */
X  _bool fCalendar;      /* -K */
X  _bool fInDay;         /* -d */
X  _bool fInDayInf;      /* -D */
X  _bool fEphemeris;     /* -E */
X  _bool fTransit;       /* -t */
X  _bool fTransitInf;    /* -T */
X
X  /* Chart suboptions */
X  _bool fVelocity;      /* -v0 */
X  _bool fWheelReverse;  /* -w0 */
X  _bool fGridConfig;    /* -g0 */
X  _bool fAppSep;        /* -ga */
X  _bool fParallel;      /* -gp */
X  _bool fAspSummary;    /* -a0 */
X  _bool fMidSummary;    /* -m0 */
X  _bool fMidAspect;     /* -ma */
X  _bool fPrimeVert;     /* -Z0 */
X  _bool fHorizonSearch; /* -Zd */
X  _bool fSectorApprox;  /* -l0 */
X  _bool fInfluenceSign; /* -j0 */
X  _bool fLatitudeCross; /* -L0 */
X  _bool fCalendarYear;  /* -Ky */
X  _bool fInDayMonth;    /* -dm */
X  _bool fArabicFlip;    /* -P0 */
X
X  /* Table chart types */
X  _bool fCredit;        /* -Hc */
X  _bool fSwitch;        /* -H  */
X  _bool fSwitchRare;    /* -Y  */
X  _bool fKeyGraph;      /* -HX */
X  _bool fSign;          /* -HC */
X  _bool fObject;        /* -HO */
X  _bool fAspect;        /* -HA */
X  _bool fConstel;       /* -HF */
X  _bool fOrbitData;     /* -HS */
X  _bool fMeaning;       /* -HI */
X
X  /* Main flags */
X  _bool fLoop;        /* -Q */
X  _bool fSidereal;    /* -s */
X  _bool fCusp;        /* -C */
X  _bool fUranian;     /* -u */
X  _bool fProgress;    /* Are we doing a -p progressed chart?           */
X  _bool fInterpret;   /* Is -I interpretation switch in effect?        */
X  _bool fDecan;       /* -3 */
X  _bool fFlip;        /* -f */
X  _bool fGeodetic;    /* -G */
X  _bool fVedic;       /* -J */
X  _bool fNavamsa;     /* -9 */
X  _bool fPlacalc;     /* -b */
X  _bool fWriteFile;   /* -o */
X  _bool fAnsiColor;   /* -k */
X  _bool fGraphics;    /* -X */
X
X  /* Main subflags */
X  _bool fNoSwitches;
X  _bool fLoopInit;    /* -Q0 */
X  _bool fSeconds;     /* -b0 */
X  _bool fPlacalcAst;  /* -ba */
X  _bool fEquator;     /* -sr */
X  _bool fSolarArc;    /* -p0 */
X  _bool fWritePos;    /* -o0 */
X  _bool fAnsiChar;    /* -k0 */
X
X  /* Rare flags */
X  _bool fTrueNode;    /* -Yn */
X  _bool fEuroDate;    /* -Yd */
X  _bool fEuroTime;    /* -Yt */
X  _bool fSmartCusp;   /* -YC */
X  _bool fClip80;      /* -Y8 */
X  _bool fWriteOld;    /* -Yo */
X  _bool fHouseAngle;  /* -Yc */
X  _bool fIgnoreSign;  /* -YR0 */
X  _bool fIgnoreDir;   /* -YR0 */
X  _bool fNoWrite;     /* -0o */
X  _bool fNoRead;      /* -0i */
X  _bool fNoQuit;      /* -0q */
X  _bool fNoGraphics;  /* -0X */
X
X  /* Value settings */
X  int   nEphemYears;  /* -Ey */
X  int   nArabic;      /* -P */
X  int   nRel;         /* What relationship chart are we doing, if any? */
X  int   nHouseSystem; /* -c */
X  int   nAsp;         /* -A */
X  int   objCenter;    /* -h */
X  int   nStar;        /* -U */
X  int   nHarmonic;    /* Harmonic chart value passed to -x switch.     */
X  int   objOnAsc;     /* House value passed to -1 or -2 switch.        */
X  int   dayDelta;     /* -+, -- */
X  int   nDegForm;     /* -s */
X  int   nDivision;    /* -d */
X  int   nScreenWidth; /* -I */
X  real  dstDef;       /* -z0 */
X  real  zonDef;       /* -z  */
X  real  lonDef;       /* -l  */
X  real  latDef;       /* -l  */
X
X  /* Value subsettings */
X  int   nWheelRows;      /* Number of rows per house to use for -w wheel. */
X  int   nAstroGraphStep; /* Latitude step rate passed to -L switch.       */
X  int   nArabicParts;    /* Arabic parts to include value passed to -P.   */
X  real  rZodiacOffset;   /* Position shifting value passed to -s switch.  */
X  real  rProgDay;        /* Progression day value passed to -pd switch.   */
X  int   nRatio1;         /* Chart ratio factors passed to -rc or -rm.     */
X  int   nRatio2;
X  int   nScrollRow;      /* -YQ */
X  long  lTimeAddition;   /* -Yz */
X  int   nArabicNight;    /* -YP */
X  int   nBioday;         /* -Yb */
} US;
X
typedef struct _InternalSettings {
X  _bool fHaveInfo;    /* Do we need to prompt user for chart info?         */
X  _bool fProgress;    /* Are we doing a chart involving progression?       */
X  _bool fReturn;      /* Are we doing a transit chart for returns?         */
X  _bool fMult;        /* Have we already printed at least one text chart?  */
X  _bool fSeconds;     /* Do we print locations to nearest second?          */
X  _bool fSzPersist;   /* Are parameter strings persistent when processing? */
X  _bool fSzInteract;  /* Are we in middle of chart so some setting fixed?  */
X  _bool fNoEphFile;   /* Have we already had a ephem file not found error? */
X  char *szProgName;   /* The name and path of the executable running.      */
X  char *szFileScreen; /* The file to send text output to as passed to -os. */
X  char *szFileOut;    /* The output chart filename string as passed to -o. */
X  char **rgszComment; /* Points to any comment strings after -o filename.  */
X  int cszComment;     /* The number of strings after -o that are comments. */
X  int cchCol;         /* The current column text charts are printing at.   */
X  int cchRow;         /* The current row text charts have scrolled to.     */
X  real rSid;          /* Sidereal offset degrees to be added to locations. */
X  real JD;            /* Fractional Julian day for current chart.          */
X  real JDp;           /* Julian day that a progressed chart indicates.     */
X  FILE *S;  /* File to write text to.   */
X  real T;   /* Julian time for chart.   */
X  real MC;  /* Midheaven at chart time. */
X  real Asc; /* Ascendant at chart time. */
X  real RA;  /* Right ascension at time. */
X  real OB;  /* Obliquity of ecliptic.   */
} IS;
X
typedef struct _ChartInfo {
X  int mon;   /* Month            */
X  int day;   /* Day              */
X  int yea;   /* Year             */
X  real tim;  /* Time in hours    */
X  real dst;  /* Daylight offset  */
X  real zon;  /* Time zone        */
X  real lon;  /* Longitude        */
X  real lat;  /* Latitude         */
X  char *nam; /* Name for chart   */
X  char *loc; /* Name of location */
} CI;
X
typedef struct _ChartPositions {
X  real obj[objMax];   /* The zodiac positions.    */
X  real alt[objMax];   /* Ecliptic declination.    */
X  real dir[objMax];   /* Retrogradation velocity. */
X  real cusp[cSign+1]; /* House cusp positions.    */
X  byte house[objMax]; /* House each object is in. */
} CP;
X
#ifdef GRAPH
typedef struct _GraphicsSettings {
X  _bool fBitmap;    /* Are we creating a bitmap file (-Xb set).         */
X  _bool fPS;        /* Are we generating a PostScript file (-Xp set).   */
X  _bool fMeta;      /* Are we generating a metafile graphic (-XM set).  */
X  _bool fColor;     /* Are we drawing a color chart (-Xm not set).      */
X  _bool fInverse;   /* Are we drawing in reverse video (-Xr set).       */
X  _bool fRoot;      /* Are we drawing on the X11 background (-XB set).  */
X  _bool fText;      /* Are we printing chart info on chart (-XT set).   */
X  _bool fFont;      /* Are we simulating fonts in charts (-XM0 set).    */
X  _bool fAlt;       /* Are we drawing in alternate mode (-Xi set).      */
X  _bool fBorder;    /* Are we drawing borders around charts (-Xu set).  */
X  _bool fLabel;     /* Are we labeling objects in charts (-Xl not set). */
X  _bool fJetTrail;  /* Are we not clearing screen on updates (-Xj set). */
X  _bool fMouse;     /* Are we not considering PC mouse inputs.          */
X  _bool fConstel;   /* Are we drawing maps as constellations (-XF set). */
X  _bool fMollewide; /* Are we drawing maps scaled correctly (-XW0 set). */
X  _bool fPrintMap;  /* Are we printing globe names on draw (-XP0 set).  */
X  int xWin;         /* Current size of graphic chart (-Xw).      */
X  int yWin;
X  int nAnim;        /* Current animation mode, if any (-Xn).     */
X  int nScale;       /* Current character scale factor (-Xs).     */
X  int objLeft;      /* Current object to place on Asc (-X1).     */
X  int nTextRows;    /* Numb. of rows to set text screen to (-V). */
X  int nRot;         /* Current rotation degree of globe.         */
X  real rTilt;       /* Current vertical tilt of rotating globe.  */
X  char chBmpMode;   /* Current bitmap file type (-Xb).           */
X  int nOrient;      /* PostScript paper orientation indicator.   */
X  real xInch;       /* PostScript horizontal paper size inches.  */
X  real yInch;       /* PostScript vertical paper size inches.    */
X  char *szDisplay;  /* Current X11 display name (-Xd).           */
X  int nGridCell;    /* Number of cells in -g grids (-Yg).        */
X  int nGlyphs;      /* Settings for what gylphs to use (-YG).    */
#ifdef PCG
X  int nResHi;       /* 'High-resolution' graphics mode. */
X  int nResLo;       /* 'Flicker-free' graphics mode.    */
#endif
} GS;
X
typedef struct _GraphicsInternal {
X  int nMode;            /* Current type of chart to create.           */
X  _bool fMono;          /* Is this a monochrome monitor.              */
X  int kiCur;            /* Current color drawing with.                */
X  hpbyte bm;            /* Pointer to allocated memory.               */
X  int cbBmpRow;         /* Horizontal size of bitmap array in memory. */
X  char *szFileOut;      /* Current name of bitmap file (-Xo).         */
X  FILE *file;           /* Actual file handle writing graphics to.    */
X  int yBand;            /* Vertical offset to current bitmap band.    */
X  real rAsc;            /* Degree to be at left edge in wheel charts. */
X  _bool fFile;          /* Are we making a graphics file.             */
X  int nScale;           /* Scale ratio, i.e. percentage / 100.        */
X  int nScaleT;          /* Relative scale to draw chart text at.      */
X  int nPenWid;          /* Pen width to use when creating metafiles.  */
X  KI kiOn;              /* Foreground color. */
X  KI kiOff;             /* Background color. */
X  KI kiLite;            /* Hilight color.    */
X  KI kiGray;            /* A "dim" color.    */
X  int xOffset;          /* Viewport origin.                           */
X  int yOffset;
X  int xTurtle;          /* Current coordinates of drawing pen.        */
X  int yTurtle;
X  int xPen;             /* Cached coordinates where last line ended.  */
X  int yPen;
#ifdef X11
X  Display *disp;        /* The opened X11 display (-Xd). */
X  GC gc, pmgc;
X  Pixmap pmap, icon;
X  Window wind, root;
X  int screen;
X  int depth;            /* Number of active color bits.  */
#endif
#ifdef PS               /* Variables used by the PostScript generator. */
X  _bool fEps;           /* Are we doing Encapsulated PostScript.    */
X  int cStroke;          /* Number of items drawn without fluahing.  */
X  _bool fLineCap;       /* Are line ends rounded instead of square. */
X  int nDash;            /* How much long are dashes in lines drawn. */
X  int nFont;            /* What system font are we drawing text in. */
X  real rLineWid;        /* How wide are lines, et al, drawn with.   */
#endif
#ifdef META             /* Variables used by the metafile generator.  */
X  word HPTR *pwMetaCur; /* Current mem position when making metafile. */
X  word HPTR *pwPoly;    /* Position for start of current polyline.    */
X  long cbMeta;
X  KI kiLineAct;         /* Desired and actual line color. */
X  KI kiLineDes;
X  KI kiFillAct;         /* Desired and actual fill color. */
X  KI kiFillDes;
X  int nFontAct;         /* Desired and actual text font.  */
X  int nFontDes;
X  KI kiTextAct;         /* Desired and actual text color. */
X  KI kiTextDes;
X  int nAlignAct;        /* Desired/actual text alignment. */
X  int nAlignDes;
#endif
#ifdef MSG              /* MS graphics PC specific global variables.  */
X  int nRes;             /* Current graphics mode.                     */
X  struct videoconfig cfg;          /* State of current graphics mode. */
#endif
#ifdef BGI              /* Borland BGI PC specific global variables.  */
X  int nRes;             /* Current graphics mode.              */
X  _bool fLoaded;        /* Have we loaded the graphics driver. */
X  int nDriver;          /* Current graphics driver.            */
X  int nGraph;           /* Current mode within driver.         */
X  int nPages;           /* Number of pages in current mode.    */
X  int nPageCur;         /* The current page bring drawn in.    */
#endif
#ifdef MACG
X  WindowPtr wpAst;
X  Rect rcDrag;
X  Rect rcBounds;
#endif
} GI;
#endif /* GRAPH */
X
typedef struct _ArabicInfo {
X  char *form;                 /* The formula to calculate it. */
X  char *name;                 /* The name of the Arabic part. */
} AI;
X
typedef struct _ElementTable {
X  int coSum;            /* Total objects considered.          */
X  int coHemi;           /* Number that can be in hemispheres. */
X  int coSign[cSign];    /* Number of objects in each sign.    */
X  int coHouse[cSign];   /* Number of objects in each house.   */
X  int coElemMode[4][3]; /* Objects in each elem/mode combo.   */
X  int coElem[4];        /* Object in each element.            */
X  int coMode[3];        /* Objects in each sign mode.         */
X  int coModeH[3];       /* Objects in each house mode.        */
X  int coYang;           /* Objects in Fire/Air signs.         */
X  int coYin;            /* Objects in Earth/Water signs.      */
X  int coLearn;          /* Objects in first six signs.        */
X  int coShare;          /* Objects in last six signs.         */
X  int coAsc;            /* Objects in Eastern houses.         */
X  int coDes;            /* Objects in Western houses.         */
X  int coMC;             /* Objects in Southern houses.        */
X  int coIC;             /* Objects in Northern houses.        */
} ET;
X
typedef struct _OrbitalElements {
X  real ma0, ma1, ma2; /* Mean anomaly.           */
X  real ec0, ec1, ec2; /* Eccentricity.           */
X  real sma;           /* Semi-major axis.        */
X  real ap0, ap1, ap2; /* Argument of perihelion. */
X  real an0, an1, an2; /* Ascending node.         */
X  real in0, in1, in2; /* Inclination.            */
} OE;
X
#ifdef WIN
#define nScrollDiv 24
#define nScrollPage 6
#define cchSzMaxFile 128
#define szFileTempCore "ASTROLOG.TMP"
X
typedef struct _WindowInternal {
X  HWND hinst;     /* Instance of the Astrolog window class.    */
X  HWND hwndMain;  /* The outer created frame window.           */
X  HWND hwnd;      /* The current window being dealt with.      */
X  HMENU hmenu;    /* The Astrolog main menu bar.               */
X  HACCEL haccel;  /* Keyboard accelerator or shortcut table.   */
X  HDC hdc;        /* The current DC bring drawn upon.          */
X  HDC hdcPrint;   /* The current DC being printed upon.        */
X  HWND hwndAbort; /* Window of the printing abort dialog.      */
X  HPEN hpen;      /* Pen with the current line color.          */
X  HBRUSH hbrush;  /* Fill if any with the current color.       */
X  HFONT hfont;    /* Font of current text size being printed.  */
X  UINT nTimer;    /* Identifier for the animation timer.       */
X  short xScroll;  /* Horizontal & vertical scrollbar position. */
X  short yScroll;
X  short xClient;  /* Horizontal & vertical window size. */
X  short yClient;
X  int xChar;      /* Horizontal & vertical font character size. */
X  int yChar;
X  int xMouse;     /* Horitontal & vertical mouse position. */
X  int yMouse;
X  WORD wCmd;      /* The currently invoked menu command.        */
X  int nMode;      /* New chart type to switch to if any.        */
X  bool fMenu;     /* Do we need to repaint the menu bar?        */
X  bool fMenuAll;  /* Do we need to redetermine all menu checks? */
X  bool fRedraw;   /* Do we need to redraw the screen?           */
X  bool fCast;     /* Do we need to recast the chart positions?  */
X  bool fAbort;    /* Did the user cancel printing in progress?  */
X  int nDlgChart;  /* Which chart to set in Open or Info dialog. */
X
X  /* Window User settings. */
X  bool fPause;       /* Is animation paused?                   */
X  bool fBuffer;      /* Are we drawing updates off screen?     */
X  bool fHourglass;   /* Bring up hourglass cursor on redraws?  */
X  bool fChartWindow; /* Does chart change cause window resize? */
X  bool fWindowChart; /* Does window resize cause chart change? */
X  bool fNoUpdate;    /* Do we not automatically update screen? */
X  KI kiPen;          /* The current pen scribble color.        */
X  int nDir;          /* Animation step factor and direction.   */
X  UINT nTimerDelay;  /* Milliseconds between animation draws.  */
} WI;
#endif
X
#include "extern.h"
X
/* astrolog.h */
SHAR_EOF
  $shar_touch -am 1223232998 'astrolog.h' &&
  chmod 0644 'astrolog.h' ||
  echo 'restore of astrolog.h failed'
  shar_count="`wc -c < 'astrolog.h'`"
  test 50005 -eq "$shar_count" ||
    echo "astrolog.h: original size 50005, current size $shar_count"
fi
# ============= astrolog.rc ==============
if test -f 'astrolog.rc' && test X"$1" != X"-c"; then
  echo 'x - skipping astrolog.rc (File already exists)'
else
  echo 'x - extracting astrolog.rc (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'astrolog.rc' &&
//Microsoft App Studio generated resource script.
//
#include "resource.h"
X
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
X
/////////////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
X
#ifdef APSTUDIO_INVOKED
//////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
X
1 TEXTINCLUDE DISCARDABLE 
BEGIN
X    "resource.h\0"
END
X
2 TEXTINCLUDE DISCARDABLE 
BEGIN
X    "#include ""afxres.h""\r\n"
X    "\0"
END
X
3 TEXTINCLUDE DISCARDABLE 
BEGIN
X    "\r\n"
X    "\0"
END
X
/////////////////////////////////////////////////////////////////////////////////////
#endif    // APSTUDIO_INVOKED
X
X
//////////////////////////////////////////////////////////////////////////////
//
// Icon
//
X
icon                    ICON    DISCARDABLE     "ASTRLOG1.ICO"
icon2                   ICON    DISCARDABLE     "ASTRLOG2.ICO"
icon3                   ICON    DISCARDABLE     "ASTRLOG3.ICO"
icon4                   ICON    DISCARDABLE     "ASTRLOG4.ICO"
X
//////////////////////////////////////////////////////////////////////////////
//
// Menu
//
X
menu MENU DISCARDABLE 
BEGIN
X    POPUP "&File"
X    BEGIN
X        MENUITEM "&Open Chart...\tAlt+o",       cmdOpenChart
X        MENUITEM "Open Chart #&2...\tAlt+O",    cmdOpenChart2
X        MENUITEM SEPARATOR
X        MENUITEM "&Save Chart Info...\tAlt+w",  cmdSaveChart
X        MENUITEM "Save Chart &Positions...\tAlt+W",cmdSavePositions
X        MENUITEM SEPARATOR
X        MENUITEM "Save Chart &Text Output...\tCtrl+5",cmdSaveText
X        MENUITEM "Save Chart &Bitmap...\tCtrl+6",cmdSaveBitmap
X        MENUITEM "Save Chart Pi&cture...\tCtrl+7",cmdSavePicture
X        MENUITEM "Save Chart P&ostScript...\tCtrl+8",cmdSavePS
X        MENUITEM SEPARATOR
X        MENUITEM "Save Settin&gs...\tCtrl+9",   cmdSaveSettings
X        POPUP "Save As &Wallpaper"
X        BEGIN
X            MENUITEM "&Tile Bitmap\tCtrl+I",        cmdSaveWallTile
X            MENUITEM "&Center Bitmap\tCtrl+J",      cmdSaveWallCenter
X        END
X        MENUITEM SEPARATOR
X        MENUITEM "P&rint...\tCtrl+p",           cmdPrint
X        MENUITEM "Pr&int Setup...\tCtrl+q",     cmdPrintSetup
X        MENUITEM SEPARATOR
X        MENUITEM "E&xit\tq",                    cmdFileExit
X    END
X    POPUP "&Edit"
X    BEGIN
X        MENUITEM "Enter Command &Line...\tReturn",cmdCommand
X        MENUITEM SEPARATOR
X        POPUP "Run Macro (&Normal Set)"
X        BEGIN
X            MENUITEM "Macro &1\tF1",                cmdMacro01
X            MENUITEM "Macro &2\tF2",                cmdMacro02
X            MENUITEM "Macro &3\tF3",                cmdMacro03
X            MENUITEM "Macro &4\tF4",                cmdMacro04
X            MENUITEM "Macro &5\tF5",                cmdMacro05
X            MENUITEM "Macro &6\tF6",                cmdMacro06
X            MENUITEM "Macro &7\tF7",                cmdMacro07
X            MENUITEM "Macro &8\tF8",                cmdMacro08
X            MENUITEM "Macro &9\tF9",                cmdMacro09
X            MENUITEM "Macro 1&0\tF10",              cmdMacro10
X            MENUITEM "&Macro 11\tF11",              cmdMacro11
X            MENUITEM "M&acro 12\tF12",              cmdMacro12
X        END
X        POPUP "Run Macro (&Shift Set)"
X        BEGIN
X            MENUITEM "Macro 1&3\tShift+F1",         cmdMacro13
X            MENUITEM "Macro 1&4\tShift+F2",         cmdMacro14
X            MENUITEM "Macro 1&5\tShift+F3",         cmdMacro15
X            MENUITEM "Macro 1&6\tShift+F4",         cmdMacro16
X            MENUITEM "Macro 1&7\tShift+F5",         cmdMacro17
X            MENUITEM "Macro 1&8\tShift+F6",         cmdMacro18
X            MENUITEM "Macro 1&9\tShift+F7",         cmdMacro19
X            MENUITEM "Macro 2&0\tShift+F8",         cmdMacro20
X            MENUITEM "Macro 2&1\tShift+F9",         cmdMacro21
X            MENUITEM "Macro 2&2\tShift+F10",        cmdMacro22
X            MENUITEM "&Macro 23\tShift+F11",        cmdMacro23
X            MENUITEM "M&acro 24\tShift+F12",        cmdMacro24
X        END
X        POPUP "Run Macro (&Control Set)"
X        BEGIN
X            MENUITEM "Macro 2&5\tCtrl+F1",          cmdMacro25
X            MENUITEM "Macro 2&6\tCtrl+F2",          cmdMacro26
X            MENUITEM "Macro 2&7\tCtrl+F3",          cmdMacro27
X            MENUITEM "Macro 2&8\tCtrl+F4",          cmdMacro28
X            MENUITEM "Macro 2&9\tCtrl+F5",          cmdMacro29
X            MENUITEM "Macro 3&0\tCtrl+F6",          cmdMacro30
X            MENUITEM "Macro 3&1\tCtrl+F7",          cmdMacro31
X            MENUITEM "Macro 3&2\tCtrl+F8",          cmdMacro32
X            MENUITEM "Macro 3&3\tCtrl+F9",          cmdMacro33
X            MENUITEM "Macro 3&4\tCtrl+F10",         cmdMacro34
X            MENUITEM "&Macro 35\tCtrl+F11",         cmdMacro35
X            MENUITEM "M&acro 36\tCtrl+F12",         cmdMacro36
X        END
X        POPUP "Run Macro (&Alt Set)"
X        BEGIN
X            MENUITEM "Macro 3&7\tAlt+F1",           cmdMacro37
X            MENUITEM "Macro 3&8\tAlt+F2",           cmdMacro38
X            MENUITEM "Macro 3&9\tAlt+F3",           cmdMacro39
X            MENUITEM "Macro 4&0\tAlt+F4",           cmdMacro40
X            MENUITEM "Macro 4&1\tAlt+F5",           cmdMacro41
X            MENUITEM "Macro 4&2\tAlt+F6",           cmdMacro42
X            MENUITEM "Macro 4&3\tAlt+F7",           cmdMacro43
X            MENUITEM "Macro 4&4\tAlt+F8",           cmdMacro44
X            MENUITEM "Macro 4&5\tAlt+F9",           cmdMacro45
X            MENUITEM "Macro 4&6\tAlt+F10",          cmdMacro46
X            MENUITEM "&Macro 47\tAlt+F11",          cmdMacro47
X            MENUITEM "M&acro 48\tAlt+F12",          cmdMacro48
X        END
X        MENUITEM SEPARATOR
X        MENUITEM "Copy Chart &Text Output\tCtrl+%",cmdCopyText
X        MENUITEM "Copy Chart &Bitmap\tCtrl+^",  cmdCopyBitmap
X        MENUITEM "Copy Chart &Picture\tCtrl+&", cmdCopyPicture
X        MENUITEM "Copy Chart P&ostScript\tCtrl+*",cmdCopyPS
X    END
X    POPUP "&View"
X    BEGIN
X        MENUITEM "Show &Graphics\tv",           cmdGraphics
X        POPUP "&Window Settings"
X        BEGIN
X            MENUITEM "&Buffer Redraws\tTab",        cmdWinBuffer
X            MENUITEM "&Redraw Screen\tSpace",       cmdWinRedraw
X            MENUITEM "&Clear Screen\tDel",          cmdWinClear
X            MENUITEM "&Hourglass On Redraw\tAlt+U", cmdWinHourglass
X            MENUITEM SEPARATOR
X            MENUITEM "Ch&art Resizes Window\tAlt+Q",cmdChartResizesWindow
X            MENUITEM "&Window Resizes Chart\tAlt+q",cmdWindowResizesChart
X            MENUITEM "Si&ze Chart To Window\tB",    cmdSizeChartToWindow
X            MENUITEM "&Size Window To Chart\tAlt+u",cmdSizeWindowToChart
X            MENUITEM SEPARATOR
X            MENUITEM "Scroll Page &Up\tPgUp",       cmdScrollPageUp
X            MENUITEM "Scroll Page &Down\tPgDn",     cmdScrollPageDown
X            MENUITEM "Scroll &To Beginning\tHome",  cmdScrollHome
X            MENUITEM "Scroll To &End\tEnd",         cmdScrollEnd
X        END
X        MENUITEM "&Colored Text\tAlt+k",        cmdColoredText
X        MENUITEM "&Set Colors...\tAlt+K",       cmdColor
X        MENUITEM SEPARATOR
X        MENUITEM "Show &Interpretations\tAlt+I",cmdInterpret
X        MENUITEM "Print &Nearest Second\tAlt+b",cmdSecond
X        MENUITEM "&Applying Aspects\tAlt+x",    cmdApplying
X        MENUITEM "&Parallel Aspects\tAlt+X",    cmdParallel
X    END
X    POPUP "&Info"
X    BEGIN
X        MENUITEM "Set Chart &Info...\tAlt+z",   cmdSetInfo
X        MENUITEM "Chart For &Now\tn",           cmdNow
X        MENUITEM "D&efault Chart Info...\tAlt+D",cmdDefaultInfo
X        MENUITEM SEPARATOR
X        MENUITEM "Set Chart #&2 Info...\tAlt+Z",cmdSetInfo2
X        MENUITEM "Charts #&3 And #4...\tCtrl+Z",cmdSetInfoAll
X        MENUITEM SEPARATOR
X        MENUITEM "No &Relationship Chart\tc",   cmdRelNo
X        MENUITEM "Com&parison Chart\tc",        cmdRelComparison
X        MENUITEM "&Synastry Chart\tAlt+y",      cmdRelSynastry
X        MENUITEM "&Composite Chart\tAlt+Y",     cmdRelComposite
X        MENUITEM "Time / Space &Midpoint Chart\tAlt+M",cmdRelMidpoint
X        MENUITEM SEPARATOR
X        MENUITEM "Date &Difference Chart\tAlt+d",cmdRelDate
X        MENUITEM "&Biorhythm Chart\tY",         cmdRelBiorhythm
X        MENUITEM "&Transit And Natal\tAlt+n",   cmdRelTransit
X        MENUITEM "&Progressed And Natal\tAlt+N",cmdRelProgressed
X    END
X    POPUP "&Setting"
X    BEGIN
X        MENUITEM "&Sidereal Zodiac\ts",         cmdSidereal
X        MENUITEM "He&liocentric\th",            cmdHeliocentric
X        POPUP "&House System"
X        BEGIN
X            MENUITEM "&Placidus\tCtrl+P",           cmdHouse00
X            MENUITEM "&Koch\tCtrl+K",               cmdHouse01
X            MENUITEM "&Equal\tCtrl+E",              cmdHouse02
X            MENUITEM "&Campanus\tCtrl+C",           cmdHouse03
X            MENUITEM "&Meridian\tCtrl+M",           cmdHouse04
X            MENUITEM "&Regiomontanus\tCtrl+R",      cmdHouse05
X            MENUITEM "&Porph&yry\tCtrl+Y",          cmdHouse06
X            MENUITEM "Morin&us\tCtrl+U",            cmdHouse07
X            MENUITEM "&Topocentric\tCtrl+T",        cmdHouse08
X            MENUITEM "&Alcabitius\tCtrl+A",         cmdHouse09
X            MENUITEM "E&qual (MC)\tCtrl+Q",         cmdHouse10
X            MENUITEM "Ne&o-Porphyry\tCtrl+O",       cmdHouse11
X            MENUITEM "&Whole\tCtrl+W",              cmdHouse12
X            MENUITEM "&Vedic\tCtrl+V",              cmdHouse13
X            MENUITEM "&Null\tCtrl+N",               cmdHouse14
X        END
X        POPUP "House S&ettings"
X        BEGIN
X            MENUITEM "&Solar Chart\tAlt+1",         cmdHouseSetSolar
X            MENUITEM "Show &Decans\tg",             cmdHouseSetDecan
X            MENUITEM "&Flip Signs && Houses\tf",    cmdHouseSetFlip
X            MENUITEM "&Geodetic Houses\tAlt+H",     cmdHouseSetGeodetic
X            MENUITEM SEPARATOR
X            MENUITEM "&Vedic Wheel Display\tz",     cmdHouseSetVedic
X            MENUITEM "Show &Navamsas\ty",           cmdHouseSetNavamsa
X        END
X        MENUITEM "&Aspect Settings...\tAlt+A",  cmdAspect
X        MENUITEM "&Object Settings...\tAlt+j",  cmdObject
X        MENUITEM "More Ob&ject Settings...\tAlt+J",cmdObject2
X        MENUITEM SEPARATOR
X        MENUITEM "&Restrictions...\tAlt+r",     cmdRes
X        MENUITEM "Include &Minors\tR",          cmdResMinor
X        MENUITEM "Include &Cusps\tC",           cmdResCusp
X        MENUITEM "Include &Uranians\tu",        cmdResUranian
X        MENUITEM "Include &Fixed Stars\tU",     cmdResStar
X        MENUITEM "Star R&estrictions...\tAlt+R",cmdStar
X        MENUITEM "&Transit Restrictions...\tAlt+F",cmdResTransit
X        MENUITEM SEPARATOR
X        MENUITEM "Calculation Settin&gs...\tAlt+S",cmdSettingMore
X        MENUITEM "O&bscure Settings...\tAlt+B", cmdObscure
X    END
X    POPUP "&Chart"
X    BEGIN
X        MENUITEM "Standard &List\tV",           cmdChartList
X        MENUITEM "House &Wheel\tAlt+V",         cmdChartWheel
X        MENUITEM "Aspect Midpoint &Grid\tA",    cmdChartGrid
X        MENUITEM "&Aspect List\tAlt+l",         cmdChartAspect
X        MENUITEM "&Midpoint List\tAlt+m",       cmdChartMidpoint
X        MENUITEM "Local Hori&zon\tZ",           cmdChartHorizon
X        MENUITEM "Solar System &Orbit\tS",      cmdChartOrbit
X        MENUITEM "Ga&uquelin Sectors\tM",       cmdChartSector
X        MENUITEM "&Calendar\tK",                cmdChartCalendar
X        MENUITEM "&Influence\tJ",               cmdChartInfluence
X        MENUITEM "Astro-Grap&h\tL",             cmdChartAstroGraph
X        MENUITEM "&Ephemeris\tE",               cmdChartEphemeris
X        MENUITEM "A&rabic Parts\tAlt+p",        cmdChartArabic
X        MENUITEM "Risi&ng And Setting\tAlt+L",  cmdChartRising
X        MENUITEM SEPARATOR
X        MENUITEM "&Transits...\tAlt+T",         cmdTransit
X        MENUITEM "&Progressions...\tAlt+P",     cmdProgress
X        MENUITEM SEPARATOR
X        MENUITEM "Chart &Settings...\tAlt+C",   cmdChartSettings
X    END
X    POPUP "&Graphics"
X    BEGIN
X        MENUITEM "Show World &Map\tW",          cmdChartMap
X        MENUITEM "Show &Globe\tG",              cmdChartGlobe
X        MENUITEM "Show &Polar Globe\tP",        cmdChartPolar
X        MENUITEM "Show &Constellations\tF",     cmdConstellation
X        MENUITEM SEPARATOR
X        MENUITEM "&Reverse Background\tx",      cmdGraphicsReverse
X        MENUITEM "&Monochrome\tm",              cmdGraphicsMonochrome
X        MENUITEM "Show &Border\tb",             cmdGraphicsBorder
X        MENUITEM "Show Chart &Info\tt",         cmdGraphicsText
X        MENUITEM "Show I&nfo Sidebar\tAlt+t",   cmdGraphicsSidebar
X        MENUITEM "Show Glyph &Labels\tl",       cmdGraphicsLabel
X        MENUITEM "S&quare Screen\tQ",           cmdGraphicsSquare
X        POPUP "Character &Scale"
X        BEGIN
X            MENUITEM "&Small\tCtrl+1",              cmdScale1
X            MENUITEM "&Medium\tCtrl+2",             cmdScale2
X            MENUITEM "&Large\tCtrl+3",              cmdScale3
X            MENUITEM "&Huge\tCtrl+4",               cmdScale4
X            MENUITEM SEPARATOR
X            MENUITEM "&Decrease\t<",                cmdScaleDecrease
X            MENUITEM "&Increase\t>",                cmdScaleIncrease
X        END
X        POPUP "Globe &Tilt"
X        BEGIN
X            MENUITEM "Set to &Zero\tAlt+E",         cmdTiltZero
X            MENUITEM SEPARATOR
X            MENUITEM "&Decrease\t[",                cmdTiltDecrease
X            MENUITEM "&Increase\t]",                cmdTiltIncrease
X        END
X        MENUITEM SEPARATOR
X        MENUITEM "Modify &Display\ti",          cmdGraphicsModify
X        MENUITEM "Modif&y Chart\t0",            cmdChartModify
X        POPUP "Scribb&le Color"
X        BEGIN
X            MENUITEM "Blac&k\tCtrl+z",              cmdPen00
X            MENUITEM "&White\tCtrl+a",              cmdPen15
X            MENUITEM "&Red\tCtrl+r",                cmdPen09
X            MENUITEM "&Green\tCtrl+g",              cmdPen10
X            MENUITEM "&Blue\tCtrl+b",               cmdPen12
X            MENUITEM "&Yellow\tCtrl+y",             cmdPen11
X            MENUITEM "&Magenta\tCtrl+v",            cmdPen13
X            MENUITEM "&Cyan\tCtrl+j",               cmdPen14
X            MENUITEM "Gr&ay\tCtrl+d",               cmdPen08
X            MENUITEM "&Lt. Gray\tCtrl+l",           cmdPen07
X            MENUITEM "Maroo&n\tCtrl+e",             cmdPen01
X            MENUITEM "Dk. Gr&een\tCtrl+f",          cmdPen02
X            MENUITEM "Dk. Bl&ue\tCtrl+n",           cmdPen04
X            MENUITEM "&Orange\tCtrl+o",             cmdPen03
X            MENUITEM "&Purple\tCtrl+u",             cmdPen05
X            MENUITEM "&Dk. Cyan\tCtrl+k",           cmdPen06
X        END
X        MENUITEM "&Graphics Settings...\tAlt+G",cmdSettingGraphics
X    END
X    POPUP "&Animate"
X    BEGIN
X        MENUITEM "Stop &Animation\tN",          cmdAnimateNo
X        POPUP "&Jump Rate"
X        BEGIN
X            MENUITEM "Update To &Now\tN",           cmdAnimateNow
X            MENUITEM SEPARATOR
X            MENUITEM "&Seconds\t!",                 cmdAnimateS1
X            MENUITEM "&Minutes\t@",                 cmdAnimateS2
X            MENUITEM "&Hours\t#",                   cmdAnimateS3
X            MENUITEM "&Days\t$",                    cmdAnimateS4
X            MENUITEM "M&onths\t%",                  cmdAnimateS5
X            MENUITEM "&Years\t^",                   cmdAnimateS6
X            MENUITEM "&Decades\t&&",                cmdAnimateS7
X            MENUITEM "&Centuries\t*",               cmdAnimateS8
X            MENUITEM "Mi&llennia\t(",               cmdAnimateS9
X        END
X        POPUP "Jump &Factor"
X        BEGIN
X            MENUITEM "&One Unit\t1",                cmdAnimateF1
X            MENUITEM "&Two Units\t2",               cmdAnimateF2
X            MENUITEM "T&hree Units\t3",             cmdAnimateF3
X            MENUITEM "&Four Units\t4",              cmdAnimateF4
X            MENUITEM "Fi&ve Units\t5",              cmdAnimateF5
X            MENUITEM "Si&x Units\t6",               cmdAnimateF6
X            MENUITEM "&Seven Units\t7",             cmdAnimateF7
X            MENUITEM "&Eight Units\t8",             cmdAnimateF8
X            MENUITEM "&Nine Units\t9",              cmdAnimateF9
X        END
X        MENUITEM "&Reverse Direction\tr",       cmdAnimateReverse
X        MENUITEM "&Pause Animation\tp",         cmdAnimatePause
X        MENUITEM "&Timed Exposure\tj",          cmdTimedExposure
X        MENUITEM SEPARATOR
X        MENUITEM "Step &Forward\t+",            cmdStepForward
X        MENUITEM "Step &Backward\t-",           cmdStepBackward
X        MENUITEM "&Store Chart Info\to",        cmdStore
X        MENUITEM "Re&call Chart Info\tO",       cmdRecall
X    END
X    POPUP "&Help"
X    BEGIN
X        POPUP "&Documentation"
X        BEGIN
X            MENUITEM "Open &Defaults\tCtrl+)",      cmdDocDefault
X            MENUITEM "Open &Summary\tCtrl+!",       cmdDocSummary
X            MENUITEM "Open &ReadMe\tCtrl+@",        cmdDocReadme
X            MENUITEM "Open &Update\tCtrl+#",        cmdDocUpdate
X            MENUITEM "Open &Helpfile\tCtrl+$",      cmdDocHelpfile
X            MENUITEM SEPARATOR
X            MENUITEM "Open Home&page\t)",           cmdDocHomepage
X        END
X        MENUITEM SEPARATOR
X        MENUITEM "List &Signs\tAlt+2",          cmdHelpSign
X        MENUITEM "List &Objects\tAlt+3",        cmdHelpObject
X        MENUITEM "List Aspec&ts\tAlt+4",        cmdHelpAspect
X        MENUITEM "List &Constellations\tAlt+5", cmdHelpConstellation
X        MENUITEM "List &Planet Info\tAlt+6",    cmdHelpPlanetInfo
X        MENUITEM "List General &Meanings\tAlt+7",cmdHelpMeaning
X        MENUITEM "List S&witches\tAlt+8",       cmdHelpSwitch
X        MENUITEM "List O&bscure Switches\tAlt+9",cmdHelpObscure
X        MENUITEM "List &Keystrokes\t?",         cmdHelpKeystroke
X        MENUITEM "List C&redits\tAlt+0",        cmdHelpCredit
X        MENUITEM SEPARATOR
X        MENUITEM "&About Astrolog...\tCtrl+0",  cmdHelpAbout
X    END
END
X
X
//////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
X
dlgInfo DIALOG DISCARDABLE  32, 32, 161, 158
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Enter Chart Info"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,105,105,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,105,85,50,14
X    COMBOBOX        dcInMon,45,5,55,115,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcInDay,45,20,55,35,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcInYea,45,35,55,95,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcInTim,45,50,55,50,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcInDst,45,65,55,35,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcInZon,45,80,55,95,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcInLon,45,95,55,35,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcInLat,45,110,55,35,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    EDITTEXT        deInNam,45,125,110,13,ES_AUTOHSCROLL
X    EDITTEXT        deInLoc,45,140,110,13,ES_AUTOHSCROLL
X    PUSHBUTTON      "&Now",dbInNow,105,5,50,14
X    PUSHBUTTON      "&Previous",dbInSet,105,25,50,14
X    LTEXT           "Month",IDC_STATIC,5,5,35,8
X    LTEXT           "Day",IDC_STATIC,5,20,35,8
X    LTEXT           "Year",IDC_STATIC,5,35,35,8
X    LTEXT           "Time",IDC_STATIC,5,50,35,8
X    LTEXT           "Daylight?",IDC_STATIC,5,65,35,8
X    LTEXT           "Time Zone",IDC_STATIC,5,80,35,8
X    LTEXT           "Longitude",IDC_STATIC,5,95,35,8
X    LTEXT           "Latitude",IDC_STATIC,5,110,35,8
X    LTEXT           "Name",IDC_STATIC,5,125,35,8
X    LTEXT           "Location",IDC_STATIC,5,140,35,8
X    ICON            icon2,IDC_STATIC,135,55,18,20
END
X
dlgAbout DIALOG DISCARDABLE  32, 32, 267, 241
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "About Astrolog"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,208,224,50,14
X    LTEXT           "Astrolog 5.40 for MS Windows",IDC_STATIC,28,4,132,8
X    LTEXT           "As of December, 1998.",IDC_STATIC,28,12,132,8
X    LTEXT           "By Walter D. Pullen (Astara@msn.com)",IDC_STATIC,28,28,
X                    132,8
X    LTEXT           "Astrolog Homepage: http://www.magitech.com/~cruiser1/astrolog.htm",
X                    IDC_STATIC,28,36,230,8
X    LTEXT           "Astrolog Homepage #2: http://www.astrolog.org/astrolog.htm",
X                    IDC_STATIC,28,44,230,8
X    LTEXT           "Main planetary calculation formulas were converted from routines by",
X                    IDC_STATIC,28,60,230,8
X    LTEXT           "James Neely, as listed in ""Manual of Computer Programming for",
X                    IDC_STATIC,28,68,230,8
X    LTEXT           "Astrologers"" by Michael Erlewine, available from Matrix Software.",
X                    IDC_STATIC,28,76,230,8
X    LTEXT           "PostScript graphics routines by Brian D. Willoughby.",
X                    IDC_STATIC,28,92,230,8
X    LTEXT           "Extended ephemeris calculation and formulas are by Alois Treindl, as",
X                    IDC_STATIC,28,108,230,8
X    LTEXT           "in the package ""Placalc"", available from Astrodienst AG.",
X                    IDC_STATIC,28,116,230,8
X    LTEXT           "IMPORTANT: Astrolog is ""freeware"", but is copyrighted and not in",
X                    IDC_STATIC,28,132,230,9
X    LTEXT           "public domain. Permission is granted to freely use and distribute these",
X                    IDC_STATIC,28,140,230,8
X    LTEXT           "routines provided one does not sell, restrict, or profit from the program",
X                    IDC_STATIC,28,148,230,8
X    LTEXT           "or its output in any way. Modification is allowed provided these exact",
X                    IDC_STATIC,28,156,230,8
X    LTEXT           "notices remain with any altered or edited versions of the program.",
X                    IDC_STATIC,28,164,230,8
X    LTEXT           "These conditions are true of both the program in whole and of all",
X                    IDC_STATIC,28,172,230,8
X    LTEXT           "parts by any individual author. Violators are subject to copyright law",
X                    IDC_STATIC,28,180,230,8
X    LTEXT           "penalties, and negative karmic debts to aforementioned contributors.",
X                    IDC_STATIC,28,188,230,8
X    LTEXT           "Special thanks to all those unmentioned, seen and unseen, who have",
X                    IDC_STATIC,28,204,230,8
X    LTEXT           "pointed out problems, suggested features, && sent many positive vibes! :)",
X                    IDC_STATIC,28,212,236,8
X    ICON            icon,IDC_STATIC,5,5,18,20
X    ICON            icon2,IDC_STATIC,190,5,18,20
X    ICON            icon3,IDC_STATIC,215,5,18,20
X    ICON            icon4,IDC_STATIC,240,5,18,20
END
X
dlgCommand DIALOG DISCARDABLE  32, 32, 143, 50
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Enter Command Line"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,90,30,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,35,30,50,14
X    EDITTEXT        deCo,25,15,115,13,ES_AUTOHSCROLL
X    LTEXT           "Enter all parameter options below:",IDC_STATIC,25,5,115,
X                    8
X    ICON            icon3,IDC_STATIC,5,15,18,20
END
X
dlgAspect DIALOG DISCARDABLE  32, 32, 322, 167
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Aspect Settings"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,265,150,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,210,150,50,14
X    EDITTEXT        deo01,70,15,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo02,70,30,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo03,70,45,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo04,70,60,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo05,70,75,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo06,70,90,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo07,70,105,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo08,70,120,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo09,70,135,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo10,225,15,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo11,225,30,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo12,225,45,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo13,225,60,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo14,225,75,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo15,225,90,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo16,225,105,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo17,225,120,25,12,ES_AUTOHSCROLL
X    EDITTEXT        deo18,225,135,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dea01,100,15,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea02,100,30,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea03,100,45,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea04,100,60,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea05,100,75,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea06,100,90,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea07,100,105,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea08,100,120,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea09,100,135,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea10,255,15,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea11,255,30,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea12,255,45,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea13,255,60,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea14,255,75,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea15,255,90,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea16,255,105,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea17,255,120,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dea18,255,135,30,12,ES_AUTOHSCROLL
X    EDITTEXT        dei01,135,15,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei02,135,30,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei03,135,45,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei04,135,60,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei05,135,75,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei06,135,90,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei07,135,105,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei08,135,120,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei09,135,135,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei10,290,15,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei11,290,30,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei12,290,45,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei13,290,60,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei14,290,75,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei15,290,90,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei16,290,105,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei17,290,120,25,12,ES_AUTOHSCROLL
X    EDITTEXT        dei18,290,135,25,12,ES_AUTOHSCROLL
X    PUSHBUTTON      "&Restrict All",dbAs_RA0,5,150,50,14
X    PUSHBUTTON      "&Unrestrict All",dbAs_RA1,60,150,50,14
X    PUSHBUTTON      "Toggle &Majors",dbAs_RA,115,150,50,14
X    CONTROL         "&Conjunction",dxa01,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,5,15,65,10
X    CONTROL         "&Opposition",dxa02,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,5,30,65,10
X    CONTROL         "&Square",dxa03,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,
X                    45,65,10
X    CONTROL         "&Trine",dxa04,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,
X                    60,65,10
X    CONTROL         "Se&xtile",dxa05,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,
X                    75,65,10
X    CONTROL         "&Inconjunct",dxa06,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,5,90,65,10
X    CONTROL         "Semisextile",dxa07,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,5,105,65,10
X    CONTROL         "Semisquare",dxa08,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    5,120,65,10
X    CONTROL         "Sesquiquadrate",dxa09,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,5,135,65,10
X    CONTROL         "&Quintile",dxa10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    170,15,55,10
X    CONTROL         "&Biquintile",dxa11,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,170,30,55,10
X    CONTROL         "Semiquintile",dxa12,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,170,45,55,10
X    CONTROL         "Se&ptile",dxa13,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    170,60,55,10
X    CONTROL         "&Novile",dxa14,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    170,75,55,10
X    CONTROL         "Binovile",dxa15,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    170,90,55,10
X    CONTROL         "Biseptile",dxa16,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    170,105,55,10
X    CONTROL         "Triseptile",dxa17,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    170,120,55,10
X    CONTROL         "Quatronovile",dxa18,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,170,135,55,10
X    LTEXT           "Angle",IDC_STATIC,101,5,24,8
X    LTEXT           "Orb",IDC_STATIC,70,5,25,8
X    LTEXT           "Influence",IDC_STATIC,130,5,35,8
X    LTEXT           "Angle",IDC_STATIC,257,5,23,8
X    LTEXT           "Orb",IDC_STATIC,225,5,25,8
X    LTEXT           "Influence",IDC_STATIC,285,5,35,8
X    ICON            icon2,IDC_STATIC,180,145,18,20
END
X
dlgColor DIALOG DISCARDABLE  32, 32, 351, 193
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Customize Colors"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,295,175,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,240,175,50,14
X    COMBOBOX        dce0,30,155,50,80,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
X    COMBOBOX        dce1,30,170,50,80,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
X    COMBOBOX        dce2,110,155,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dce3,110,170,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dck00,40,15,50,80,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
X    COMBOBOX        dck01,40,30,50,80,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
X    COMBOBOX        dck02,40,45,50,80,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
X    COMBOBOX        dck03,40,60,50,80,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
X    COMBOBOX        dck04,40,75,50,80,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
X    COMBOBOX        dck05,40,90,50,80,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
X    COMBOBOX        dck06,40,105,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dck07,40,120,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dck08,130,15,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dck09,130,30,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dck10,130,45,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dck11,130,60,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dck12,130,75,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dck13,130,90,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dck14,130,105,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dck15,130,120,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca01,215,15,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca02,215,30,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca03,215,45,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca04,215,60,50,85,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca05,215,75,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca06,215,90,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca07,215,105,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca08,215,120,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca09,215,135,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca10,290,15,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca11,290,30,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca12,290,45,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca13,290,60,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca14,290,75,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca15,290,90,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca16,290,105,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca17,290,120,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dca18,290,135,50,80,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    LTEXT           "Fire",IDC_STATIC,10,155,20,8
X    LTEXT           "Earth",IDC_STATIC,10,170,20,8
X    LTEXT           "Air",IDC_STATIC,85,155,20,8
X    LTEXT           "Water",IDC_STATIC,85,170,20,8
X    LTEXT           "Black",IDC_STATIC,10,15,25,8
X    LTEXT           "White",IDC_STATIC,10,30,25,8
X    LTEXT           "Red",IDC_STATIC,10,45,25,8
X    LTEXT           "Green",IDC_STATIC,10,60,25,8
X    LTEXT           "Blue",IDC_STATIC,10,75,25,8
X    LTEXT           "Yellow",IDC_STATIC,10,90,25,8
X    LTEXT           "Magenta",IDC_STATIC,10,105,29,8
X    LTEXT           "Cyan",IDC_STATIC,10,120,25,8
X    LTEXT           "Gray",IDC_STATIC,95,15,25,8
X    LTEXT           "Lt. Gray",IDC_STATIC,95,30,30,8
X    LTEXT           "Maroon",IDC_STATIC,95,45,25,8
X    LTEXT           "Dk. Green",IDC_STATIC,95,60,35,8
X    LTEXT           "Dk. Blue",IDC_STATIC,95,75,30,8
X    LTEXT           "Orange",IDC_STATIC,95,90,25,8
X    LTEXT           "Purple",IDC_STATIC,95,105,25,8
X    LTEXT           "Dk. Cyan",IDC_STATIC,95,120,30,8
X    LTEXT           "Con.",IDC_STATIC,195,15,20,8
X    LTEXT           "Opp.",IDC_STATIC,195,30,20,8
X    LTEXT           "Squ.",IDC_STATIC,195,45,20,8
X    LTEXT           "Tri.",IDC_STATIC,195,60,20,8
X    LTEXT           "Sex.",IDC_STATIC,195,75,20,8
X    LTEXT           "Inc.",IDC_STATIC,195,90,20,8
X    LTEXT           "S.Sx.",IDC_STATIC,195,105,20,8
X    LTEXT           "S.Sq.",IDC_STATIC,195,120,20,8
X    LTEXT           "Ses.",IDC_STATIC,195,135,20,8
X    LTEXT           "Qui.",IDC_STATIC,270,15,20,8
X    LTEXT           "B.Qn.",IDC_STATIC,270,30,20,8
X    LTEXT           "S.Qn.",IDC_STATIC,270,45,20,8
X    LTEXT           "Sep.",IDC_STATIC,270,60,20,8
X    LTEXT           "Nov.",IDC_STATIC,270,75,20,8
X    LTEXT           "B.Nv.",IDC_STATIC,270,90,20,8
X    LTEXT           "B.Sp.",IDC_STATIC,270,105,20,8
X    LTEXT           "T.Sp.",IDC_STATIC,270,120,20,8
X    LTEXT           "Q.Nv.",IDC_STATIC,270,135,20,8
X    GROUPBOX        "Elements",IDC_STATIC,5,140,160,50
X    GROUPBOX        "Standard Color Palette",IDC_STATIC,5,0,180,140
X    GROUPBOX        "Aspects",IDC_STATIC,190,0,155,155
X    ICON            icon3,IDC_STATIC,190,170,18,20
END
X
dlgRestrict DIALOG DISCARDABLE  32, 32, 311, 138
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Object Restrictions"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,255,120,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,255,100,50,14
X    CONTROL         "&Sun",dx01,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,10,
X                    40,10
X    CONTROL         "M&oon",dx02,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,20,
X                    40,10
X    CONTROL         "Mercur&y",dx03,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,
X                    30,40,10
X    CONTROL         "&Venus",dx04,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,
X                    40,40,10
X    CONTROL         "&Mars",dx05,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,50,
X                    40,10
X    CONTROL         "&Jupiter",dx06,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,
X                    60,40,10
X    CONTROL         "Sa&turn",dx07,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,
X                    70,40,10
X    CONTROL         "Ur&anus",dx08,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,
X                    80,40,10
X    CONTROL         "&Neptune",dx09,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,
X                    90,40,10
X    CONTROL         "&Pluto",dx10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,
X                    100,40,10
X    CONTROL         "&Chiron",dx11,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,
X                    10,60,10
X    CONTROL         "Ceres",dx12,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,20,
X                    60,10
X    CONTROL         "Pallas Athena",dx13,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,65,30,60,10
X    CONTROL         "Juno",dx14,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,40,
X                    60,10
X    CONTROL         "Vesta",dx15,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,50,
X                    60,10
X    CONTROL         "North Node",dx16,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    65,60,60,10
X    CONTROL         "Lilith / S.Node",dx17,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,65,70,60,10
X    CONTROL         "Part of Fortune",dx18,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,65,80,60,10
X    CONTROL         "Vertex",dx19,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,
X                    90,60,10
X    CONTROL         "East Point",dx20,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    65,100,60,10
X    CONTROL         "Asc&endant",dx21,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    141,10,50,10
X    CONTROL         "2nd Cusp",dx22,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    141,20,50,10
X    CONTROL         "3rd Cusp",dx23,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    141,30,50,10
X    CONTROL         "Nadir",dx24,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,141,
X                    40,50,10
X    CONTROL         "5th Cusp",dx25,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    141,50,50,10
X    CONTROL         "6th Cusp",dx26,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    141,60,50,10
X    CONTROL         "&Descendant",dx27,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    141,70,50,10
X    CONTROL         "8th Cusp",dx28,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    141,80,50,10
X    CONTROL         "9th Cusp",dx29,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    141,90,50,10
X    CONTROL         "Mid&heaven",dx30,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    141,100,50,10
X    CONTROL         "11th Cusp",dx31,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    141,110,50,10
X    CONTROL         "12th Cusp",dx32,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    141,120,50,10
X    CONTROL         "Cupido",dx33,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,
X                    10,40,10
X    CONTROL         "Hades",dx34,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,
X                    20,40,10
X    CONTROL         "Zeus",dx35,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,30,
X                    40,10
X    CONTROL         "Kronos",dx36,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,
X                    40,40,10
X    CONTROL         "Apollon",dx37,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,
X                    50,40,10
X    CONTROL         "Admetos",dx38,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,
X                    60,40,10
X    CONTROL         "Vulkanus",dx39,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    205,70,40,10
X    CONTROL         "Poseidon",dx40,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    205,80,40,10
X    PUSHBUTTON      "&Restrict All",dbRe_R0,255,5,50,14
X    PUSHBUTTON      "&Unrestrict All",dbRe_R1,255,20,50,14
X    PUSHBUTTON      "Toggle Minors",dbRe_R,255,45,50,14
X    PUSHBUTTON      "Toggle Cusps",dbRe_RC,255,60,50,14
X    PUSHBUTTON      "Toggle Uran.",dbRe_Ru,255,75,50,14
X    PUSHBUTTON      "Copy &From Other Restriction Set",dbRT,5,120,125,14
X    GROUPBOX        "Planets",IDC_STATIC,5,0,50,115
X    GROUPBOX        "Minor Objects",IDC_STATIC,60,0,70,115
X    GROUPBOX        "Houses",IDC_STATIC,135,0,60,135
X    GROUPBOX        "Uranians",IDC_STATIC,200,0,50,95
X    ICON            icon2,IDC_STATIC,215,110,18,20
END
X
dlgDefault DIALOG DISCARDABLE  32, 32, 162, 86
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Default Info"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,105,65,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,105,45,50,14
X    COMBOBOX        dcDeDst,45,5,55,35,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcDeZon,45,20,55,95,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcDeLon,45,35,55,35,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcDeLat,45,50,55,35,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcDeCor,45,65,55,35,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | 
X                    WS_TABSTOP
X    LTEXT           "Daylight?",IDC_STATIC,5,5,35,8
X    LTEXT           "Time Zone",IDC_STATIC,5,20,35,8
X    LTEXT           "Longitude",IDC_STATIC,5,35,35,8
X    LTEXT           "Latitude",IDC_STATIC,5,50,35,8
X    LTEXT           "Correction For Now",IDC_STATIC,5,65,35,20
X    ICON            icon2,IDC_STATIC,135,5,18,20
END
X
dlgProgress DIALOG DISCARDABLE  32, 32, 187, 170
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Progressions"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,130,148,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,130,129,50,14
X    CONTROL         "Do &Progression",dxPr_p,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,5,5,85,10
X    COMBOBOX        dcPrMon,50,35,55,115,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcPrDay,50,50,55,35,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcPrYea,50,65,55,95,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcPrTim,50,80,55,50,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | 
X                    WS_TABSTOP
X    CONTROL         "&Secondary Progression",dr01,"Button",
X                    BS_AUTORADIOBUTTON | WS_GROUP,10,118,90,10
X    CONTROL         "Solar &Arc Progression",dr02,"Button",
X                    BS_AUTORADIOBUTTON,10,129,90,10
X    COMBOBOX        dcPr_pd,70,143,48,42,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    PUSHBUTTON      "&Now",dbPr_pn,130,5,50,14
X    LTEXT           "Month",IDC_STATIC,10,35,35,8
X    LTEXT           "Day",IDC_STATIC,10,50,35,8
X    LTEXT           "Year",IDC_STATIC,10,65,35,8
X    LTEXT           "Time",IDC_STATIC,10,80,35,8
X    LTEXT           "Degrees Per Day",IDC_STATIC,10,143,60,8
X    GROUPBOX        "Progress Chart To",IDC_STATIC,5,20,105,80
X    GROUPBOX        "Progresion Settings",IDC_STATIC,5,105,120,58
X    ICON            icon2,IDC_STATIC,145,55,18,20
END
X
dlgTransit DIALOG DISCARDABLE  32, 32, 229, 175
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Transits"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,170,155,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,170,135,50,14
X    CONTROL         "N&one",dr01,"Button",BS_AUTORADIOBUTTON | WS_GROUP,10,
X                    15,105,10
X    CONTROL         "Transit To Transit &Hits",dr02,"Button",
X                    BS_AUTORADIOBUTTON,10,25,105,10
X    CONTROL         "Transit To &Transit Influence",dr03,"Button",
X                    BS_AUTORADIOBUTTON,10,35,105,10
X    CONTROL         "Transit To N&atal Hits",dr04,"Button",
X                    BS_AUTORADIOBUTTON,10,45,105,10
X    CONTROL         "Transit To Natal &Influence",dr05,"Button",
X                    BS_AUTORADIOBUTTON,10,55,105,10
X    CONTROL         "&Progress Instead Of Transit",dxTr_p,"Button",
X                    BS_AUTOCHECKBOX | WS_TABSTOP,5,75,105,10
X    CONTROL         "Display R&eturns Only",dxTr_r,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,120,75,100,10
X    COMBOBOX        dcTrMon,50,105,55,115,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcTrDay,50,120,55,35,CBS_DROPDOWN | WS_VSCROLL | 
X                    WS_TABSTOP
X    COMBOBOX        dcTrYea,50,135,55,95,CBS_DROPDOWN | CBS_SORT | 
X                    WS_VSCROLL | WS_TABSTOP
X    COMBOBOX        dcTrTim,50,150,55,50,CBS_DROPDOWN | CBS_SORT | 
X                    WS_VSCROLL | WS_TABSTOP
X    CONTROL         "Given &Day",dr06,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
X                    135,15,65,10
X    CONTROL         "Given &Month",dr07,"Button",BS_AUTORADIOBUTTON,135,25,
X                    65,10
X    CONTROL         "Given &Year",dr08,"Button",BS_AUTORADIOBUTTON,135,35,65,
X                    10
X    CONTROL         "&Range Of Years",dr09,"Button",BS_AUTORADIOBUTTON,135,
X                    45,65,10
X    EDITTEXT        deTr_tY,190,55,25,13,ES_AUTOHSCROLL
X    EDITTEXT        deTr_d,190,95,30,13,ES_AUTOHSCROLL
X    PUSHBUTTON      "&Now",dbTr_tn,170,115,50,14
X    LTEXT           "Month",IDC_STATIC,10,105,35,8
X    LTEXT           "Day",IDC_STATIC,10,120,35,8
X    LTEXT           "Year",IDC_STATIC,10,135,35,8
X    LTEXT           "Time",IDC_STATIC,10,150,35,8
X    LTEXT           "Years To Span:",IDC_STATIC,135,55,55,8
X    LTEXT           "Searching Divisions:",IDC_STATIC,120,95,70,8
X    GROUPBOX        "Transit Type",IDC_STATIC,5,5,115,65
X    GROUPBOX        "Do Transits For",IDC_STATIC,5,90,105,80
X    GROUPBOX        "Search For Hits Over",IDC_STATIC,130,5,90,65
X    ICON            icon2,IDC_STATIC,130,130,18,20
END
X
dlgSetting DIALOG DISCARDABLE  32, 32, 206, 146
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Calculation Settings"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,150,125,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,150,105,50,14
X    COMBOBOX        dcSe_s,120,4,56,52,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | 
X                    WS_TABSTOP
X    EDITTEXT        deSe_A,85,20,20,13,ES_AUTOHSCROLL
X    EDITTEXT        deSe_x,85,35,20,13,ES_AUTOHSCROLL
X    EDITTEXT        deSe_h,65,50,40,13,ES_AUTOHSCROLL
X    CONTROL         "&None",dr01,"Button",BS_AUTORADIOBUTTON | WS_GROUP,10,
X                    75,35,10
X    CONTROL         "Object On &Ascendant",dr02,"Button",BS_AUTORADIOBUTTON,
X                    10,85,90,10
X    CONTROL         "Object On &Midheaven",dr03,"Button",BS_AUTORADIOBUTTON,
X                    10,95,90,10
X    EDITTEXT        deSe_1,65,105,40,13,ES_AUTOHSCROLL
X    EDITTEXT        deSe_I,65,130,20,13,ES_AUTOHSCROLL
X    CONTROL         "Use &Ephemeris Files",dxSe_b,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,120,25,80,10
X    CONTROL         "&Zodiac Position",dr04,"Button",BS_AUTORADIOBUTTON | 
X                    WS_GROUP,125,50,65,10
X    CONTROL         "&Hours && Minutes",dr05,"Button",BS_AUTORADIOBUTTON,125,
X                    60,65,10
X    CONTROL         "&360 Degrees",dr06,"Button",BS_AUTORADIOBUTTON,125,70,
X                    65,10
X    CONTROL         "E&quatorial Positions",dxSe_sr,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,120,90,80,10
X    LTEXT           "Zodiac Degree Offset / Ayanamsa:",IDC_STATIC,5,5,115,8
X    LTEXT           "Aspects To Consider:",IDC_STATIC,5,20,75,8
X    LTEXT           "Harmonic Chart Factor:",IDC_STATIC,5,35,80,8
X    LTEXT           "Central Planet:",IDC_STATIC,5,50,60,8
X    LTEXT           "Use This Planet:",IDC_STATIC,10,105,55,8
X    LTEXT           "Text Columns:",IDC_STATIC,5,130,60,8
X    GROUPBOX        "Solar Chart Setting",IDC_STATIC,5,65,105,60
X    GROUPBOX        "Display Format",IDC_STATIC,120,40,75,45
X    ICON            icon3,IDC_STATIC,120,120,18,20
END
X
dlgChart DIALOG DISCARDABLE  32, 32, 266, 173
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Chart Setting Details"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,210,155,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,210,135,50,14
X    CONTROL         "Text Listing &Velocities Relative To Average Speed",
X                    dxCh_v0,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,5,180,10
X    EDITTEXT        deCh_w,90,15,15,13,ES_AUTOHSCROLL
X    CONTROL         "Text House &Wheel Reverses Object Order",dxCh_w0,
X                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,30,175,10
X    CONTROL         "Text Aspect &Grid Shows Aspect Configurations",dxCh_g0,
X                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,40,175,10
X    CONTROL         "Text &Aspect List Shows Aspect Summary",dxCh_a0,
X                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,50,175,10
X    CONTROL         "Text &Midpoint List Shows Midpoint Summary",dxCh_m0,
X                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,60,175,10
X    CONTROL         "Text Midpoint List Includes Aspects &To Midpoints",
X                    dxCh_ma,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,70,175,
X                    10
X    CONTROL         "Hori&zon Chart Displays With Polar Center",dxCh_Z0,
X                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,80,175,10
X    CONTROL         "Text &Influence Chart Shows Sign Influences Too",
X                    dxCh_j0,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,100,175,
X                    10
X    EDITTEXT        deCh_L,125,111,20,13,ES_AUTOHSCROLL
X    CONTROL         "Text Astro-Graph Shows &Latitude Crossings",dxCh_L0,
X                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,126,175,10
X    CONTROL         "Text &Calendar Is For Entire Year",dxCh_Ky,"Button",
X                    BS_AUTOCHECKBOX | WS_TABSTOP,5,135,175,10
X    EDITTEXT        deCh_P,125,145,20,13,ES_AUTOHSCROLL
X    CONTROL         "Display Arabic &Part Formulas With Terms Reversed.",
X                    dxCh_P0,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,161,175,
X                    10
X    CONTROL         "Default",dr01,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
X                    190,15,60,10
X    CONTROL         "By Azimuth",dr02,"Button",BS_AUTORADIOBUTTON,190,25,60,
X                    10
X    CONTROL         "By Altitude",dr03,"Button",BS_AUTORADIOBUTTON,190,35,60,
X                    10
X    CONTROL         "By Name",dr04,"Button",BS_AUTORADIOBUTTON,190,45,60,10
X    CONTROL         "By Brightness",dr05,"Button",BS_AUTORADIOBUTTON,190,55,
X                    60,10
X    CONTROL         "Default",dr06,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
X                    190,85,50,10
X    CONTROL         "By Position",dr07,"Button",BS_AUTORADIOBUTTON,190,95,50,
X                    10
X    CONTROL         "By Name",dr08,"Button",BS_AUTORADIOBUTTON,190,105,50,10
X    CONTROL         "By Formula",dr09,"Button",BS_AUTORADIOBUTTON,190,115,50,
X                    10
X    LTEXT           "Text House Wheel Rows:",IDC_STATIC,5,15,85,8
X    LTEXT           "Text Astro-Graph Degree Step Rate:",IDC_STATIC,5,111,
X                    120,8
X    LTEXT           "Number of Arabic Parts To Display:",IDC_STATIC,5,145,
X                    120,8
X    GROUPBOX        "Fixed Star Ordering",IDC_STATIC,185,5,75,65
X    GROUPBOX        "Arabic Part Ordering",IDC_STATIC,185,75,75,55
X    ICON            icon3,IDC_STATIC,185,145,18,20
X    CONTROL         "&Sector Chart Approximated With Placidus Cusps",dxCh_l,
X                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,90,175,10
END
X
dlgObscure DIALOG DISCARDABLE  32, 32, 251, 210
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Obscure Settings"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,195,190,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,140,190,50,14
X    CONTROL         "Compute True &Node Instead Of Mean Node.",dxOb_Yn,
X                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,5,180,10
X    CONTROL         "Display &Dates In D/M/Y Instead Of M/D/Y Format.",
X                    dxOb_Yd,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,15,180,
X                    10
X    CONTROL         "Display &Times In 24 Hour Instead Of am/pm Format.",
X                    dxOb_Yt,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,25,180,
X                    10
X    CONTROL         "Ignore Insignificant House &Cusp Aspects.",dxOb_YC,
X                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,35,180,10
X    CONTROL         "Clip Text Charts At Rightmost (e.g. &80th) Column.",
X                    dxOb_Y8,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,45,180,
X                    10
X    CONTROL         "&Output Chart Data Files In Old Style Format.",dxOb_Yo,
X                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,55,180,10
X    CONTROL         "Cusp Objects Are Positions &Instead Of Angles.",
X                    dxOb_Yc0,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,65,180,
X                    10
X    CONTROL         "Restrict &Sign Change Events In Searches.",dxOb_YR0_s,
X                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,75,180,10
X    CONTROL         "Restrict Di&rection Change Events In Searches.",
X                    dxOb_YR0_d,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,85,
X                    180,10
X    EDITTEXT        deOb_YXg,145,95,25,13,ES_AUTOHSCROLL
X    CONTROL         "Use Real System &Fonts In Graphic Files.",dxOb_YXf,
X                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,110,180,10
X    EDITTEXT        deOb_YXp0_x,135,120,25,13,ES_AUTOHSCROLL
X    EDITTEXT        deOb_YXp0_y,135,135,25,13,ES_AUTOHSCROLL
X    CONTROL         "&Portrait",dr09,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
X                    10,155,105,10
X    CONTROL         "&Landscape",dr10,"Button",BS_AUTORADIOBUTTON,10,165,105,
X                    10
X    CONTROL         "&Based On Chart Dimensions",dr11,"Button",
X                    BS_AUTORADIOBUTTON,10,175,105,10
X    CONTROL         "American",dr01,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
X                    190,15,50,10
X    CONTROL         "European",dr02,"Button",BS_AUTORADIOBUTTON,190,25,50,10
X    CONTROL         "Herschel's",dr03,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
X                    190,50,50,10
X    CONTROL         "Astronomical",dr04,"Button",BS_AUTORADIOBUTTON,190,60,
X                    53,10
X    CONTROL         "Astrological",dr05,"Button",BS_AUTORADIOBUTTON | 
X                    WS_GROUP,190,85,50,10
X    CONTROL         "Astronomical",dr06,"Button",BS_AUTORADIOBUTTON,190,95,
X                    53,10
X    CONTROL         "American",dr07,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
X                    190,120,50,10
X    CONTROL         "European",dr08,"Button",BS_AUTORADIOBUTTON,190,130,50,
X                    10
X    CONTROL         "Rising",dx01,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,
X                    160,35,10
X    CONTROL         "Setting",dx03,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,
X                    170,35,10
X    CONTROL         "Zenith Crossing",dx02,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,170,160,70,10
X    CONTROL         "Nadir Crossing",dx04,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,170,170,70,10
X    LTEXT           "Number Of Cells In Graphics Aspect Grid:",IDC_STATIC,5,
X                    95,135,8
X    LTEXT           "Horizontal PostScript Paper Inch Size:",IDC_STATIC,5,
X                    120,125,8
X    LTEXT           "Vertical PostScript Paper Inch Size:",IDC_STATIC,5,135,
X                    125,8
X    GROUPBOX        "PostScript Paper Orientation",IDC_STATIC,5,145,115,45
X    GROUPBOX        "Capricorn Gyph",IDC_STATIC,185,5,60,35
X    GROUPBOX        "Uranus Glyph",IDC_STATIC,185,40,60,35
X    GROUPBOX        "Pluto Glyph",IDC_STATIC,185,75,60,35
X    GROUPBOX        "Lilith Glyph",IDC_STATIC,185,110,60,35
X    GROUPBOX        "Rising And Setting Restrictions",IDC_STATIC,125,150,120,
X                    35
X    ICON            icon3,IDC_STATIC,165,125,18,20
END
X
dlgGraphics DIALOG DISCARDABLE  32, 32, 170, 170
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Graphics Settings"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,115,150,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,115,130,50,14
X    EDITTEXT        deGr_Xw_x,80,5,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deGr_Xw_y,80,20,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deGr_XW,115,35,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deGr_XG,115,50,30,13,ES_AUTOHSCROLL
X    CONTROL         "&World Map In Mollewide Projection",dxGr_XW0,"Button",
X                    BS_AUTOCHECKBOX | WS_TABSTOP,5,65,125,10
X    EDITTEXT        deGr_WN,90,80,30,13,ES_AUTOHSCROLL
X    CONTROL         "Don't &Automatically Update Screen",dxGr_Wn,"Button",
X                    BS_AUTOCHECKBOX | WS_TABSTOP,5,95,125,10
X    CONTROL         "&None",dr01,"Button",BS_AUTORADIOBUTTON | WS_GROUP,10,
X                    116,35,10
X    CONTROL         "Object At &Left Edge",dr02,"Button",BS_AUTORADIOBUTTON,
X                    10,126,85,10
X    CONTROL         "Object At &Top Edge",dr03,"Button",BS_AUTORADIOBUTTON,
X                    10,135,85,10
X    EDITTEXT        deGr_X1,65,145,40,13,ES_AUTOHSCROLL
X    LTEXT           "Horizontal Chart Size:",IDC_STATIC,5,5,75,8
X    LTEXT           "Vertical Chart Size:",IDC_STATIC,5,20,75,8
X    LTEXT           "Horizontal Map Degree Rotation:",IDC_STATIC,5,35,108,8
X    LTEXT           "Vertical Globe Degree Tilt:",IDC_STATIC,5,50,105,8
X    LTEXT           "Animation Delay In Msec:",IDC_STATIC,5,80,85,8
X    LTEXT           "Use This Planet:",IDC_STATIC,10,145,55,8
X    GROUPBOX        "Wheel Chart Rotation",IDC_STATIC,5,105,105,60
X    ICON            icon2,IDC_STATIC,135,90,18,20
END
X
dlgStar DIALOG DISCARDABLE  32, 32, 297, 130
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Fixed Star Restrictions"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,240,110,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,240,90,50,14
X    CONTROL         "Achernar",dx01,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,
X                    5,55,10
X    CONTROL         "Polaris",dx02,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,
X                    15,55,10
X    CONTROL         "&Zeta Reticuli",dx03,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,5,25,55,10
X    CONTROL         "&Pleiades",dx04,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,
X                    35,55,10
X    CONTROL         "Aldeberan",dx05,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,
X                    45,55,10
X    CONTROL         "Capella",dx06,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,
X                    55,55,10
X    CONTROL         "Rigel",dx07,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,65,
X                    55,10
X    CONTROL         "Bellatrix",dx08,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,
X                    75,55,10
X    CONTROL         "Alnath",dx09,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,85,
X                    55,10
X    CONTROL         "&Orion",dx10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,95,
X                    55,10
X    CONTROL         "&Betelgeuse",dx11,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    5,105,55,10
X    CONTROL         "Menkalinan",dx12,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    5,115,55,10
X    CONTROL         "Murzim",dx13,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,5,
X                    50,10
X    CONTROL         "Canopus",dx14,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,
X                    15,50,10
X    CONTROL         "Alhena",dx15,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,
X                    25,50,10
X    CONTROL         "&Sirius",dx16,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,
X                    35,50,10
X    CONTROL         "Adara",dx17,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,45,
X                    50,10
X    CONTROL         "Wezen",dx18,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,55,
X                    50,10
X    CONTROL         "Castor",dx19,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,
X                    65,50,10
X    CONTROL         "Procyon",dx20,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,
X                    75,50,10
X    CONTROL         "Pollux",dx21,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,
X                    85,50,10
X    CONTROL         "Suhail",dx22,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,
X                    95,50,10
X    CONTROL         "Avior",dx23,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,
X                    105,50,10
X    CONTROL         "Miaplacidus",dx24,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    65,115,50,10
X    CONTROL         "Alphard",dx25,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,
X                    5,55,10
X    CONTROL         "Regulus",dx26,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,
X                    15,55,10
X    CONTROL         "Dubhe",dx27,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,
X                    25,55,10
X    CONTROL         "Acrux",dx28,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,
X                    35,55,10
X    CONTROL         "Gacrux",dx29,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,
X                    45,55,10
X    CONTROL         "Becrux",dx30,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,
X                    55,55,10
X    CONTROL         "Alioth",dx31,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,
X                    65,55,10
X    CONTROL         "Spica",dx32,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,
X                    75,55,10
X    CONTROL         "Alkaid",dx33,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,
X                    85,55,10
X    CONTROL         "Agena",dx34,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,
X                    95,55,10
X    CONTROL         "Arcturus",dx35,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    120,105,55,10
X    CONTROL         "Rigel Kentaurus",dx36,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,120,115,65,10
X    CONTROL         "Antares",dx37,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,175,
X                    5,60,10
X    CONTROL         "Shaula",dx38,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,175,
X                    15,60,10
X    CONTROL         "Sargas",dx39,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,175,
X                    25,60,10
X    CONTROL         "Kaus Australis",dx40,"Button",BS_AUTOCHECKBOX | 
X                    WS_TABSTOP,175,35,60,10
X    CONTROL         "&Vega",dx41,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,175,
X                    45,60,10
X    CONTROL         "Altair",dx42,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,175,
X                    55,60,10
X    CONTROL         "Peacock",dx43,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,175,
X                    65,60,10
X    CONTROL         "Deneb",dx44,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,175,
X                    75,60,10
X    CONTROL         "Alnair",dx45,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,175,
X                    85,60,10
X    CONTROL         "Formalhaut",dx46,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    175,95,60,10
X    CONTROL         "&Andromeda",dx47,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
X                    175,105,60,10
X    PUSHBUTTON      "&Restrict All",dbSt_RU0,240,5,50,14
X    PUSHBUTTON      "&Unrestrict All",dbSt_RU1,240,25,50,14
X    ICON            icon2,IDC_STATIC,255,55,18,20
END
X
dlgObject DIALOG DISCARDABLE  32, 32, 281, 188
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Object Settings"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,225,170,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,170,170,50,14
X    EDITTEXT        deo01,40,15,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo02,40,30,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo03,40,45,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo04,40,60,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo05,40,75,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo06,40,90,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo07,40,105,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo08,40,120,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo09,40,135,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo10,40,150,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo11,185,15,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo12,185,30,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo13,185,45,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo14,185,60,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo15,185,75,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo16,185,90,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo17,185,105,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo18,185,120,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo19,185,135,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo20,185,150,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dea01,75,15,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea02,75,30,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea03,75,45,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea04,75,60,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea05,75,75,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea06,75,90,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea07,75,105,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea08,75,120,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea09,75,135,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea10,75,150,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea11,220,15,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea12,220,30,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea13,220,45,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea14,220,60,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea15,220,75,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea16,220,90,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea17,220,105,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea18,220,120,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea19,220,135,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea20,220,150,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dei01,100,15,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei02,100,30,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei03,100,45,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei04,100,60,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei05,100,75,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei06,100,90,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei07,100,105,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei08,100,120,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei09,100,135,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei10,100,150,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei11,245,15,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei12,245,30,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei13,245,45,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei14,245,60,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei15,245,75,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei16,245,90,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei17,245,105,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei18,245,120,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei19,245,135,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei20,245,150,30,13,ES_AUTOHSCROLL
X    LTEXT           "Sun",IDC_STATIC,5,15,30,8
X    LTEXT           "Moon",IDC_STATIC,5,30,30,8
X    LTEXT           "Mercury",IDC_STATIC,5,45,30,8
X    LTEXT           "Venus",IDC_STATIC,5,60,30,8
X    LTEXT           "Mars",IDC_STATIC,5,75,30,8
X    LTEXT           "Jupiter",IDC_STATIC,5,90,30,8
X    LTEXT           "Saturn",IDC_STATIC,5,105,30,8
X    LTEXT           "Uranus",IDC_STATIC,5,120,30,8
X    LTEXT           "Neptune",IDC_STATIC,5,135,30,8
X    LTEXT           "Pluto",IDC_STATIC,5,150,30,8
X    LTEXT           "Chiron",IDC_STATIC,135,15,50,8
X    LTEXT           "Ceres",IDC_STATIC,135,30,50,8
X    LTEXT           "Pallas Athena",IDC_STATIC,135,45,50,8
X    LTEXT           "Juno",IDC_STATIC,135,60,50,8
X    LTEXT           "Vesta",IDC_STATIC,135,75,50,8
X    LTEXT           "North Node",IDC_STATIC,135,90,50,8
X    LTEXT           "Lilith / S.Node",IDC_STATIC,135,105,50,8
X    LTEXT           "Part of Fortune",IDC_STATIC,135,120,50,8
X    LTEXT           "Vertex",IDC_STATIC,135,135,50,8
X    LTEXT           "East Point",IDC_STATIC,135,150,50,8
X    LTEXT           "Max Orb",IDC_STATIC,40,5,30,8
X    LTEXT           "Add",IDC_STATIC,75,5,20,8
X    LTEXT           "Influence",IDC_STATIC,100,5,30,8
X    LTEXT           "Max Orb",IDC_STATIC,185,5,30,8
X    LTEXT           "Add",IDC_STATIC,220,5,20,8
X    LTEXT           "Influence",IDC_STATIC,245,5,30,8
X    ICON            icon2,IDC_STATIC,140,165,18,20
END
X
dlgObject2 DIALOG DISCARDABLE  32, 32, 277, 198
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Cusp & Uranian Settings"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,220,180,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,220,160,50,14
X    EDITTEXT        deo01,50,15,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo02,50,30,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo03,50,45,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo04,50,60,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo05,50,75,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo06,50,90,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo07,50,105,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo08,50,120,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo09,50,135,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo10,50,150,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo11,50,165,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo12,50,180,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dea01,85,15,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea02,85,30,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea03,85,45,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea04,85,60,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea05,85,75,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea06,85,90,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea07,85,105,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea08,85,120,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea09,85,135,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea10,85,150,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea11,85,165,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea12,85,180,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dei01,110,15,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei02,110,30,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei03,110,45,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei04,110,60,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei05,110,75,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei06,110,90,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei07,110,105,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei08,110,120,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei09,110,135,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei10,110,150,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei11,110,165,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei12,110,180,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo13,180,15,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo14,180,30,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo15,180,45,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo16,180,60,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo17,180,75,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo18,180,90,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo19,180,105,30,13,ES_AUTOHSCROLL
X    EDITTEXT        deo20,180,120,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dea13,215,15,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea14,215,30,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea15,215,45,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea16,215,60,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea17,215,75,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea18,215,90,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea19,215,105,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dea20,215,120,20,13,ES_AUTOHSCROLL
X    EDITTEXT        dei13,240,15,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei14,240,30,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei15,240,45,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei16,240,60,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei17,240,75,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei18,240,90,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei19,240,105,30,13,ES_AUTOHSCROLL
X    EDITTEXT        dei20,240,120,30,13,ES_AUTOHSCROLL
X    LTEXT           "Ascendant",IDC_STATIC,5,15,40,8
X    LTEXT           "2nd Cusp",IDC_STATIC,5,30,40,8
X    LTEXT           "3rd Cusp",IDC_STATIC,5,45,40,8
X    LTEXT           "Nadir",IDC_STATIC,5,60,40,8
X    LTEXT           "5th Cusp",IDC_STATIC,5,75,40,8
X    LTEXT           "6th Cusp",IDC_STATIC,5,90,40,8
X    LTEXT           "Descendant",IDC_STATIC,5,105,40,8
X    LTEXT           "8th Cusp",IDC_STATIC,5,120,40,8
X    LTEXT           "9th Cusp",IDC_STATIC,5,135,40,8
X    LTEXT           "Midheaven",IDC_STATIC,5,150,40,8
X    LTEXT           "11th Cusp",IDC_STATIC,5,165,40,8
X    LTEXT           "12th Cusp",IDC_STATIC,5,180,40,8
X    LTEXT           "Cupido",IDC_STATIC,145,15,30,8
X    LTEXT           "Hades",IDC_STATIC,145,30,30,8
X    LTEXT           "Zeus",IDC_STATIC,145,45,30,8
X    LTEXT           "Kronos",IDC_STATIC,145,60,30,8
X    LTEXT           "Apollon",IDC_STATIC,145,75,30,8
X    LTEXT           "Admetos",IDC_STATIC,145,90,30,8
X    LTEXT           "Vulkanus",IDC_STATIC,145,105,30,8
X    LTEXT           "Poseidon",IDC_STATIC,145,120,30,8
X    LTEXT           "Max Orb",IDC_STATIC,50,5,30,8
X    LTEXT           "Add",IDC_STATIC,85,5,20,8
X    LTEXT           "Influence",IDC_STATIC,110,5,30,8
X    LTEXT           "Max Orb",IDC_STATIC,180,5,30,8
X    LTEXT           "Add",IDC_STATIC,215,5,20,8
X    LTEXT           "Influence",IDC_STATIC,240,5,30,8
X    ICON            icon2,IDC_STATIC,175,175,18,20
END
X
dlgAbort DIALOG DISCARDABLE  32, 32, 125, 38
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Print Progress"
FONT 8, "MS Sans Serif"
BEGIN
X    PUSHBUTTON      "Cancel",IDCANCEL,40,20,50,14
X    LTEXT           "The Astrolog chart is being printed.",IDC_STATIC,5,5,
X                    115,8
X    ICON            icon3,IDC_STATIC,5,15,18,20
END
X
dlgInfoAll DIALOG DISCARDABLE  32, 32, 143, 151
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Charts #3 And #4"
FONT 8, "MS Sans Serif"
BEGIN
X    DEFPUSHBUTTON   "OK",IDOK,90,130,50,14
X    PUSHBUTTON      "Cancel",IDCANCEL,35,130,50,14
X    ICON            icon2,IDC_STATIC,5,125,18,20
X    PUSHBUTTON      "&Open Chart...",dbIa_o1,5,5,60,14
X    PUSHBUTTON      "Set Chart &Info...",dbIa_i1,70,5,70,14
X    PUSHBUTTON      "O&pen Chart #2...",dbIa_o2,5,25,60,14
X    PUSHBUTTON      "Set Chart #&2 Info...",dbIa_i2,70,25,70,14
X    PUSHBUTTON      "Op&en Chart #3...",dbIa_o3,5,45,60,14
X    PUSHBUTTON      "Set Chart #&3 Info...",dbIa_i3,70,45,70,14
X    PUSHBUTTON      "Ope&n Chart #4...",dbIa_o4,5,65,60,14
X    PUSHBUTTON      "Set Chart #&4 Info...",dbIa_i4,70,65,70,14
X    GROUPBOX        "Wheel Chart Is",IDC_STATIC,5,85,135,35
X    CONTROL         "&Single Wheel",dr01,"Button",BS_AUTORADIOBUTTON,10,95,
X                    55,10
X    CONTROL         "&Dual Wheel",dr02,"Button",BS_AUTORADIOBUTTON,10,105,55,
X                    10
X    CONTROL         "&Tri-Wheel",dr03,"Button",BS_AUTORADIOBUTTON,75,95,50,
X                    10
X    CONTROL         "&Quad-Wheel",dr04,"Button",BS_AUTORADIOBUTTON,75,105,50,
X                    10
END
X
X
//////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
X
accelerator ACCELERATORS DISCARDABLE 
BEGIN
X    "!",            cmdAnimateS1,           ASCII,  NOINVERT
X    "#",            cmdAnimateS3,           ASCII,  NOINVERT
X    "$",            cmdAnimateS4,           ASCII,  NOINVERT
X    "%",            cmdAnimateS5,           ASCII,  NOINVERT
X    "&",            cmdAnimateS7,           ASCII,  NOINVERT
X    "(",            cmdAnimateS9,           ASCII,  NOINVERT
X    ")",            cmdDocHomepage,         ASCII,  NOINVERT
X    "*",            cmdAnimateS8,           ASCII,  NOINVERT
X    "+",            cmdStepForward,         ASCII,  NOINVERT
X    "-",            cmdStepBackward,        ASCII,  NOINVERT
X    "<",            cmdScaleDecrease,       ASCII,  NOINVERT
X    ">",            cmdScaleIncrease,       ASCII,  NOINVERT
X    "?",            cmdHelpKeystroke,       ASCII,  NOINVERT
X    "@",            cmdAnimateS2,           ASCII,  NOINVERT
X    "[",            cmdTiltDecrease,        ASCII,  NOINVERT
X    "]",            cmdTiltIncrease,        ASCII,  NOINVERT
X    94,             cmdAnimateS6,           ASCII,  NOINVERT
X    "0",            cmdChartModify,         VIRTKEY,NOINVERT
X    "0",            cmdHelpAbout,           VIRTKEY,CONTROL, NOINVERT
X    "0",            cmdHelpCredit,          VIRTKEY,ALT, NOINVERT
X    "0",            cmdDocDefault,          VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "1",            cmdAnimateF1,           VIRTKEY,NOINVERT
X    "1",            cmdScale1,              VIRTKEY,CONTROL, NOINVERT
X    "1",            cmdHouseSetSolar,       VIRTKEY,ALT, NOINVERT
X    "1",            cmdDocSummary,          VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "2",            cmdAnimateF2,           VIRTKEY,NOINVERT
X    "2",            cmdScale2,              VIRTKEY,CONTROL, NOINVERT
X    "2",            cmdHelpSign,            VIRTKEY,ALT, NOINVERT
X    "2",            cmdDocReadme,           VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "3",            cmdAnimateF3,           VIRTKEY,NOINVERT
X    "3",            cmdScale3,              VIRTKEY,CONTROL, NOINVERT
X    "3",            cmdHelpObject,          VIRTKEY,ALT, NOINVERT
X    "3",            cmdDocUpdate,           VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "4",            cmdAnimateF4,           VIRTKEY,NOINVERT
X    "4",            cmdScale4,              VIRTKEY,CONTROL, NOINVERT
X    "4",            cmdHelpAspect,          VIRTKEY,ALT, NOINVERT
X    "4",            cmdDocHelpfile,         VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "5",            cmdAnimateF5,           VIRTKEY,NOINVERT
X    "5",            cmdSaveText,            VIRTKEY,CONTROL, NOINVERT
X    "5",            cmdHelpConstellation,   VIRTKEY,ALT, NOINVERT
X    "5",            cmdCopyText,            VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "6",            cmdAnimateF6,           VIRTKEY,NOINVERT
X    "6",            cmdSaveBitmap,          VIRTKEY,CONTROL, NOINVERT
X    "6",            cmdHelpPlanetInfo,      VIRTKEY,ALT, NOINVERT
X    "6",            cmdCopyBitmap,          VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "7",            cmdAnimateF7,           VIRTKEY,NOINVERT
X    "7",            cmdSavePicture,         VIRTKEY,CONTROL, NOINVERT
X    "7",            cmdHelpMeaning,         VIRTKEY,ALT, NOINVERT
X    "7",            cmdCopyPicture,         VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "8",            cmdAnimateF8,           VIRTKEY,NOINVERT
X    "8",            cmdSavePS,              VIRTKEY,CONTROL, NOINVERT
X    "8",            cmdHelpSwitch,          VIRTKEY,ALT, NOINVERT
X    "8",            cmdCopyPS,              VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "9",            cmdAnimateF9,           VIRTKEY,NOINVERT
X    "9",            cmdSaveSettings,        VIRTKEY,CONTROL, NOINVERT
X    "9",            cmdHelpObscure,         VIRTKEY,ALT, NOINVERT
X    "A",            cmdPen15,               VIRTKEY,CONTROL, NOINVERT
X    "A",            cmdChartGrid,           VIRTKEY,SHIFT, NOINVERT
X    "A",            cmdHouse09,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "A",            cmdAspect,              VIRTKEY,SHIFT, ALT, NOINVERT
X    "B",            cmdGraphicsBorder,      VIRTKEY,NOINVERT
X    "B",            cmdPen12,               VIRTKEY,CONTROL, NOINVERT
X    "B",            cmdSecond,              VIRTKEY,ALT, NOINVERT
X    "B",            cmdSizeChartToWindow,   VIRTKEY,SHIFT, NOINVERT
X    "B",            cmdObscure,             VIRTKEY,SHIFT, ALT, NOINVERT
X    "C",            cmdRelComparison,       VIRTKEY,NOINVERT
X    "C",            cmdFileExit,            VIRTKEY,CONTROL, NOINVERT
X    "C",            cmdResCusp,             VIRTKEY,SHIFT, NOINVERT
X    "C",            cmdHouse03,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "C",            cmdChartSettings,       VIRTKEY,SHIFT, ALT, NOINVERT
X    "D",            cmdPen08,               VIRTKEY,CONTROL, NOINVERT
X    "D",            cmdRelDate,             VIRTKEY,ALT, NOINVERT
X    "D",            cmdDefaultInfo,         VIRTKEY,SHIFT, ALT, NOINVERT
X    "E",            cmdPen01,               VIRTKEY,CONTROL, NOINVERT
X    "E",            cmdChartEphemeris,      VIRTKEY,SHIFT, NOINVERT
X    "E",            cmdHouse02,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "E",            cmdTiltZero,            VIRTKEY,SHIFT, ALT, NOINVERT
X    "F",            cmdHouseSetFlip,        VIRTKEY,NOINVERT
X    "F",            cmdPen02,               VIRTKEY,CONTROL, NOINVERT
X    "F",            cmdConstellation,       VIRTKEY,SHIFT, NOINVERT
X    "F",            cmdResTransit,          VIRTKEY,SHIFT, ALT, NOINVERT
X    "G",            cmdHouseSetDecan,       VIRTKEY,NOINVERT
X    "G",            cmdPen10,               VIRTKEY,CONTROL, NOINVERT
X    "G",            cmdChartGlobe,          VIRTKEY,SHIFT, NOINVERT
X    "G",            cmdSettingGraphics,     VIRTKEY,SHIFT, ALT, NOINVERT
X    "H",            cmdHeliocentric,        VIRTKEY,NOINVERT
X    "H",            cmdHelpKeystroke,       VIRTKEY,SHIFT, NOINVERT
X    "H",            cmdHouseSetGeodetic,    VIRTKEY,SHIFT, ALT, NOINVERT
X    "I",            cmdGraphicsModify,      VIRTKEY,NOINVERT
X    "I",            cmdSaveWallTile,        VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "I",            cmdInterpret,           VIRTKEY,SHIFT, ALT, NOINVERT
X    "J",            cmdTimedExposure,       VIRTKEY,NOINVERT
X    "J",            cmdPen14,               VIRTKEY,CONTROL, NOINVERT
X    "J",            cmdObject,              VIRTKEY,ALT, NOINVERT
X    "J",            cmdChartInfluence,      VIRTKEY,SHIFT, NOINVERT
X    "J",            cmdSaveWallCenter,      VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "J",            cmdObject2,             VIRTKEY,SHIFT, ALT, NOINVERT
X    "K",            cmdPen06,               VIRTKEY,CONTROL, NOINVERT
X    "K",            cmdColoredText,         VIRTKEY,ALT, NOINVERT
X    "K",            cmdChartCalendar,       VIRTKEY,SHIFT, NOINVERT
X    "K",            cmdHouse01,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "K",            cmdColor,               VIRTKEY,SHIFT, ALT, NOINVERT
X    "L",            cmdGraphicsLabel,       VIRTKEY,NOINVERT
X    "L",            cmdPen07,               VIRTKEY,CONTROL, NOINVERT
X    "L",            cmdChartAspect,         VIRTKEY,ALT, NOINVERT
X    "L",            cmdChartAstroGraph,     VIRTKEY,SHIFT, NOINVERT
X    "L",            cmdChartRising,         VIRTKEY,SHIFT, ALT, NOINVERT
X    "M",            cmdGraphicsMonochrome,  VIRTKEY,NOINVERT
X    "M",            cmdChartMidpoint,       VIRTKEY,ALT, NOINVERT
X    "M",            cmdChartSector,         VIRTKEY,SHIFT, NOINVERT
X    "M",            cmdHouse04,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "M",            cmdRelMidpoint,         VIRTKEY,SHIFT, ALT, NOINVERT
X    "N",            cmdNow,                 VIRTKEY,NOINVERT
X    "N",            cmdPen04,               VIRTKEY,CONTROL, NOINVERT
X    "N",            cmdRelTransit,          VIRTKEY,ALT, NOINVERT
X    "N",            cmdAnimateNow,          VIRTKEY,SHIFT, NOINVERT
X    "N",            cmdHouse14,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "N",            cmdRelProgressed,       VIRTKEY,SHIFT, ALT, NOINVERT
X    "O",            cmdStore,               VIRTKEY,NOINVERT
X    "O",            cmdPen03,               VIRTKEY,CONTROL, NOINVERT
X    "O",            cmdOpenChart,           VIRTKEY,ALT, NOINVERT
X    "O",            cmdRecall,              VIRTKEY,SHIFT, NOINVERT
X    "O",            cmdHouse11,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "O",            cmdOpenChart2,          VIRTKEY,SHIFT, ALT, NOINVERT
X    "P",            cmdAnimatePause,        VIRTKEY,NOINVERT
X    "P",            cmdPrint,               VIRTKEY,CONTROL, NOINVERT
X    "P",            cmdChartArabic,         VIRTKEY,ALT, NOINVERT
X    "P",            cmdChartPolar,          VIRTKEY,SHIFT, NOINVERT
X    "P",            cmdHouse00,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "P",            cmdProgress,            VIRTKEY,SHIFT, ALT, NOINVERT
X    "Q",            cmdFileExit,            VIRTKEY,NOINVERT
X    "Q",            cmdPrintSetup,          VIRTKEY,CONTROL, NOINVERT
X    "Q",            cmdWindowResizesChart,  VIRTKEY,ALT, NOINVERT
X    "Q",            cmdGraphicsSquare,      VIRTKEY,SHIFT, NOINVERT
X    "Q",            cmdHouse10,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "Q",            cmdChartResizesWindow,  VIRTKEY,SHIFT, ALT, NOINVERT
X    "R",            cmdAnimateReverse,      VIRTKEY,NOINVERT
X    "R",            cmdPen09,               VIRTKEY,CONTROL, NOINVERT
X    "R",            cmdRes,                 VIRTKEY,ALT, NOINVERT
X    "R",            cmdResMinor,            VIRTKEY,SHIFT, NOINVERT
X    "R",            cmdHouse05,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "R",            cmdStar,                VIRTKEY,SHIFT, ALT, NOINVERT
X    "S",            cmdSidereal,            VIRTKEY,NOINVERT
X    "S",            cmdChartOrbit,          VIRTKEY,SHIFT, NOINVERT
X    "S",            cmdSettingMore,         VIRTKEY,SHIFT, ALT, NOINVERT
X    "T",            cmdGraphicsText,        VIRTKEY,NOINVERT
X    "T",            cmdGraphicsSidebar,     VIRTKEY,ALT, NOINVERT
X    "T",            cmdHouse08,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "T",            cmdTransit,             VIRTKEY,SHIFT, ALT, NOINVERT
X    "U",            cmdResUranian,          VIRTKEY,NOINVERT
X    "U",            cmdPen05,               VIRTKEY,CONTROL, NOINVERT
X    "U",            cmdSizeWindowToChart,   VIRTKEY,ALT, NOINVERT
X    "U",            cmdResStar,             VIRTKEY,SHIFT, NOINVERT
X    "U",            cmdHouse07,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "U",            cmdWinHourglass,        VIRTKEY,SHIFT, ALT, NOINVERT
X    "V",            cmdGraphics,            VIRTKEY,NOINVERT
X    "V",            cmdPen13,               VIRTKEY,CONTROL, NOINVERT
X    "V",            cmdChartList,           VIRTKEY,SHIFT, NOINVERT
X    "V",            cmdHouse13,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "V",            cmdChartWheel,          VIRTKEY,SHIFT, ALT, NOINVERT
X    VK_BACK,        cmdWinClear,            VIRTKEY,NOINVERT
X    VK_END,         cmdScrollEnd,           VIRTKEY,NOINVERT
X    VK_ESCAPE,      cmdFileExit,            VIRTKEY,NOINVERT
X    VK_F1,          cmdMacro01,             VIRTKEY,NOINVERT
X    VK_F1,          cmdMacro25,             VIRTKEY,CONTROL, NOINVERT
X    VK_F1,          cmdMacro37,             VIRTKEY,ALT, NOINVERT
X    VK_F1,          cmdMacro13,             VIRTKEY,SHIFT, NOINVERT
X    VK_F10,         cmdMacro10,             VIRTKEY,NOINVERT
X    VK_F10,         cmdMacro34,             VIRTKEY,CONTROL, NOINVERT
X    VK_F10,         cmdMacro46,             VIRTKEY,ALT, NOINVERT
X    VK_F10,         cmdMacro22,             VIRTKEY,SHIFT, NOINVERT
X    VK_F11,         cmdMacro11,             VIRTKEY,NOINVERT
X    VK_F11,         cmdMacro35,             VIRTKEY,CONTROL, NOINVERT
X    VK_F11,         cmdMacro47,             VIRTKEY,ALT, NOINVERT
X    VK_F11,         cmdMacro23,             VIRTKEY,SHIFT, NOINVERT
X    VK_F12,         cmdMacro12,             VIRTKEY,NOINVERT
X    VK_F12,         cmdMacro36,             VIRTKEY,CONTROL, NOINVERT
X    VK_F12,         cmdMacro48,             VIRTKEY,ALT, NOINVERT
X    VK_F12,         cmdMacro24,             VIRTKEY,SHIFT, NOINVERT
X    VK_F2,          cmdMacro02,             VIRTKEY,NOINVERT
X    VK_F2,          cmdMacro26,             VIRTKEY,CONTROL, NOINVERT
X    VK_F2,          cmdMacro38,             VIRTKEY,ALT, NOINVERT
X    VK_F2,          cmdMacro14,             VIRTKEY,SHIFT, NOINVERT
X    VK_F3,          cmdMacro03,             VIRTKEY,NOINVERT
X    VK_F3,          cmdMacro27,             VIRTKEY,CONTROL, NOINVERT
X    VK_F3,          cmdMacro39,             VIRTKEY,ALT, NOINVERT
X    VK_F3,          cmdMacro15,             VIRTKEY,SHIFT, NOINVERT
X    VK_F4,          cmdMacro04,             VIRTKEY,NOINVERT
X    VK_F4,          cmdMacro28,             VIRTKEY,CONTROL, NOINVERT
X    VK_F4,          cmdMacro40,             VIRTKEY,ALT, NOINVERT
X    VK_F4,          cmdMacro16,             VIRTKEY,SHIFT, NOINVERT
X    VK_F5,          cmdMacro05,             VIRTKEY,NOINVERT
X    VK_F5,          cmdMacro29,             VIRTKEY,CONTROL, NOINVERT
X    VK_F5,          cmdMacro41,             VIRTKEY,ALT, NOINVERT
X    VK_F5,          cmdMacro17,             VIRTKEY,SHIFT, NOINVERT
X    VK_F6,          cmdMacro06,             VIRTKEY,NOINVERT
X    VK_F6,          cmdMacro30,             VIRTKEY,CONTROL, NOINVERT
X    VK_F6,          cmdMacro42,             VIRTKEY,ALT, NOINVERT
X    VK_F6,          cmdMacro18,             VIRTKEY,SHIFT, NOINVERT
X    VK_F7,          cmdMacro07,             VIRTKEY,NOINVERT
X    VK_F7,          cmdMacro31,             VIRTKEY,CONTROL, NOINVERT
X    VK_F7,          cmdMacro43,             VIRTKEY,ALT, NOINVERT
X    VK_F7,          cmdMacro19,             VIRTKEY,SHIFT, NOINVERT
X    VK_F8,          cmdMacro08,             VIRTKEY,NOINVERT
X    VK_F8,          cmdMacro32,             VIRTKEY,CONTROL, NOINVERT
X    VK_F8,          cmdMacro44,             VIRTKEY,ALT, NOINVERT
X    VK_F8,          cmdMacro20,             VIRTKEY,SHIFT, NOINVERT
X    VK_F9,          cmdMacro09,             VIRTKEY,NOINVERT
X    VK_F9,          cmdMacro33,             VIRTKEY,CONTROL, NOINVERT
X    VK_F9,          cmdMacro45,             VIRTKEY,ALT, NOINVERT
X    VK_F9,          cmdMacro21,             VIRTKEY,SHIFT, NOINVERT
X    VK_HOME,        cmdScrollHome,          VIRTKEY,NOINVERT
X    VK_NEXT,        cmdScrollPageDown,      VIRTKEY,NOINVERT
X    VK_PAUSE,       cmdAnimatePause,        VIRTKEY,NOINVERT
X    VK_PRIOR,       cmdScrollPageUp,        VIRTKEY,NOINVERT
X    VK_RETURN,      cmdCommand,             VIRTKEY,NOINVERT
X    VK_SPACE,       cmdWinRedraw,           VIRTKEY,NOINVERT
X    VK_TAB,         cmdWinBuffer,           VIRTKEY,NOINVERT
X    "W",            cmdSaveChart,           VIRTKEY,ALT, NOINVERT
X    "W",            cmdChartMap,            VIRTKEY,SHIFT, NOINVERT
X    "W",            cmdHouse12,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "W",            cmdSavePositions,       VIRTKEY,SHIFT, ALT, NOINVERT
X    "X",            cmdGraphicsReverse,     VIRTKEY,NOINVERT
X    "X",            cmdApplying,            VIRTKEY,ALT, NOINVERT
X    "X",            cmdParallel,            VIRTKEY,SHIFT, ALT, NOINVERT
X    "Y",            cmdHouseSetNavamsa,     VIRTKEY,NOINVERT
X    "Y",            cmdPen11,               VIRTKEY,CONTROL, NOINVERT
X    "Y",            cmdRelSynastry,         VIRTKEY,ALT, NOINVERT
X    "Y",            cmdRelBiorhythm,        VIRTKEY,SHIFT, NOINVERT
X    "Y",            cmdHouse06,             VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "Y",            cmdRelComposite,        VIRTKEY,SHIFT, ALT, NOINVERT
X    "Z",            cmdHouseSetVedic,       VIRTKEY,NOINVERT
X    "Z",            cmdPen00,               VIRTKEY,CONTROL, NOINVERT
X    "Z",            cmdSetInfo,             VIRTKEY,ALT, NOINVERT
X    "Z",            cmdChartHorizon,        VIRTKEY,SHIFT, NOINVERT
X    "Z",            cmdSetInfoAll,          VIRTKEY,SHIFT, CONTROL, NOINVERT
X    "Z",            cmdSetInfo2,            VIRTKEY,SHIFT, ALT, NOINVERT
END
X
X
#ifndef APSTUDIO_INVOKED
////////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
X
X
/////////////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED
X
SHAR_EOF
  $shar_touch -am 1223232998 'astrolog.rc' &&
  chmod 0644 'astrolog.rc' ||
  echo 'restore of astrolog.rc failed'
  shar_count="`wc -c < 'astrolog.rc'`"
  test 91166 -eq "$shar_count" ||
    echo "astrolog.rc: original size 91166, current size $shar_count"
fi
# ============= calc.c ==============
if test -f 'calc.c' && test X"$1" != X"-c"; then
  echo 'x - skipping calc.c (File already exists)'
else
  echo 'x - extracting calc.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'calc.c' &&
/*
** Astrolog (Version 5.40) File: calc.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
/*
******************************************************************************
** House Cusp Calculations.
******************************************************************************
*/
X
X
/* This is a subprocedure of ComputeInHouses(). Given a zodiac position,  */
/* return which of the twelve houses it falls in. Remember that a special */
/* check has to be done for the house that spans 0 degrees Aries.         */
X
int HousePlaceIn(rDeg)
real rDeg;
{
X  int i = 0;
X
X  rDeg = Mod(rDeg + 0.5/60.0/60.0);
X  do {
X    i++;
X  } while (!(i >= cSign ||
X      (rDeg >= chouse[i] && rDeg < chouse[Mod12(i+1)]) ||
X      (chouse[i] > chouse[Mod12(i+1)] &&
X      (rDeg >= chouse[i] || rDeg < chouse[Mod12(i+1)]))));
X  return i;
}
X
X
/* For each object in the chart, determine what house it belongs in. */
X
void ComputeInHouses()
{
X  int i;
X
X  for (i = 0; i <= cObj; i++)
X    inhouse[i] = HousePlaceIn(planet[i]);
}
X
X
/* This house system is just like the Equal system except that we start */
/* our 12 equal segments from the Midheaven instead of the Ascendant.   */
X
void HouseEqualMidheaven()
{
X  int i;
X
X  for (i = 1; i <= cSign; i++)
X    chouse[i] = Mod(is.MC-270.0+30.0*(real)(i-1));
}
X
X
/* Compute the cusp positions using the Alcabitius house system. */
X
void HouseAlcabitius()
{
X  real rDecl, rSda, rSna, r;
X  int i;
X
X  rDecl = RAsin(RSin(is.OB) * RSinD(is.Asc));
X  r = -RTan(AA) * RTan(rDecl);
X  rSda = DFromR(RAcos(r));
X  rSna = rDegHalf - rSda;
X  chouse[sLib] = DFromR(is.RA) - rSna;
X  chouse[sSco] = DFromR(is.RA) - rSna*2.0/3.0;
X  chouse[sSag] = DFromR(is.RA) - rSna/3.0;
X  chouse[sCap] = DFromR(is.RA);
X  chouse[sAqu] = DFromR(is.RA) + rSda/3.0;
X  chouse[sPis] = DFromR(is.RA) + rSda*2.0/3.0;
X  for (i = sLib; i <= sPis; i++)
X    chouse[i] = Mod(chouse[i]+is.rSid);
X  for (i = sAri; i <= sVir; i++)
X    chouse[i] = Mod(chouse[i+6]+rDegHalf);
}
X
X
/* This is a new house system similar in philosophy to Porphyry houses.   */
/* Instead of just trisecting the difference in each quadrant, we do a    */
/* smooth sinusoidal distribution of the difference around all the cusps. */
X
void HousePorphyryNeo()
{
X  real delta;
X  int i;
X
X  delta = (MinDistance(is.MC, is.Asc) - rDegQuad)/4.0;
X  chouse[sLib] = Mod(is.Asc+rDegHalf); chouse[sCap] = is.MC;
X  chouse[sAqu] = Mod(chouse[sCap] + 30.0 + delta   + is.rSid);
X  chouse[sPis] = Mod(chouse[sAqu] + 30.0 + delta*2 + is.rSid);
X  chouse[sSag] = Mod(chouse[sCap] - 30.0 + delta   + is.rSid);
X  chouse[sSco] = Mod(chouse[sSag] - 30.0 + delta*2 + is.rSid);
X  for (i = sAri; i < sLib; i++)
X    chouse[i] = Mod(chouse[i+6]-rDegHalf);
}
X
X
/* The "Whole" house system is like the Equal system with 30 degree houses, */
/* where the 1st house starts at zero degrees of the sign of the Ascendant. */
X
void HouseWhole()
{
X  int i;
X
X  for (i = 1; i <= cSign; i++)
X    chouse[i] = Mod((real)((SFromZ(is.Asc)-1)*30) + ZFromS(i));
}
X
X
/* The "Vedic" house system is like the Equal system except each house      */
/* starts 15 degrees earlier. The Asc falls in the middle of the 1st house. */
X
void HouseVedic()
{
X  int i;
X
X  for (i = 1; i <= cSign; i++)
X    chouse[i] = Mod(is.Asc - 15.0 + ZFromS(i));
}
X
X
/* In "null" houses, the cusps are always fixed to start at their cor-    */
/* responding sign, i.e. the 1st house is always at 0 degrees Aries, etc. */
X
void HouseNull()
{
X  int i;
X
X  for (i = 1; i <= cSign; i++)
X    chouse[i] = Mod(ZFromS(i));
}
X
X
/* Calculate the house cusp positions, using the specified algorithm. */
X
void ComputeHouses(housesystem)
int housesystem;
{
X  char sz[cchSzDef];
X
X  if (RAbs(AA) > RFromD(rDegQuad-rAxis) && housesystem < 2) {
X    sprintf(sz,
X      "The %s system of houses is not defined at extreme latitudes.",
X      szSystem[housesystem]);
X    PrintWarning(sz);
X    AA = RSgn2(AA)*RFromD(rDegQuad-rAxis);
X  }
X
X  /* Flip the Ascendant if it falls in the wrong half of the zodiac. */
X  if (MinDifference(is.MC, is.Asc) < 0.0)
X    is.Asc = Mod(is.Asc + rDegHalf);
X
X  switch (housesystem) {
X  case  1: HouseKoch();           break;
X  case  2: HouseEqual();          break;
X  case  3: HouseCampanus();       break;
X  case  4: HouseMeridian();       break;
X  case  5: HouseRegiomontanus();  break;
X  case  6: HousePorphyry();       break;
X  case  7: HouseMorinus();        break;
X  case  8: HouseTopocentric();    break;
X  case  9: HouseAlcabitius();     break;
X  case 10: HouseEqualMidheaven(); break;
X  case 11: HousePorphyryNeo();    break;
X  case 12: HouseWhole();          break;
X  case 13: HouseVedic();          break;
X  case 14: HouseNull();           break;
X  default: HousePlacidus();
X  }
}
X
X
/*
******************************************************************************
** Star Position Calculations.
******************************************************************************
*/
X
/* This is used by the chart calculation routine to calculate the positions */
/* of the fixed stars. Since the stars don't move in the sky over time,     */
/* getting their positions is mostly just reading info from an array and    */
/* converting it to the correct reference frame. However, we have to add    */
/* in the correct precession for the tropical zodiac, and sort the final    */
/* index list based on what order the stars are supposed to be printed in.  */
X
void ComputeStars(SD)
real SD;
{
X  int i, j;
X  real x, y, z;
X
X  /* Read in star positions. */
X
X  for (i = 1; i <= cStar; i++) {
X    x = rStarData[i*6-6]; y = rStarData[i*6-5]; z = rStarData[i*6-4];
X    planet[oNorm+i] = RFromD(x*rDegMax/24.0+y*15.0/60.0+z*0.25/60.0);
X    x = rStarData[i*6-3]; y = rStarData[i*6-2]; z = rStarData[i*6-1];
X    if (x < 0.0) {
X      neg(y); neg(z);
X    }
X    planetalt[oNorm+i] = RFromD(x+y/60.0+z/60.0/60.0);
X    /* Convert to ecliptic zodiac coordinates. */
X    EquToEcl(&planet[oNorm+i], &planetalt[oNorm+i]);
X    planet[oNorm+i] = Mod(DFromR(planet[oNorm+i])+rEpoch2000+SD);
X    planetalt[oNorm+i] = DFromR(planetalt[oNorm+i]);
X    ret[oNorm+i] = RFromD(rDegMax/26000.0/365.25);
X    starname[i] = i;
X  }
X
X  /* Sort the index list if -Uz, -Ul, -Un, or -Ub switch in effect. */
X
X  if (us.nStar > 1) for (i = 2; i <= cStar; i++) {
X    j = i-1;
X
X    /* Compare star names for -Un switch. */
X
X    if (us.nStar == 'n') while (j > 0 && NCompareSz(
X      szObjName[oNorm+starname[j]], szObjName[oNorm+starname[j+1]]) > 0) {
X      SwapN(starname[j], starname[j+1]);
X      j--;
X
X    /* Compare star brightnesses for -Ub switch. */
X
X    } else if (us.nStar == 'b') while (j > 0 &&
X      rStarBright[starname[j]] > rStarBright[starname[j+1]]) {
X      SwapN(starname[j], starname[j+1]);
X      j--;
X
X    /* Compare star zodiac locations for -Uz switch. */
X
X    } else if (us.nStar == 'z') while (j > 0 &&
X      planet[oNorm+starname[j]] > planet[oNorm+starname[j+1]]) {
X      SwapN(starname[j], starname[j+1]);
X      j--;
X
X    /* Compare star declinations for -Ul switch. */
X
X    } else if (us.nStar == 'l') while (j > 0 &&
X      planetalt[oNorm+starname[j]] < planetalt[oNorm+starname[j+1]]) {
X      SwapN(starname[j], starname[j+1]);
X      j--;
X    }
X  }
}
X
X
/*
******************************************************************************
** Chart Calculation.
******************************************************************************
*/
X
/* Given a zodiac degree, transform it into its Decan sign, where each    */
/* sign is trisected into the three signs of its element. For example,    */
/* 1 Aries -> 3 Aries, 10 Leo -> 0 Sagittarius, 25 Sagittarius -> 15 Leo. */
X
real Decan(deg)
real deg;
{
X  int sign;
X  real unit;
X
X  sign = SFromZ(deg);
X  unit = deg - ZFromS(sign);
X  sign = Mod12(sign + 4*((int)RFloor(unit/10.0)));
X  unit = (unit - RFloor(unit/10.0)*10.0)*3.0;
X  return ZFromS(sign)+unit;
}
X
X
/* Given a zodiac degree, transform it into its Navamsa position, where   */
/* each sign is divided into ninths, which determines the number of signs */
/* after a base element sign to use. Degrees within signs are unaffected. */
X
real Navamsa(deg)
real deg;
{
X  int sign, sign2;
X  real unit;
X
X  sign = SFromZ(deg);
X  unit = deg - ZFromS(sign);
X  sign2 = Mod12(((sign-1 & 3)^(2*(sign-1 & 1)))*3+(int)(unit*0.3)+1);
X  return ZFromS(sign2)+unit;
}
X
X
/* Transform spherical to rectangular coordinates in x, y, z. */
X
void SphToRec(r, azi, alt, rx, ry, rz)
real r, azi, alt, *rx, *ry, *rz;
{
X  real rT;
X
X  *rz = r *RSinD(alt);
X  rT  = r *RCosD(alt);
X  *rx = rT*RCosD(azi);
X  *ry = rT*RSinD(azi);
}
X
X
#ifdef PLACALC
/* Compute the positions of the planets at a certain time using the Placalc */
/* accurate formulas and ephemeris. This will supersede the Matrix routine  */
/* values and is only called with the -b switch is in effect. Not all       */
/* objects or modes are available using this, but some additional values    */
/* such as Moon and Node velocities not available without -b are. (This is  */
/* the one place in Astrolog which calls the Placalc package functions.)    */
X
void ComputePlacalc(t)
real t;
{
X  int i;
X  real r1, r2, r3, r4;
X
X  /* We can compute the positions of Sun through Pluto, Chiron, the four */
X  /* asteroids, Lilith, and the (true or mean) North Node using Placalc. */
X  /* The other objects must be done elsewhere.                           */
X
X  for (i = oSun; i <= oLil; i++) {
X    if ((ignore[i] && i > oMoo) ||
X      (us.fPlacalcAst && FBetween(i, oCer, oVes)))
X      continue;
X    if (FPlacalcPlanet(i, t*36525.0+2415020.0, us.objCenter != oEar,
X      &r1, &r2, &r3, &r4)) {
X
X      /* Note that this can't compute charts with central planets other */
X      /* than the Sun or Earth or relative velocities in current state. */
X
X      planet[i]    = Mod(r1 + is.rSid);
X      planetalt[i] = r2;
X      ret[i]       = RFromD(r3);
X
X      /* Compute x,y,z coordinates from azimuth, altitude, and distance. */
X
X      SphToRec(r4, planet[i], planetalt[i],
X        &spacex[i], &spacey[i], &spacez[i]);
X    }
X  }
X
X  /* If heliocentric, move Earth position to object slot zero. */
X
X  i = us.objCenter != oEar;
X  if (i) {
X    planet[oEar] = planet[oSun];
X    planetalt[oEar] = planetalt[oSun];
X    ret[oEar] = ret[oSun];
X    spacex[oEar] = spacex[oSun];
X    spacey[oEar] = spacey[oSun];
X    spacez[oEar] = spacez[oSun];
X  }
X  spacex[i] = spacey[i] = spacez[i] =
X    planet[i] = planetalt[i] = ret[i] = 0.0;
X  if (us.objCenter < oMoo)
X    return;
X
X  /* If other planet centered, shift all positions as in Matrix formulas. */
X
X  for (i = 0; i <= oLil; i++) if (!FIgnore(i)) {
X    spacex[i] -= spacex[us.objCenter];
X    spacey[i] -= spacey[us.objCenter];
X    spacez[i] -= spacez[us.objCenter];
X    ProcessPlanet(i, 0.0);
X  }
X  spacex[us.objCenter] = spacey[us.objCenter] = spacez[us.objCenter] =
X    planet[us.objCenter] = planetalt[us.objCenter] = ret[us.objCenter] = 0.0;
}
#endif
X
X
/* This is probably the main routine in all of Astrolog. It generates a   */
/* chart, calculating the positions of all the celestial bodies and house */
/* cusps, based on the current chart information, and saves them for use  */
/* by any of the display routines.                                        */
X
real CastChart(fDate)
bool fDate;
{
X  CI ci;
X  real housetemp[cSign+1], Off = 0.0, vtx, j;
X  int i, k;
X
X  /* Hack: Time zone +/-24 means to have the time of day be in Local Mean */
X  /* Time (LMT). This is done by making the time zone value reflect the   */
X  /* logical offset from GMT as indicated by the chart's longitude value. */
X
X  if (RAbs(ZZ) == 24.0)
X    ZZ = DegToDec(DecToDeg(OO)/15.0);
X  ci = ciCore;
X
X  if (MM == -1) {
X
X    /* Hack: If month is negative, then we know chart was read in through a  */
X    /* -o0 position file, so the planet positions are already in the arrays. */
X
X    is.MC = planet[oMC]; is.Asc = planet[oAsc];
X  } else {
X    for (i = 0; i <= cObj; i++) {
X      planet[i] = planetalt[i] = 0.0;    /* On ecliptic unless we say so.  */
X      ret[i] = 1.0;                      /* Direct until we say otherwise. */
X    }
X    Off = ProcessInput(fDate);
X    ComputeVariables(&vtx);
X    if (us.fGeodetic)               /* Check for -G geodetic chart. */
X      is.RA = RFromD(Mod(-OO));
X    is.MC  = CuspMidheaven();       /* Calculate our Ascendant & Midheaven. */
X    is.Asc = CuspAscendant();
X    ComputeHouses(us.nHouseSystem); /* Go calculate house cusps. */
X
X    /* Go calculate planet, Moon, and North Node positions. */
X
X    ComputePlanets();
X    if (!ignore[oMoo] || !ignore[oNod] || !ignore[oSou] || !ignore[oFor]) {
X      ComputeLunar(&planet[oMoo], &planetalt[oMoo],
X        &planet[oNod], &planetalt[oNod]);
X      ret[oNod] = -1.0;
X    }
X
X    /* Compute more accurate ephemeris positions for certain objects. */
X
#ifdef PLACALC
X    if (us.fPlacalc)
X      ComputePlacalc(is.T);
#endif
X    if (!us.fPlacalc) {
X      planet[oSou] = Mod(planet[oNod]+rDegHalf);
X      ret[oSou] = ret[oNod] = RFromD(-0.053);
X      ret[oMoo] = RFromD(12.5);
X    }
X
X    /* Calculate position of Part of Fortune. */
X
X    j = planet[oMoo]-planet[oSun];
X    if (us.nArabicNight < 0 ||
X      (us.nArabicNight == 0 && HousePlaceIn(planet[oSun]) < sLib))
X      neg(j);
X    j = RAbs(j) < rDegQuad ? j : j - RSgn(j)*rDegMax;
X    planet[oFor] = Mod(j+is.Asc);
X
X    /* Fill in "planet" positions corresponding to house cusps. */
X
X    planet[oVtx] = vtx; planet[oEP] = CuspEastPoint();
X    for (i = 1; i <= cSign; i++)
X      planet[cuspLo + i - 1] = chouse[i];
X    if (!us.fHouseAngle) {
X      planet[oAsc] = is.Asc; planet[oMC] = is.MC;
X      planet[oDes] = Mod(is.Asc + rDegHalf);
X      planet[oNad] = Mod(is.MC + rDegHalf);
X    }
X    for (i = oFor; i <= cuspHi; i++)
X      ret[i] = RFromD(rDegMax);
X  }
X
X  /* Go calculate star positions if -U switch in effect. */
X
X  if (us.nStar)
X    ComputeStars(us.fSidereal ? 0.0 : -Off);
X
X  /* Transform ecliptic to equatorial coordinates if -sr in effect. */
X
X  if (us.fEquator)
X    for (i = 0; i <= cObj; i++) if (!ignore[i]) {
X      planet[i]    = RFromD(Tropical(planet[i]));
X      planetalt[i] = RFromD(planetalt[i]);
X      EclToEqu(&planet[i], &planetalt[i]);
X      planet[i]    = DFromR(planet[i]);
X      planetalt[i] = DFromR(planetalt[i]);
X    }
X
X  /* Now, we may have to modify the base positions we calculated above */
X  /* based on what type of chart we are generating.                    */
X
X  if (us.fProgress && us.fSolarArc) {  /* Are we doing -p0 solar arc chart? */
X    for (i = 0; i <= cObj; i++)
X      planet[i] = Mod(planet[i] + (is.JDp - is.JD) / us.rProgDay);
X    for (i = 1; i <= cSign; i++)
X      chouse[i]  = Mod(chouse[i]  + (is.JDp - is.JD) / us.rProgDay);
X    }
X  if (us.nHarmonic > 1)            /* Are we doing a -x harmonic chart?     */
X    for (i = 0; i <= cObj; i++)
X      planet[i] = Mod(planet[i] * (real)us.nHarmonic);
X  if (us.objOnAsc) {
X    if (us.objOnAsc > 0)           /* Is -1 put on Ascendant in effect?     */
X      j = planet[us.objOnAsc]-is.Asc;
X    else                           /* Or -2 put object on Midheaven switch? */
X      j = planet[-us.objOnAsc]-is.MC;
X    for (i = 1; i <= cSign; i++)   /* If so, rotate the houses accordingly. */
X      chouse[i] = Mod(chouse[i]+j);
X  }
X
X  /* Check to see if we are -F forcing any objects to be particular values. */
X
X  for (i = 0; i <= cObj; i++)
X    if (force[i] != 0.0) {
X      planet[i] = force[i]-rDegMax;
X      planetalt[i] = ret[i] = 0.0;
X    }
X
X  ComputeInHouses();        /* Figure out what house everything falls in. */
X
X  /* If -f domal chart switch in effect, switch planet and house positions. */
X
X  if (us.fFlip) {
X    for (i = 0; i <= cObj; i++) {
X      k = inhouse[i];
X      inhouse[i] = SFromZ(planet[i]);
X      planet[i] = ZFromS(k)+MinDistance(chouse[k], planet[i]) /
X        MinDistance(chouse[k], chouse[Mod12(k+1)])*30.0;
X    }
X    for (i = 1; i <= cSign; i++) {
X      k = HousePlaceIn(ZFromS(i));
X      housetemp[i] = ZFromS(k)+MinDistance(chouse[k], ZFromS(i)) /
X        MinDistance(chouse[k], chouse[Mod12(k+1)])*30.0;
X    }
X    for (i = 1; i <= cSign; i++)
X      chouse[i] = housetemp[i];
X  }
X
X  /* If -3 decan chart switch in effect, edit planet positions accordingly. */
X
X  if (us.fDecan) {
X    for (i = 0; i <= cObj; i++)
X      planet[i] = Decan(planet[i]);
X    ComputeInHouses();
X  }
X
X  /* If -9 navamsa chart switch in effect, edit positions accordingly. */
X
X  if (us.fNavamsa) {
X    for (i = 0; i <= cObj; i++)
X      planet[i] = Navamsa(planet[i]);
X    ComputeInHouses();
X  }
X
X  ciCore = ci;
X  return is.T;
}
X
X
/* Calculate the position of each planet with respect to the Gauquelin      */
/* sectors. This is used by the sector charts. Fill out the planet position */
/* array where one degree means 1/10 the way across one of the 36 sectors.  */
X
void CastSectors()
{
X  int source[MAXINDAY], type[MAXINDAY], occurcount, division, div,
X    i, j, s1, s2, ihouse, fT;
X  real time[MAXINDAY], rgalt1[objMax], rgalt2[objMax],
X    azi1, azi2, alt1, alt2, lon, lat, mc1, mc2, d, k;
X
X  /* If the -l0 approximate sectors flag is set, we can quickly get rough   */
X  /* positions by having each position be the location of the planet as     */
X  /* mapped into Placidus houses. The -f flip houses flag does this for us. */
X
X  if (us.fSectorApprox) {
X    ihouse = us.nHouseSystem; us.nHouseSystem = 0;
X    not(us.fFlip);
X    CastChart(fTrue);
X    not(us.fFlip);
X    us.nHouseSystem = ihouse;
X    return;
X  }
X
X  /* If not approximating sectors, then they need to be computed the formal */
X  /* way: based on a planet's nearest rising and setting times. The code    */
X  /* below is similar to ChartInDayHorizon() accessed by the -Zd switch.    */
X
X  fT = us.fSidereal; us.fSidereal = fFalse;
X  lon = RFromD(Mod(Lon)); lat = RFromD(Lat);
X  division = us.nDivision * 4;
X  occurcount = 0;
X
X  /* Start scanning from 18 hours before to 18 hours after the time of the */
X  /* chart in question, to find the closest rising and setting times.      */
X
X  ciCore = ciMain; ciCore.tim -= 18.0;
X  if (ciCore.tim < 0.0) {
X    ciCore.tim += 24.0;
X    ciCore.day--;
X  }
X  CastChart(fTrue);
X  mc2 = RFromD(planet[oMC]); k = RFromD(planetalt[oMC]);
X  EclToEqu(&mc2, &k);
X  cp2 = cp0;
X  for (i = 1; i <= cObj; i++) {
X    rgalt2[i] = planetalt[i];
X  }
X
X  /* Loop through 36 hours, dividing it into a certain number of segments. */
X  /* For each segment we get the planet positions at its endpoints.        */
X
X  for (div = 1; div <= division; div++) {
X    ciCore = ciMain;
X    ciCore.tim = DecToDeg(ciCore.tim) - 18.0 + 36.0*(real)div/(real)division;
X    if (ciCore.tim < 0.0) {
X      ciCore.tim += 24.0;
X      ciCore.day--;
X    } else if (ciCore.tim >= 24.0) {
X      ciCore.tim -= 24.0;
X      ciCore.day++;
X    }
X    ciCore.tim = DegToDec(ciCore.tim);
X    CastChart(fTrue);
X    mc1 = mc2;
X    mc2 = RFromD(planet[oMC]); k = RFromD(planetalt[oMC]);
X    EclToEqu(&mc2, &k);
X    cp1 = cp2; cp2 = cp0;
X    for (i = 1; i <= cObj; i++) {
X      rgalt1[i] = rgalt2[i]; rgalt2[i] = planetalt[i];
X    }
X
X    /* During our segment, check to see if each planet rises or sets. */
X
X    for (i = 0; i <= cObj; i++) if (!FIgnore(i) && FThing(i)) {
X      EclToHorizon(&azi1, &alt1, cp1.obj[i], rgalt1[i], lon, lat, mc1);
X      EclToHorizon(&azi2, &alt2, cp2.obj[i], rgalt2[i], lon, lat, mc2);
X      j = 0;
X      if ((alt1 > 0.0) != (alt2 > 0.0)) {
X        d = RAbs(alt1)/(RAbs(alt1)+RAbs(alt2));
X        k = Mod(azi1 + d*MinDifference(azi1, azi2));
X        j = 1 + (MinDistance(k, rDegHalf) < rDegQuad);
X      }
X      if (j && occurcount < MAXINDAY) {
X        source[occurcount] = i;
X        type[occurcount] = j;
X        time[occurcount] = 36.0*((real)(div-1)+d)/(real)division*60.0;
X        occurcount++;
X      }
X    }
X  }
X
X  /* Sort each event in order of time when it happens during the day. */
X
X  for (i = 1; i < occurcount; i++) {
X    j = i-1;
X    while (j >= 0 && time[j] > time[j+1]) {
X      SwapN(source[j], source[j+1]);
X      SwapN(type[j], type[j+1]);
X      SwapR(&time[j], &time[j+1]);
X      j--;
X    }
X  }
X
X  /* Now fill out the planet array with the appropriate sector location. */
X
X  for (i = 1; i <= cObj; i++) if (!ignore[i] && FThing(i)) {
X    planet[i] = 0.0;
X    /* Search for the first rising or setting event of our planet. */
X    for (s2 = 0; s2 < occurcount && source[s2] != i; s2++)
X      ;
X    if (s2 == occurcount)
X      {
LFail:
X      /* If we failed to find a rising/setting bracket around our time, */
X      /* automatically restrict that planet so it doesn't show up.      */
X      ignore[i] = fTrue;
X      continue;
X      }
LRetry:
X    /* One rising or setting event was found. Now search for the next one. */
X    s1 = s2;
X    for (s2 = s1 + 1; s2 < occurcount && source[s2] != i; s2++)
X      ;
X    if (s2 == occurcount)
X      goto LFail;
X    /* Reject the two events if either (1) they're both the same, i.e. both */
X    /* rising or both setting, or (2) they don't bracket the chart's time.  */
X    if (type[s2] == type[s1] || time[s1] > 18.0*60.0 || time[s2] < 18.0*60.0)
X      goto LRetry;
X    /* Cool, we've found our rising/setting bracket. The sector position is */
X    /* the proportion the chart time is between the two event times.        */
X    planet[i] = (18.0*60.0 - time[s1])/(time[s2] - time[s1])*rDegHalf;
X    if (type[s1] == 2)
X      planet[i] += rDegHalf;
X    planet[i] = Mod(rDegMax - planet[i]);
X  }
X
X  /* Restore original chart info as we've overwritten it. */
X
X  ciCore = ciMain;
X  us.fSidereal = fT;
}
X
X
/*
******************************************************************************
** Aspect Calculations.
******************************************************************************
*/
X
/* Set up the aspect/midpoint grid. Allocate memory for this array, if not */
/* already done. Allocation is only done once, first time this is called.  */
X
bool FEnsureGrid()
{
X  if (grid != NULL)
X    return fTrue;
X  grid = (GridInfo FPTR *)PAllocate(sizeof(GridInfo), fFalse, "grid");
X  return grid != NULL;
}
X
X
/* Indicate whether some aspect between two objects should be shown. */
X
bool FAcceptAspect(obj1, asp, obj2)
int obj1, asp, obj2;
{
X  int fSupp;
X
X  if (ignorea(asp))    /* If the aspect restricted, reject immediately. */
X    return fFalse;
X  if (us.fSmartCusp) {
X
X    /* Allow only conjunctions to the minor house cusps. */
X
X    if ((FMinor(obj1) || FMinor(obj2)) && asp > aCon)
X      return fFalse;
X
X    /* Prevent any simultaneous aspects to opposing angle cusps,     */
X    /* e.g. if conjunct one, don't be opposite the other; if trine   */
X    /* one, don't sextile the other; don't square both at once, etc. */
X
X    fSupp = (asp == aOpp || asp == aSex || asp == aSSx || asp == aSes);
X    if ((FAngle(obj1) || FAngle(obj2)) &&
X      (fSupp || (asp == aSqu &&
X      (obj1 == oDes || obj2 == oDes || obj1 == oNad || obj2 == oNad))))
X      return fFalse;
X
X    /* Prevent any simultaneous aspects to the North and South Node. */
X
X    if (fSouthNode) {
X      if (((obj1 == oNod || obj2 == oNod) && fSupp) ||
X        ((obj1 == oSou || obj2 == oSou) && (fSupp || asp == aSqu)))
X        return fFalse;
X    }
X  }
X  return fTrue;
}
X
X
/* This is a subprocedure of FCreateGrid() and FCreateGridRelation().   */
/* Given two planets, determine what aspect, if any, is present between */
/* them, and save the aspect name and orb in the specified grid cell.   */
X
void GetAspect(planet1, planet2, ret1, ret2, i, j)
real *planet1, *planet2, *ret1, *ret2;
int i, j;
{
X  int k;
X  real l, m;
X
X  grid->v[i][j] = grid->n[i][j] = 0;
X  l = MinDistance(planet2[i], planet1[j]);
X  for (k = us.nAsp; k >= 1; k--) {
X    if (!FAcceptAspect(i, k, j))
X      continue;
X    m = l-rAspAngle[k];
X    if (RAbs(m) < GetOrb(i, j, k)) {
X      grid->n[i][j] = k;
X
X      /* If -ga switch in effect, then change the sign of the orb to    */
X      /* correspond to whether the aspect is applying or separating.    */
X      /* To do this, we check the velocity vectors to see if the        */
X      /* planets are moving toward, away, or are overtaking each other. */
X
X      if (us.fAppSep)
X        m = RSgn2(ret1[j]-ret2[i])*
X          RSgn2(MinDifference(planet2[i], planet1[j]))*RSgn2(m)*RAbs(m);
X      grid->v[i][j] = (int)(m*60.0);
X    }
X  }
}
X
X
/* Very similar to GetAspect(), this determines if there is a parallel or */
/* contraparallel aspect between the given two planets, and stores the    */
/* result as above. The settings and orbs for conjunction are used for    */
/* parallel and those for opposition are used for contraparallel.         */
X
void GetParallel(planet1, planet2, planetalt1, planetalt2, i, j)
real *planet1, *planet2, *planetalt1, *planetalt2;
int i, j;
{
X  int k;
X  real l, alt1, alt2;
X
X  l = RFromD(planet1[j]); alt1 = RFromD(planetalt1[j]);
X  EclToEqu(&l, &alt1); alt1 = DFromR(alt1);
X  l = RFromD(planet2[i]); alt2 = RFromD(planetalt2[i]);
X  EclToEqu(&l, &alt2); alt2 = DFromR(alt2);
X  grid->v[i][j] = grid->n[i][j] = 0;
X  for (k = Min(us.nAsp, aOpp); k >= 1; k--) {
X    if (!FAcceptAspect(i, k, j))
X      continue;
X    l = RAbs(k == aCon ? alt1 - alt2 : RAbs(alt1) - RAbs(alt2));
X    if (l < GetOrb(i, j, k)) {
X      grid->n[i][j] = k;
X      grid->v[i][j] = (int)(l*60.0);
X    }
X  }
}
X
X
/* Fill in the aspect grid based on the aspects taking place among the */
/* planets in the present chart. Also fill in the midpoint grid.       */
X
bool FCreateGrid(fFlip)
bool fFlip;
{
X  int i, j, k;
X  real l;
X
X  if (!FEnsureGrid())
X    return fFalse;
X  for (j = 0; j <= cObj; j++) if (!FIgnore(j))
X    for (i = 0; i <= cObj; i++) if (!FIgnore(i))
X
X      /* The parameter 'flip' determines what half of the grid is filled in */
X      /* with the aspects and what half is filled in with the midpoints.    */
X
X      if (fFlip ? i > j : i < j) {
X        if (us.fParallel)
X          GetParallel(planet, planet, planetalt, planetalt, i, j);
X        else
X          GetAspect(planet, planet, ret, ret, i, j);
X      } else if (fFlip ? i < j : i > j) {
X        l = Mod(Midpoint(planet[i], planet[j])); k = (int)l;  /* Calculate */
X        grid->n[i][j] = k/30+1;                               /* midpoint. */
X        grid->v[i][j] = (int)((l-(real)(k/30)*30.0)*60.0);
X      } else {
X        grid->n[i][j] = SFromZ(planet[j]);
X        grid->v[i][j] = (int)(planet[j]-(real)(grid->n[i][j]-1)*30.0);
X      }
X  return fTrue;
}
X
X
/* This is similar to the previous function; however, this time fill in the */
/* grid based on the aspects (or midpoints if 'acc' set) taking place among */
/* the planets in two different charts, as in the -g -r0 combination.       */
X
bool FCreateGridRelation(fMidpoint)
bool fMidpoint;
{
X  int i, j, k;
X  real l;
X
X  if (!FEnsureGrid())
X    return fFalse;
X  for (j = 0; j <= cObj; j++) if (!FIgnore(j) || !FIgnore2(j))
X    for (i = 0; i <= cObj; i++) if (!FIgnore(i) || !FIgnore2(i))
X      if (!fMidpoint) {
X        if (us.fParallel)
X          GetParallel(cp1.obj, cp2.obj, cp1.alt, cp2.alt, i, j);
X        else
X          GetAspect(cp1.obj, cp2.obj, cp1.dir, cp2.dir, i, j);
X      } else {
X        l = Mod(Midpoint(cp2.obj[i], cp1.obj[j])); k = (int)l; /* Calculate */
X        grid->n[i][j] = k/30+1;                                /* midpoint. */
X        grid->v[i][j] = (int)((l-(real)(k/30)*30.0)*60.0);
X      }
X  return fTrue;
}
X
X
/*
******************************************************************************
** Other Calculations.
******************************************************************************
*/
X
/* Fill out tables based on the number of unrestricted planets in signs by  */
/* element, signs by mode, as well as other values such as the number of    */
/* objects in yang vs. yin signs, in various house hemispheres (north/south */
/* and east/west), and the number in first six signs vs. second six signs.  */
/* This is used by the -v chart listing and the sidebar in graphics charts. */
X
void CreateElemTable(pet)
ET *pet;
{
X  int i, s;
X
X  ClearB((lpbyte)pet, (int)sizeof(ET));
X  for (i = 0; i <= cObj; i++) if (!FIgnore(i)) {
X    pet->coSum++;
X    s = SFromZ(planet[i]);
X    pet->coSign[s-1]++;
X    pet->coElemMode[(s-1)&3][(s-1)%3]++;
X    pet->coElem[(s-1)&3]++; pet->coMode[(s-1)%3]++;
X    pet->coYang += (s & 1);
X    pet->coLearn += (s < sLib);
X    if (!FCusp(i)) {
X      pet->coHemi++;
X      s = inhouse[i];
X      pet->coHouse[s-1]++;
X      pet->coModeH[(s-1)%3]++;
X      pet->coMC += (s >= sLib);
X      pet->coAsc += (s < sCan || s >= sCap);
X    }
X  }
X  pet->coYin   = pet->coSum  - pet->coYang;
X  pet->coShare = pet->coSum  - pet->coLearn;
X  pet->coDes   = pet->coHemi - pet->coAsc;
X  pet->coIC    = pet->coHemi - pet->coMC;
}
X
/* calc.c */
SHAR_EOF
  $shar_touch -am 1223232998 'calc.c' &&
  chmod 0644 'calc.c' ||
  echo 'restore of calc.c failed'
  shar_count="`wc -c < 'calc.c'`"
  test 30138 -eq "$shar_count" ||
    echo "calc.c: original size 30138, current size $shar_count"
fi
# ============= charts0.c ==============
if test -f 'charts0.c' && test X"$1" != X"-c"; then
  echo 'x - skipping charts0.c (File already exists)'
else
  echo 'x - extracting charts0.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'charts0.c' &&
/*
** Astrolog (Version 5.40) File: charts0.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
/*
******************************************************************************
** Table Display Routines.
******************************************************************************
*/
X
/* A subprocedure of the credit displayed below, this prints out one line */
/* of credit information on the screen. Given a string, it's displayed    */
/* centered with left and right borders around it, in the given color.    */
X
void PrintW(sz, col)
char *sz;
int col;
{
X  int i;
X
X  if (!sz) {
X
X    /* Null string means print the top, bottom, or a separator row. */
X
X    if (col < 0)
X      AnsiColor(kRed);
X    PrintCh((char)(col ? (col > 0 ? chSW : chNW) : chJE));
X    PrintTab(chH, CREDITWIDTH);
X    PrintCh((char)(col ? (col > 0 ? chSE : chNE) : chJW));
X  } else {
X    i = CchSz(sz);
X    PrintCh(chV);
X    PrintTab(' ', (CREDITWIDTH-i)/2 + (i&1));
X    AnsiColor(col);
X    PrintSz(sz);
X    PrintTab(' ', (CREDITWIDTH-i)/2);
X    AnsiColor(kRed);
X    PrintCh(chV);
X  }
X  PrintL();
}
X
X
/* Display a list of credits showing those who helped create the various  */
/* parts of Astrolog, as well as important copyright and version info, as */
/* displayed with the -Hc switch.                                         */
X
void DisplayCredits()
{
X  char sz[cchSzDef];
X
X  PrintW(NULL, -1);
X  sprintf(sz, "** %s version %s **", szAppName, szVersionCore);
X  PrintW(sz, kWhite);
X  sprintf(sz, "As of %s. By Walter D. Pullen", szDateCore);
X  PrintW(sz, kLtGray);
X  sprintf(sz, "(%s)", szAddressCore); PrintW(sz, kCyan);
X  PrintW(NULL, 0);
X  PrintW("Main planetary calculation formulas were converted from", kGreen);
X  PrintW(
X    "routines by James Neely, as listed in 'Manual of Computer Programming",
X    kGreen);
X  PrintW(
X    "for Astrologers' by Michael Erlewine, available from Matrix Software.",
X    kGreen);
X  PrintW("PostScript graphics routines by Brian D. Willoughby.", kYellow);
X  PrintW(
X    "Extended ephemeris calculation and formulas are by Alois Treindl,",
X    kMagenta);
X  PrintW(
X    "as in the package 'Placalc', available from Astrodienst AG.", kMagenta);
X  PrintW(
X    "IMPORTANT: Astrolog is 'freeware', but is copyrighted and not in public",
X    kLtGray);
X  PrintW(
X    "domain. Permission is granted to freely use and distribute these",
X    kLtGray);
X  PrintW(
X    "routines provided one does not sell, restrict, or profit from the",
X    kLtGray);
X  PrintW(
X    "program or its output in any way. Modification is allowed provided",
X    kLtGray);
X  PrintW(
X    "these exact notices remain with any altered or edited versions of the",
X    kLtGray);
X  PrintW(
X    "program. These conditions are true of both the program in whole and of",
X    kLtGray);
X  PrintW(
X    "all parts by any individual author. Violators are subject to copyright",
X    kLtGray);
X  PrintW(
X    "law penalties, and negative karmic debts to aforementioned contributors.",
X    kLtGray);
X  PrintW(NULL, 0);
X  PrintW(
X    "Special thanks to all those unmentioned, seen and unseen, who have",
X     kBlue);
X  PrintW(
X    "pointed out problems, suggested features, & sent many positive vibes! :)",
X    kBlue);
X  PrintW(NULL, 1);
X  AnsiColor(kDefault);
}
X
X
/* Print out a command switch or keypress info line to the screen, as done  */
/* with the -H switch or 'H' key in a graphic window. This is just printing */
/* out the string, except in Ansi mode we set the proper colors: Red for    */
/* header lines, Green for individual switches or keys, and White for the   */
/* rest of the line telling what it does. We also prefix each switch with   */
/* either Unix's '-' or PC's '/', whichever is appropriate for the system.  */
X
void PrintS(sz)
char *sz;
{
X  int chDash;
X  char ch;
X
X  chDash = sz[1];
X  if (*sz != ' ')
X    AnsiColor(kRed);
X  else if (chDash != ' ')
X    AnsiColor(chDash == 'P' || sz[3] == ' ' || sz[3] == ':' ?
X      kGreen : kDkGreen);
X  else
X    AnsiColor(kDefault);
X  while ((ch = *sz) && ch != ':' &&
X    (chDash != 'P' || (ch != ' ' || *(sz+1) != 't'))) {
X    if (ch != '_')
X      PrintCh(ch);
X    else
X      PrintCh(chSwitch);
X    sz++;
X  }
X  if (*sz)
X    PrintCh(*sz++);
X  AnsiColor(kDefault);
X  while (ch = *sz) {
X    if (ch != '_')
X      PrintCh(ch);
X    else
X      PrintCh(chSwitch);
X    sz++;
X  }
X  PrintL();
}
X
X
/* Print a list of every command switch that can be passed to the program, */
/* and a description of what it does. This is what the -H switch prints.   */
X
void DisplaySwitches()
{
X  char sz[cchSzDef];
X
X  sprintf(sz, "%s (version %s) command switches:", szAppName, szVersionCore);
X  PrintS(sz);
X  PrintS(" _H: Display this help list.");
X  PrintS(" _Hc: Display program credits and copyrights.");
X  PrintS(" _HC: Display names of zodiac signs and houses.");
X  PrintS(" _HO: Display available planets and other celestial objects.");
X  PrintS(" _HA: Display available aspects, their angles, and present orbs.");
#ifdef CONSTEL
X  PrintS(" _HF: Display names of astronomical constellations.");
#endif
X  PrintS(" _HS: Display information about planets in the solar system.");
#ifdef INTERPRET
X  PrintS(" _HI: Display meanings of signs, houses, planets, and aspects.");
#endif
X  sprintf(sz,
X    " _He: Display all info tables together (_Hc_H_Y_HX_HC_HO_HA%s_HS%s).",
#ifdef CONSTEL
X  "_HF",
#else
X  "",
#endif
#ifdef INTERPRET
X  "_HI");
#else
X  "");
#endif
X  PrintS(sz);
X  PrintS(" _Q: Prompt for more command switches after display finished.");
#ifdef SWITCHES
X  PrintS(" _Q0: Like _Q but prompt for additional switches on startup.");
#endif
X  PrintS(" _M <1-48>: Run the specified command switch macro.");
X  PrintS(" _M0 <1-48> <string>: Define the specified command switch macro.");
X  PrintS(" _Y: Display help list of less commonly used command switches.");
X  PrintS("\nSwitches which determine the type of chart to display:");
X  PrintS(" _v: Display list of object positions (chosen by default).");
X  PrintS(" _v0: Like _v but express velocities relative to average speed.");
X  PrintS(" _w [<rows>]: Display chart in a graphic house wheel format.");
X  PrintS(" _w0 [..]: Like _w but reverse order of objects in houses 4..9.");
X  PrintS(" _g: Display aspect and midpoint grid among planets.");
X  PrintS(" _g0: Like _g but flag aspect configurations (e.g. Yod's) too.");
X  PrintS(" _g0: For comparison charts, show midpoints instead of aspects.");
X  PrintS(" _ga: Like _g but indicate applying instead of difference orbs.");
X  PrintS(" _gp: Like _g but generate parallel and contraparallel aspects.");
X  PrintS(" _a: Display list of all aspects ordered by influence.");
X  PrintS(" _a0: Like _a but display aspect summary too.");
X  PrintS(" _a[0]a: Like _a but indicate applying and separating orbs.");
X  PrintS(" _a[0]p: Like _a but do parallel and contraparallel aspects.");
X  PrintS(" _m: Display all object midpoints in sorted zodiac order.");
X  PrintS(" _m0: Like _m but display midpoint summary too.");
X  PrintS(" _ma: Like _m but show aspects from midpoints to planets as well.");
X  PrintS(" _Z: Display planet locations with respect to the local horizon.");
X  PrintS(" _Z0: Like _Z but express coordinates relative to polar center.");
X  PrintS(" _Zd: Search day for object local rising and setting times.");
X  PrintS(" _S: Display x,y,z coordinate positions of planets in space.");
X  PrintS(" _l: Display Gauquelin sectors for each planet in chart.");
X  PrintS(" _l0: Like _l but approximate sectors using Placidus cusps.");
X  PrintS(" _j: Display astrological influences of each object in chart.");
X  PrintS(" _j0: Like _j but include influences of each zodiac sign as well.");
X  PrintS(" _L [<step>]: Display astro-graph locations of planetary angles.");
X  PrintS(" _L0 [..]: Like _L but display list of latitude crossings too.");
X  PrintS(" _K: Display a calendar for given month.");
X  PrintS(" _Ky: Like _K but display a calendar for the entire year.");
X  PrintS(" _d [<step>]: Print all aspects and changes occurring in a day.");
X  PrintS(" _dm: Like _d but print all aspects for the entire month.");
X  PrintS(" _dy: Like _d but print all aspects for the entire year.");
X  PrintS(" _dY <years>: Like _d but search within a number of years.");
X  PrintS(" _dp <month> <year>: Print aspects within progressed chart.");
X  PrintS(" _dpy <year>: Like _dp but search for aspects within entire year.");
X  PrintS(" _dpY <year> <years>: Like _dp but search within number of years.");
X  PrintS(" _dp[y]n: Search for progressed aspects in current month/year.");
X  PrintS(" _D: Like _d but display aspects by influence instead of time.");
X  PrintS(" _E: Display planetary ephemeris for given month.");
X  PrintS(" _Ey: Display planetary ephemeris for the entire year.");
X  PrintS(" _EY <years>: Display planetary ephemeris for a number of years.");
X  PrintS(
X    " _e: Print all charts together (i.e. _v_w_g0_a_m_Z_S_l_K_j0_L0_d_D_E).");
X  PrintS(
X    " _t <month> <year>: Compute all transits to natal planets in month.");
X  PrintS(
X    " _tp <month> <year>: Compute progressions to natal in month for chart.");
X  PrintS(" _tr <month> <year>: Compute all returns in month for chart.");
X  PrintS(" _t[p]y: <year>: Compute transits/progressions for entire year.");
X  PrintS(" _t[p]Y: <year> <years>: Compute transits for a number of years.");
#ifdef TIME
X  PrintS(" _t[py]n: Compute transits to natal planets for current time now.");
#endif
X  PrintS(" _T <month> <day> <year>: Display transits ordered by influence.");
X  PrintS(" _Tp <month> <day> <year>: Print progressions instead of transits.");
#ifdef TIME
X  PrintS(" _T[p]n: Display transits ordered by influence for current date.");
#endif
#ifdef ARABIC
X  PrintS(" _P [<parts>]: Display list of Arabic parts and their positions.");
X  PrintS(" _P0 [<parts>]: Like _P but display formulas with terms reversed.");
X  PrintS(" _P[z,n,f]: Order parts by position, name, or formula.");
#endif
#ifdef INTERPRET
X  PrintS(" _I [<columns>]: Print interpretation of selected charts.");
#endif
X  PrintS("\nSwitches which affect how the chart parameters are obtained:");
#ifdef TIME
X  PrintS(" _n: Compute chart for this exact moment using current time.");
X  PrintS(" _n[d,m,y]: Compute chart for start of current day, month, year.");
#endif
X  PrintS(" _z [<zone>]: Change the default time zone (for _d_E_t_q options).");
X  PrintS(" _z0 [<offset>]: Change the default daylight time setting.");
X  PrintS(" _zl <long> <lat>: Change the default longitude & latitude.");
X  PrintS(" _zt <time>: Set only the time of current chart.");
X  PrintS(" _zd <date>: Set only the day of current chart.");
X  PrintS(" _zm <month>: Set only the month of current chart.");
X  PrintS(" _zy <year>: Set only the year of current chart.");
X  PrintS(" _zi <name> <place>: Set name and place strings of current chart.");
X  PrintS(" _q <month> <date> <year> <time>: Compute chart with defaults.");
X  PrintS(" _qd <month> <date> <year>: Compute chart for noon on date.");
X  PrintS(" _qm <month> <year>: Compute chart for first of month.");
X  PrintS(" _qy <year>: Compute chart for first day of year.");
X  PrintS(" _qa <month> <date> <year> <time> <zone> <long> <lat>:");
X  PrintS("     Compute chart automatically given specified data.");
X  PrintS(" _qb <month> <date> <year> <time> <daylight> <zone> <long> <lat>:");
X  PrintS("     Like _qa but takes additional parameter for daylight offset.");
X  PrintS(" _qj <day>: Compute chart for time of specified Julian day.");
X  PrintS(" _i <file>: Compute chart based on info in file.");
X  PrintS(" _i[2,3,4] <file>: Load chart info into chart slots 2, 3, or 4.");
X  PrintS(" _o <file> [..]: Write parameters of current chart to file.");
X  PrintS(" _o0 <file> [..]: Like _o but output planet/house positions.");
X  PrintS(" _os <file>, > <file>: Redirect output of text charts to file.");
X  PrintS("\nSwitches which affect what information is used in a chart:");
X  PrintS(" _R [<obj1> [<obj2> ..]]: Restrict specific bodies from displays.");
X  PrintS(" _R0 [<obj1> ..]: Like _R but restrict everything first.");
X  PrintS(" _R1 [<obj1> ..]: Like _R0 but unrestrict and show all objects.");
X  PrintS(" _R[C,u,U]: Restrict all minor cusps, all uranians, or stars.");
X  PrintS(" _RT[0,1,C,u,U] [..]: Restrict transiting planets in _t lists.");
X  PrintS(" _RA [<asp1> ..]: Restrict aspects by giving them negative orbs.");
X  PrintS(" _C: Include angular and non-angular house cusps in charts.");
X  PrintS(" _u: Include transneptunian/uranian bodies in charts.");
X  PrintS(" _U: Include locations of fixed background stars in charts.");
X  PrintS(" _U[z,l,n,b]: Order by azimuth, altitude, name, or brightness.");
X  PrintS(" _A <0-18>: Specify the number of aspects to use in charts.");
X  PrintS(" _Ao <aspect> <orb>: Specify maximum orb for an aspect.");
X  PrintS(" _Am <planet> <orb>: Specify maximum orb allowed to a planet.");
X  PrintS(" _Ad <planet> <orb>: Specify orb addition given to a planet.");
X  PrintS(" _Aa <aspect> <angle>: Change the actual angle of an aspect.");
X  PrintS("\nSwitches which affect how a chart is computed:");
#ifdef PLACALC
X  PrintS(" _b: Use ephemeris files for more accurate location computations.");
X  PrintS(" _b0: Like _b but display locations to the nearest second too.");
#endif
X  PrintS(" _c <value>: Select a different default system of houses.");
X  PrintS("     (0 = Placidus, 1 = Koch, 2 = Equal, 3 = Campanus,");
X  PrintS("     4 = Meridian, 5 = Regiomontanus, 6 = Porphyry, 7 = Morinus,");
X  PrintS("     8 = Topocentric, 9 = Alcabitius, 10 = Equal (MC),");
X  PrintS("     11 = Neo-Porphyry, 12 = Whole, 13 = Vedic, 14 = None.)");
X  PrintS(" _s [..]: Compute a sidereal instead of the normal tropical chart.");
X  PrintS(" _sr: Compute right ascension locations relative to equator.");
X  PrintS(
X    " _s[z,h,d]: Display locations as in zodiac, hours/minutes, or degrees.");
X  PrintS(" _h [<objnum>]: Compute positions centered on specified object.");
X  PrintS(" _p <month> <day> <year>: Cast 2ndary progressed chart for date.");
X  PrintS(" _p0 <month> <day> <year>: Cast solar arc chart for date.");
#ifdef TIME
X  PrintS(" _p[0]n: Cast progressed chart based on current date now.");
#endif
X  PrintS(" _pd <days>: Set no. of days to progress / day (default 365.25).");
X  PrintS(" _x <value>: Cast harmonic chart based on specified factor.");
X  PrintS(" _1 [<objnum>]: Cast chart with specified object on Ascendant.");
X  PrintS(" _2 [<objnum>]: Cast chart with specified object on Midheaven.");
X  PrintS(" _3: Display objects in their zodiac decan positions.");
X  PrintS(" _f: Display houses as sign positions (flip them).");
X  PrintS(" _G: Compute houses based on geographic location only.");
X  PrintS(" _J: Display wheel charts in Vedic format.");
X  PrintS(" _9: Display objects in their zodiac navamsa positions.");
X  PrintS(" _F <objnum> <sign> <deg>: Force object's position to be value.");
X  PrintS(" _+ [<days>]: Cast chart for specified no. of days in the future.");
X  PrintS(" _- [<days>]: Cast chart for specified no. of days in the past.");
X  PrintS(" _+[m,y] [<value>]: Cast chart for no. of months/years in future.");
X  PrintS("\nSwitches for relationship and comparison charts:");
X  PrintS(" _r <file1> <file2>: Compute a relationship synastry chart.");
X  PrintS(" _rc <file1> <file2>: Compute a composite chart.");
X  PrintS(" _rm <file1> <file2>: Compute a time space midpoint chart.");
X  PrintS(" _r[c,m]0 <file1> <file2> <ratio1> <ratio2>: Weighted chart.");
X  PrintS(" _rd <file1> <file2>: Print time span between files' dates.");
#ifdef BIORHYTHM
X  PrintS(" _rb <file1> <file2>: Display biorhythm for file1 at time file2.");
#endif
X  PrintS(" _r0 <file1> <file2>: Keep the charts separate in comparison.");
X  PrintS(" _rp[0] <file1> <file2>: Like _r0 but do file1 progr. to file2.");
X  PrintS(" _rt <file1> <file2>: Like _r0 but treat file2 as transiting.");
#ifdef GRAPH
X  PrintS(" _r[3,4]: Make graphics wheel chart tri-wheel or quad-wheel.");
#endif
#ifdef TIME
X  PrintS(" _y <file>: Display current house transits for particular chart.");
#ifdef BIORHYTHM
X  PrintS(" _y[b,d,p,t] <file>: Like _r0 but compare to current time now.");
#endif
#endif /* TIME */
X  PrintS("\nSwitches to access graphics options:");
X  PrintS(" _k: Display text charts using Ansi characters and color.");
X  PrintS(" _k0: Like _k but only use special characters, not Ansi color.");
#ifdef MSG
X  PrintS(" _V: <25,43,50>: Start up with text mode set to number of rows.");
#endif
X
X  /* If graphics features are compiled in, call an additional procedure to */
X  /* display the command switches offered dealing with the graphics stuff. */
X
#ifdef GRAPH
X  DisplaySwitchesX();
#ifdef WIN
X  DisplaySwitchesW();  /* Windows version has its own set of switches too. */
#endif
#endif /* GRAPH */
}
X
X
/* Print a list of the obscure command switches that can be passed to the */
/* program and a description of them. This is what the -Y switch prints.  */
X
void DisplaySwitchesRare()
{
X  char sz[cchSzDef];
X
X  sprintf(sz, "%s (version %s) obscure command switches:",
X    szAppName, szVersionCore);
X  PrintS(sz);
X  PrintS(" _Y: Display this help list.");
X  PrintS(" _Yn: Compute location of true instead of mean node.");
X  PrintS(" _Yd: Display dates in D/M/Y instead of M/D/Y format.");
X  PrintS(" _Yt: Display times in 24 hour instead of am/pm format.");
X  PrintS(" _YC: Automatically ignore insignificant house cusp aspects.");
X  PrintS(" _Y8: Clip text charts at the rightmost (e.g. 80th) column.");
X  PrintS(" _YQ <rows>: Pause text scrolling after a page full has printed.");
X  PrintS(" _Yo: Output chart info and position files in old style format.");
X  PrintS(" _Yc: Angular cusp objects are house positions instead of angles.");
X  PrintS(" _Yz <min>: Forward clock by amount for current moment charts.");
X  PrintS(" _Yl <1-36>: Toggle plus zone status of sector for sector chart.");
#ifdef ARABIC
X  PrintS(" _YP <-1,0,1>: Set how Arabic parts are computed for night charts.");
#endif
X  PrintS(" _Yb <days>: Set number of days to span for biorhythm chart.");
X  PrintS(" _YE <obj> <semi-major axis> <eccentricity (3)> <inclination (3)>");
X  PrintS("     <perihelion (3)> <ascending node (3)> <time offset (3)>");
X  PrintS("     Change orbit of object to be the given elements.");
X  PrintS(
X    " _YR <obj1> <obj2> <flag1>..<flag2>: Set restrictions for object range.");
X  PrintS(
X    " _YRT <obj1> <obj2> <flag1>..<flag2>: Transit restrictions for range.");
X  PrintS(
X    " _YR0 <flag1> <flag2>: Set restrictions for sign, direction changes.");
X  PrintS(
X    " _YRZ <rise> <zenith> <set> <nadir>: Set restrictions for _Zd chart.");
X  PrintS(
X    " _YAo <asp1> <asp2> <orb1>..<orb2>: Set aspect orbs for range.");
X  PrintS(
X    " _YAm <obj1> <obj2> <orb1>..<orb2>: Set max planet orbs for range.");
X  PrintS(
X    " _YAd <obj1> <obj2> <orb1>..<orb2>: Set planet orb additions for range.");
X  PrintS(
X    " _YAa <asp1> <asp2> <ang1>..<ang2>: Set planet aspect angles for range.");
X  PrintS(
X    " _Yj <obj1> <obj2> <inf1>..<inf2>: Set influences for object range.");
X  PrintS(
X    " _YjC <cusp1> <cusp2> <inf1>..<inf2>: Set influences for house cusps.");
X  PrintS(
X    " _YjA <asp1> <asp2> <inf1>..<inf2>: Set influences for aspect range.");
X  PrintS(
X    " _YjT <obj1> <obj2> <inf1>..<inf2>: Set transit influences for range.");
X  PrintS(
X    " _Yj0 <inf1> <inf2> <inf3> <inf4>: Set influences given to planets");
X  PrintS("     in ruling sign, exalted sign, ruling house, exalted house.");
X  PrintS(" _YJ <obj> <sign> <cosign>: Set sign planet rules and co-rules.");
X  PrintS(" _YJ0 <obj> <sign>: Set zodiac sign given planet exalts in.");
X  PrintS(" _YI <obj> <string>: Customize interpretation for object.");
X  PrintS(
X    " _YIa <sign> <string>: Customize interpretation adjective for sign.");
X  PrintS(" _YIv <sign> <string>: Customize interpretation verb for sign.");
X  PrintS(" _YIC <house> <string>: Customize interpretation for house.");
X  PrintS(" _YIA <asp> <string>: Customize interpretation for aspect.");
X  PrintS(" _YIA0 <asp> <string>: Customize aspect interpretation statement.");
X  PrintS(" _YkC <fir> <ear> <air> <wat>: Customize element colors.");
X  PrintS(" _YkA <asp1> <asp2> <col1>..<col2>: Customize aspect colors.");
X  PrintS(" _Yk0 <1..7> <1..7> <col1>..<col2>: Customize 'rainbow' colors.");
X  PrintS(" _Yk <0..8> <0..8> <col1>..<col2>: Customize 'general' colors.");
X  PrintS(" _YXG <0-2><0-2><0-2><0-3>: Select among different graphic glyphs");
X  PrintS("     for Capricorn, Uranus, Pluto, and Lilith.");
X  PrintS(" _YXg <cells>: Set number of cells for graphic aspect grid.");
X  PrintS(" _YXf <val>: Set usage of actual system fonts in graphic file.");
X  PrintS(" _YXp <-1,0,1>: Set paper orientation for PostScript files.");
X  PrintS(" _YXp0 <hor> <ver>: Set paper size for PostScript files.");
#ifdef PCG
X  PrintS(" _YX <hi-res> <lo-res>: Set modes to use for PC screen graphics.");
#endif
X  PrintS(" _0[o,i,q,X]: Disallow file output, input, exiting, and graphics.");
X  PrintS(" _;: Ignore rest of command line and treat it as a comment.");
}
X
X
/* Print out a list of the various objects - planets, asteroids, house     */
/* cusps, stars - recognized by the program, and their index values. This  */
/* is displayed when the -O switch is invoked. For some objects, display   */
/* additional information, e.g. ruling signs for planets, brightnesses and */
/* positions in the sky for fixed stars, etc.                              */
X
void PrintObjects()
{
X  char sz[cchSzDef];
X  CI ci;
X  int i, j, k;
X  real Off;
X
X  if (!us.fCusp)
X    for (i = cuspLo; i <= cuspHi; i++)    /* Set up restrictions properly: */
X      ignore[i] = fTrue;                  /* Minor cusps and uranians      */
X  if (!us.fUranian)                       /* included only if -C and -u    */
X    for (i = uranLo; i <= uranHi; i++)    /* switches are in effect.       */
X      ignore[i] = fTrue;
X  sprintf(sz, "%s planets and objects:\n", szAppName);
X  PrintSz(sz);
X  PrintSz("No. Name       Rule Co-Rule Fall Co-Fall Exalt Debilitate\n\n");
X  for (i = 1; i <= oNorm; i++) if (!ignore[i]) {
X    AnsiColor(kObjA[i]);
X    sprintf(sz, "%2d %-12s", i, szObjName[i]); PrintSz(sz);
X
X    /* Print rulerships and exaltations for the planets. */
X
X    j = ruler1[i]; k = ruler2[i];
X    if (j) {
X      sprintf(sz, "%c%c%c", chSig3(j)); PrintSz(sz);
X    } else
X      PrintSz("   ");
X    PrintSz("  ");
X    if (k) {
X      sprintf(sz, "%c%c%c", chSig3(k)); PrintSz(sz);
X    } else
X      PrintSz("   ");
X    PrintTab(' ', 5);
X    if (j) {
X      sprintf(sz, "%c%c%c", chSig3(Mod12(j+6))); PrintSz(sz);
X    } else
X      PrintSz("   ");
X    PrintSz("  ");
X    if (k) {
X      sprintf(sz, "%c%c%c", chSig3(Mod12(k+6))); PrintSz(sz);
X    } else
X      PrintSz("   ");
X    PrintTab(' ', 5);
X    j = exalt[i];
X    if (j) {
X      sprintf(sz, "%c%c%c", chSig3(j)); PrintSz(sz);
X    } else
X      PrintSz("   ");
X    PrintSz("   ");
X    if (j) {
X      sprintf(sz, "%c%c%c", chSig3(Mod12(j+6))); PrintSz(sz);
X    } else
X      PrintSz("   ");
X    if (FCusp(i)) {
X      sprintf(sz, "  House Cusp #%d", i-cuspLo+1); PrintSz(sz);
X    } else if (FUranian(i)) {
X      sprintf(sz, "  Uranian #%d", i-uranLo+1); PrintSz(sz);
X    }
X    PrintL();
X  }
X
X  /* Now, if -U in effect, read in and display stars in specified order. */
X
X  if (us.nStar) {
X    ci = ciCore;
X    Off = ProcessInput(fTrue);
X    ciCore = ci;
X    ComputeStars(us.fSidereal ? 0.0 : -Off);
X    for (i = starLo; i <= starHi; i++) if (!ignore[i]) {
X      j = oNorm+starname[i-oNorm];
X      AnsiColor(kObjA[j]);
X      sprintf(sz, "%2d %-12s", i, szObjName[j]); PrintSz(sz);
X      sprintf(sz, "Star #%2d   ", i-oNorm); PrintSz(sz);
X      PrintZodiac(planet[j]);
X      PrintTab(' ', 4);
X      PrintAltitude(planetalt[j]);
X      sprintf(sz, " %5.2f\n", rStarBright[j-oNorm]); PrintSz(sz);
X    }
X  }
X  AnsiColor(kDefault);
}
X
X
/* Print out a list of all the aspects recognized by the program, and info  */
/* about them: their names, index numbers, degree angles, present orbs, and */
/* the description of their glyph. This gets displayed when the -A switch   */
/* is invoked (without any argument).                                       */
X
void PrintAspects()
{
X  char sz[cchSzDef];
X  int i;
X
X  sprintf(sz,
X    "%s aspects:\nNo. Name         Abbrev. ", szAppName); PrintSz(sz);
X  PrintSz("Angle    Orb          Description of glyph\n\n");
X  for (i = 1; i <= cAspect; i++) {
X    AnsiColor(kAspA[i]);
X    sprintf(sz, "%2d %-15s(%s) %6.2f +/- %1.0f degrees - %s\n",
X      i, szAspectName[i], szAspectAbbrev[i],
X      rAspAngle[i], rAspOrb[i], szAspectGlyph[i]); PrintSz(sz);
X  }
X  AnsiColor(kDefault);
}
X
X
/* Print out a list of the 12 signs and houses of the zodiac, and their    */
/* standard and traditional names, as done when the -H0 switch is invoked. */
X
void PrintSigns()
{
X  char sz[cchSzDef];
X  int i;
X
X  sprintf(sz, "%s signs and houses:\n", szAppName); PrintSz(sz);
X  PrintSz("Sign        English name      House Traditional name");
X  PrintTab(' ', 19); PrintSz("Ruler\n\n");
X  for (i = 1; i <= cSign; i++) {
X    AnsiColor(kSignA(i));
X    sprintf(sz, "%-12sthe %-14s%2d%s  House of %-24s  %s\n",
X    szSignName[i], szSignEnglish[i], i, szSuffix[i], szHouseTradition[i],
X    szObjName[rules[i]]);
X    PrintSz(sz);
X  }
X  AnsiColor(kDefault);
}
X
X
#ifdef CONSTEL
/* Given the standard 'noun' form of a constellation string, convert it  */
/* to its genitive or posessive form. Some standard rules are used but a */
/* special instructions string is passed for special cases.              */
X
char *GetSzGenitive(szGen, szInst)
char *szGen, *szInst;
{
X  char *pch, ch1, ch2;
X  int cch;
X
X  pch = szGen + CchSz(szGen);
X  if (*szInst == ' ')            /* Instructions starting with a space or */
X    szInst++;                    /* that are empty means no special case. */
X  else if (*szInst) {
X    cch = *szInst - '0';
X    if (cch < 10) {          /* Instructions starting with a number means */
X      szInst++;              /* hack off that many characters of string.  */
X      pch -= cch;
X    }
X    while (*szInst > '9')  /* Instructions end with characters to append. */
X      *pch++ = *szInst++;
X    *pch = chNull;
X    return szInst;
X  }
X  ch1 = *(pch-1);
X  ch2 = *(pch-2);
X  if (ch1 == 'a') {           /* Standard rule: 'a' ending -> 'ae'. */
X    *pch++ = 'e';
X    *pch = chNull;
X  } else if (ch1 == 's' && ch2 == 'u') {     /* 'us' ending -> 'i'. */
X    *(pch-2) = 'i';
X    *(pch-1) = chNull;
X  } else if (ch1 == 'm' && ch2 == 'u') {     /* 'um' ending -> 'i'. */
X    *(pch-2) = 'i';
X    *(pch-1) = chNull;
X  } else if (ch1 == 'x')     /* Standard rule: 'x' ending -> 'cis'. */
X    sprintf(pch-1, "cis");
X  return szInst;
}
X
X
/* Given a constellation index, fill out a string with the genitive or   */
/* posessive form of its name. This basically just calls GetSzGenitive() */
/* above, however it has to be called twice for names having two words.  */
X
void GetSzConstel(szGen, i)
char *szGen;
int i;
{
X  char sz1[cchSzDef], sz2[cchSzDef], *pchSpace, *szInst;
X
X  sprintf(szGen, "%s", szCnstlName[i]);
X  for (pchSpace = szGen; *pchSpace && *pchSpace != ' '; pchSpace++)
X    ;
X  szInst = (char *)szCnstlGenitive[i];
X  if (*pchSpace == chNull) {
X    GetSzGenitive(szGen, szInst);
X    return;
X  }
X  *pchSpace = chNull;
X  if (szInst[0] == '!') {
X    GetSzGenitive(szGen, szInst+1);
X    return;
X  }
X  sprintf(sz1, "%s", szGen);
X  sprintf(sz2, "%s", pchSpace+1);
X  szInst = GetSzGenitive(sz1, szInst);
X  GetSzGenitive(sz2, szInst);
X  sprintf(szGen, "%s %s", sz1, sz2);
}
X
X
/* Print out a list of the 88 constellations used in astronomy, in their  */
/* standard, English, and genitive forms, as invoked with the -HF switch. */
X
void PrintConstellations()
{
X  int i, j = eWat;
X  char szGen[cchSzDef], sz[cchSzDef], chLast = chNull;
X
X  sprintf(sz, "%s constellations:\n", szAppName); PrintSz(sz);
X  PrintSz("No. Name                Abbrev.   ");
X  PrintSz("Meaning            Genitive form\n\n");
X  for (i = 1; i <= cCnstl; i++) {
X    if (szCnstlName[i][0] != chLast) {
X      chLast = szCnstlName[i][0];
X      j = j + 1 & 3;
X      AnsiColor(kElemA[j]);
X    }
X    sprintf(sz, "%2d: %-19s (%s) ", i, szCnstlName[i], szCnstlAbbrev[i]);
X    PrintSz(sz);
X    if (szCnstlMeaning[i][0] == ' ')
X      sprintf(sz, "%-22s", szCnstlMeaning[i]+1);
X    else
X      sprintf(sz, "the %-18s", szCnstlMeaning[i]);
X    PrintSz(sz);
X    GetSzConstel(szGen, i);
X    sprintf(sz, " (%s)\n", szGen); PrintSz(sz);
X  }
X  AnsiColor(kDefault);
}
#endif /* CONSTEL */
X
X
/* Print out a list of the planets in the solar system (and our Moon), */
/* listing astronomical info on them, as invoked with the -HS switch.  */
X
void PrintOrbit()
{
X  char sz[cchSzDef];
X  int i;
X  real r;
X
X  sprintf(sz, "%s planets:\n", szAppName); PrintSz(sz);
X  PrintSz("   Name: Distance   Year Diameter     Day       Mass Density  ");
X  PrintSz("Axis Satellites\n\n");
X  for (i = 0; i <= oVes; i++) {
X    AnsiColor(kObjA[i]);
X    sprintf(sz, "%7s:%9.3f%7.2f%9.3f", szObjName[i],
X      rObjDist[i]/rObjDist[0], rObjYear[i], rObjDiam[i]/rObjDiam[0]);
X    PrintSz(sz);
X    if (i <= oPlu) {
X      r = rObjDiam[i]*1000.0/2.0;
X      sprintf(sz, "%8.2f%11.3f%8.2f%6.2f%11d",
X        rObjDay[i], rObjMass[i],
X        (rObjMass[i]*5.974E24/1000.0)/((4.0/3.0)*(r*r*r)*rPi),
X        rObjAxis[i], cSatellite[i]);
X      PrintSz(sz);
X    }
X    PrintL();
X  }
X  AnsiColor(kDefault);
}
X
X
#ifdef ARABIC
/* Compare the strings corresponding to two Arabic part formulas. Like   */
/* NCompareSz, this returns 0 if they are equal, a positive value if the */
/* first is greater, and negative if the second is greater.              */
X
int NCompareSzPart(ap1, ap2)
int ap1, ap2;
{
X  char *pch1, *pch2;
X  int ich;
X
X  pch1 = ai[ap1].form; pch2 = ai[ap2].form;
X  for (ich = 0; pch1[ich] && pch1[ich] == pch2[ich]; ich++) {
X    if (!us.fArabicFlip) {
X
X      /* If formulas are being displayed in alternate form, we need to */
X      /* effectively swap two sections in the string and then compare. */
X
X      if (ich == 2)
X        ich = 5;
X      else if (ich == 8)
X        ich = 2;
X      else if (ich == 5)
X        ich = 8;
X    }
X  }
X  return pch1[ich] - pch2[ich];
}
X
X
/* Print out a list of all the Arabic parts in the current chart, computing */
/* their positions first, as brought up with the -P switch.                 */
X
void DisplayArabic()
{
X  real rPart[cPart], rBit[3], rCur;
X  char sz[cchSzDef], *pch, ch;
X  int iPart[cPart], h, i, j, k, l;
X
X  PrintSz("Num."); PrintTab(' ', 20); PrintSz("Name Position");
X  PrintTab(' ', 1 + 4 * is.fSeconds);
X  PrintSz("House Formula              Flip Type\n");
X
X  /* Calculate the zodiac positions of all the parts. */
X
X  for (i = 0; i < cPart; i++) {
X    rPart[i] = -rDegMax;
X    if (i >= us.nArabicParts)
X      goto LNextPart;
X    for (j = 0; j < 3; j++) {
X      pch = &ai[i].form[j*3];
X      ch = pch[1];
X      if (ch == ' ')
X        k = oAsc;
X      else if (ch == 'F')
X        k = -apFor;
X      else if (ch == 'S')
X        k = -apSpi;
X      else
X        k = (ch-'0') * 10 + (pch[2]-'0');
X      ch = *pch;
X      if (ch == 'h')      /* House cusp */
X        rCur = chouse[k];
X      else if (ch == 'r') /* Ruler of house cusp */
X        rCur = planet[rules[SFromZ(chouse[k])]];
X      else if (ch == 'j') /* 10 degrees of house cusp */
X        rCur = chouse[k] + 10.0;
X      else if (ch == 'H') /* Planet's house */
X        rCur = chouse[inhouse[k]];
X      else if (ch == 'R') /* Ruler of planet's house */
X        rCur = planet[rules[SFromZ(chouse[inhouse[k]])]];
X      else if (ch == 'D') /* Dispositor / ruler of planet's position */
X        rCur = planet[rules[SFromZ(planet[k])]];
X      else if (FBetween(ch, '0', '3'))
X        rCur = (real)((ch-'0') * 100 + k);
X      else {
X        if (k < 1) {
X          rCur = rPart[-k];
X          if (rCur < 0.0)
X            goto LNextPart;
X        } else {
X          if (ignore[k] && (us.fCusp || !FCusp(k)))
X            goto LNextPart;
X          else
X            rCur = planet[k];
X        }
X      }
X      rBit[j] = rCur;
X    }
X    rCur = rBit[1] - rBit[2];
X    if (us.nArabicNight < 0 || (ai[i].form[9] == 'F' &&
X      inhouse[oSun] < sLib && us.nArabicNight == 0))
X      rCur = -rCur;
X    rCur = Mod(rCur + rBit[0]);
X    rPart[i] = rCur;
LNextPart:
X    iPart[i] = i;
X  }
X
X  /* Sort parts to figure out what order to display them in. */
X
X  if (us.nArabic > 1) for (i = 1; i < cPart; i++) {
X    j = i-1;
X
X    /* Compare part zodiac locations for -Pz switch. */
X
X    if (us.nArabic == 'z') while (j >= 0 &&
X      rPart[iPart[j]] > rPart[iPart[j+1]]) {
X      SwapN(iPart[j], iPart[j+1]);
X      j--;
X
X    /* Compare part names for -Pn switch. */
X
X    } else if (us.nArabic == 'n') while (j >= 0 && NCompareSz(
X      ai[iPart[j]].name, ai[iPart[j+1]].name) > 0) {
X      SwapN(iPart[j], iPart[j+1]);
X      j--;
X
X    /* Compare part formulas for -Pf switch. */
X
X    } else if (us.nArabic == 'f') while (j >= 0 && NCompareSzPart(
X      iPart[j], iPart[j+1]) > 0) {
X      SwapN(iPart[j], iPart[j+1]);
X      j--;
X    }
X  }
X
X  /* Display the positions and formulas of the parts. */
X
X  for (h = i = 0; i < cPart; i++) {
X    l = iPart[i];
X    if (rPart[l] < 0.0)
X      continue;
X    sprintf(sz, "%3d: %23.23s ", ++h, ai[l].name); PrintSz(sz);
X    PrintZodiac(rPart[l]);
X    j = HousePlaceIn(rPart[l]);
X    sprintf(sz, " [%2d%s] ", j, szSuffix[j]);
X    AnsiColor(kSignA(j)); PrintSz(sz); AnsiColor(kDefault);
X    PrintCh('(');
X    for (j = 0; j < 3; j++) {
X      k = j < 1 || us.fArabicFlip ? j : 3-j;
X      pch = &ai[l].form[k*3];
X      ch = pch[1];
X      if (ch == ' ')
X        k = oAsc;
X      else if (ch == 'F')
X        k = -apFor;
X      else if (ch == 'S')
X        k = -apSpi;
X      else
X        k = (ch-'0') * 10 + (pch[2]-'0');
X      ch = *pch;
X      if (k < 1) {
X        AnsiColor(kObjA[oFor]);
X        sprintf(sz, "%3.3s", ai[-k].name); PrintSz(sz);
X      } else {
X        if (ch == ' ' || ch == 'H' || ch == 'R' || ch == 'D') {
X          AnsiColor(kSignA(ruler1[k]));
X          sprintf(sz, "%c%c%c", chObj3(k));
X        } else if (FBetween(ch, '0', '3')) {
X          k = (ch-'0') * 100 + k;
X          AnsiColor(kSignA(k/30+1));
X          sprintf(sz, "%2d%c%c%c", k%30, chSig3(k/30+1));
X        } else {
X          AnsiColor(kSignA(k));
X          sprintf(sz, "%3d", k);
X        }
X        PrintSz(sz);
X      }
X      AnsiColor(kDefault);
X      if (sz[3] == chNull) {
X        PrintCh(' ');
X        switch (ch) {
X        case 'h': ch = ' '; break;
X        case 'r': ch = 'R'; break;
X        case 'j': ch = '&'; break;
X        default: ch = *pch;
X        }
X        PrintCh(ch);
X      }
X      if (j < 2) {
X        sprintf(sz, " %c ", (j < 1 == us.fArabicFlip) ? '+' : '-');
X        PrintSz(sz);
X      }
X    }
X    PrintCh(' ');
X    ch = ai[l].form[9];
X    switch (ch) {
X    case 'F': PrintSz("Y"); break;
X    default: AnsiColor(kWhite); PrintSz("N"); AnsiColor(kDefault); break;
X    }
X    PrintSz(") ");
X    ch = ai[l].form[10];
X    switch (ch) {
X    case 'C': AnsiColor(kElemA[eWat]); PrintSz("Comm."); break;
X    case 'E': AnsiColor(kElemA[eFir]); PrintSz("Event"); break;
X    case 'H': AnsiColor(kElemA[eEar]); PrintSz("Hora."); break;
X    }
X    AnsiColor(kDefault);
X    PrintL();
X  }
}
#endif /* ARABIC */
X
X
#ifdef GRAPH
/* Print a list of every key that one can press in a graphics window to do  */
/* a certain function, and a description of what it does, as displayed when */
/* one presses the 'H' or '?' key, and as shown with the -HX switch.        */
X
void DisplayKeysX()
{
X  char sz[cchSzDef];
X
X  sprintf(sz, "%s graphics screen key press options (version %s):",
X    szAppName, szVersionCore);
X  PrintS(sz);
X  PrintS(" Press 'H' or '?' to display this list of key options.");
X  PrintS(" Press 'p' to toggle pause status on or off.");
X  PrintS(" Press 'x' to toggle fg/bg colors on screen.");
X  PrintS(" Press 'm' to toggle color/monochrome display on screen.");
X  PrintS(" Press 'i' to toggle status of the minor chart modification.");
X  PrintS(" Press 't' to toggle header info on current chart on screen.");
X  PrintS(" Press 'b' to toggle drawing of a border around the chart.");
X  PrintS(" Press 'l' to toggle labeling of object points in chart.");
X  PrintS(" Press 'j' to toggle not clearing screen between chart updates.");
X  PrintS(" Press 'v' to display current chart positions on text screen.");
X  PrintS(" Press 'R', 'C', 'u', 'U' to toggle restriction status of minor");
X  PrintS("       objects, minor house cusps, uranian planets, and stars.");
X  PrintS(" Press 'c' to toggle relationship comparison chart mode.");
X  PrintS(" Press 's', 'h', 'f', 'g', 'z', 'y' to toggle status of sidereal");
X  PrintS("       zodiac, heliocentric charts, domal charts, decan charts,");
X  PrintS("       vedic format wheel charts, and navamsa charts.");
X  PrintS(" Press 'O' and 'o' to recall/store a previous chart from memory.");
#ifdef X11
X  PrintS(" Press 'B' to dump current window contents to root background.");
#else
X  PrintS(" Press 'B' to resize chart display to full size of screen.");
#endif
X  PrintS(" Press 'Q' to resize chart display to a square.");
X  PrintS(" Press '<' and '>' to decrease/increase the scale size of the");
X  PrintS("       glyphs and the size of world map.");
X  PrintS(" Press '[' and ']' to decrease/increase tilt in globe display.");
X  PrintS(" Press '+' and '-' to add/subtract a day from current chart.");
#ifdef TIME
X  PrintS(" Press 'n' to set chart information to current time now.");
#endif
X  PrintS(" Press 'N' to toggle animation status on or off. Charts will");
X  PrintS("       be updated to current status and globe will rotate.");
X  PrintS(" Press '!'-'(' to begin updating current chart by adding times.");
X  PrintS("       !: seconds, @: minutes, #: hours, $: days, %: months,");
X  PrintS("       ^: years, &: years*10, *: years*100, (: years*1000.");
X  PrintS(" Press 'r' to reverse direction of time-lapse or animation.");
X  PrintS(" Press '1'-'9' to set rate of animation to 'n' degrees, etc.");
#ifdef PCG
X  PrintS(" Press '1'-'9' to determine section of chart to show if clipped.");
#endif
X  PrintS(
X    " Press 'V','A','Z','S','M','K','J','L','E','W','G','P' to switch to");
X  PrintS(
X    "       normal (_v), grid (_g), local (_Z), space (_S), sector (_l),");
X  PrintS("       calendar (_K), dispositor (_j), astro-graph (_L), ephemeris");
X  PrintS("       (_E), world map (_XW), globe (_XG), and polar (_XP) modes.");
X  PrintS(" Press 'Y' to switch to biorhythm relation chart mode.");
X  PrintS(" Press '0' to toggle between _Z,_Z0 & _XW,_XW0 & _E,_Ey modes.");
#ifdef CONSTEL
X  PrintS(" Press 'F' to toggle between world and constellation map modes.");
#endif
#ifdef PCG
X  PrintS(" Press 'F1'..'F12' [plus Shift,Ctrl,Alt] to run macros 1..48.");
#endif
X  PrintS(" Press 'space' to force redraw of current graphics display.");
X  PrintS(" Press 'del' to clear the graphics screen and not redraw.");
#ifdef PCG
X  PrintS(" Press 'tab' to toggle between graphics resolutions.");
#endif
X  PrintS(" Press 'enter' to input a command line of general switches.");
X  PrintS(" Press 'q' to terminate graphics and the program.");
#ifdef MOUSE
X  PrintL();
#ifdef X11
X  PrintS(" Left   mouse button: Draw line strokes on chart in window.");
X  PrintS(" Middle mouse button: Print coordinates of pointer on world map.");
X  PrintS(" Right  mouse button: Terminate the window and program.");
#endif
#ifdef PCG
X  PrintS(" Left  mouse button: Draw line strokes on chart in screen.");
X  PrintS(" Right mouse button: Set coordinates to pointer on world map.");
#endif
#endif /* MOUSE */
}
X
X
/* Print a list of every command switch dealing with the graphics features  */
/* that can be passed to the program, and a description of what it does.    */
/* This is part of what the -H switch prints, if graphics were compiled in. */
X
void DisplaySwitchesX()
{
X  PrintS(" _X: Create a graphics chart instead of displaying it as text.");
#ifdef ISG
X  PrintS(" _Xb: Create bitmap file instead of putting graphics on screen.");
#endif
X  PrintS(" _Xb[n,c,v,a,b]: Set bitmap file output mode to X11 normal,");
X  PrintS("     compacted, very compact, Ascii (bmtoa), or Windows bmp.");
#ifdef PS
X  PrintS(" _Xp: Create PostScript stroke graphic instead of bitmap file.");
X  PrintS(" _Xp0: Like _Xp but create complete instead of encapsulated file.");
#endif
#ifdef META
X  PrintS(" _XM[0]: Create Windows metafile stroke graphic instead of bitmap.");
#endif
X  PrintS(" _Xo <file>: Write output bitmap or graphic to specified file.");
#ifdef X11
X  PrintS(" _XB: Display X chart on root instead of in a separate window.");
#endif
X  PrintS(" _Xm: Create monochrome graphic instead of one in color.");
X  PrintS(" _Xr: Create chart graphic in reversed colors (white background).");
#ifdef X11
X  PrintS(" _Xw <hor> [<ver>], _ge[..]: Change the size of chart graphic.");
#else
X  PrintS(" _Xw <hor> [<ver>]: Change the size of chart graphic.");
#endif
X  PrintS(" _Xs <100,200,300,400>: Change the size of map or characters by %.");
X  PrintS(" _Xi: Create chart graphic in slightly modified form.");
X  PrintS(" _Xt: Inhibit display of chart info at bottom of graphic.");
X  PrintS(" _Xu: Inhibit display of a border around graphic.");
X  PrintS(" _Xl: Inhibit labeling of object points in chart graphic.");
X  PrintS(" _Xj: Don't clear screen between chart updates, drawing trails.");
X  PrintS(" _X1 <object>: Rotate wheel charts so object is at left edge.");
X  PrintS(" _X2 <object>: Rotate wheel charts so object is at top edge.");
#ifdef X11
X  PrintS(" _Xd <name>, _di[..] <name>: Open X window on specified display.");
#endif
X  PrintS(" _XW: Simply create an image of the world map.");
X  PrintS(" _XW0: Like _XW but do a non-rectangular Mollewide projection.");
X  PrintS(" _XG [<degrees>]: Display the image of the world as a globe.");
X  PrintS(" _XP: Like _XG but create the globe from a polar projection.");
#ifdef CONSTEL
X  PrintS(" _XF: Display maps as constellations on the celestial sphere.");
#endif
#ifdef ISG
X  PrintS(" _Xn [<mode>]: Start up chart or globe display in animation mode.");
X  PrintS(" _HX: Display list of key press options for screen graphics.");
#endif
}
X
X
#ifdef WIN
/* Print a list of every command switch dealing with the Windows features */
/* that can be passed to the program, and a description of what it does.  */
/* This is part of what the -H switch prints in the MS Windows version.   */
X
void DisplaySwitchesW()
{
X  PrintS(" _W <value>: Run given Windows menu command internally.");
X  PrintS(" _WN <1-32000>: Set animation update delay in milliseconds.");
X  PrintS(" _WM <1-48> <text>: Set Windows menu text for macro command.");
X  PrintS(" _Wn: Don't redraw screen until user forces update.");
}
#endif
#endif /* GRAPH */
X
X
/* This is the dispatch procedure for all the generic table information      */
/* routines, such as those displaying the -H switch list, the list of signs, */
/* objects, default interpretations, and so on not requiring a date or time. */
X
bool FPrintTables()
{
#ifdef WIN
X  if (us.fGraphics)
X    return fFalse;
#endif
X  if (us.fCredit) {
X    DisplayCredits();
X    is.fMult = fTrue;
X  }
X  if (us.fSwitch) {
X    if (is.fMult)
X      PrintL2();
X    DisplaySwitches();
X    is.fMult = fTrue;
X  }
X  if (us.fSwitchRare) {
X    if (is.fMult)
X      PrintL2();
X    DisplaySwitchesRare();
X    is.fMult = fTrue;
X  }
#ifdef GRAPH
X  if (us.fKeyGraph) {
X    if (is.fMult)
X      PrintL2();
X    DisplayKeysX();
X    is.fMult = fTrue;
X  }
#endif
X  if (us.fSign) {
X    if (is.fMult)
X      PrintL2();
X    PrintSigns();
X    is.fMult = fTrue;
X  }
X  if (us.fObject) {
X    if (is.fMult)
X      PrintL2();
X    PrintObjects();
X    is.fMult = fTrue;
X  }
X  if (us.fAspect) {
X    if (is.fMult)
X      PrintL2();
X    PrintAspects();
X    is.fMult = fTrue;
X  }
#ifdef CONSTEL
X  if (us.fConstel) {
X    if (is.fMult)
X      PrintL2();
X    PrintConstellations();
X    is.fMult = fTrue;
X  }
#endif
X  if (us.fOrbitData) {
X    if (is.fMult)
X      PrintL2();
X    PrintOrbit();
X    is.fMult = fTrue;
X  }
#ifdef INTERPRET
X  if (us.fMeaning) {
X    if (is.fMult)
X      PrintL2();
X    InterpretGeneral();
X    InterpretAspectGeneral();
X    is.fMult = fTrue;
X  }
#endif
X
X  /* If we also already have enough information to generate a chart,    */
X  /* then go on and do so, else exit. (So things like "-H -i file" will */
X  /* work, but things like just "-H" will print and exit right away.)   */
X
#ifndef WIN
X  return is.fMult && !is.fHaveInfo;
#else
X  return is.fMult;
#endif
}
X
/* charts0.c */
SHAR_EOF
  $shar_touch -am 1223232998 'charts0.c' &&
  chmod 0644 'charts0.c' ||
  echo 'restore of charts0.c failed'
  shar_count="`wc -c < 'charts0.c'`"
  test 46020 -eq "$shar_count" ||
    echo "charts0.c: original size 46020, current size $shar_count"
fi
# ============= charts1.c ==============
if test -f 'charts1.c' && test X"$1" != X"-c"; then
  echo 'x - skipping charts1.c (File already exists)'
else
  echo 'x - extracting charts1.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'charts1.c' &&
/*
** Astrolog (Version 5.40) File: charts1.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
/*
******************************************************************************
** Single Chart Display Routines.
******************************************************************************
*/
X
X
/* Print header info showing time and date of the chart being displayed.   */
/* This is used by ChartListing() and the -l sector chart in PrintChart(). */
X
void PrintHeader()
{
X  char sz[cchSzDef];
X  int day, fNam, fLoc;
X
X  fNam = *ciMain.nam > chNull; fLoc = *ciMain.loc > chNull;
X  AnsiColor(kWhite);
X  sprintf(sz, "%s %s chart ", szAppName, szVersionCore); PrintSz(sz);
X  if (fNoTimeOrSpace)
X    PrintSz("(No time or space)\n");
X  else if (us.nRel == rcComposite)
X    PrintSz("(Composite)\n");
X  else {
X    sprintf(sz, "for %s%s", ciMain.nam, fNam ? "\n" : ""); PrintSz(sz);
X    day = DayOfWeek(Mon, Day, Yea);
X    sprintf(sz, "%c%c%c %s %s (%cT %s GMT)", chDay3(day),
X      SzDate(Mon, Day, Yea, 3), SzTim(Tim), ChDst(Dst),
X      SzZone(Zon)); PrintSz(sz);
X    sprintf(sz, "%c%s%s%s\n", fLoc && !fNam ? '\n' : ' ', ciMain.loc,
X      fLoc ? " " : "", SzLocation(Lon, Lat)); PrintSz(sz);
X  }
}
X
X
/* Print the straight listing of planet and house positions and specified */
/* by the -v switch, along with the element table, etc.                   */
X
void ChartListing()
{
X  ET et;
X  char sz[cchSzDef];
X  int i, j, k, fNam, fLoc;
X  real rT;
X
X  CreateElemTable(&et);
X  fNam = *ciMain.nam > chNull; fLoc = *ciMain.loc > chNull;
X
X  PrintHeader();    /* Show time and date of the chart being displayed. */
X
#ifdef INTERPRET
X  if (us.fInterpret) {          /* Print an interpretation if -I in effect. */
X    if (us.nRel == rcSynastry)
X      InterpretSynastry();      /* Print synastry interpretaion for -r -I.  */
X    else
X      InterpretLocation();      /* Do normal interpretation for just -v -I. */
X    return;
X  }
#endif
X
X  AnsiColor(kDkGray);
X  if (us.fSeconds) {
X    sprintf(sz, "Body  Location   Ret. %s Rul.      House  Rul. Velocity\n",
X      us.fEquator ? "Declin. " : "Latitude"); PrintSz(sz);
X  } else {
X    sprintf(sz,
X      "Body  Locat. Ret. %s. Rul.      House  Rul. Veloc.    %s Houses.\n",
X      us.fEquator ? "Decl" : "Lati", szSystem[us.nHouseSystem]); PrintSz(sz);
X  }
X  if (!fNam && !fLoc)
X    PrintL();
X
X  /* Ok, now print out the location of each object. */
X
X  for (i = 1-us.fSeconds, j = 0; i <= oNorm; i++, j++) {
X    if (us.fSeconds) {
X      if (FIgnore(i))
X        continue;
X    } else {
X      if (i > oCore && (i <= cuspHi || FIgnore(i)))
X        continue;
X      while (i <= oCore && j <= oCore && FIgnore(j))
X        j++;
X    }
X    if (i <= oCore && j > oCore)
X      PrintTab(' ', 51);
X    else {
X      if (i > oCore)
X        j = i;
X      AnsiColor(kObjA[j]);
X      sprintf(sz, "%-4.4s: ", szObjName[j]); PrintSz(sz);
X      PrintZodiac(planet[j]);
X      sprintf(sz, " %c ", ret[j] >= 0.0 ? ' ' : chRet); PrintSz(sz);
X      if (j <= cThing || j > cuspHi)
X        PrintAltitude(planetalt[j]);
X      else
X        PrintTab('_', us.fSeconds ? 10 : 7);
X      sprintf(sz, " (%c)", Dignify(j, SFromZ(planet[j])));
X      PrintSz(FCusp(j) ? "    " : sz);
X      k = inhouse[j];
X      AnsiColor(kSignA(k));
X      sprintf(sz, " [%2d%s house] ", k, szSuffix[k]); PrintSz(sz);
X      AnsiColor(kDefault);
X      sprintf(sz, "[%c] ", Dignify(j, k)); PrintSz(FCusp(j) ? "    " : sz);
X      if ((j != oMoo || us.fPlacalc) &&
X        (FObject(j) || ((j == oNod || j == oLil) && us.fPlacalc))) {
X        PrintCh((char)(ret[i] < 0.0 ? '-' : '+'));
X        rT = DFromR(RAbs(ret[j]));
X        sprintf(sz, us.fSeconds ? (rT < 10.0 ? "%9.7f" : "%9.6f") :
X          (rT < 10.0 ? "%5.3f" : "%5.2f"), rT); PrintSz(sz);
X      } else
X        PrintTab('_', us.fSeconds ? 10 : 6);
X    }
X    if (!us.fSeconds) {
X
X      /* For some lines, we have to append the house cusp positions. */
X
X      if (i <= cSign) {
X        PrintSz("  -  ");
X        AnsiColor(kSignA(i));
X        sprintf(sz, "House cusp %2d: ", i); PrintSz(sz);
X        PrintZodiac(chouse[i]);
X      }
X
X      /* For some lines, we have to append the element table information. */
X
X      if (i == cSign+2)
X        PrintSz("     Car Fix Mut TOT");
X      else if (i > cSign+2 && i < cSign+7) {
X        k = i-(cSign+2)-1;
X        AnsiColor(kElemA[k]);
X        sprintf(sz, "  %c%c%c%3d %3d %3d %3d",
X          szElem[k][0], szElem[k][1], szElem[k][2],
X          et.coElemMode[k][0], et.coElemMode[k][1], et.coElemMode[k][2],
X          et.coElem[k]); PrintSz(sz);
X        AnsiColor(kDefault);
X      } else if (i == cSign+7) {
X        sprintf(sz, "  TOT %2d %3d %3d %3d",
X          et.coMode[0], et.coMode[1], et.coMode[2], et.coSum); PrintSz(sz);
X      } else if (i == oCore)
X        PrintTab(' ', 23);
X      else if (i >= uranLo) {
X        sprintf(sz, "  Uranian #%d", i-uranLo+1); PrintSz(sz);
X      }
X      sz[0] = chNull;
X      switch (i-cSign-1) {
X      case 1: sprintf(sz, "   +:%2d", et.coYang);  break;
X      case 2: sprintf(sz, "   -:%2d", et.coYin);   break;
X      case 3: sprintf(sz, "   M:%2d", et.coMC);    break;
X      case 4: sprintf(sz, "   N:%2d", et.coIC);    break;
X      case 5: sprintf(sz, "   A:%2d", et.coAsc);   break;
X      case 6: sprintf(sz, "   D:%2d", et.coDes);   break;
X      case 7: sprintf(sz,    "<:%2d", et.coLearn); break;
X      }
X      PrintSz(sz);
X    } else {
X      PrintSz(" Decan: ");
X      is.fSeconds = fFalse;
X      PrintZodiac(Decan(planet[i]));
X      is.fSeconds = us.fSeconds;
X    }
X    PrintL();
X  }
X
X  /* Do another loop to print out the stars in their specified order. */
X
X  if (us.nStar) for (i = starLo; i <= starHi; i++) {
X    j = oNorm+starname[i-oNorm];
X    if (ignore[j])
X      continue;
X    AnsiColor(kObjA[j]);
X    sprintf(sz, "%-4.4s: ", szObjName[j]); PrintSz(sz);
X    PrintZodiac(planet[j]);
X    PrintSz("   ");
X    PrintAltitude(planetalt[j]);
X    k = inhouse[j];
X    AnsiColor(kSignA(k));
X    sprintf(sz, "     [%2d%s house]", k, szSuffix[k]); PrintSz(sz);
X    AnsiColor(kDefault);
X    sprintf(sz, "     ______%s Star #%2d: %5.2f\n",
X      us.fSeconds ? "____" : " ", i-oNorm, rStarBright[j-oNorm]); PrintSz(sz);
X  }
}
X
X
/* Print out the aspect and midpoint grid for a chart, as specified with the */
/* -g switch. (Each grid row takes up 4 lines of text.)                      */
X
void ChartGrid()
{
X  char sz[cchSzDef];
X  int x, y, r, x1, y1, temp;
X
#ifdef INTERPRET
X  if (us.fInterpret) {    /* Print interpretation instead if -I in effect. */
X    InterpretGrid();
X    return;
X  }
#endif
X
X  for (y1 = 0, y = 1; y <= cObj; y++) if (!ignore[y])
X    for (r = 1; r <= 4; r++) {
X      for (x1 = 0, x = 1; x <= cObj; x++) if (!ignore[x]) {
X        if (y1 > 0 && x1 > 0 && y+r > 2)
X          PrintCh((char)(r > 1 ? chV : chC));
X        if (r > 1) {
X          temp = grid->n[x][y];
X
X          /* Print aspect rows. */
X
X          if (x < y) {
X            if (temp)
X              AnsiColor(kAspA[temp]);
X            if (r == 2)
X              PrintSz(temp ? szAspectAbbrev[temp] : "   ");
X            else if (!temp)
X              PrintSz("   ");
X            else {
X              if (r == 3) {
X                if (grid->v[x][y] < 6000)
X                  sprintf(sz, "%c%2d", us.fAppSep ?
X                    (grid->v[x][y] < 0 ? 'a' : 's') :
X                    (grid->v[x][y] < 0 ? '-' : '+'), abs(grid->v[x][y])/60);
X                else
X                  sprintf(sz, "%3d", abs(grid->v[x][y])/60);
X              } else
X                sprintf(sz, "%02d'", abs(grid->v[x][y])%60);
X              PrintSz(sz);
X            }
X
X          /* Print midpoint rows. */
X
X          } else if (x > y) {
X            AnsiColor(kSignA(temp));
X            if (r == 2) {
X              temp = grid->n[x][y];
X              sprintf(sz, "%c%c%c", chSig3(temp));
X            } else if (r == 3) {
X              sprintf(sz, "%2d%c", grid->v[x][y]/60, chDeg0);
X            } else
X              sprintf(sz, "%02d'", grid->v[x][y]%60);
X            PrintSz(sz);
X
X          /* Print the diagonal of object names. */
X
X          } else {
X            AnsiColor(kReverse);
X            if (r == 2) {
X              AnsiColor(kObjA[y]);
X              sprintf(sz, "%c%c%c", chObj3(y));
X            } else {
X              temp = SFromZ(planet[y]);
X              AnsiColor(kSignA(temp));
X              if (r == 3)
X                sprintf(sz, "%2d%c", (int)planet[y] - (temp-1)*30, chDeg0);
X              else
X                sprintf(sz, "%c%c%c", chSig3(temp));
X            }
X            PrintSz(sz);
X          }
X          AnsiColor(kDefault);
X        } else
X          if (y1 > 0)
X            PrintTab(chH, 3);
X        x1++;
X      }
X      if (y+r > 2)
X        PrintL();
X      y1++;
X    }
X  if (y1 == 0)
X    PrintSz("Empty aspect grid.\n");
}
X
X
/* This is a subprocedure of DisplayGrands(). Here we print out one aspect */
/* configuration found by the parent procedure.                            */
X
void PrintGrand(ac, i1, i2, i3, i4)
char ac;
int i1, i2, i3, i4;
{
X  char sz[cchSzDef];
X  int asp;
X
X  switch (ac) {
X  case acS : asp = aCon; break;
X  case acGT: asp = aTri; break;
X  case acTS: asp = aOpp; break;
X  case acY : asp = aInc; break;
X  case acGC: asp = aSqu; break;
X  case acC : asp = aSex; break;
X  default: ;
X  }
X  AnsiColor(kAspA[asp]);
X  sprintf(sz, "%-11s", szAspectConfig[ac]); PrintSz(sz);
X  AnsiColor(kDefault);
X  sprintf(sz, " %s ",
X    ac == acS || ac == acGT || ac == acGC ? "with" : "from"); PrintSz(sz);
X  AnsiColor(kObjA[i1]);
X  sprintf(sz, "%c%c%c: ", chObj3(i1)); PrintSz(sz);
X  PrintZodiac(planet[i1]);
X  sprintf(sz, " %s ", ac == acS || ac == acGT ? "and" : "to "); PrintSz(sz);
X  AnsiColor(kObjA[i2]);
X  sprintf(sz, "%c%c%c: ", chObj3(i2)); PrintSz(sz);
X  PrintZodiac(planet[i2]);
X  sprintf(sz, " %s ", ac == acGC || ac == acC ? "to " : "and"); PrintSz(sz);
X  AnsiColor(kObjA[i3]);
X  sprintf(sz, "%c%c%c: ", chObj3(i3)); PrintSz(sz);
X  PrintZodiac(planet[i3]);
X  if (ac == acGC || ac == acC) {
X    PrintSz(" to ");
X    AnsiColor(kObjA[i4]);
X    sprintf(sz, "%c%c%c: ", chObj3(i4)); PrintSz(sz);
X    PrintZodiac(planet[i4]);
X  }
X  PrintL();
}
X
X
/* Scan the aspect grid of a chart and print out any major configurations, */
/* as specified with the -g0 switch.                                       */
X
void DisplayGrands()
{
X  int cac = 0, i, j, k, l;
X
X  for (i = 0; i <= cObj; i++) if (!FIgnore(i))
X    for (j = 0; j <= cObj; j++) if (j != i && !FIgnore(j))
X      for (k = 0; k <= cObj; k++) if (k != i && k != j && !FIgnore(k)) {
X
X        /* Is there a Stellium among the current three planets? */
X
X        if (i < j && j < k && grid->n[i][j] == aCon &&
X            grid->n[i][k] == aCon && grid->n[j][k] == aCon) {
X          cac++;
X          PrintGrand(acS, i, j, k, l);
X
X        /* Is there a Grand Trine? */
X
X        } else if (i < j && j < k && grid->n[i][j] == aTri &&
X            grid->n[i][k] == aTri && grid->n[j][k] == aTri) {
X          cac++;
X          PrintGrand(acGT, i, j, k, l);
X
X        /* Is there a T-Square? */
X
X        } else if (j < k && grid->n[j][k] == aOpp &&
X            grid->n[Min(i, j)][Max(i, j)] == aSqu &&
X            grid->n[Min(i, k)][Max(i, k)] == aSqu) {
X          cac++;
X          PrintGrand(acTS, i, j, k, l);
X
X        /* Is there a Yod? */
X
X        } else if (j < k && grid->n[j][k] == aSex &&
X            grid->n[Min(i, j)][Max(i, j)] == aInc &&
X            grid->n[Min(i, k)][Max(i, k)] == aInc) {
X          cac++;
X          PrintGrand(acY, i, j, k, l);
X        }
X        for (l = 0; l <= cObj; l++) if (!FIgnore(l)) {
X
X          /* Is there a Grand Cross among the current four planets? */
X
X          if (i < j && i < k && i < l && j < l && grid->n[i][j] == aSqu &&
X              grid->n[Min(j, k)][Max(j, k)] == aSqu &&
X              grid->n[Min(k, l)][Max(k, l)] == aSqu &&
X              grid->n[i][l] == aSqu &&
X              MinDistance(planet[i], planet[k]) > 150.0 &&
X              MinDistance(planet[j], planet[l]) > 150.0) {
X            cac++;
X            PrintGrand(acGC, i, j, k, l);
X
X          /* Is there a Cradle? */
X
X          } else if (i < l && grid->n[Min(i, j)][Max(i, j)] == aSex &&
X              grid->n[Min(j, k)][Max(j, k)] == aSex &&
X              grid->n[Min(k, l)][Max(k, l)] == aSex &&
X              MinDistance(planet[i], planet[l]) > 150.0) {
X            cac++;
X            PrintGrand(acC, i, j, k, l);
X          }
X        }
X      }
X  if (!cac)
X    PrintSz("No major configurations in aspect grid.\n");
}
X
X
/* This is subprocedure of ChartWheel(). Here we print out the location */
/* of a particular house cusp as well as what house cusp number it is.  */
X
void PrintHouse(i, left)
int i, left;
{
X  char sz[cchSzDef];
X  real r;
X  int j;
X
X  if (us.fVedic) {
X    j = Mod12(12-i);
X    r = ZFromS(j);
X  } else {
X    j = i;
X    r = chouse[i];
X  }
X  if (!left)
X    PrintZodiac(r);
X  AnsiColor(kSignA(j));
X  sprintf(sz, "<%d>", j); PrintSz(sz);
X  if (left)
X    PrintZodiac(r);
X  else
X    AnsiColor(kDefault);
}
X
X
/* Another subprocedure of ChartWheel(). Print out one of the chart info */
/* rows in the middle of the wheel (which may be blank) given an index.  */
X
void PrintWheelCenter(irow)
int irow;
{
X  char sz[cchSzDef], szT[8];
X  int cch, nT;
X
X  if (*ciMain.nam == chNull && *ciMain.loc == chNull)    /* Try to center */
X    irow--;
X  if (*ciMain.nam == chNull && irow >= 1)    /* Don't have blank lines if */
X    irow++;                                  /* the name and/or location  */
X  if (*ciMain.loc == chNull && irow >= 3)    /* strings are empty.        */
X    irow++;
X  switch (irow) {
X  case 0:
X    sprintf(sz, "%s %s chart", szAppName, szVersionCore);
X    break;
X  case 1:
X    sprintf(sz, "%s", ciMain.nam);
X    break;
X  case 2:
X    nT = DayOfWeek(Mon, Day, Yea);
X    sprintf(sz, "%c%c%c %s %s", chDay3(nT), SzDate(Mon, Day, Yea, 2),
X      SzTim(Tim));
X    break;
X  case 3:
X    sprintf(sz, "%s", ciMain.loc);
X    break;
X  case 4:
X    nT = (int)(RFract(RAbs(Zon))*100.0+rRound);
X    sprintf(sz, "%cT %c%02d:%02d, %s", ChDst(Dst),
X      Zon > 0.0 ? '-' : '+', (int)RAbs(Zon), nT, SzLocation(Lon, Lat));
X    break;
X  case 5:
X    nT = us.fEuroTime; us.fEuroTime = fTrue;
X    sprintf(szT, "%s", SzTim(DegToDec(DFromR(is.RA)*(24.0/rDegMax))));
X    sprintf(sz, "UT: %s, Sid.T: %s", SzTim(Tim+Zon-Dst), szT);
X    us.fEuroTime = nT;
X    break;
X  case 6:
X    sprintf(sz, "%s Houses", szSystem[us.nHouseSystem]);
X    break;
X  case 7:
X    sprintf(sz, "%s / %s", us.fSidereal ? "Sidereal" : "Tropical",
X      us.objCenter == oSun ? "Heliocentric" :
X      (us.objCenter == oEar ? "Geocentric" : szObjName[us.objCenter]));
X    break;
X  case 8:
X    sprintf(sz, "Julian Day = %12.4f", JulianDayFromTime(is.T));
X    break;
X  default:
X    *sz = chNull;
X  }
X  cch = CchSz(sz);
X  nT = WHEELCOLS*2-1 + is.fSeconds*8;
X  PrintTab(' ', (nT - cch) / 2);
X  PrintSz(sz);
X  PrintTab(' ', nT-cch - (nT - cch) / 2);
}
X
X
/* Yet another subprocedure of ChartWheel(). Here we print out one line */
/* in a particular house cell (which may be blank).                     */
X
void PrintWheelSlot(obj)
int obj;
{
X  char sz[cchSzDef];
X
X  if (obj >= oEar) {
X    AnsiColor(kObjA[obj]);
X    sprintf(sz, " %c%c%c ", chObj3(obj)); PrintSz(sz);
X    PrintZodiac(planet[obj]);
X    sprintf(sz, "%c ", ret[obj] < 0.0 ? 'r' : ' '); PrintSz(sz);
X    PrintTab(' ', WHEELCOLS-15);
X  } else                            /* This particular line is blank. */
X    PrintTab(' ', WHEELCOLS-1 + is.fSeconds*4);
}
X
X
/* Display all the objects in a wheel format on the screen, as specified */
/* with the -w switch. The wheel is divided into the 12 houses and the   */
/* planets are placed accordingly.                                       */
X
void ChartWheel()
{
X  int wheel[cSign][WHEELROWS], wheelcols, count = 0, i, j, k, l;
X
X  /* If the seconds (-b0) flag is set, we'll print all planet and house    */
X  /* locations to the nearest zodiac second instead of just to the minute. */
X
X  wheelcols = WHEELCOLS + is.fSeconds*4;
X
X  for (i = 0; i < cSign; i++)
X    for (j = 0; j < us.nWheelRows; j++)
X      wheel[i][j] = -1;                    /* Clear out array. */
X
X  /* This section of code places each object in the wheel house array. */
X
X  for (i = 0; i <= cObj && count < us.nWheelRows*12; i++) {
X    if (FIgnore(i) || (FCusp(i) &&
X      MinDistance(planet[i], chouse[i-oAsc+1]) < rRound/60.0))
X      continue;
X
X    /* Try to put object in its proper house. If no room, */
X    /* then overflow over to the next succeeding house.   */
X
X    for (j = (us.fVedic ? Mod12(11-SFromZ(planet[i])) : inhouse[i])-1;
X      j < cSign; j = j < cSign ? (j+1)%cSign : j) {
X
X      /* Now try to find the proper place in the house to put the object. */
X      /* This is in sorted order, although a check is made for 0 Aries.   */
X
X      if (wheel[j][us.nWheelRows-1] >= 0)
X        continue;
X      l = chouse[j+1] > chouse[Mod12(j+2)];
X      for (k = 0; wheel[j][k] >= 0 && (planet[i] >= planet[wheel[j][k]] ||
X         (l && planet[i] < rDegHalf && planet[wheel[j][k]] > rDegHalf)) &&
X        !(l && planet[i] > rDegHalf && planet[wheel[j][k]] < rDegHalf); k++)
X        ;
X
X      /* Actually insert object in proper place. */
X
X      if (wheel[j][k] < 0)
X        wheel[j][k] = i;
X      else {
X        for (l = us.nWheelRows-1; l > k; l--)
X          wheel[j][l] = wheel[j][l-1];
X        wheel[j][k] = i;
X      }
X      count++;
X      j = cSign;
X    }
X  }
X
X  /* Now, if this is really the -w switch and not -w0, then reverse the  */
X  /* order of objects in western houses for more intuitive reading. Also */
X  /* reverse the order of everything in the reverse order Vedic wheels.  */
X
X  if (us.fVedic)
X    for (i = 0; i < cSign; i++)
X      for (j = 0; j < us.nWheelRows/2; j++) {
X        k = us.nWheelRows-1-j;
X        l = wheel[i][j]; wheel[i][j] = wheel[i][k]; wheel[i][k] = l;
X      }
X  if (!us.fWheelReverse)
X    for (i = 3; i < 9; i++)
X      for (j = 0; j < us.nWheelRows/2; j++) {
X        k = us.nWheelRows-1-j;
X        l = wheel[i][j]; wheel[i][j] = wheel[i][k]; wheel[i][k] = l;
X      }
X
X  /* Here we actually print the wheel and the objects in it. */
X
X  PrintCh(chNW); PrintTab(chH, WHEELCOLS-8); PrintHouse(11, fTrue);
X  PrintTab(chH, WHEELCOLS-11+us.fVedic); PrintHouse(10, fTrue);
X  PrintTab(chH, WHEELCOLS-10+us.fVedic); PrintHouse(9, fTrue);
X  PrintTab(chH, wheelcols-4); PrintCh(chNE); PrintL();
X  for (i = 0; i < us.nWheelRows; i++) {
X    for (j = 10; j >= 7; j--) {
X      PrintCh(chV); PrintWheelSlot(wheel[j][i]);
X    }
X    PrintCh(chV); PrintL();
X  }
X  PrintHouse(12, fTrue); PrintTab(chH, WHEELCOLS-11);
X  PrintCh(chC); PrintTab(chH, wheelcols-1); PrintCh(chJN);
X  PrintTab(chH, wheelcols-1); PrintCh(chC); PrintTab(chH, WHEELCOLS-10);
X  PrintHouse(8, fFalse); PrintL();
X  for (i = 0; i < us.nWheelRows; i++) {
X    PrintCh(chV); PrintWheelSlot(wheel[11][i]); PrintCh(chV);
X    PrintWheelCenter(i);
X    PrintCh(chV); PrintWheelSlot(wheel[6][i]);
X    PrintCh(chV); PrintL();
X  }
X  PrintHouse(1, fTrue); PrintTab(chH, WHEELCOLS-10-us.fVedic);
X  PrintCh(chJW); PrintWheelCenter(us.nWheelRows); PrintCh(chJE);
X  PrintTab(chH, WHEELCOLS-10); PrintHouse(7, fFalse); PrintL();
X  for (i = 0; i < us.nWheelRows; i++) {
X    PrintCh(chV); PrintWheelSlot(wheel[0][i]); PrintCh(chV);
X    PrintWheelCenter(us.nWheelRows+1 + i);
X    PrintCh(chV); PrintWheelSlot(wheel[5][i]);
X    PrintCh(chV); PrintL();
X  }
X  PrintHouse(2, fTrue); PrintTab(chH, WHEELCOLS-10-us.fVedic);
X  PrintCh(chC); PrintTab(chH, wheelcols-1); PrintCh(chJS);
X  PrintTab(chH, wheelcols-1); PrintCh(chC);
X  PrintTab(chH, WHEELCOLS-10); PrintHouse(6, fFalse); PrintL();
X  for (i = 0; i < us.nWheelRows; i++) {
X    for (j = 1; j <= 4; j++) {
X      PrintCh(chV); PrintWheelSlot(wheel[j][i]);
X    }
X    PrintCh(chV); PrintL();
X  }
X  PrintCh(chSW); PrintTab(chH, wheelcols-4); PrintHouse(3, fFalse);
X  PrintTab(chH, WHEELCOLS-10); PrintHouse(4, fFalse);
X  PrintTab(chH, WHEELCOLS-10); PrintHouse(5, fFalse);
X  PrintTab(chH, WHEELCOLS-7); PrintCh(chSE); PrintL();
}
X
X
/* This is a subprocedure of ChartAspect() and ChartAspectRelation().       */
/* Display summary information about the aspect list, i.e. the total number */
/* of aspects of each type, and the number of aspects to each object, as    */
/* done when the -a0 aspect summary setting is set.                         */
X
void PrintAspectSummary(ca, co, count, rPowSum)
int *ca, *co, count;
real rPowSum;
{
X  char sz[cchSzDef];
X  int i, j, k;
X
X  if (!us.fAspSummary)
X    return;
X  if (count == 0) {
X    PrintSz("No aspects in list.\n");
X    return;
X  }
X  PrintL();
X  sprintf(sz, "Sum power: %.2f - Average power: %.2f\n",
X    rPowSum, rPowSum/(real)count); PrintSz(sz);
X  k = us.fParallel ? Min(us.nAsp, aOpp) : us.nAsp;
X  for (j = 0, i = 1; i <= k; i++) if (!ignorea(i)) {
X    if (!(j & 7)) {
X      if (j)
X        PrintL();
X    } else
X      PrintSz("   ");
X    AnsiColor(kAspA[i]);
X    sprintf(sz, "%s:%3d", szAspectAbbrev[i], ca[i]); PrintSz(sz);
X    j++;
X  }
X  PrintL();
X  for (j = 0, i = 0; i <= cObj; i++) if (!FIgnore(i)) {
X    if (!(j & 7)) {
X      if (j)
X        PrintL();
X    } else
X      PrintSz("   ");
X    AnsiColor(kObjA[i]);
X    sprintf(sz, "%c%c%c:%3d", chObj3(i), co[i]); PrintSz(sz);
X    j++;
X  }
X  PrintL();
}
X
X
/* Display all aspects between objects in the chart, one per line, in       */
/* sorted order based on the total "power" of the aspect, as specified with */
/* the -a switch. The same influences used for -I charts are used here.     */
X
void ChartAspect()
{
X  int ca[cAspect + 1], co[objMax];
X  char sz[cchSzDef];
X  int pcut = 30000, icut, jcut, phi, ihi, jhi, ahi, p, i, j, k, count = 0;
X  real ip, jp, rPowSum = 0.0;
X
X  ClearB((lpbyte)ca, (cAspect + 1)*(int)sizeof(int));
X  ClearB((lpbyte)co, objMax*(int)sizeof(int));
X  loop {
X    phi = -1;
X
X    /* Search for the next most powerful aspect in the aspect grid. */
X
X    for (i = 1; i <= cObj; i++) if (!FIgnore(i))
X      for (j = 0; j < i; j++) if (!FIgnore(j))
X        if (k = grid->n[j][i]) {
X          ip = i <= oNorm ? rObjInf[i] : 2.5;
X          jp = j <= oNorm ? rObjInf[j] : 2.5;
X          p = (int)(rAspInf[k]*(ip+jp)/2.0*
X            (1.0-RAbs((real)(grid->v[j][i]))/60.0/GetOrb(i, j, k))*1000.0);
X          if ((p < pcut || (p == pcut && (i > icut ||
X            (i == icut && j > jcut)))) && p > phi) {
X            ihi = i; jhi = j; phi = p; ahi = k;
X          }
X        }
X    if (phi < 0)    /* Exit when no less powerful aspect found. */
X      break;
X    pcut = phi; icut = ihi; jcut = jhi;
X    count++;                               /* Display the current aspect.   */
#ifdef INTERPRET
X    if (us.fInterpret) {                   /* Interpret it if -I in effect. */
X      InterpretAspect(jhi, ihi);
X      continue;
X    }
#endif
X    rPowSum += (real)phi/1000.0;
X    ca[ahi]++;
X    co[jhi]++; co[ihi]++;
X    sprintf(sz, "%3d: ", count); PrintSz(sz);
X    PrintAspect(jhi, SFromZ(planet[jhi]), (int)RSgn(ret[jhi]), ahi,
X      ihi, SFromZ(planet[ihi]), (int)RSgn(ret[ihi]), 'a');
X    k = grid->v[jhi][ihi];
X    AnsiColor(k < 0 ? kWhite : kLtGray);
X    sprintf(sz, " - orb: %c%d%c%02d'",
X      us.fAppSep ? (k < 0 ? 'a' : 's') : (k < 0 ? '-' : '+'),
X      abs(k)/60, chDeg1, abs(k)%60); PrintSz(sz);
X    AnsiColor(kDkGreen);
X    sprintf(sz, " - power:%6.2f\n", (real)phi/1000.0); PrintSz(sz);
X    AnsiColor(kDefault);
X  }
X
X  PrintAspectSummary(ca, co, count, rPowSum);
}
X
X
/* This is a subprocedure of ChartMidpoint() and ChartMidpointRelation().  */
/* Display summary information about the midpoint list, i.e. the total     */
/* number of midpoints in each sign, and their average span in degrees, as */
/* done when the -m0 midpoint summary setting is set.                      */
X
void PrintMidpointSummary(cs, count, lSpanSum)
int *cs, count;
long lSpanSum;
{
X  char sz[cchSzDef];
X  int m, i;
X
X  if (!us.fMidSummary)
X    return;
X  if (count == 0) {
X    PrintSz("No midpoints in list.\n");
X    return;
X  }
X  PrintL();
X  m = (int)(lSpanSum/count);
X  sprintf(sz, "Average span:%4d%c%02d'\n", m/60, chDeg1, m%60); PrintSz(sz);
X  for (i = 1; i <= cSign; i++) {
X    if (i == sLib)
X      PrintL();
X    else if (i != sAri)
X      PrintSz("   ");
X    AnsiColor(kSignA(i));
X    sprintf(sz, "%c%c%c:%3d", chSig3(i), cs[i]); PrintSz(sz);
X  }
X  PrintL();
}
X
X
/* Display locations of all midpoints between objects in the chart, */
/* one per line, in sorted zodiac order from zero Aries onward, as  */
/* specified with the -m switch.                                    */
X
void ChartMidpoint()
{
X  int cs[cSign + 1];
X  char sz[cchSzDef];
X  int mcut = -1, icut, jcut, mlo, ilo, jlo, m, i, j, k, count = 0;
X  long lSpanSum = 0;
X  real l, n, mid;
X
X  ClearB((lpbyte)cs, (cSign + 1)*(int)sizeof(int));
X  is.fSeconds = fFalse;
X  loop {
X    mlo = 21600;
X
X    /* Search for the next closest midpoint farther down in the zodiac. */
X
X    for (i = 0; i < cObj; i++) if (!FIgnore(i))
X      for (j = i+1; j <= cObj; j++) if (!FIgnore(j)) {
X        m = (grid->n[j][i]-1)*30*60 + grid->v[j][i];
X        if ((m > mcut || (m == mcut && (i > icut ||
X          (i == icut && j > jcut)))) && m < mlo) {
X          ilo = i; jlo = j; mlo = m;
X        }
X      }
X    if (mlo >= 21600)    /* Exit when no midpoint farther in zodiac found. */
X      break;
X    mcut = mlo; icut = ilo; jcut = jlo;
X    count++;                               /* Display the current midpoint. */
#ifdef INTERPRET
X    if (us.fInterpret) {                   /* Interpret it if -I in effect. */
X      InterpretMidpoint(ilo, jlo);
X      continue;
X    }
#endif
X    cs[mlo/60/30+1]++;
X    sprintf(sz, "%4d: ", count); PrintSz(sz);
X    mid = (real)mlo/60.0; PrintZodiac(mid);
X    PrintCh(' ');
X    PrintAspect(ilo, SFromZ(planet[ilo]), (int)RSgn(ret[ilo]), 0,
X      jlo, SFromZ(planet[jlo]), (int)RSgn(ret[jlo]), 'm');
X    AnsiColor(kDefault);
X    m = (int)(MinDistance(planet[ilo], planet[jlo])*60.0);
X    lSpanSum += m;
X    sprintf(sz, "-%4d%c%02d' degree span.\n", m/60, chDeg1, m%60);
X    PrintSz(sz);
X
X    /* If the -ma switch is set, determine and display each aspect from one */
X    /* of the planets to the current midpoint, and the aspect's orb.        */
X
X    if (!us.fMidAspect)
X      continue;
X    for (i = 0; i < cObj; i++) if (!FIgnore(i)) {
X      l = MinDistance(planet[i], mid);
X      for (k = us.nAsp; k >= 1; k--) {
X        if (!FAcceptAspect(i, k, ilo))
X          continue;
X        n = l-rAspAngle[k];
X        if (RAbs(n) < GetOrb(i, ilo, k)) {
X          if (us.fAppSep)
X            n = RSgn2((ret[ilo]+ret[jlo])/2.0-ret[i])*
X              RSgn2(MinDifference(planet[i], mid))*RSgn2(n)*RAbs(n);
X          PrintSz("      Midpoint "); PrintZodiac(mid); PrintSz(" makes ");
X          AnsiColor(kAspA[k]); PrintSz(szAspectAbbrev[k]);
X          AnsiColor(kDefault); PrintSz(" to ");
X          AnsiColor(kObjA[i]); sprintf(sz, "%.10s", szObjName[i]);
X          PrintSz(sz);
X          PrintTab(' ', 10-CchSz(szObjName[i]));
X          j = (int)(n*60.0);
X          AnsiColor(j < 0.0 ? kWhite : kLtGray);
X          sprintf(sz, "- orb: %c%d%c%02d'",
X            us.fAppSep ? (j < 0 ? 'a' : 's') : (j < 0 ? '-' : '+'),
X            abs(j)/60, chDeg1, abs(j)%60); PrintSz(sz);
X          PrintL();
X          AnsiColor(kDefault);
X        }
X      }
X    }
X  }
X  is.fSeconds = us.fSeconds;
X
X  PrintMidpointSummary(cs, count, lSpanSum);
}
X
X
/* Display locations of the objects on the screen with respect to the local */
/* horizon, as specified with the -Z switch.                                */
X
void ChartHorizon()
{
X  char sz[cchSzDef], szFormat[cchSzDef];
X  real lon, lat, sx, sy, vx, vy,
X    lonz[objMax], latz[objMax], azi[objMax], alt[objMax];
X  int fPrime, i, j, k, tot;
X
X  /* Set up some initial variables. */
X
X  fPrime = us.fPrimeVert;
X  lon = RFromD(Mod(Lon)); lat = RFromD(Lat);
X  tot = us.nStar ? cObj : oNorm;
X
X  /* First find zenith location on Earth of each object. */
X
X  for (i = 1; i <= tot; i++) if (!ignore[i] || i == oMC) {
X    lonz[i] = RFromD(Tropical(planet[i])); latz[i] = RFromD(planetalt[i]);
X    EclToEqu(&lonz[i], &latz[i]);
X  }
X
X  /* Then, convert this to local horizon altitude and azimuth. */
X
X  for (i = 1; i <= tot; i++) if (!ignore[i] && i != oMC) {
X    lonz[i] = RFromD(Mod(DFromR(lonz[oMC]-lonz[i]+lon)));
X    lonz[i] = RFromD(Mod(DFromR(lonz[i]-lon+rPiHalf)));
X    EquToLocal(&lonz[i], &latz[i], rPiHalf-lat);
X    azi[i] = rDegMax-DFromR(lonz[i]); alt[i] = DFromR(latz[i]);
X  }
X
X  /* If the -Z0 switch flag is in effect, convert from altitude/azimuth  */
X  /* coordinates to prime vertical coordinates that we'll print instead. */
X
X  if (fPrime) {
X    for (i = 1; i <= tot; i++) if (!ignore[i] && i != oMC) {
X      azi[i] = RFromD(azi[i]); alt[i] = RFromD(alt[i]);
X      CoorXform(&azi[i], &alt[i], rPiHalf);
X      azi[i] = DFromR(azi[i]); alt[i] = DFromR(alt[i]);
X    }
X  }
X
X  /* Now, actually print the location of each object. */
X
X  sprintf(szFormat, is.fSeconds ? " " : "");
X  sprintf(sz, "Body %s%sAltitude%s %s%sAzimuth%s%s  Azi. Vector%s    ",
X    szFormat, szFormat, szFormat, szFormat, szFormat, szFormat, szFormat,
X    szFormat); PrintSz(sz);
X  sprintf(sz, "%s Vector%s%s    Moon Vector\n\n",
X    us.objCenter != oSun ? "Sun" : "Earth", szFormat, szFormat); PrintSz(sz);
X  for (k = 1; k <= tot; k++) {
X    i = k <= oNorm ? k : oNorm+starname[k-oNorm];
X    if (ignore[i] || !FThing(i))
X      continue;
X    AnsiColor(kObjA[i]);
X    sprintf(sz, "%-4.4s: ", szObjName[i]); PrintSz(sz);
X    PrintAltitude(alt[i]);
X
X    /* Determine directional vector based on azimuth. */
X
X    sprintf(sz, " %s", SzDegree(azi[i])); PrintSz(sz);
X    sx = RCos(RFromD(azi[i])); sy = RSin(RFromD(azi[i]));
X    if (RAbs(sx) < RAbs(sy)) {
X      vx = RAbs(sx / sy); vy = 1.0;
X    } else {
X      vy = RAbs(sy / sx); vx = 1.0;
X    }
X    sprintf(sz, is.fSeconds ? " (%.3f%c" : " (%.2f%c", vy,
X      sy < 0.0 ? (fPrime ? 'u' : 's') : (fPrime ? 'd' : 'n')); PrintSz(sz);
X    sprintf(sz, is.fSeconds ? " %.2f%c)" : " %.2f%c)", vx,
X      sx > 0.0 ? 'e' : 'w'); PrintSz(sz);
X
X    /* Determine distance vector of current object from Sun and Moon. */
X
X    vx = azi[1]-azi[i]; vy = azi[2]-azi[i];
X    j = 1 + is.fSeconds;
X    sprintf(szFormat, " [%%%d.%df%%%d.%df] [%%%d.%df%%%d.%df]",
X      j+5, j, j+5, j, j+5, j, j+5, j);
X    sprintf(sz, szFormat,
X      RAbs(vx) < rDegHalf ? vx : RSgn(vx)*(rDegMax-RAbs(vx)), alt[1]-alt[i],
X      RAbs(vy) < rDegHalf ? vy : RSgn(vy)*(rDegMax-RAbs(vy)), alt[2]-alt[i]);
X    PrintSz(sz);
X    if (!is.fSeconds && i >= uranLo) {
X      if (i <= uranHi)
X        sprintf(sz, "  Uranian #%d", i-uranLo+1);
X      else
X        sprintf(sz, "  Star #%2d", i-starLo+1);
X      PrintSz(sz);
X    }
X    PrintL();
X  }
X  AnsiColor(kDefault);
}
X
X
/* Display x,y,z locations of each body (in AU) with respect to the Sun */
/* (or whatever the specified center planet is), as in the -S switch.   */
/* These values were already determined when calculating the planet     */
/* positions themselves, so this procedure is basically just a loop.    */
X
void ChartOrbit()
{
X  char sz[cchSzDef], szFormat[cchSzDef];
X  real x, y, z;
X  int i;
X
X  sprintf(szFormat, is.fSeconds ? " " : "");
X  sprintf(sz, "Body%s    Angle%s%s%s%s    ",
X    szFormat, szFormat, szFormat, szFormat, szFormat);
X  PrintSz(sz);
X  sprintf(sz,
X    "%sX axis%s%s%s    %sY axis%s%s%s    %sZ axis%s%s%s    %sLength\n",
X    szFormat, szFormat, szFormat, szFormat, szFormat, szFormat, szFormat,
X    szFormat, szFormat, szFormat, szFormat, szFormat, szFormat);
X  PrintSz(sz);
X  for (i = 0; i <= oNorm; i++) {
X    if (ignore[i] || (!FThing(i) ||
X      ((i == oMoo || i == oNod || i == oSou) && !us.fPlacalc)))
X      continue;
X    AnsiColor(kObjA[i]);
X    sprintf(sz, "%c%c%c%c: ", chObj3(i),
X      szObjName[i][3] ? szObjName[i][3] : ' '); PrintSz(sz);
X    x = spacex[i]; y = spacey[i]; z = spacez[i];
X    sprintf(sz, is.fSeconds ? "[%11.7f] [%11.7f] [%11.7f] [%11.7f] [%11.7f]" :
X      "[%7.3f] [%7.3f] [%7.3f] [%7.3f] [%7.3f]",
X      planet[i], x, y, z, RSqr(x*x+y*y+z*z)); PrintSz(sz);
X    if (!is.fSeconds && i >= uranLo) {
X      sprintf(sz, "  Uranian #%d", i-uranLo+1); PrintSz(sz);
X    }
X    PrintL();
X  }
X  AnsiColor(kDefault);
}
X
X
/* Display locations of the planets on the screen with respect to the 36    */
/* Gauquelin sectors and their plus zones, as specified with the -l switch. */
X
void ChartSector()
{
X  char sz[cchSzDef];
X  CP cp;
X  int c[cSector + 1], i, sec, pls, kPls, cpls = 0, co = 0, cq = 0;
X  real r, rT;
X
X  for (i = 1; i <= cSector; i++) {
X    c[i] = 0;
X    cpls += pluszone[i];
X  }
X  cp = cp0;
X  CastSectors();
X
X  AnsiColor(kDkGray);
X  PrintSz("Body  Sector ");
X  if (is.fSeconds)
X    PrintSz(
X      "  Plus      House   Sign Loc. Ret. Latitude Velocity Sec.18 Sec.12\n");
X  else
X    PrintSz("Plus    House   Sign Ret. Latit. Veloc. 18 12\n");
X  for (i = 0; i <= cObj; i++) {
X    if (FIgnore(i) || !FThing(i))
X      continue;
X    co++;
X    AnsiColor(kObjA[i]);
X    sprintf(sz, "%c%c%c%c: ", chObj3(i),
X      szObjName[i][3] ? szObjName[i][3] : ' '); PrintSz(sz);
X    r = GFromO(i);
X    sec = (int)r + 1; c[sec]++;
X    pls = pluszone[sec];
X    cq += pls;
X    kPls = (pls ? kRainbowA[1] : kMainA[5]);
X    AnsiColor(kDkGray);
X    PrintSz("Sec");
X    AnsiColor(kPls);
X    sprintf(sz, " %2d", sec); PrintSz(sz);
X    if (is.fSeconds) {
X      AnsiColor(kDkGray);
X      sprintf(sz, "%.3f", RFract(r)); PrintSz(&sz[1]);
X      AnsiColor(kPls);
X    }
X    sprintf(sz, " %c", (char)(pls ? '+' : '-')); PrintSz(sz);
X    AnsiColor(kSignA(cp.house[i]));
X    sprintf(sz, " [%2d%s house] ", cp.house[i], szSuffix[cp.house[i]]);
X    PrintSz(sz);
X    PrintZodiac(cp.obj[i]);
X    sprintf(sz, " %c ", cp.dir[i] < 0.0 ? chRet : ' '); PrintSz(sz);
X    PrintAltitude(cp.alt[i]);
X    PrintCh(' ');
X    if ((i != oMoo || us.fPlacalc) &&
X      (FObject(i) || ((i == oNod || i == oLil) && us.fPlacalc))) {
X      PrintCh((char)(ret[i] < 0.0 ? '-' : '+'));
X      rT = DFromR(RAbs(ret[i]));
X      sprintf(sz, is.fSeconds ? (rT < 10.0 ? "%7.5f" : "%7.4f") :
X        (rT < 10.0 ? "%5.3f" : "%5.2f"), rT); PrintSz(sz);
X    } else
X      PrintTab('_', us.fSeconds ? 8 : 6);
X    AnsiColor(kPls);
X    sprintf(sz, " %2d", (sec-1)/2 + 1); PrintSz(sz);
X    if (is.fSeconds) {
X      AnsiColor(kDkGray);
X      sprintf(sz, "%.3f", RFract(r/2.0)); PrintSz(&sz[1]);
X    }
X    AnsiColor(kPls);
X    sprintf(sz, " %2d", (sec-1)/3 + 1); PrintSz(sz);
X    if (is.fSeconds) {
X      AnsiColor(kDkGray);
X      sprintf(sz, "%.3f", RFract(r/3.0)); PrintSz(&sz[1]);
X    }
X    PrintL();
X  }
X
X  /* Display summary information, i.e. the planet in plus zone ratio. */
X
X  AnsiColor(kDefault);
X  sprintf(sz, "\nPlus zones: %d/%d = %.2f%% - ", cpls, cSector,
X    (real)cpls/(real)36*100.0); PrintSz(sz);
X  sprintf(sz, "Planets in plus zones: %d/%d = %.2f%%\n", cq, co,
X    co ? (real)cq/(real)co*100.0 : 0.0); PrintSz(sz);
X
X  /* Display more summary information, i.e. the number of planets in each */
X  /* sector, as well as whether each sector is a plus zone or not.        */
X
X  PrintSz("\nZone:");
X  for (i = 1; i <= cSector/2; i++) {
X    pls = pluszone[i];
X    AnsiColor(pls ? kRainbowA[1] : kMainA[5]);
X    sprintf(sz, " %2d%c", i, pls ? '+' : '-'); PrintSz(sz);
X  }
X  AnsiColor(kDefault);
X  PrintSz("\nNum :");
X  for (i = 1; i <= cSector/2; i++) {
X    if (c[i]) {
X      sprintf(sz, " %2d ", c[i]); PrintSz(sz);
X    } else
X      PrintSz("  . ");
X  }
X  PrintSz("\nZone:");
X  for (i = cSector; i > cSector/2; i--) {
X    pls = pluszone[i];
X    AnsiColor(pls ? kRainbowA[1] : kMainA[5]);
X    sprintf(sz, " %2d%c", i, pls ? '+' : '-'); PrintSz(sz);
X  }
X  AnsiColor(kDefault);
X  PrintSz("\nNum :");
X  for (i = cSector; i > cSector/2; i--) {
X    if (c[i]) {
X      sprintf(sz, " %2d ", c[i]); PrintSz(sz);
X    } else
X      PrintSz("  . ");
X  }
X  PrintL();
X  CastChart(fTrue);
}
X
X
/* Print the locations of the astro-graph lines on the Earth as specified */
/* with the -L switch. This includes Midheaven and Nadir lines, zenith    */
/* positions, and locations of Ascendant and Descendant lines.            */
X
void ChartAstroGraph()
{
X  CrossInfo FPTR *c;
X  char sz[cchSzDef];
X  real planet1[objMax], planet2[objMax], mc[objMax], ic[objMax],
X    as[objMax], ds[objMax], as1[objMax], ds1[objMax],
X    lo = Lon, longm, w, x, y, z, ad, oa, am, od, dm;
X  int cCross = 0, tot = cObj, i, j, k, l, m, n;
X
X  if (us.fLatitudeCross)
X    {
X    if ((c = (CrossInfo FPTR *)
X      PAllocate(sizeof(CrossInfo), fFalse, "crossing table")) == NULL)
X      return;
X    }
X
#ifdef MATRIX
X  for (i = 1; i <= cObj; i++) if (!ignore[i] || i == oMC) {
X    planet1[i] = RFromD(Tropical(i == oMC ? is.MC : planet[i]));
X    planet2[i] = RFromD(planetalt[i]);     /* Calculate zenith location on */
X    EclToEqu(&planet1[i], &planet2[i]);    /* Earth of each object.        */
X  }
X
X  /* Print header. */
X
X  PrintSz("Object :");
X  for (j = 0, i = 1; i <= cObj; i++)
X    if (!ignore[i] && FThing(i)) {
X      AnsiColor(kObjA[i]);
X      sprintf(sz, " %c%c%c", chObj3(i)); PrintSz(sz);
X      j++;
X    }
X  AnsiColor(kDefault);
X  PrintSz("\n------ :");
X  for (i = 1; i <= tot; i++)
X    if (!ignore[i] && FThing(i))
X      PrintSz(" ###");
X
X  /* Print the longitude locations of the Midheaven lines. */
X
X  PrintSz("\nMidheav: ");
X  if (lo < 0.0)
X    lo += rDegMax;
X  for (i = 1; i <= tot; i++)
X    if (!ignore[i] && FThing(i)) {
X    AnsiColor(kObjA[i]);
X    x = planet1[oMC]-planet1[i];
X    if (x < 0.0)
X      x += 2.0*rPi;
X    if (x > rPi)
X      x -= 2.0*rPi;
X    z = lo+DFromR(x);
X    if (z > rDegHalf)
X      z -= rDegMax;
X    mc[i] = z;
X    sprintf(sz, "%3.0f%c", RAbs(z), z < 0.0 ? 'e' : 'w'); PrintSz(sz);
X  }
X  AnsiColor(kDefault);
X
X  /* The Nadir lines are just always 180 degrees away from the Midheaven. */
X
X  PrintSz("\nNadir  : ");
X  for (i = 1; i <= tot; i++)
X    if (!ignore[i] && FThing(i)) {
X    AnsiColor(kObjA[i]);
X    z = mc[i] + rDegHalf;
X    if (z > rDegHalf)
X      z -= rDegMax;
X    ic[i] = z;
X    sprintf(sz, "%3.0f%c", RAbs(z), z < 0.0 ? 'e' : 'w'); PrintSz(sz);
X  }
X  AnsiColor(kDefault);
X
X  /* Print the Zenith latitude locations. */
X
X  PrintSz("\nZenith : ");
X  for (i = 1; i <= tot; i++)
X    if (!ignore[i] && FThing(i)) {
X      AnsiColor(kObjA[i]);
X      y = DFromR(planet2[i]);
X      sprintf(sz, "%3.0f%c", RAbs(y), y < 0.0 ? 's' : 'n'); PrintSz(sz);
X      as[i] = ds[i] = as1[i] = ds1[i] = rLarge;
X    }
X  PrintL2();
X
X  /* Now print the locations of Ascendant and Descendant lines. Since these */
X  /* are curvy, we loop through the latitudes, and for each object at each  */
X  /* latitude, print the longitude location of the line in question.        */
X
X  longm = RFromD(Mod(DFromR(planet1[oMC])+lo));
X  for (j = 80; j >= -80; j -= us.nAstroGraphStep) {
X    AnsiColor(kDefault);
X    sprintf(sz, "Asc@%2d%c: ", j >= 0 ? j : -j, j < 0 ? 's' : 'n');
X    PrintSz(sz);
X    for (i = 1; i <= tot; i++)
X      if (!ignore[i] && FThing(i)) {
X      AnsiColor(kObjA[i]);
X      ad = RTan(planet2[i])*RTan(RFromD(j));
X      if (ad*ad > 1.0) {
X        PrintSz(" -- ");
X        as1[i] = ds1[i] = cp2.dir[i] = rLarge;
X      } else {
X        ad = RAsin(ad);
X        oa = planet1[i]-ad;
X        if (oa < 0.0)
X          oa += 2.0*rPi;
X        am = oa-rPiHalf;
X        if (am < 0.0)
X          am += 2.0*rPi;
X        z = longm-am;
X        if (z < 0.0)
X          z += 2.0*rPi;
X        if (z > rPi)
X          z -= 2.0*rPi;
X        as1[i] = as[i];
X        as[i] = z = DFromR(z);
X        cp2.dir[i] = ad;
X        sprintf(sz, "%3.0f%c", RAbs(z), z < 0.0 ? 'e' : 'w'); PrintSz(sz);
X      }
X    }
X
X    /* Again, the Descendant position is related to the Ascendant's,  */
X    /* being a mirror image, so it can be calculated somewhat easier. */
X
X    AnsiColor(kDefault);
X    sprintf(sz, "\nDsc@%2d%c: ", j >= 0 ? j : -j, j < 0 ? 's' : 'n');
X    PrintSz(sz);
X    for (i = 1; i <= tot; i++)
X      if (!ignore[i] && FThing(i)) {
X      AnsiColor(kObjA[i]);
X      ad = cp2.dir[i];
X      if (ad == rLarge)
X        PrintSz(" -- ");
X      else {
X        od = planet1[i]+ad;
X        dm = od+rPiHalf;
X        z = longm-dm;
X        if (z < 0.0)
X          z += 2.0*rPi;
X        if (z > rPi)
X          z -= 2.0*rPi;
X        ds1[i] = ds[i];
X        ds[i] = z = DFromR(z);
X        sprintf(sz, "%3.0f%c", RAbs(z), z < 0.0 ? 'e' : 'w'); PrintSz(sz);
X      }
X    }
X    PrintL();
#endif /* MATRIX */
X
X    /* Now, if the -L0 switch is in effect, then take these line positions, */
X    /* which we saved in an array above as we were printing them, and       */
X    /* calculate and print the latitude crossings.                          */
X
X    if (us.fLatitudeCross)
X      for (l = 1; l <= cObj; l++) if (!ignore[l] && FThing(l))
X        for (k = 1; k <= cObj; k++) {
X          if (ignore[k] || !FThing(k))
X            continue;
X          for (n = 0; n <= 1; n++) {
X            x = n ? ds1[l] : as1[l];
X            y = n ? ds[l] : as[l];
X            for (m = 0; m <= 1; m++) {
X
X            /* Check if Ascendant/Descendant cross Midheaven/Nadir. */
X
X            z = m ? ic[k] : mc[k];
X            if (cCross < MAXCROSS &&
X              RAbs(x-y) < rDegHalf && RSgn(z-x) != RSgn(z-y)) {
X              c->obj1[cCross] = n ? -l : l;
X              c->obj2[cCross] = m ? -k : k;
X              c->lat[cCross] = (real)j+5.0*RAbs(z-y)/RAbs(x-y);
X              c->lon[cCross] = z;
X              cCross++;
X            }
X
X            /* Check if Ascendant/Descendant cross another Asc/Des. */
X
X            w = m ? ds1[k] : as1[k];
X            z = m ? ds[k] : as[k];
X            if (cCross < MAXCROSS && k > l &&
X                RAbs(x-y)+RAbs(w-z) < rDegHalf && RSgn(w-x) != RSgn(z-y)) {
X              c->obj1[cCross] = n ? -l : l;
X              c->obj2[cCross] = 100+(m ? -k : k);
X              c->lat[cCross] = (real)j+5.0*
X                RAbs(y-z)/(RAbs(x-w)+RAbs(y-z));
X              c->lon[cCross] = Min(x, y)+RAbs(x-y)*
X                RAbs(y-z)/(RAbs(x-w)+RAbs(y-z));
X              cCross++;
X            }
X          }
X        }
X    }
X  }
X  if (!us.fLatitudeCross)
X    return;
X  PrintL();
X
X  /* Now, print out all the latitude crossings we found.  */
X  /* First, we sort them in order of decreasing latitude. */
X
X  for (i = 1; i < cCross; i++) {
X    j = i-1;
X    while (j >= 0 && c->lat[j] < c->lat[j+1]) {
X      SwapN(c->obj1[j], c->obj1[j+1]); SwapN(c->obj2[j], c->obj2[j+1]);
X      SwapR(&c->lat[j], &c->lat[j+1]); SwapR(&c->lon[j], &c->lon[j+1]);
X      j--;
X    }
X  }
X  for (i = 1; i < cCross; i++) {
X    j = abs(c->obj1[i]);
X    AnsiColor(kObjA[j]);
X    sprintf(sz, "%c%c%c ", chObj3(j)); PrintSz(sz);
X    AnsiColor(kElemA[c->obj1[i] > 0 ? eFir : eAir]);
X    PrintSz(c->obj1[i] > 0 ? "Ascendant " : "Descendant");
X    AnsiColor(kWhite);
X    PrintSz(" crosses ");
X    j = abs(c->obj2[i] - (c->obj2[i] < 50 ? 0 : 100));
X    AnsiColor(kObjA[j]);
X    sprintf(sz, "%c%c%c ", chObj3(j)); PrintSz(sz);
X    AnsiColor(kElemA[c->obj2[i] < 50 ?
X      (c->obj2[i] > 0 ? eEar : eWat) : (c->obj2[i] > 100 ? eFir : eAir)]);
X    sprintf(sz, "%s ", c->obj2[i] < 50 ? (c->obj2[i] > 0 ? "Midheaven " :
X      "Nadir     ") : (c->obj2[i] > 100 ? "Ascendant " : "Descendant"));
X    PrintSz(sz);
X    AnsiColor(kDefault);
X    sprintf(sz, "at %s%c,", SzDegree(c->lon[i]),
X      c->lon[i] < 0.0 ? 'E' : 'W'); PrintSz(sz);
X    j = (int)(RFract(RAbs(c->lat[i]))*60.0);
X    sprintf(sz, "%s%c\n", SzDegree(c->lat[i]),
X      c->lat[i] < 0.0 ? 'S' : 'N'); PrintSz(sz);
X  }
X  DeallocateFar(c);
X  if (!cCross) {
X    AnsiColor(kDefault);
X    PrintSz("No latitude crossings.\n");
X  }
}
X
X
/* Another important procedure: Display any of the types of (text) charts    */
/* that the user specified they wanted, by calling the appropriate routines. */
X
void PrintChart(fProg)
bool fProg;
{
X  int fCall = fFalse;
X
X  if (us.fListing) {
X    if (is.fMult)
X      PrintL2();
X    if (us.nRel < rcDifference)
X      ChartListing();
X    else
X
X      /* If the -rb or -rd relationship charts are in effect, then instead  */
X      /* of doing the standard -v chart, print either of these chart types. */
X
X      DisplayRelation();
X    is.fMult = fTrue;
X  }
X  if (us.fWheel) {
X    if (is.fMult)
X      PrintL2();
X    ChartWheel();
X    is.fMult = fTrue;
X  }
X  if (us.fGrid) {
X    if (is.fMult)
X      PrintL2();
X    if (us.nRel > rcDual) {
X      fCall = us.fSmartCusp; us.fSmartCusp = fFalse;
X      if (!FCreateGrid(fFalse))
X        return;
X      us.fSmartCusp = fCall;
X      not(fCall);
X      ChartGrid();
X      if (us.fGridConfig) {    /* If -g0 switch in effect, then  */
X        PrintL();              /* display aspect configurations. */
X        if (!fCall)
X          FCreateGrid(fFalse);
X        DisplayGrands();
X      }
X    } else {
X
X      /* Do a relationship aspect grid between two charts if -r0 in effect. */
X
X      fCall = us.fSmartCusp; us.fSmartCusp = fFalse;
X      if (!FCreateGridRelation(us.fGridConfig))
X        return;
X      us.fSmartCusp = fCall;
X      ChartGridRelation();
X    }
X    is.fMult = fTrue;
X  }
X  if (us.fAspList) {
X    if (is.fMult)
X      PrintL2();
X    if (us.nRel > rcDual) {
X      if (!fCall) {
X        fCall = fTrue;
X        if (!FCreateGrid(fFalse))
X          return;
X      }
X      ChartAspect();
X    } else {
X      if (!FCreateGridRelation(fFalse))
X        return;
X      ChartAspectRelation();
X    }
X    is.fMult = fTrue;
X  }
X  if (us.fMidpoint) {
X    if (is.fMult)
X      PrintL2();
X    if (us.nRel > rcDual) {
X      if (!fCall) {
X        if (!FCreateGrid(fFalse))
X          return;
X      }
X      ChartMidpoint();
X    } else {
X      if (!FCreateGridRelation(fTrue))
X        return;
X      ChartMidpointRelation();
X    }
X    is.fMult = fTrue;
X  }
X  if (us.fHorizon) {
X    if (is.fMult)
X      PrintL2();
X    if (us.fHorizonSearch)
X      ChartInDayHorizon();
X    else
X      ChartHorizon();
X    is.fMult = fTrue;
X  }
X  if (us.fOrbit) {
X    if (is.fMult)
X      PrintL2();
X    ChartOrbit();
X    is.fMult = fTrue;
X  }
X  if (us.fSector) {
X    if (is.fMult)
X      PrintL2();
X    else
X      PrintHeader();    /* Print chart header if it hasn't been done yet. */
X    ChartSector();
X    is.fMult = fTrue;
X  }
X  if (us.fInfluence) {
X    if (is.fMult)
X      PrintL2();
X    ChartInfluence();
X    is.fMult = fTrue;
X  }
X  if (us.fAstroGraph) {
X    if (is.fMult)
X      PrintL2();
X    ChartAstroGraph();
X    is.fMult = fTrue;
X  }
X  if (us.fCalendar) {
X    if (is.fMult)
X      PrintL2();
X    if (us.fCalendarYear)
X      ChartCalendarYear();
X    else
X      ChartCalendarMonth();
X    is.fMult = fTrue;
X  }
X  if (us.fInDay) {
X    if (is.fMult)
X      PrintL2();
X    ChartInDaySearch(fProg);
X    is.fMult = fTrue;
X  }
X  if (us.fInDayInf) {
X    if (is.fMult)
X      PrintL2();
X    ChartInDayInfluence();
X    is.fMult = fTrue;
X  }
X  if (us.fEphemeris) {
X    if (is.fMult)
X      PrintL2();
X    ChartEphemeris();
X    is.fMult = fTrue;
X  }
X  if (us.fTransit) {
X    if (is.fMult)
X      PrintL2();
X    ChartTransitSearch(fProg);
X    is.fMult = fTrue;
X  }
X  if (us.fTransitInf) {
X    if (is.fMult)
X      PrintL2();
X    ChartTransitInfluence(fProg);
X    is.fMult = fTrue;
X  }
#ifdef ARABIC
X  if (us.nArabic) {
X    if (is.fMult)
X      PrintL2();
X    DisplayArabic();
X    is.fMult = fTrue;
X  }
#endif
X
X  if (!is.fMult) {          /* Assume the -v chart if user */
X    us.fListing = fTrue;    /* didn't indicate anything.   */
X    PrintChart(fProg);
X    is.fMult = fTrue;
X  }
}
X
/* charts1.c */
SHAR_EOF
  $shar_touch -am 1223232998 'charts1.c' &&
  chmod 0644 'charts1.c' ||
  echo 'restore of charts1.c failed'
  shar_count="`wc -c < 'charts1.c'`"
  test 48646 -eq "$shar_count" ||
    echo "charts1.c: original size 48646, current size $shar_count"
fi
# ============= charts2.c ==============
if test -f 'charts2.c' && test X"$1" != X"-c"; then
  echo 'x - skipping charts2.c (File already exists)'
else
  echo 'x - extracting charts2.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'charts2.c' &&
/*
** Astrolog (Version 5.40) File: charts2.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
/*
******************************************************************************
** Dual Chart Display Routines.
******************************************************************************
*/
X
/* Print out an aspect (or midpoint if -g0 switch in effect) grid of a      */
/* relationship chart. This is similar to the ChartGrid() routine; however, */
/* here we have both axes labeled with the planets for the two charts in    */
/* question, instead of just a diagonal down the center for only one chart. */
X
void ChartGridRelation()
{
X  char sz[cchSzDef];
X  int i, j, k, tot = cObj, temp;
X
#ifdef INTERPRET
X  if (us.fInterpret && !us.fGridConfig) {
X    InterpretGridRelation();
X    return;
X  }
#endif
X  PrintSz(" 2>");
X  for (temp = 0, i = 1; i <= cObj; i++) if (!ignore[i]) {
X    PrintCh(chV);
X    AnsiColor(kObjA[i]);
X    sprintf(sz, "%c%c%c", chObj3(i)); PrintSz(sz);
X    AnsiColor(kDefault);
X    temp++;
X  }
X  PrintSz("\n1  ");
X  for (i = 1; i <= tot; i++) if (!ignore[i]) {
X    PrintCh(chV);
X    AnsiColor(kSignA(SFromZ(cp2.obj[i])));
X    sprintf(sz, "%2d%c", (int)cp2.obj[i] % 30, chDeg0); PrintSz(sz);
X    AnsiColor(kDefault);
X  }
X  PrintSz("\nV  ");
X  for (i = 1; i <= tot; i++) if (!ignore[i]) {
X    PrintCh(chV);
X    temp = SFromZ(cp2.obj[i]);
X    AnsiColor(kSignA(temp));
X    sprintf(sz, "%c%c%c", chSig3(temp)); PrintSz(sz);
X    AnsiColor(kDefault);
X  }
X  PrintL();
X  for (j = 1; j <= cObj; j++) if (!ignore[j])
X    for (k = 1; k <= 4; k++) {
X      if (k < 2)
X        PrintTab(chH, 3);
X      else if (k == 2) {
X        AnsiColor(kObjA[j]);
X        sprintf(sz, "%c%c%c", chObj3(j)); PrintSz(sz);
X      } else {
X        temp = SFromZ(cp1.obj[j]);
X        AnsiColor(kSignA(temp));
X        if (k == 3)
X          sprintf(sz, "%2d%c", (int)cp1.obj[j] - (temp-1)*30, chDeg0);
X        else
X          sprintf(sz, "%c%c%c", chSig3(temp));
X        PrintSz(sz);
X      }
X      if (k > 1)
X        AnsiColor(kDefault);
X      for (i = 1; i <= tot; i++) if (!ignore[i]) {
X        PrintCh((char)(k < 2 ? chC : chV));
X        temp = grid->n[i][j];
X        if (k > 1) {
X          if (i == j)
X            AnsiColor(kReverse);
X          AnsiColor(us.fGridConfig ? kSignA(temp) :
X            kAspA[temp]);
X        }
X        if (k < 2)
X          PrintTab(chH, 3);
X        else if (k == 2) {
X          if (us.fGridConfig)
X            sprintf(sz, "%c%c%c", chSig3(temp));
X          else
X            sprintf(sz, "%s", temp ? szAspectAbbrev[temp] : "   ");
X          PrintSz(sz);
X        } else if (k == 3) {
X          if (us.fGridConfig) {
X            sprintf(sz, "%2d%c", grid->v[i][j]/60, chDeg0); PrintSz(sz);
X          } else
X            if (grid->n[i][j]) {
X              if (grid->v[i][j] < 6000)
X                sprintf(sz, "%c%2d", us.fAppSep ?
X                  (grid->v[i][j] < 0 ? 'a' : 's') :
X                  (grid->v[i][j] < 0 ? '-' : '+'), abs(grid->v[i][j])/60);
X              else
X                sprintf(sz, "%3d", abs(temp)/60);
X              PrintSz(sz);
X            } else
X              PrintSz("   ");
X        } else {
X          if (grid->n[i][j]) {
X            sprintf(sz, "%02d'", abs(grid->v[i][j])%60); PrintSz(sz);
X          } else
X            PrintSz("   ");
X        }
X        AnsiColor(kDefault);
X      }
X      PrintL();
X    }
}
X
X
/* Display all aspects between objects in the relationship comparison chart, */
/* one per line, in sorted order based on the total "power" of the aspects,  */
/* as specified with the -r0 -a switch combination.                          */
X
void ChartAspectRelation()
{
X  int ca[cAspect + 1], co[objMax];
X  char sz[cchSzDef];
X  int pcut = 30000, icut, jcut, phi, ihi, jhi, ahi, p, i, j, k, count = 0;
X  real ip, jp, rPowSum = 0.0;
X
X  ClearB((lpbyte)ca, (cAspect + 1)*(int)sizeof(int));
X  ClearB((lpbyte)co, objMax*(int)sizeof(int));
X  loop {
X    phi = -1;
X
X    /* Search for the next most powerful aspect in the aspect grid. */
X
X    for (i = 0; i <= cObj; i++) if (!FIgnore(i))
X      for (j = 0; j <= cObj; j++) if (!FIgnore(j))
X        if (k = grid->n[i][j]) {
X          ip = i <= oNorm ? rObjInf[i] : 2.5;
X          jp = j <= oNorm ? rObjInf[j] : 2.5;
X          p = (int)(rAspInf[k]*(ip+jp)/2.0*
X            (1.0-RAbs((real)(grid->v[i][j]))/60.0/GetOrb(i, j, k))*1000.0);
X          if ((p < pcut || (p == pcut && (i > icut ||
X            (i == icut && j > jcut)))) && p > phi) {
X            ihi = i; jhi = j; phi = p; ahi = k;
X          }
X        }
X    if (phi < 0)    /* Exit when no less powerful aspect found. */
X      break;
X    pcut = phi; icut = ihi; jcut = jhi;
X    count++;                              /* Display the current aspect.   */
#ifdef INTERPRET
X    if (us.fInterpret) {                  /* Interpret it if -I in effect. */
X      InterpretAspectRelation(jhi, ihi);
X      continue;
X    }
#endif
X    rPowSum += (real)phi/1000.0;
X    ca[ahi]++;
X    co[jhi]++; co[ihi]++;
X    sprintf(sz, "%3d: ", count); PrintSz(sz);
X    PrintAspect(jhi, SFromZ(cp1.obj[jhi]), (int)RSgn(cp1.dir[jhi]), ahi,
X      ihi, SFromZ(cp2.obj[ihi]), (int)RSgn(cp2.dir[ihi]), 'A');
X    k = grid->v[ihi][jhi];
X    AnsiColor(k < 0 ? kWhite : kLtGray);
X    sprintf(sz, "- orb: %c%d,%02d'",
X      us.fAppSep ? (k < 0 ? 'a' : 's') : (k < 0 ? '-' : '+'),
X      abs(k)/60, abs(k)%60); PrintSz(sz);
X    AnsiColor(kDkGreen);
X    sprintf(sz, " - power:%6.2f\n", (real)phi/1000.0); PrintSz(sz);
X    AnsiColor(kDefault);
X  }
X
X  PrintAspectSummary(ca, co, count, rPowSum);
}
X
X
/* Display locations of all midpoints between objects in the relationship */
/* comparison chart, one per line, in sorted zodiac order from zero Aries */
/* onward, as specified with the -r0 -m switch combination.               */
X
void ChartMidpointRelation()
{
X  int cs[cSign + 1];
X  char sz[cchSzDef];
X  int mcut = -1, icut, jcut, mlo, ilo, jlo, m, i, j, count = 0;
X  long lSpanSum = 0;
X
X  ClearB((lpbyte)cs, (cSign + 1)*(int)sizeof(int));
X  loop {
X    mlo = 21600;
X
X    /* Search for the next closest midpoint farther down in the zodiac. */
X
X    for (i = 0; i <= cObj; i++) if (!FIgnore(i))
X      for (j = 0; j <= cObj; j++) if (!FIgnore(j)) {
X        m = (grid->n[j][i]-1)*30*60 + grid->v[j][i];
X        if ((m > mcut || (m == mcut && (i > icut ||
X          (i == icut && j > jcut)))) && m < mlo) {
X          ilo = i; jlo = j; mlo = m;
X        }
X      }
X    if (mlo >= 21600)    /* Exit when no midpoint farther in zodiac found. */
X      break;
X    mcut = mlo; icut = ilo; jcut = jlo;
X    count++;                               /* Display the current midpoint. */
#ifdef INTERPRET
X    if (us.fInterpret) {                   /* Interpret it if -I in effect. */
X      InterpretMidpointRelation(ilo, jlo);
X      continue;
X    }
#endif
X    cs[mlo/60/30+1]++;
X    sprintf(sz, "%4d: ", count); PrintSz(sz);
X    PrintZodiac((real)mlo/60.0);
X    PrintCh(' ');
X    PrintAspect(ilo, SFromZ(cp1.obj[ilo]), (int)RSgn(cp1.dir[ilo]), 0,
X      jlo, SFromZ(cp2.obj[jlo]), (int)RSgn(cp2.dir[jlo]), 'M');
X    AnsiColor(kDefault);
X    m = (int)(MinDistance(cp1.obj[ilo], cp2.obj[jlo])*60.0);
X    lSpanSum += m;
X    sprintf(sz, "-%4d%c%02d' degree span.\n", m/60, chDeg1, m%60);
X    PrintSz(sz);
X  }
X
X  PrintMidpointSummary(cs, count, lSpanSum);
}
X
X
/* Calculate any of the various kinds of relationship charts. This involves */
/* computing and storing the planet and house positions for the "core" and  */
/* "second" charts, and then combining them in the main single chart in the */
/* proper manner, e.g. for synastry, composite, time space midpoint charts. */
X
void CastRelation()
{
X  byte ignoreT[objMax];
X  int i;
X  real ratio, t1, t2, t;
X
X  /* Cast the first chart. */
X
X  ciMain = ciCore;
X  t1 = CastChart(fTrue);
X  cp1 = cp0;
X
X  /* Cast the second chart. */
X
X  ciCore = ciTwin;
X  if (us.nRel == rcTransit) {
X    for (i = 0; i <= cObj; i++) {
X      ignoreT[i] = ignore[i];
X      ignore[i] = ignore[i] && ignore2[i];
X    }
X  } else if (us.nRel == rcProgress) {
X    us.fProgress = fTrue;
X    is.JDp = MdytszToJulian(MM, DD, YY, TT, SS, ZZ);
X    ciCore = ciMain;
X  }
X  t2 = CastChart(fTrue);
X  if (us.nRel == rcTransit) {
X    for (i = 0; i <= cObj; i++)
X      ignore[i] = ignoreT[i];
X  } else if (us.nRel == rcProgress)
X    us.fProgress = fFalse;
X  cp2 = cp0;
X  ciCore = ciMain;
X
X  /* Now combine the two charts based on what relation we are doing.   */
X  /* For the standard -r synastry chart, use the house cusps of chart1 */
X  /* and the planet positions of chart2.                               */
X
X  ratio = (real)us.nRatio1 / ((real)(us.nRatio1 + us.nRatio2));
X  if (us.nRel <= rcSynastry) {
X    for (i = 1; i <= cSign; i++)
X      chouse[i] = cp1.cusp[i];
X
X  /* For the -rc composite chart, take the midpoints of the planets/houses. */
X
X  } else if (us.nRel == rcComposite) {
X    for (i = 0; i <= cObj; i++) {
X      planet[i] = Ratio(cp1.obj[i], cp2.obj[i], ratio);
X      if (RAbs(cp2.obj[i] - cp1.obj[i]) > rDegHalf)
X        planet[i] = Mod(planet[i] + rDegMax*ratio);
X      planetalt[i] = Ratio(cp1.alt[i], cp2.alt[i], ratio);
X      ret[i] = Ratio(cp1.dir[i], cp2.dir[i], ratio);
X    }
X    for (i = 1; i <= cSign; i++) {
X      chouse[i] = Ratio(cp1.cusp[i], cp2.cusp[i], ratio);
X      if (RAbs(cp2.cusp[i] - cp1.cusp[i]) > rDegHalf)
X        chouse[i] = Mod(chouse[i] + rDegMax*ratio);
X    }
X
X    /* Make sure we don't have any 180 degree errors in house cusp    */
X    /* complement pairs, which may happen if the cusps are far apart. */
X
X    for (i = 1; i <= cSign; i++)
X      if (MinDistance(chouse[sCap], Mod(chouse[i]-ZFromS(i+3))) > rDegQuad)
X        chouse[i] = Mod(chouse[i]+rDegHalf);
X    for (i = 1; i <= cSign; i++)
X      if (RAbs(MinDistance(chouse[i], planet[oAsc - 1 + i])) > rDegQuad)
X        planet[oAsc - 1 + i] = Mod(planet[oAsc - 1 + i]+rDegHalf);
X
X  /* For the -rm time space midpoint chart, calculate the midpoint time and */
X  /* place between the two charts and then recast for the new chart info.   */
X
X  } else if (us.nRel == rcMidpoint) {
X    is.T = Ratio(t1, t2, ratio);
X    t = (is.T*36525.0)+rRound; is.JD = RFloor(t)+2415020.0;
X    TT = RFract(t)*24.0;
X    ZZ = Ratio(DecToDeg(Zon), DecToDeg(ciTwin.zon), ratio);
X    SS = Ratio(DecToDeg(Dst), DecToDeg(ciTwin.dst), ratio);
X    TT -= ZZ - SS;
X    if (TT < 0.0) {
X      TT += 24.0; is.JD -= 1.0;
X    }
X    JulianToMdy(is.JD, &MM, &DD, &YY);
X    OO = Ratio(DecToDeg(Lon), DecToDeg(ciTwin.lon), ratio);
X    if (RAbs(ciTwin.lon-Lon) > rDegHalf)
X      OO = Mod(OO+rDegMax*ratio);
X    AA = Ratio(DecToDeg(Lat), DecToDeg(ciTwin.lat), ratio);
X    TT = DegToDec(TT); SS = DegToDec(SS); ZZ = DegToDec(ZZ);
X    OO = DegToDec(OO); AA = DegToDec(AA);
X    ciMain = ciCore;
X    CastChart(fTrue);
X
X  /* There are a couple of non-astrological charts, which only require the */
X  /* number of days that have passed between the two charts to be done.    */
X
X  } else
X    is.JD = RAbs(t2-t1)*36525.0;
X
X  ComputeInHouses();
}
X
X
/*
******************************************************************************
** Other Chart Display Routines.
******************************************************************************
*/
X
/* Given two objects and an aspect between them, or an object and a sign  */
/* that it's entering, print if this is a "major" event, such as a season */
/* change or major lunar phase. This is called from the ChartInDay()      */
/* searching and influence routines. Do an interpretation if need be too. */
X
void PrintInDay(source, aspect, dest)
int source, aspect, dest;
{
X  if (aspect == aSig) {
X    if (source == oSun) {
X      AnsiColor(kWhite);
X      if (dest == 1)
X        PrintSz(" (Vernal Equinox)");     /* If the Sun changes sign, */
X      else if (dest == 4)                 /* then print out if this   */
X        PrintSz(" (Summer Solstice)");    /* is a season change.      */
X      else if (dest == 7)
X        PrintSz(" (Autumnal Equinox)");
X      else if (dest == 10)
X        PrintSz(" (Winter Solstice)");
X    }
X  } else if (aspect > 0) {
X    if (source == oSun && dest == oMoo) {
X      if (aspect <= aSqu)
X        AnsiColor(kWhite);
X      if (aspect == aCon)
X        PrintSz(" (New Moon)");     /* Print out if the present */
X      else if (aspect == aOpp)      /* aspect is a New, Full,   */
X        PrintSz(" (Full Moon)");    /* or Half Moon.            */
X      else if (aspect == aSqu)
X        PrintSz(" (Half Moon)");
X    }
X  }
X  PrintL();
X
#ifdef INTERPRET
X  if (us.fInterpret)
X    InterpretInDay(source, aspect, dest);
#endif
X  AnsiColor(kDefault);
}
X
X
/* Given two objects and an aspect (or one object, and an event such as a */
/* sign or direction change) display the configuration in question. This  */
/* is called by the many charts which list aspects among items, such as   */
/* the -a aspect lists, -m midpoint lists, -d aspect in day search and    */
/* influence charts, and -t transit search and influence charts.          */
X
void PrintAspect(obj1, sign1, ret1, asp, obj2, sign2, ret2, chart)
int obj1, sign1, ret1, asp, obj2, sign2, ret2;
char chart;
{
X  char sz[cchSzDef];
X
X  AnsiColor(kObjA[obj1]);
X  if (chart == 't' || chart == 'T')
X    PrintSz("trans ");
X  else if (chart == 'e' || chart == 'u' || chart == 'U')
X    PrintSz("progr ");
X  sprintf(sz, "%7.7s", szObjName[obj1]); PrintSz(sz);
X  AnsiColor(kSignA(sign1));
X  sprintf(sz, " %c%c%c%c%c",
X    ret1 > 0 ? '(' : (ret1 < 0 ? '[' : '<'), chSig3(sign1),
X    ret1 > 0 ? ')' : (ret1 < 0 ? ']' : '>')); PrintSz(sz);
X  AnsiColor(asp > 0 ? kAspA[asp] : kWhite);
X  PrintCh(' ');
X  if (asp == aSig)
X    sprintf(sz, "-->");                        /* Print a sign change. */
X  else if (asp == aDir)
X    sprintf(sz, "S/%c", obj2 ? chRet : 'D');   /* Print a direction change. */
X  else if (asp == 0)
X    sprintf(sz, chart == 'm' ? "&" : "with");
X  else
X    sprintf(sz, "%s", szAspectAbbrev[asp]);    /* Print an aspect. */
X  PrintSz(sz);
X  if (asp != aDir)
X    PrintCh(' ');
X  if (chart == 'A')
X    PrintSz("with ");
X  if (asp == aSig) {
X    AnsiColor(kSignA(obj2));
X    sprintf(sz, "%s", szSignName[obj2]); PrintSz(sz);
X  } else if (asp >= 0) {
X    AnsiColor(kSignA(sign2));
X    if (chart == 't' || chart == 'u' || chart == 'T' || chart == 'U')
X      PrintSz("natal ");
X    sprintf(sz, "%c%c%c%c%c ",
X      ret2 > 0 ? '(' : (ret2 < 0 ? '[' : '<'), chSig3(sign2),
X      ret2 > 0 ? ')' : (ret2 < 0 ? ']' : '>')); PrintSz(sz);
X    AnsiColor(kObjA[obj2]);
X    sprintf(sz, "%.10s", szObjName[obj2]); PrintSz(sz);
X  }
X  if (chart == 'D' || chart == 'T' || chart == 'U' ||
X    chart == 'a' || chart == 'A' || chart == 'm' || chart == 'M')
X    PrintTab(' ', 10-CchSz(szObjName[obj2]));
}
X
X
/* Based on the given chart information, display all the aspects taking   */
/* place in the chart, as specified with the -D switch. The aspects are   */
/* printed in order of influence determined by treating them as happening */
/* outside among transiting planets, such that rare outer planet aspects  */
/* are given more power than common ones among inner planets. (This is    */
/* almost identical to the -a list, except the influences are different.) */
X
void ChartInDayInfluence()
{
X  int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY];
X  real power[MAXINDAY];
X  char sz[cchSzDef];
X  int occurcount = 0, i, j, k, l, m;
X
X  /* Go compute the aspects in the chart. */
X
X  i = us.fAppSep;
X  us.fAppSep = fTrue;     /* We always want applying vs. separating orbs. */
X  FCreateGrid(fFalse);
X  us.fAppSep = i;
X
X  /* Search through the grid and build up the list of aspects. */
X
X  for (j = 1; j <= cObj; j++) {
X    if (FIgnore(j))
X      continue;
X    for (i = 0; i < j; i++) {
X      if (FIgnore(i) || (k = grid->n[i][j]) == 0 || occurcount >= MAXINDAY)
X        continue;
X      source[occurcount] = i; aspect[occurcount] = k; dest[occurcount] = j;
X      l = grid->v[i][j];
X      power[occurcount] =
X        ((i <= oNorm ? rTransitInf[i] : 2.0)/4.0)*
X        ((j <= oNorm ? rTransitInf[j] : 2.0)/4.0)*
X        rAspInf[k]*(1.0-(real)abs(l)/60.0/GetOrb(i, j, k));
X      occurcount++;
X    }
X  }
X
X  /* Sort aspects by order of influence. */
X
X  for (i = 1; i < occurcount; i++) {
X    j = i-1;
X    while (j >= 0 && power[j] < power[j+1]) {
X      SwapN(source[j], source[j+1]);
X      SwapN(aspect[j], aspect[j+1]);
X      SwapN(dest[j], dest[j+1]);
X      SwapR(&power[j], &power[j+1]);
X      j--;
X    }
X  }
X
X  /* Now display each aspect line. */
X
X  for (i = 0; i < occurcount; i++) {
X    sprintf(sz, "%3d: ", i+1); PrintSz(sz);
X    j = source[i]; k = aspect[i]; l = dest[i];
X    PrintAspect(
X      j, SFromZ(planet[j]), (int)RSgn(ret[j]), k,
X      l, SFromZ(planet[l]), (int)RSgn(ret[l]), 'D');
X    m = grid->v[j][l];
X    AnsiColor(m < 0 ? kWhite : kLtGray);
X    sprintf(sz, "- %s%2d%c%02d'", m < 0 ? "app" : "sep",
X      abs(m)/60, chDeg1, abs(m)%60); PrintSz(sz);
X    AnsiColor(kDkGreen);
X    sprintf(sz, " - power:%6.2f", power[i]); PrintSz(sz);
X    PrintInDay(j, k, l);
X  }
X  if (occurcount == 0)
X    PrintSz("Empty transit aspect list.\n");
}
X
X
/* Given an arbitrary day, determine what aspects are made between this */
/* transiting chart and the given natal chart, as specified with the -T */
/* switch, and display the transits in order sorted by influence.       */
X
void ChartTransitInfluence(fProg)
bool fProg;
{
X  int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY];
X  real power[MAXINDAY];
X  byte ignore3[objMax];
X  char sz[cchSzDef];
X  int occurcount = 0, fProgress = us.fProgress, i, j, k, l, m;
X
X  /* Cast the natal and transiting charts as with a relationship chart. */
X
X  cp1 = cp0;
X  for (i = 0; i <= cObj; i++) {
X    ignore3[i] = ignore[i]; ignore[i] = ignore2[i];
X  }
X  SetCI(ciCore, ciTran.mon, ciTran.day, ciTran.yea, Tim,
X    Dst, Zon, Lon, Lat);
X  if (us.fProgress = fProg) {
X    is.JDp = MdytszToJulian(MM, DD, YY, TT, SS, ZZ);
X    ciCore = ciMain;
X  }
X  CastChart(fTrue);
X  cp2 = cp0;
X  for (i = 0; i <= cObj; i++) {
X    ignore[i] = ignore3[i];
X  }
X
X  /* Do a relationship aspect grid to get the transits. We have to make and */
X  /* restore three changes to get it right for this chart. (1) We make the  */
X  /* natal planets have zero velocity so applying vs. separating is only a  */
X  /* function of the transiter. (2) We force applying vs. separating orbs   */
X  /* regardless if -ga or -ma is in effect or not. (3) Finally we tweak the */
X  /* main restrictions to allow for transiting objects not restricted.      */
X
X  for (i = 0; i <= cObj; i++) {
X    ret[i] = cp1.dir[i];
X    cp1.dir[i] = 0.0;
X    ignore3[i] = ignore[i];
X    ignore[i] = ignore[i] && ignore2[i];
X  }
X  i = us.fAppSep; us.fAppSep = fTrue;
X  FCreateGridRelation(fFalse);
X  us.fAppSep = i;
X  for (i = 0; i <= cObj; i++) {
X    cp1.dir[i] = ret[i];
X    ignore[i] = ignore3[i];
X  }
X
X  /* Loop through the grid, and build up a list of the valid transits. */
X
X  for (i = 0; i <= oNorm; i++) {
X    if (FIgnore2(i))
X      continue;
X    for (j = 0; j <= cObj; j++) {
X      if (FIgnore(j) || (is.fReturn && i != j) || (k = grid->n[i][j]) == 0 ||
X        occurcount >= MAXINDAY)
X        continue;
X      source[occurcount] = i; aspect[occurcount] = k; dest[occurcount] = j;
X      l = grid->v[i][j];
X      power[occurcount] = rTransitInf[i]*
X        ((j <= oNorm ? rObjInf[j] : 2.0)/4.0)*rAspInf[k]*
X        (1.0-(real)abs(l)/60.0/GetOrb(i, j, k));
X      occurcount++;
X    }
X  }
X
X  /* After all transits located, sort them by their total power. */
X
X  for (i = 1; i < occurcount; i++) {
X    j = i-1;
X    while (j >= 0 && power[j] < power[j+1]) {
X      SwapN(source[j], source[j+1]);
X      SwapN(aspect[j], aspect[j+1]);
X      SwapN(dest[j], dest[j+1]);
X      SwapR(&power[j], &power[j+1]);
X      j--;
X    }
X  }
X
X  /* Now loop through list and display each transit in effect at the time. */
X
X  for (i = 0; i < occurcount; i++) {
X    k = aspect[i];
X    l = source[i];
X    sprintf(sz, "%3d: ", i+1); PrintSz(sz);
X    j = SFromZ(cp2.obj[l]);
X    PrintAspect(l, j, (int)RSgn(cp2.dir[l]), k,
X      dest[i], SFromZ(cp1.obj[dest[i]]), (int)RSgn(cp1.dir[dest[i]]),
X      (char)(fProg ? 'U' : 'T'));
X    m = grid->v[l][dest[i]];
X    AnsiColor(m < 0 ? kWhite : kLtGray);
X    sprintf(sz, "- %s%2d%c%02d'", m < 0 ? "app" : "sep",
X      abs(m)/60, chDeg1, abs(m)%60); PrintSz(sz);
X    AnsiColor(kDkGreen);
X    sprintf(sz, " - power:%6.2f", power[i]); PrintSz(sz);
X    if (k == aCon && l == dest[i]) {    /* Print a small "R" for returns. */
X      AnsiColor(kWhite);
X      PrintSz(" R");
X    }
X    PrintL();
#ifdef INTERPRET
X    if (us.fInterpret)
X      InterpretTransit(l, k, dest[i]);
#endif
X    AnsiColor(kDefault);
X  }
X  if (occurcount == 0)
X    PrintSz("Empty transit list.\n");
X  us.fProgress = fProgress;
X  ciCore = ciMain;
X  CastChart(fTrue);
}
X
X
/* Given the zodiac location of a planet in the sky and its declination,   */
/* and a location on the Earth, compute the azimuth and altitude of where  */
/* on the local horizon sky the planet would appear to one at the given    */
/* location. A reference MC position at Greenwich is also needed for this. */
X
void EclToHorizon(azi, alt, obj, objalt, lon, lat, mc)
real *azi, *alt, obj, objalt, lon, lat, mc;
{
X  real lonz, latz;
X
X  lonz = RFromD(obj); latz = RFromD(objalt);
X  EclToEqu(&lonz, &latz);
X  lonz = RFromD(Mod(DFromR(mc-lonz+lon)));
X  lonz = RFromD(Mod(DFromR(lonz-lon+rPiHalf)));
X  EquToLocal(&lonz, &latz, rPiHalf-lat);
X  *azi = rDegMax-DFromR(lonz); *alt = DFromR(latz);
}
X
X
/* Display a calendar for the given month in the chart, as specified with  */
/* with the -K switch. When color is on, the title is white, weekends are  */
/* highlighted in red, and the specific day in the chart is colored green. */
X
void ChartCalendarMonth()
{
X  char sz[cchSzDef];
X  int i, j, k;
X
X  AnsiColor(kWhite);
X  PrintTab(' ', 16-CchSz(szMonth[Mon]) >> 1);
X  sprintf(sz, "%s%5d\n", szMonth[Mon], Yea); PrintSz(sz);
X  for (i = 0; i < cWeek; i++) {
X    sprintf(sz, "%c%c%c", szDay[i][0], szDay[i][1], i < cWeek-1 ? ' ' : '\n');
X    PrintSz(sz);
X  }
X  j = DayOfWeek(Mon, 1, Yea);
X  AnsiColor(kDefault);
X  for (i = 0; i < j; i++) {
X    if (i == 0)
X      AnsiColor(kRainbowA[1]);
X    PrintSz("-- ");
X    if (i == 0)
X      AnsiColor(kDefault);
X  }
X  k = DayInMonth(Mon, Yea);
X  for (i = 1; i <= k; i = AddDay(Mon, i, Yea, 1)) {
X    if (i == (int)Day)
X      AnsiColor(kRainbowA[4]);
X    else if (j == 0 || j == cWeek-1)
X      AnsiColor(kRainbowA[1]);
X    sprintf(sz, "%2d", i); PrintSz(sz);
X    if (j == 0 || j == cWeek-1 || i == Day)
X      AnsiColor(kDefault);
X    if (j < cWeek-1) {
X      j++;
X      PrintCh(' ');
X    } else {
X      j = 0;
X      PrintL();
X    }
X  }
X  while (j > 0 && j < cWeek) {
X    if (j == cWeek-1)
X      AnsiColor(kRainbowA[1]);
X    j++;
X    sprintf(sz, "--%c", j < cWeek ? ' ' : '\n'); PrintSz(sz);
X  }
X  AnsiColor(kDefault);
}
X
X
/* Display a calendar for the entire year given in the chart, as specified */
/* with the -Ky switch. This is just like twelve of the individual month   */
/* calendars above displayed together, with same color highlights and all. */
X
void ChartCalendarYear()
{
X  char sz[cchSzDef];
X  int r, w, c, m, d, dy, p[3], l[3], n[3];
X
X  dy = DayOfWeek(1, 1, Yea);
X  for (r = 0; r < 4; r++) {     /* Loop over one set of three months */
X    AnsiColor(kWhite);
X    for (c = 0; c < 3; c++) {
X      m = r*3+c+1;
X      PrintTab(' ', 16-CchSz(szMonth[m]) >> 1);
X      sprintf(sz, "%s%5d", szMonth[m], Yea); PrintSz(sz);
X      if (c < 2)
X        PrintTab(' ', 20 + MONTHSPACE -
X          (16-CchSz(szMonth[m]) >> 1) - CchSz(szMonth[m]) - 5);
X    }
X    PrintL();
X    for (c = 0; c < 3; c++) {
X      for (d = 0; d < cWeek; d++) {
X        sprintf(sz, "%c%c%c", szDay[d][0], szDay[d][1],
X          d < cWeek-1 || c < 2 ? ' ' : '\n'); PrintSz(sz);
X      }
X      if (c < 2)
X        PrintTab(' ', MONTHSPACE-1);
X      m = r*3+c+1;
X      p[c] = dy % cWeek;
X      l[c] = DayInMonth(m, Yea);
X      n[c] = 0;
X      dy += DaysInMonth(m, Yea);
X    }
X    for (w = 0; w < cWeek-1; w++) {    /* Loop over one set of week rows */
X      for (c = 0; c < 3; c++) {        /* Loop over one week in a month  */
X        m = r*3+c+1;
X        d = 0;
X        if (w == 0)
X          while (d < p[c]) {
X            if (d == 0)
X              AnsiColor(kRainbowA[1]);
X            PrintSz("-- ");
X            if (d == 0)
X              AnsiColor(kDefault);
X            d++;
X          }
X        AnsiColor(kDefault);
X        while (d < cWeek && n[c] < l[c]) {
X          n[c] = AddDay(m, n[c], Yea, 1);
X          if (n[c] == Day && m == Mon)
X            AnsiColor(kRainbowA[4]);
X          else if (d == 0 || d == cWeek-1)
X            AnsiColor(kRainbowA[1]);
X          sprintf(sz, "%2d%c", n[c], d < cWeek-1 || c < 2 ? ' ' : '\n');
X          PrintSz(sz);
X          if (d == 0 || d == cWeek-1 || (n[c] == Day && m == Mon))
X            AnsiColor(kDefault);
X          d++;
X        }
X        while (d < cWeek) {
X          if (d == 0 || d == cWeek-1)
X            AnsiColor(kRainbowA[1]);
X          sprintf(sz, "--%c", d < cWeek-1 || c < 2 ? ' ' : '\n'); PrintSz(sz);
X          if (d == 0)
X            AnsiColor(kDefault);
X          d++;
X        }
X        if (c < 2)
X          PrintTab(' ', MONTHSPACE-1);
X      }
X    }
X    if (r < 3)
X      PrintL();
X  }
X  AnsiColor(kDefault);
}
X
X
/* Display either a biorhythm chart or the time difference in various units */
/* between two charts, i.e. two types of relationship "charts" that aren't  */
/* related in any way to planetary positions, as specified by either the    */
/* -rb or -rd switches, respectively.                                       */
X
void DisplayRelation()
{
X  char sz[cchSzDef];
X  int i;
#ifdef BIORHYTHM
X  int j;
X  real k, l;
#endif
X
X  /* If we are calculating the difference between two dates, then display */
X  /* the value and return, as with the -rd switch.                        */
X
X  if (us.nRel == rcDifference) {
X    PrintSz("Differences between the dates in the two charts:\n");
X    for (i = 1; i <= 7; i++) {
X      AnsiColor(kRainbowA[i]);
X      switch (i) {
X      case 1: sprintf(sz, "Years  : %.0f", is.JD/365.25);      break;
X      case 2: sprintf(sz, "Months : %.0f", is.JD/(365.25/12)); break;
X      case 3: sprintf(sz, "Weeks  : %.0f", is.JD/7.0);         break;
X      case 4: sprintf(sz, "Days   : %.0f", is.JD);             break;
X      case 5: sprintf(sz, "Hours  : %.0f", is.JD*24.0);        break;
X      case 6: sprintf(sz, "Minutes: %.0f", is.JD*24.0*60.0);   break;
X      case 7: sprintf(sz, "Seconds: %.0f", is.JD*24.0*3600.0); break;
X      }
X      PrintSz(sz);
X      PrintL();
X    }
X    AnsiColor(kDefault);
X    return;
X  }
X
#ifdef BIORHYTHM
X  /* If we are doing a biorhythm (-rb switch), then we'll calculate it for */
X  /* someone born on the older date, at the time of the younger date. Loop */
X  /* through the week preceeding and following the date in question.       */
X
X  is.JD = RFloor(is.JD + rRound);
X  for (is.JD -= (real)(us.nBioday/2), i = -us.nBioday/2; i <= us.nBioday/2;
X    i++, is.JD += 1.0) {
X    if (i == 0)
X      AnsiColor(kWhite);
X    else if (i == 1)
X      AnsiColor(kDefault);
X    j = abs(i);
X    sprintf(sz, "T%c%d%sDay%c:", i < 0 ? '-' : '+', j,
X      j < 10 ? " " : "", j != 1 ? 's' : ' '); PrintSz(sz);
X    for (j = 1; j <= 3; j++) {
X      PrintCh(' ');
X      switch (j) {
X      case 1: k = brPhy; AnsiColor(kRed);   PrintSz("Physical");     break;
X      case 2: k = brEmo; AnsiColor(kBlue);  PrintSz("Emotional");    break;
X      case 3: k = brInt; AnsiColor(kGreen); PrintSz("Intellectual"); break;
X      }
X      AnsiColor(i ? kDefault : kWhite);
X
X      /* The biorhythm calculation is below. */
X
X      l = RBiorhythm(is.JD, k);
X      sprintf(sz, " at %c%3.0f%%", l < 0.0 ? '-' : '+', RAbs(l)); PrintSz(sz);
X
X      /* Print smiley face, medium face, or sad face based on current cycle. */
X
X      AnsiColor(kPurple);
X      sprintf(sz, " :%c", l > 50.0 ? ')' : (l < -50.0 ? '(' : '|'));
X      PrintSz(sz);
X      AnsiColor(i ? kDefault : kWhite);
X      if (j < 3)
X        PrintCh(',');
X    }
X    PrintL();
X  }
#endif /* BIORHYTHM */
}
X
/* charts2.c */
SHAR_EOF
  $shar_touch -am 1223232998 'charts2.c' &&
  chmod 0644 'charts2.c' ||
  echo 'restore of charts2.c failed'
  shar_count="`wc -c < 'charts2.c'`"
  test 29610 -eq "$shar_count" ||
    echo "charts2.c: original size 29610, current size $shar_count"
fi
# ============= charts3.c ==============
if test -f 'charts3.c' && test X"$1" != X"-c"; then
  echo 'x - skipping charts3.c (File already exists)'
else
  echo 'x - extracting charts3.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'charts3.c' &&
/*
** Astrolog (Version 5.40) File: charts3.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
/*
******************************************************************************
** Multiple Chart Scanning Routines.
******************************************************************************
*/
X
/* Search through a day, and print out the times of exact aspects among the  */
/* planets during that day, as specified with the -d switch, as well as the  */
/* times when a planet changes sign or direction. To do this, we cast charts */
/* for the beginning and end of the day, or a part of a day, and do a linear */
/* equation check to see if anything exciting happens during the interval.   */
/* (This is probably the single most complicated procedure in the program.)  */
X
void ChartInDaySearch(fProg)
bool fProg;
{
X  char sz[cchSzDef];
X  int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY],
X    sign1[MAXINDAY], sign2[MAXINDAY], D1, D2, counttotal = 0, occurcount,
X    division, div, fYear, yea0, yea1, yea2, i, j, k, l, s1, s2;
X  real time[MAXINDAY], divsiz, d1, d2, e1, e2, f1, f2, g;
X  CI ciT;
X
X  /* If parameter 'fProg' is set, look for changes in a progressed chart. */
X
X  ciT = ciTran;
X  fYear = us.fInDayMonth && (MonT == 0);
X  division = (fYear || fProg) ? 1 : us.nDivision;
X  divsiz = 24.0 / (real)division*60.0;
X
X  /* If -dY in effect, then search through a range of years. */
X
X  yea1 = fProg ? YeaT : Yea;
X  yea2 = fYear ? (yea1 + us.nEphemYears - 1) : yea1;
X  for (yea0 = yea1; yea0 <= yea2; yea0++) {
X
X  /* If -dm in effect, then search through the whole month, day by day. */
X
X  if (us.fInDayMonth) {
X    D1 = 1;
X    if (fYear) {
X      MonT = 1; D2 = DayInYearHi(yea0);
X    } else
X      D2 = DayInMonth(fProg ? MonT : Mon, yea0);
X  } else
X    D1 = D2 = Day;
X
X  /* Start searching the day or days in question for exciting stuff. */
X
X  for (DayT = D1; DayT <= D2; DayT = AddDay(Mon, DayT, yea0, 1)) {
X    occurcount = 0;
X
X    /* Cast chart for beginning of day and store it for future use. */
X
X    SetCI(ciCore, fYear ? MonT : Mon, DayT, yea0, 0.0, Dst, Zon, Lon, Lat);
X    if (us.fProgress = fProg) {
X      is.JDp = MdytszToJulian(MonT, DD, yea0, 0.0, Dst, Zon);
X      ciCore = ciMain;
X    }
X    CastChart(fTrue);
X    cp2 = cp0;
X
X    /* Now divide the day into segments and search each segment in turn. */
X    /* More segments is slower, but has slightly better time accuracy.   */
X
X    for (div = 1; div <= division; div++) {
X
X      /* Cast the chart for the ending time of the present segment. The   */
X      /* beginning time chart is copied from the previous end time chart. */
X
X      SetCI(ciCore, fYear ? MonT : Mon, DayT, yea0,
X        DegToDec(24.0*(real)div/(real)division), Dst, Zon, Lon, Lat);
X      if (fProg) {
X        is.JDp = MdytszToJulian(MonT, DD+1, yea0, 0.0, Dst, Zon);
X        ciCore = ciMain;
X      }
X      CastChart(fTrue);
X      cp1 = cp2; cp2 = cp0;
X
X      /* Now search through the present segment for anything exciting. */
X
X      for (i = 0; i <= cObj; i++) if (!FIgnore(i) && (fProg || FThing(i))) {
X        s1 = SFromZ(cp1.obj[i])-1;
X        s2 = SFromZ(cp2.obj[i])-1;
X
X        /* Does the current planet change into the next or previous sign? */
X
X        if (s1 != s2 && !us.fIgnoreSign) {
X          source[occurcount] = i;
X          aspect[occurcount] = aSig;
X          dest[occurcount] = s2+1;
X          time[occurcount] = MinDistance(cp1.obj[i],
X            (real)(cp1.dir[i] >= 0.0 ? s2 : s1) * 30.0) /
X            MinDistance(cp1.obj[i], cp2.obj[i])*divsiz + (real)(div-1)*divsiz;
X          sign1[occurcount] = sign2[occurcount] = s1+1;
X          occurcount++;
X        }
X
X        /* Does the current planet go retrograde or direct? */
X
X        if ((cp1.dir[i] < 0.0) != (cp2.dir[i] < 0.0) && !us.fIgnoreDir) {
X          source[occurcount] = i;
X          aspect[occurcount] = aDir;
X          dest[occurcount] = cp2.dir[i] < 0.0;
X          time[occurcount] = RAbs(cp1.dir[i])/(RAbs(cp1.dir[i])+
X            RAbs(cp2.dir[i]))*divsiz + (real)(div-1)*divsiz;
X          sign1[occurcount] = sign2[occurcount] = s1+1;
X          occurcount++;
X        }
X
X        /* Now search for anything making an aspect to the current planet. */
X
X        for (j = i+1; j <= cObj; j++) if (!FIgnore(j) && (fProg || FThing(j)))
X          for (k = 1; k <= us.nAsp; k++) if (FAcceptAspect(i, k, j)) {
X            d1 = cp1.obj[i]; d2 = cp2.obj[i];
X            e1 = cp1.obj[j]; e2 = cp2.obj[j];
X            if (MinDistance(d1, d2) < MinDistance(e1, e2)) {
X              SwapR(&d1, &e1);
X              SwapR(&d2, &e2);
X            }
X
X            /* We are searching each aspect in turn. Let's subtract the  */
X            /* size of the aspect from the angular difference, so we can */
X            /* then treat it like a conjunction.                         */
X
X            if (MinDistance(e1, Mod(d1-rAspAngle[k])) <
X                MinDistance(e2, Mod(d2+rAspAngle[k]))) {
X              e1 = Mod(e1+rAspAngle[k]);
X              e2 = Mod(e2+rAspAngle[k]);
X            } else {
X              e1 = Mod(e1-rAspAngle[k]);
X              e2 = Mod(e2-rAspAngle[k]);
X            }
X
X            /* Check to see if the aspect actually occurs during our    */
X            /* segment, making sure we take into account if one or both */
X            /* planets are retrograde or if they cross the Aries point. */
X
X            f1 = e1-d1;
X            if (RAbs(f1) > rDegHalf)
X              f1 -= RSgn(f1)*rDegMax;
X            f2 = e2-d2;
X            if (RAbs(f2) > rDegHalf)
X              f2 -= RSgn(f2)*rDegMax;
X            if (MinDistance(Midpoint(d1, d2), Midpoint(e1, e2)) < rDegQuad &&
X              RSgn(f1) != RSgn(f2)) {
X              source[occurcount] = i;
X              aspect[occurcount] = k;
X              dest[occurcount] = j;
X
X              /* Horray! The aspect occurs sometime during the interval.   */
X              /* Now we just have to solve an equation in two variables to */
X              /* find out where the "lines" cross, i.e. the aspect's time. */
X
X              f1 = d2-d1;
X              if (RAbs(f1) > rDegHalf)
X                f1 -= RSgn(f1)*rDegMax;
X              f2 = e2-e1;
X              if (RAbs(f2) > rDegHalf)
X                f2 -= RSgn(f2)*rDegMax;
X              g = (RAbs(d1-e1) > rDegHalf ?
X                (d1-e1)-RSgn(d1-e1)*rDegMax : d1-e1)/(f2-f1);
X              time[occurcount] = g*divsiz + (real)(div-1)*divsiz;
X              sign1[occurcount] = (int)(Mod(cp1.obj[i]+
X                RSgn(cp2.obj[i]-cp1.obj[i])*
X                (RAbs(cp2.obj[i]-cp1.obj[i]) > rDegHalf ? -1 : 1)*
X                RAbs(g)*MinDistance(cp1.obj[i], cp2.obj[i]))/30.0)+1;
X              sign2[occurcount] = (int)(Mod(cp1.obj[j]+
X                RSgn(cp2.obj[j]-cp1.obj[j])*
X                (RAbs(cp2.obj[j]-cp1.obj[j]) > rDegHalf ? -1 : 1)*
X                RAbs(g)*MinDistance(cp1.obj[j], cp2.obj[j]))/30.0)+1;
X              occurcount++;
X            }
X          }
X      }
X    }
X
X    /* After all the aspects, etc, in the day have been located, sort   */
X    /* them by time at which they occur, so we can print them in order. */
X
X    for (i = 1; i < occurcount; i++) {
X      j = i-1;
X      while (j >= 0 && time[j] > time[j+1]) {
X        SwapN(source[j], source[j+1]);
X        SwapN(aspect[j], aspect[j+1]);
X        SwapN(dest[j], dest[j+1]);
X        SwapR(&time[j], &time[j+1]);
X        SwapN(sign1[j], sign1[j+1]); SwapN(sign2[j], sign2[j+1]);
X        j--;
X      }
X    }
X
X    /* Finally, loop through and display each aspect and when it occurs. */
X
X    for (i = 0; i < occurcount; i++) {
X      s1 = (int)time[i]/60;
X      s2 = (int)time[i]-s1*60;
X      j = DayT;
X      if (fYear || fProg) {
X        l = MonT;
X        while (j > (k = DayInMonth(l, yea0))) {
X          j -= k;
X          l++;
X        }
X      }
X      SetCI(ciSave, fYear || fProg ? l : Mon, j, yea0,
X        DegToDec(time[i] / 60.0), Dst, Zon, Lon, Lat);
X      k = DayOfWeek(fYear || fProg ? l : Mon, j, yea0);
X      AnsiColor(kRainbowA[k + 1]);
X      sprintf(sz, "(%c%c%c) ", chDay3(k)); PrintSz(sz);
X      AnsiColor(kDefault);
X      sprintf(sz, "%s %s ",
X        SzDate(fYear || fProg ? l : Mon, j, yea0, fFalse),
X        SzTime(s1, s2)); PrintSz(sz);
X      PrintAspect(source[i], sign1[i],
X        (int)RSgn(cp1.dir[source[i]])+(int)RSgn(cp2.dir[source[i]]),
X        aspect[i], dest[i], sign2[i],
X        (int)RSgn(cp1.dir[dest[i]])+(int)RSgn(cp2.dir[dest[i]]),
X        (char)(fProg ? 'e' : 'd'));
X      PrintInDay(source[i], aspect[i], dest[i]);
X    }
X    counttotal += occurcount;
X  }
X  }
X  if (counttotal == 0)
X    PrintSz("No transit events found.\n");
X
X  /* Recompute original chart placements as we've overwritten them. */
X
X  ciCore = ciMain; ciTran = ciT;
X  CastChart(fTrue);
}
X
X
/* Search through a month, year, or years, and print out the times of exact */
/* transits where planets in the time frame make aspect to the planets in   */
/* some other chart, as specified with the -t switch. To do this, we cast   */
/* charts for the start and end of each month, or within a month, and do an */
/* equation check for aspects to the other base chart during the interval.  */
X
void ChartTransitSearch(fProg)
bool fProg;
{
X  real planet3[objMax], house3[cSign+1], ret3[objMax], time[MAXINDAY];
X  char sz[cchSzDef];
X  int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY], sign[MAXINDAY],
X    isret[MAXINDAY], M1, M2, Y1, Y2, counttotal = 0, occurcount, division,
X    div, nAsp, fCusp, i, j, k, s1, s2, s3;
X  real divsiz, daysiz, d, e1, e2, f1, f2;
X  CI ciT;
X
X  /* Save away natal chart and initialize things. */
X
X  ciT = ciTran;
X  for (i = 1; i <= cSign; i++)
X    house3[i] = chouse[i];
X  for (i = 0; i <= cObj; i++) {
X    planet3[i] = planet[i];
X    ret3[i] = ret[i];
X  }
X  if (fProg)
X    fCusp = fFalse;
X  else {
X    fCusp = fTrue;
X    for (i = cuspLo; i <= cuspHi; i++)
X      fCusp &= ignore2[i];
X  }
X  division = us.nDivision;
X  if (!fProg && !fCusp)
X    division = Max(division, 96);
X  nAsp = is.fReturn ? aCon : us.nAsp;
X
X  /* Hacks: Searching month number zero means to search the whole year    */
X  /* instead, month by month. Searching a negative month means to search  */
X  /* multiple years, with the span of the year stored in the "day" field. */
X
X  Y1 = Y2 = YeaT;
X  M1 = M2 = MonT;
X  if (MonT < 1) {
X    M1 = 1; M2 = 12;
X    if (MonT < 0) {
X      if (DayT < 1) {
X        Y1 = YeaT + DayT + 1; Y2 = YeaT;
X      } else {
X        Y1 = YeaT; Y2 = YeaT + DayT - 1;
X      }
X    }
X  }
X
X  /* Start searching the year or years in question for any transits. */
X
X  for (YeaT = Y1; YeaT <= Y2; YeaT++)
X
X  /* Start searching the month or months in question for any transits. */
X
X  for (MonT = M1; MonT <= M2; MonT++) {
X    daysiz = (real)DayInMonth(MonT, YeaT)*24.0*60.0;
X    divsiz = daysiz / (real)division;
X
X    /* Cast chart for beginning of month and store it for future use. */
X
X    SetCI(ciCore, MonT, 1, YeaT, 0.0, DstT, ZonT, LonT, LatT);
X    if (us.fProgress = fProg) {
X      is.JDp = MdytszToJulian(MM, DD, YY, 0.0, DstT, ZonT);
X      ciCore = ciMain;
X    }
X    for (i = 0; i <= oNorm; i++)
X      SwapN(ignore[i], ignore2[i]);
X    CastChart(fTrue);
X    for (i = 0; i <= oNorm; i++)
X      SwapN(ignore[i], ignore2[i]);
X    cp2 = cp0;
X
X    /* Divide our month into segments and then search each segment in turn. */
X
X    for (div = 1; div <= division; div++) {
X      occurcount = 0;
X
X      /* Cast the chart for the ending time of the present segment, and */
X      /* copy the start time chart from the previous end time chart.    */
X
X      d = 1.0 + (daysiz/24.0/60.0)*(real)div/(real)division;
X      SetCI(ciCore, MonT, (int)d, YeaT,
X        DegToDec(RFract(d)*24.0), DstT, ZonT, LonT, LatT);
X      if (fProg) {
X        is.JDp = MdytszToJulian(MM, DD, YY, 0.0, DstT, ZonT);
X        ciCore = ciMain;
X      }
X      for (i = 0; i <= oNorm; i++)
X        SwapN(ignore[i], ignore2[i]);
X      CastChart(fTrue);
X      for (i = 0; i <= oNorm; i++)
X        SwapN(ignore[i], ignore2[i]);
X      cp1 = cp2; cp2 = cp0;
X
X      /* Now search through the present segment for any transits. Note that */
X      /* stars can be transited, but they can't make transits themselves.   */
X
X      for (i = 0; i <= cObj; i++) if (!FIgnore(i)) {
X        for (j = 0; j <= oNorm; j++) {
X          if ((is.fReturn ? i != j : FIgnore2(j)) || (fCusp && !FThing(j)))
X            continue;
X
X          /* Between each pair of planets, check if they make any aspects. */
X
X          for (k = 1; k <= nAsp; k++) if (FAcceptAspect(i, k, j)) {
X            d = planet3[i]; e1 = cp1.obj[j]; e2 = cp2.obj[j];
X            if (MinDistance(e1, Mod(d-rAspAngle[k])) <
X                MinDistance(e2, Mod(d+rAspAngle[k]))) {
X              e1 = Mod(e1+rAspAngle[k]);
X              e2 = Mod(e2+rAspAngle[k]);
X            } else {
X              e1 = Mod(e1-rAspAngle[k]);
X              e2 = Mod(e2-rAspAngle[k]);
X            }
X
X            /* Check to see if the present aspect actually occurs during the */
X            /* segment, making sure we check any Aries point crossings.      */
X
X            f1 = e1-d;
X            if (RAbs(f1) > rDegHalf)
X              f1 -= RSgn(f1)*rDegMax;
X            f2 = e2-d;
X            if (RAbs(f2) > rDegHalf)
X              f2 -= RSgn(f2)*rDegMax;
X            if (MinDistance(d, Midpoint(e1, e2)) < rDegQuad &&
X              RSgn(f1) != RSgn(f2) && occurcount < MAXINDAY) {
X
X              /* Ok, we have found a transit. Now determine the time */
X              /* and save this transit in our list to be printed.    */
X
X              source[occurcount] = j;
X              aspect[occurcount] = k;
X              dest[occurcount] = i;
X              time[occurcount] = RAbs(f1)/(RAbs(f1)+RAbs(f2))*divsiz +
X                (real)(div-1)*divsiz;
X              sign[occurcount] = (int)(Mod(
X                MinDistance(cp1.obj[j], Mod(d-rAspAngle[k])) <
X                MinDistance(cp2.obj[j], Mod(d+rAspAngle[k])) ?
X                d-rAspAngle[k] : d+rAspAngle[k])/30.0)+1;
X              isret[occurcount] = (int)RSgn(cp1.dir[j]) +
X                (int)RSgn(cp2.dir[j]);
X              occurcount++;
X            }
X          }
X        }
X      }
X
X      /* After all transits located, sort them by time at which they occur. */
X
X      for (i = 1; i < occurcount; i++) {
X        j = i-1;
X        while (j >= 0 && time[j] > time[j+1]) {
X          SwapN(source[j], source[j+1]);
X          SwapN(aspect[j], aspect[j+1]);
X          SwapN(dest[j], dest[j+1]);
X          SwapR(&time[j], &time[j+1]);
X          SwapN(sign[j], sign[j+1]);
X          SwapN(isret[j], isret[j+1]);
X          j--;
X        }
X      }
X
X      /* Now loop through list and display all the transits. */
X
X      for (i = 0; i < occurcount; i++) {
X        s1 = (_int)time[i]/24/60;
X        s3 = (_int)time[i]-s1*24*60;
X        s2 = s3/60;
X        s3 = s3-s2*60;
X        SetCI(ciSave, MonT, s1+1, YeaT, DegToDec((real)
X          ((_int)time[i]-s1*24*60) / 60.0), DstT, ZonT, LonT, LatT);
X        sprintf(sz, "%s %s ",
X          SzDate(MonT, s1+1, YeaT, fFalse), SzTime(s2, s3)); PrintSz(sz);
X        PrintAspect(source[i], sign[i], isret[i], aspect[i],
X          dest[i], SFromZ(planet3[dest[i]]), (int)RSgn(ret3[dest[i]]),
X          (char)(fProg ? 'u' : 't'));
X
X        /* Check for a Solar, Lunar, or any other return. */
X
X        if (aspect[i] == aCon && source[i] == dest[i]) {
X          AnsiColor(kWhite);
X          sprintf(sz, " (%s Return)", source[i] == oSun ? "Solar" :
X            (source[i] == oMoo ? "Lunar" : szObjName[source[i]]));
X          PrintSz(sz);
X        }
X        PrintL();
#ifdef INTERPRET
X        if (us.fInterpret)
X          InterpretTransit(source[i], aspect[i], dest[i]);
#endif
X        AnsiColor(kDefault);
X      }
X      counttotal += occurcount;
X    }
X  }
X  if (counttotal == 0)
X    PrintSz("No transits found.\n");
X
X  /* Recompute original chart placements as we've overwritten them. */
X
X  ciCore = ciMain; ciTran = ciT;
X  us.fProgress = fFalse;
X  CastChart(fTrue);
}
X
X
/* Display a list of planetary rising times relative to the local horizon */
/* for the day indicated in the chart information, as specified with the  */
/* -Zd switch. For the day, the time each planet rises (transits horizon  */
/* in East half of sky), sets (transits horizon in West), reaches its     */
/* zenith point (transits meridian in South half of sky), and nadirs      */
/* transits meridian in North), is displayed.                             */
X
void ChartInDayHorizon()
{
X  char sz[cchSzDef];
X  int source[MAXINDAY], type[MAXINDAY], sign[MAXINDAY],
X    fRet[MAXINDAY], occurcount, division, div, s1, s2, i, j, fT;
X  real time[MAXINDAY], rgalt1[objMax], rgalt2[objMax], azialt[MAXINDAY],
X    azi1, azi2, alt1, alt2, lon, lat, mc1, mc2, xA, yA, xV, yV, d, k;
X  CI ciT;
X
X  fT = us.fSidereal; us.fSidereal = fFalse;
X  lon = RFromD(Mod(Lon)); lat = RFromD(Lat);
X  division = us.nDivision * 4;
X  occurcount = 0;
X
X  ciT = ciTwin; ciCore = ciMain; ciCore.tim = 0.0;
X  CastChart(fTrue);
X  mc2 = RFromD(planet[oMC]); k = RFromD(planetalt[oMC]);
X  EclToEqu(&mc2, &k);
X  cp2 = cp0;
X  for (i = 1; i <= cObj; i++) {
X    rgalt2[i] = planetalt[i];
X  }
X
X  /* Loop through the day, dividing it into a certain number of segments. */
X  /* For each segment we get the planet positions at its endpoints.       */
X
X  for (div = 1; div <= division; div++) {
X    ciCore = ciMain; ciCore.tim = DegToDec(24.0*(real)div/(real)division);
X    CastChart(fTrue);
X    mc1 = mc2;
X    mc2 = RFromD(planet[oMC]); k = RFromD(planetalt[oMC]);
X    EclToEqu(&mc2, &k);
X    cp1 = cp2; cp2 = cp0;
X    for (i = 1; i <= cObj; i++) {
X      rgalt1[i] = rgalt2[i]; rgalt2[i] = planetalt[i];
X    }
X
X    /* For our segment, check to see if each planet during it rises, sets, */
X    /* reaches its zenith, or reaches its nadir.                           */
X
X    for (i = 1; i <= cObj; i++) if (!ignore[i] && FThing(i)) {
X      EclToHorizon(&azi1, &alt1, cp1.obj[i], rgalt1[i], lon, lat, mc1);
X      EclToHorizon(&azi2, &alt2, cp2.obj[i], rgalt2[i], lon, lat, mc2);
X      j = 0;
X
X      /* Check for transits to the horizon. */
X      if ((alt1 > 0.0) != (alt2 > 0.0)) {
X        d = RAbs(alt1)/(RAbs(alt1)+RAbs(alt2));
X        k = Mod(azi1 + d*MinDifference(azi1, azi2));
X        j = 1 + 2*(MinDistance(k, rDegHalf) < rDegQuad);
X
X      /* Check for transits to the meridian. */
X      } else if (RSgn(MinDifference(azi1, rDegQuad)) !=
X        RSgn(MinDifference(azi2, rDegQuad))) {
X        j = 2 + 2*(MinDistance(azi1, rDegQuad) < rDegQuad);
X        d = RAbs(azi1 - (j > 2 ? rDegQuad : 270.0))/MinDistance(azi1, azi2);
X        k = alt1 + d*(alt2-alt1);
X      }
X      if (j && !ignorez[j-1] && occurcount < MAXINDAY) {
X        source[occurcount] = i;
X        type[occurcount] = j;
X        time[occurcount] = 24.0*((real)(div-1)+d)/(real)division*60.0;
X        sign[occurcount] = (int)Mod(cp1.obj[i] +
X          d*MinDifference(cp1.obj[i], cp2.obj[i]))/30 + 1;
X        fRet[occurcount] = (int)RSgn(cp1.dir[i]) + (int)RSgn(cp2.dir[i]);
X        azialt[occurcount] = k;
X        ciSave = ciMain;
X        ciSave.tim = DegToDec(time[occurcount] / 60.0);
X        occurcount++;
X      }
X    }
X  }
X
X  /* Sort each event in order of time when it happens during the day. */
X
X  for (i = 1; i < occurcount; i++) {
X    j = i-1;
X    while (j >= 0 && time[j] > time[j+1]) {
X      SwapN(source[j], source[j+1]);
X      SwapN(type[j], type[j+1]);
X      SwapR(&time[j], &time[j+1]);
X      SwapN(sign[j], sign[j+1]);
X      SwapN(fRet[j], fRet[j+1]);
X      SwapR(&azialt[j], &azialt[j+1]);
X      j--;
X    }
X  }
X
X  /* Finally display the list showing each event and when it occurs. */
X
X  for (i = 0; i < occurcount; i++) {
X    ciSave = ciMain;
X    ciSave.tim = DegToDec(time[i] / 60.0);
X    j = DayOfWeek(Mon, Day, Yea);
X    AnsiColor(kRainbowA[j + 1]);
X    sprintf(sz, "(%c%c%c) ", chDay3(j)); PrintSz(sz);
X    AnsiColor(kDefault);
X    s1 = (int)time[i]/60;
X    s2 = (int)time[i]-s1*60;
X    sprintf(sz, "%s %s ", SzDate(Mon, Day, Yea, fFalse), SzTime(s1, s2));
X    PrintSz(sz);
X    AnsiColor(kObjA[source[i]]);
X    sprintf(sz, "%7.7s ", szObjName[source[i]]); PrintSz(sz);
X    AnsiColor(kSignA(sign[i]));
X    sprintf(sz, "%c%c%c%c%c ",
X      fRet[i] > 0 ? '(' : (fRet[i] < 0 ? '[' : '<'), chSig3(sign[i]),
X      fRet[i] > 0 ? ')' : (fRet[i] < 0 ? ']' : '>')); PrintSz(sz);
X    AnsiColor(kElemA[type[i]-1]);
X    if (type[i] == 1)
X      PrintSz("rises  ");
X    else if (type[i] == 2)
X      PrintSz("zeniths");
X    else if (type[i] == 3)
X      PrintSz("sets   ");
X    else
X      PrintSz("nadirs ");
X    AnsiColor(kDefault);
X    PrintSz(" at ");
X    if (type[i] & 1) {
X      j = (int)(RFract(azialt[i])*60.0);
X      sprintf(sz, "%3d%c%02d'", (int)azialt[i], chDeg1, j); PrintSz(sz);
X
X      /* For rising and setting events, we'll also display a direction  */
X      /* vector to make the 360 degree azimuth value thought of easier. */
X
X      xA = RCosD(azialt[i]); yA = RSinD(azialt[i]);
X      if (RAbs(xA) < RAbs(yA)) {
X        xV = RAbs(xA / yA); yV = 1.0;
X      } else {
X        yV = RAbs(yA / xA); xV = 1.0;
X      }
X      sprintf(sz, " (%.2f%c %.2f%c)",
X        yV, yA < 0.0 ? 's' : 'n', xV, xA > 0.0 ? 'e' : 'w'); PrintSz(sz);
X    } else
X      PrintAltitude(azialt[i]);
X    PrintL();
X  }
X  if (occurcount == 0)
X    PrintSz("No horizon events found.\n");
X
X  /* Recompute original chart placements as we've overwritten them. */
X
X  ciCore = ciMain; ciTwin = ciT;
X  us.fSidereal = fT;
X  CastChart(fTrue);
}
X
X
/* Print out an ephemeris - the positions of the planets (at the time in the */
/* current chart) each day during a specified month, as done with the -E     */
/* switch. Display the ephemeris for the whole year if -Ey is in effect.     */
X
void ChartEphemeris()
{
X  char sz[cchSzDef];
X  int yea, yea1, yea2, mon, mon1, mon2, daysiz, i, j, s, d, m;
X
X  /* If -Ey is in effect, then loop through all months in the whole year. */
X
X  if (us.nEphemYears) {
X    yea1 = Yea; yea2 = yea1 + us.nEphemYears - 1; mon1 = 1; mon2 = 12;
X  } else {
X    yea1 = yea2 = Yea; mon1 = mon2 = Mon;
X  }
X
X  /* Loop through the year or years in question. */
X
X  for (yea = yea1; yea <= yea2; yea++)
X
X  /* Loop through the month or months in question, printing each ephemeris. */
X
X  for (mon = mon1; mon <= mon2; mon++) {
X    daysiz = DayInMonth(mon, yea);
X    PrintSz(us.fEuroDate ? "Dy/Mo/Yr" : "Mo/Dy/Yr");
X    for (j = 1; j <= cObj; j++) {
X      if (!ignore[j] && FThing(j)) {
X        sprintf(sz, "  %s%c%c%c%c", is.fSeconds ? "  " : "", chObj3(j),
X          szObjName[j][3] != 0 ? szObjName[j][3] : ' '); PrintSz(sz);
X        PrintTab(' ', us.fParallel ? 2 + is.fSeconds : 1 + 3*is.fSeconds);
X      }
X    }
X    PrintL();
X    for (i = 1; i <= daysiz; i = AddDay(mon, i, yea, 1)) {
X
X      /* Loop through each day in the month, casting a chart for that day. */
X
X      SetCI(ciCore, mon, i, yea, Tim, Dst, Zon, Lon, Lat);
X      CastChart(fTrue);
X      PrintSz(SzDate(mon, i, yea, -1));
X      PrintCh(' ');
X      for (j = 0; j <= cObj; j++)
X        if (!FIgnore(j) && FThing(j)) {
X          if (!us.fParallel) {
X            if (is.fSeconds)
X              PrintZodiac(planet[j]);
X            else {
X              AnsiColor(kObjA[j]);
X              s = SFromZ(planet[j]);
X              d = (int)planet[j] - (s-1)*30;
X              m = (int)(RFract(planet[j])*60.0);
X              sprintf(sz, "%2d%s%02d", d, szSignAbbrev[s], m); PrintSz(sz);
X            }
X          } else {
X            AnsiColor(kObjA[j]);
X            PrintAltitude(planetalt[j]);
X          }
X          PrintCh((char)(ret[j] >= 0.0 ? ' ' : '.'));
X        }
X      PrintL();
X      AnsiColor(kDefault);
X    }
X    if (mon < mon2 || yea < yea2)
X      PrintL();
X  }
X
X  ciCore = ciMain;    /* Recast original chart. */
X  CastChart(fTrue);
}
X
/* charts3.c */
SHAR_EOF
  $shar_touch -am 1223232998 'charts3.c' &&
  chmod 0644 'charts3.c' ||
  echo 'restore of charts3.c failed'
  shar_count="`wc -c < 'charts3.c'`"
  test 25364 -eq "$shar_count" ||
    echo "charts3.c: original size 25364, current size $shar_count"
fi
# ============= data.c ==============
if test -f 'data.c' && test X"$1" != X"-c"; then
  echo 'x - skipping data.c (File already exists)'
else
  echo 'x - extracting data.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'data.c' &&
/*
** Astrolog (Version 5.40) File: data.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
/*
******************************************************************************
** Global Variables.
******************************************************************************
*/
X
#ifdef __TURBOC__
extern unsigned _stklen = 0x4000;
#endif
X
US NPTR us = {
X
X  /* Chart types */
X  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X
X  /* Chart suboptions */
X  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X
X  /* Table chart types */
X  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X
X  /* Main flags */
X  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X
X  /* Main subflags */
#ifdef SWITCHES
X  fFalse,
#else
X  fTrue,
#endif
X  0, 0, 0, 0, 0, 0, 0,
X
X  /* Rare flags */
#ifdef TRUENODE
X  fTrue,
#else
X  fFalse,
#endif
X  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X
X  /* Value settings */
X  0,
X  0,
X  0,
X  DEFAULT_SYSTEM,
X  DEFAULT_ASPECTS,
X  oEar,
X  0,
X  1,
X  0,
X  0,
X  0,
X  DIVISIONS,
X  SCREENWIDTH,
X  0.0,
X  DEFAULT_ZONE,
X  DEFAULT_LONG,
X  DEFAULT_LAT,
X
X  /* Value subsettings */
X
X  4, 5, cPart, 0.0, 365.25, 1, 1, 24, 0L, 0, BIODAYS};
X
IS NPTR is = {
X  fFalse, fFalse, fFalse, fFalse, fFalse, fFalse, fFalse, fFalse,
X  NULL, NULL, NULL, NULL, 0, 0, 0, 0.0, 0.0, 0.0,
X  NULL, 0.0, 0.0, 0.0, 0.0, 0.0};
X
CI ciCore = {11, 19, 1971, 11.01, 0.0, 8.0, 122.20, 47.36, "", ""};
CI ciMain = {-1, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, "", ""};
CI ciTwin = {9, 11, 1991, 0.01, 0.0, 0.0, 122.20, 47.36, "", ""};
CI ciThre = {-1, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, "", ""};
CI ciFour = {-1, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, "", ""};
CI ciTran = {12, 31, 1999, 23.59, 0.0, 0.0, 0.0, 0.0, "", ""};
CI ciSave = {12, 21, 1998, 17.57, 0.0, 8.0, 122.20, 47.36, "", ""};
CP cp0, cp1, cp2;
X
X
/*
******************************************************************************
** Global Arrays.
******************************************************************************
*/
X
real spacex[oNorm+1], spacey[oNorm+1], spacez[oNorm+1], force[objMax];
GridInfo FPTR *grid = NULL;
int starname[cStar+1], kObjA[objMax];
char *szMacro[48];
X
/* Restriction status of each object, as specified with -R switch. */
X
byte ignore[objMax] = {0,
X  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                   /* Planets  */
X  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                   /* Minors   */
X  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,             /* Cusps    */
X  0, 0, 0, 0, 0, 0, 0, 0,                         /* Uranians */
X  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* Stars    */
X  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
X
/* Restriction of objects when transiting, as specified with -RT switch. */
X
byte ignore2[objMax] = {0,
X  0, 1, 0, 0, 0, 0, 0, 0, 0, 0,                   /* Planets  */
X  0, 0, 0, 0, 0, 0, 1, 1, 1, 1,                   /* Minors   */
X  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,             /* Cusps    */
X  0, 0, 0, 0, 0, 0, 0, 0,                         /* Uranians */
X  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* Stars    */
X  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
X
byte ignorez[4] = {0, 0, 0, 0};    /* Restrictions for -Zd chart events. */
X
/* Gauquelin sector plus zones, as specified with -Yl switch. */
X
byte pluszone[cSector+1] = {0,
X  1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1,
X  1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1};
X
X
/*
******************************************************************************
** Global Tables.
******************************************************************************
*/
X
CONST char *szAppName = szAppNameCore;
X
CONST char *szSignName[cSign+1] = {"",
X  "Aries", "Taurus", "Gemini", "Cancer", "Leo",
X  "Virgo", "Libra", "Scorpio",
X  "Sagittarius", "Capricorn", "Aquarius", "Pisces"};
X
CONST char *szSignAbbrev[cSign+1] = {"",
X  "Ar", "Ta", "Ge", "Cn", "Le", "Vi", "Li", "Sc", "Sg", "Cp", "Aq", "Pi"};
X
CONST char * ARR szSignEnglish[cSign+1] = {"",
X  "Ram", "Bull", "Twins", "Crab", "Lion", "Virgin",
X  "Scales", "Scorpion", "Archer", "Sea Goat", "Water Bearer", "Fishes"};
X
CONST char * ARR szHouseTradition[cSign+1] = {"",
X  "Personality", "Money", "Communication", "Home",
X  "Children", "Servants", "Marriage", "Death",
X  "Long Journeys Over Water", "Career", "Friends", "Troubles"};
X
CONST char * ARR szObjName[objMax] = {
X  "Earth", "Sun", "Moon", "Mercury", "Venus", "Mars",       /* Planets   */
X  "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto",
X  "Chiron", "Ceres", "Pallas", "Juno", "Vesta",             /* Asteroids */
X  "Node", "Lilith", "Fortune", "Vertex", "East Point",      /* Others    */
X  "Ascendant", "2nd Cusp", "3rd Cusp", "Nadir",             /* Cusps     */
X  "5th Cusp", "6th Cusp", "Descendant", "8th Cusp",
X  "9th Cusp", "Midheaven", "11th Cusp", "12th Cusp",
X  "Cupido", "Hades", "Zeus", "Kronos",                      /* Uranians  */
X  "Apollon", "Admetos", "Vulkanus", "Poseidon",
X
X  "Achernar", "Polaris", "Zeta Retic.", "Pleiades",         /* Stars     */
X  "Aldebaran", "Capella", "Rigel", "Bellatrix", "Alnath",
X  "Orion", "Betelgeuse", "Menkalinan", "Murzim", "Canopus",
X  "Alhena", "Sirius", "Adara", "Wezen", "Castor",
X  "Procyon", "Pollux", "Suhail", "Avior", "Miaplacidus",
X  "Alphard", "Regulus", "Dubhe", "Acrux", "Gacrux",
X  "Becrux", "Alioth", "Spica", "Alkaid", "Agena",
X  "Arcturus", "Rigel Kent.", "Antares", "Shaula", "Sargas",
X  "Kaus Austr.", "Vega", "Altair", "Peacock", "Deneb",
X  "Alnair", "Fomalhaut", "Andromeda"};
X
CONST char * ARR szSystem[cSystem] = {
X  "Placidus", "Koch", "Equal", "Campanus", "Meridian",
X  "Regiomontanus", "Porphyry", "Morinus", "Topocentric", "Alcabitius",
X  "Equal (MC)", "Neo-Porphyry", "Whole", "Vedic", "Null"};
X
CONST char * ARR szAspectName[cAspect+1] = {"",
X  "Conjunct", "Opposite", "Square", "Trine", "Sextile",
X  "Inconjunct", "Semisextile", "Semisquare", "Sesquiquadrate",
X  "Quintile", "Biquintile",
X  "Semiquintile", "Septile", "Novile",
X  "Binovile", "Biseptile", "Triseptile", "Quatronovile"};
X
char * ARR szAspectAbbrev[cAspect+1] = {"",
X  "Con", "Opp", "Squ", "Tri", "Sex",
X  "Inc", "SSx", "SSq", "Ses", "Qui", "BQn",
X  "SQn", "Sep", "Nov", "BNv", "BSp", "TSp", "QNv"};
X
CONST char * ARR szAspectGlyph[cAspect+1] = {"",
X  "Circle with extending line", "Two circles joined by line",
X  "Quadrilateral", "Triangle", "Six pointed asterisk",
X  "'K' rotated right", "'K' rotated left", "Acute angle",
X  "Square with extending lines", "Letter 'Q'", "'+' over '-'",
X  "'-' over '+'", "Number '7'", "Number '9'", "'9' under Roman 'II'",
X  "'7' under Roman 'II'", "'7' under Roman 'III'", "'9' under Roman 'IV'"};
X
CONST char *szAspectConfig[cAspConfig+1] = {"",
X  "Stellium", "Grand Trine", "T-Square", "Yod", "Grand Cross", "Cradle"};
X
CONST char *szElem[4] = {"Fire", "Earth", "Air", "Water"};
X
CONST char *szMode[3] = {"Cardinal", "Fixed", "Mutuable"};
X
CONST char *szMonth[cSign+1] = {"",
X  "January", "February", "March", "April", "May", "June",
X  "July", "August", "September", "October", "November", "December"};
X
CONST char *szDay[cWeek] = {"Sunday", "Monday", "Tuesday", "Wednesday",
X  "Thursday", "Friday", "Saturday"};
X
CONST char * ARR szZon[cZone] = {
X  "HST", "HT", "H", "CAT", "AHS", "HDT", "AHD", "YST", "YT", "Y", "YDT",
X  "PST", "PT", "P", "PDT", "PWT", "MST", "MT", "M", "MDT", "MWT",
X  "CST", "CT", "C", "CDT", "CWT", "EST", "ET", "E", "EDT", "EWT",
X  "AST", "AT", "A", "ADT", "AWT", "BST", "BT", "B", "BDT", "WAT",
X  "GMT", "GT", "G", "WET", "CET", "EET", "UZ3", "UZ4",
X  "IST", "IT", "I", "UZ5", "NST", "SST", "CCT", "JST", "JT", "J",
X  "SAS", "GST", "UZ1", "NZT", "ZT", "Z", "IDL", "LMT", "LT", "L"};
X
CONST real ARR rZon[cZone] = {
X  10.30, 10.30, 10.30, 10.0, 10.0, 9.30, 9.0, 9.0, 9.0, 9.0, 8.0,
X  8.0, 8.0, 8.0, 7.0, 7.0, 7.0, 7.0, 7.0, 6.0, 6.0,
X  6.0, 6.0, 6.0, 5.0, 5.0, 5.0, 5.0, 5.0, 4.0, 4.0,
X  4.0, 4.0, 4.0, 3.0, 3.0, 3.0, 3.0, 3.0, 2.0, 1.0,
X  0.0, 0.0, 0.0, 0.0, -1.0, -2.0, -4.0, -5.0,
X  -5.30, -5.30, -5.30, -6.0, -6.30, -7.0, -8.0, -9.0, -9.0, -9.0,
X  -9.30, -10.0, -11.0, -11.30, -11.30, -11.30, -12.0, 24.0, 24.0, 24.0};
X
CONST char *szDir[4] = {"North", "East", "South", "West"};
X
CONST char *szSuffix[cSign+1] = {"",
X  "st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th", "th", "th"};
X
real rAspAngle[cAspect+1] = {0,
X  0.0, 180.0, 90.0, 120.0, 60.0, 150.0, 30.0, 45.0, 135.0, 72.0, 144.0,
X  36.0, rDegMax/7.0, 40.0, 80.0, 720.0/7.0, 1080.0/7.0, 160.0};
X
real rAspOrb[cAspect+1] = {0,
X  7.0, 7.0, 7.0, 7.0, 6.0, 3.0, 3.0, 3.0, 3.0, 2.0, 2.0,
X  1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
X
real rObjOrb[oNorm+1] = {360.0,
X  360.0, 360.0, 360.0, 360.0, 360.0, 360.0, 360.0, 360.0, 360.0, 360.0,
X  360.0, 360.0, 360.0, 360.0, 360.0, 2.0, 2.0, 360.0, 360.0, 2.0,
X  360.0, 360.0, 360.0, 360.0, 360.0, 360.0,
X  360.0, 360.0, 360.0, 360.0, 360.0, 360.0,
X  360.0, 360.0, 360.0, 360.0, 360.0, 360.0, 360.0, 360.0};
X
real rObjAdd[oNorm+1] = {0.0,
X  1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
X  0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
X  0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
X  0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
X
int ruler1[oNorm+1] = {0,
X   5,  4,  3,  7,  1,  9, 10, 11, 12,  8,
X  12,  2,  6,  7,  8, 11,  8, 12,  7,  1,
X   1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,
X   7,  8,  5, 10,  9,  6,  1,  9};
int ruler2[oNorm+1] = {0,
X   0,  0,  6,  2,  8, 12, 11,  0,  0,  0,
X   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
X   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
X   0,  0,  0,  0,  0,  0,  0,  0};
int exalt[oNorm+1] = {0,
X   1,  2, 11, 12, 10,  4,  7,  8,  9,  6,
X   4,  4, 10,  5, 11,  6, 12,  9, 12, 10,
X   5,  6,  7,  8,  9, 10, 11, 12,  1,  2,  3,  4,
X   3,  6,  1,  9, 11,  8,  5, 12};
X
X  /* This array is the reverse of the ruler arrays:   */
X  /* Here, given a sign, return what planet rules it. */
int rules[cSign+1] = {0,
X  5, 4, 3, 2, 1, 3, 4, 10, 6, 7, 8, 9};
X
CONST char * ARR szColor[cColor] = {"Black",
X  "Maroon", "DkGreen", "Orange", "DkBlue", "Purple", "DkCyan", "LtGray",
X  "Gray", "Red", "Green", "Yellow", "Blue", "Magenta", "Cyan", "White"};
int kMainA[9] = {kBlack, kWhite, kLtGray, kDkGray,
X  kMaroon, kDkGreen, kDkCyan, kDkBlue, kMagenta};
int kRainbowA[8] = {kWhite,
X  kRed, kOrange, kYellow, kGreen, kCyan, kBlue, kPurple};
int kElemA[4] = {kRed, kYellow, kGreen, kBlue};
int kAspA[cAspect+1] = {kWhite,
X  kYellow, kBlue, kRed, kGreen, kCyan,
X  kMagenta, kMagenta, kOrange, kOrange, kDkCyan, kDkCyan,
X  kDkCyan, kMaroon, kPurple, kPurple, kMaroon, kMaroon, kPurple};
X
/* Influence information used by ChartInfluence() follows. The influence of */
/* a planet in its ruling or exalting sign or house is tacked onto the last */
/* two positions of the object and house influence array, respectively.     */
X
X  /* The inherent strength of each planet - */
real rObjInf[oNorm+3] = {0,
X  30, 25, 10, 10, 10, 10, 10, 10, 10, 10,
X  5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
X  20, 10, 10, 10, 10, 10, 10, 10, 10, 15, 10, 10,
X  3, 3, 3, 3, 3, 3, 3, 3,
X  20, 10};
X
X  /* The inherent strength of each house - */
real rHouseInf[cSign+3]  = {0,
X  20, 0, 0, 10, 0, 0, 5, 0, 0, 15, 0, 0,
X  15, 5};
X
X  /* The inherent strength of each aspect - */
real rAspInf[cAspect+1] = {0.0,
X  1.0, 0.8, 0.8, 0.6, 0.6, 0.4, 0.4, 0.2, 0.2,
X  0.2, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1};
X
X  /* The inherent strength of each planet when transiting - */
real rTransitInf[oNorm+3] = {0,
X  10, 4, 8, 9, 20, 30, 35, 40, 45, 50,
X  30, 15, 15, 15, 15, 30,
X  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
X  50, 50, 50, 50, 50, 50, 50, 50};
X
CONST real rObjDist[oVes+1] = {149.59787, 0.0, 0.3844,
X  57.91, 108.2, 227.94, 778.33, 1426.98, 2870.99, 4497.07, 5913.52,
X  13.670*149.59787, 2.767*149.59787, 2.770*149.59787, 2.669*149.59787,
X  2.361*149.59787};
CONST real rObjYear[oVes+1] = {1, 0, 27.32166/365.25,
X  87.969/365.25, 224.701/365.25, 686.98/365.25, 11.8623,
X  29.458, 84.01, 164.79, 248.54,
X  51.0, 4.60, 4.61, 4.36, 3.63};
CONST real rObjDiam[oVes+1] = {12756.0, 1392000.0, 3476.0,
X  4878.0, 12102.0, 6786.0, 142984.0, 120536.0, 51118.0, 49528.0, 2300.0,
X  320.0, 955.0, 538.0, 226.0, 503.0};
CONST real rObjDay[oPlu+1] = {24.0, 30.0*24.0, 27.322*24.0,
X  58.65*24.0, 243.01*24.0, 24.6229, 9.841, 10.233, 17.9, 19.2, 6.3872*24.0};
CONST real rObjMass[oPlu+1] = {1.0, 322946.0, 0.0123,
X  0.0553, 0.8149, 0.1074, 317.938, 95.181, 14.531, 17.135, 0.0022};
CONST real rObjAxis[oPlu+1] = {23.5, 0.0, 6.7,
X  2.0, 2.7, 25.19, 3.12, 26.73, 82.14, 29.6, 57.54};
CONST byte cSatellite[oPlu+1] = {1, 9, 0,
X  0, 0, 2, 16, 18, 15, 8, 1};
X
#ifdef ARABIC
CONST AI ai[cPart] = {
X  {"    02 01F ", "Fortune"},
X  {"    01 02F ", "Spirit"},
X  {"    06 S F ", "Victory"},
X  {"    F  05F ", "Valor & Bravery"},
X  {"    05 03Fh", "Mind & Administrators"},
X  {"   h02r02Fh", "Property & Goods"},
X  {"    06 07 h", "Siblings"},
X  {"   j03 01Fh", "Death of Siblings"},
X  {"    06 07Fh", "Death of Parents"},
X  {"    07h02Fh", "Grandparents"},
X  {"    06 03Fh", "Real Estate"},
X  {"    07 06Fh", "Children & Life"},
X  {"   R02 02 h", "Expected Birth"},
X  {"    05 03 h", "Disease & Defects (1)"},
X  {"    05 07 h", "Disease & Defects (2)"},
X  {"   R07 07 h", "Captivity"},
X  {"    02 03 h", "Servants"},
X  {"   h07 04 h", "Partners"},
X  {"   h08 02 h", "Death"},
X  {"    05 07Fh", "Sickness & Murder"},
X  {"    03 07Fh", "Danger, Violence & Debt"},
X  {"   h09r09 h", "Journeys"},
X  {"   105 07Fh", "Travel by Water"},
X  {"    03 02Fh", "Faith, Trust & Belief"},
X  {"    02 07Fh", "Deep Reflection"},
X  {"    01 07Fh", "Understanding & Wisdom"},
X  {"    06 01Fh", "Fame & Recognition"},
X  {"    02 05Fh", "Rulers & Disassociation"},
X  {"    07 01Fh", "Father, Fate & Karma"}, /* Combust */
X  {"    F  07Fh", "Sudden Advancement"},
X  {"    01 07 h", "Celebrity of Rank"},
X  {"    07 05Fh", "Surgery & Accident"},
X  {"    04 03Fh", "Merchants & Their Work"},
X  {"    F  S Fh", "Merchandise (Exchange)"}, /* Moon */
X  {"    02 04Fh", "Mother"},
X  {"    S  F Fh", "Glory & Constancy"},
X  {"    01 F Fh", "Honorable Acquaintances"},
X  {"    06 F Fh", "Success"},
X  {"    04 F Fh", "Worldliness"},
X  {"    03 02 h", "Acquaintances"},
X  {"    03 S  h", "Violence"},
X  {"    01 03Fh", "Liberty of Person"},
X  {"    04 06Fh", "Praise & Acceptance"},
X  {"   h12r12 h", "Enmity"},
X  {"    F  S  h", "Bad Luck"},
X  {"    05 F F ", "Debilitated Bodies"},
X  {"    02D  F ", "Boldness & Violence"},
X  {"    S  03F ", "Trickery & Deceit"},
X  {"   h03 05  ", "Necessities"},
X  {"    03 F   ", "Realization of Needs"},
X  {"    01 05F ", "Retribution"},
X  {"    06 02  ", "Children (Male)"},
X  {"    04 02  ", "Children (Female)"},
X  {"    05 04  ", "Play & Variety"}, /* Change */
X  {"    07 03 h", "Stability"},
X  {"   h05 06Fh", "Speculation"},
X  {"    03 04Fh", "Art"},
X  {"   h05r05 h", "Sexual Attraction"},
X  {"    10 04 h", "Sex Drive & Stimulation"},
X  {"    05 01 h", "Passion"},
X  {"    05 04 h", "Emotion & Affection"},
X  {"   r08 07 h", "Most Perilous Year"},
X  {"   h08 07 h", "Peril"},
X  {"    09 08 h", "Occultism"},
X  {"    03 01 h", "Commerce"},
X  {"h09h03 04 h", "Marriage Contracts"},
X  {"   h09r09 h", "Travel by Land"},
X  {"    08H08 h", "Travel by Air"},
X  {" 30 01 02Fh", "Destiny"},
X  {" 30 02 01Fh", "Vocation & Status"},
X  {"   019 01 h", "Honor, Nobility (Day)"},
X  {"   033 02 h", "Honor, Nobility (Night)"},
X  {"    10 01 h", "Organization"},
X  {"    04h07 h", "Divorce"},
X  {"    08 01 h", "Ostracism & Loss"},
X  {"    02 08Fh", "Friends"},
X  {"    07 01 h", "Tragedy & Brethren"},
X  {"    02 10Fh", "Race (Consciousness)"},
X  {"    02D02Fh", "Bondage & Slavery"},
X  {"    F  09 h", "Imprisonment & Sorrow"},
X  {"    04 08 h", "Perversion"},
X  {"   h12 09 h", "Self-Undoing"},
X  {"    09 01 h", "Treachery & Entrapment"},
X  {"h12r12 09 h", "Bereavement"},
X  {"    06h12 h", "Suicide (Yang)"},
X  {"   h08 09 h", "Suicide (Yin)"},
X  {"    06 09 h", "Depression"},
X  {" 05 09 08 h", "Assassination (Yang)"},
X  {"   r12 09 h", "Assassination (Yin)"},
X  {"    09 06  ", "Cancer (Disease)"},
X  {"    08 07  ", "Catastrophe"},
X  {"    07 08  ", "Foolhardiness"},
X  {"    03 05  ", "Release & Luck"},
X  {"    06 03  ", "Benevolence & Assurance"},
X  {"    03 06  ", "Hope & Sensitivity"},
X  {"    03 07  ", "Aptness & Aloofness"},
X  {"    08 09  ", "Charm & Personality"},
X  {"    02 03F ", "Faith & Good Manners"},
X  {"    01 03  ", "Temperament"},
X  {"    04 03  ", "Security & Treasure"},
X  {"    08 03  ", "Originality"},
X  {"    03 08  ", "Eccentricity, Astrology"},
X  {"    09 03  ", "Divination"},
X  {"    03 09  ", "Intrusion"},
X  {"    05 06  ", "Negotiation"},
X  {"    06 05  ", "Discord & Controversy"},
X  {"    05 08  ", "Coincidence"},
X  {"    08 05  ", "Unpreparedness"},
X  {"    05 09  ", "Popularity"},
X  {"    09 05  ", "Misunderstanding"},
X  {"    04 06  ", "Sentiment & Marriage"},
X  {"    06 04  ", "Loneliness"},
X  {"    04 07  ", "Success in Investment"},
X  {"    07 04  ", "Frugality & Labor"},
X  {"    08 04  ", "Wastefulness"},
X  {"    04 09  ", "Vanity"},
X  {"    09 04  ", "Corruptness"},
X  {"    01 05  ", "Initiative"},
X  {"    05 02F ", "Memory"},
X  {"    04 01  ", "Love, Beauty & Peace"},
X  {"    01 04  ", "Disinterest & Boredom"},
X  {"    01 06  ", "Accomplishment"},
X  {"    07 02F ", "Influence"},
X  {"    06 01  ", "Increase & Impression"},
X  {"    09 07  ", "Caution"},
X  {"    07 09  ", "Timidity"},
X  {"    08 06  ", "Entertainment"},
X  {"    06 08  ", "Bequest"},
X  {"    01 09  ", "Genius"},
X  {"    02 09F ", "Revelation"},
X  {"    09 02F ", "Delusion"},
X  {"    08 02F ", "Misinterpretation"},
X  {"    01 08  ", "Intellectuality"},
X  {"    06 07 E", "Earth"},
X  {"    04 02 E", "Water"},
X  {"   r04 03 E", "Air & Wind"},
X  {"    05 01 E", "Fire"},
X  {"    07 05FE", "Clouds"},
X  {"    04 02FE", "Rains"},
X  {"    07 03FE", "Cold"},
X  {"    06 01FC", "Wheat"},
X  {"    06 02FC", "Barley & Meats"},
X  {"    04 06FC", "Rice & Millet"},
X  {"    07 06FC", "Corn"},
X  {"    07 05FC", "Lentils, Iron, Pungents"},
X  {"    05 07FC", "Beans & Onions"},
X  {"    01 03FC", "Chick Peas"},
X  {"    04 07FC", "Sesame & Grapes"},
X  {"    03 04FC", "Sugar & Legumes"},
X  {"    01 02FC", "Honey"},
X  {"    02 05FC", "Oils"},
X  {"    04 05FC", "Nuts & Flax"},
X  {"    02 03FC", "Olives"},
X  {"    05 07FC", "Apricots & Peaches"},
X  {"    03 06FC", "Melons"},
X  {"    05 02FC", "Salt"},
X  {"    03 01FC", "Sweets"},
X  {"    07 03FC", "Astrigents & Purgatives"},
X  {"    04 03FC", "Silk & Cotton"},
X  {"    05 07FC", "Purgatives (Bitter)"},
X  {"    06 07FC", "Purgatives (Acid)"},
X  {"    30D   H", "Secrets"},
X  {"    02 03FH", "Information True/False"},
X  {"    F D  FH", "Injury to Business"},
X  {" 03 07 06 H", "Freedmen & Servants"},
X  {" 02 07 06 H", "Employers"},
X  {"   h07 04 H", "Marriage"},
X  {"    06 01 H", "Time for Action/Success"},
X  {"    07 01 H", "Time Occupied in Action"},
X  {" 07 06 01 H", "Dismissal & Resignation"},
X  {"    05 02 H", "Life/Death of Absentee"},
X  {"    05 01 H", "Lost Animal (Light)"},
X  {"    05 07 H", "Lost Animal (Dark)"},
X  {"    03 05 H", "Lawsuit"},
X  {"h08 05 02 H", "Decapitation"},
X  {" 30 07 02 H", "Torture"},
X  {" 02h04D   H", "Lost Objects"}
};
#endif /* ARABIC */
X
/* data.c */
SHAR_EOF
  $shar_touch -am 1223232998 'data.c' &&
  chmod 0644 'data.c' ||
  echo 'restore of data.c failed'
  shar_count="`wc -c < 'data.c'`"
  test 20770 -eq "$shar_count" ||
    echo "data.c: original size 20770, current size $shar_count"
fi
# ============= data2.c ==============
if test -f 'data2.c' && test X"$1" != X"-c"; then
  echo 'x - skipping data2.c (File already exists)'
else
  echo 'x - extracting data2.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'data2.c' &&
/*
** Astrolog (Version 5.40) File: data2.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
/*
******************************************************************************
** Constellation Tables.
******************************************************************************
*/
X
#ifdef CONSTEL
CONST char * ARR szCnstlName[cCnstl+1] = {"",
X  "Andromeda", "Antilia", "Apus", "Aquarius",
X  "Aquila", "Ara", "Aries", "Auriga",
X  "Bootes", "Caelum", "Camelopardalis", "Cancer",
X  "Canes Venatici", "Canis Major", "Canis Minor", "Capricornus",
X  "Carina", "Cassiopeia", "Centaurus", "Cepheus",
X  "Cetus", "Chamaeleon", "Circinus", "Columba",
X  "Coma Berenices", "Corona Australis", "Corona Borealis", "Corvus",
X  "Crater", "Crux", "Cygnus", "Delphinus",
X  "Dorado", "Draco", "Equuleus", "Eridanus",
X  "Fornax", "Gemini", "Grus", "Hercules",
X  "Horologium", "Hydra", "Hydrus", "Indus",
X  "Lacerta", "Leo", "Leo Minor", "Lepus",
X  "Libra", "Lupus", "Lynx", "Lyra",
X  "Mensa", "Microscopium", "Monoceros", "Musca",
X  "Norma", "Octans", "Ophiuchus", "Orion",
X  "Pavo", "Pegasus", "Perseus", "Phoenix",
X  "Pictor", "Pisces", "Piscis Austrinus", "Puppis",
X  "Pyxis", "Reticulum", "Sagitta", "Sagittarius",
X  "Scorpius", "Sculptor", "Scutum", "Serpens Caput/Cauda",
X  "Sextans", "Taurus", "Telescopium", "Triangulum",
X  "Triangulum Australe", "Tucana", "Ursa Major", "Ursa Minor",
X  "Vela", "Virgo", "Volans", "Vulpecula"};
X
CONST char * ARR szCnstlAbbrev[cCnstl+1] = {"",
X  "And", "Ant", "Aps", "Aqu", "Aql", "Ara", "Ari", "Aur",
X  "Boo", "Cae", "Cam", "Cnc", "CVn", "CMa", "CMi", "Cap",
X  "Car", "Cas", "Cen", "Cep", "Cet", "Cha", "Cir", "Col",
X  "Com", "CrA", "CrB", "Crv", "Crt", "Cru", "Cyg", "Del",
X  "Dor", "Dra", "Equ", "Eri", "For", "Gem", "Gru", "Her",
X  "Hor", "Hya", "Hyi", "Ind", "Lac", "Leo", "LMi", "Lep",
X  "Lib", "Lup", "Lyn", "Lyr", "Men", "Mic", "Mon", "Mus",
X  "Nor", "Oct", "Oph", "Ori", "Pav", "Peg", "Per", "Phe",
X  "Pic", "Psc", "PsA", "Pup", "Pyx", "Ret", "Sge", "Sgr",
X  "Sco", "Scl", "Sct", "Ser", "Sex", "Tau", "Tel", "Tri",
X  "TrA", "Tuc", "UMa", "UMi", "Vel", "Vir", "Vol", "Vul"};
X
CONST char * ARR szCnstlMeaning[cCnstl+1] = {"",
X  "Chained Maiden", "Air Pump", "Bird of Paradise", "Water Bearer",
X  "Eagle", "Altar", "Ram", "Charioteer",
X  "Herdsman", "Chisel", "Giraffe", "Crab",
X  "Hunting Dogs", "Great Dog", "Little Dog", "Sea Goat",
X  "Keel", "Queen", "Centaur", "King",
X  "Sea Monster", "Chameleon", "Drawing Compass", "Dove",
X  " Berenice's Hair", "Southern Crown", "Northern Crown", "Crow",
X  "Cup", "Southern Cross", "Swan", "Dolphin",
X  "Dolphinfish", "Dragon", "Little Horse", "River",
X  "Furnace", "Twins", "Crane", "Strongman",
X  "Clock", "Sea Serpent", "Water Snake", "Indian",
X  "Lizard", "Lion", "Little Lion", "Hare",
X  "Scales", "Wolf", "Lynx", "Lyre",
X  "Table Mountain", "Microscope", "Unicorn", "Fly",
X  "Level", "Octant", "Serpent Bearer", "Hunter",
X  "Peacock", "Winged Horse", "Hero", "Phoenix",
X  "Painter", "Fishes", "Southern Fish", "Stern",
X  "Compass", "Net", "Arrow", "Archer",
X  "Scorpion", "Sculptor", "Shield", " Head/Tail of the Snake",
X  "Sextant", "Bull", "Telescope", "Triangle",
X  "Southern Triangle", "Toucan", "Great Bear", "Little Bear",
X  "Sail", "Virgin", "Flying Fish", "Fox"};
X
CONST char * ARR szCnstlGenitive[cCnstl+1] = {"",
X  "", "", "2odis", "", "", "", "1tis", "",
X  "2is", "", "", "2ri", "2um1orum", " is", " is", "",
X  "", "", "", "", "", "tis", "", "",
X  "", "", "", "", "is", "", "", "",
X  "1us", "nis", "", "", "", "1orum", "1is", "2is",
X  "", "", "", "", "", "nis", "nis0is", "2oris",
X  "", "", "", "", "", "", "1tis", "",
X  "", "1is", "", "is", "nis", "", "", "",
X  "is", "2ium", "", "", "1dis", "", "", "",
X  "", "is", "", "!1is", "1tis", "", "", "",
X  "2i1is", "", " is", " is", "1orum", "1inis", "1tis", ""};
#endif /* CONSTEL */
X
X
/*
******************************************************************************
** Object Calculation Tables.
******************************************************************************
*/
X
#ifdef MATRIX
CONST byte rErrorCount[oPlu-oJup+1] = {11, 5, 4, 4, 4};
CONST byte rErrorOffset[oPlu-oJup+1] = {0, 72, 72+51, 72+51+42, 72+51+42+42};
X
CONST real ARR rErrorData[72+51+42*3] = {
-.001,-.0005,.0045,.0051,581.7,-9.7,-.0005,2510.7,-12.5,-.0026,1313.7,-61.4,
0.0013,2370.79,-24.6,-.0013,3599.3,37.7,-.001,2574.7,31.4,-.00096,6708.2,
-114.5,-.0006,5499.4,-74.97,-.0013,1419,54.2,.0006,6339.3,-109,.0007,4824.5,
-50.9,.0020,-.0134,.0127,-.0023,676.2,.9,.00045,2361.4,174.9,.0015,1427.5,
-188.8,.0006,2110.1,153.6,.0014,3606.8,-57.7,-.0017,2540.2,121.7,-.00099,
6704.8,-22.3,-.0006,5480.2,24.5,.00096,1651.3,-118.3,.0006,6310.8,-4.8,.0007,
4826.6,36.2, /* Jupiter error */
X
-.0009,.0037,0,.0134,1238.9,-16.4,-.00426,3040.9,-25.2,.0064,1835.3,36.1,
-.0153,610.8,-44.2,-.0015,2480.5,-69.4,-.0014,.0026,0,.0111,1242.2,78.3,
-.0045,3034.96,62.8,-.0066,1829.2,-51.5,-.0078,640.6,24.2,-.0016,2363.4,
-141.4,.0006,-.0002,0,-.0005,1251.1,43.7,.0005,622.8,13.7,.0003,1824.7,-71.1,
X.0001,2997.1,78.2, /* Saturn error */
X
-.0021,-.0159,0,.0299,422.3,-17.7,-.0049,3035.1,-31.3,-.0038,945.3,60.1,
-.0023,1227,-4.99,.0134,-.02186,0,.0317,404.3,81.9,-.00495,3037.9,57.3,.004,
993.5,-54.4,-.0018,1249.4,79.2,-.0003,.0005,0,.0005,352.5,-54.99,.0001,3027.5,
54.2,-.0001,1150.3,-88, /* Uranus error */
X
0.1832,-.6718,.2726,-.1923,175.7,31.8,.0122,542.1,189.6,.0027,1219.4,178.1,
-.00496,3035.6,-31.3,-.1122,.166,-.0544,-.00496,3035.3,58.7,.0961,177.1,-68.8,
-.0073,630.9,51,-.0025,1236.6,78,.00196,-.0119,.0111,.0001,3049.3,44.2,-.0002,
893.9,48.5,.00007,1416.5,-25.2, /* Neptune error */
X
-.0426,.073,-.029,.0371,372,-331.3,-.0049,3049.6,-39.2,-.0108,566.2,318.3,
0.0003,1746.5,-238.3,-.0603,.5002,-.6126,.049,273.97,89.97,-.0049,3030.6,61.3,
0.0027,1075.3,-28.1,-.0007,1402.3,20.3,.0145,-.0928,.1195,.0117,302.6,-77.3,
0.00198,528.1,48.6,-.0002,1000.4,-46.1 /* Pluto error */
};
X
OE ARR rgoe[oVes-1+cUran] = {
{358.4758,35999.0498,-.0002,.01675,-.4E-4,0,1,101.2208,1.7192,.00045,0,0,0,0,
0,0}, /* Earth/Sun */
{102.2794,149472.515,0,.205614,.2E-4,0,.3871,28.7538,.3703,.0001,47.1459,
1.1852,0.0002,7.009,.00186,0}, /* Mercury */
{212.6032,58517.8039,.0013,.00682,-.5E-4,0,.7233,54.3842,.5082,-.14E-2,
75.7796,0.8999,.4E-3,3.3936,.1E-2,0}, /* Venus */
{319.5294,19139.8585,.2E-3,.09331,.9E-4,0,1.5237,285.4318,1.0698,.1E-3,
48.7864,0.77099,0,1.8503,-.7E-3,0}, /* Mars */
X
{225.4928,3033.6879,0,.04838,-.2E-4,0,5.2029,273.393,1.3383,0,99.4198,1.0583,
0,1.3097,-.52E-2,0}, /* Jupiter */
{174.2153,1223.50796,0,.05423,-.2E-3,0,9.5525,338.9117,-.3167,0,112.8261,
X.8259,0,2.4908,-.0047,0}, /* Saturn */
{74.1757,427.2742,0,.04682,.00042,0,19.2215,95.6863,2.0508,0,73.5222,.5242,0,
0.7726,.1E-3,0}, /* Uranus */
{30.13294,240.45516,0,.00913,-.00127,0,30.11375,284.1683,-21.6329,0,130.68415,
1.1005,0,1.7794,-.0098,0}, /* Neptune */
{229.781,145.1781,0,.24797,.002898,0,39.539,113.5366,.2086,0,108.944,1.3739,0,
17.1514,-.0161,0}, /* Pluto */
X
{34.6127752,713.5756219,0,.382270369,-.004694073,0,13.66975144,337.407213,
2.163306646,0,208.1482658,1.247724355,0,6.911179715,.011236955,0}, /* Chiron */
{108.2925,7820.36556,0,.0794314,0,0,2.7672273,71.0794444,0,0,80.23555556,
1.3960111,0,10.59694444,0,0}, /* Ceres */
{106.6641667,7806.531667,0,.2347096,0,0,2.7704955,310.166111,0,0,172.497222,
1.39601111,0,34.81416667,0,0}, /* Pallas Athena */
{267.685,8256.081111,0,.2562318,0,0,2.6689897,245.3752778,0,0,170.137777,
1.396011111,.0003083333,13.01694444,0,0}, /* Juno */
{138.7733333,9924.931111,0,.0902807,0,0,2.360723,149.6386111,0,0,103.2197222,
1.396011111,.000308333,7.139444444,0,0}, /* Vesta */
X
{104.5959,138.5369,0,0,0,0,40.99837, 0,0,0,0,0,0,0,0,0}, /* Cupido   */
{337.4517,101.2176,0,0,0,0,50.667443,0,0,0,0,0,0,0,0,0}, /* Hades    */
{104.0904,80.4057, 0,0,0,0,59.214362,0,0,0,0,0,0,0,0,0}, /* Zeus     */
{17.7346, 70.3863, 0,0,0,0,64.816896,0,0,0,0,0,0,0,0,0}, /* Kronos   */
{138.0354,62.5,    0,0,0,0,70.361652,0,0,0,0,0,0,0,0,0}, /* Apollon  */
{-8.678,  58.3468, 0,0,0,0,73.736476,0,0,0,0,0,0,0,0,0}, /* Admetos  */
{55.9826, 54.2986, 0,0,0,0,77.445895,0,0,0,0,0,0,0,0,0}, /* Vulkanus */
{165.3595,48.6486, 0,0,0,0,83.493733,0,0,0,0,0,0,0,0,0}  /* Poseidon */
};
#endif /* MATRIX */
X
CONST real ARR rStarBright[cStar+1] = {0,
X  0.46, 2.02, 5.24, 5.09, 0.85, 0.08, 0.12, 1.64, 1.65, 1.70,
X  0.50, 1.90, 1.98,-0.72, 1.93,-1.46, 1.50, 1.84, 1.59, 0.38,
X  1.14, 1.78, 1.86, 1.68, 1.98, 1.35, 1.79, 1.58, 1.63, 1.25,
X  1.77, 0.98, 1.86, 0.61,-0.04,-0.01, 0.96, 1.63, 1.87, 1.85,
X  0.03, 0.77, 1.94, 1.25, 1.74, 1.16, 4.61};
X
CONST real ARR rStarData[cStar*6] = {
X 1,37,42.9,-57,14,12,   2,31,50.5, 89,15,51,   3,17,46.1,-62,34,32,
X 3,49,11.1, 24, 8,12,   4,35,55.2, 16,30,33,   5,16,41.3, 45,59,53,
X 5,14,32.2, -8,12, 6,   5,25, 7.8,  6,20,59,   5,26,17.5, 28,36,27,
X 5,36,12.7, -1,12, 7,   5,55,10.3,  7,24,25,   5,59,31.7, 44,56,51,
X 6,22,41.9,-17,57,22,   6,23,57.2,-52,41,44,   6,37,42.7, 16,23,57,
X 6,45, 8.9,-16,42,58,   6,58,37.5,-28,58,20,   7, 8,23.4,-26,23,35,
X 7,34,35.9, 31,53,18,   7,39,18.1,  5,13,30,   7,45,18.9, 28, 1,34,
X 8, 9,31.9,-47,20,12,   8,22,30.8,-59,30,34,   9,13,12.1,-69,43, 2,
X 9,27,35.2, -8,39,31,  10, 8,22.3, 11,58, 2,  11, 3,43.6, 61,45, 3,
12,26,35.9,-63, 5,56,  12,31, 9.9,-57, 6,47,  12,47,43.3,-59,41,19,
12,54, 1.7, 55,57,35,  13,25,11.5,-11, 9,41,  13,47,32.3, 49,18,48,
14, 3,49.4,-60,22,22,  14,15,39.6, 19,10,57,  14,39,36.2,-60,50, 7,
16,29,24.4,-26,25,55,  17,33,36.4,-37, 6,13,  17,37,19.0,-42,59,52,
18,24,10.3,-34,23, 5,  18,36,56.2, 38,47, 1,  19,50,46.9,  8,52, 6,
20,25,38.8,-56,44, 7,  20,41,25.8, 45,16,49,  22, 8,13.9,-46,57,40,
22,57,39.0,-29,37,20,   0,42, 7.0, 41,16, 0};
X
X
#ifdef INTERPRET
/*
******************************************************************************
** Interpretation Tables.
******************************************************************************
*/
X
char * ARR szMindPart[oNorm+1] = {"earthy nature",
X  "spirit, ego, image of self, and sense of aliveness",
X  "emotional nature, moods, feelings, and caring tendencies",
X  "thoughts, intellect, and communicative activity",
X  "creativity, tendencies for affection and calmness, and relationship needs",
X  "will, energy, activity, and aggressive, assertive tendencies",
X  "enthusiastic, faithful, wise, expansive, spontaneous nature",
X  "part of mind that is disciplined, respectful, and solitary",
X  "individuality, desires for change, and tendency to go against social norms",
X  "intuitive, spiritual, compassionate, psychic nature",
X  "destiny, and capacity to transform the self and the outer world",
X  "ability to help, heal, and teach others, and where one has much experience",
X  "tendency to direct energy to instinctive, creative, reproductive goals",
X  "tendency to direct energy away from emotional and into mental pursuits",
X  "tendency to give away individual power for the benefit of a relationship",
X  "capacity to direct creative energy into personal or devotional goals",
X  "karmic goals, and best direction of evolutionary growth",
X  "capacity to let go and accept their natural darker side",
X  "place where opportunity and success can be found",
X  "karmic fate and method of reception of energies",
X  "generalized projected personality and outward appearance",
X  "personality and outward appearance, as projected to the world",
X  "", "", "", "", "", "", "", "",
X  "view as seen in the eyes of others, reputation, and social standing",
X  "", "",
X  "group associations and matters relating to art",
X  "dark, secretive, past, shameful side",
X  "fiery, creative, leadership tendencies",
X  "lofty, extraordinary parts",
X  "progressive, abundant energies",
X  "intense, focused nature",
X  "greatly forceful energies",
X  "idealistic, honorable side"};
X
char * ARR szDesc[cSign+1] = {"",
X  "forceful, energetic, direct, courageous",
X  "practical, often skeptical and stubborn",
X  "inquisitive, witty, perceptive, adaptable",
X  "introspective, emotional, protective",
X  "proud, gregarious, dramatic, dignified",
X  "analytical, critical, modest, helpful",
X  "affectionate, tolerant, often indecisive, appreciates beauty",
X  "penetrating, suspicious, introspective",
X  "jovial, open minded, loves freedom",
X  "industrious, practical, disciplined",
X  "progressive, erratic, revolutionary, idealistic, humanitarian, inventive",
X  "imaginative, other worldly, impressionable"};
X
char * ARR szDesire[cSign+1] = {"",
X  "seeks adventure and challenge",
X  "loves serenity and inner peace",
X  "seeks out information",
X  "wants inner and outer security",
X  "desires self expression",
X  "works toward perfection",
X  "seeks balance, relationship, and calmness",
X  "desires to transform and remove outer masks",
X  "seeks meaning and new experience",
X  "works for solitude and personal integrity",
X  "desires individuality",
X  "seeks transcendence of self"};
X
char * ARR szLifeArea[cSign+1] = {"",
X  "establishment of personal identity",
X  "self image, self worth, and material security",
X  "communicating to and receiving from the environment",
X  "imagination, fantasies, inner feelings, and domestic life",
X  "finding joy, pleasure, and creative expression",
X  "work and feeling talented and useful",
X  "personal relationships and intimacy",
X  "sex, death, the occult, and other hard to grasp topics",
X  "changes, exploration, and the breaking of routine",
X  "career, social stature, and destiny",
X  "the future, life goals, and association with friends and groups",
X  "things that disrupt or cause disassociation with the personality"};
X
char * ARR szInteract[cAspectInt+1] = {"",
X  "is %sconnected and fused together with",
X  "%sopposes and creates tension with",
X  "is %sin conflict with",
X  "is %sin harmony with",
X  "has %sopportunity for growth, exchange, and harmony in relation with",
X  "is %sdifferent from",
X  "%sgets new perspectives in relation with",
X  "%screates internal friction with",
X  "%screates internal agitation with",
X  "%screatively relates externally with",
X  "%screatively relates internally with"};
X
char * ARR szTherefore[cAspectInt+1] = {"",
X  "Both parts are prominent in their psyche", "Balance is needed",
X  "Adaptation is required by both sides", "", "",
X  "They can often relate in a discordant way", "", "", "", "", ""};
X
/* Modifier array makes the interpretation stronger for narrower orbs. */
X
char * ARR szModify[3][cAspectInt] =
X  {{"always ", "always ", "irreconcilably ", "always ", "much ",
X  "completely ", "often ", "often ", "often ", "often ", "often "},
X  {"", "", "", "", "", "", "", "", "", "", ""},
X  {"somewhat ", "somewhat ", "somewhat ", "somewhat ", "some ", "somewhat ",
X  "sometimes ", "sometimes ", "sometimes ", "sometimes ", "sometimes "}};
#endif /* INTERPRET */
X
/* data2.c */
SHAR_EOF
  $shar_touch -am 1223232998 'data2.c' &&
  chmod 0644 'data2.c' ||
  echo 'restore of data2.c failed'
  shar_count="`wc -c < 'data2.c'`"
  test 16447 -eq "$shar_count" ||
    echo "data2.c: original size 16447, current size $shar_count"
fi
# ============= extern.h ==============
if test -f 'extern.h' && test X"$1" != X"-c"; then
  echo 'x - skipping extern.h (File already exists)'
else
  echo 'x - extracting extern.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'extern.h' &&
/*
** Astrolog (Version 5.40) File: extern.h
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
/*
******************************************************************************
** Function Declarations.
******************************************************************************
*/
X
#ifdef PROTO
#define P(t) t
#else
#define P(t) ()
#endif
X
/* From astrolog.c */
X
extern void InitColors P((void));
extern void Action P((void));
extern void InitVariables P((void));
extern bool FProcessCommandLine P((char *));
extern int NParseCommandLine P((char *, char **));
extern int NPromptSwitches P((char *, char *[MAXSWITCHES]));
extern int NProcessSwitchesRare P((int, char **, int, bool, bool, bool));
extern bool FProcessSwitches P((int, char **));
X
X
/* From data.c & data2.c */
X
#define MM ciCore.mon
#define DD ciCore.day
#define YY ciCore.yea
#define TT ciCore.tim
#define ZZ ciCore.zon
#define SS ciCore.dst
#define OO ciCore.lon
#define AA ciCore.lat
X
#define Mon ciMain.mon
#define Day ciMain.day
#define Yea ciMain.yea
#define Tim ciMain.tim
#define Zon ciMain.zon
#define Dst ciMain.dst
#define Lon ciMain.lon
#define Lat ciMain.lat
X
#define MonT ciTran.mon
#define DayT ciTran.day
#define YeaT ciTran.yea
#define TimT ciTran.tim
#define ZonT ciTran.zon
#define DstT ciTran.dst
#define LonT ciTran.lon
#define LatT ciTran.lat
X
#define planet    cp0.obj
#define planetalt cp0.alt
#define ret       cp0.dir
#define chouse    cp0.cusp
#define inhouse   cp0.house
X
#define ignorea(a) (rAspOrb[a] <= 0.0)
X
extern US NPTR us;
extern IS NPTR is;
extern CI ciCore, ciMain, ciTwin, ciThre, ciFour, ciTran, ciSave;
extern CP cp0, cp1, cp2;
X
extern real spacex[oNorm+1], spacey[oNorm+1], spacez[oNorm+1], force[objMax];
extern GridInfo FPTR *grid;
extern int starname[cStar+1], kObjA[objMax];
X
extern byte ignore[objMax], ignore2[objMax], ignorez[4], pluszone[cSector+1];
extern real rAspAngle[cAspect+1], rAspOrb[cAspect+1], rObjOrb[oNorm+1],
X  rObjAdd[oNorm+1];
extern int ruler1[oNorm+1], ruler2[oNorm+1], exalt[oNorm+1], rules[cSign+1],
X  kMainA[9], kRainbowA[8], kElemA[4], kAspA[cAspect+1];
extern real rObjInf[oNorm+3], rHouseInf[cSign+3], rAspInf[cAspect+1],
X  rTransitInf[oNorm+3];
X
extern CONST char *szAppName, *szSignName[cSign+1], *szSignAbbrev[cSign+1],
X  *szSignEnglish[cSign+1], *szHouseTradition[cSign+1], *szSystem[cSystem],
X  *szAspectName[cAspect+1], *szAspectGlyph[cAspect+1],
X  *szAspectConfig[cAspConfig+1], *szElem[4], *szMode[3], *szMonth[cSign+1],
X  *szDay[cWeek], *szZon[cZone], *szDir[4], *szSuffix[cSign+1];
extern CONST real rZon[cZone];
extern char *szAspectAbbrev[cAspect+1];
extern CONST char *szObjName[objMax], *szCnstlName[cCnstl+1],
X  *szCnstlAbbrev[cCnstl+1], *szCnstlMeaning[cCnstl+1],
X  *szCnstlGenitive[cCnstl+1];
extern CONST real rStarBright[cStar+1], rStarData[cStar*6];
extern char *szMindPart[oNorm+1], *szDesc[cSign+1], *szDesire[cSign+1],
X  *szLifeArea[cSign+1], *szInteract[cAspectInt+1], *szTherefore[cAspectInt+1],
X  *szModify[3][cAspectInt];
X
extern CONST real rObjDist[oVes+1], rObjYear[oVes+1], rObjDiam[oVes+1],
X  rObjDay[oPlu+1], rObjMass[oPlu+1], rObjAxis[oPlu+1];
extern CONST byte cSatellite[oPlu+1];
extern CONST AI ai[cPart];
X
extern CONST byte rErrorCount[oPlu-oJup+1];
extern CONST byte rErrorOffset[oPlu-oJup+1];
extern CONST real rErrorData[72+51+42*3];
extern OE rgoe[oVes-1+cUran];
extern char *szMacro[48];
extern CONST char *szColor[cColor];
X
X
/* From general.c */
X
#define PrintAltitude(deg) PrintSz(SzAltitude(deg))
#define ErrorValR(sz, r) ErrorValN(sz, (int)r)
X
extern void SwapR P((real *, real *));
extern int CchSz P((CONST char *));
extern int NCompareSz P((CONST char *, CONST char *));
extern void ClearB P((lpbyte, int));
extern void CopyRgb P((byte *, byte *, int));
extern real RSgn P((real));
extern real Angle P((real, real));
extern real Mod P((real));
extern real ModRad P((real));
extern long Dvd P((long, long));
extern int Mod12 P((int));
extern real DecToDeg P((real));
extern real DegToDec P((real));
extern real MinDistance P((real, real));
extern real MinDifference P((real, real));
extern real Midpoint P((real, real));
extern char Dignify P((int, int));
extern int DayInMonth P((int, int));
extern int DaysInMonth P((int, int));
extern int DayOfWeek P((int, int, int));
extern int AddDay P((int, int, int, int));
extern real GetOrb P((int, int, int));
extern void Terminate P((int));
extern void PrintSz P((CONST char *));
extern void PrintCh P((char));
extern void PrintSzScreen P((char *));
extern void PrintNotice P((char *));
extern void PrintWarning P((char *));
extern void PrintError P((char *));
extern void ErrorArgc P((char *));
extern void ErrorValN P((char *, int));
extern void ErrorArgv P((char *));
extern void ErrorSwitch P((char *));
extern void ErrorEphem P((char *, long));
extern void PrintTab P((char, int));
extern void AnsiColor P((int));
extern void PrintZodiac P((real));
extern char *SzZodiac P((real));
extern char *SzAltitude P((real));
extern char *SzDegree P((real));
extern char *SzDate P((int, int, int, int));
extern char *SzTime P((int, int));
extern char *SzTim P((real));
extern char *SzZone P((real));
extern char *SzLocation P((real, real));
extern void GetTimeNow P((int *, int *, int *, real *, real));
extern int NFromAltN P((int));
extern char *ProcessProgname P((char *));
extern char *SzPersist P((char *));
extern lpbyte PAllocate P((long, bool, char *));
X
X
/* From io.c */
X
extern FILE *FileOpen P((char *, int));
extern bool FProcessSwitchFile P((char *, FILE *));
extern bool FOutputData P((void));
extern int NParseSz P((char *, int));
extern real RParseSz P((char *, int));
extern void InputString P((char *, char *));
extern int NInputRange P((char *, int, int, int));
extern real RInputRange P((char *, real, real, int));
extern bool FInputData P((char *));
X
X
/* From calc.c */
X
#define RBiorhythm(day, rate) (RSin(((day)/(rate))*rPi2)*100.0)
X
extern int HousePlaceIn P((real));
extern void ComputeInHouses P((void));
extern void HouseAlcabitius P((void));
extern void HouseEqualMidheaven P((void));
extern void HousePorphyryNeo P((void));
extern void HouseWhole P((void));
extern void HouseNull P((void));
extern void ComputeHouses P((int));
extern void ComputeStars P((real));
extern real Decan P((real));
extern real Navamsa P((real));
extern void SphToRec P((real, real, real, real *, real *, real *));
extern void ComputePlacalc P((real));
extern real CastChart P((bool));
extern void CastSectors P((void));
extern bool FEnsureGrid P((void));
extern bool FAcceptAspect P((int, int, int));
extern void GetAspect P((real *, real *, real *, real *, int, int));
extern void GetParallel P((real *, real *, real *, real *, int, int));
extern bool FCreateGrid P((bool));
extern bool FCreateGridRelation P((bool));
extern void CreateElemTable P((ET *));
X
X
/* From matrix.c */
X
#define EclToEqu(Z, L) CoorXform(Z, L, RFromD(rAxis))
#define EquToEcl(Z, L) CoorXform(Z, L, RFromD(-rAxis))
#define EquToLocal(Z, L, T) CoorXform(Z, L, T)
#define JulianDayFromTime(t) ((t)*36525.0+2415020.0)
#define IoeFromObj(obj) \
X  (obj < oMoo ? 0 : (obj <= cPlanet ? obj-2 : obj-uranLo+cPlanet-1))
#define Tropical(deg) (deg - is.rSid + us.rZodiacOffset)
X
extern real MC, Asc, RA, OB;
X
extern long MdyToJulian P((int, int, int));
extern real MdytszToJulian P((int, int, int, real, real, real));
extern void JulianToMdy P((real, int *, int *, int *));
extern real ProcessInput P((bool));
extern void PolToRec P((real, real, real *, real *));
extern void RecToPol P((real, real, real *, real *));
extern real RecToSph P((real, real, real));
extern void CoorXform P((real *, real *, real));
extern void ComputeVariables P((real *));
extern real CuspMidheaven P((void));
extern real CuspAscendant P((void));
extern real CuspEastPoint P((void));
extern real CuspPlacidus P((real, real, bool));
extern void HousePlacidus P((void));
extern void HouseKoch P((void));
extern void HouseEqual P((void));
extern void HouseCampanus P((void));
extern void HouseMeridian P((void));
extern void HouseRegiomontanus P((void));
extern void HousePorphyry P((void));
extern void HouseMorinus P((void));
extern real CuspTopocentric P((real));
extern void HouseTopocentric P((void));
extern real ReadThree P((real, real, real));
extern void RecToSph2 P((real, real, real, real *, real *, real *));
extern void ErrorCorrect P((int, real *, real *, real *));
extern void ProcessPlanet P((int, real));
extern void ComputePlanets P((void));
extern void ComputeLunar P((real *, real *, real *, real *));
X
X
#ifdef PLACALC
/* From placalc.c & placalc2.c */
X
extern bool FPlacalcPlanet
X  P((int, double, int, real *, real *, real *, real *));
extern double julday P((int, int, int, double, int));
extern void revjul P((double, int, int *, int *, int *, double *));
#endif
X
X
/* From charts0.c */
X
extern void PrintW P((char *, int));
extern void DisplayCredits P((void));
extern void PrintS P((char *));
extern void DisplaySwitches P((void));
extern void DisplaySwitchesRare P((void));
extern void PrintObjects P((void));
extern void PrintAspects P((void));
extern void PrintSigns P((void));
#ifdef CONSTEL
extern char *GetSzGenitive P((char *, char *));
extern void GetSzConstel P((char *, int));
extern void PrintConstellations P((void));
#endif
extern void PrintOrbit P((void));
extern int NCompareSzPart P((int, int));
extern void DisplayArabic P((void));
#ifdef GRAPH
extern void DisplayKeysX P((void));
extern void DisplaySwitchesX P((void));
#ifdef WIN
extern void DisplaySwitchesW P((void));
#endif
#endif /* GRAPH */
extern bool FPrintTables P((void));
X
X
/* From charts1.c */
X
extern void PrintHeader P((void));
extern void ChartListing P((void));
extern void ChartGrid P((void));
extern void PrintGrand P((char, int, int, int, int));
extern void DisplayGrands P((void));
extern void PrintHouse P((int, int));
extern void PrintWheelCenter P((int));
extern void PrintWheelSlot P((int));
extern void ChartWheel P((void));
extern void PrintAspectSummary P((int *, int *, int, real));
extern void ChartAspect P((void));
extern void PrintMidpointSummary P((int *, int, long));
extern void ChartMidpoint P((void));
extern void ChartHorizon P((void));
extern void ChartOrbit P((void));
extern void ChartSector P((void));
extern void ChartAstroGraph P((void));
extern void PrintChart P((bool));
X
X
/* From charts2.c */
X
extern void ChartGridRelation P((void));
extern void ChartAspectRelation P((void));
extern void ChartMidpointRelation P((void));
extern void CastRelation P((void));
extern void PrintInDay P((int, int, int));
extern void PrintAspect P((int, int, int, int, int, int, int, char));
extern void ChartInDayInfluence P((void));
extern void ChartTransitInfluence P((bool));
extern void EclToHorizon P((real *, real *, real, real, real, real, real));
extern void ChartCalendarMonth P((void));
extern void ChartCalendarYear P((void));
extern void DisplayRelation P((void));
X
X
/* From charts3.c */
X
extern void ChartInDaySearch P((bool));
extern void ChartTransitSearch P((bool));
extern void ChartInDayHorizon P((void));
extern void ChartEphemeris P((void));
X
X
/* From intrpret.c */
X
#ifdef INTERPRET
extern void FieldWord P((char *));
extern void InterpretGeneral P((void));
extern void InterpretAspectGeneral P((void));
extern void InterpretLocation P((void));
extern void InterpretAspect P((int, int));
extern void InterpretGrid P((void));
extern void InterpretMidpoint P((int, int));
extern void InterpretInDay P((int, int, int));
extern void InterpretTransit P((int, int, int));
extern void InterpretSynastry P((void));
extern void InterpretAspectRelation P((int, int));
extern void InterpretGridRelation P((void));
extern void InterpretMidpointRelation P((int, int));
#endif
extern void SortRank P((real *, int *, int));
extern void ChartInfluence P((void));
X
X
#ifdef GRAPH
/* From xdata.c */
X
extern GS NPTR gs;
extern GI NPTR gi;
X
#ifdef X11
extern XSizeHints hint;
extern char xkey[];
extern char *szColorX[cColor];
extern KV rgbind[cColor];
extern KV fg, bg;
#endif
#ifdef WIN
extern int ikPalette[cColor];
#endif
X
extern CONST KV rgb[cColor], rgbbmp[cColor];
extern KI kMainB[9], kRainbowB[8], kElemB[4], kAspB[cAspect+1], kObjB[objMax];
extern CONST char szObjectFont[oNorm+2], szAspectFont[cAspect+1],
X  *szDrawSign[cSign+2], *szDrawSign2[cSign+2], *szDrawObject[oNorm+5],
X  *szDrawObject2[oNorm+5], *szDrawHouse[cSign+1], *szDrawHouse2[cSign+1],
X  *szDrawAspect[cAspect+3], *szDrawAspect2[cAspect+3], *szDrawCh[128-32+1],
X  *szWorldData[62*3], *szDrawConstel[cCnstl+1];
X
X
/* From xgeneral.c */
X
#define BBmGet(B, X, Y) ((B)[(long)(Y)*(long)(gi.cbBmpRow) + ((X) >> 1)])
#define FBmGet(B, X, Y) (BBmGet(B, X, Y) >> (((X)&1^1) << 2) & 15)
#define BmSet(B, X, Y, O) BBmGet(B, X, Y) = BBmGet(B, X, Y) & \
X  15 << (((X)&1) << 2) | (O) << (((X)&1^1) << 2)
X
#define PutByte(A) putc((byte) (A), file)
#define PutWord(A) PutByte(BLo(A)); PutByte(BHi(A))
#define PutLong(A) PutWord(WLo(A)); PutWord(WHi(A))
X
#define DrawEdge(X1, Y1, X2, Y2) \
X  DrawBox(X1, Y1, X2, Y2, gi.nScaleT, gi.nScaleT)
#define DrawEdgeAll() DrawEdge(0, 0, gs.xWin-1, gs.yWin-1)
#define DrawLine(X1, Y1, X2, Y2) DrawDash(X1, Y1, X2, Y2, 0)
#define DrawCircle(X, Y, RX, RY) \
X  DrawEllipse((X)-(RX), (Y)-(RY), (X)+(RX), (Y)+(RY))
X
extern void DrawColor P((KI));
extern void DrawPoint P((int, int));
extern void DrawSpot P((int, int));
extern void DrawBlock P((int, int, int, int));
extern void DrawBox P((int, int, int, int, int, int));
extern void DrawClearScreen P((void));
extern void DrawDash P((int, int, int, int, int));
extern void DrawWrap P((int, int, int, int, int, int));
extern void ClipLesser P((int *, int *, int *, int *, int));
extern void ClipGreater P((int *, int *, int *, int *, int));
extern void DrawClip P((int, int, int, int, int, int, int, int, int));
extern void DrawEllipse P((int, int, int, int));
extern void DrawSz P((CONST char *, int, int, int));
extern void DrawSign P((int, int, int));
extern void DrawHouse P((int, int, int));
extern void DrawObject P((int, int, int));
extern void DrawAspect P((int, int, int));
extern int NFromPch P((CONST char **));
extern void DrawTurtle P((CONST char *, int, int));
X
X
/* From xdevice.c */
X
#ifdef META
/* Macros to output the various metafile commands used. */
X
#define MetaRecord(S, R) MetaLong((long)(S)); MetaWord(R)
#define MetaSelectObject(O) MetaRecord(4, 0x12D); MetaWord(O)
#define MetaDeleteObject(O) MetaRecord(4, 0x1F0); MetaWord(O)
#define MetaSaveDc() MetaRecord(3, 0x01E)
#define MetaRestoreDc() MetaRecord(4, 0x127); MetaWord((word)-1)
#define MetaWindowOrg(X, Y) MetaRecord(5, 0x20B); MetaWord(Y); MetaWord(X)
#define MetaWindowExt(X, Y) MetaRecord(5, 0x20C); MetaWord(Y); MetaWord(X)
#define MetaCreatePen(S, W, C) MetaRecord(8, 0x2FA); MetaWord(S); \
X  MetaWord(W); MetaWord(W); MetaLong(C)
#define MetaCreateBrush(S, C) MetaRecord(7, 0x2FC); \
X  MetaWord(S); MetaLong(C); MetaWord(0 /* Not used */);
#define MetaCreateFont(S, X, Y, C) MetaRecord(12+(S), 0x2FB); MetaWord(Y); \
X  MetaWord(X); MetaWord(0 /* Angle */); MetaWord(0 /* Not used */); \
X  MetaWord(400 /* Normal Weight */); MetaWord(0 /* Italic, Underline */); \
X  MetaWord(WFromBB(0 /* Strikeout */, C)); \
X  MetaWord(WFromBB(4 /* TrueType */, 0 /* Clip */))
#define MetaBkMode(M) MetaRecord(4, 0x102); MetaWord(M)
#define MetaTextAlign(A) MetaRecord(4, 0x12E); MetaWord(A)
#define MetaTextColor(C) MetaRecord(5, 0x209); MetaLong(C);
#define MetaTextOut(X, Y, S) MetaRecord(7+((S)+1)/2, 0xA32); \
X  MetaWord(Y); MetaWord(X); MetaWord(S); MetaWord(0 /* ETO */)
#define MetaRectangle(X1, Y1, X2, Y2) MetaRecord(7, 0x41B); \
X  MetaWord(Y2); MetaWord(X2); MetaWord(Y1); MetaWord(X1)
#define MetaEllipse(X1, Y1, X2, Y2) MetaRecord(7, 0x418); \
X  MetaWord(Y2); MetaWord(X2); MetaWord(Y1); MetaWord(X1)
#define MetaEscape(S) MetaRecord((S), 0x626); \
X  MetaWord(15 /* MFCOMMENT */); MetaWord(((S)-5)*2 /* Bytes in comment */);
#endif /* META */
X
extern void WriteXBitmap P((FILE *, char *, char));
extern void WriteAscii P((FILE *));
extern void WriteBmp P((FILE *));
extern void BeginFileX P((void));
extern void EndFileX P((void));
extern void PsStrokeForce P((void));
extern void PsStroke P((int));
extern void PsLineCap P((bool));
extern void PsDash P((int));
extern void PsLineWidth P((int));
extern void PsFont P((int));
extern void PsBegin P((void));
extern void PsEnd P((void));
extern void MetaWord P((word));
extern void MetaLong P((long));
extern void MetaSelect P((void));
extern void MetaInit P((void));
extern void WriteMeta P((FILE *));
extern int MouseInit P((int, int));
extern void MouseShow P((bool));
extern bool MouseStatus P((int *, int *, int *));
X
X
/* From xcharts0.c */
X
extern int DrawPrint P((char *, int, int));
extern void DrawInfo P((void));
extern void DrawWheel
X  P((real *, real *, int, int, real, real, real, real,real,real,real,real));
extern void DrawSymbolRing
X  P((real *, real *, real *, int, int, real, real, real,real,real,real));
extern bool FReadWorldData P((char FPTR **, char FPTR **, char FPTR **));
extern bool FGlobeCalc P((real, real, int *, int *, int, int, int, int, int));
extern void DrawLeyLine P((real, real, real, real));
extern void DrawLeyLines P((int));
extern void DrawMap P((bool, bool, int));
extern void DrawChartX P((void));
X
X
/* From xcharts1.c */
X
extern void XChartWheel P((void));
extern void XChartAstroGraph P((void));
extern void XChartGrid P((void));
extern void XChartHorizon P((void));
extern void XChartHorizonSky P((void));
extern void XChartOrbit P((void));
extern void XChartSector P((void));
extern void DrawArrow P((int, int, int, int));
extern void XChartDispositor P((void));
extern void XChartCalendar P((void));
X
X
/* From xcharts2.c */
X
extern bool FProper P((int));
extern void FillSymbolRing P((real *, real));
extern void FillSymbolLine P((real *));
extern real PlaceInX P((real));
extern real HousePlaceInX P((real));
extern void XChartWheelRelation P((void));
extern void XChartWheelThreeFour P((void));
extern void XChartGridRelation P((void));
extern void XChartEphemeris P((void));
extern void XChartBiorhythm P((void));
X
X
/* From xscreen.c */
X
extern void InitColorsX P((void));
#ifdef ISG
extern void BeginX P((void));
extern void AddTime P((int, int));
extern void Animate P((int, int));
extern void CommandLineX P((void));
extern void SquareX P((int *, int *, int));
extern void InteractX P((void));
extern void EndX P((void));
#endif
extern int NProcessSwitchesX P((int, char **, int, bool, bool, bool));
extern int NProcessSwitchesRareX P((int, char **, int));
extern bool FActionX P((void));
#endif /* GRAPH */
X
X
#ifdef WIN
/* From wdriver.c & wdialog.c */
X
extern WI NPTR wi;
extern OPENFILENAME ofn;
extern PRINTDLG prd;
extern char szFileName[cchSzMaxFile], szFileTitle[cchSzMaxFile], *szFileTemp;
X
#define TextClearScreen() PatBlt(wi.hdc, 0, 0, wi.xClient, wi.yClient, \
X  us.fAnsiColor || !gs.fInverse ? BLACKNESS : WHITENESS);
#define CheckMenu(cmd, f) \
X  CheckMenuItem(wi.hmenu, (_int)cmd, f ? MF_CHECKED : MF_UNCHECKED);
#define WiCheckMenu(cmd, f) CheckMenu(cmd, f); wi.fMenu = fTrue
#define WiDoDialog(pfn, dlg) \
X  dlgproc = (DLGPROC)MakeProcInstance(pfn, wi.hinst); \
X  DialogBox(wi.hinst, MAKEINTRESOURCE(dlg), wi.hwnd, dlgproc); \
X  FreeProcInstance((FARPROC)dlgproc)
X
#define SetCheck(id, f) CheckDlgButton(hdlg, id, f)
#define SetRadio(id, idLo, idHi) CheckRadioButton(hdlg, idLo, idHi, id)
#define SetEdit(id, sz) SetDlgItemText(hdlg, id, (LPCSTR)sz)
#define SetEditN(id, n) SetDlgItemInt(hdlg, id, n, fTrue)
#define SetCombo(id, sz) \
X  SendDlgItemMessage(hdlg, id, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)sz)
#define ClearCombo(id) SendDlgItemMessage(hdlg, id, CB_RESETCONTENT, 0, 0);
#define GetCheck(id) IsDlgButtonChecked(hdlg, id)
#define GetEdit(id, sz) GetDlgItemText(hdlg, id, sz, cchSzDef)
#define GetEditN(id) GetDlgItemInt(hdlg, id, NULL, fTrue)
#define EnsureN(n, f, sz) if (!(f)) { ErrorEnsure(n, sz); return fTrue; }
#define EnsureR(r, f, sz) EnsureN((int)r, f, sz)
X
extern LONG API WndProc P((HWND, WORD, WORD, LONG));
extern int NProcessSwitchesW P((int, char **, int, bool, bool, bool));
extern void ResizeWindowToChart P((void));
extern WORD WCmdFromRc P((int));
extern void SetRel P((int));
extern void ProcessState P((void));
extern int NWmCommand P((WORD));
extern void API RedoMenu P((void));
extern bool API FRedraw P((void));
X
extern void SetEditSz(HWND, int, char *);
extern void SetEditR(HWND, int, real, int);
extern void SetEditMDYT(HWND, int, int, int, int, int, int, int, real);
extern void SetEditSZOA(HWND, int, int, int, int, real, real, real, real);
extern void SetEditColor(HWND, int, KI);
extern real GetEditR(HWND, int);
extern void ErrorEnsure(int, char *);
extern bool FOutputSettings P((void));
extern bool API DlgOpenChart P((void));
extern bool API DlgSaveChart P((void));
extern bool API DlgPrint P((void));
extern bool API DlgAbortProc P((HDC, int));
extern bool API DlgAbort P((HWND, _int, WORD, LONG));
extern bool API DlgCommand P((HWND, _int, WORD, LONG));
extern bool API DlgColor P((HWND, _int, WORD, LONG));
extern bool API DlgInfo P((HWND, _int, WORD, LONG));
extern bool API DlgDefault P((HWND, _int, WORD, LONG));
extern bool API DlgInfoAll P((HWND, _int, WORD, LONG));
extern bool API DlgAspect P((HWND, _int, WORD, LONG));
extern bool API DlgObject P((HWND, _int, WORD, LONG));
extern bool API DlgObject2 P((HWND, _int, WORD, LONG));
extern bool API DlgRestrict P((HWND, _int, WORD, LONG));
extern bool API DlgStar P((HWND, _int, WORD, LONG));
extern bool API DlgSetting P((HWND, _int, WORD, LONG));
extern bool API DlgObscure P((HWND, _int, WORD, LONG));
extern bool API DlgTransit P((HWND, _int, WORD, LONG));
extern bool API DlgProgress P((HWND, _int, WORD, LONG));
extern bool API DlgChart P((HWND, _int, WORD, LONG));
extern bool API DlgGraphics P((HWND, _int, WORD, LONG));
extern bool API DlgAbout P((HWND, _int, WORD, LONG));
#endif /* WIN */
X
/* extern.h */
SHAR_EOF
  $shar_touch -am 1223232998 'extern.h' &&
  chmod 0644 'extern.h' ||
  echo 'restore of extern.h failed'
  shar_count="`wc -c < 'extern.h'`"
  test 23600 -eq "$shar_count" ||
    echo "extern.h: original size 23600, current size $shar_count"
fi
# ============= general.c ==============
if test -f 'general.c' && test X"$1" != X"-c"; then
  echo 'x - skipping general.c (File already exists)'
else
  echo 'x - extracting general.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'general.c' &&
/*
** Astrolog (Version 5.40) File: general.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
/*
******************************************************************************
** General Procedures.
******************************************************************************
*/
X
/* Swap two floating point values. */
X
void SwapR(d1, d2)
real *d1, *d2;
{
X  real temp;
X
X  temp = *d1; *d1 = *d2; *d2 = temp;
}
X
X
/* Return the length of a string (not counting the null terminator). */
X
int CchSz(sz)
CONST char *sz;
{
X  int i;
X
X  for (i = 0; *sz++; i++)
X    ;
X  return i;
}
X
X
/* Compare two strings. Return 0 if they are equal, a positive value if  */
/* the first string is greater, and a negative if the second is greater. */
X
int NCompareSz(s1, s2)
CONST char *s1, *s2;
{
X  while (*s1 && *s1 == *s2)
X    s1++, s2++;
X  return *s1 - *s2;
}
X
X
/* Set a given number of bytes to zero given a starting pointer. */
X
void ClearB(pb, cb)
lpbyte pb;
int cb;
{
X  while (cb-- > 0)
X    *pb++ = 0;
}
X
X
/* Copy a given number of bytes from one location to another. */
X
void CopyRgb(pbSrc, pbDst, cb)
byte *pbSrc, *pbDst;
int cb;
{
X  while (cb-- > 0)
X    *pbDst++ = *pbSrc++;
}
X
X
/* Determine the sign of a number: -1 if value negative, +1 if value */
/* positive, and 0 if it's zero.                                     */
X
real RSgn(r)
real r;
{
X  return r == 0.0 ? 0.0 : RSgn2(r);
}
X
X
/* Given an x and y coordinate, return the angle formed by a line from the */
/* origin to this coordinate. This is just converting from rectangular to  */
/* polar coordinates; however, we don't determine the radius here.         */
X
real Angle(x, y)
real x, y;
{
X  real a;
X
X  if (x != 0.0) {
X    if (y != 0.0)
X      a = RAtn(y/x);
X    else
X      a = x < 0.0 ? rPi : 0.0;
X  } else
X    a = y < 0.0 ? -rPiHalf : rPiHalf;
X  if (a < 0.0)
X    a += rPi;
X  if (y < 0.0)
X    a += rPi;
X  return a;
}
X
X
/* Modulus function for floating point values, where we bring the given */
/* parameter to within the range of 0 to 360.                           */
X
real Mod(d)
real d;
{
X  if (d >= rDegMax)        /* In most cases, our value is only slightly */
X    d -= rDegMax;          /* out of range, so we can test for it and   */
X  else if (d < 0.0)        /* avoid the more complicated arithmetic.    */
X    d += rDegMax;
X  if (d >= 0 && d < rDegMax)
X    return d;
X  return (d - RFloor(d/rDegMax)*rDegMax);
}
X
X
/* Another modulus function, this time for the range of 0 to 2 Pi. */
X
real ModRad(r)
real r;
{
X  while (r >= rPi2)    /* We assume our value is only slightly out of       */
X    r -= rPi2;         /* range, so test and never do any complicated math. */
X  while (r < 0.0)
X    r += rPi2;
X  return r;
}
X
X
/* Integer division - like the "/" operator but always rounds result down. */
X
long Dvd(x, y)
long x, y;
{
X  long z;
X
X  if (y == 0)
X    return x;
X  z = x / y;
X  if (((x >= 0) == (y >= 0)) || x-z*y == 0)
X    return z;
X  return z - 1;
}
X
X
/*
******************************************************************************
** General Astrology Procedures.
******************************************************************************
*/
X
/* A similar modulus function: convert an integer to value from 1..12. */
X
int Mod12(i)
int i;
{
X  while (i > cSign)
X    i -= cSign;
X  while (i < 1)
X    i += cSign;
X  return i;
}
X
X
/* Convert an inputed fractional degrees/minutes value to a true decimal   */
/* degree quantity. For example, the user enters the decimal value "10.30" */
/* to mean 10 degrees and 30 minutes; this will return 10.5, i.e. 10       */
/* degrees and 30 minutes expressed as a floating point degree value.      */
X
real DecToDeg(d)
real d;
{
X  return RSgn(d)*(RFloor(RAbs(d))+RFract(RAbs(d))*100.0/60.0);
}
X
X
/* This is the inverse of the above function. Given a true decimal value */
/* for a zodiac degree, adjust it so the degrees are in the integer part */
/* and the minute expressed as hundredths, e.g. 10.5 degrees -> 10.30    */
X
real DegToDec(d)
real d;
{
X  return RSgn(d)*(RFloor(RAbs(d))+RFract(RAbs(d))*60.0/100.0);
}
X
X
/* Return the shortest distance between two degrees in the zodiac. This is  */
/* normally their difference, but we have to check if near the Aries point. */
X
real MinDistance(deg1, deg2)
real deg1, deg2;
{
X  real i;
X
X  i = RAbs(deg1-deg2);
X  return i < rDegHalf ? i : rDegMax - i;
}
X
X
/* This is just like the above routine, except the min distance value  */
/* returned will either be positive or negative based on whether the   */
/* second value is ahead or behind the first one in a circular zodiac. */
X
real MinDifference(deg1, deg2)
real deg1, deg2;
{
X  real i;
X
X  i = deg2 - deg1;
X  if (RAbs(i) < rDegHalf)
X    return i;
X  return RSgn(i)*(RAbs(i) - rDegMax);
}
X
X
/* Return the degree of the midpoint between two zodiac positions, making */
/* sure we return the true midpoint closest to the positions in question. */
X
real Midpoint(deg1, deg2)
real deg1, deg2;
{
X  real mid;
X
X  mid = (deg1+deg2)/2.0;
X  return MinDistance(deg1, mid) < rDegQuad ? mid : Mod(mid+rDegHalf);
}
X
X
/* Given a planet and sign, determine whether: The planet rules the sign, */
/* the planet has its fall in the sign, the planet exalts in the sign, or */
/* is debilitated in the sign; and return an appropriate character.       */
X
char Dignify(obj, sign)
int obj, sign;
{
X  if (obj > oNorm)
X    return ' ';
X  if (ruler1[obj] == sign || ruler2[obj] == sign)
X    return 'R';
X  if (ruler1[obj] == Mod12(sign+6) || ruler2[obj] == Mod12(sign+6))
X    return 'F';
X  if (exalt[obj] == sign)
X    return 'e';
X  if (exalt[obj] == Mod12(sign+6))
X    return 'd';
X  return '-';
}
X
X
/* Determine the number of days in a particular month. The year is needed, */
/* too, because we have to check for leap years in the case of February.   */
X
int DayInMonth(month, year)
int month, year;
{
X  int d;
X
X  if (month == mSep || month == mApr || month == mJun || month == mNov)
X    d = 30;
X  else if (month != mFeb)
X    d = 31;
X  else {
X    d = 28;
X    if (year % 4 == 0 &&
X      (year % 100 != 0 || year % 400 == 0 || year <= yeaJ2G))
X      d++;
X  }
X  return d;
}
X
X
/* Return the actual number of days in a particular month. Normally, this  */
/* is the same as the above routine which determines the index of the last */
/* day of the month, but the values can differ when changing between       */
/* calendar systems (Julian to Gregorian) in which one can jump over days. */
X
int DaysInMonth(month, year)
int month, year;
{
X  int d;
X
X  d = DayInMonth(month, year);
X  if (year == yeaJ2G && month == monJ2G)
X    d -= (dayJ2G2 - dayJ2G1 - 1);
X  return d;
}
X
X
/* Return the day of the week (Sunday is 0) of the specified given date. */
X
int DayOfWeek(month, day, year)
int month, day, year;
{
X  int d;
X
X  d = (int)((MdyToJulian(month, day, year) + 1) % 7);
X  return d < 0 ? d+7 : d;
}
X
X
/* Given a day, and the month and year it falls in, add a number of days    */
/* to it and return the new day index. As month changes are not checked for */
/* here, this is mostly just adding the offset to the day; however we need  */
/* to check for calendar changes for when days in a month may be skipped.   */
X
int AddDay(month, day, year, delta)
int month, day, year, delta;
{
X  int d;
X
X  d = day + delta;
X  if (year == yeaJ2G && month == monJ2G) {     /* Check for Julian to  */
X    if (d > dayJ2G1 && d < dayJ2G2)            /* Gregorian crossover. */
X      d += NSgn(delta)*(dayJ2G2-dayJ2G1-1);
X  }
X  return d;
}
X
X
/* Given an aspect and two objects making that aspect with each other,   */
/* return the maximum orb allowed for such an aspect. Normally this only */
/* depends on the aspect itself, but some objects require narrow orbs,   */
/* and some allow wider orbs, so check for these cases.                  */
X
real GetOrb(obj1, obj2, asp)
int obj1, obj2, asp;
{
X  real orb, r;
X
X  orb = rAspOrb[asp];
X  r = obj1 > oNorm ? 2.0 : rObjOrb[obj1];
X  orb = Min(orb, r);
X  r = obj2 > oNorm ? 2.0 : rObjOrb[obj2];
X  orb = Min(orb, r);
X  if (obj1 <= oNorm)
X    orb += rObjAdd[obj1];
X  if (obj2 <= oNorm)
X    orb += rObjAdd[obj2];
X  return orb;
}
X
X
/*
******************************************************************************
** String Procedures.
******************************************************************************
*/
X
/* Exit the program, and do any cleanup necessary. Note that if we had     */
/* a non-fatal error, and we are in the -Q loop mode, then we won't        */
/* actually terminate the program, but drop back to the command line loop. */
X
void Terminate(tc)
int tc;
{
X  char sz[cchSzDef];
X
X  if (us.fNoQuit)
X    return;
X  if (tc == tcForce) {
X    is.S = stdout;
X    AnsiColor(kWhite);
X    sprintf(sz, "\n%s %s exited.\n", szAppName, szVersionCore);
X    PrintSz(sz);
X  }
X  if (tc == tcError && us.fLoop)
X    return;
X  if (us.fAnsiColor) {
X    sprintf(sz, "%c[0m", chEscape);    /* Get out of any Ansi color mode. */
X    PrintSz(sz);
X  }
X  exit(abs(tc));
}
X
X
/* Print a string on the screen. A seemingly simple operation, however we */
/* keep track of what column we are printing at after each newline so we  */
/* can automatically clip at the appropriate point, and we keep track of  */
/* the row we are printing at, so we may prompt before screen scrolling.  */
X
void PrintSz(sz)
CONST char *sz;
{
X  char szInput[cchSzDef], *pch;
#ifndef WIN
X  int fT;
#endif
X
X  for (pch = (char *)sz; *pch; pch++) {
X    if (*pch != '\n') {
X      is.cchCol++;
X      if (us.fClip80 && is.cchCol >= us.nScreenWidth)  /* Clip if need be. */
X        continue;
X    } else {
X      is.cchRow++;
X      is.cchCol = 0;
X    }
#ifdef WIN
X    if (is.S == stdout) {
X      if ((byte)*pch >= ' ') {
X        szInput[0] = *pch; szInput[1] = chNull;
X        TextOut(wi.hdc, (is.cchCol - 1 - wi.xScroll * 10) * wi.xChar + 4,
X          (is.cchRow - wi.yScroll * 10) * wi.yChar, szInput, 1);
X      }
X    } else
#endif
X    putc(*pch, is.S);
#ifndef WIN
X    if (*pch == '\n' && is.S == stdout &&
X      us.nScrollRow > 0 && is.cchRow >= us.nScrollRow) {
X
X      /* If we've printed 'n' rows, stop and wait for a line to be entered. */
X
X      fT = us.fAnsiColor;
X      us.fAnsiColor = fFalse;
X      InputString("Press return to continue scrolling", szInput);
X      us.fAnsiColor = fT;
X      is.cchRow = 0;
X
X      /* One can actually give a few simple commands before hitting return. */
X
X      if (szInput[0] == '.' || szInput[0] == 'q')
X        Terminate(tcForce);
X      else if (szInput[0] == '8')
X        not(us.fClip80);
X      else if (szInput[0] == 'Q')
X        us.nScrollRow = 0;
X      else if (szInput[0] == 'k') {
X        if (us.fAnsiColor)
X          AnsiColor(kDefault);
X        not(us.fAnsiColor); not(us.fAnsiChar);
X      }
X    }
#else
X    if (*pch == '\n' && is.S == stdout && wi.hdcPrint != hdcNil &&
X      is.cchRow >= us.nScrollRow) {
X
X      /* If writing to the printer, start a new page when appropriate. */
X
X      is.cchRow = 0;
X      EndPage(wi.hdcPrint);
X      StartPage(wi.hdcPrint);
X      /* StartPage clobbers all the DC settings */
X      SetMapMode(wi.hdcPrint, MM_ANISOTROPIC);      /* For SetViewPortExt */
X      SetViewportOrg(wi.hdcPrint, 0, 0);
X      SetViewportExt(wi.hdcPrint, GetDeviceCaps(wi.hdcPrint, HORZRES),
X        GetDeviceCaps(wi.hdcPrint, VERTRES));
X      SetWindowOrg(wi.hdcPrint, 0, 0);
X      SetWindowExt(wi.hdcPrint, wi.xClient, wi.yClient);
X      SetBkMode(wi.hdcPrint, TRANSPARENT);
X      SelectObject(wi.hdcPrint, wi.hfont);
X    }
#endif
X  }
}
X
X
/* Print a single character on the screen. */
X
void PrintCh(ch)
char ch;
{
X  char sz[2];
X
X  sz[0] = ch; sz[1] = chNull;    /* Treat char as a string of length one. */
X  PrintSz(sz);                   /* Then call above to print the string.  */
}
X
X
/* Print a string on the screen. Unlike the normal PrintSz(), here we still */
/* go to the standard output even if text is being sent to a file with -os. */
X
void PrintSzScreen(sz)
char *sz;
{
X  FILE *fileT;
X
X  fileT = is.S;
X  is.S = stdout;
X  PrintSz(sz);
X  is.S = fileT;
}
X
X
/* Print a general user message given a string. This is just like the */
/* warning displayer below just that we print in a different color.   */
X
void PrintNotice(sz)
char *sz;
{
#ifndef WIN
X  /* Notice messages are ignored in the Windows version. */
X  AnsiColor(kYellow);
X  fprintf(stderr, "%s\n", sz);
X  AnsiColor(kDefault);
#endif
}
X
X
/* Print a warning message given a string. This is called in non-fatal  */
/* cases where we return to normal execution after printing the string. */
X
void PrintWarning(sz)
char *sz;
{
#ifndef WIN
X  AnsiColor(kRed);
X  fprintf(stderr, "%s\n", sz);
X  AnsiColor(kDefault);
#else
X  char szT[cchSzDef];
X
X  sprintf(szT, "%s Warning", szAppName);
X  MessageBox(wi.hwndMain, sz, szT, MB_ICONSTOP);
#endif
}
X
X
/* Print an error message. This is called in more serious cases which halt */
/* running of the current chart sequence, which can terminate the program  */
/* but isn't a fatal error in that we can still fall back to the -Q loop.  */
X
void PrintError(sz)
char *sz;
{
#ifndef WIN
X  AnsiColor(kRed);
X  fprintf(stderr, "%s: %s\n", szAppName, sz);
X  Terminate(tcError);
X  AnsiColor(kDefault);
#else
X  char szT[cchSzDef];
X
X  sprintf(szT, "%s Error", szAppName);
X  MessageBox(wi.hwndMain, sz, szT, MB_ICONEXCLAMATION);
#endif
}
X
X
/* Simplification for a commonly printed error message. */
X
void ErrorArgc(szOpt)
char *szOpt;
{
X  char sz[cchSzDef];
X
X  sprintf(sz, "Too few options to switch %c%s", chSwitch, szOpt);
X  PrintError(sz);
}
X
X
/* Another simplification for a commonly printed error message. */
X
void ErrorValN(szOpt, nVal)
char *szOpt;
int nVal;
{
X  char sz[cchSzDef];
X
X  sprintf(sz, "Value %d passed to switch %c%s out of range.\n",
X    nVal, chSwitch, szOpt);
X  PrintError(sz);
}
X
X
/* Yet another place to print a type of error message. */
X
void ErrorArgv(szOpt)
char *szOpt;
{
X  char sz[cchSzDef];
X
X  sprintf(sz, "The switch %c%s is not allowed now.\n", chSwitch, szOpt);
X  PrintError(sz);
}
X
X
/* Still another place to print a type of error message. */
X
void ErrorSwitch(szOpt)
char *szOpt;
{
X  char sz[cchSzDef];
X
X  sprintf(sz, "Unknown switch '%s'", szOpt);
X  PrintError(sz);
}
X
X
#ifdef PLACALC
/* Print error messages dealing with ephemeris file access. */
X
void ErrorEphem(sz, l)
char *sz;
long l;
{
X  char szT[cchSzDef];
X
X  if (l < 0)
X    sprintf(szT, "Ephemeris file %s not found.\n", sz);
X  else
X    sprintf(szT, "Seek error in file %s at position %ld.\n", sz, l);
X  is.fNoEphFile = fTrue;
X  PrintWarning(szT);
}
#endif
X
X
/* A simple procedure used throughout Astrolog: Print a particular */
/* character on the screen 'n' times.                              */
X
void PrintTab(ch, cch)
char ch;
int cch;
{
X  int i;
X
X  for (i = 0; i < cch; i++)
X    PrintCh(ch);
}
X
X
/* Set an Ansi or MS Windows text color. */
X
void AnsiColor(k)
int k;
{
X  char sz[cchSzDef];
X  int cchSav;
X
#ifdef WIN
X  if (is.S == stdout) {
X    if (k < 0)
X      k = kLtGray;
X    SetTextColor(wi.hdc,
X      (COLORREF)rgbbmp[us.fAnsiColor ? k : (gs.fInverse ? kBlack : kLtGray)]);
X    return;
X  }
#endif
X
X  /* Special case: If we are passed the value Reverse, and Ansi color is */
X  /* not only on but set to a value > 1, then enter reverse video mode.  */
X
X  if (!us.fAnsiColor || (k == kReverse && us.fAnsiColor < 2))
X    return;
X  cchSav = is.cchCol;
X  is.cchCol = 0;
X  sprintf(sz, "%c[", chEscape);
X  PrintSz(sz);
X  if (k == kDefault)
X    PrintCh('0');
X  else if (k == kReverse) {
X    PrintCh('7');
X  } else {
X    sprintf(sz, "%c;%d", k > 7 ? '1' : '0', 30 + (k & 7));
X    PrintSz(sz);
X  }
X  PrintCh('m');
X  is.cchCol = cchSav;
}
X
X
/* Print a zodiac position on the screen. This basically just prints the */
/* string returned from SzZodiac() below, except we take care of color.  */
X
void PrintZodiac(deg)
real deg;
{
X  AnsiColor(kElemA[(int)(deg / 30.0) & 3]);
X  PrintSz(SzZodiac(deg));
X  AnsiColor(kDefault);
}
X
X
/* Given a zodiac position, return a string containing it as it's */
/* formatted for display to the user.                             */
X
char *SzZodiac(deg)
real deg;
{
X  static char szZod[11];
X  int sign, d, m;
X  real s;
X
X  switch (us.nDegForm) {
X  case 0:
X
X    /* Normally, we format the position in degrees/sign/minutes format: */
X
X    deg = Mod(deg + (is.fSeconds ? rRound/60.0/60.0 : rRound/60.0));
X    sign = (int)deg / 30;
X    d = (int)deg - sign*30;
X    m = (int)(RFract(deg)*60.0);
X    sprintf(szZod, "%2d%c%c%c%02d", d, chSig3(sign + 1), m);
X    if (is.fSeconds) {
X      s = RFract(deg)*60.0; s = RFract(s)*60.0;
X      sprintf(&szZod[7], "'%02d\"", (int)s);
X    }
X    break;
X
X  case 1:
X    /* However, if -sh switch in effect, get position in hours/minutes: */
X
X    deg = Mod(deg + (is.fSeconds ? rRound/4.0/60.0 : rRound/4.0));
X    d = (int)deg / 15;
X    m = (int)((deg - (real)d*15.0)*4.0);
X    sprintf(szZod, "%2dh,%02dm", d, m);
X    if (is.fSeconds) {
X      s = RFract(deg)*4.0; s = RFract(s)*60.0;
X      sprintf(&szZod[7], ",%02ds", (int)s);
X    }
X    break;
X
X  default:
X    /* Otherwise, if -sd in effect, format position as a simple degree: */
X
X    sprintf(szZod, is.fSeconds ? "%11.7f" : "%7.3f", deg);
X    break;
X  }
X  return szZod;
}
X
X
/* This is similar to formatting a zodiac degree, but here we return a */
/* string of a (signed) declination value in degrees and minutes.      */
X
char *SzAltitude(deg)
real deg;
{
X  static char szAlt[10];
X  int d, m, f;
X  real s;
X  char ch;
X
X  f = deg < 0.0;
X  deg = RAbs(deg) + (is.fSeconds ? rRound/60.0/60.0 : rRound/60.0);
X  d = (int)deg;
X  m = (int)(RFract(deg)*60.0);
X  ch = us.fAnsiChar > 1 ? 128 : chDeg1;
X  sprintf(szAlt, "%c%2d%c%02d'", f ? '-' : '+', d, ch, m);
X  if (is.fSeconds) {
X    s = RFract(deg)*60.0; s = RFract(s)*60.0;
X    sprintf(&szAlt[7], "%02d\"", (int)s);
X  }
X  return szAlt;
}
X
X
/* Here we return a string simply expressing the given value as degrees */
/* and minutes (and sometimes seconds) in the 0 to 360 degree circle.   */
X
char *SzDegree(deg)
real deg;
{
X  static char szPos[11];
X  int d, m;
X  real s;
X
X  deg = RAbs(deg) + (is.fSeconds ? rRound/60.0/60.0 : rRound/60.0);
X  d = (int)deg;
X  m = (int)(RFract(deg)*60.0);
X  sprintf(szPos, "%3d%c%02d'", d, chDeg1, m);
X  if (is.fSeconds) {
X    s = RFract(deg)*60.0; s = RFract(s)*60.0;
X    sprintf(&szPos[7], "%02d\"", (int)s);
X  }
X  return szPos;
}
X
X
/* Another string formatter, here we return a date string given a month,    */
/* day, and year. We format with the day or month first based on whether    */
/* the "European" date variable is set or not. The routine also takes a     */
/* parameter to indicate how much the string should be abbreviated, if any. */
X
char *SzDate(mon, day, yea, nFormat)
int mon, day, yea, nFormat;
{
X  static char szDat[20];
X
X  if (us.fEuroDate) {
X    switch (nFormat) {
X    case  2: sprintf(szDat, "%2d %c%c%c%5d", day, chMon3(mon), yea); break;
X    case  1: sprintf(szDat, "%d %s %d", day, szMonth[mon], yea);     break;
X    case -1: sprintf(szDat, "%2d-%2d-%2d", day, mon, abs(yea)%100);  break;
X    default: sprintf(szDat, "%2d-%2d-%4d", day, mon, yea);           break;
X    }
X  } else {
X    switch (nFormat) {
X    case  3: sprintf(szDat, "%c%c%c %2d, %d", chMon3(mon), day, yea); break;
X    case  2: sprintf(szDat, "%c%c%c %2d%5d", chMon3(mon), day, yea);  break;
X    case  1: sprintf(szDat, "%s %d, %d", szMonth[mon], day, yea);     break;
X    case -1: sprintf(szDat, "%2d/%2d/%2d", mon, day, abs(yea)%100);   break;
X    default: sprintf(szDat, "%2d/%2d/%4d", mon, day, yea);            break;
X    }
X  }
X  return szDat;
}
X
X
/* Return a string containing the given time expressed as an hour and */
/* minute quantity. This is formatted in 24 hour or am/pm time based  */
/* on whether the "European" time format flag is set or not.          */
X
char *SzTime(hr, min)
int hr, min;
{
X  static char szTim[8];
X
X  while (min >= 60) {
X    min -= 60;
X    hr++;
X  }
X  while (hr < 0)
X    hr += 24;
X  while (hr >= 24)
X    hr -= 24;
X  if (us.fEuroTime)
X    sprintf(szTim, "%2d:%02d", hr, min);
X  else
X    sprintf(szTim, "%2d:%02d%cm", Mod12(hr), min, hr < 12 ? 'a' : 'p');
X  return szTim;
}
X
X
/* This just determines the correct hour and minute and calls the above. */
X
char *SzTim(tim)
real tim;
{
X  return SzTime(NFloor(tim), (int)(RFract(RAbs(tim))*100.0+rRound/600.0));
}
X
X
/* Return a string containing the given time zone, given as a real value     */
/* having the hours before GMT in the integer part and minutes fractionally. */
X
char *SzZone(zon)
real zon;
{
X  static char szZon[7];
X
X  sprintf(szZon, "%c%d:%02d", zon > 0.0 ? '-' : '+', (int)RAbs(zon),
X    (int)(RFract(RAbs(zon))*100.0+rRound/60.0));
X  return szZon;
}
X
X
/* Nicely format the given longitude and latitude locations and return    */
/* them in a string. Various parts of the program display a chart header, */
/* and this allows the similar computations to be coded only once.        */
X
char *SzLocation(lon, lat)
real lon, lat;
{
X  static char szLoc[15];
X  int i, j;
X  char ch;
X
X  i = (int)(RFract(RAbs(lon))*100.0+rRound);
X  j = (int)(RFract(RAbs(lat))*100.0+rRound);
X  ch = us.fAnsiChar > 1 ? 128 : chDeg1;
X  if (us.fAnsiChar != 3) {
X    sprintf(szLoc, "%3.0f%c%02d%c%3.0f%c%02d%c",
X      RFloor(RAbs(lon)), ch, i, lon < 0.0 ? 'E' : 'W',
X      RFloor(RAbs(lat)), ch, j, lat < 0.0 ? 'S' : 'N');
X  } else {
X    sprintf(szLoc, "%3.0f%c%02d%3.0f%c%02d",
X      RFloor(RAbs(lon)), lon < 0.0 ? 'E' : 'W', i,
X      RFloor(RAbs(lat)), lat < 0.0 ? 'S' : 'N', j);
X  }
X  return szLoc;
}
X
X
#ifdef TIME
/* Compute the date and time it is right now as the program is running      */
/* using the computer's internal clock. We do this by getting the number    */
/* of seconds which have passed since January 1, 1970 and going from there. */
/* The time return value filled is expressed in the given zone parameter.   */
X
void GetTimeNow(mon, day, yea, tim, zon)
int *mon, *day, *yea;
real *tim, zon;
{
X  dword curtimer;
X  int min, sec;
X  real hr;
X
X  time(&curtimer);
X  sec = (int)(curtimer % 60);
X  curtimer = curtimer / 60 + us.lTimeAddition;
X  min = (int)(curtimer % 60);
X  curtimer /= 60;
#ifdef MAC
X  curtimer += 8;
#endif
X  hr = (real)(curtimer % 24) - zon;
X  curtimer /= 24;
X  while (hr < 0.0) {
X    curtimer--;
X    hr += 24.0;
X  }
X  while (hr >= 24.0) {
X    curtimer++;
X    hr -= 24.0;
X  }
X  curtimer += ldTime;  /* Number of days between 1/1/1970 and 1/1/4713 BC. */
X  JulianToMdy((real)curtimer, mon, day, yea);
X  *tim = hr + (real)min / 100.0 + (real)sec / 6000.0;
}
#endif /* TIME */
X
X
#ifdef PCG
/* Map one character value to another. This is used in processing special  */
/* keys and alt key combinations, which are read in from the keyboard as a */
/* zero immediately followed by some value. This converts that value into  */
/* something more useful to process and deal with.                         */
X
int NFromAltN(nAlt)
int nAlt;
{
X  /* Map number pad keys to the numbers characters they correspond to. */
X  if (nAlt == 82)
X    return '0';
X  else if (FBetween(nAlt, 79, 81))
X    return '1' + nAlt - 79;
X  else if (FBetween(nAlt, 75, 77))
X    return '4' + nAlt - 75;
X  else if (FBetween(nAlt, 71, 73))
X    return '7' + nAlt - 71;
X
X  /* Map F1 through F12 function keys to the values 201-212. */
X  else if (FBetween(nAlt, 59, 68))
X    return 201 + nAlt - 59;
X  else if (FBetween(nAlt, 133, 134))
X    return 211 + nAlt - 133;
X
X  /* Map Shift+F1 through Shift+F12 keys to the values 213-224. */
X  else if (FBetween(nAlt, 84, 93))
X    return 213 + nAlt - 84;
X  else if (FBetween(nAlt, 135, 136))
X    return 223 + nAlt - 135;
X
X  /* Map Control+F1 through Control+F12 keys to the values 225-236. */
X  else if (FBetween(nAlt, 94, 103))
X    return 225 + nAlt - 94;
X  else if (FBetween(nAlt, 137, 138))
X    return 235 + nAlt - 137;
X
X  /* Map Alt+F1 through Alt+F12 keys to the values 237-248. */
X  else if (FBetween(nAlt, 104, 113))
X    return 237 + nAlt - 104;
X  else if (FBetween(nAlt, 139, 140))
X    return 247 + nAlt - 139;
X
X  return chNull;
}
#endif
X
X
/* Given a string representing the complete pathname to a file, strip off    */
/* all the path information leaving just the filename itself. This is called */
/* by the main program to determine the name of the Astrolog executable.     */
X
char *ProcessProgname(szPath)
char *szPath;
{
X  char *b, *c, *e;
X
X  b = c = szPath;
X  while (*c) {
#ifdef PC
X    *c = ChUncap(*c);    /* Because DOS filenames are case insensitive. */
#endif
X    c++;
X  }
X  e = c;
X  while (c > b && *c != '.')
X    c--;
X  if (c > b)
X    *c = 0;
X  else
X    c = e;
X  while (c > b && *c != chDirSep)
X    c--;
X  if (c > b)
X    szPath = c+1;
X  return szPath;
}
X
X
/* Given a string, return a pointer to a persistent version of it, where  */
/* 'persistent' means its contents won't be invalidated when the stack    */
/* frame changes. Strings such as macros, et al, need to be in their own  */
/* space and can't just be local variables in a function reading them in. */
X
char *SzPersist(szSrc)
char *szSrc;
{
X  char szT[cchSzDef], *szNew;
X  int cb;
X
X  /* Some strings such as outer level command line parameter arguments */
X  /* already persist, so we can just return the same string passed in. */
X  if (is.fSzPersist)
X    return szSrc;
X
X  /* Otherwise we make a copy of the string in the local heap and use it. */
X  cb = CchSz(szSrc)+1;
X  AllocateNear(szNew, cb);
X  if (szNew == NULL) {
X    sprintf(szT, "%s: Not enough near memory for string (%d bytes).",
X      szAppName, cb);
X    PrintWarning(szT);
X  } else
X    CopyRgb((byte *)szSrc, (byte *)szNew, cb);
X  return szNew;
}
X
X
/* This is Astrolog's memory allocation routine, returning a pointer given */
/* a size, a flag for if it is a more than 64K huge allocation, and a      */
/* string to use when printing an error if the allocation fails.           */
X
lpbyte PAllocate(lcb, fHuge, szType)
long lcb;
bool fHuge;
char *szType;
{
X  char szT[cchSzDef];
X  lpbyte lp;
X
X  if (fHuge)
X    AllocateHuge(lp, lcb);
X  else
X    AllocateFar(lp, (int)lcb);
#ifdef PC
X  /* For PC's the array better not cross a segment boundary. */
X  if (lp && !fHuge && WHi(WLo(lp) + lcb) > 0)
X    lp = NULL;
#endif
X  if (lp == NULL && szType) {
X    sprintf(szT, "%s: Not enough memory for %s (%ld bytes).",
X      szAppName, szType, lcb);
X    PrintWarning(szT);
X  }
X  return lp;
}
X
/* general.c */
SHAR_EOF
  $shar_touch -am 1223232998 'general.c' &&
  chmod 0644 'general.c' ||
  echo 'restore of general.c failed'
  shar_count="`wc -c < 'general.c'`"
  test 27795 -eq "$shar_count" ||
    echo "general.c: original size 27795, current size $shar_count"
fi
# ============= intrpret.c ==============
if test -f 'intrpret.c' && test X"$1" != X"-c"; then
  echo 'x - skipping intrpret.c (File already exists)'
else
  echo 'x - extracting intrpret.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'intrpret.c' &&
/*
** Astrolog (Version 5.40) File: intrpret.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
#ifdef INTERPRET
/*
******************************************************************************
** Interpretation Routines.
******************************************************************************
*/
X
/* This function is used by the interpretation routines to print out lines  */
/* of text with newlines inserted just before the end of screen is reached. */
X
void FieldWord(sz)
char *sz;
{
X  static char line[cchSzMax];
X  static int cursor = 0;
X  int i, j;
X
X  /* Hack: Dump buffer if function called with a null string. */
X
X  if (sz == NULL) {
X    line[cursor] = 0;
X    PrintSz(line); PrintL();
X    cursor = 0;
X    return;
X  }
X  if (cursor)
X    line[cursor++] = ' ';
X  for (i = 0; (line[cursor] = sz[i]); i++, cursor++)
X    ;
X
X  /* When buffer overflows 'n' columns, display one line and start over. */
X
X  while (cursor >= us.nScreenWidth-1) {
X    for (i = us.nScreenWidth-1; line[i] != ' '; i--)
X      ;
X    line[i] = 0;
X    PrintSz(line); PrintL();
X    line[0] = line[1] = ' ';
X    for (j = 2; (line[j] = line[i+j-1]) != 0; j++)
X      ;
X    cursor -= (i-1);
X  }
}
X
X
/* Display a general interpretation of what each sign of the zodiac, house, */
/* and planet or object means. This is called to do the -I0 switch table.   */
X
void InterpretGeneral()
{
X  char sz[cchSzDef*2];
X  int i;
X
X  PrintSz("Signs of the zodiac represent psychological characteristics.\n\n");
X  for (i = 1; i <= cSign; i++) {
X    AnsiColor(kSignA(i));
X    sprintf(sz, "%s is", szSignName[i]); FieldWord(sz);
X    sprintf(sz, "%s, and", szDesc[i]); FieldWord(sz);
X    sprintf(sz, "%s.", szDesire[i]); FieldWord(sz);
X    FieldWord(NULL);
X  }
X  AnsiColor(kDefault);
X  PrintSz("\nHouses represent different areas within one's life.\n\n");
X  for (i = 1; i <= cSign; i++) {
X    AnsiColor(kSignA(i));
X    sprintf(sz, "The %d%s House is the area of life dealing with",
X      i, szSuffix[i]); FieldWord(sz);
X    sprintf(sz, "%s.", szLifeArea[i]); FieldWord(sz);
X    FieldWord(NULL);
X  }
X  AnsiColor(kDefault);
X  PrintSz("\nPlanets represent various parts of one's mind or self.\n\n");
X  for (i = 1; i <= cObjInt; i++) {
X    if (ignore[i] || FCusp(i))
X      continue;
X    AnsiColor(kObjA[i]);
X    if (i <= oMoo || (FBetween(i, oNod, oCore)) && (i != oLil || fSouthNode))
X      FieldWord("The");
X    sprintf(sz, "%s%s%s represents one's",
X      i == oNod ? "North " : (i == oFor ? "Part of " : ""), szObjName[i],
X      i == 13 ? " Athena" : ""); FieldWord(sz);
X    sprintf(sz, "%s.", szMindPart[i]); FieldWord(sz);
X    FieldWord(NULL);
X  }
X  AnsiColor(kDefault);
}
X
X
/* Display a general interpretation of what each aspect type means. This */
/* is called when printing the interpretation table in the -I0 switch.   */
X
void InterpretAspectGeneral()
{
X  char sz[cchSzDef*2];
X  int i;
X
X  PrintSz("\nAspects are different relationships between planets.\n\n");
X  for (i = 1; i <= Min(us.nAsp, cAspectInt); i++) {
X    AnsiColor(kAspA[i]);
X    sprintf(sz, "When planets are %s, one", szAspectName[i]);
X    FieldWord(sz); sprintf(sz, szInteract[i], ""); FieldWord(sz);
X    FieldWord("another.");
X    if (szTherefore[i][0]) {
X      sprintf(sz, "%s.", szTherefore[i]); FieldWord(sz);
X    }
X    FieldWord(NULL);
X  }
X  return;
}
X
X
/* Print the interpretation of each planet in sign and house, as specified */
/* with the -I switch. This is basically array accessing combining the     */
/* meanings of each planet, sign, and house, and a couple of other things. */
X
void InterpretLocation()
{
X  char sz[cchSzDef*2], c;
X  int i, j;
X
X  PrintL();
X  for (i = 1; i <= cObjInt; i++) {
X    if (ignore[i] || FCusp(i))
X      continue;
X    AnsiColor(kObjA[i]);
X    j = SFromZ(planet[i]); c = Dignify(i, j);
X    sprintf(sz, "%s%s%s%s in %s", ret[i] < 0.0 ? "Retrograde " : "",
X      i == oNod ? "North " : (i == oFor ? "Part of " : ""), szObjName[i],
X      i == 13 ? " Athena" : "", szSignName[j]);
X    FieldWord(sz);
X    sprintf(sz, "and %d%s House:", inhouse[i], szSuffix[inhouse[i]]);
X    FieldWord(sz);
X    sprintf(sz, "%s's", szPerson); FieldWord(sz);
X    FieldWord(szMindPart[i]); FieldWord("is");
X    if (((int)planet[i]) % 30 < 10)
X      FieldWord("very");
X    sprintf(sz, "%s, and", szDesc[j]); FieldWord(sz);
X    sprintf(sz, "%s.", szDesire[j]); FieldWord(sz);
X    FieldWord("Most often this manifests");
X    if (ret[i] < 0.0 && i != oNod)
X      FieldWord("in an independent, backward, introverted manner, and");
X    FieldWord("in the area of life dealing with");
X    sprintf(sz, "%s.", szLifeArea[inhouse[i]]); FieldWord(sz);
X
X    /* Extra information if planet is in its ruling, falling, etc, sign. */
X
X    if (c == 'R')
X      FieldWord("This is a major aspect of their psyche!");
X    else if (c == 'F')
X      FieldWord("(This bit plays only a minor part in their psyche.)");
X    else if (c == 'e')
X      FieldWord("It is easy for them to express this part of themself.");
X    else if (c == 'd')
X      FieldWord("It is difficult for them to express this part of themself.");
X    FieldWord(NULL);
X  }
}
X
X
/* Print an interpretation for a particular aspect in effect in a chart. */
/* This is called from the InterpretGrid and ChartAspect routines.       */
X
void InterpretAspect(x, y)
int x, y;
{
X  char sz[cchSzDef*2];
X  int n;
X
X  n = grid->n[x][y];
X  if (n < 1 || n > cAspectInt ||
X    FCusp(x) || FCusp(y) || x > cObjInt || y > cObjInt)
X    return;
X  AnsiColor(kAspA[n]);
X  sprintf(sz, "%s %s %s: %s's", szObjName[x],
X    szAspectName[n], szObjName[y], szPerson);
X  FieldWord(sz); FieldWord(szMindPart[x]);
X  sprintf(sz, szInteract[n],
X    szModify[Min(abs(grid->v[x][y])/150, 2)][n-1]);
X  FieldWord(sz);
X  sprintf(sz, "their %s.", szMindPart[y]); FieldWord(sz);
X  if (szTherefore[n][0]) {
X    sprintf(sz, "%s.", szTherefore[n]); FieldWord(sz);
X  }
X  FieldWord(NULL);
}
X
X
/* Print the interpretation of each aspect in the aspect grid, as specified */
/* with the -g -I switch. Again, this is done by basically array accessing  */
/* of the meanings of the two planets in aspect and of the aspect itself.   */
X
void InterpretGrid()
{
X  int i, j;
X
X  for (i = 1; i < cObjInt; i++) if (!ignore[i] && !FCusp(i))
X    for (j = i+1; j <= cObjInt; j++) if (!ignore[j] && !FCusp(i))
X      InterpretAspect(i, j);
}
X
X
/* Print an interpretation for a particular midpoint in effect in a chart. */
/* This is called from the ChartMidpoint routine.                          */
X
void InterpretMidpoint(x, y)
int x, y;
{
X  char sz[cchSzDef*2];
X  int n, i;
X
X  if (FCusp(x) || FCusp(y) || x > cObjInt || y > cObjInt)
X    return;
X  n = grid->n[y][x];
X  AnsiColor(kSignA(n));
X  sprintf(sz, "%s midpoint %s in %s: The merging of %s's",
X    szObjName[x], szObjName[y], szSignName[n], szPerson0);
X  FieldWord(sz); FieldWord(szMindPart[x]);
X  FieldWord("with their"); FieldWord(szMindPart[y]);
X  FieldWord("is");
X  if (grid->v[y][x]/60 < 10)
X    FieldWord("very");
X  sprintf(sz, "%s, and", szDesc[n]); FieldWord(sz);
X  sprintf(sz, "%s.", szDesire[n]); FieldWord(sz);
X  FieldWord("Most often this manifests in");
X  if (ret[x]+ret[y] < 0.0 && x != oNod && y != oNod)
X    FieldWord("an independent, backward, introverted manner, and");
X  FieldWord("the area of life dealing with");
X  i = HousePlaceIn(ZFromS(n) + (real)grid->v[y][x]/60.0);
X  sprintf(sz, "%s.", szLifeArea[i]); FieldWord(sz);
X  FieldWord(NULL);
}
X
X
/* This is a subprocedure of ChartInDaySearch(). Print the interpretation    */
/* for a particular instance of the various exciting events that can happen. */
X
void InterpretInDay(source, aspect, dest)
int source, aspect, dest;
{
X  char sz[cchSzDef*2];
X
X  if (source > cObjInt || dest > cObjInt)
X    return;
X
X  /* Interpret object changing direction. */
X
X  if (aspect == aDir) {
X    AnsiColor(kObjA[source]);
X    FieldWord("Energy representing"); FieldWord(szMindPart[source]);
X    FieldWord("will tend to manifest in");
X    FieldWord(dest ? "an independent, backward, introverted" :
X      "the standard, direct, open");
X    FieldWord("manner.");
X    FieldWord(NULL);
X
X  /* Interpret object entering new sign. */
X
X  } else if (aspect == aSig) {
X    AnsiColor(kObjA[source]);
X    FieldWord("Energy representing"); FieldWord(szMindPart[source]);
X    sprintf(sz, "will be %s,", szDesc[dest]);
X    FieldWord(sz);
X    sprintf(sz, "and it %s.", szDesire[dest]); FieldWord(sz);
X    FieldWord(NULL);
X
X  /* Interpret aspect between transiting planets. */
X
X  } else if (aspect > 0 && aspect <= cAspectInt) {
X    AnsiColor(kAspA[aspect]);
X    FieldWord("Energy representing"); FieldWord(szMindPart[source]);
X    sprintf(sz, szInteract[aspect], szModify[1][aspect-1]);
X    FieldWord(sz);
X    sprintf(sz, "energies of %s.", szMindPart[dest]); FieldWord(sz);
X    if (szTherefore[aspect][0]) {
X      if (aspect > aCon) {
X        sprintf(sz, "%s.", szTherefore[aspect]); FieldWord(sz);
X      } else
X        FieldWord("They will affect each other prominently.");
X    }
X    FieldWord(NULL);
X  }
}
X
X
/* This is a subprocedure of ChartTransitSearch(). Print the interpretation */
/* for a particular transit of a planet to a natal object of a chart.       */
X
void InterpretTransit(source, aspect, dest)
int source, aspect, dest;
{
X  char sz[cchSzDef*2];
X
X  if (source <= oCore && dest <= oCore && aspect <= cAspectInt) {
X    AnsiColor(kAspA[aspect]);
X    FieldWord("Energy representing"); FieldWord(szMindPart[source]);
X    sprintf(sz, szInteract[aspect], szModify[1][aspect-1]);
X    FieldWord(sz);
X    if (source != dest) {
X      sprintf(sz, "%s's %s.", szPerson0, szMindPart[dest]);
X    } else {
X      sprintf(sz, "the same aspect inside %s's makeup.", szPerson0);
X    }
X    FieldWord(sz);
X    if (szTherefore[aspect][0]) {
X      if (aspect > aCon) {
X        sprintf(sz, "%s.", szTherefore[aspect]); FieldWord(sz);
X      } else
X        FieldWord("This part of their psyche will be strongly influenced.");
X    }
X    FieldWord(NULL);
X  }
}
X
X
/* Print the interpretation of one person's planet in another's sign and    */
/* house, in a synastry chart as specified with the -r switch combined with */
/* -I. This is very similar to the interpretation of the standard -v chart  */
/* in InterpretLocation(), but we treat the chart as a relationship here.   */
X
void InterpretSynastry()
{
X  char sz[cchSzDef*2], c;
X  int i, j;
X
X  PrintL();
X  for (i = 1; i <= cObjInt; i++) {
X    if (ignore[i] || FCusp(i))
X      continue;
X    AnsiColor(kObjA[i]);
X    j = SFromZ(planet[i]); c = Dignify(i, j);
X    sprintf(sz, "%s%s%s%s in %s,", ret[i] < 0.0 ? "Retrograde " : "",
X      i == oNod ? "North " : (i == oFor ? "Part of " : ""), szObjName[i],
X      i == 13 ? " Athena" : "", szSignName[j]);
X    FieldWord(sz);
X    sprintf(sz, "in their %d%s House:", inhouse[i], szSuffix[inhouse[i]]);
X    FieldWord(sz);
X    sprintf(sz, "%s's", szPerson2); FieldWord(sz);
X    FieldWord(szMindPart[i]); FieldWord("is");
X    if (((int)planet[i]) % 30 < 10)
X      FieldWord("very");
X    sprintf(sz, "%s, and", szDesc[j]); FieldWord(sz);
X    sprintf(sz, "%s.", szDesire[j]); FieldWord(sz);
X    FieldWord("This");
X    if (ret[i] < 0.0 && i != oNod)
X      FieldWord(
X        "manifests in an independent, backward, introverted manner, and");
X    sprintf(sz, "affects %s in the area of life dealing with %s.",
X      szPerson1, szLifeArea[inhouse[i]]); FieldWord(sz);
X
X    /* Extra information if planet is in its ruling, falling, etc, sign. */
X
X    if (c == 'R') {
X      sprintf(sz, "This is a major aspect of %s's psyche!", szPerson2);
X      FieldWord(sz);
X    } else if (c == 'F') {
X      sprintf(sz, "(This bit plays only a minor part in %s's psyche.)",
X        szPerson2);
X      FieldWord(sz);
X    } else if (c == 'e') {
X      sprintf(sz, "%s is affected harmoniously in this way.", szPerson1);
X      FieldWord(sz);
X    } else if (c == 'd') {
X      sprintf(sz, "%s is affected discordantly in this way.", szPerson1);
X      FieldWord(sz);
X    }
X    FieldWord(NULL);
X  }
}
X
X
/* Print an interpretation for a particular aspect in effect in a comparison */
/* relationship chart. This is called from the InterpretGridRelation and     */
/* the ChartAspectRelation routines.                                         */
X
void InterpretAspectRelation(x, y)
int x, y;
{
X  char sz[cchSzDef*2];
X  int n;
X
X  n = grid->n[y][x];
X  if (n < 1 || n > cAspectInt ||
X    FCusp(x) || FCusp(y) || x > cObjInt || y > cObjInt)
X    return;
X  AnsiColor(kAspA[n]);
X  sprintf(sz, "%s %s %s: %s's", szObjName[x],
X    szAspectName[n], szObjName[y], szPerson1);
X  FieldWord(sz); FieldWord(szMindPart[x]);
X  sprintf(sz, szInteract[n],
X    szModify[Min(abs(grid->v[y][x])/150, 2)][n-1]);
X  FieldWord(sz);
X  sprintf(sz, "%s's %s.", szPerson2, szMindPart[y]); FieldWord(sz);
X  if (szTherefore[n][0]) {
X    if (n != 1) {
X      sprintf(sz, "%s.", szTherefore[n]); FieldWord(sz);
X    } else
X      FieldWord("These parts affect each other prominently.");
X  }
X  FieldWord(NULL);
}
X
X
/* Print the interpretation of each aspect in the relationship aspect grid, */
/* as specified with the -r0 -g -I switch combination.                      */
X
void InterpretGridRelation()
{
X  int i, j;
X
X  for (i = 1; i <= cObjInt; i++) if (!ignore[i])
X    for (j = 1; j <= cObjInt; j++) if (!ignore[j])
X      InterpretAspectRelation(i, j);
}
X
X
/* Print the interpretation of a midpoint in the relationship grid, as */
/* specified with the -r0 -m -I switch combination.                    */
X
void InterpretMidpointRelation(x, y)
int x, y;
{
X  char sz[cchSzDef*2];
X  int n;
X
X  if (FCusp(x) || FCusp(y) || x > cObjInt || y > cObjInt)
X    return;
X  n = grid->n[y][x];
X  AnsiColor(kSignA(n));
X  sprintf(sz, "%s midpoint %s in %s: The merging of %s's",
X    szObjName[x], szObjName[y], szSignName[n], szPerson1);
X  FieldWord(sz); FieldWord(szMindPart[x]);
X  sprintf(sz, "with %s's", szPerson2); FieldWord(sz);
X  FieldWord(szMindPart[y]); FieldWord("is");
X  if (grid->v[y][x]/60 < 10)
X    FieldWord("very");
X  sprintf(sz, "%s, and", szDesc[n]); FieldWord(sz);
X  sprintf(sz, "%s.", szDesire[n]); FieldWord(sz);
X  if (cp1.dir[x]+cp2.dir[y] < 0.0 && x != oNod && y != oNod) {
X    FieldWord("Most often this manifests in");
X    FieldWord("an independent, backward, introverted manner.");
X  }
X  FieldWord(NULL);
}
#endif /* INTERPRET */
X
X
/*
******************************************************************************
** Chart Influence Routines.
******************************************************************************
*/
X
/* This is a subprocedure of ChartInfluence(). Based on the values in the */
/* array parameter 'value', store numbers in array 'rank' reflecting the  */
/* relative order, e.g. value[x] 2nd greatest array value -> rank[x] = 2. */
X
void SortRank(value, rank, size)
real *value;
int *rank, size;
{
X  int h, i, j, k;
X
X  value[0] = -1.0;
X  for (i = 1; i <= size; i++)
X    rank[i] = -1;
X  for (h = 1, i = 0; h <= size; h++) {
X    if (size != cSign && (ignore[h] || !FThing(h)))
X      continue;
X    i++;
X    k = 0;
X    for (j = 1; j <= size; j++) {
X      if (size != cSign && (ignore[j] || !FThing(j)))
X        continue;
X      if (value[j] > value[k] && rank[j] < 0)
X        k = j;
X    }
X
X    /* 'k' is the current position of the 'i'th place planet. */
X
X    rank[k] = i;
X  }
}
X
X
/* Print out a list of power values and relative rankings, based on the */
/* placements of the planets, and their aspects in the aspect grid, as  */
/* specified with the -j "find influences" switch.                      */
X
void ChartInfluence()
{
X  real power[oNorm+1], power1[oNorm+1], power2[oNorm+1],
X    total, total1, total2, x;
X  int rank[oNorm+1], rank1[oNorm+1], rank2[oNorm+1], i, j, k, l;
X  char sz[cchSzDef], c;
X
X  for (i = 1; i <= oNorm; i++)
X    power1[i] = power2[i] = 0.0;
X  total = total1 = total2 = 0.0;
X
X  /* First, for each object, find its power based on its placement alone. */
X
X  for (i = 1; i <= oNorm; i++) if (!ignore[i] && FThing(i)) {
X    j = SFromZ(planet[i]);
X    power1[i] += rObjInf[i];               /* Influence of planet itself. */
X    power1[i] += rHouseInf[inhouse[i]];    /* Influence of house it's in. */
X    c = Dignify(i, j);
X    switch (c) {
X    case 'R': x = rObjInf[oNorm+1]; break; /* Planets in signs they rule / */
X    case 'e': x = rObjInf[oNorm+2]; break; /* exalted in have influence.   */
X    default:  x = 0.0;
X    }
X    c = Dignify(i, inhouse[i]);
X    switch (c) {
X    case 'R': x += rHouseInf[cSign+1]; break; /* Item in house aligned with */
X    case 'e': x += rHouseInf[cSign+2]; break; /* sign ruled has influence.  */
X    default: ;
X    }
X    power1[i] += x;
X    if (i != rules[j])                       /* The planet ruling the sign */
X      power1[rules[j]] += rObjInf[i]/2.0;    /* and the house that the     */
X    if (i != (j = rules[inhouse[i]]))        /* current planet is in, gets */
X      power1[j] += rObjInf[i]/2.0;           /* extra influence.           */
X  }
X  for (i = 1; i <= cSign; i++) {         /* Various planets get influence */
X    j = SFromZ(chouse[i]);               /* if house cusps fall in signs  */
X    power1[rules[j]] += rHouseInf[i];    /* they rule.                    */
X  }
X
X  /* Second, for each object, find its power based on aspects it makes. */
X
X  if (!FCreateGrid(fFalse))
X    return;
X  for (j = 1; j <= oNorm; j++) if (!ignore[j] && FThing(j))
X    for (i = 1; i <= oNorm; i++) if (!ignore[i] && FThing(i) && i != j) {
X      k = grid->n[Min(i, j)][Max(i, j)];
X      if (k) {
X        l = grid->v[Min(i, j)][Max(i, j)];
X        power2[j] += rAspInf[k]*rObjInf[i]*
X          (1.0-RAbs((real)l)/60.0/GetOrb(i, j, k));
X      }
X    }
X
X  /* Calculate total power of each planet. */
X
X  for (i = 1; i <= oNorm; i++) if (!ignore[i] && FThing(i)) {
X    power[i] = power1[i]+power2[i]; total1 += power1[i]; total2 += power2[i];
X  }
X  total = total1+total2;
X
X  /* Finally, determine ranks of the arrays, then print everything out. */
X
X  SortRank(power1, rank1, oNorm); SortRank(power2, rank2, oNorm);
X  SortRank(power, rank, oNorm);
X  PrintSz("  Planet:    Position      Aspects    Total Rank  Percent\n");
X  for (i = 1; i <= oNorm; i++) if (!ignore[i] && FThing(i)) {
X    AnsiColor(kObjA[i]);
X    sprintf(sz, "%8.8s: ", szObjName[i]); PrintSz(sz);
X    sprintf(sz, "%6.1f (%2d) +%6.1f (%2d) =%7.1f (%2d) /%6.1f%%\n",
X      power1[i], rank1[i], power2[i], rank2[i], power[i], rank[i],
X      total > 0.0 ? power[i]/total*100.0 : 0.0); PrintSz(sz);
X  }
X  AnsiColor(kDefault);
X  sprintf(sz, "   Total: %6.1f      +%6.1f      =%7.1f      / 100.0%%\n",
X    total1, total2, total); PrintSz(sz);
X
X  /* Now, print out a list of power values and relative rankings, based on  */
X  /* the power of each sign of the zodiac, as indicated by the placement of */
X  /* the planets above, in the chart, as specified with the -j0 switch.     */
X
X  if (!us.fInfluenceSign)
X    return;
X  for (i = 1; i <= cSign; i++)
X    power1[i] = 0.0;
X
X  /* For each sign, determine its power based on the power of the object. */
X
X  for (i = 1; i <= oNorm; i++) if (!ignore[i] && FThing(i)) {
X    power1[SFromZ(planet[i])] += power[i] / 2.0;
X    power1[inhouse[i]]        += power[i] / 4.0;
X    power1[ruler1[i]]         += power[i] / 3.0;
X    if (ruler2[i])
X      power1[ruler2[i]]       += power[i] / 4.0;
X  }
X  if (!fSouthNode && !ignore[oNod]) {
X    power1[Mod12(SFromZ(planet[oNod])+6)] += power[oNod] / 2.0;  /* South */
X    power1[Mod12(inhouse[oNod]+6)]        += power[oNod] / 4.0;  /* Node. */
X  }
X  for (i = cThing+1; i <= oCore; i++) if (!ignore[i]) {
X    power1[SFromZ(planet[i])] += rObjInf[i];
X  }
X
X  total1 = 0.0;
X  for (i = 1; i <= cSign; i++)
X    total1 += power1[i];
X  for (i = 1; i <= cSign; i++) if (total1 > 0.0)
X    power1[i] *= total/total1;
X  total1 = total;
X
X  /* Again, determine ranks in the array, and print everything out. */
X
X  SortRank(power1, rank1, cSign);
X  PrintSz(
X    "\n       Sign:  Power Rank  Percent  -   Element  Power  Percent\n");
X  for (i = 1; i <= cSign; i++) {
X    AnsiColor(kSignA(i));
X    sprintf(sz, "%11.11s: ", szSignName[i]); PrintSz(sz);
X    sprintf(sz, "%6.1f (%2d) /%6.1f%%", power1[i],
X      rank1[i], total1 > 0.0 ? power1[i]/total1*100.0 : 0.0); PrintSz(sz);
X    if (i <= 4) {
X      sprintf(sz, "  -%9.7s:", szElem[i-1]); PrintSz(sz);
X      total2 = 0.0;
X      for (j = 1; j < cSign; j += 4)
X        total2 += power1[i-1+j];
X      sprintf(sz, "%7.1f /%6.1f%%", total2,
X        total1 > 0.0 ? total2/total1*100.0 : 0.0); PrintSz(sz);
X    } else if (i == 6) {
X      AnsiColor(kDefault);
X      PrintSz("  -      Mode  Power  Percent");
X    } else if (i >= 7 && i <= 9) {
X      AnsiColor(kModeA(i-7));
X      sprintf(sz, "  -%9.8s:", szMode[i-7]); PrintSz(sz);
X      total2 = 0.0;
X      for (j = 1; j < cSign; j += 3)
X        total2 += power1[i-7+j];
X      sprintf(sz, "%7.1f /%6.1f%%", total2,
X        total1 > 0.0 ? total2/total1*100.0 : 0.0); PrintSz(sz);
X    }
X    PrintL();
X  }
X  AnsiColor(kDefault);
X  sprintf(sz, "      Total:%7.1f      / 100.0%%\n", total1); PrintSz(sz);
}
X
/* intrpret.c */
SHAR_EOF
  $shar_touch -am 1223232998 'intrpret.c' &&
  chmod 0644 'intrpret.c' ||
  echo 'restore of intrpret.c failed'
  shar_count="`wc -c < 'intrpret.c'`"
  test 22619 -eq "$shar_count" ||
    echo "intrpret.c: original size 22619, current size $shar_count"
fi
# ============= io.c ==============
if test -f 'io.c' && test X"$1" != X"-c"; then
  echo 'x - skipping io.c (File already exists)'
else
  echo 'x - extracting io.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'io.c' &&
/*
** Astrolog (Version 5.40) File: io.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
/*
******************************************************************************
** File IO Routines.
******************************************************************************
*/
X
/* Open the file indicated by the given string and return the file's stream */
/* pointer, or NULL if the file couldn't be found or opened. All parts of   */
/* the program which open files to read call this routine. We look in       */
/* several various locations and directories for the file before giving up. */
X
FILE *FileOpen(szFile, nFileMode)
char *szFile;
int nFileMode;
{
X  FILE *file;
X  char name[cchSzDef], mode[3];
#ifdef ENVIRON
X  char *env;
#endif
X
X  /* Some file types we want to open as binary instead of Ascii. */
X  sprintf(mode, "r%s", nFileMode == 2 ? "b" : "");
X
X  /* First look for the file in the current directory. */
X  file = fopen(szFile, mode);
X  if (file != NULL)
X    return file;
X
#ifdef ENVIRON
X  /* Next look for the file in the directory indicated by the version */
X  /* specific system environment variable.                            */
X  sprintf(name, "%s%s", ENVIRONVER, szVersionCore);
X  env = getenv(name);
X  if (env && *env) {
X    sprintf(name, "%s%c%s", env, chDirSep, szFile);
X    file = fopen(name, mode);
X    if (file != NULL)
X      return file;
X  }
X
X  /* Next look in the directory in the general environment variable. */
X  env = getenv(ENVIRONALL);
X  if (env && *env) {
X    sprintf(name, "%s%c%s", env, chDirSep, szFile);
X    file = fopen(name, mode);
X    if (file != NULL)
X      return file;
X  }
X
X  /* Next look in the directory in the version prefix environment variable. */
X  env = getenv(ENVIRONVER);
X  if (env && *env) {
X    sprintf(name, "%s%c%s", env, chDirSep, szFile);
X    file = fopen(name, mode);
X    if (file != NULL)
X      return file;
X  }
#endif
X
X  /* Finally look in one of several directories specified at compile time. */
X  sprintf(name, "%s%c%s", nFileMode == 0 ? DEFAULT_DIR :
X    (nFileMode == 1 ? CHART_DIR : EPHE_DIR), chDirSep, szFile);
X  file = fopen(name, mode);
X  if (file == NULL && nFileMode == 1) {
X    /* If the file was never found, print an error (unless we were looking */
X    /* for a certain file type, e.g. the optional astrolog.dat file).      */
X    sprintf(name, "File '%s' not found.", szFile);
X    PrintError(name);
X  }
X  return file;
}
X
X
/* This is Astrolog's generic file processing routine, which handles chart */
/* info files, position files, and config files. Given a file name or a    */
/* file handle, run through each line as a series of command switches.     */
X
bool FProcessSwitchFile(szFile, file)
char *szFile;
FILE *file;
{
X  char szLine[cchSzMax], *argv[MAXSWITCHES], ch;
X  int argc, i;
X
X  if (file == NULL)
X    file = FileOpen(szFile, 0);
X  if (file == NULL)
X    return fFalse;
X
X  /* All files have to begin with the -@ switch file type identifier. */
X  ch = getc(file); ungetc(ch, file);
X  if (ch != '@') {
X    sprintf(szLine,
X      "The command file '%s' is not in any valid format (character %d).",
X      szFile, (int)ch);
X    PrintWarning(szLine);
X    return fFalse;
X  }
X
X  loop {
X    while (!feof(file) && (ch = getc(file)) < ' ')
X      ;
X    if (feof(file))
X      break;
X    for (szLine[0] = ch, i = 1; i < cchSzMax && !feof(file) &&
X      (szLine[i] = getc(file)) >= ' '; i++)
X      ;
X    szLine[i] = chNull;
X    argc = NParseCommandLine(szLine, argv);
X    if (!FProcessSwitches(argc, argv))
X      return fFalse;
X  }
X  return fTrue;
}
X
X
/* Take the current chart information, and write it out to the file   */
/* as indicated by the -o switch. This is only executed at the end of */
/* program execution if the -o switch is in effect.                   */
X
bool FOutputData()
{
X  char sz[cchSzDef];
X  FILE *file;
X  int i, j;
X  real rT;
X
X  if (us.fNoWrite)
X    return fFalse;
X  file = fopen(is.szFileOut, "w");  /* Create and open the file for output. */
X  if (file == NULL) {
X    sprintf(sz, "File %s can not be created.", is.szFileOut);
X    PrintError(sz);
X    return fFalse;
X  }
X  if (!us.fWritePos) {
X
X    /* Write the chart information to the file. */
X
X    if (Mon < 1) {
X      fclose(file);
X      PrintError("Can't output chart with no time/space to file.");
X      return fFalse;
X    }
X    if (us.fWriteOld) {
X      fprintf(file, "%d\n%d\n%d\n%.2f\n%.2f\n%.2f\n%.2f\n",
X        Mon, Day, Yea, Tim, Zon-Dst, Lon, Lat);
X    } else {
X      fprintf(file, "@0102  ; %s chart info.\n", szAppName);
X      i = us.fAnsiChar;
X      us.fAnsiChar = fFalse;
X      fprintf(file, "%cqb %c%c%c %d %d %s %s %s %s\n", chSwitch, chMon3(Mon),
X        Day, Yea, SzTim(Tim), Dst == 0.0 ? "ST" : (Dst == 1.0 ? "DT" :
X        SzZone(Dst)), SzZone(-Zon), SzLocation(Lon, Lat));
X      fprintf(file, "%czi \"%s\" \"%s\"\n", chSwitch, ciMain.nam, ciMain.loc);
X      us.fAnsiChar = i;
X    }
X  } else {
X
X    /* However, if the -o0 switch is in effect, then write the actual */
X    /* positions of the planets and houses to the file instead.       */
X
X    if (us.fWriteOld) {
X      for (i = 1; i <= oNorm; i++) {
X        j = (int)planet[i];
X        fprintf(file, "%c%c%c: %2d %2d %10.7f\n", chObj3(i),
X          j%30, j/30+1, RFract(planet[i])*60.0);              /* Position */
X        rT = planetalt[i];
X        fprintf(file, "[%c]: %3d %12.8f\n",                   /* Altitude */
X          ret[i] >= 0.0 ? 'D' : chRet, (int)(RSgn(rT)*
X          RFloor(RAbs(rT))), (rT-(real)(int)rT)*60.0);     /* Retrograde? */
X        if (i == oNod)
X          i = oFor-1;
X        else if (i == oFor)
X          i = oMC -1;
X        else if (i == oMC)
X          i = oAsc-1;
X        else if (i == oAsc)
X          i = oVtx-1;
X        else if (i == oVtx)    /* Skip minor cusps to write uranians  */
X          i = us.fUranian ? uranLo-1 : cObj;
X      }
X      for (i = 1; i <= cSign/2; i++) {   /* Write first six cusp positions */
X        j = (int)chouse[i];
X        fprintf(file, "H_%c: %2d %2d %10.7f\n",
X          'a'+i-1, j%30, j/30+1, RFract(chouse[i])*60.0);
X      }
X
X    } else {
X      fprintf(file, "@0203  ; %s chart positions.\n", szAppName);
X      fprintf(file, "%czi \"%s\" \"%s\"\n", chSwitch, ciMain.nam, ciMain.loc);
X      for (i = 1; i <= cObj; i++) if (!ignore[i] || FCusp(i)) {
X        fprintf(file, "%cYF ", chSwitch);
X        if (i <= oNorm)
X          fprintf(file, "%c%c%c", chObj3(i));
X        else
X          fprintf(file, "%3d", i);
X        rT = FBetween(i, cuspLo-1+4, cuspLo-1+9) ?
X          chouse[i-(cuspLo-1)] : planet[i];
X        j = (int)rT;
X        fprintf(file, ":%3d %c%c%c%13.9f,%4d%13.9f,",
X          j%30, chSig3(j/30+1), RFract(rT)*60.0,
X          (int)planetalt[i], RFract(RAbs(planetalt[i]))*60.0);
X        rT = i > oNorm ? 999.0 : (i == oMoo && !us.fPlacalc ? 0.0026 :
X          RSqr(spacex[i]*spacex[i]+spacey[i]*spacey[i]+spacez[i]*spacez[i]));
X        fprintf(file, "%14.9f%14.9f\n", DFromR(ret[i]), rT);
X      }
X    }
X  }
X
X  /* Now write any extra strings that were on the command line after the -o */
X  /* specification but before the next switch, to the file as comments.     */
X
X  for (i = 1; i < is.cszComment; i++) {
X    is.rgszComment++;
X    fprintf(file, "%s%s\n", us.fWriteOld ? "" : "; ", is.rgszComment[1]);
X  }
X  fclose(file);
X  return fTrue;
}
X
X
/*
******************************************************************************
** User Input Routines.
******************************************************************************
*/
X
/* Given a string, return an index number corresponding to what the string */
/* indicates, based on a given parsing mode. In most cases this is mainly  */
/* looking up a string in the appropriate array and returning the index.   */
X
int NParseSz(szEntry, pm)
char *szEntry;
int pm;
{
X  char szLocal[cchSzMax], *sz, ch0, ch1, ch2;
X  int cch, n, i;
X
X  /* First strip off any leading or trailing spaces. */
X  for (cch = 0; szLocal[cch] = szEntry[cch]; cch++)
X    ;
X  while (cch && szLocal[cch-1] <= ' ')
X    szLocal[--cch] = chNull;
X  for (sz = szLocal; *sz && *sz <= ' '; sz++, cch--)
X    ;
X
X  if (cch >= 3) {
X    ch0 = ChCap(sz[0]); ch1 = ChUncap(sz[1]); ch2 = ChUncap(sz[2]);
X    switch (pm) {
X    /* Parse months, e.g. "February" or "Feb" -> 2 for February. */
X    case pmMon:
X      for (i = 1; i <= cSign; i++) {
X        if (ch0 == szMonth[i][0] && ch1 == szMonth[i][1] &&
X          ch2 == szMonth[i][2])
X          return i;
X      }
X      break;
X    /* Parse planets, e.g. "Jupiter" or "Jup" -> 6 for Jupiter. */
X    case pmObject:
X      for (i = 1; i <= cObj; i++) {
X        if (ch0 == szObjName[i][0] && ch1 == szObjName[i][1] &&
X          ch2 == szObjName[i][2])
X          return i;
X      }
X      if (ch0 == 'L' && ch1 == 'i' && ch2 == 'l')
X        return oLil;
X      if (ch0 == 'S' && ch1 == '.' && ch2 == 'n')
X        return oSou;
X      break;
X    /* Parse aspects, e.g. "Conjunct" or "Con" -> 1 for the Conjunction. */
X    case pmAspect:
X      for (i = 1; i <= cAspect; i++) {
X        if (ch0 == szAspectAbbrev[i][0] &&
X          ch1 == ChUncap(szAspectAbbrev[i][1]) &&
X          ch2 == szAspectAbbrev[i][2])
X          return i;
X      }
X      break;
X    /* Parse house systems, e.g. "Koch" or "Koc" -> 1 for Koch houses. */
X    case pmSystem:
X      for (i = 1; i <= cSystem; i++) {
X        if (ch0 == szSystem[i][0] && ch1 == szSystem[i][1] &&
X          ch2 == szSystem[i][2])
X          return i;
X      }
X    /* Parse zodiac signs, e.g. "Scorpio" or "Sco" -> 8 for Scorpio. */
X    case pmSign:
X      for (i = 1; i <= cSign; i++) {
X        if (ch0 == szSignName[i][0] && ch1 == szSignName[i][1] &&
X          ch2 == szSignName[i][2])
X          return i;
X      }
X    /* Parse colors, e.g. "White" or "Whi" -> 15 for White. */
X    case pmColor:
X      for (i = 0; i < cColor; i++) {
X        if (ch0 == szColor[i][0] && ch1 == szColor[i][1] &&
X          ch2 == ChUncap(szColor[i][2]))
X          return i;
X      }
X    }
X  }
X  n = atoi(sz);
X
X  if (pm == pmYea) {
X    /* For years, process any "BC" (or "B.C.", "b.c", and variations) and   */
X    /* convert an example such as "5BC" to -4. For negative years, note the */
X    /* difference of one, as 1AD was preceeded by 1BC, with no year zero.   */
X    i = Max(cch-1, 0);
X    if (i && sz[i] == '.')
X      i--;
X    if (i && ChCap(sz[i]) == 'C')
X      i--;
X    if (i && sz[i] == '.')
X      i--;
X    if (i && ChCap(sz[i]) == 'B')
X      n = 1 - n;
X  }
X  return n;
}
X
X
/* Given a string, return a floating point number corresponding to what the  */
/* string indicates, based on a given parsing mode, like above for integers. */
X
real RParseSz(szEntry, pm)
char *szEntry;
int pm;
{
X  char szLocal[cchSzMax], *sz, *pch, ch;
X  int cch, i, f = fFalse;
X  real r;
X
X  /* First strip off any leading or trailing spaces. */
X  for (cch = 0; szLocal[cch] = szEntry[cch]; cch++)
X    ;
X  while (cch && szLocal[cch-1] <= ' ')
X    szLocal[--cch] = chNull;
X  for (sz = szLocal; *sz && *sz <= ' '; sz++, cch--);
X    ;
X  /* Capitalize all letters and make colons be periods to be like numbers. */
X  for (pch = sz; *pch; pch++) {
X    ch = *pch;
X    if (ch == ':')
X      ch = '.';
X    else
X      ch = ChCap(ch);
X    *pch = ch;
X  }
X  ch = sz[0];
X
X  if (pm == pmTim) {
X    /* For times, process "Noon" and "Midnight" (or just "N" and "M"). */
X    if (ch == 'N')
X      return 12.0;
X    else if (ch == 'M')
X      return 0.0;
X  } else if (pm == pmDst) {
X    /* For the Daylight time flag, "Daylight", "Yes", and "True" (or just */
X    /* their first characters) are all indications to be ahead one hour.  */
X    if (ch == 'D' || ch == 'Y' || ch == 'T')
X      return 1.0;
X    /* "Standard", "No", and "False" mean the normal zero offset. */
X    else if (ch == 'S' || ch == 'N' || ch == 'F')
X      return 0.0;
X  } else if (pm == pmZon) {
X    /* For time zones, see if the abbrev is in a table, e.g. "EST" -> 5. */
X    for (i = 0; i < cZone; i++)
X      if (NCompareSz(sz, szZon[i]) == 0)
X        return rZon[i];
X  } else if (pm == pmLon || pm == pmLat) {
X    /* For locations, negate the value for an "E" or "S" in the middle    */
X    /* somewhere (e.g. "105E30" or "27:40S") for eastern/southern values. */
X    for (i = 0; i < cch; i++) {
X      ch = sz[i];
X      if (FCapCh(ch)) {
X        if (ch == 'E' || ch == 'S')
X          f = fTrue;
X        sz[i] = '.';
X        i = cch;
X      }
X    }
X    ch = sz[0];
X  }
X
X  /* Anything still at this point should be in a numeric format. */
X  if (!FNumCh(ch) && ch != '+' && ch != '-' && ch != '.')
X    return rLarge;
X  r = (f ? -1.0 : 1.0) * atof(sz);
X
X  if (pm == pmTim) {
X    /* Backtrack over any time suffix, e.g. "AM", "p.m." and variations. */
X    i = Max(cch-1, 0);
X    if (i && sz[i] == '.')
X      i--;
X    if (i && sz[i] == 'M')
X      i--;
X    if (i && sz[i] == '.')
X      i--;
X    if (i) {
X      ch = sz[i];
X      if (ch == 'A')                   /* Adjust value appropriately */
X        r = r >= 12.0 ? r-12.0 : r;    /* if AM or PM suffix.        */
X      else if (ch == 'P')
X        r = r >= 12.0 ? r : r+12.0;
X    }
X  }
X  return r;
}
X
X
/* Stop and wait for the user to enter a line of text given a prompt to */
/* display and a string buffer to fill with it.                         */
X
void InputString(szPrompt, sz)
char *szPrompt, *sz;
{
X  FILE *file;
X  int cch;
X
X  file = is.S; is.S = stdout;
X  PrintSz(szPrompt);
X  AnsiColor(kYellow);
X  PrintSz(" > ");
X  AnsiColor(kDefault);
X  if (fgets(sz, cchSzMax, stdin) == NULL)  /* Pressing control-D terminates */
X    Terminate(tcForce);                    /* the program on some machines. */
X  cch = CchSz(sz);
X  while (cch > 0 && sz[cch-1] < ' ')
X    cch--;
X  sz[cch] = chNull;
X  is.S = file;
X  is.cchCol = 0;
}
X
X
/* Prompt the user for a floating point value, parsing as appropriate, and */
/* make sure it conforms to the specified bounds before returning it.      */
X
int NInputRange(szPrompt, low, high, pm)
char *szPrompt;
int low, high;
int pm;
{
X  char szLine[cchSzDef];
X  int n;
X
X  loop {
X    InputString(szPrompt, szLine);
X    n = NParseSz(szLine, pm);
X    if (FBetween(n, low, high))
X      return n;
X    sprintf(szLine, "Value %d out of range from %d to %d.", n, low, high);
X    PrintWarning(szLine);
X  }
}
X
X
/* This is identical to above except it takes/returns floating point values. */
X
real RInputRange(szPrompt, low, high, pm)
char *szPrompt;
real low, high;
int pm;
{
X  char szLine[cchSzDef];
X  real r;
X
X  loop {
X    InputString(szPrompt, szLine);
X    r = RParseSz(szLine, pm);
X    if (FBetween(r, low, high))
X      return r;
X    sprintf(szLine, "Value %.0f out of range from %.0f to %.0f.",
X      r, low, high);
X    PrintWarning(szLine);
X  }
}
X
X
/* This important procedure gets all the parameters defining the chart that  */
/* will be worked with later. Given a "filename", it gets from it all the    */
/* pertinent chart information. This is more than just reading from a file - */
/* the procedure also takes care of the cases of prompting the user for the  */
/* information and using the time functions to determine the date now - the  */
/* program considers these cases "virtual" files. Furthermore, when reading  */
/* from a real file, we have to check if it was written in the -o0 format.   */
X
bool FInputData(szFile)
char *szFile;
{
X  FILE *file;
X  char sz[cchSzDef], ch;
X  int i, fT;
X  real k, l, m;
X
X  /* If we are to read from the virtual file "nul" that means to leave the */
X  /* chart information alone with whatever settings it may have already.   */
X
X  if (NCompareSz(szFile, szNulCore) == 0) {
X    is.fHaveInfo = fTrue;
X    return fTrue;
X  }
X
X  /* If we are to read from the virtual file "set" then that means use a   */
X  /* particular set of chart information generated earlier in the program. */
X
X  if (NCompareSz(szFile, szSetCore) == 0) {
X    is.fHaveInfo = fTrue;
X    ciCore = ciSave;
X    return fTrue;
X  }
X
#ifdef TIME
X  /* If we are to read from the file "now" then that means use the time */
X  /* functions to calculate the present date and time.                  */
X
X  if (NCompareSz(szFile, szNowCore) == 0) {
X    is.fHaveInfo = fTrue;
X    SS = us.dstDef; ZZ = us.zonDef; OO = us.lonDef; AA = us.latDef;
X    GetTimeNow(&MM, &DD, &YY, &TT, ZZ-SS);
X    ciCore.nam = ciCore.loc = "";
X    return fTrue;
X  }
#endif
X
#ifndef WIN
X  /* If we are to read from the file "tty" then that means prompt the user */
X  /* for all the chart information.                                        */
X
X  if (NCompareSz(szFile, szTtyCore) == 0) {
X    file = is.S; is.S = stdout;
X    if (!us.fNoSwitches) {
X      /* Temporarily disable an internal redirection of output to a file  */
X      /* because we always want user headers and prompts to be displayed. */
X
X      AnsiColor(kWhite);
X      sprintf(sz, "** %s version %s ", szAppName, szVersionCore); PrintSz(sz);
X      sprintf(sz, "(See '%cHc' switch for copyrights and credits.) **\n",
X        chSwitch); PrintSz(sz);
X      AnsiColor(kDefault);
X      sprintf(sz, "   Invoke as '%s %cH' for list of command line options.\n",
X        ProcessProgname(is.szProgName), chSwitch); PrintSz(sz);
X    }
X
X    MM = NInputRange("Enter month for chart (e.g. '8' 'Aug')",
X      1, 12, pmMon);
X    DD = NInputRange("Enter day   for chart (e.g. '1' '31') ",
X      1, DayInMonth(MM, 0), pmDay);
X    YY = NInputRange("Enter year  for chart (e.g. '1995')   ",
X      -5000, 5000, pmYea);
X    if (FBetween(YY, 0, 99)) {
X      sprintf(sz,
X        "Assuming first century A.D. is really meant instead of %d.",
X        1900 + YY);
X      PrintWarning(sz);
X    }
X    TT = RInputRange("Enter time  for chart (e.g. '18:30' '6:30pm')  ",
X      -2.0, 24.0, pmTim);
X    SS = us.fWriteOld ? 0.0 :
X      RInputRange("Enter if Daylight time in effect (e.g. 'y' '1')",
X      -24.0, 24.0, pmDst);
X    ZZ = RInputRange("Enter time zone (e.g. '5' 'ET' for Eastern)    ",
X      -24.0, 24.0, pmZon);
X    if ((int)(RFract(ZZ) * 100.0 + rRound) == 50) {
X      PrintWarning(
X        "Assuming unusual zone of 50 minutes after the hour instead of 30.");
X    }
X    OO = RInputRange("Enter Longitude of place (e.g. '122W20')",
X      -rDegHalf, rDegHalf, pmLon);
X    AA = RInputRange("Enter Latitude  of place (e.g. '47N36') ",
X      -rDegQuad, rDegQuad, pmLat);
X    if (!us.fWriteOld) {
X      InputString("Enter name or title for chart ", sz);
X      ciCore.nam = SzPersist(sz);
X      InputString("Enter name of city or location", sz);
X      ciCore.loc = SzPersist(sz);
X    }
X    PrintL();
X    is.cchRow = 0;
X    is.S = file;
X    return fTrue;
X  }
#endif /* WIN */
X
X  /* Now that the special cases are taken care of, we can assume we are */
X  /* to read from a real file.                                          */
X
X  file = FileOpen(szFile, 1);
X  if (file == NULL)
X    return fFalse;
X  is.fHaveInfo = fTrue;
X  ch = getc(file); ungetc(ch, file);
X
X  /* Read the chart parameters from a standard command switch file. */
X
X  if (ch == '@') {
X    fT = is.fSzPersist; is.fSzPersist = fFalse;
X    if (!FProcessSwitchFile(szFile, file))
X      return fFalse;
X    is.fSzPersist = fT;
X
X  /* Read the chart info from an older style -o list of seven numbers. */
X
X  } else if (FNumCh(ch)) {
X    SS = 0.0;
X    fscanf(file, "%d%d%d", &MM, &DD, &YY);
X    fscanf(file, "%lf%lf%lf%lf", &TT, &ZZ, &OO, &AA);
X    if (!FValidMon(MM) || !FValidDay(DD, MM, YY) || !FValidYea(YY) ||
X      !FValidTim(TT) || !FValidZon(ZZ) || !FValidLon(OO) || !FValidLat(AA)) {
X      PrintWarning("Values in old style chart info file are out of range.");
X      return fFalse;
X    }
X
X  /* Read the actual chart positions from a file produced with the -o0. */
X
X  } else if (ch == 'S') {
X    MM = -1;
X
X    /* Hack: A negative month value means the chart parameters are invalid, */
X    /* hence -o0 is in effect and we can assume the chart positions are     */
X    /* already in memory so we don't have to calculate them later.          */
X
X    for (i = 1; i <= oNorm; i++) {
X      fscanf(file, "%s%lf%lf%lf", sz, &k, &l, &m);
X      planet[i] = Mod((l-1.0)*30.0+k+m/60.0);
X      fscanf(file, "%s%lf%lf", sz, &k, &l);
X      if ((m = k+l/60.0) > rDegHalf)
X        m = rDegMax - m;
X      planetalt[i] = m;
X      ret[i] = RFromD(sz[1] == 'D' ? 1.0 : -1.0);
X
X      /* -o0 files from versions 3.05 and before don't have the uranians in  */
X      /* them. Be prepared to skip over them in old files for compatibility. */
X
X      if (i == oVtx) {
X        while (getc(file) >= ' ')
X          ;
X        if ((ch = getc(file)) != 'H')
X          i = cuspHi;
X        else
X          i = cObj;
X      }
X      if (i == oNod)
X        i = oFor-1;
X      else if (i == oFor)
X        i = oLil-1;
X      else if (i == oLil)
X        i = oEP -1;
X      else if (i == oEP)
X        i = oVtx-1;
X    }
X    for (i = 1; i <= cSign/2; i++) {
X      fscanf(file, "%s%lf%lf%lf", sz, &k, &l, &m);
X      chouse[i+6] = Mod((chouse[i] = Mod((l-1.0)*30.0+k+m/60.0))+rDegHalf);
X    }
X    for (i = 1; i <= cSign; i++)
X      planet[cuspLo-1+i] = chouse[i];
X    planet[oMC] = planet[oLil]; planet[oNad] = Mod(planet[oMC]  + rDegHalf);
X    planet[oAsc] = planet[oEP]; planet[oDes] = Mod(planet[oAsc] + rDegHalf);
X    planet[oSou] = Mod(planet[oNod] + rDegHalf); ret[oSou] = ret[oNod];
X
X  } else {
X    sprintf(sz,
X      "The chart info file is not in any valid format (character %d).",
X      (int)ch);
X    PrintWarning(sz);
X    return fFalse;
X  }
X  fclose(file);
X  return fTrue;
}
X
/* io.c */
SHAR_EOF
  $shar_touch -am 1223232998 'io.c' &&
  chmod 0644 'io.c' ||
  echo 'restore of io.c failed'
  shar_count="`wc -c < 'io.c'`"
  test 22959 -eq "$shar_count" ||
    echo "io.c: original size 22959, current size $shar_count"
fi
# ============= makefile.bgi ==============
if test -f 'makefile.bgi' && test X"$1" != X"-c"; then
  echo 'x - skipping makefile.bgi (File already exists)'
else
  echo 'x - extracting makefile.bgi (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'makefile.bgi' &&
# Astrolog (Version 5.40) File: makefile (PC version)
#
# IMPORTANT NOTICE: The graphics database and chart display routines
# used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
# (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
# Permission is granted to freely use and distribute these routines
# provided one doesn't sell, restrict, or profit from them in any way.
# Modification is allowed provided these notices remain with any
# altered or edited versions of the program.
#
# This Makefile created for Borland Turbo C/C++ compiler.
# First created 8/21/1994.
X
CFLAGS = -ml -Ff=50  -G- -O -r  -w-pia -w-sus
X
CC = tcc
TLINK = tlink
LIBPATH = C:\TC\LIB
name = astrolog
objs = attf.obj cgaf.obj egavgaf.obj hercf.obj ibm8514f.obj pc3270f.obj\
X astrolog.obj data.obj data2.obj general.obj io.obj\
X calc.obj matrix.obj placalc.obj placalc2.obj\
X charts0.obj charts1.obj charts2.obj charts3.obj intrpret.obj\
X xdata.obj xgeneral.obj xdevice.obj\
X xcharts0.obj xcharts1.obj xcharts2.obj xscreen.obj
X
$(name).exe : $(objs)
# We are compiling in Large memory model with 16,384 bytes for stack storage.
X  $(TLINK) /c /x /L$(LIBPATH) @makefile.cfg
#
SHAR_EOF
  $shar_touch -am 1223232998 'makefile.bgi' &&
  chmod 0644 'makefile.bgi' ||
  echo 'restore of makefile.bgi failed'
  shar_count="`wc -c < 'makefile.bgi'`"
  test 1179 -eq "$shar_count" ||
    echo "makefile.bgi: original size 1179, current size $shar_count"
fi
# ============= makefile.cfg ==============
if test -f 'makefile.cfg' && test X"$1" != X"-c"; then
  echo 'x - skipping makefile.cfg (File already exists)'
else
  echo 'x - extracting makefile.cfg (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'makefile.cfg' &&
c0l.obj+
astrolog.obj+
calc.obj+
charts0.obj+
charts1.obj+
charts2.obj+
charts3.obj+
data.obj+
data2.obj+
general.obj+
intrpret.obj+
io.obj+
matrix.obj+
placalc.obj+
placalc2.obj+
xcharts0.obj+
xcharts1.obj+
xcharts2.obj+
xdata.obj+
xdevice.obj+
xgeneral.obj+
xscreen.obj+
attf.obj+
cgaf.obj+
egavgaf.obj+
hercf.obj+
ibm8514f.obj+
pc3270f.obj
astrolog
# no map file
graphics.lib+
emu.lib+
mathl.lib+
cl.lib
#
# Astrolog (Version 5.40) File: makefile.cfg (PC version)
# This Makefile created for Borland Turbo C/C++ compiler.
#
# IMPORTANT NOTICE: The graphics database and chart display routines
# used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
# (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
# Permission is granted to freely use and distribute these routines
# provided one doesn't sell, restrict, or profit from them in any way.
# Modification is allowed provided these notices remain with any
# altered or edited versions of the program.
SHAR_EOF
  $shar_touch -am 1223232998 'makefile.cfg' &&
  chmod 0644 'makefile.cfg' ||
  echo 'restore of makefile.cfg failed'
  shar_count="`wc -c < 'makefile.cfg'`"
  test 984 -eq "$shar_count" ||
    echo "makefile.cfg: original size 984, current size $shar_count"
fi
# ============= makefile.com ==============
if test -f 'makefile.com' && test X"$1" != X"-c"; then
  echo 'x - skipping makefile.com (File already exists)'
else
  echo 'x - extracting makefile.com (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'makefile.com' &&
$ ! Astrolog (Version 5.40) File: makefile.com (VMS version)
$ !
$ ! IMPORTANT NOTICE: The graphics database and chart display routines
$ ! used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
$ ! (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
$ ! Permission is granted to freely use and distribute these routines
$ ! provided one doesn't sell, restrict, or profit from them in any way.
$ ! Modification is allowed provided these notices remain with any
$ ! altered or edited versions of the program.
$ !
$ ! This script originally created by Max Calvani.
$ !
$ set ver
$ define X11 decw$include
$ define lnk$library sys$library:vaxcrtl
$ CC ASTROLOG
$ CC CALC
$ CC CHARTS0
$ CC CHARTS1
$ CC CHARTS2
$ CC CHARTS3
$ CC DATA
$ CC DATA2
$ CC GENERAL
$ CC INTRPRET
$ CC IO
$ CC MATRIX
$ CC PLACALC
$ CC PLACALC2
$ CC XCHARTS0
$ CC XCHARTS1
$ CC XCHARTS2
$ CC XDATA
$ CC XDEVICE
$ CC XGENERAL
$ CC XSCREEN
$ link/exe=astrolog.exe -
X	ASTROLOG.obj, -
X	CALC.obj, -
X	CHARTS0.obj, -
X	CHARTS1.obj, -
X	CHARTS2.obj, -
X	CHARTS3.obj, -
X	DATA.obj, -
X	DATA2.obj, -
X	GENERAL.obj, -
X	INTRPRET.obj, -
X	IO.obj, -
X	MATRIX.obj, -
X	PLACALC.obj, -
X	PLACALC2.obj, -
X	XCHARTS0.obj, -
X	XCHARTS1.obj, -
X	XCHARTS2.obj, -
X	XDATA.obj, -
X	XDEVICE.obj, -
X	XGENERAL.obj, -
X	XSCREEN.obj, -
X	sys$input/opt
sys$share:decw$xlibshr/share
$ set nover
$ exit
SHAR_EOF
  $shar_touch -am 1223232998 'makefile.com' &&
  chmod 0644 'makefile.com' ||
  echo 'restore of makefile.com failed'
  shar_count="`wc -c < 'makefile.com'`"
  test 1352 -eq "$shar_count" ||
    echo "makefile.com: original size 1352, current size $shar_count"
fi
# ============= makefile.msc ==============
if test -f 'makefile.msc' && test X"$1" != X"-c"; then
  echo 'x - skipping makefile.msc (File already exists)'
else
  echo 'x - extracting makefile.msc (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'makefile.msc' &&
# Astrolog (Version 5.40) File: makefile (DOS version)
#
# IMPORTANT NOTICE: The graphics database and chart display routines
# used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
# (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
# Permission is granted to freely use and distribute these routines
# provided one doesn't sell, restrict, or profit from them in any way.
# Modification is allowed provided these notices remain with any
# altered or edited versions of the program.
#
# This Makefile created for Microsoft nmake utility.
# First created 2/9/1993.
#
# Generally, all that needs to be done to compile (once astrolog.h has been
# customized), is compile each source file, and link them together with the
# math library, and if applicable, the Microsoft C graphics library.
#
#If you have a 286 or higher processor, you can add /G2 to the line below.
#if you have a math coprocessor, you can add /FPi to the line below.
CFLAGS = /nologo /AL /Gt50 /W3 /Ox /Os
#CFLAGS = /nologo /AL /Gt50 /W3 /G2 /FPi /Os
X
CC = cl
name = astrolog
objs = astrolog.obj data.obj data2.obj general.obj io.obj\
X calc.obj matrix.obj placalc.obj placalc2.obj\
X charts0.obj charts1.obj charts2.obj charts3.obj intrpret.obj\
X xdata.obj xgeneral.obj xdevice.obj\
X xcharts0.obj xcharts1.obj xcharts2.obj xscreen.obj
X
$(name).exe : $(objs)
# We are compiling in Large memory model with 16,384 bytes for stack storage.
X  $(CC) /F 4000 /o $(name) *.obj graphics.lib
#
SHAR_EOF
  $shar_touch -am 1223232998 'makefile.msc' &&
  chmod 0644 'makefile.msc' ||
  echo 'restore of makefile.msc failed'
  shar_count="`wc -c < 'makefile.msc'`"
  test 1480 -eq "$shar_count" ||
    echo "makefile.msc: original size 1480, current size $shar_count"
fi
# ============= makefile.win ==============
if test -f 'makefile.win' && test X"$1" != X"-c"; then
  echo 'x - skipping makefile.win (File already exists)'
else
  echo 'x - extracting makefile.win (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'makefile.win' &&
# Microsoft Visual C++ generated build script - Do not modify
X
PROJ = ASTROLOG
DEBUG = 0
PROGTYPE = 0
CALLER = 
ARGS = 
DLLS = 
D_RCDEFINES = /d_DEBUG 
R_RCDEFINES = /dNDEBUG 
ORIGIN = MSVC
ORIGIN_VER = 1.00
PROJPATH = C:\AST\
USEMFC = 0
CC = cl
CPP = cl
CXX = cl
CCREATEPCHFLAG = 
CPPCREATEPCHFLAG = 
CUSEPCHFLAG = 
CPPUSEPCHFLAG = 
FIRSTC = ASTROLOG.C  
FIRSTCPP =             
RC = rc
CFLAGS_D_WEXE = /nologo /G2 /W3 /Zi /AL /Gt50 /Gx- /Od /D "_DEBUG" /FR /GA /Fd"ASTROLOG.PDB"
CFLAGS_R_WEXE = /nologo /W3 /Gf /AL /Gt50 /Gx- /O2 /D "NDEBUG" /FR /GA 
LFLAGS_D_WEXE = /NOLOGO /NOD /PACKC:61440 /STACK:11264 /ALIGN:16 /ONERROR:NOEXE /CO  
LFLAGS_R_WEXE = /NOLOGO /NOD /PACKC:61440 /STACK:11264 /ALIGN:16 /ONERROR:NOEXE  
LIBS_D_WEXE = oldnames libw llibcew commdlg.lib olecli.lib olesvr.lib shell.lib 
LIBS_R_WEXE = oldnames libw llibcew commdlg.lib olecli.lib olesvr.lib shell.lib 
RCFLAGS = /nologo 
RESFLAGS = /nologo /k
RUNFLAGS = 
DEFFILE = ASTROLOG.DEF
OBJS_EXT = 
LIBS_EXT = 
!if "$(DEBUG)" == "1"
CFLAGS = $(CFLAGS_D_WEXE)
LFLAGS = $(LFLAGS_D_WEXE)
LIBS = $(LIBS_D_WEXE)
MAPFILE = nul
RCDEFINES = $(D_RCDEFINES)
!else
CFLAGS = $(CFLAGS_R_WEXE)
LFLAGS = $(LFLAGS_R_WEXE)
LIBS = $(LIBS_R_WEXE)
MAPFILE = nul
RCDEFINES = $(R_RCDEFINES)
!endif
!if [if exist MSVC.BND del MSVC.BND]
!endif
SBRS = ASTROLOG.SBR \
X		CALC.SBR \
X		CHARTS0.SBR \
X		CHARTS1.SBR \
X		CHARTS2.SBR \
X		CHARTS3.SBR \
X		DATA.SBR \
X		DATA2.SBR \
X		GENERAL.SBR \
X		INTRPRET.SBR \
X		IO.SBR \
X		MATRIX.SBR \
X		PLACALC.SBR \
X		PLACALC2.SBR \
X		WDIALOG.SBR \
X		WDRIVER.SBR \
X		XCHARTS0.SBR \
X		XCHARTS1.SBR \
X		XCHARTS2.SBR \
X		XDATA.SBR \
X		XDEVICE.SBR \
X		XGENERAL.SBR \
X		XSCREEN.SBR
X
X
ASTROLOG_RCDEP = c:\ast\astrlog2.ico \
X	c:\ast\astrlog3.ico
X
X
all:	$(PROJ).EXE $(PROJ).BSC
X
ASTROLOG.OBJ:	ASTROLOG.C $(ASTROLOG_DEP)
X	$(CC) $(CFLAGS) $(CCREATEPCHFLAG) /c ASTROLOG.C
X
CALC.OBJ:	CALC.C $(CALC_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c CALC.C
X
CHARTS0.OBJ:	CHARTS0.C $(CHARTS0_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c CHARTS0.C
X
CHARTS1.OBJ:	CHARTS1.C $(CHARTS1_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c CHARTS1.C
X
CHARTS2.OBJ:	CHARTS2.C $(CHARTS2_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c CHARTS2.C
X
CHARTS3.OBJ:	CHARTS3.C $(CHARTS3_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c CHARTS3.C
X
DATA.OBJ:	DATA.C $(DATA_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c DATA.C
X
DATA2.OBJ:	DATA2.C $(DATA2_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c DATA2.C
X
GENERAL.OBJ:	GENERAL.C $(GENERAL_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c GENERAL.C
X
INTRPRET.OBJ:	INTRPRET.C $(INTRPRET_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c INTRPRET.C
X
IO.OBJ:	IO.C $(IO_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c IO.C
X
MATRIX.OBJ:	MATRIX.C $(MATRIX_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c MATRIX.C
X
PLACALC.OBJ:	PLACALC.C $(PLACALC_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c PLACALC.C
X
PLACALC2.OBJ:	PLACALC2.C $(PLACALC2_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c PLACALC2.C
X
WDIALOG.OBJ:	WDIALOG.C $(WDIALOG_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c WDIALOG.C
X
WDRIVER.OBJ:	WDRIVER.C $(WDRIVER_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c WDRIVER.C
X
XXCHARTS0.OBJ:	XCHARTS0.C $(XCHARTS0_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c XCHARTS0.C
X
XXCHARTS1.OBJ:	XCHARTS1.C $(XCHARTS1_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c XCHARTS1.C
X
XXCHARTS2.OBJ:	XCHARTS2.C $(XCHARTS2_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c XCHARTS2.C
X
XXDATA.OBJ:	XDATA.C $(XDATA_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c XDATA.C
X
XXDEVICE.OBJ:	XDEVICE.C $(XDEVICE_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c XDEVICE.C
X
XXGENERAL.OBJ:	XGENERAL.C $(XGENERAL_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c XGENERAL.C
X
XXSCREEN.OBJ:	XSCREEN.C $(XSCREEN_DEP)
X	$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c XSCREEN.C
X
ASTROLOG.RES:	ASTROLOG.RC $(ASTROLOG_RCDEP)
X	$(RC) $(RCFLAGS) $(RCDEFINES) -r ASTROLOG.RC
X
X
$(PROJ).EXE::	ASTROLOG.RES
X
$(PROJ).EXE::	ASTROLOG.OBJ CALC.OBJ CHARTS0.OBJ CHARTS1.OBJ CHARTS2.OBJ CHARTS3.OBJ \
X	DATA.OBJ DATA2.OBJ GENERAL.OBJ INTRPRET.OBJ IO.OBJ MATRIX.OBJ PLACALC.OBJ PLACALC2.OBJ \
X	WDIALOG.OBJ WDRIVER.OBJ XCHARTS0.OBJ XCHARTS1.OBJ XCHARTS2.OBJ XDATA.OBJ XDEVICE.OBJ \
X	XGENERAL.OBJ XSCREEN.OBJ $(OBJS_EXT) $(DEFFILE)
X	echo >NUL @<<$(PROJ).CRF
ASTROLOG.OBJ +
CALC.OBJ +
CHARTS0.OBJ +
CHARTS1.OBJ +
CHARTS2.OBJ +
CHARTS3.OBJ +
DATA.OBJ +
DATA2.OBJ +
GENERAL.OBJ +
INTRPRET.OBJ +
IO.OBJ +
MATRIX.OBJ +
PLACALC.OBJ +
PLACALC2.OBJ +
WDIALOG.OBJ +
WDRIVER.OBJ +
XXCHARTS0.OBJ +
XXCHARTS1.OBJ +
XXCHARTS2.OBJ +
XXDATA.OBJ +
XXDEVICE.OBJ +
XXGENERAL.OBJ +
XXSCREEN.OBJ +
$(OBJS_EXT)
$(PROJ).EXE
$(MAPFILE)
c:\vc\lib\+
c:\vc\mfc\lib\+
$(LIBS)
$(DEFFILE);
<<
X	link $(LFLAGS) @$(PROJ).CRF
X	$(RC) $(RESFLAGS) ASTROLOG.RES $@
X	@copy $(PROJ).CRF MSVC.BND
X
$(PROJ).EXE::	ASTROLOG.RES
X	if not exist MSVC.BND 	$(RC) $(RESFLAGS) ASTROLOG.RES $@
X
run: $(PROJ).EXE
X	$(PROJ) $(RUNFLAGS)
X
X
$(PROJ).BSC: $(SBRS)
X	bscmake @<<
/o$@ $(SBRS)
<<
SHAR_EOF
  $shar_touch -am 1223232998 'makefile.win' &&
  chmod 0644 'makefile.win' ||
  echo 'restore of makefile.win failed'
  shar_count="`wc -c < 'makefile.win'`"
  test 4774 -eq "$shar_count" ||
    echo "makefile.win: original size 4774, current size $shar_count"
fi
# ============= matrix.c ==============
if test -f 'matrix.c' && test X"$1" != X"-c"; then
  echo 'x - skipping matrix.c (File already exists)'
else
  echo 'x - extracting matrix.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'matrix.c' &&
/*
** Astrolog (Version 5.40) File: matrix.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
#ifdef MATRIX
/*
******************************************************************************
** Assorted Calculations.
******************************************************************************
*/
X
/* Given a month, day, and year, convert it into a single Julian day value, */
/* i.e. the number of days passed since a fixed reference date.             */
X
long MdyToJulian(mon, day, yea)
int mon, day, yea;
{
#ifndef PLACALC
X  long im, j;
X
X  im = 12*((long)yea+4800)+(long)mon-3;
X  j = (2*(im%12) + 7 + 365*im)/12;
X  j += (long)day + im/48 - 32083;
X  if (j > 2299171)                   /* Take care of dates in */
X    j += im/4800 - im/1200 + 38;     /* Gregorian calendar.   */
X  return j;
#else
X  int fGreg = fTrue;
X
X  if (yea < yeaJ2G || (yea == yeaJ2G &&
X    (mon < monJ2G || (mon == monJ2G && day < 15))))
X    fGreg = fFalse;
X  return (long)RFloor(julday(mon, day, yea, 12.0, fGreg)+rRound);
#endif
}
X
X
/* Like above but return a fractional Julian time given the extra info. */
X
real MdytszToJulian(mon, day, yea, tim, dst, zon)
int mon, day, yea;
real tim, dst, zon;
{
X  return (real)MdyToJulian(mon, day, yea) +
X    (DecToDeg(tim) + DecToDeg(zon) - DecToDeg(dst)) / 24.0;
}
X
X
/* Take a Julian day value, and convert it back into the corresponding */
/* month, day, and year.                                               */
X
void JulianToMdy(JD, mon, day, yea)
real JD;
int *mon, *day, *yea;
{
#ifndef PLACALC
X  long L, N, IT, JT, K, IK;
X
X  L  = (long)RFloor(JD+rRound)+68569L;
X  N  = Dvd(4L*L, 146097L);
X  L  -= Dvd(146097L*N + 3L, 4L);
X  IT = Dvd(4000L*(L+1L), 1461001L);
X  L  -= Dvd(1461L*IT, 4L) - 31L;
X  JT = Dvd(80L*L, 2447L);
X  K  = L-Dvd(2447L*JT, 80L);
X  L  = Dvd(JT, 11L);
X  JT += 2L - 12L*L;
X  IK = 100L*(N-49L) + IT + L;
X  *mon = (int)JT; *day = (int)K; *yea = (int)IK;
#else
X  double tim;
X
X  revjul(JD, JD >= 2299171.0 /* October 15, 1582 */, mon, day, yea, &tim);
#endif
}
X
X
/* This is a subprocedure of CastChart(). Once we have the chart parameters, */
/* calculate a few important things related to the date, i.e. the Greenwich  */
/* time, the Julian day and fractional part of the day, the offset to the    */
/* sidereal, and a couple of other things.                                   */
X
real ProcessInput(fDate)
bool fDate;
{
X  real Off, Ln;
X
X  TT = RSgn(TT)*RFloor(RAbs(TT))+RFract(RAbs(TT))*100.0/60.0 +
X    (DecToDeg(ZZ) - DecToDeg(SS));
X  OO = DecToDeg(OO);
X  AA = Min(AA, 89.9999);        /* Make sure the chart isn't being cast */
X  AA = Max(AA, -89.9999);       /* on the precise north or south pole.  */
X  AA = RFromD(DecToDeg(AA));
X
X  /* if parameter 'fDate' isn't set, then we can assume that the true time */
X  /* has already been determined (as in a -rm switch time midpoint chart). */
X
X  if (fDate) {
X    is.JD = (real)MdyToJulian(MM, DD, YY);
X    if (!us.fProgress || us.fSolarArc)
X      is.T = (is.JD + TT/24.0 - 2415020.5) / 36525.0;
X    else {
X      /* Determine actual time that a progressed chart is to be cast for. */
X
X      is.T = ((is.JD + TT/24.0 + (is.JDp - (is.JD + TT/24.0)) / us.rProgDay) -
X        2415020.5) / 36525.0;
X    }
X  }
X
X  /* Compute angle that the ecliptic is inclined to the Celestial Equator */
X  is.OB = RFromD(23.452294-0.0130125*is.T);
X
X  Ln = Mod((933060-6962911*is.T+7.5*is.T*is.T)/3600.0);  /* Mean lunar node */
X  Off = (259205536.0*is.T+2013816.0)/3600.0;             /* Mean Sun        */
X  Off = 17.23*RSin(RFromD(Ln))+1.27*RSin(RFromD(Off))-(5025.64+1.11*is.T)*is.T;
X  Off = (Off-84038.27)/3600.0;
X  is.rSid = (us.fSidereal ? Off : 0.0) + us.rZodiacOffset;
X  return Off;
}
X
X
/* Convert polar to rectangular coordinates. */
X
void PolToRec(A, R, X, Y)
real A, R, *X, *Y;
{
X  if (A == 0.0)
X    A = rSmall;
X  *X = R*RCos(A);
X  *Y = R*RSin(A);
}
X
X
/* Convert rectangular to polar coordinates. */
X
void RecToPol(X, Y, A, R)
real X, Y, *A, *R;
{
X  if (Y == 0.0)
X    Y = rSmall;
X  *R = RSqr(X*X + Y*Y);
X  *A = Angle(X, Y);
}
X
X
/* Convert rectangular to spherical coordinates. */
X
real RecToSph(B, L, O)
real B, L, O;
{
X  real R, Q, G, X, Y, A;
X
X  A = B; R = 1.0;
X  PolToRec(A, R, &X, &Y);
X  Q = Y; R = X; A = L;
X  PolToRec(A, R, &X, &Y);
X  G = X; X = Y; Y = Q;
X  RecToPol(X, Y, &A, &R);
X  A += O;
X  PolToRec(A, R, &X, &Y);
X  Q = RAsin(Y);
X  Y = X; X = G;
X  RecToPol(X, Y, &A, &R);
X  if (A < 0.0)
X    A += 2*rPi;
X  G = A;
X  return G;  /* We only ever care about and return one of the coordinates. */
}
X
X
/* Do a coordinate transformation: Given a longitude and latitude value,    */
/* return the new longitude and latitude values that the same location      */
/* would have, were the equator tilted by a specified number of degrees.    */
/* In other words, do a pole shift! This is used to convert among ecliptic, */
/* equatorial, and local coordinates, each of which have zero declination   */
/* in different planes. In other words, take into account the Earth's axis. */
X
void CoorXform(azi, alt, tilt)
real *azi, *alt, tilt;
{
X  real x, y, a1, l1;
X  real sinalt, cosalt, sinazi, sintilt, costilt;
X
X  sinalt = RSin(*alt); cosalt = RCos(*alt); sinazi = RSin(*azi);
X  sintilt = RSin(tilt); costilt = RCos(tilt);
X
X  x = cosalt * sinazi * costilt;
X  y = sinalt * sintilt;
X  x -= y;
X  a1 = cosalt;
X  y = cosalt * RCos(*azi);
X  l1 = Angle(y, x);
X  a1 = a1 * sinazi * sintilt + sinalt * costilt;
X  a1 = RAsin(a1);
X  *azi = l1; *alt = a1;
}
X
X
/* This is another subprocedure of CastChart(). Calculate a few variables */
/* corresponding to the chart parameters that are used later on. The      */
/* astrological vertex (object number nineteen) is also calculated here.  */
X
void ComputeVariables(vtx)
real *vtx;
{
X  real R, R2, B, L, O, G, X, Y, A;
X
X  is.RA = RFromD(Mod((6.6460656+2400.0513*is.T+2.58E-5*is.T*is.T+TT)*15.0-OO));
X  R2 = is.RA; O = -is.OB; B = AA; A = R2; R = 1.0;
X  PolToRec(A, R, &X, &Y);
X  X *= RCos(O);
X  RecToPol(X, Y, &A, &R);
X  is.MC = Mod(is.rSid + DFromR(A));           /* Midheaven */
#if FALSE
X  L = R2;
X  G = RecToSph(B, L, O);
X  is.Asc = Mod(is.rSid + Mod(G+rPiHalf));     /* Ascendant */
#endif
X  L= R2+rPi; B = rPiHalf-RAbs(B);
X  if (AA < 0.0)
X    B = -B;
X  G = RecToSph(B, L, O);
X  *vtx = Mod(is.rSid + DFromR(G+rPiHalf));    /* Vertex */
}
X
X
/*
******************************************************************************
** House Cusp Calculations.
******************************************************************************
*/
X
/* The following three functions calculate the Midheaven, Ascendant, and  */
/* East Point of the chart in question, based on time and location. The   */
/* first two are also used in some of the house cusp calculation routines */
/* as a quick way to get the 10th and 1st cusps. The East Point object is */
/* technically defined as the Ascendant's position at zero latitude.      */
X
real CuspMidheaven()
{
X  real MC;
X
X  MC = RAtn(RTan(is.RA)/RCos(is.OB));
X  if (MC < 0.0)
X    MC += rPi;
X  if (is.RA > rPi)
X    MC += rPi;
X  return Mod(DFromR(MC)+is.rSid);
}
X
real CuspAscendant()
{
X  real Asc;
X
X  Asc = Angle(-RSin(is.RA)*RCos(is.OB)-RTan(AA)*RSin(is.OB), RCos(is.RA));
X  return Mod(DFromR(Asc)+is.rSid);
}
X
real CuspEastPoint()
{
X  real EP;
X
X  EP = Angle(-RSin(is.RA)*RCos(is.OB), RCos(is.RA));
X  return Mod(DFromR(EP)+is.rSid);
}
X
X
/* These are various different algorithms for calculating the house cusps: */
X
real CuspPlacidus(deg, FF, fNeg)
real deg, FF;
bool fNeg;
{
X  real LO, R1, XS, X;
X  int i;
X
X  R1 = is.RA+RFromD(deg);
X  X = fNeg ? 1.0 : -1.0;
X  /* Looping 10 times is arbitrary, but it's what other programs do. */
X  for (i = 1; i <= 10; i++) {
X
X    /* This formula works except at 0 latitude (AA == 0.0). */
X
X    XS = X*RSin(R1)*RTan(is.OB)*RTan(AA == 0.0 ? 0.0001 : AA);
X    XS = RAcos(XS);
X    if (XS < 0.0)
X      XS += rPi;
X    R1 = is.RA + (fNeg ? rPi-(XS/FF) : (XS/FF));
X  }
X  LO = RAtn(RTan(R1)/RCos(is.OB));
X  if (LO < 0.0)
X    LO += rPi;
X  if (RSin(R1) < 0.0)
X    LO += rPi;
X  return DFromR(LO);
}
X
void HousePlacidus()
{
X  int i;
X
X  chouse[1] = Mod(is.Asc-is.rSid);
X  chouse[4] = Mod(is.MC+rDegHalf-is.rSid);
X  chouse[5] = CuspPlacidus(30.0, 3.0, fFalse) + rDegHalf;
X  chouse[6] = CuspPlacidus(60.0, 1.5, fFalse) + rDegHalf;
X  chouse[2] = CuspPlacidus(120.0, 1.5, fTrue);
X  chouse[3] = CuspPlacidus(150.0, 3.0, fTrue);
X  for (i = 1; i <= cSign; i++) {
X    if (i <= 6)
X      chouse[i] = Mod(chouse[i]+is.rSid);
X    else
X      chouse[i] = Mod(chouse[i-6]+rDegHalf);
X  }
}
X
void HouseKoch()
{
X  real A1, A2, A3, KN, D, X;
X  int i;
X
X  A1 = RSin(is.RA)*RTan(AA)*RTan(is.OB);
X  A1 = RAsin(A1);
X  for (i = 1; i <= cSign; i++) {
X    D = Mod(60.0+30.0*(real)i);
X    A2 = D/rDegQuad-1.0; KN = 1.0;
X    if (D >= rDegHalf) {
X      KN = -1.0;
X      A2 = D/rDegQuad-3.0;
X    }
X    A3 = RFromD(Mod(DFromR(is.RA)+D+A2*DFromR(A1)));
X    X = Angle(RCos(A3)*RCos(is.OB)-KN*RTan(AA)*RSin(is.OB), RSin(A3));
X    chouse[i] = Mod(DFromR(X)+is.rSid);
X  }
}
X
void HouseEqual()
{
X  int i;
X
X  for (i = 1; i <= cSign; i++)
X    chouse[i] = Mod(is.Asc + ZFromS(i));
}
X
void HouseCampanus()
{
X  real KO, DN, X;
X  int i;
X
X  for (i = 1; i <= cSign; i++) {
X    KO = RFromD(60.000001+30.0*(real)i);
X    DN = RAtn(RTan(KO)*RCos(AA));
X    if (DN < 0.0)
X      DN += rPi;
X    if (RSin(KO) < 0.0)
X      DN += rPi;
X    X = Angle(RCos(is.RA+DN)*RCos(is.OB)-RSin(DN)*RTan(AA)*RSin(is.OB),
X      RSin(is.RA+DN));
X    chouse[i] = Mod(DFromR(X)+is.rSid);
X  }
}
X
void HouseMeridian()
{
X  real D, X;
X  int i;
X
X  for (i = 1; i <= cSign; i++) {
X    D = RFromD(60.0+30.0*(real)i);
X    X = Angle(RCos(is.RA+D)*RCos(is.OB), RSin(is.RA+D));
X    chouse[i] = Mod(DFromR(X)+is.rSid);
X  }
}
X
void HouseRegiomontanus()
{
X  real D, X;
X  int i;
X
X  for (i = 1; i <= cSign; i++) {
X    D = RFromD(60.0+30.0*(real)i);
X    X = Angle(RCos(is.RA+D)*RCos(is.OB)-RSin(D)*RTan(AA)*RSin(is.OB),
X      RSin(is.RA+D));
X    chouse[i] = Mod(DFromR(X)+is.rSid);
X  }
}
X
void HousePorphyry()
{
X  real X, Y;
X  int i;
X
X  X = is.Asc-is.MC;
X  if (X < 0.0)
X    X += rDegMax;
X  Y = X/3.0;
X  for (i = 1; i <= 2; i++)
X    chouse[i+4] = Mod(rDegHalf+is.MC+i*Y);
X  X = Mod(rDegHalf+is.MC)-is.Asc;
X  if (X < 0.0)
X    X += rDegMax;
X  chouse[1]=is.Asc;
X  Y = X/3.0;
X  for (i = 1; i <= 3; i++)
X    chouse[i+1] = Mod(is.Asc+i*Y);
X  for (i = 1; i <= 6; i++)
X    chouse[i+6] = Mod(chouse[i]+rDegHalf);
}
X
void HouseMorinus()
{
X  real D, X;
X  int i;
X
X  for (i = 1; i <= cSign; i++) {
X    D = RFromD(60.0+30.0*(real)i);
X    X = Angle(RCos(is.RA+D), RSin(is.RA+D)*RCos(is.OB));
X    chouse[i] = Mod(DFromR(X)+is.rSid);
X  }
}
X
real CuspTopocentric(deg)
real deg;
{
X  real OA, X, LO;
X
X  OA = ModRad(is.RA+RFromD(deg));
X  X = RAtn(RTan(AA)/RCos(OA));
X  LO = RAtn(RCos(X)*RTan(OA)/RCos(X+is.OB));
X  if (LO < 0.0)
X    LO += rPi;
X  if (RSin(OA) < 0.0)
X    LO += rPi;
X  return LO;
}
X
void HouseTopocentric()
{
X  real TL, P1, P2, LT;
X  int i;
X
X  chouse[4] = ModRad(RFromD(is.MC+rDegHalf-is.rSid));
X  TL = RTan(AA); P1 = RAtn(TL/3.0); P2 = RAtn(TL/1.5); LT = AA;
X  AA = P1; chouse[5] = CuspTopocentric(30.0) + rPi;
X  AA = P2; chouse[6] = CuspTopocentric(60.0) + rPi;
X  AA = LT; chouse[1] = CuspTopocentric(90.0);
X  AA = P2; chouse[2] = CuspTopocentric(120.0);
X  AA = P1; chouse[3] = CuspTopocentric(150.0);
X  AA = LT;
X  for (i = 1; i <= 6; i++) {
X    chouse[i] = Mod(DFromR(chouse[i])+is.rSid);
X    chouse[i+6] = Mod(chouse[i]+rDegHalf);
X  }
}
X
X
/*
******************************************************************************
** Planetary Position Calculations.
******************************************************************************
*/
X
/* Given three values, return them combined as the coefficients of a */
/* quadratic equation as a function of the chart time.               */
X
real ReadThree(r0, r1, r2)
real r0, r1, r2;
{
X  return RFromD(r0 + r1*is.T + r2*is.T*is.T);
}
X
X
/* Another coordinate transformation. This is used by the ComputePlanets() */
/* procedure to rotate rectangular coordinates by a certain amount.        */
X
void RecToSph2(AP, AN, IN, X, Y, G)
real AP, AN, IN, *X, *Y, *G;
{
X  real R, D, A;
X
X  RecToPol(*X, *Y, &A, &R); A += AP; PolToRec(A, R, X, Y);
X  D = *X; *X = *Y; *Y = 0.0; RecToPol(*X, *Y, &A, &R);
X  A += IN; PolToRec(A, R, X, Y);
X  *G = *Y; *Y = *X; *X = D; RecToPol(*X, *Y, &A, &R); A += AN;
X  if (A < 0.0)
X    A += 2.0*rPi;
X  PolToRec(A, R, X, Y);
}
X
X
/* Calculate some harmonic delta error correction factors to add onto the */
/* coordinates of Jupiter through Pluto, for better accuracy.             */
X
void ErrorCorrect(ind, x, y, z)
int ind;
real *x, *y, *z;
{
X  real U, V, W, A, S0, T0[4], FPTR *pr;
X  int IK, IJ, irError;
X
X  irError = rErrorCount[ind-oJup];
X  pr = (lpreal)&rErrorData[rErrorOffset[ind-oJup]];
X  for (IK = 1; IK <= 3; IK++) {
X    if (ind == oJup && IK == 3) {
X      T0[3] = 0.0;
X      break;
X    }
X    if (IK == 3)
X      irError--;
X    S0 = ReadThree(pr[0], pr[1], pr[2]); pr += 3;
X    A = 0.0;
X    for (IJ = 1; IJ <= irError; IJ++) {
X      U = *pr++; V = *pr++; W = *pr++;
X      A += RFromD(U)*RCos((V*is.T+W)*rPi/rDegHalf);
X    }
X    T0[IK] = DFromR(S0+A);
X  }
X  *x += T0[2]; *y += T0[1]; *z += T0[3];
}
X
X
/* Another subprocedure of the ComputePlanets() routine. Convert the final */
/* rectangular coordinates of a planet to zodiac position and declination. */
X
void ProcessPlanet(ind, aber)
int ind;
real aber;
{
X  real ang, rad;
X
X  RecToPol(spacex[ind], spacey[ind], &ang, &rad);
X  planet[ind] = Mod(DFromR(ang) /*+ NU*/ - aber + is.rSid);
X  RecToPol(rad, spacez[ind], &ang, &rad);
X  if (us.objCenter == oSun && ind == oSun)
X    ang = 0.0;
X  ang = DFromR(ang);
X  while (ang > rDegQuad)    /* Ensure declination is from -90..+90 degrees. */
X    ang -= rDegHalf;
X  while (ang < -rDegQuad)
X    ang += rDegHalf;
X  planetalt[ind] = ang;
}
X
X
/* This is probably the heart of the whole program of Astrolog. Calculate  */
/* the position of each body that orbits the Sun. A heliocentric chart is  */
/* most natural; extra calculation is needed to have other central bodies. */
X
void ComputePlanets()
{
X  real helioret[oNorm+1], heliox[oNorm+1], helioy[oNorm+1], helioz[oNorm+1];
X  real aber = 0.0, AU, E, EA, E1, M, XW, YW, AP, AN, IN, X, Y, G, XS, YS, ZS;
X  int ind = oSun, i;
X  OE *poe;
X
X  while (ind <= (us.fUranian ? oNorm : cPlanet)) {
X    if (ignore[ind] && ind > oSun)
X      goto LNextPlanet;
X    poe = &rgoe[IoeFromObj(ind)];
X
X    EA = M = ModRad(ReadThree(poe->ma0, poe->ma1, poe->ma2));
X    E = DFromR(ReadThree(poe->ec0, poe->ec1, poe->ec2));
X    for (i = 1; i <= 5; i++)
X      EA = M+E*RSin(EA);            /* Solve Kepler's equation */
X    AU = poe->sma;                  /* Semi-major axis         */
X    E1 = 0.01720209/(pow(AU, 1.5)*
X      (1.0-E*RCos(EA)));                     /* Begin velocity coordinates */
X    XW = -AU*E1*RSin(EA);                    /* Perifocal coordinates      */
X    YW = AU*E1*pow(1.0-E*E,0.5)*RCos(EA);
X    AP = ReadThree(poe->ap0, poe->ap1, poe->ap2);
X    AN = ReadThree(poe->an0, poe->an1, poe->an2);
X    IN = ReadThree(poe->in0, poe->in1, poe->in2); /* Calculate inclination  */
X    X = XW; Y = YW;
X    RecToSph2(AP, AN, IN, &X, &Y, &G);  /* Rotate velocity coords */
X    heliox[ind] = X; helioy[ind] = Y;
X    helioz[ind] = G;                    /* Helio ecliptic rectangtular */
X    X = AU*(RCos(EA)-E);                /* Perifocal coordinates for        */
X    Y = AU*RSin(EA)*pow(1.0-E*E,0.5);   /* rectangular position coordinates */
X    RecToSph2(AP, AN, IN, &X, &Y, &G);  /* Rotate for rectangular */
X    XS = X; YS = Y; ZS = G;             /* position coordinates   */
X    if (FBetween(ind, oJup, oPlu))
X      ErrorCorrect(ind, &XS, &YS, &ZS);
X    ret[ind] =                                        /* Helio daily motion */
X      (XS*helioy[ind]-YS*heliox[ind])/(XS*XS+YS*YS);
X    spacex[ind] = XS; spacey[ind] = YS; spacez[ind] = ZS;
X    ProcessPlanet(ind, 0.0);
LNextPlanet:
X    ind += (ind == oSun ? 2 : (ind != cPlanet ? 1 : uranLo-cPlanet));
X  }
X
X  spacex[oEar] = spacex[oSun];
X  spacey[oEar] = spacey[oSun];
X  spacez[oEar] = spacez[oSun];
X  planet[oEar] = planet[oSun]; planetalt[oEar] = planetalt[oSun];
X  ret[oEar] = ret[oSun];
X  heliox[oEar] = heliox[oSun]; helioy[oEar] = helioy[oSun];
X  helioret[oEar] = helioret[oSun];
X  spacex[oSun] = spacey[oSun] = spacez[oSun] =
X    planet[oSun] = planetalt[oSun] = heliox[oSun] = helioy[oSun] = 0.0;
X  if (us.objCenter == oSun) {
X    if (us.fVelocity)
X      for (i = 0; i <= oNorm; i++)    /* Use relative velocity */
X        ret[i] = RFromD(1.0);         /* if -v0 is in effect.  */
X    return;
X  }
#endif /* MATRIX */
X
X  /* A second loop is needed for geocentric charts or central bodies other */
X  /* than the Sun. For example, we can't find the position of Mercury in   */
X  /* relation to Pluto until we know the position of Pluto in relation to  */
X  /* the Sun, and since Mercury is calculated first, another pass needed.  */
X
X  ind = us.objCenter;
X  for (i = 0; i <= oNorm; i++) {
X    helioret[i] = ret[i];
X    if (i != oMoo && i != ind) {
X      spacex[i] -= spacex[ind];
X      spacey[i] -= spacey[ind];
X      spacez[i] -= spacez[ind];
X    }
X  }
X  for (i = oEar; i <= (us.fUranian ? oNorm : cPlanet);
X    i += (i == oSun ? 2 : (i != cPlanet ? 1 : uranLo-cPlanet))) {
X    if ((ignore[i] && i > oSun) || i == ind)
X      continue;
X    XS = spacex[i]; YS = spacey[i]; ZS = spacez[i];
X    ret[i] = (XS*(helioy[i]-helioy[ind])-YS*(heliox[i]-heliox[ind]))/
X      (XS*XS+YS*YS);
X    if (ind == oEar)
X      aber = 0.0057756*RSqr(XS*XS+YS*YS+ZS*ZS)*DFromR(ret[i]); /* Aberration */
X    ProcessPlanet(i, aber);
X    if (us.fVelocity)                         /* Use relative velocity */
X      ret[i] = RFromD(ret[i]/helioret[i]);    /* if -v0 is in effect   */
X  }
X  spacex[ind] = spacey[ind] = spacez[ind] = 0.0;
}
X
X
#ifdef MATRIX
/*
******************************************************************************
** Lunar Position Calculations
******************************************************************************
*/
X
/* Calculate the position and declination of the Moon, and the Moon's North  */
/* Node. This has to be done separately from the other planets, because they */
/* all orbit the Sun, while the Moon orbits the Earth.                       */
X
void ComputeLunar(moonlo, moonla, nodelo, nodela)
real *moonlo, *moonla, *nodelo, *nodela;
{
X  real LL, G, N, G1, D, L, ML, L1, MB, T1, Y, M = 3600.0, T2;
X
X  T2 = is.T*is.T;
X  LL = 973563.0+1732564379.0*is.T-4.0*T2; /* Compute mean lunar longitude    */
X  G = 1012395.0+6189.0*is.T;              /* Sun's mean longitude of perigee */
X  N = 933060.0-6962911.0*is.T+7.5*T2;     /* Compute mean lunar node         */
X  G1 = 1203586.0+14648523.0*is.T-37.0*T2; /* Mean longitude of lunar perigee */
X  D = 1262655.0+1602961611.0*is.T-5.0*T2; /* Mean elongation of Moo from Sun */
X  L = (LL-G1)/M; L1 = ((LL-D)-G)/M;       /* Some auxiliary angles           */
X  T1 = (LL-N)/M; D = D/M; Y = 2.0*D;
X
X  /* Compute Moon's perturbations. */
X
X  ML = 22639.6*RSinD(L) - 4586.4*RSinD(L-Y) + 2369.9*RSinD(Y) +
X    769.0*RSinD(2.0*L) - 669.0*RSinD(L1) - 411.6*RSinD(2.0*T1) -
X    212.0*RSinD(2.0*L-Y) - 206.0*RSinD(L+L1-Y);
X  ML += 192.0*RSinD(L+Y) - 165.0*RSinD(L1-Y) + 148.0*RSinD(L-L1) -
X    125.0*RSinD(D) - 110.0*RSinD(L+L1) - 55.0*RSinD(2.0*T1-Y) -
X    45.0*RSinD(L+2.0*T1) + 40.0*RSinD(L-2.0*T1);
X
X  *moonlo = G = Mod((LL+ML)/M+is.rSid);    /* Lunar longitude */
X
X  /* Compute lunar latitude. */
X
X  MB = 18461.5*RSinD(T1) + 1010.0*RSinD(L+T1) - 999.0*RSinD(T1-L) -
X    624.0*RSinD(T1-Y) + 199.0*RSinD(T1+Y-L) - 167.0*RSinD(L+T1-Y);
X  MB += 117.0*RSinD(T1+Y) + 62.0*RSinD(2.0*L+T1) -
X    33.0*RSinD(T1-Y-L) - 32.0*RSinD(T1-2.0*L) - 30.0*RSinD(L1+T1-Y);
X  *moonla = MB =
X    RSgn(MB)*((RAbs(MB)/M)/rDegMax-RFloor((RAbs(MB)/M)/rDegMax))*rDegMax;
X
X  /* Compute position of the North Lunar Node, either True or Mean. */
X
X  if (us.fTrueNode)
X    N = N+5392.0*RSinD(2.0*T1-Y)-541.0*RSinD(L1)-442.0*RSinD(Y)+
X      423.0*RSinD(2.0*T1)-291.0*RSinD(2.0*L-2.0*T1);
X  *nodelo = Mod(N/M+is.rSid);
X  *nodela = 0.0;
}
#endif /* MATRIX */
X
/* matrix.c */
SHAR_EOF
  $shar_touch -am 1223232998 'matrix.c' &&
  chmod 0644 'matrix.c' ||
  echo 'restore of matrix.c failed'
  shar_count="`wc -c < 'matrix.c'`"
  test 21696 -eq "$shar_count" ||
    echo "matrix.c: original size 21696, current size $shar_count"
fi
# ============= placalc.c ==============
if test -f 'placalc.c' && test X"$1" != X"-c"; then
  echo 'x - skipping placalc.c (File already exists)'
else
  echo 'x - extracting placalc.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'placalc.c' &&
/*
** Astrolog (Version 5.40) File: placalc.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "placalc.h"
X
X
#ifdef PLACALC
/*
** ---------------------------------------------------------------
** | Copyright Astrodienst AG and Alois Treindl, 1989,1991,1993  |
** | The use of this source code is subject to regulations made  |
** | by Astrodienst Zurich. The code is NOT in the public domain.|
** |                                                             |
** | This copyright notice must not be changed or removed        |
** | by any user of this program.                                |
** ---------------------------------------------------------------
**
** Important changes:
** 11-jun-93 revision 1.12: fixed error which affected Mercury between -2100
** and -3100 (it jumped wildly).
*/
X
/* function calc():
** This is the main routine for computing a planets position.
** The function has several modes, which are controlled by bits in
** the parameter 'flag'. The normal mode (flag == 0) computes
** a planets apparent geocentric position in ecliptic coordinates relative to
** the true equinox of date, without speed
**
** Explanation of the arguments: see the functions header.
**
** Returns OK or ERR (if some planet out of time range). OK and ERR are
** defined in ourdef.h and must not be confused with TRUE and FALSE.
** OK and ERR are of type int, not of type BOOLEAN.
**
** Bits used in flag:
** CALC_BIT_HELIO     0 = geocentric, 1 = heliocentric
** CALC_BIT_NOAPP       0 = apparent positions, 1 = true positions
** CALC_BIT_NONUT     0 = do nutation (true equinox of date)
** 1 = don't do nutation (mean equinox of date).
**
** CALC_BIT_SPEED     0 = don't calc speed,
** 1 = calc speed, takes quite long for moon
** (is observed only for moon, with other
** planets speed is cheap)
**
** Side effects and local memory:
** For doing heliocentric positions the fucntion must know the
** earth's position for the desired time t. It remembers the earth
** position so it does not have to recompute it each time a planet
** position is wanted for the same time t.
** It calls helup(t), which leaves as a side effect the global
** variables meanekl, ekl and nut for the time t.
**
** Functions called by calc():
** helup(t)
** hel(t)
** moon(t)
** togeo()
**
** Time range:
** The function can be used savely in the time range 5000 BC to
** 3000 AD. The stored ephemeris is available only for this time
** range, so Jupiter ... Pluto cannot be computed outside. The
** function will return results for the other planets also outside
** of this time range, but they become meaningless pretty soon
** before 5000 BC, because Newcombs time series expansions for the
** elements will not work anymore.
**
** pointers to the return variables:
** alng = ecliptic longitude in degrees
** arad = radius vector in AU (astronomic units)
** alat = ecliptic latitude in degrees
** alngspeed = speed of planet in degrees per day
**
** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
** The precision of the speed is quite limited.
** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
**
** For Sun, Mercury, Venus and Mars we take only the speed from
** the undisturbed Kepler orbit. For the Moon there is no
** reasonable undisturbed orbit and we derive the speed from
** its position at t + dt and t - dt. We need these
** moon positions anyway for the true node calculation.
** For the outer planets and Chiron we derive the precise
** speed from the stored ephemeris by high order inter-
** polation; the precision is limited for the geocentric
** case due to the limited precision of the earth's/sun's speed.
** Applications who need precise speeds should
** get them by calling calc() with slightly different times.
**
** Comment 7 May 1991 by Alois Treindl:
** Center of Earth versus Barycenter Earth-Moon:
** Brown's theory of the moon gives the moon's coordinates relative
** to the center of the earth. Newcomb's theory of the Sun gives the
** coordinates of the earth's center relative to the center of the Sun.
** This is what we need.
**
** How about the Mean Lunar Node?
** The orbital elements of the Sun in Newcomb's theory are given
** relative to the barycenter Earth-Moon; the reduction to geocentric
** is only applied after doing the Kepler ellipse calculation.
** Are the Lunar elements also relative to the barycenter??
** If yes:
** When we use the moon's mean node out of the elements, it is still
** as seen from the barycenter. Because the node is close to the
** earth, we would have to apply a considerable correction, which is of
** the order of 4000/384000 km or 35' (minutes of arc).
** Nobody has ever applied such a correction to the mean node.
**
** And the True Node?
** When we calculate the osculating orbital elements of the Moon (true node),
** are they relative to the barycenter or to the Earth's center?
** Our derivation of true node from the actual Moon positions considers
** the earth's center as the focal point of the osculating lunar ellipse.
** A more correct approach would first reduce the lunar position from
** geocentric to barycentric, then compute the orbital elements from
** the reduced positions, and then reduce the desired items
** (node, apogaeum, 'dark moon') to geocentric positions.
** No known astrological ephemeris has ever used such a correction, which is
** of the same order of magnitude as the correction to the meannode above.
** When the moon is going through the ecliptic, the geocenter, barycenter
** moon (and the node identical to the moon itself) line up; this is why
** the error does not show up in normal considerations.
*/
X
int calc(planet, jd_ad, flag, alng, arad, alat, alngspeed)
int planet;  /* planet index as defined in placalc.h,
SUN = 0, MOON = 1 etc.
planet == -1 calc calculates only nut and ecl */
REAL8 jd_ad;  /* relative Astrodienst Juldate, ephemeris time.
Astrodienst Juldate is relative 31 Dec 1949, noon. */
int flag;  /* See definition of flag bits above */
REAL8 *alng;
REAL8 *arad;
REAL8 *alat;
REAL8 *alngspeed;
{
X  struct rememberdat  /* time for which the datas are calculated */
X    {REAL8 calculation_time, lng, rad, zet, lngspeed, radspeed, zetspeed;};
X  static struct rememberdat earthrem =
X    {HUGE8, HUGE8, HUGE8, HUGE8, HUGE8, HUGE8, HUGE8};
X  static struct rememberdat moonrem  =
X    {HUGE8, HUGE8, HUGE8, HUGE8, HUGE8, HUGE8, HUGE8};
X  REAL8 c, s, x, knn, knv;
X  REAL8 rp, zp; /* needed to call hel! */
X  REAL8 *azet = alat;
X  BOOLEAN calc_geo, calc_helio, calc_apparent, calc_speed,
X  calc_nut;
X
X  /* helup checks whether it was already called with same time */
X  helup (jd_ad);
X  /* we could return now if we only wanted to compute ecl and nut */
X
X  calc_helio =  flag & CALC_BIT_HELIO;
X  calc_geo = ! calc_helio;
X  calc_apparent = ! (flag & CALC_BIT_NOAPP);
X  calc_nut = ! (flag & CALC_BIT_NONUT);
X  calc_speed = flag & CALC_BIT_SPEED;
X  /*
X  ** it is necessary to compute EARTH in the following cases:
X  ** heliocentric MOON or EARTH
X  ** geocentric any planet except MOON or nodes or LILITH
X  */
X  if (calc_helio && (planet == MOON || planet == EARTH)
X    || calc_geo && planet != MOON
X    && planet != MEAN_NODE
X    && planet != TRUE_NODE
X    && planet != LILITH) {
X    if (earthrem.calculation_time != jd_ad) {
X      hel (EARTH, jd_ad, alng, arad, azet, alngspeed, &rp, &zp);
X      /* store earthdata for geocentric calculation: */
X      earthrem.lng = *alng;
X      earthrem.rad = *arad;
X      earthrem.zet = *azet;
X      earthrem.lngspeed = *alngspeed;
X      earthrem.radspeed = rp;
X      earthrem.zetspeed = zp;
X      earthrem.calculation_time = jd_ad;
X    }
X  }
X  switch(planet) {
X
X  case EARTH: /* has been already computed */
X    *alng = earthrem.lng;
X    *arad = earthrem.rad;
X    *azet = earthrem.zet;
X    *alngspeed = earthrem.lngspeed;
X    rp = earthrem.radspeed;
X    zp = earthrem.zetspeed;
X    if (calc_geo) { /* SUN seen from earth */
X      *alng = smod8360(*alng + 180.0);
X      *azet = - *azet;
X    }
X    if (calc_apparent)
X      *alng = *alng - 0.0057683 * (*arad) * (*alngspeed);
X    break;
X
X  case MOON:
X    moon(alng, arad, azet);
X    moonrem.lng = *alng;  /* moonrem will be used for TRUE_NODE */
X    moonrem.rad = *arad;
X    moonrem.zet = *azet;
X    *alngspeed = 12;
X    moonrem.calculation_time = jd_ad;
X    if (calc_helio || calc_speed) {/* get a second moon position */
X      REAL8 lng2, rad2, zet2;
X      helup(jd_ad + MOON_SPEED_INTERVAL);
X      moon(&lng2, &rad2, &zet2);
X      helup(jd_ad);
X      if (calc_helio) { /* moon as seen from sun */
X        togeo(earthrem.lng, -earthrem.rad, moonrem.lng, moonrem.rad,
X        moonrem.zet, alng, arad);
X        togeo(earthrem.lng + MOON_SPEED_INTERVAL * earthrem.lngspeed,
X        -(earthrem.rad + MOON_SPEED_INTERVAL * earthrem.radspeed),
X        lng2, rad2, zet2, &lng2, &rad2);
X      }
X      *alngspeed =  diff8360(lng2, *alng) / MOON_SPEED_INTERVAL;
X      /* rp = (rad2 - *arad) / MOON_SPEED_INTERVAL;       */
X      /* zp = (zet2 - moonrem.zet) / MOON_SPEED_INTERVAL; */
X    }
X    *alat = RADTODEG * ASIN8(*azet / *arad);
X    /*
X    ** light time correction, not applied for moon or nodes;
X    ** moon would have only term of ca. 0.02", see Expl.Sup.1961 p.109
X    */
X    break;
X
X  case MERCURY:
X  case VENUS:
X  case MARS:
X  case JUPITER:
X  case SATURN:
X  case URANUS:
X  case NEPTUNE:
X  case PLUTO:
X  case CHIRON:
X  case CERES:
X  case PALLAS:
X  case JUNO:
X  case VESTA:
X    if (hel(planet, jd_ad, alng, arad, azet, alngspeed, &rp, &zp) != OK)
X      return ERR; /* outer planets can fail if out of ephemeris range */
X    if (calc_geo) {       /* geocentric */
X      REAL8 lng1, rad1, lng2, rad2;
X      togeo(earthrem.lng, earthrem.rad, *alng, *arad, *azet, &lng1, &rad1);
X      togeo(earthrem.lng + earthrem.lngspeed,
X      earthrem.rad + earthrem.radspeed,
X      *alng + *alngspeed, *arad + rp, *azet + zp, &lng2, &rad2);
X      *alng = lng1;
X      *arad = rad1;
X      *alngspeed = diff8360(lng2, lng1);
X      /* rp = rad2 - rad1; */
X    }
X    *alat = RADTODEG * ASIN8(*azet / *arad);
X    if (calc_apparent)
X      *alng = *alng - 0.0057683 * (*arad) * (*alngspeed);
X    break;
X
X  case MEAN_NODE:
X    *alng = smod8360(el[MOON].kn);
X    /*
X    * the distance of the node is the 'orbital parameter' p = a (1-e^2);
X    * Our current use of the axis a is wrong, but is never used.
X    */
X    *arad = pd[MOON].axis;
X    *alat = 0.0;
X    *alngspeed = -0.053;
X    break;
X
X  case TRUE_NODE: {
X    /* see comment 'Note 7 May 1991' above */
X    REAL8 ln, rn, zn,
X    lv, rv, zv,
X    l1, r1, z1,
X    xn, yn, xv, yv, r0, x0, y0;
X
X    helup(jd_ad + NODE_INTERVAL);
X    moon(&ln, &rn, &zn);
X    helup(jd_ad - NODE_INTERVAL);
X    moon(&lv, &rv, &zv);
X    helup(jd_ad);
X    if (moonrem.calculation_time != jd_ad)
X      moon(&l1, &r1, &z1);
X    else {  /* moon is already calculated */
X      l1 = moonrem.lng;
X      r1 = moonrem.rad;
X      z1 = moonrem.zet;
X    }
X    rn = sqrt(rn * rn - zn * zn);
X    rv = sqrt(rv * rv - zv * zv);
X    r0 = sqrt(r1 * r1 - z1 * z1);
X    xn = rn * COS8(DEGTORAD * ln);
X    yn = rn * SIN8(DEGTORAD * ln);
X    xv = rv * COS8(DEGTORAD * lv);
X    yv = rv * SIN8(DEGTORAD * lv);
X    x0 = r0 * COS8(DEGTORAD * l1);
X    y0 = r0 * SIN8(DEGTORAD * l1);
X    x = test_near_zero(x0 * yn - xn * y0);
X    s = (y0 * zn - z1 * yn) / x;
X    c = test_near_zero((x0 * zn - z1 * xn) / x);
X    knn =  smod8360(RADTODEG * ATAN28(s, c)); /* = ATAN8(s / c) */
X    x = test_near_zero(y0 * xv - x0 * yv);
X    s = (yv * z1 - zv * y0) / x;
X    c = test_near_zero((xv * z1 - zv * x0) / x);
X    knv =  smod8360(RADTODEG * ATAN28(s, c));
X    *alng = smod8360((knv + knn) / 2);
X    /*
X    ** the distance of the node is the 'orbital parameter' p = a (1-e^2);
X    ** Our current use of the axis a is wrong.
X    */
X    *arad = pd[MOON].axis;
X    *alat = 0.0;
X    *alngspeed = diff8360(knn, knv) / NODE_INTERVAL;
X    }
X    break;
X
X  case LILITH: {
X    /*
X    ** Added 22-Jun-93
X    ** Lilith or Dark Moon is the empty focal point of the mean lunar ellipse.
X    ** This is 180 degrees from the perihel.
X    ** Because the lunar orbit is not in the ecliptic, it must be
X    ** projected onto the ecliptic in the same way as the planetary orbits
X    ** are (see for example Montenbruck, Grundlagen der Ephemeridenrechnung).
X    **
X    ** We compute the MEAN Lilith, not the TRUE one which would have to be
X    ** derived in a similar way as the true node.
X    ** For the radius vector of Lilith we use a simple formula;
X    ** to get a precise value, the fact that the focal point of the ellipse
X    ** is not at the center of the earth but at the barycenter moon-earth
X    ** would have to be accounted for.
X    ** For the speed we always return a constant: the T term from the
X    ** lunar perihel.
X    ** Joelle de Gravelaine publishes in her book "Lilith der schwarze Mond"
X    ** (Astrodata, 1990) an ephemeris which gives noon (12.00) positions
X    ** but does not project onto the ecliptic.
X    ** This creates deviations
X    */
X    double arg_lat, lon, cosi;
X    struct elements *e = &el[MOON];
X    arg_lat = degnorm(e->pe - e->kn + 180.0);
X    cosi = COSDEG(e->in);
X    if (e->in == 0 || ABS8(arg_lat -  90.0) < TANERRLIMIT
X      || ABS8(arg_lat - 270.0) < TANERRLIMIT) {
X      lon = arg_lat;
X    } else {
X      lon = ATAN8(TANDEG(arg_lat) * cosi);
X      lon = RADTODEG * lon;
X      if (arg_lat > 90.0 && arg_lat < 270.0)  lon += 180.0;
X    }
X    lon = degnorm(lon + e->kn);
X    *alng = lon;
X    *alngspeed = 0.111404;  /* 6'41.05" per day */
X    *arad = 2 * pd[MOON].axis * e->ex;
X    /*
X    ** To test Gravalaines error, return unprojected long in alat.
X    ** the correct latitude would be:
X    ** *alat = RADTODEG * ASIN8(SINDEG(arg_lat) * SINDEG(e->in));
X    */
#ifdef ASTROLOG
X    *alat = RADTODEG * ASIN8(SINDEG(arg_lat) * SINDEG(e->in));
#else
X    *alat = degnorm(arg_lat + e->kn); /* unprojected longitude, no nut */
#endif
X    }
X    break;
X
X  default:
X    return ERR;
X  } /* end switch */
X
X  if (calc_nut)
X    *alng += nut;
X  *alng = smod8360(*alng);  /* normalize to circle */
X  return OK;
}
X
X
/* helio to geocentric conversion */
X
void togeo(lngearth, radearth, lng, rad, zet, alnggeo, aradgeo)
REAL8 lngearth;
REAL8 radearth;
REAL8 lng;
REAL8 rad;
REAL8 zet;
REAL8 *alnggeo;
REAL8 *aradgeo;
{
X  REAL8 r1, x, y;
X
X  r1 = sqrt(rad * rad - zet * zet);
X  x = r1 * COS8(DEGTORAD * lng) - radearth * COS8(DEGTORAD * lngearth);
X  y = r1 * SIN8(DEGTORAD * lng) - radearth * SIN8(DEGTORAD * lngearth);
X  *aradgeo = sqrt(x * x + y * y + zet * zet);
X  x = test_near_zero(x);
X  *alnggeo = smod8360(RADTODEG * ATAN28(y, x));
}
X
X
/*
** helup()
** prepares the orbital elements and the disturbation arguments for the
** inner planets and the moon. helup(t) is called by hel() and by calc().
** helup() returns its results in global variables.
** helup() remembers the t it has been called with before and does
** not recalculate its results when it is called more than once with
** the same t.
*/
X
void helup(jd_ad)
REAL8 jd_ad;
{
X  int i;
X  static REAL8 thelup = HUGE8;  /* is initialized only once at load time */
X  struct elements *e = el;      /* pointer to el[i] */
X  struct elements *ee = el;     /* pointer to el[EARTH] */
X  struct eledata  *d = pd;      /* pointer to pd[i] */
X  REAL8 td, ti, ti2, tj1, tj2, tj3;
X
X  if (thelup == jd_ad)
X    return; /* if already calculated then return */
X
X  for (i = SUN; i <= MARS; i++, d++, e++) {
X    td = jd_ad - d->epoch;
X    ti = e->tj = td / 36525.0;  /* julian centuries from epoch */
X    ti2 = ti * ti;
X    tj1 = ti / 3600.0;  /* used when coefficients are in seconds of arc */
X    tj2 = ti * tj1;
X    tj3 = ti * tj2;
X    e->lg = mod8360(d->lg0 + d->lg1 * td  + d->lg2 * tj2 + d->lg3 * tj3);
X    /* also with moon lg1 *td is exact to 10e-8 degrees within 5000 years */
X    e->pe = mod8360(d->pe0 + d->pe1 * tj1 + d->pe2 * tj2 + d->pe3 * tj3);
X    e->ex = d->ex0 + d->ex1 * ti + d->ex2 * ti2;
X    e->kn = mod8360(d->kn0 + d->kn1 * tj1 + d->kn2 * tj2 + d->kn3 * tj3);
X    e->in = d->in0 + d->in1 * tj1 + d->in2 * tj2;
X    e->ma = smod8360(e->lg - e->pe);
X
X    if (i == MOON) {
X      /* calculate ekliptic according Newcomb, APAE VI,
X      ** and nutation according Exp.Suppl. 1961, identical
X      ** with Mark Potttenger elemnut()
X      ** all terms >= 0.01" only .
X      ** The 1984 IAU Theory of Nutation, as published in
X      ** AE 1984 suppl. has not yet been implemented
X      ** because it would mean to use other elements of
X      ** moon and sun */
X
X      REAL8 mnode, mlong2, slong2, mg, sg, d2;
X
X      mnode  = DEGTORAD * e->kn;        /* moon's mean node */
X      mlong2 = DEGTORAD * 2.0 * e->lg;  /* 2 x moon's mean longitude */
X      mg     = DEGTORAD * e->ma;        /* moon's mean anomaly (g1) */
X      slong2 = DEGTORAD * 2.0 * ee->lg; /* 2 x sun's mean longitude (L), with
X                                        the phase 180 deg earth-sun irrelevant
X                                        because 2 x 180 = 360 deg */
X      sg     = DEGTORAD * ee->ma; /* sun's mean anomaly = earth's */
X      d2     = mlong2 - slong2;   /* 2 x elongation of moon from sun */
X      meanekl = ekld[0] + ekld[1] * tj1 + ekld[2] * tj2 + ekld[3] * tj3;
X      ekl = meanekl +
X        (9.2100 * COS8(mnode)
X        - 0.0904 * COS8(2.0 * mnode)
X        + 0.0183 * COS8(mlong2 - mnode)
X        + 0.0884 * COS8(mlong2)
X        + 0.0113 * COS8(mlong2 + mg)
X        + 0.5522 * COS8(slong2)
X        + 0.0216 * COS8(slong2 + sg)) / 3600.0;
X        nut = ((-17.2327 - 0.01737 * ti) * SIN8(mnode)
X        + 0.2088 * SIN8(2.0 * mnode)
X        + 0.0675 * SIN8(mg)
X        - 0.0149 * SIN8(mg - d2)
X        - 0.0342 * SIN8(mlong2 - mnode)
X        + 0.0114 * SIN8(mlong2 - mg)
X        - 0.2037 * SIN8(mlong2)
X        - 0.0261 * SIN8(mlong2 + mg)
X        + 0.0124 * SIN8(slong2 - mnode)
X        + 0.0214 * SIN8(slong2 - sg)
X        - 1.2729 * SIN8(slong2)
X        - 0.0497 * SIN8(slong2 + sg)
X        + 0.1261 * SIN8(sg)) / 3600.0;
X    }
X  }
X
X  /* calculate the arguments sa[] for the disturbation terms */
X  ti = (jd_ad - EPOCH1850) / 365.25;  /* julian years from 1850 */
X  for (i = 0; i < SDNUM; i++)
X    sa [i] = mod8360(_sd [i].sd0 + _sd [i].sd1 * ti);
X  /*
X  ** sa[2] += 0.3315 * SIN8 (DEGTORAD *(133.9099 + 38.39365 * el[SUN].tj));
X  **
X  ** correction of jupiter perturbation argument for sun from Pottenger;
X  ** creates only .03" and 1e-7 rad, not applied because origin unclear */
X  thelup = jd_ad;               /* note the last helup time */
}
X
X
/*
** hel()
** Computes the heliocentric positions for all planets except the moon.
** The outer planets from Jupiter onwards, including Chiron, are
** actually done by a subsequent call to outer_hel() which takes
** exactly the same parameters.
** hel() does true position relative to the mean ecliptic and equinox
** of date. Nutation is not added and must be done so by the caller.
** The latitude of the Sun (max. 0.5") is neglected and always returned
** as zero.
**
** return: OK or ERR
*/
X
int hel(planet, t, al, ar, az, alp, arp, azp)
int planet;   /* planet index as defined by placalc.h */
REAL8 t;      /* relative juliand date, ephemeris time */
X              /* Now come 6 pointers to return values. */
REAL8 *al;    /* longitude in degrees */
REAL8 *ar;    /* radius in AU */
REAL8 *az;    /* distance from ecliptic in AU */
REAL8 *alp;   /* speed in longitude, degrees per day */
REAL8 *arp;   /* speed in radius, AU per day */
REAL8 *azp;   /* speed in z, AU per day */
{
X  register struct elements *e;
X  register struct eledata  *d;
X  REAL8 lk = 0.0;
X  REAL8 rk = 0.0;
X  REAL8 b, h1, sini, sinv, cosi, cosu, cosv, man, truanom, esquare,
X    k8, u, up, v, vp;
X
X  if (planet >= JUPITER)
X    return (outer_hel(planet, t, al, ar, az, alp, arp, azp));
X  if (planet < SUN || planet == MOON)
X    return ERR;
X
X  e = &el[planet];
X  d = &pd[planet];
X  sini = SIN8(DEGTORAD * e->in);
X  cosi = COS8(DEGTORAD * e->in);
X  esquare = sqrt((1.0 + e->ex) / (1.0 - e->ex)); /* H6 in old version */
X  man = e->ma;
X  if (planet == EARTH)  /* some longperiodic terms in mean longitude */
X    man += (0.266 * SIN8 (DEGTORAD * (31.8 + 119.0 * e->tj))
X      + 6.40 * SIN8(DEGTORAD * (231.19 + 20.2 * e->tj))
X      + (1.882-0.016*e->tj) * SIN8(DEGTORAD * (57.24 + 150.27 * e->tj))
X      ) / 3600.0;
X  if (planet == MARS)  /* some longperiodic terms */
X    man += (0.606 * SIN8(DEGTORAD * (212.87 + e->tj * 119.051))
X      + 52.490 * SIN8(DEGTORAD * (47.48 + e->tj * 19.771))
X      +  0.319 * SIN8(DEGTORAD * (116.88 + e->tj * 773.444))
X      +  0.130 * SIN8(DEGTORAD * (74 + e->tj * 163))
X      +  0.280 * SIN8(DEGTORAD * (300 + e->tj * 40.8))
X      -  (37.05 +13.5 * e->tj)
X      ) / 3600.0;
X  u = fnu (man, e->ex, 0.0000003); /* error 0.001" returns radians */
X  cosu = COS8(u);
X  h1 = 1 - e->ex * cosu;
X  *ar = d->axis * h1;
X  if (ABS8(rPi - u) < TANERRLIMIT)
X    truanom = u; /* very close to aphel */
X  else
X    truanom = 2.0 * ATAN8(esquare * TAN8(u * 0.5)); /* true anomaly, rad*/
X  v = smod8360(truanom * RADTODEG + e->pe - e->kn); /* argument of latitude */
X  if (sini == 0.0 || ABS8(v -  90.0) < TANERRLIMIT
X    || ABS8(v - 270.0) < TANERRLIMIT) {
X    *al = v;
X  } else {
X    *al = RADTODEG * ATAN8(TAN8(v * DEGTORAD) * cosi);
X    if (v > 90.0 && v < 270.0)  *al += 180.0;
X  }
X  *al = smod8360(*al + e->kn);
X  sinv = SIN8(v * DEGTORAD);
X  cosv = COS8(v * DEGTORAD);
X  *az = *ar * sinv * sini;
X  b = ASIN8(sinv * sini);     /* latitude in radians */
X  k8 = cosv / COS8(b) * sini;
X  up = 360.0 / d->period / h1;    /* du/dt degrees/day */
X  if (ABS8(rPi - u) < TANERRLIMIT)
X    vp = up / esquare;  /* speed at aphel */
X  else
X    vp = up * esquare * (1 + COS8 (truanom)) / (1 + cosu);
X  /* dv/dt degrees/day */
X  *arp = d->axis * up * DEGTORAD * SIN8(u) * e->ex;
X  /* dr/dt AU/day */
X  *azp = *arp * sinv * sini + *ar * vp * DEGTORAD * cosv * sini;  /* dz/dt */
X  *alp = vp / cosi * (1 - k8 * k8);
X
X  /* now come the disturbations */
X
X  switch (planet) {
X    REAL8 am, mma, ema, u2;
X
X  case EARTH:
X    /*
X    ** earth has some special moon values and a disturbation series due to the
X    ** planets. The moon stuff is due to the fact, that the mean elements
X    ** give the coordinates of the earth-moon barycenter. By adding the
X    ** corrections we effectively reduce to the center of the earth.
X    ** We neglect the correction in latitude, which is about 0.5", because
X    ** for astrological purposes we want the Sun to have latitude zero.
X    */
X    am = DEGTORAD * smod8360(el[MOON].lg - e->lg + 180.0); /* degrees */
X    mma = DEGTORAD * el[MOON].ma;
X    ema = DEGTORAD * e->ma;
X    u2 = 2.0 * DEGTORAD * (e->lg - 180.0 - el[MOON].kn); /* 2u' */
X    lk = 6.454 * SIN8(am)
X      + 0.013 * SIN8(3.0 * am)
X      + 0.177 * SIN8(am + mma)
X      - 0.424 * SIN8(am - mma)
X      + 0.039 * SIN8(3.0 * am - mma)
X      - 0.064 * SIN8(am + ema)
X      + 0.172 * SIN8(am - ema)
X      - 0.013 * SIN8(am - mma - ema)
X      - 0.013 * SIN8(u2);
X    rk = 13360 * COS8(am)
X      + 30    * COS8(3.0 * am)
X      + 370   * COS8(am + mma)
X      - 1330  * COS8(am - mma)
X      + 80    * COS8(3.0 * am - mma)
X      - 140   * COS8(am + ema)
X      + 360   * COS8(am - ema)
X      - 30    * COS8(am - mma - ema)
X      + 30    * COS8(u2);
X    /* long periodic term from mars 15g''' - 8g'', Vol 6 p19, p24 */
X    lk += 0.202 * SIN8(DEGTORAD * (315.6 + 893.3 * e->tj));
X    disturb(earthkor, al, ar, lk, rk, man);
X    break;
X
X  case MERCURY:  /* only normal disturbation series */
X    disturb(mercurykor, al, ar, 0.0, 0.0, man);
X    break;
X
X  case VENUS:  /* some longperiod terms and normal series */
X    lk = (2.761 - 0.22*e->tj) * SIN8(DEGTORAD * (237.24 + 150.27 * e->tj))
X    + 0.269 * SIN8(DEGTORAD * (212.2  + 119.05 * e->tj))
X    - 0.208 * SIN8(DEGTORAD * (175.8  + 1223.5 * e->tj));
X    /* make seconds */
X    disturb(venuskor, al, ar, lk, 0.0, man);
X    break;
X
X  case MARS:  /* only normal disturbation series */
X    disturb(marskor, al, ar, 0.0, 0.0, man);
X    break;
X  }
X  return OK;
}
X
X
void disturb(k, al, ar, lk, rk, man)
register struct kor *k;  /* ENDMARK-terminated array of struct kor */
REAL8 *al, /* longitude in degrees, use a pointer to return value */
*ar;       /* radius in AU */
REAL8 lk,  /* longitude correction in SECONDS OF ARC */
X           /* function can be called with an lk and rk already
X              != 0, but no value is returned */
rk,        /* radius correction in units of 9th place of log r */
man;       /* mean anomaly of planet */
{
X  REAL8 arg;
X  while (k->j != ENDMARK) {
X    arg = k->j * sa[k->k] + k->i * man;
X    lk += k->lampl * COS8(DEGTORAD * (k->lphase - arg));
X    rk += k->rampl * COS8(DEGTORAD * (k->rphase - arg));
X    k++;
X  }
X  *ar *= EXP10(rk * 1.0E-9);  /* 10^rk */
X  *al += lk / 3600.0;
}
X
X
int moon(al, ar, az)  /* return OK or ERR */
REAL8 *al;
REAL8 *ar;
REAL8 *az;
{
X  REAL8 a1,a2,a3,a4,a5,a6,a7,a8,a9,c2,c4,arg,b,d,f,dgc,dlm,dpm,dkm,dls;
X  REAL8 ca, cb, cd, f_2d, f_4d, g1c,lk,lk1,man,ms,nib,s,sinarg,sinp,sk;
X  REAL8 t, tb, t2c, r2rad, i1corr, i2corr, dlid;
X  int i;
X  struct elements *e;
X  struct m45dat   *mp;
#if MOON_TEST_CORR
X  struct m5dat    *m5p;
#endif
X  e = &el[MOON];
X  t = e->tj * 36525;  /* days from epoch 1900 */
X
X  /* new format table II, parameters in full rotations of 360 degrees */
X  r2rad = 360.0 * DEGTORAD;
X  tb  = t * 1e-12;  /* units of 10^12 */
X  t2c = t * t * 1e-16;  /* units of 10^16 */
X  a1 = SIN8(r2rad * (0.53733431 -  10104982 * tb + 191 * t2c));
X  a2 = SIN8(r2rad * (0.71995354 - 147094228 * tb +  43 * t2c));
X  c2 = COS8(r2rad * (0.71995354 - 147094228 * tb +  43 * t2c));
X  a3 = SIN8(r2rad * (0.14222222 +   1536238 * tb));
X  a4 = SIN8(r2rad * (0.48398132 - 147269147 * tb +  43 * t2c));
X  c4 = COS8(r2rad * (0.48398132 - 147269147 * tb +  43 * t2c));
X  a5 = SIN8(r2rad * (0.52453688 - 147162675 * tb +  43 * t2c));
X  a6 = SIN8(r2rad * (0.84536324 -  11459387 * tb));
X  a7 = SIN8(r2rad * (0.23363774 +   1232723 * tb + 191 * t2c));
X  a8 = SIN8(r2rad * (0.58750000 +   9050118 * tb));
X  a9 = SIN8(r2rad * (0.61043085 -  67718733 * tb));
X
X  dlm = 0.84 * a3 + 0.31 * a7 + 14.27 * a1 + 7.261  * a2 + 0.282 * a4
X    + 0.237 * a6;
X  dpm = -2.1  * a3 - 2.076  * a2 - 0.840 * a4 - 0.593 * a6;
X  dkm = 0.63 * a3 + 95.96 * a2 + 15.58 * a4 + 1.86 * a5;
X  dls = -6.4  * a3 - 0.27 * a8 - 1.89  * a6 + 0.20 * a9;
X  dgc = (-4.318 * c2 - 0.698 * c4) / 3600.0 / 360.0;  /* in revolutions */
X  dgc = (1.000002708 + 139.978 * dgc);  /* in this form used later */
X  man = DEGTORAD * (e->ma + (dlm - dpm) / 3600.0);
X  /* man with periodic and secular corr. */
X  ms  = DEGTORAD * (el[EARTH].ma + dls / 3600.0);
X  f   = DEGTORAD * (e->lg - e->kn + (dlm - dkm) / 3600.0);
X  d   = DEGTORAD * (e->lg + 180 - el[EARTH].lg + (dlm - dls) / 3600.0);
X
X  lk = lk1 = sk = sinp = nib = g1c = 0;
X  i1corr = 1.0 - 6.8320E-8 * t;
X  i2corr = dgc * dgc; /* i2 occurs only as -2, 2 */
X  for (i = 0, mp = m45; i < NUM_MOON_CORR; i++, mp++) {
X    /* arg = mp->i0 * man + mp->i1 * ms + mp->i2 * f + mp->i3 * d; */
X    arg = mp->i0 * man;
X    arg += mp->i3 * d;
X    arg += mp->i2 * f;
X    arg += mp->i1 * ms;
X    sinarg = SIN8(arg);
X    /*
X    ** now apply corrections due to changes in constants;
X    ** we correct only terms in l' (i1) and F (i2), not in l (i0), because
X    ** the latter are < 0.05"
X    ** We don't apply corrections  for cos(arg), i.e. for parallax
X    */
X    if (mp->i1 != 0) {  /* i1 can be -2, -1, 0, 1, 2 */
X      sinarg *= i1corr;
X      if  (mp->i1 == 2 || mp->i1 == -2)
X        sinarg *= i1corr;
X    }
X    if (mp->i2 != 0)  /* i2 can be -2, 0, 2 */
X      sinarg *= i2corr;
X    lk += mp->lng * sinarg;
X    sk += mp->lat * sinarg;
X    sinp += mp->par * COS8 (arg) ;
X  }
X
#if MOON_TEST_CORR  /* optionally add more lunar longitudes  */
X  for (m5p = m5; m5p->i0 != 99; m5p++) {  /* i0 = 99 is end mark */
X    arg = m5p->i0 * man + m5p->i1 * ms + m5p->i2 * f + m5p->i3 * d;
X    sinarg = SIN8(arg);
X    lk1 += m5p->lng * sinarg;
X  }
#endif
X
X  /*
X  ** now compute some planetary terms in longitude, list i delta;
X  ** we take all > 0.5" and neglect secular terms in the arguments. These
X  ** produce phase errors > 10 degrees only after 3000 years.
X  */
X  dlid =  0.822 * SIN8 (r2rad * (0.32480 - 0.0017125594 * t));
X  dlid += 0.307 * SIN8 (r2rad * (0.14905 - 0.0034251187 * t));
X  dlid += 0.348 * SIN8 (r2rad * (0.68266 - 0.0006873156 * t));
X  dlid += 0.662 * SIN8 (r2rad * (0.65162 + 0.0365724168 * t));
X  dlid += 0.643 * SIN8 (r2rad * (0.88098 - 0.0025069941 * t));
X  dlid += 1.137 * SIN8 (r2rad * (0.85823 + 0.0364487270 * t));
X  dlid += 0.436 * SIN8 (r2rad * (0.71892 + 0.0362179180 * t));
X  dlid += 0.327 * SIN8 (r2rad * (0.97639 + 0.0001734910 * t));
X
X  /* without nutation */
X  *al = smod8360(e->lg + (dlm + lk + lk1 + dlid) / 3600.0);
X
X  /* solar Terms in latitude Nibeta */
X  f_2d = f - 2.0 * d;
X  f_4d = f - 4.0 * d;
X  nib += -526.069 * SIN8(                   f_2d);
X  nib +=   -3.352 * SIN8(                   f_4d);
X  nib +=   44.297 * SIN8( man             + f_2d);
X  nib +=   -6.000 * SIN8( man             + f_4d);
X  nib +=   20.599 * SIN8(-man             + f   );
X  nib +=  -30.598 * SIN8(-man             + f_2d);
X  nib +=  -24.649 * SIN8(-2*man           + f   );
X  nib +=   -2.000 * SIN8(-2*man           + f_2d);
X  nib +=  -22.571 * SIN8(          ms     + f_2d);
X  nib +=   10.985 * SIN8(         -ms     + f_2d);
X
X  /* new gamma1C from 29 Jul 88, all terms > 0.4 " in table III, code 2 */
X  g1c += -0.725 * COS8(          d);
X  g1c +=  0.601 * COS8(      2 * d);
X  g1c +=  0.394 * COS8(      3 * d);
X  g1c += -0.445 * COS8(man                   + 4 * d);
X  g1c +=  0.455 * COS8(man                   + 1 * d);
X  g1c +=  5.679 * COS8(2 * man               - 2 * d);
X  g1c += -1.300 * COS8(3 * man                      );
X  g1c += -1.302 * COS8(            ms               );
X  g1c += -0.416 * COS8(            ms        - 4 * d);
X  g1c += -0.740 * COS8(        2 * ms        - 2 * d);
X  g1c +=  0.787 * COS8(    man +   ms        + 2 * d);
X  g1c +=  0.461 * COS8(    man +   ms               );
X  g1c +=  2.056 * COS8(    man +   ms        - 2 * d);
X  g1c += -0.471 * COS8(    man +   ms        - 4 * d);
X  g1c += -0.443 * COS8(   -man +   ms        + 2 * d);
X  g1c +=  0.679 * COS8(   -man +   ms               );
X  g1c += -1.540 * COS8(   -man +   ms        - 2 * d);
X
X  s =  f + sk / 3600.0 * DEGTORAD;
X  ca = 18519.7 + g1c;
X  cb = -0.000336992 * ca * dgc * dgc * dgc;
X  cd = ca / 18519.7;
X  b = (ca * SIN8(s) * dgc  + cb * SIN8(3.0 * s) + cd * nib) / 3600.0;
X
X  /* we neglect the planetary terms in latitude, code 4 in table III */
X
X  sinp = (sinp + 3422.451);
X  /*
X  ** Improved lunar ephemeris and APAE until ca. 1970 had here
X  ** 3422.54 as constant of moon's sine parallax.
X  ** The difference can be applied by direct addition of 0.089" to
X  ** our parallax results.
X  **
X  ** To get the radius in A.U. from the sine parallax,
X  ** we use 1964 IAU value 8.794" for solar parallax.
X  ** sinp is still in seconds of arc.
X  ** To calculate moon parallax in " it would be:
X  ** p = sinp (1  + sinp * sinp * 3.917405E-12)
X  ** based on the formula p = sinp + 1/6 sinp^3
X  ** and taking into account the conversion of " to radians.
X  ** The semidiameter of the moon is: (Expl.Suppl. 61, p 109)
X  ** s = 0.0796 + 0.272446 * p
X  */
X
X  *ar = 8.794 / sinp;
X  *az = *ar * SIN8(DEGTORAD * b);
X  return OK;
}
X
X
/*
** outer_hel()
** Computes the position of Jupiter, Saturn, Uranus, Neptune, Pluto and
** Chiron by reading our stored ephemeris in steps of 80 (!) days and
** applying a high order interpolation to it. The interpolation errors are
** less than 0.01" seconds of arc.
** The stored ephemeris is packed in a special format consisting of
** 32 bit numbers; it has been created on the Astrodienst Unix system
** by numerical integration with routines provided originally by Marc
** Pottenger, USA, which we improved for better long term precision.
** Because the Unix system uses a different byte order than the MSDOS
** systems, the bytes must be reordered for MSDOS after reading from
** the binary files.
**
** outer_hel() takes the same parameters as hel().
** It returns the same type of values.
**
** The access to the ephemeris files is done in the functions chi_file_posit()
** and lrz_file_posit().
*/
X
int outer_hel(planet, jd_ad, al, ar, az, alp, arp, azp)
int planet;
REAL8 jd_ad;  /* jd_ad Astrodienst relative Julian ephemeris time */
REAL8 *al;
REAL8 *ar;
REAL8 *az;
REAL8 *alp;
REAL8 *arp;
REAL8 *azp;
{
X  static FILE *outerfp = NULL, *chironfp = NULL, *asterfp = NULL;
X  static double last_j0_outer = HUGE8;
X  static double last_j0_chiron = HUGE8;
X  static double last_j0_aster = HUGE8;
X  static long icoord[6][5][3], chicoord[6][3], ascoord[6][4][3];
X  REAL8 j0, jd, jfrac;
X  REAL8 l[6], r[6], z[6];
X  int n, order, p;
X
X  if ((planet < JUPITER || planet > PLUTO) && planet != CHIRON &&
X    (planet < CERES || planet > VESTA))
X    return ERR;
X  jd = jd_ad + JUL_OFFSET;
X  j0 = RFloor((jd - 0.5) / EPHE_STEP) * EPHE_STEP + 0.5;
X  jfrac = (jd - j0) / EPHE_STEP;
X  if (planet == CHIRON) {
X    if (last_j0_chiron != j0) {
X      for (n = 0; n < 6; n++) { /* read 6 days */
X        jd = j0 + (n - 2) * EPHE_STEP;
X        if (chi_file_posit(jd, &chironfp) != OK)
X          return ERR;
X        fread(&chicoord[n][0], sizeof(word4), 3, chironfp);
X        longreorder((UCHAR *)&chicoord[n][0], 3*4);
X      }
X      last_j0_chiron = j0;
X    }
X    for (n = 0; n < 6; n++) {
X      l[n] = chicoord[n][0] / DEG2MSEC;
X      r[n] = chicoord[n][1] / AU2INT;
X      z[n] = chicoord[n][2] / AU2INT;
X    }
X  } else if (planet >= CERES && planet <= VESTA) {
X    if (last_j0_aster != j0) {  /* read all 4 asteroids for 6 steps */
X      for (n = 0; n < 6; n++) {
X        jd = j0 + (n - 2) * EPHE_STEP;
X        if (ast_file_posit(jd, &asterfp) != OK)
X          return ERR;
X        fread(&ascoord[n][0][0], sizeof(word4), 12, asterfp);
X        longreorder((UCHAR *)&ascoord[n][0][0], 12*4);
X      }
X      last_j0_outer = j0;
X    }
X    p = planet - CERES;
X    for (n = 0; n < 6; n++) {
X      l[n] = ascoord[n][p][0] / DEG2MSEC;
X      r[n] = ascoord[n][p][1] / AU2INT;
X      z[n] = ascoord[n][p][2] / AU2INT;
X    }
X  } else {  /* an outerplanet */
X    if (last_j0_outer != j0) {  /* read all 5 planets for 6 steps */
X      for (n = 0; n < 6; n++) {
X        jd = j0 + (n - 2) * EPHE_STEP;
X        if (lrz_file_posit(jd, &outerfp) != OK)
X          return ERR;
X        fread(&icoord[n][0][0], sizeof(word4), 15, outerfp);
X        longreorder((UCHAR *)&icoord[n][0][0], 15*4);
X      }
X      last_j0_outer = j0;
X    }
X    p = planet - JUPITER;
X    for (n = 0; n < 6; n++) {
X      l[n] = icoord[n][p][0] / DEG2MSEC;
X      r[n] = icoord[n][p][1] / AU2INT;
X      z[n] = icoord[n][p][2] / AU2INT;
X    }
X  }
X  if (planet > SATURN)
X    order = 3;
X  else
X    order = 5;
X  inpolq(2, order, jfrac, l, al, alp);
X  *alp /= EPHE_STEP;
X  inpolq(2, order, jfrac, r, ar, arp);
X  *arp /= EPHE_STEP;
X  inpolq(2, order, jfrac, z, az, azp);
X  *azp /= EPHE_STEP;
X  return OK;
}
X
X
/*
** quicker Everett interpolation, after Pottenger
** version 9 Jul 1988 by Alois Treindl
** return OK or ERR.
*/
X
int inpolq(n, o, p, x, axu, adxu)
int n,     /* interpolate between x[n] and x[n-1], at argument n+p */
o;         /* order of interpolation, maximum 5 */
double p,  /* argument , intervall [0..1] */
x[],       /* array of function values, x[n-o]..x[n+o] must exist */
*axu,      /* pointer for storage of result */
*adxu;     /* pointer for storage of dx/dt  */
{
X  static double q, q2, q3, q4, q5, p2, p3, p4, p5, u, u0, u1, u2;
X  static double lastp = 9999;
X  double dm2, dm1, d0, dp1, dp2,
X    d2m1, d20, d2p1, d2p2, d30, d3p1, d3p2, d4p1, d4p2;
X  double offset = 0.0;
X
X  if (lastp != p) {
X    q  = 1.0-p;
X    q2 = q*q;
X    q3 = (q+1.0)*q*(q-1.0)/6.0;       /* q - 1 over 3; u5 */
X    p2 = p*p;
X    p3 = (p+1.0)*p*(p-1.0)/6.0;       /* p - 1 over 3; u8 */
X    u  = (3.0*p2-1.0)/6.0;
X    u0 = (3.0*q2-1.0)/6.0;
X    q4 = q2*q2;                       /* f5 */
X    p4 = p2*p2;                       /* f4 */
X    u1 = (5.0*p4-15.0*p2+4.0)/120.0;  /* u1 */
X    u2 = (5.0*q4-15.0*q2+4.0)/120.0;  /* u2 */
X    q5 = q3*(q+2.0)*(q-2.0)/20.0;     /* q - 2 over 5; u6 */
X    p5 = (p+2.0)*p3*(p-2.0)/20.0;     /* p - 2 over 5; u9 */
X    lastp = p;
X  }
X  dm1 = x[n] - x[n-1];
X  if (dm1 > 180.0)
X    dm1 -= 360.0;
X  if (dm1 < -180.0)
X    dm1 += 360.0;
X  d0 = x[n+1] - x[n];
X  if (d0 > 180.0) {
X    d0 -= 360.0;
X    offset = 360.0;
X  }
X  if (d0 < -180.0) {
X    d0 += 360.0;
X    offset = -360.0;
X  }
X  dp1 = x[n+2] - x[n+1];
X  if (dp1 > 180.0)
X    dp1 -= 360.0;
X  if (dp1 < -180.0)
X    dp1 += 360.0;
X  d20  = d0 - dm1;    /* f8 */
X  d2p1 = dp1 - d0;    /* f9 */
X
X  /* Everett interpolation 3rd order */
X
X  *axu = q*(x[n] + offset) + q3*d20 + p*x[n+1] + p3*d2p1;
X  *adxu = d0 + u*d2p1 - u0*d20;
X  if (o > 3) {    /* 5th order */
X    dm2 = x[n-1] - x[n-2];
X    if (dm2 > 180.0)
X      dm2 -= 360.0;
X    if (dm2 < -180.0)
X      dm2 += 360.0;
X    dp2 = x[n+3] - x[n+2];
X    if (dp2 > 180.0)
X      dp2 -= 360.0;
X    if (dp2 < -180.0)
X      dp2 += 360.0;
X    d2m1 = dm1 - dm2;
X    d2p2 = dp2 - dp1;
X    d30  = d20 - d2m1;
X    d3p1 = d2p1 - d20;
X    d3p2 = d2p2 - d2p1;
X    d4p1 = d3p1 - d30;     /* f7 */
X    d4p2 = d3p2 - d3p1;    /* f */
X    *axu  += p5*d4p2 + q5*d4p1;
X    *adxu += u1*d4p2 - u2*d4p1;
X  }
X  return OK;
}
X
X
/*
** position lrz file at proper position for julian date jd;
** Return OK or ERR.  Version for outer planets.
*/
X
int lrz_file_posit(jd, lrzfpp)
double jd;     /* full Julian day number, not Astrodienst relative */
FILE **lrzfpp; /* pointer to file pointer; this function
X                  opens or closes the ephemeris file, and caller
X                  should keep it open while using it. The caller
X                  should close it when he is finished with using
X                  the placalc() package. */
{
X  int filenr;
X  long posit, jlong;
X  char fname[cchSzDef];
X  static int open_lrznr = -10000; /* local memory to remember whether
X    an already open file is the one with
X    the correct number for this date */
X
X  jlong = (long)RFloor(jd);
X  filenr = (int)(jlong / EPHE_DAYS_PER_FILE);
X  if (jlong < 0 && filenr * EPHE_DAYS_PER_FILE != jlong)
X    filenr--;
X  posit = jlong - filenr * EPHE_DAYS_PER_FILE;
X  posit = (posit / (int)EPHE_STEP) * EPHE_OUTER_BSIZE;
X  if (*lrzfpp == NULL || open_lrznr != filenr) { /* no or wrong open file */
X    open_lrznr = -10000;
X    sprintf(fname, "%s%s%d", EPHE_OUTER, filenr < 0 ? "M" : "", abs(filenr));
X    if (*lrzfpp != NULL)
X      fclose(*lrzfpp);
X    *lrzfpp = FileOpen(fname, 2);
X    if (*lrzfpp == NULL) {
X      ErrorEphem(fname, -1);
X      return ERR;
X    }
X    open_lrznr = filenr;
X  }
X  if (fseek(*lrzfpp, posit, 0) == 0)
X    return OK;
X  ErrorEphem(fname, posit);
X  return ERR; /* this fseek error occurs only with incomplete files */
}
X
X
/*
** position cpjv file at proper position for julian date jd;
** Return OK or ERR.  Version for asteroids.
** Sister function to lrz_file_posit().
*/
X
int ast_file_posit(jd, astfpp)
double jd;     /* full Julian day number, not Astrodienst relative */
FILE **astfpp; /* pointer to file pointer; this function
X                  opens or closes the ephemeris file, and caller
X                  should keep it open while using it. */
{
X  int filenr;
X  long posit, jlong;
X  char fname[cchSzDef];
X  static int open_astnr = -10000; /* local memory to remember whether
X    an already open file is the one with
X    the correct number for this date */
X
X  jlong = (long)RFloor(jd);
X  filenr = (int)(jlong / EPHE_DAYS_PER_FILE);
X  if (jlong < 0 && filenr * EPHE_DAYS_PER_FILE != jlong)
X    filenr--;
X  posit = jlong - filenr * EPHE_DAYS_PER_FILE;
X  posit = (posit / (int)EPHE_STEP) * EPHE_ASTER_BSIZE;
X  if (*astfpp == NULL || open_astnr != filenr) { /* no or wrong open file */
X    open_astnr = -10000;
X    sprintf(fname, "%s%s%d", EPHE_ASTER, filenr < 0 ? "M" : "", abs(filenr));
X    if (*astfpp != NULL)
X      fclose(*astfpp);
X    *astfpp = FileOpen(fname, 2);
X    if (*astfpp == NULL) {
X      ErrorEphem(fname, -1);
X      return ERR;
X    }
X    open_astnr = filenr;
X  }
X  if (fseek(*astfpp, posit, 0) == 0)
X    return OK;
X  ErrorEphem(fname, posit);
X  return ERR; /* this fseek error occurs only with incomplete files */
}
X
X
/*
** position chiron file at proper position for julian date jd;
** Return OK or ERR. Version for Chiron.
*/
X
int chi_file_posit(jd, lrzfpp)
double jd;  /* full Julian day number, not Astrodienst relative */
FILE **lrzfpp; /* pointer to file pointer; this function
X                  opens or closes the ephemeris file, and caller
X                  should keep it open while using it */
{
X  int filenr;
X  long posit, jlong;
X  char fname[cchSzDef];
X  static int open_lrznr = -10000; /* local memory to remember whether
X    an already open file is the one with
X    the correct number for this date */
X
X  jlong = (long)RFloor(jd);
X  filenr = (int)(jlong / EPHE_DAYS_PER_FILE);
X  if (jlong < 0 && filenr * EPHE_DAYS_PER_FILE != jlong)
X    filenr--;
X  posit = jlong - filenr * EPHE_DAYS_PER_FILE;
X  posit = (posit / (int)EPHE_STEP) * EPHE_CHIRON_BSIZE;
X  if (*lrzfpp == NULL || open_lrznr != filenr) { /* no or wrong open file */
X    open_lrznr = -10000;
X    sprintf(fname, "%s%s%d", EPHE_CHIRON, filenr < 0 ? "M" : "", abs(filenr));
X    if (*lrzfpp != NULL)
X      fclose(*lrzfpp);
X    *lrzfpp = FileOpen(fname, 2);
X    if (*lrzfpp == NULL) {
X      ErrorEphem(fname, -1);
X      return ERR;
X    }
X    open_lrznr = filenr;
X  }
X  if (fseek (*lrzfpp, posit, 0) == 0)
X    return OK;
X  ErrorEphem(fname, posit);
X  return ERR; /* this fseek error occurs only with incomplete files */
}
#endif /* PLACALC */
X
/* placalc.c */
SHAR_EOF
  $shar_touch -am 1223232998 'placalc.c' &&
  chmod 0644 'placalc.c' ||
  echo 'restore of placalc.c failed'
  shar_count="`wc -c < 'placalc.c'`"
  test 43215 -eq "$shar_count" ||
    echo "placalc.c: original size 43215, current size $shar_count"
fi
# ============= placalc.h ==============
if test -f 'placalc.h' && test X"$1" != X"-c"; then
  echo 'x - skipping placalc.h (File already exists)'
else
  echo 'x - extracting placalc.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'placalc.h' &&
/*
** Astrolog (Version 5.40) File: placalc.h
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
/* "planet" is defined to be cp0.obj, but is often a local in Placalc code. */
#undef planet
X
X
#define EPHE_PATH EPHE_DIR
#define HUGE8 1.7E+308     /* biggest value for REAL8 */
X
extern int lrz_file_posit();
extern int ast_file_posit();
extern int chi_file_posit();
extern int outer_hel();
extern void longreorder();
extern int inpolq();
X
#ifdef PLACALC
/************************************************************
$Header: placalc.h,v 1.4 93/03/22 10:08:39 alois Exp $
definitions and constants for planetary routines
X
ATTENTION: PLACALC USERS ON MSDOS:
See the note close to the end of this file regarding EPHE_PATH.
X
---------------------------------------------------------------
| Copyright Astrodienst AG and Alois Treindl, 1991, 1993.     |
| The use of this source code is subject to regulations made  |
| by Astrodienst Zurich. The code is NOT in the public domain.|
|                                                             |
| This copyright notice must not be changed or removed        |
| by any user of this program.                                |
---------------------------------------------------------------
************************************************************/
X
/************************************************************
$Header: ourdef.h,v 1.2 91/11/16 16:21:37 alois Exp $
definitions and constants for all Astrodienst C programs
contains only declarations and #defines, no global variables.
auto-dectection of MSDOS (TURBO_C or MS_C) or HPUNIX
************************************************************/
X
#ifdef MSDOS  /* already defined by some DOS compilers */
#undef MSDOS
#define MSDOS 1
#endif
X
#ifdef __TURBOC__ /* defined by turboc */
#ifndef MSDOS
#define MSDOS 1
#endif
#define TURBO_C
#endif
X
#if MSDOS
#define HPUNIX 0
#ifndef TURBO_C
#define MS_C /* assume Microsoft C compiler */
#endif
#else
#define MSDOS 0
#define HPUNIX 1
#ifndef _HPUX_SOURCE
#define _HPUX_SOURCE
#endif
#endif
X
#include <stdlib.h>
#if HPUNIX
#ifndef MAC
#ifndef NeXT
#include <unistd.h>
#endif
#endif /* MAC */
#endif /* HPUNIX */
X
#ifndef OK
#define OK 0
#define ERR (-1)
#endif
X
X
#define UCHP (unsigned char*)  /* used for casting *char  */
#define UCP (unsigned char*)  /* used for casting *char  */
#define SCP (char*)     /* used for casting *unsigned char */
#define UCHAR unsigned char
X
#if HPUNIX
#ifndef MAC
#ifndef NeXT
#include <malloc.h>
#endif
#endif /* MAC */
typedef double  REAL8;  /* real with at least 64 bit precision */
typedef float   REAL4;  /* real with at least 32 bit precision */
typedef long    INT4;   /* signed integer with at least 32 bit precision */
typedef unsigned long UINT4;
/* unsigned integer with at least 32 bit precision */
typedef int     INT2;   /* signed integer with at least 16 bit precision */
typedef int     INT1;   /* signed integer with at least 8  bit precision */
#ifndef dbd_VERSION     /* db_vista defines boolean in vista.h already */
typedef int     BOOLEAN;
#endif
typedef unsigned short UINT2; /* unsigned 16 bits */
#define ABS4  abs   /* abs function for long */
#endif /* HPUNIX */
X
#if MSDOS
#ifdef TURBO_C
#include <alloc.h>    /* MSC needs malloc ! */
#else
#include <malloc.h>
#endif
typedef double  REAL8;  /* real with at least 64 bit precision */
typedef float   REAL4;  /* real with at least 32 bit precision */
typedef long    INT4;   /* signed integer with at least 32 bit precision */
typedef unsigned long UINT4;
X                        /* unsigned integer with at least 32 bit precision */
typedef int     INT2;   /* signed integer with at least 16 bit precision */
typedef int     INT1;   /* signed integer with at least 8  bit precision */
typedef int     BOOLEAN;
typedef unsigned int UINT2; /* unsigned 16 bits */
#define ABS4  labs    /* abs function for long */
#endif /* MSDOS */
X
#define COS8 RCos
#define SIN8 RSin
#define ASIN8 asin
#define TAN8 RTan
#define ATAN8 RAtn
#define ATAN28 atan2
#define EXP10(x) pow(10.0, (x))
#define ABS8(x) RAbs(x)
X
#define TANERRLIMIT 1.0E-10     /* used to check for arguments close to pi */
#define NEAR_ZERO   1.0E-16     /* used to compare for divisors close to 0 */
#define BIGREAL     1.0E+38
X
#define DEGTORAD 0.0174532925199433
#define RADTODEG 57.2957795130823
X
typedef INT4 centisec;   /* centiseconds used for angles and times */
#define CS   (centisec)  /* use for casting */
#define CSEC centisec    /* use for typing */
X
#define DEG     (360000L)   /* degree expressed in centiseconds */
#define DEG7_30 (2700000L)  /* 7.5 degrees */
#define DEG15   (15 * DEG)
#define DEG24   (24 * DEG)
#define DEG30   (30 * DEG)
#define DEG60   (60 * DEG)
#define DEG90   (90 * DEG)
#define DEG120  (120 * DEG)
#define DEG150  (150 * DEG)
#define DEG180  (180 * DEG)
#define DEG270  (270 * DEG)
#define DEG360  (360 * DEG)
X
#define CSTORAD 4.84813681109536E-08 /* centisec to rad: pi / 180 /3600/100 */
#define RADTOCS 2.06264806247096E+07 /* rad to centisec 180*3600*100/pi */
X
#define DEG2MSEC 3600000.0  /* degree to milliseconds */
#define DEG2CSEC 360000.0   /* degree to centiseconds */
X
#define SEC2CSEC 100  /* seconds to centiseconds */
X
#define CS2DEG    (1.0/360000.0)  /* centisec to degree */
#define CS2CIRCLE (CS2DEG/360.0)  /* centisec to circle */
#define AU2INT    1e7             /* factor for long storage of A.U. */
X
#define CSMIN 6000L
#define CSSEC 100L
X
#define SINDEG(x) sin(DEGTORAD * (x))
#define COSDEG(x) cos(DEGTORAD * (x))
#define TANDEG(x) tan(DEGTORAD * (x))
#define SINCS(x)  sin((double)(CSTORAD * (x)))
#define COSCS(x)  cos((double)(CSTORAD * (x)))
#define TANCS(x)  tan((double)(CSTORAD * (x)))
X
/*************************************************************
Exported functions:
X
In all functions the variable jd_ad indicates the use of
Astrodienst relative julian days, and jd the use of absolute
julian days.
*************************************************************/
X
extern int nacalc();
extern int calcserv();
extern void helup();
extern void togeo();
extern int calc();
extern int hel();
extern int moon();
extern REAL8 sidtime();
extern REAL8 smod8360();
extern REAL8 mod8360();
extern REAL8 diff8360();
extern REAL8 test_near_zero();
extern REAL8 deltat();
extern void to_mean_ekl();
extern int afl2planet();
extern void disturb();
extern REAL8 fnu();
X
/*************************************************************
definitions
*************************************************************/
X
/*
* planet index numbers, used to identify a planet in calc() and
* other related functions.
*/
#define SUN       0   /* used synonymously for earth too */
#define EARTH     0
#define MOON      1
#define MERCURY   2
#define VENUS     3
#define MARS      4
#define JUPITER   5
#define SATURN    6
#define URANUS    7
#define NEPTUNE   8
#define PLUTO     9
#define MEAN_NODE 10
#define TRUE_NODE 11
#define CHIRON    12
#define LILITH    13
#define CERES     14
#define PALLAS    15
#define JUNO      16
#define VESTA     17
X
/*************************************************************
exported variables
*************************************************************/
X
extern REAL8 meanekl;
extern REAL8 ekl;
extern REAL8 nut;
X
extern struct elements { /* actual elements at time thelup */
X  REAL8 tj,     /* centuries from epoch */
X  lg,     /* mean longitude in degrees of arc*/
X  pe,     /* longitude of the perihelion in degrees of arc*/
X  ex,     /* excentricity in degrees of arc*/
X  kn,     /* longitude of node in degrees of arc*/
X  in,     /* inclination of the orbit in degrees of arc*/
X  ma;     /* mean anomaly in degrees of arc*/
} el [MARS + 1];
X
extern char *ephe_path;
X
/*
* in a bitlist flag each planet is represented by a bit;
* all 13 defined planets can be called at once with
* LILITH is not automatically included
*/
#define CALC_ALL_PLANET_BITS ((1 << 13) - 1) /* bits 0..12 set */
X
#define J2000 2451545.0 /* Epoch of JPL ephemeris DE200, absolute */
#define J1950  2433282.423  /* Epoch of JPL ephemeris DE102 */
#define JUL_OFFSET 2433282.0  /* offset of Astrodienst relative Julian date */
#define EPOCH1850 -36524.0  /* jupiter,saturn 0 jan 1850, 12:00 */
#define EPOCH1900 -18262.0  /* inner planets  0 jan 1900, 12:00 */
#define EPOCH1950  0.0    /* pluto    0 jan 1950, 12:00 */
X                /* this is the origin of the Astrodienst
X                   relative julian calendar system */
#define EPOCH1960 3653.0 /* uranus,neptune 1 jan 1960, 12:00 */
X
#define ENDMARK 99 /* used to mark the end of disturbation terms */
X
#define NODE_INTERVAL 0.005        /* days, = 7m20s */
#define MOON_SPEED_INTERVAL 0.0001 /* 8.64 seconds later */
X
/*
* flag bits used in calc and calcserv
*/
#define CALC_BIT_HELIO 1   /* geo/helio */
#define CALC_BIT_NOAPP 2   /* apparent/true positions */
#define CALC_BIT_NONUT 4   /* true eq. of date/ mean equ. of date */
#define CALC_BIT_EPHE  8   /* universal/ephemeris time */
#define CALC_BIT_SPEED 16  /* without/with speed */
#define CALC_BIT_BETA  32  /* without/with latitude */
#define CALC_BIT_RGEO  64  /* without/with relative rgeo */
#define CALC_BIT_RAU   128 /* without/with real radius */
#define CALC_BIT_MUST_USE_EPHE 256 /* epheserv may not use calc */
#define CALC_BIT_MAY_USE_EPHE  512 /* calcserv may use ephread */
X
#define EPHE_STEP 80              /* days step in LRZ ephe */
#define EPHE_DAYS_PER_FILE 100000 /* days per ephe file */
#define EPHE_OUTER "LRZ5_"        /* file name prefix */
#define EPHE_OUTER_BSIZE  60      /* blocksize */
#define EPHE_CHIRON "CHI_"        /* file name prefix */
#define EPHE_CHIRON_BSIZE 12      /* blocksize */
#define EPHE_ASTER "CPJV_"        /* file name prefix */
#define EPHE_ASTER_BSIZE  48      /* blocksize */
X
/********************************************
About the format of the ephemeris files
----------------------------------------
We use currently ephemeris files with steps of 80 days.
There are 1250 "records" in each file, so that one file
spans 100000 days. We have three types of ephemeris files:
LRZ5_nn for the outer planets Jupiter ... Pluto,
CHI_nn for Chiron, and CPJV_nn for the four asteroids Ceres ... Vesta.
nn is an expression derived from the first julian daynumber on the
file. Jd 2100'000 to 2199'920 is on file LRZ5_21, CHI_21, and CPJV_21;
for negative Jd we use the filenames LRZ5_Mxx  with M indicating the minus.
X
Given the jd for which you want the ephemeris, it is simple to build
the filename and use fseek() within the file to go where the data is.
This is done by the functions lrz_file_posit() and chi_file_posit().
X
The stored coordinates are for each date and planet:
L = ecliptic longitude relative to mean exquinox of date,
in units of milliseconds of acr (1/3600000 degree) as type long;
R = radius vector, units of 10-7 AU, as type long.
Z = disctance of ecliptic; Z = R * sin(latitude); in units of 10-7 AU,
as type long.
The data is stored in the byte ordering of the Astrodienst HPUX machines,
which is most significant byte first. It is not the same byte ordering
as on Intel processors; the function longreorder() converts between
the disk file format and the internal format of MSDOS machines.
X
For LRZ5- files, we have 60-byte records LRZ(Jupiter),LRZ(Saturn),
LRZ(Uranus), LRZ(Neptune), LRZ(Pluto).
For CHI- files we have 12-byte records LRZ.
For CPJV- files we have 48-byte records.
X
************************************************/
X
X
/*************************************************************
placalc2.c definitions
*************************************************************/
X
#define SDNUM 20
#define NUM_MOON_CORR 93
X
struct eledata {
REAL8 axis,   /* mean distance, in a.u., A(N) in basic */
period,   /* days for one revolution, P(N) in basic */
epoch,    /* relative juldate of epoch, Ep(N) in basic */
/* T = distance to epoch in jul.centuries 36525 day*/
lg0,lg1,lg2,lg3,/* deg(epoch), degree/day, seconds/T^2,seconds/T^3 */
/* Pd(N,0..2) in basic, lg3 was not present */
pe0,pe1,pe2,pe3,/* deg(epoch), seconds/T,  seconds/T^2,seconds/T^3 */
/* Pd(N,3..5) in basic, pe3 was not present */
ex0,ex1,ex2,  /* ecl(epoch), 1/T, 1/T^2 */
/* Pd(N,6..8) in basic */
kn0,kn1,kn2,kn3,/* node(epoch),seconds/T,  seconds/T^2,seconds/T^3 */
/* Pd(N,9..11) in basic, kn3 was not present */
in0,in1,in2;    /* incl(epoch),1/T, 1/T^2 */
/* Pd(N,12..14) in basic */
};
X
struct kor {
X  int     j, i;
X  REAL8   lampl;  /* amplitude of disturbation in long, seconds of arc */
X  REAL8 lphase;   /* phase of disturbation in long, degrees */
X  INT4    rampl;  /* ampl. of disturbation in radius, 9th place of log */
X  REAL8   rphase; /* phase of disturbation in radius, degrees */
X  int     k;      /* index into disturbing planet anomaly table sa[] */
};
X
struct sdat {   /* 0..19 mean anomalies of disturbing planets
X  Sd(0..19,0..1) in basic */
X  REAL8 sd0,  /* mean anomaly at epoch 1850 */
X  sd1;  /* degrees/year */
};
X
/* moon correction data; revised 30-jul-88: all long. to 0.3" */
struct m45dat {
X  int  i0,i1,i2,i3;
X  REAL8 lng,lat,par;
};
X
extern struct eledata pd[MARS + 1];
extern struct kor earthkor[86+1];
extern struct kor mercurykor[24+1];
extern struct kor venuskor[22+1];
extern struct kor marskor[62+1];
extern struct sdat _sd [SDNUM];
extern struct m45dat m45[NUM_MOON_CORR];
extern REAL8 ekld[4];
extern REAL8 sa[SDNUM];
extern double degnorm();
extern REAL8 fnu();
extern REAL8 smod8360();
extern REAL8 mod8360();
extern REAL8 diff8360();
extern REAL8 test_near_zero();
X
/*******************************************
$Header: astrolib.h,v 1.2 91/11/16 16:21:02 alois Exp $
astrolib.h
X
*******************************************/
X
/* macros for bit operations */
X
#define clear_bit(v,bit_nr) ((v) & ~(1L << (bit_nr)))
#define set_bit(v,bit_nr)   ((v) | (1L << (bit_nr)))
#define bit(bit_nr)         (1L << (bit_nr))
#define check_bit(v,bit_nr) ((v) & (1L << (bit_nr)))
X
#endif /* PLACALC */
X
/* placalc.h */
SHAR_EOF
  $shar_touch -am 1223232998 'placalc.h' &&
  chmod 0644 'placalc.h' ||
  echo 'restore of placalc.h failed'
  shar_count="`wc -c < 'placalc.h'`"
  test 15662 -eq "$shar_count" ||
    echo "placalc.h: original size 15662, current size $shar_count"
fi
# ============= placalc2.c ==============
if test -f 'placalc2.c' && test X"$1" != X"-c"; then
  echo 'x - skipping placalc2.c (File already exists)'
else
  echo 'x - extracting placalc2.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'placalc2.c' &&
/*
** Astrolog (Version 5.40) File: placalc2.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "placalc.h"
X
X
#ifdef PLACALC
/*
** ---------------------------------------------------------------
** | Copyright Astrodienst AG and Alois Treindl, 1989,1991,1993  |
** | The use of this source code is subject to regulations made  |
** | by Astrodienst Zurich. The code is NOT in the public domain.|
** |                                                             |
** | This copyright notice must not be changed or removed        |
** | by any user of this program.                                |
** ---------------------------------------------------------------
**
** Important changes:
** 11-jun-93 revision 1.12: fixed error which affected Mercury between -2100
** and -3100 (it jumped wildly).
*/
X
#ifdef ASTROLOG
/* Given an object index and a Julian Day time, get its zodiac and        */
/* declination position (planetary longitude and latitude) of the object  */
/* and its velocity and distance from the Earth or Sun. This basically    */
/* just calls the Placalc calculation function to actually do it, but as  */
/* this is the one routine called from Astrolog, this is the one routine  */
/* which has knowledge of and uses both Astrolog and Placalc definitions, */
/* and does things such as translation to Placalc indices and formats.    */
X
bool FPlacalcPlanet(ind, jd, helio, obj, objalt, dir, space)
int ind, helio;
double jd;
real *obj, *objalt, *dir, *space;
{
X  int iobj, flag;
X  REAL8 jd_ad, rlng, rrad, rlat, rspeed;
X
X  if (ind <= oPlu)      /* Convert Astrolog object index to Placalc index. */
X    iobj = ind-1;
X  else if (ind == oChi)
X    iobj = CHIRON;
X  else if (FBetween(ind, oCer, oVes))
X    iobj = ind - oCer + CERES;
X  else if (ind == oNod)
X    iobj = us.fTrueNode ? TRUE_NODE : MEAN_NODE;
X  else if (ind == oLil)
X    iobj = LILITH;
X  else
X    return fFalse;
X
X  jd_ad = jd - JUL_OFFSET;
X  flag = helio ? CALC_BIT_SPEED | CALC_BIT_HELIO : CALC_BIT_SPEED;
X  jd_ad += deltat(jd_ad);
X  if (calc(iobj, jd_ad, flag, &rlng, &rrad, &rlat, &rspeed) == OK) {
X    *obj    = rlng;
X    *objalt = rlat;
X    *dir    = rspeed;
X    *space  = rrad;
X    return fTrue;
X  }
X  return fFalse;
}
#endif /* ASTROLOG */
X
X
/***********************************************************
** $Header$
**
** definition module for planetary elements
** and disturbation coefficients
** version HP-UX C  for new version with stored outer planets
** 31-jul-88
** by Alois Treindl
**
** ---------------------------------------------------------------
** | Copyright Astrodienst Zurich AG and Alois Treindl, 1989.    |
** | The use of this source code is subject to regulations made |
** | by Astrodienst Zurich. The code is NOT in the public domain.|
** |                                                             |
** | This copyright notice must not be changed or removed        |
** | by any user of this program.                                |
** ---------------------------------------------------------------
**
***********************************************************/
X
/************************************************************
externally accessible globals, defined as extern in placalc.h
************************************************************/
X
REAL8 meanekl, ekl, nut;
struct elements el[MARS + 1];
X
/*
** In the elements degrees were kept as the units for the constants. This
** requires conversion to radians, when the actual calculations are performed.
** This approach is not the most efficient, but safer for development.
** Constant conversion could be done by writing all degree constants with
** value * DEGTORAD
*/
X
#define TIDAL_26  TRUE  /* decide wheter to use new or old lunar tidal
term; a consistent system of delta t must be
used */
#define MOON_TEST_CORR FALSE  /* to include more lunar terms in longitude */
X
REAL8 ekld[4] = {23.452294, -46.845, -.0059, 0.00181};
/* ecliptic with epoch1900, Ekd(0..3) in basic */
X
struct eledata pd[MARS + 1] = {
{/*earth*/  1.00000023, 365.25636042, EPOCH1900,
99.696678,  .9856473354,  1.089,    0,
101.220833, 6189.03,  1.63,   0.012,
0.01675104, -0.00004180,  -0.000000126,
0,    0,    0,    0,
0,    0,    0},
/*
** note 29 June 88 by Alois: G.M.Clemence, Astronomical Journal
** vol.53,p. 178 (1948) gives a correction to the perihel motion
** of -4.78" T, giving 6184.25 for the linear Term above. We have
** not yet applied this correction. It has been used in APAE 22,4
** on the motion of mars and does make an official impression.
*/
{/*moon*/ 0.0025955307, 27.321661,  EPOCH1900,
# if ! TIDAL_26
/*
** values from Improved Lunar Ephemeris, corresponding to tidal
** term -22.44"/cy and  consistent with delta t ~ 29.949 T*T
*/
270.4341638,  13.176396526808121, -4.08,  0.0068,
# endif
# if TIDAL_26
/*
** new values from Morrison 1979, with tidal term -26"/cy as
** stated in A.E. 1986 onwards, consistent with delta t ~ 44.3 T*T
** correction: -1.54" + 2.33" T - 1.78" T*T
*/
270.4337361,  13.176396544528099, -5.86,  0.0068,
# endif
334.329556, 14648522.52,  -37.17,   -0.045,
0.054900489,  0,    0,
259.183275, -6962911.23,  7.48 ,    0.008,
5.145388889,  0,    0},
{/*mercury*/  .3870986, 87.969252,  EPOCH1900,
178.179078, 4.0923770233, 1.084,    0,
75.89969722,  5599.76,  1.061,    0,
0.20561421, .00002046,   -.000000030,
47.145944444, 4266.75,  .626,   0,
7.0028805555, 6.699,    -.066},
{/*venus*/  .72333162,  224.700726, EPOCH1900,
342.767053, 1.6021687039, 1.1148,   0,
130.16383333, 5068.93,  -3.515,   0,
0.00682069, -.00004774, .000000091,
75.7796472223,3239.46,  1.476,    0,
3.3936305555, 3.621,    .0035},
{/*mars*/ 1.5236914620, 686.9296097,  EPOCH1900,
/* These are the corrected elements by Ross */
293.74762778, .524071163814,  1.1184,   0,
334.21820278, 6626.73,  .4675,    -0.0043,
0.09331290, .000092064, -.000000077,
48.786441667, 2775.57,  -.005,    -0.0192,
1.85033333, -2.430,   .0454}
};
X
struct sdat _sd [SDNUM] = {
X  114.50,   585.17493,
X  109.856,  191.39977,
X  148.031,  30.34583,
X  284.716,  12.21794,
X  114.508,  585.17656,
X  -0.56,    359.99213,
X  148.03,   30.34743,
X  284.72,   12.2196,
X  248.07,   1494.726615,
X  359.44,   359.993595,
X  109.86,   191.402867,
X  148.02,   30.348930,
X  114.503,  585.173715,
X  359.444,  359.989285,
X  148.021,  30.344620,
X  284.716,  12.21669,
X  148.0315, 30.34906264,
X  284.7158, 12.22117085,
X  220.1695, 4.284931111,
X  291.8024, 2.184704167
};
X
REAL8 sa[SDNUM];
X
/*
** delta long = lampl * COS (lphase - arg) in seconds of arc
** delta rad  = rampl * COS (rphase - arg) in ninth place of log
** arg = j * sa (k) + i * ma (this planet)
** ma = mean anomaly
** sa = mean anomaly of disturbing planet, where this
** is taken from the aproximate value in sa[]
** For the COS (phase - arg) it is good enough to compute
** with 32 bit reals, because ampl and phase have only
** four to five significant digits.
** While saving constant space, it is costing execution time due
** to float/double conversions.
**
** In basic, all correction terms for sun, mercury, venus and mars
** were contained in one array K(0..142,0..6); Nk(N,0) contained
** the index of the first term of planet N and Nk(N,1) the number
** of terms for this planet. Here, we use a  0 in the first column
** kor.j to indicate the end of the table for a planet.
** K(*) was a basic INTEGER array, therefore the amplitudes and phases
** had to be expressed as
** K(i,2) = ampl. of longitude in 0.001 seconds of arc
** K(i,3) = phase of longitude in 0.01 degrees
** K(i,4) = ampl. of radius in 9th place of log
** K(i,5) = phase of radius in 0.01 degrees.
** Here we have converted the amplitude of long. to seconds of arc
** and the phases to degrees.
*/
X
struct kor ARR earthkor[86+1] = {  /* 11-jul-88 all terms to 0.020" long */
X  /* j i  lampl  lphase  rampl  rphase  k */
X  -1, 1,  0.013, 243,    28,    335,    8,  /* mercury */
X  -1, 3,  0.015, 357,    18,    267,    8,
X  -1, 4,  0.023, 326,    5,     239,    8,
X  -1, 0,  0.075, 296.6,  94,    205.0,  0,  /* venus */
X  -1, 1,  4.838, 299.10, 2359,  209.08, 0,
X  -1, 2,  0.074, 207.9,  69,    348.5,  0,
X  -1, 3,  0.009, 249,    16,    330,    0,
X  -2, 1,  .116,  148.90, 160,   58.40,  0,
X  -2, 2,  5.526, 148.31, 6842,  58.32,  0,
X  -2, 3,  2.497, 315.94, 869,   226.70, 0,
X  -2, 4,  0.044, 311.4,  52,    38.8,   0,
X  -3, 2,  0.013, 176,    21,    90,     0,
X  -3, 3,  .666,  177.71, 1045,  87.57,  0,
X  -3, 4,  1.559, -14.75, 1497,  255.25, 0,
X  -3, 5,  1.024, 318.15, 194,   49.50,  0,
X  -3, 6,  0.017, 315,    19,    43,     0,
X  -4, 4,  .210,  206.20, 376,   116.28, 0,
X  -4, 5,  .144,  195.40, 196,   105.20, 0,
X  -4, 6,  .152,  -16.20, 94,    254.80, 0,
X  -5, 5,  0.084, 235.6,  163,   145.4,  0,
X  -5, 6,  0.037, 221.8,  59,    132.2,  0,
X  -5, 7,  .123,  195.30, 141,   105.40, 0,
X  -5, 8,  .154,  -.40,   26,    270.00, 0,
X  -6, 6,  0.038, 264.1,  80,    174.3,  0,
X  -6, 7,  0.014, 253,    25,    164,    0,
X  -6, 8,  0.01,  230,    14,    135,    0,
X  -6, 9,  0.014, 12,     12,    284,    0,
X  -7, 7,  0.020, 294,    42,    203.5,  0,
X  -7, 8,  0.006, 279,    12,    194,    0,
X  -8, 8,  0.011, 322,    24,    234,    0,
X  -8, 12, 0.042, 259.2,  44,    169.7,  0,
X  -8, 14, 0.032, 48.8,   33,    138.7,  0,
X  -9, 9,  0.006, 351,    13,    261,    0,
X  1,  -1, .273,  217.70, 150,   127.70, 1,  /* mars */
X  1,  0,  0.048, 260.3,  28,    347,    1,
X  2,  -3, 0.041, 346,    52,    255.4,  1,
X  2,  -2, 2.043, 343.89, 2057,  253.83, 1,
X  2,  -1, 1.770, 200.40, 151,   295.00, 1,
X  2,  0,  0.028, 148,    31,    234.3,  1,
X  3,  -3, .129,  294.20, 168,   203.50, 1,
X  3,  -2, .425,  -21.12, 215,   249.00, 1,
X  4,  -4, 0.034, 71,     49,    339.7,  1,
X  4,  -3, .500,  105.18, 478,   15.17,  1,
X  4,  -2, .585,  -25.94, 105,   65.90,  1,
X  5,  -4, 0.085, 54.6,   107,   324.6,  1,
X  5,  -3, .204,  100.80, 89,    11.00,  1,
X  6,  -5, 0.020, 186,    30,    95.7,   1,
X  6,  -4, .154,  227.40, 139,   137.30, 1,
X  6,  -3, .101,  96.30,  27,    188.00, 1,
X  7,  -5, 0.049, 176.5,  60,    86.2,   1,
X  7,  -4, .106,  222.70, 38,    132.90, 1,
X  8,  -5, 0.052, 348.9,  45,    259.7,  1,
X  8,  -4, 0.021, 215.2,  8,     310,    1,
X  8,  -6, 0.010, 307,    15,    217,    1,
X  9,  -6, 0.028, 298,    34,    208.1,  1,
X  9,  -5, 0.062, 346,    17,    257,    1,
X  10, -6, 0.019, 111,    15,    23,     1,
X  11, -7, 0.017, 59,     20,    330,    1,
X  11, -6, 0.044, 105.9,  9,     21,     1,
X  13, -8, 0.013, 184,    15,    94,     1,
X  13, -7, 0.045, 227.8,  5,     143,    1,
X  15, -9, 0.021, 309,    22,    220,    1,
X  17, -9, 0.026, 113,    0,     0,      1,
X  1,  -2, .163,  198.60, 208,   112.00, 2,  /* jupiter */
X  1,  -1, 7.208, 179.53, 7067,  89.55,  2,
X  1,  0,  2.600, 263.22, 244,   -21.40, 2,
X  1,  1,  0.073, 276.3,  80,    6.5,    2,
X  2,  -3, 0.069, 80.8,   103,   350.5,  2,
X  2,  -2, 2.731, 87.15,  4026,  -2.89,  2,
X  2,  -1, 1.610, 109.49, 1459,  19.47,  2,
X  2,  0,  0.073, 252.6,  8,     263,    2,
X  3,  -3, .164,  170.50, 281,   81.20,  2,
X  3,  -2, .556,  82.65,  803,   -7.44,  2,
X  3,  -1, .210,  98.50,  174,   8.60,   2,
X  4,  -4, 0.016, 259,    29,    170,    2,
X  4,  -3, 0.044, 168.2,  74,    79.9,   2,
X  4,  -2, 0.080, 77.7,   113,   347.7,  2,
X  4,  -1, 0.023, 93,     17,    3,      2,
X  5,  -2, 0.009, 71,     14,    343,    2,
X  1,  -2, 0.011, 105,    15,    11,     3,  /* saturn */
X  1,  -1, .419,  100.58, 429,   10.60,  3,
X  1,  0,  .320,  269.46, 8,     -7.00,  3,
X  2,  -2, .108,  290.60, 162,   200.60, 3,
X  2,  -1, .112,  293.60, 112,   203.10, 3,
X  3,  -2, 0.021, 289,    32,    200.1,  3,
X  3,  -1, 0.017, 291,    17,    201,    3,
X  ENDMARK
};
X
struct kor ARR mercurykor[24+1] = {
X  1,  -1, .711,  35.47,  491,  305.28, 4,
X  2,  -3, .552,  161.15, 712,  71.12,  4,
X  2,  -2, 2.100, 161.15, 2370, 71.19,  4,
X  2,  -1, 3.724, 160.69, 899,  70.49,  4,
X  2,  0,  .729,  159.76, 763,  250.00, 4,
X  3,  -3, .431,  105.37, 541,  15.53,  4,
X  3,  -2, 1.329, 104.78, 1157, 14.84,  4,
X  3,  -1, .539,  278.95, 14,   282.00, 4,
X  4,  -2, .484,  226.40, 234,  136.02, 4,
X  5,  -4, .685,  -10.43, 849,  259.51, 4,
X  5,  -3, 2.810, -10.14, 2954, 259.92, 4,
X  5,  -2, 7.356, -12.22, 282,  255.43, 4,
X  5,  -1, 1.471, -12.30, 1550, 77.75,  4,
X  5,  0,  .375,  -12.29, 472,  77.70,  4,
X  2,  -1, .443,  218.48, 256,  128.36, 5,
X  4,  -2, .374,  151.81, 397,  61.63,  5,
X  4,  -1, .808,  145.93, 13,   35.00,  5,
X  1,  -1, .697,  181.07, 708,  91.38,  6,
X  1,  0,  .574,  236.72, 75,   265.40, 6,
X  2,  -2, .938,  36.98,  1185, 306.97, 6,
X  2,  -1, 3.275, 37.00,  3268, 306.99, 6,
X  2,  0,  .499,  31.91,  371,  126.90, 6,
X  3,  -1, .353,  25.84,  347,  295.76, 6,
X  2,  -1, .380,  239.87, 0,    0,      7,
X  ENDMARK
};
X
struct kor ARR venuskor[22+1] = {
X  -1, 2,  .264,   -19.20, 175,  251.10, 8,
X  -2, 5,  .361,   167.68, 55,   77.20,  8,
X  1,  -1, 4.889,  119.11, 2246, 29.11,  9,
X  2,  -2, 11.261, 148.23, 9772, 58.21,  9,
X  3,  -3, 7.128,  -2.57,  8271, 267.42, 9,
X  3,  -2, 3.446,  135.91, 737,  47.37,  9,
X  4,  -4, 1.034,  26.54,  1426, 296.49, 9,
X  4,  -3, .677,   165.32, 445,  75.70,  9,
X  5,  -5, .330,   56.88,  510,  -33.36, 9,
X  5,  -4, 1.575,  193.93, 1572, 104.21, 9,
X  5,  -3, 1.439,  138.08, 162,  229.90, 9,
X  6,  -6, .143,   84.40,  236,  -5.80,  9,
X  6,  -5, .205,   44.20,  256,  314.20, 9,
X  6,  -4, .176,   164.30, 70,   75.70,  9,
X  8,  -5, .231,   180.00, 25,   75.00,  9,
X  3,  -2, .673,   221.62, 717,  131.60, 10,
X  3,  -1, 1.208,  237.57, 29,   149.00, 10,
X  1,  -1, 2.966,  208.09, 2991, 118.09, 11,
X  1,  0,  1.563,  268.31, 91,   -7.60,  11,
X  2,  -2, .889,   145.16, 1335, 55.17,  11,
X  2,  -1, .480,   171.01, 464,  80.95,  11,
X  3,  -2, .169,   144.20, 250,  54.00,  11,
X  ENDMARK
};
X
struct kor ARR marskor[62+1] = {
X  -1, 1,  .115,   65.84,  684,   156.14, 12,
X  -1, 2,  .623,   246.03, 812,   155.77, 12,
X  -1, 3,  6.368,  57.60,  556,   -32.06, 12,
X  -1, 4,  .588,   57.24,  616,   147.28, 12,
X  -2, 5,  .138,   39.18,  157,   309.39, 12,
X  -2, 6,  .459,   217.58, 82,    128.10, 12,
X  -1, -1, .106,   33.60,  141,   303.45, 13,
X  -1, 0,  .873,   34.34,  1112,  304.05, 13,
X  -1, 1,  8.559,  35.10,  6947,  304.45, 13,
X  -1, 2,  13.966, 20.50,  2875,  113.20, 13,
X  -1, 3,  1.487,  22.18,  1619,  112.38, 13,
X  -1, 4,  .175,   22.46,  225,   112.15, 13,
X  -2, 2,  .150,   18.96,  484,   266.42, 13,
X  -2, 3,  7.355,  158.64, 6412,  68.62,  13,
X  -2, 4,  4.905,  154.09, 1985,  244.70, 13,
X  -2, 5,  .489,   154.39, 543,   244.50, 13,
X  -3, 3,  .216,   111.06, 389,   21.10,  13,
X  -3, 4,  .355,   110.64, 587,   19.17,  13,
X  -3, 5,  2.641,  280.58, 2038,  190.60, 13,
X  -3, 6,  .970,   276.06, 587,   6.75,   13,
X  -3, 7,  .100,   276.20, 116,   6.40,   13,
X  -4, 5,  .152,   232.48, 259,   142.60, 13,
X  -4, 6,  .264,   230.47, 387,   139.75, 13,
X  -4, 7,  1.156,  41.64,  749,   312.67, 13,
X  -4, 8,  .259,   37.92,  205,   128.80, 13,
X  -5, 8,  .172,   -8.99,  234,   260.70, 13,
X  -5, 9,  .575,   164.48, 308,   74.60,  13,
X  -6, 10, .115,   113.70, 145,   23.53,  13,
X  -6, 11, .363,   285.69, 144,   196.00, 13,
X  -7, 13, .353,   48.83,  85,    319.10, 13,
X  -8, 15, 1.553,  170.14, 110,   81.00,  13,
X  -8, 16, .148,   170.74, 154,   259.94, 13,
X  -9, 17, .193,   293.70, 23,    22.80,  13,
X  1,  -3, .382,   46.48,  521,   316.25, 14,
X  1,  -2, 3.144,  46.78,  3894,  316.39, 14,
X  1,  -1, 25.384, 48.96,  23116, 318.87, 14,
X  1,  0,  3.732,  -17.62, 1525,  117.81, 14,
X  1,  1,  .474,   -34.60, 531,   59.67,  14,
X  2,  -4, .265,   192.88, 396,   103.12, 14,
X  2,  -3, 2.108,  192.72, 3042,  102.89, 14,
X  2,  -2, 16.035, 191.90, 22144, 101.99, 14,
X  2,  -1, 21.869, 188.35, 16624, 98.33,  14,
X  2,  0,  1.461,  189.66, 1478,  279.04, 14,
X  2,  1,  .167,   191.04, 224,   280.81, 14,
X  3,  -4, .206,   167.11, 338,   76.13,  14,
X  3,  -3, 1.309,  168.27, 2141,  76.24,  14,
X  3,  -2, 2.607,  228.41, 3437,  139.74, 14,
X  3,  -1, 3.174,  207.20, 1915,  115.83, 14,
X  3,  0,  .232,   207.78, 240,   298.06, 14,
X  4,  -4, .178,   127.25, 322,   36.16,  14,
X  4,  -3, .241,   200.69, 389,   110.02, 14,
X  4,  -2, .330,   267.57, 413,   179.86, 14,
X  4,  -1, .416,   221.88, 184,   128.17, 14,
X  1,  -2, .155,   -38.20, 191,   231.58, 15,
X  1,  -1, 1.351,  -34.10, 1345,  235.85, 15,
X  1,  0,  .884,   288.05, 111,   39.90,  15,
X  1,  1,  .132,   284.88, 144,   15.67,  15,
X  2,  -2, .620,   35.15,  869,   305.30, 15,
X  2,  -1, 1.768,  32.50,  1661,  302.51, 15,
X  2,  0,  .125,   18.73,  103,   119.90, 15,
X  3,  -2, .141,   47.59,  199,   318.06, 15,
X  3,  -1, .281,   40.95,  248,   310.75, 15,
X  ENDMARK
};
X
struct m45dat m45[NUM_MOON_CORR] = {
X  /*    l,     l',  F,  D,      Long,    Lat,         Par),*/
X  { 0,   0, 0,   4,    13.902,     14.06,  0.2607},
X  { 0,   0, 0,   2,    2369.912,   2373.36,     28.2333},
X  { 1,   0, 0,   4,     1.979,      6.98,  0.0433},
X  { 1,   0, 0,   2,     191.953,    192.72,  3.0861},
X  { 1,   0, 0,   0,   22639.500,  22609.1,     186.5398},
X  { 1,   0, 0,  -2,   -4586.465,  -4578.13,     34.3117},
X  { 1,   0, 0,  -4, -38.428,    -38.64,  0.6008},
X  { 1,   0, 0,  -6,  -0.393,     -1.43,  0.0086},
X  { 0,   1, 0,   4,  -0.289,     -1.59, -0.0053},
X  { 0,   1, 0,   2, -24.420,    -25.10, -0.3000},
X  { 0,   1, 0,   0,    -668.146,   -126.98,     -0.3997},
X  { 0,   1, 0,  -2,    -165.145,   -165.06,      1.9178},
X  { 0,   1, 0,  -4,  -1.877,     -6.46,  0.0339},
X  { 0,   0, 0,   3,   0.403,     -4.01,  0.0023},
X  { 0,   0, 0,   1,    -125.154,   -112.79,     -0.9781},
X  { 2,   0, 0,   4,   0.213,      1.02,  0.0054},
X  { 2,   0, 0,   2,  14.387,     14.78,  0.2833},
X  { 2,   0, 0,   0, 769.016,    767.96, 10.1657},
X  { 2,   0, 0,  -2,    -211.656,   -152.53,     -0.3039},
X  { 2,   0, 0,  -4, -30.773,    -34.07,  0.3722},
X  { 2,   0, 0,  -6,  -0.570,     -1.40,  0.0109},
X  { 1,   1, 0,   2,  -2.921,    -11.75, -0.0484},
X  { 1,   1, 0,   0,    -109.673,   -115.18,     -0.9490},
X  { 1,   1, 0,  -2,    -205.962,   -182.36,      1.4437},
X  { 1,  1,  0,  -4,  -4.391,     -9.66,  0.0673},
X  { 1,  -1, 0,  4,    0.283,      1.53,  0.0060},
X  { 1,  -1, 0,  2,   14.577,     31.70,  0.2302},
X  { 1,  -1, 0,  0,  147.687,    138.76,  1.1528},
X  { 1,  -1, 0,  -2,  28.475,     23.59, -0.2257},
X  { 1,  -1, 0,  -4,   0.636,      2.27, -0.0102},
X  { 0,  2,  0,  2,   -0.189,     -1.68, -0.0028},
X  { 0,  2,  0,  0,   -7.486,     -0.66, -0.0086},
X  { 0,  2,  0,  -2,  -8.096,    -16.35,  0.0918},
X  { 0,  0,  2,  2,   -5.741,     -0.04, -0.0009},
X  { 0,  0,  2,  0,  -411.608,    -0.2,      -0.0124},
X  { 0,  0,  2,  -2, -55.173,    -52.14, -0.1052},
X  { 0,  0,  2,  -4,   0.025,     -1.67,  0.0031},
X  { 1,  0,  0,  1,   -8.466,    -13.51, -0.1093},
X  { 1,  0,  0,  -1,  18.609,      3.59,  0.0118},
X  { 1,  0,  0,  -3,   3.215,      5.44, -0.0386},
X  { 0,  1,  0,  1,   18.023,     17.93,  0.1494},
X  { 0,  1,  0,  -1,   0.560,      0.32, -0.0037},
X  { 3,  0,  0,  2,    1.060,      2.96,  0.0243},
X  { 3,  0,  0,  0,   36.124,     50.64,  0.6215},
X  { 3,  0,  0,  -2, -13.193,    -16.40, -0.1187},
X  { 3,  0,  0,  -4,  -1.187,     -0.74,  0.0074},
X  { 3,  0,  0,  -6,  -0.293,     -0.31,  0.0046},
X  { 2,  1,  0,  2,   -0.290,     -1.45, -0.0051},
X  { 2,  1,  0,  0,   -7.649,    -10.56, -0.1038},
X  { 2,  1,  0,  -2,  -8.627,     -7.59, -0.0192},
X  { 2,  1,  0,  -4,  -2.740,     -2.54,  0.0324},
X  { 2,  -1, 0,  2,    1.181,      3.32,  0.0213},
X  { 2,  -1, 0,  0,    9.703,     11.67,  0.1268},
X  { 2,  -1, 0,  -2,  -2.494,     -1.17, -0.0017},
X  { 2,  -1, 0,  -4,   0.360,      0.20, -0.0043},
X  { 1,  2,  0,  0,   -1.167,     -1.25, -0.0106},
X  { 1,  2,  0,  -2,  -7.412,     -6.12,  0.0484},
X  { 1,  2,  0,  -4,  -0.311,     -0.65,  0.0044},
X  { 1,  -2, 0,  2,    0.757,      1.82,  0.0112},
X  { 1,  -2, 0,  0,    2.580,      2.32,  0.0196},
X  { 1,  -2, 0,  -2,   2.533,      2.40, -0.0212},
X  { 0,  3,  0,  -2,  -0.344,     -0.57,  0.0036},
X  { 1,  0,  2,  2,   -0.992,     -0.02,  0},
X  { 1,  0,  2,  0,  -45.099,     -0.02, -0.0010},
X  { 1,  0,  2,  -2,  -0.179,     -9.52, -0.0833},
X  { 1,  0,  -2, 2,   -6.382,     -3.37, -0.0481},
X  { 1,  0,  -2, 0,   39.528,     85.13, -0.7136},
X  { 1,  0,  -2, -2,   9.366,      0.71,     -0.0112},
X  { 0,  1,  2,  0,    0.415,      0.10,    0.0013},
X  { 0,  1,  2,  -2,  -2.152,     -2.26, -0.0066},
X  { 0,  1,  -2, 2,   -1.440,     -1.30,  0.0014},
X  { 0,  1,  -2, -2,   0.384,      0.0,   0.0},
X  { 2,  0,  0,  1,   -0.586,     -1.20, -0.0100},
X  { 2,  0,  0,  -1,   1.750,      2.01,  0.0155},
X  { 2,  0,  0,  -3,   1.225,      0.91,     -0.0088},
X  { 1,  1,  0,  1,    1.267,      1.52,  0.0164},
X  { 1,  -1, 0,  -1,  -1.089,      0.55,      0},
X  { 0,  0,  2,  -1,   0.584,      8.84,  0.0071},
X  { 4,  0,  0,  0,    1.938,      3.60,  0.0401},
X  { 4,  0,  0,  -2,  -0.952,     -1.58, -0.0130},
X  { 3,  1,  0,  0,   -0.551,      0.94, -0.0097},
X  { 3,  1,  0,  -2,  -0.482,     -0.57, -0.0045},
X  { 3,  -1, 0,  0,    0.681,      0.96,      0.0115},
X  { 2,  0,  2,  0,   -3.996,      0,   0.0004},
X  { 2,  0,  2,  -2,   0.557,     -0.75,     -0.0090},
X  { 2,  0,  -2, 2,   -0.459,     -0.38, -0.0053},
X  { 2,  0,  -2, 0,   -1.298,      0.74,      0.0004},
X  { 2,  0,  -2, -2,   0.538,      1.14, -0.0141},
X  { 1,  1,  -2, -2,   0.426,      0.07,     -0.0006},
X  { 1,  -1, 2,  0,   -0.304,      0.03,  0.0003},
X  { 1,  -1, -2, 2,   -0.372,     -0.19, -0.0027},
X  { 0,  0,  4,  0,    0.418,      0,   0},
X  { 2,  -1, 0,  -1,  -0.352,     -0.37,     -0.0028}
};
X
# if MOON_TEST_CORR
/* moon additional correction terms */
struct m5dat {
X  REAL8 lng;
X  int  i0,i1,i2,i3;
} m5[] = {
X  /*    lng,  l,     l',  F,  D,      */
X  0.127,  0,  0,  0,  6,
X  -0.151, 0,  2,  0,  -4,
X  -0.085, 0,  0,  2,  4,
X  0.150,  0,  1,  0,  3,
X  -0.091, 2,  1,  0,  -6,
X  -0.103, 0,  3,  0,  0,
X  -0.301, 1,  0,  2,  -4,
X  0.202,  1,  0,  -2, -4,
X  0.137,  1,  1,  0,  -1,
X  0.233,  1,  1,  0,  -3,
X  -0.122, 1,  -1, 0,  1,
X  -0.276, 1,  -1, 0,  -3,
X  0.255,  0,  0,  2,  1,
X  0.254,  0,  0,  2,  -3,
X  -0.100, 3,  1,  0,  -4,
X  -0.183, 3,  -1, 0,  -2,
X  -0.297, 2,  2,  0,  -2,
X  -0.161, 2,  2,  0,  -4,
X  0.197,  2,  -2, 0,  0,
X  0.254,  2,  -2, 0,  -2,
X  -0.250, 1,  3,  0,  -2,
X  -0.123, 2,  0,  2,  2,
X  0.173,  2,  0,  -2, -4,
X  0.263,  1,  1,  2,  0,
X  0.130,  3,  0,  0,  -1,
X  0.113,  5,  0,  0,  0,
X  0.092,  3,  0,  2,  -2,
X  0,  99, 0,  0,  0 /* end mark */
};
# endif /* MOON_TEST_CORR */
X
X
/* solution of the Kepler equation, return rad */
/* t = mean anomaly in degrees                 */
/* ex = excentricity of orbit                  */
/* err = maximum error in degrees              */
X
REAL8 fnu(t, ex, err)
REAL8 t;
REAL8 ex;
REAL8 err;
{
X  REAL8 u0, delta;
X
X  t *= DEGTORAD;
X  u0 = t;
X  err *= DEGTORAD;
X  delta = 1;
X  while (ABS8(delta) >= err) {
X    delta = (t + ex * SIN8(u0) - u0) / (1 - ex * COS8(u0));
X    u0 += delta;
X  }
X  return u0;
}
X
X
/* x MOD 360.0, so that x in 0..360 */
X
REAL8 smod8360(x)
REAL8 x;
{
X  while (x >= 360.0)
X    x -= 360.0;
X  while (x < 0.0)
X    x += 360.0;
X  return x;
}
X
X
/* x MOD 360.0, so that x in 0..360 */
X
REAL8 mod8360(x)
REAL8 x;
{
X  if (x >= 0 && x < 360.0)
X    return x;
X  return x - 360.0 * RFloor(x / 360.0);
}
X
X
/* a - b on a 360 degree circle, result -180..180 */
X
REAL8 diff8360(a, b)
REAL8 a;
REAL8 b;
{
X  REAL8 d;
X
X  d = a - b;
X  if (d >= 180.0)
X    return d - 360.0;
X  if (d < -180.0)
X    return d + 360.0;
X  return d;
}
X
X
REAL8 test_near_zero(x)
REAL8 x;
{
X  if (ABS8(x) >= NEAR_ZERO)
X    return x;
X  if (x < 0)
X    return -NEAR_ZERO;
X  return NEAR_ZERO;
}
X
X
/*
** p points to memory filled with long values; for
** each of the values the seqeuence of the four bytes
** has to be reversed, to translate HP-UX and VAX
** ordering to MSDOS/Turboc ordering
*/
X
void longreorder(p, n)
UCHAR *p;
int n;
{
X  int i;
X  unsigned char c0, c1, c2, c3;
X  static int orderinit = 0;
X  unsigned short test;
X
X  if (!orderinit) {
X    test = 0x0001;
X    orderinit = (*(unsigned char *)(&test)) ? 1 : -1;
X  }
X  if (orderinit < 0)
X    return;
X  for (i = 0; i < n; i += 4, p += 4) {
X    c0 = *p;
X    c1 = *(p + 1);
X    c2 = *(p + 2);
X    c3 = *(p + 3);
X    *p = c3;
X    *(p + 1) = c2;
X    *(p + 2) = c1;
X    *(p + 3) = c0;
X  }
}
X
X
/*****************************************************
$Header: deltat.c,v 1.10 93/01/27 14:37:06 alois Exp $
deltat.c
deltat(t): returns delta t (in julian days) from universal time t
is included by users
ET = UT +  deltat
X
---------------------------------------------------------------
| Copyright Astrodienst Zurich AG and Alois Treindl, 1989.    |
| The use of this source code is subject to regulations made  |
| by Astrodienst Zurich. The code is NOT in the public domain.|
|                                                             |
| This copyright notice must not be changed or removed        |
| by any user of this program.                                |
---------------------------------------------------------------
X
******************************************************/
X
double deltat(jd_ad)
double jd_ad;
{
X  static short int ARR dt[] = { /* in centiseconds */
X  /*
X  ** dt from 1637 to 2000, as tabulated in A.E.
X  ** the values 1620 - 1636 are not taken, as they fit
X  ** badly the parabola 25.5 t*t for the next range. The
X  ** best crossing point to switch to the parabola is
X  ** 1637, where we have fitted the value for continuity
X  */
X  6780, 6500, 6300,
X  6200, 6000, 5800, 5700, 5500,
X  5400, 5300, 5100, 5000, 4900,
X  4800, 4700, 4600, 4500, 4400,
X  4300, 4200, 4100, 4000, 3800, /* 1655 - 59 */
X  3700, 3600, 3500, 3400, 3300,
X  3200, 3100, 3000, 2800, 2700,
X  2600, 2500, 2400, 2300, 2200,
X  2100, 2000, 1900, 1800, 1700,
X  1600, 1500, 1400, 1400, 1300,
X  1200, 1200, 1100, 1100, 1000,
X  1000, 1000, 900,  900,  900,
X  900,  900,  900,  900,  900,
X  900,  900,  900,  900,  900,  /* 1700 - 1704 */
X  900,  900,  900,  1000, 1000,
X  1000, 1000, 1000, 1000, 1000,
X  1000, 1000, 1100, 1100, 1100,
X  1100, 1100, 1100, 1100, 1100,
X  1100, 1100, 1100, 1100, 1100,
X  1100, 1100, 1100, 1100, 1200, /* 1730 - 1734 */
X  1200, 1200, 1200, 1200, 1200,
X  1200, 1200, 1200, 1200, 1300,
X  1300, 1300, 1300, 1300, 1300,
X  1300, 1400, 1400, 1400, 1400,
X  1400, 1400, 1400, 1500, 1500,
X  1500, 1500, 1500, 1500, 1500, /* 1760 - 1764 */
X  1600, 1600, 1600, 1600, 1600,
X  1600, 1600, 1600, 1600, 1600,
X  1700, 1700, 1700, 1700, 1700,
X  1700, 1700, 1700, 1700, 1700,
X  1700, 1700, 1700, 1700, 1700,
X  1700, 1700, 1600, 1600, 1600, /* 1790 - 1794 */
X  1600, 1500, 1500, 1400, 1400,
X  1370, 1340, 1310, 1290, 1270, /* 1800 - 1804 */
X  1260, 1250, 1250, 1250, 1250,
X  1250, 1250, 1250, 1250, 1250,
X  1250, 1250, 1240, 1230, 1220,
X  1200, 1170, 1140, 1110, 1060,
X  1020, 960,  910,  860,  800,
X  750,  700,  660,  630,  600,  /* 1830 - 1834 */
X  580,  570,  560,  560,  560,
X  570,  580,  590,  610,  620,
X  630,  650,  660,  680,  690,
X  710,  720,  730,  740,  750,
X  760,  770,  770,  780,  780,
X  788,  782,  754,  697,  640,  /* 1860 - 1864 */
X  602,  541,  410,  292,  182,
X  161,  10, -102, -128, -269,
X  -324, -364, -454, -471, -511,
X  -540, -542, -520, -546, -546,
X  -579, -563, -564, -580, -566,
X  -587, -601, -619, -664, -644, /* 1890 - 1894 */
X  -647, -609, -576, -466, -374,
X  -272, -154, -2, 124,  264,
X  386,  537,  614,  775,  913,
X  1046, 1153, 1336, 1465, 1601,
X  1720, 1824, 1906, 2025, 2095,
X  2116, 2225, 2241, 2303, 2349, /* 1920 - 1924 */
X  2362, 2386, 2449, 2434, 2408,
X  2402, 2400, 2387, 2395, 2386,
X  2393, 2373, 2392, 2396, 2402,
X  2433, 2483, 2530, 2570, 2624,
X  2677, 2728, 2778, 2825, 2871,
X  2915, 2957, 2997, 3036, 3072, /* 1950 - 1954 */
X  3107, 3135, 3168, 3218, 3268,
X  3315, 3359, 3400, 3447, 3503,
X  3573, 3654, 3743, 3829, 3920,
X  4018, 4117, 4223, 4337, 4449,
X  4548, 4646, 4752, 4853, 4959,
X  5054, 5138, 5217, 5296, 5379, /* 1980 - 1984 */
X  5434, 5487, 5532, 5582, 5630, /* 1985 - 89 from AE 1991 */
X  5686, 5757, 5900, 5900, 6000, /* AE 1993 and extrapol */
X  6050, 6100, 6150, 6200, 6250, /* 1995 - 1999 */
X  6300};          /* 2000 */
X  double yr, cy, delta;
X  long iyr, i;
X  yr = (jd_ad + 18262) / 365.25 + 100.0;    /*  year  relative 1800 */
X  cy = yr / 100;
X  iyr =  (long) (RFloor(yr) + 1800);   /* truncated to integer, rel 0 */
#if TIDAL_26    /* Stephenson formula only when 26" tidal
X  term in lunar motion */
X  if (iyr >= 1637  && iyr < 2000) {
X  i = iyr - 1637;
X  delta = dt[i] * 0.01 + (dt[i+1] - dt[i]) * (yr - RFloor(yr)) * 0.01;
X  } else if (iyr >= 2000) { /* parabola, fitted at value[2000] */
X  delta = 25.5 * cy * cy  - 25.5 * 4 + 63.00;
X  } else if (iyr >= 948) {  /* from 948 - 1637 use parabola */
X  delta = 25.5 * cy * cy;
X  } else {  /* before 984 use other parabola */
X  delta = 1361.7  + 320 * cy + 44.3 * cy * cy;  /* fits at 948 */
X  }
#else    /* use Clemence value + 5 sec before 1690, new dt afterwards */
X  cy -= 1;  /* epoch 1900 */
X  if (iyr >= 1690  && iyr < 2000) {
X  i = iyr - 1637;
X  delta = dt[i] * 0.01 + (dt[i+1] - dt[i]) * (yr - RFloor(yr)) * 0.01;
X  } else if (iyr >= 2000) { /* parabola, fitted at value[2000] */
X  delta = 29.949 * cy * cy  - 29.949 * 4 + 63.0;
X  } else {
X  delta = 5 + 24.349 + 72.3165 * cy + 29.949 * cy * cy; /* fits at 1690 */
X  }
#endif
X  return delta / 86400.0;
}
X
X
/*******************************************
$Header: d2l.c,v 1.9 91/11/16 16:24:20 alois Exp $
X
double to long with rounding, no overflow check
*************************************/
long d2l(x)
double x;
{
X  if (x >=0)
X    return ((long) (x + 0.5));
X  else
X    return (-(long) (0.5 - x));
}
X
X
/*
* $Header$
*
* A collection of useful functions for centisec calculations.
X
---------------------------------------------------------------
| Copyright Astrodienst Zurich AG and Alois Treindl, 1991.    |
| The use of this source code is subject to regulations made  |
| by Astrodienst Zurich. The code is NOT in the public domain.|
|                                                             |
| This copyright notice must not be changed or removed        |
| by any user of this program.                                |
---------------------------------------------------------------
*******************************************************/
X
double degnorm(p)
double p;
{
X  if (p < 0)
X    do {
X      p += 360.0;
X    } while (p < 0);
X  else if (p >= 360.0)
X    do {
X      p -= 360.0;
X    } while (p >= 360.0);
X  return (p);
}
X
X
/*********************************************************
$Header: julday.c,v 1.9 91/11/16 16:25:06 alois Exp $
*********************************************************/
X
/*
** This function returns the absolute Julian day number (JD)
** for a given calendar date.
** The aruguments are a calendar date: day, month, year as integers,
** hour as double with decimal fraction.
** If gregflag = 1, Gregorian calendar is assumed, gregflag = 0
** Julian calendar is assumed.
**
** The Julian day number is system of numbering all days continously
** within the time range of known human history. It should be familiar
** for every astrological or astronomical programmer. The time variable
** in astronomical theories is usually expressed in Julian days or
** Julian centuries (36525 days per century) relative to some start day;
** the start day is called 'the epoch'.
** The Julian day number is a double representing the number of
** days since JD = 0.0 on 1 Jan -4712, 12:00 noon.
** Midnight has always a JD with fraction .5, because traditionally
** the astronomical day started at noon.
**
** NOTE: The Julian day number is named after the monk Julianus. It must
** not be confused with the Julian calendar system, which is named after
** Julius Cesar, the Roman politician who introduced this calendar.
**
** Original author: Marc Pottenger, Los Angeles.
** with bug fix for year < -4711   15-aug-88 by Alois Treindl
**
** References: Oliver Montenbruck, Grundlagen der Ephemeridenrechnung,
**             Verlag Sterne und Weltraum (1987), p.49 ff
**
** related functions: revjul() reverse Julian day number: compute the
**             calendar date from a given JD
*/
X
double julday(month, day, year, hour, gregflag)
int month;
int day;
int year;
double hour;
int gregflag;
{
X  double jd, u, u0, u1, u2;
X
X  u = year;
X  if (month < 3)
X    u -=1;
X  u0 = u + 4712.0;
X  u1 = month + 1.0;
X  if (u1 < 4)
X    u1 += 12.0;
X  jd = RFloor(u0*365.25)
X    + RFloor(30.6*u1+0.000001)
X    + day + hour/24.0 - 63.5;
X  if (gregflag) {
X    u2 = RFloor(ABS8(u) / 100) - RFloor(ABS8(u) / 400);
X    if (u < 0.0)
X      u2 = -u2;
X    jd = jd - u2 + 2;
X    if ((u < 0.0) && (u/100 == RFloor(u/100)) && (u/400 != RFloor(u/400)))
X      jd -= 1;
X  }
X  return jd;
}
X
X
/*********************************************************
$Header: revjul.c,v 1.9 91/11/16 16:25:37 alois Exp $
*********************************************************/
X
/*
** revjul() is the inverse function to julday(), see the description there.
** Arguments are julian day number, calendar flag (0=julian, 1=gregorian)
** return values are the calendar day, month, year and the hour of
** the day with decimal fraction (0 .. 23.999999).
**
** Original author Mark Pottenger, Los Angeles.
** with bug fix for year < -4711 16-aug-88 Alois Treindl
*/
X
void revjul(jd, gregflag, jmon, jday, jyear, jut)
double jd;
int gregflag;
int *jmon;
int *jday;
int *jyear;
double *jut;
{
X  double u0, u1, u2, u3, u4;
X
X  u0 = jd + 32082.5;
X  if (gregflag) {
X    u1 = u0 + RFloor(u0/36525.0) - RFloor(u0/146100.0) - 38.0;
X    if (jd >= 1830691.5) u1 +=1;
X      u0 = u0 + RFloor(u1/36525.0) - RFloor(u1/146100.0) - 38.0;
X  }
X  u2 = RFloor(u0 + 123.0);
X  u3 = RFloor((u2 - 122.2) / 365.25);
X  u4 = RFloor((u2 - RFloor(365.25 * u3)) / 30.6001);
X  *jmon = (int)(u4-1.0);
X  if (*jmon > 12)
X    *jmon -= 12;
X  *jday = (int)(u2 - RFloor(365.25 * u3) - RFloor(30.6001 * u4));
X  *jyear = (int)(u3 + RFloor((u4 - 1.9999) / 12.0) - 4800.0);
X  *jut = (jd - RFloor(jd + 0.5) + 0.5) * 24.0;
}
#endif /* PLACALC */
X
/* placalc2.c */
SHAR_EOF
  $shar_touch -am 1223232998 'placalc2.c' &&
  chmod 0644 'placalc2.c' ||
  echo 'restore of placalc2.c failed'
  shar_count="`wc -c < 'placalc2.c'`"
  test 35451 -eq "$shar_count" ||
    echo "placalc2.c: original size 35451, current size $shar_count"
fi
# ============= resource.h ==============
if test -f 'resource.h' && test X"$1" != X"-c"; then
  echo 'x - skipping resource.h (File already exists)'
else
  echo 'x - extracting resource.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'resource.h' &&
//{{NO_DEPENDENCIES}}
// App Studio generated include file.
// Used by ASTROLOG.RC
//
#define menu                            101
#define accelerator                     111
#define icon                            121
#define icon2                           122
#define icon3                           123
#define icon4                           124
#define dlgAbort                        201
#define dlgCommand                      202
#define dlgColor                        203
#define dlgInfo                         204
#define dlgDefault                      205
#define dlgInfoAll                      206
#define dlgAspect                       207
#define dlgObject                       208
#define dlgObject2                      209
#define dlgRestrict                     210
#define dlgStar                         211
#define dlgSetting                      212
#define dlgObscure                      213
#define dlgProgress                     214
#define dlgTransit                      215
#define dlgChart                        216
#define dlgGraphics                     217
#define dlgAbout                        218
#define dbAs_RA                         1001
#define dbAs_RA0                        1002
#define dbAs_RA1                        1003
#define dbIa_i1                         1004
#define dbIa_i2                         1005
#define dbIa_i3                         1006
#define dbIa_i4                         1007
#define dbIa_o1                         1008
#define dbIa_o2                         1009
#define dbIa_o3                         1010
#define dbIa_o4                         1011
#define dbInNow                         1012
#define dbInSet                         1013
#define dbPr_pn                         1014
#define dbRe_R                          1015
#define dbRe_R0                         1016
#define dbRe_R1                         1017
#define dbRe_RC                         1018
#define dbRe_Ru                         1019
#define dbRT                            1020
#define dbSt_RU0                        1021
#define dbSt_RU1                        1022
#define dbTr_tn                         1023
#define dca01                           1024
#define dca02                           1025
#define dca03                           1026
#define dca04                           1027
#define dca05                           1028
#define dca06                           1029
#define dca07                           1030
#define dca08                           1031
#define dca09                           1032
#define dca10                           1033
#define dca11                           1034
#define dca12                           1035
#define dca13                           1036
#define dca14                           1037
#define dca15                           1038
#define dca16                           1039
#define dca17                           1040
#define dca18                           1041
#define dcDeCor                         1042
#define dcDeDst                         1043
#define dcDeLat                         1044
#define dcDeLon                         1045
#define dcDeZon                         1046
#define dce0                            1047
#define dce1                            1048
#define dce2                            1049
#define dce3                            1050
#define dcInDay                         1051
#define dcInDst                         1052
#define dcInfoDay                       1053
#define dcInfoMon                       1054
#define dcInfoYea                       1055
#define dcInLat                         1056
#define dcInLon                         1057
#define dcInMon                         1058
#define dcInTim                         1059
#define dcInYea                         1060
#define dcInZon                         1061
#define dck00                           1062
#define dck01                           1063
#define dck02                           1064
#define dck03                           1065
#define dck04                           1066
#define dck05                           1067
#define dck06                           1068
#define dck07                           1069
#define dck08                           1070
#define dck09                           1071
#define dck10                           1072
#define dck11                           1073
#define dck12                           1074
#define dck13                           1075
#define dck14                           1076
#define dck15                           1077
#define dcPrDay                         1078
#define dcPrMon                         1079
#define dcPrTim                         1080
#define dcPrYea                         1081
#define dcPr_pd                         1082
#define dcSe_s                          1083
#define dcTrDay                         1084
#define dcTrMon                         1085
#define dcTrTim                         1086
#define dcTrYea                         1087
#define dea01                           1088
#define dea02                           1089
#define dea03                           1090
#define dea04                           1091
#define dea05                           1092
#define dea06                           1093
#define dea07                           1094
#define dea08                           1095
#define dea09                           1096
#define dea10                           1097
#define dea11                           1098
#define dea12                           1099
#define dea13                           1100
#define dea14                           1101
#define dea15                           1102
#define dea16                           1103
#define dea17                           1104
#define dea18                           1105
#define dea19                           1106
#define dea20                           1107
#define deCh_L                          1108
#define deCh_P                          1109
#define deCh_w                          1110
#define deCo                            1111
#define deGr_WN                         1112
#define deGr_X1                         1113
#define deGr_XG                         1114
#define deGr_XW                         1115
#define deGr_Xw_x                       1116
#define deGr_Xw_y                       1117
#define dei01                           1118
#define dei02                           1119
#define dei03                           1120
#define dei04                           1121
#define dei05                           1122
#define dei06                           1123
#define dei07                           1124
#define dei08                           1125
#define dei09                           1126
#define dei10                           1127
#define dei11                           1128
#define dei12                           1129
#define dei13                           1130
#define dei14                           1131
#define dei15                           1132
#define dei16                           1133
#define dei17                           1134
#define dei18                           1135
#define dei19                           1136
#define dei20                           1137
#define deInLoc                         1138
#define deInNam                         1139
#define deo01                           1140
#define deo02                           1141
#define deo03                           1142
#define deo04                           1143
#define deo05                           1144
#define deo06                           1145
#define deo07                           1146
#define deo08                           1147
#define deo09                           1148
#define deo10                           1149
#define deo11                           1150
#define deo12                           1151
#define deo13                           1152
#define deo14                           1153
#define deo15                           1154
#define deo16                           1155
#define deo17                           1156
#define deo18                           1157
#define deo19                           1158
#define deo20                           1159
#define deOb_YXg                        1160
#define deOb_YXp0_x                     1161
#define deOb_YXp0_y                     1162
#define deSe_1                          1163
#define deSe_A                          1164
#define deSe_h                          1165
#define deSe_I                          1166
#define deSe_x                          1167
#define deTr_d                          1168
#define deTr_tY                         1169
#define dr01                            1170
#define dr02                            1171
#define dr03                            1172
#define dr04                            1173
#define dr05                            1174
#define dr06                            1175
#define dr07                            1176
#define dr08                            1177
#define dr09                            1178
#define dr10                            1179
#define dr11                            1180
#define dx01                            1181
#define dx02                            1182
#define dx03                            1183
#define dx04                            1184
#define dx05                            1185
#define dx06                            1186
#define dx07                            1187
#define dx08                            1188
#define dx09                            1189
#define dx10                            1190
#define dx11                            1191
#define dx12                            1192
#define dx13                            1193
#define dx14                            1194
#define dx15                            1195
#define dx16                            1196
#define dx17                            1197
#define dx18                            1198
#define dx19                            1199
#define dx20                            1200
#define dx21                            1201
#define dx22                            1202
#define dx23                            1203
#define dx24                            1204
#define dx25                            1205
#define dx26                            1206
#define dx27                            1207
#define dx28                            1208
#define dx29                            1209
#define dx30                            1210
#define dx31                            1211
#define dx32                            1212
#define dx33                            1213
#define dx34                            1214
#define dx35                            1215
#define dx36                            1216
#define dx37                            1217
#define dx38                            1218
#define dx39                            1219
#define dx40                            1220
#define dx41                            1221
#define dx42                            1222
#define dx43                            1223
#define dx44                            1224
#define dx45                            1225
#define dx46                            1226
#define dx47                            1227
#define dxa01                           1228
#define dxa02                           1229
#define dxa03                           1230
#define dxa04                           1231
#define dxa05                           1232
#define dxa06                           1233
#define dxa07                           1234
#define dxa08                           1235
#define dxa09                           1236
#define dxa10                           1237
#define dxa11                           1238
#define dxa12                           1239
#define dxa13                           1240
#define dxa14                           1241
#define dxa15                           1242
#define dxa16                           1243
#define dxa17                           1244
#define dxa18                           1245
#define dxCh_a0                         1246
#define dxCh_Ey                         1247
#define dxCh_g0                         1248
#define dxCh_j0                         1249
#define dxCh_Ky                         1250
#define dxCh_l                          1251
#define dxCh_L0                         1252
#define dxCh_m0                         1253
#define dxCh_ma                         1254
#define dxCh_P0                         1255
#define dxCh_v0                         1256
#define dxCh_w0                         1257
#define dxCh_Z0                         1258
#define dxGr_Wn                         1259
#define dxGr_XW0                        1260
#define dxOb_Y8                         1261
#define dxOb_YC                         1262
#define dxOb_Yc0                        1263
#define dxOb_Yd                         1264
#define dxOb_Yn                         1265
#define dxOb_Yo                         1266
#define dxOb_YR0_d                      1267
#define dxOb_YR0_s                      1268
#define dxOb_Yt                         1269
#define dxOb_YXf                        1270
#define dxPr_p                          1271
#define dxSe_b                          1272
#define dxSe_sr                         1273
#define dxTr_p                          1274
#define dxTr_r                          1275
#define cmdAnimateF1                    40001
#define cmdAnimateF2                    40002
#define cmdAnimateF3                    40003
#define cmdAnimateF4                    40004
#define cmdAnimateF5                    40005
#define cmdAnimateF6                    40006
#define cmdAnimateF7                    40007
#define cmdAnimateF8                    40008
#define cmdAnimateF9                    40009
#define cmdAnimatePause                 40010
#define cmdAnimateReverse               40011
#define cmdAnimateNo                    40012
#define cmdAnimateS1                    40013
#define cmdAnimateS2                    40014
#define cmdAnimateS3                    40015
#define cmdAnimateS4                    40016
#define cmdAnimateS5                    40017
#define cmdAnimateS6                    40018
#define cmdAnimateS7                    40019
#define cmdAnimateS8                    40020
#define cmdAnimateS9                    40021
#define cmdAnimateNow                   40022
#define cmdApplying                     40023
#define cmdAspect                       40024
#define cmdChartArabic                  40025
#define cmdChartAspect                  40026
#define cmdChartAstroGraph              40027
#define cmdChartCalendar                40028
#define cmdChartEphemeris               40029
#define cmdChartGlobe                   40030
#define cmdChartGrid                    40031
#define cmdChartHorizon                 40032
#define cmdChartInfluence               40033
#define cmdChartList                    40034
#define cmdChartMap                     40035
#define cmdChartMidpoint                40036
#define cmdChartModify                  40037
#define cmdChartOrbit                   40038
#define cmdChartPolar                   40039
#define cmdChartResizesWindow           40040
#define cmdChartRising                  40041
#define cmdChartSector                  40042
#define cmdChartSettings                40043
#define cmdChartWheel                   40044
#define cmdColor                        40045
#define cmdColoredText                  40046
#define cmdCommand                      40047
#define cmdConstellation                40048
#define cmdCopyBitmap                   40049
#define cmdCopyPicture                  40050
#define cmdCopyPS                       40051
#define cmdCopyText                     40052
#define cmdDefaultInfo                  40053
#define cmdDocDefault                   40054
#define cmdDocHelpfile                  40055
#define cmdDocHomepage                  40056
#define cmdDocReadme                    40057
#define cmdDocSummary                   40058
#define cmdDocUpdate                    40059
#define cmdFileExit                     40060
#define cmdGraphics                     40061
#define cmdGraphicsBorder               40062
#define cmdGraphicsLabel                40063
#define cmdGraphicsModify               40064
#define cmdGraphicsMonochrome           40065
#define cmdGraphicsReverse              40066
#define cmdGraphicsSidebar              40067
#define cmdGraphicsSquare               40068
#define cmdGraphicsText                 40069
#define cmdHeliocentric                 40070
#define cmdHelpAbout                    40071
#define cmdHelpAspect                   40072
#define cmdHelpConstellation            40073
#define cmdHelpCredit                   40074
#define cmdHelpKeystroke                40075
#define cmdHelpMeaning                  40076
#define cmdHelpObject                   40077
#define cmdHelpObscure                  40078
#define cmdHelpPlanetInfo               40079
#define cmdHelpSign                     40080
#define cmdHelpSwitch                   40081
#define cmdHouse00                      40082
#define cmdHouse01                      40083
#define cmdHouse02                      40084
#define cmdHouse03                      40085
#define cmdHouse04                      40086
#define cmdHouse05                      40087
#define cmdHouse06                      40088
#define cmdHouse07                      40089
#define cmdHouse08                      40090
#define cmdHouse09                      40091
#define cmdHouse10                      40092
#define cmdHouse11                      40093
#define cmdHouse12                      40094
#define cmdHouse13                      40095
#define cmdHouse14                      40096
#define cmdHouseSetDecan                40097
#define cmdHouseSetFlip                 40098
#define cmdHouseSetGeodetic             40099
#define cmdHouseSetNavamsa              40100
#define cmdHouseSetSolar                40101
#define cmdHouseSetVedic                40102
#define cmdInterpret                    40103
#define cmdMacro01                      40104
#define cmdMacro02                      40105
#define cmdMacro03                      40106
#define cmdMacro04                      40107
#define cmdMacro05                      40108
#define cmdMacro06                      40109
#define cmdMacro07                      40110
#define cmdMacro08                      40111
#define cmdMacro09                      40112
#define cmdMacro10                      40113
#define cmdMacro11                      40114
#define cmdMacro12                      40115
#define cmdMacro13                      40116
#define cmdMacro14                      40117
#define cmdMacro15                      40118
#define cmdMacro16                      40119
#define cmdMacro17                      40120
#define cmdMacro18                      40121
#define cmdMacro19                      40122
#define cmdMacro20                      40123
#define cmdMacro21                      40124
#define cmdMacro22                      40125
#define cmdMacro23                      40126
#define cmdMacro24                      40127
#define cmdMacro25                      40128
#define cmdMacro26                      40129
#define cmdMacro27                      40130
#define cmdMacro28                      40131
#define cmdMacro29                      40132
#define cmdMacro30                      40133
#define cmdMacro31                      40134
#define cmdMacro32                      40135
#define cmdMacro33                      40136
#define cmdMacro34                      40137
#define cmdMacro35                      40138
#define cmdMacro36                      40139
#define cmdMacro37                      40140
#define cmdMacro38                      40141
#define cmdMacro39                      40142
#define cmdMacro40                      40143
#define cmdMacro41                      40144
#define cmdMacro42                      40145
#define cmdMacro43                      40146
#define cmdMacro44                      40147
#define cmdMacro45                      40148
#define cmdMacro46                      40149
#define cmdMacro47                      40150
#define cmdMacro48                      40151
#define cmdNow                          40152
#define cmdObject                       40153
#define cmdObject2                      40154
#define cmdObscure                      40155
#define cmdOpenChart                    40156
#define cmdOpenChart2                   40157
#define cmdParallel                     40158
#define cmdPen00                        40159
#define cmdPen01                        40160
#define cmdPen02                        40161
#define cmdPen03                        40162
#define cmdPen04                        40163
#define cmdPen05                        40164
#define cmdPen06                        40165
#define cmdPen07                        40166
#define cmdPen08                        40167
#define cmdPen09                        40168
#define cmdPen10                        40169
#define cmdPen11                        40170
#define cmdPen12                        40171
#define cmdPen13                        40172
#define cmdPen14                        40173
#define cmdPen15                        40174
#define cmdPrint                        40175
#define cmdPrintSetup                   40176
#define cmdProgress                     40177
#define cmdRecall                       40178
#define cmdRelBiorhythm                 40179
#define cmdRelComparison                40180
#define cmdRelComposite                 40181
#define cmdRelDate                      40182
#define cmdRelMidpoint                  40183
#define cmdRelNo                        40184
#define cmdRelProgressed                40185
#define cmdRelSynastry                  40186
#define cmdRelTransit                   40187
#define cmdRes                          40188
#define cmdResCusp                      40189
#define cmdResMinor                     40190
#define cmdResStar                      40191
#define cmdResTransit                   40192
#define cmdResUranian                   40193
#define cmdSaveBitmap                   40194
#define cmdSaveChart                    40195
#define cmdSavePicture                  40196
#define cmdSavePositions                40197
#define cmdSavePS                       40198
#define cmdSaveSettings                 40199
#define cmdSaveText                     40200
#define cmdSaveWallCenter               40201
#define cmdSaveWallTile                 40202
#define cmdScale1                       40203
#define cmdScale2                       40204
#define cmdScale3                       40205
#define cmdScale4                       40206
#define cmdScaleDecrease                40207
#define cmdScaleIncrease                40208
#define cmdScrollEnd                    40209
#define cmdScrollHome                   40210
#define cmdScrollPageDown               40211
#define cmdScrollPageUp                 40212
#define cmdSecond                       40213
#define cmdSetInfo                      40214
#define cmdSetInfo2                     40215
#define cmdSetInfoAll                   40216
#define cmdSettingGraphics              40217
#define cmdSettingMore                  40218
#define cmdSidereal                     40219
#define cmdSizeChartToWindow            40220
#define cmdSizeWindowToChart            40221
#define cmdStar                         40222
#define cmdStepBackward                 40223
#define cmdStepForward                  40224
#define cmdStore                        40225
#define cmdTiltDecrease                 40226
#define cmdTiltIncrease                 40227
#define cmdTiltZero                     40228
#define cmdTimedExposure                40229
#define cmdTransit                      40230
#define cmdWinBuffer                    40231
#define cmdWinClear                     40232
#define cmdWindowResizesChart           40233
#define cmdWinHourglass                 40234
#define cmdWinRedraw                    40235
#define IDC_STATIC                      -1
X
// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
X
#define _APS_NEXT_RESOURCE_VALUE        302
#define _APS_NEXT_COMMAND_VALUE         40307
#define _APS_NEXT_CONTROL_VALUE         1303
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif
SHAR_EOF
  $shar_touch -am 1223232998 'resource.h' &&
  chmod 0644 'resource.h' ||
  echo 'restore of resource.h failed'
  shar_count="`wc -c < 'resource.h'`"
  test 24666 -eq "$shar_count" ||
    echo "resource.h: original size 24666, current size $shar_count"
fi
# ============= wdialog.c ==============
if test -f 'wdialog.c' && test X"$1" != X"-c"; then
  echo 'x - skipping wdialog.c (File already exists)'
else
  echo 'x - extracting wdialog.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'wdialog.c' &&
/*
** Astrolog (Version 5.40) File: wdialog.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
#ifdef WIN
/*
******************************************************************************
** Dialog Utility Functions.
******************************************************************************
*/
X
/* Set the contents of the given edit control in a dialog to a string. */
X
void SetEditSz(hdlg, id, sz)
HWND hdlg;
int id;
char *sz;
{
X  while (*sz == ' ')    /* Strip off any extra leading spaces. */
X    sz++;
X  SetEdit(id, sz);
}
X
X
/* Set the contents of the given edit control in a dialog to a floating */
/* point value, with at most 'n' significant fractional digits.         */
X
void SetEditR(hdlg, id, r, n)
HWND hdlg;
int id;
real r;
int n;
{
X  char sz[cchSzDef], szT[8], *pch;
X
X  sprintf(szT, "%%.%df", n);
X  sprintf(sz, szT, r);
X  for (pch = sz; *pch; pch++)
X    ;
X  while (*(--pch) == '0')          /* Drop off any trailing zero digits. */
X    ;
X  pch[1 + (*pch == '.')] = chNull; /* Ensure at least one fractional digit. */
X  SetEdit(id, sz);
}
X
X
/* Set the contents of four combo controls and their dropdowns in a dialog */
/* indicating month, day, year, and time fields to the given values.       */
X
void SetEditMDYT(hdlg, idMon, idDay, idYea, idTim, mon, day, yea, tim)
HWND hdlg;
int idMon, idDay, idYea, idTim;
int mon, day, yea;
real tim;
{
X  char sz[cchSzDef];
X  int i;
X
X  ClearCombo(idMon);
X  ClearCombo(idDay);
X  ClearCombo(idYea);
X  ClearCombo(idTim);
X  if (!FValidMon(mon))
X    mon = 1;
X  sprintf(sz, "%c%c%c", chMon3(mon));
X  SetEdit(idMon, sz);
X  for (i = 1; i <= cSign; i++)
X    SetCombo(idMon, szMonth[i]);
X  if (!FValidDay(day, mon, yea))
X    day = 1;
X  SetEditN(idDay, day);
X  SetCombo(idDay, "1"); SetCombo(idDay, "15");
X  SetEditN(idYea, yea);
X  for (i = 1990; i < 2000; i++) {
X    sprintf(sz, "%d", i); SetCombo(idYea, sz);
X  }
X  sprintf(sz, "%s", SzTim(tim));
X  SetEditSz(hdlg, idTim, sz);
X  SetCombo(idTim, "Midnight");
X  SetCombo(idTim, (char *)(us.fEuroTime ? "6:00" : "6:00am"));
X  SetCombo(idTim, "Noon");
X  SetCombo(idTim, (char *)(us.fEuroTime ? "18:00" : "6:00pm"));
}
X
X
/* Set the contents of four combo controls in a dialog indicating daylight, */
/* time zone, longitude, and latitude fields to the given values.           */
X
void SetEditSZOA(hdlg, idDst, idZon, idLon, idLat, dst, zon, lon, lat)
HWND hdlg;
int idDst, idZon, idLon, idLat;
real dst, zon, lon, lat;
{
X  char sz[cchSzDef];
X  int i;
X  bool fT;
X
X  if (dst == 0.0 || dst == 1.0)
X    sprintf(sz, "%s", dst == 0.0 ? "No" : "Yes");
X  else
X    sprintf(sz, "%.2f", dst);
X  SetEdit(idDst, sz);
X  SetCombo(idDst, "No"); SetCombo(idDst, "Yes");
X  sprintf(sz, "%s", SzZone(-zon));
X  SetEdit(idZon, (char *)(sz[0] == '+' ? &sz[1] : sz));
X  /* For the time zone dropdown, fill it out with all abbreviations of */
X  /* three letters that don't reference daylight or war time.          */
X  for (i = 0; i < cZone; i++) {
X    if (szZon[i][1] && szZon[i][1] != 'D' && szZon[i][1] != 'W' &&
X      szZon[i][2] && szZon[i][2] != 'D')
X      SetCombo(idZon, szZon[i]);
X  }
X  fT = us.fAnsiChar; us.fAnsiChar = fFalse;
X  sprintf(sz, "%s", SzLocation(lon, lat));
X  us.fAnsiChar = fT;
X  sz[7] = chNull;
X  SetEditSz(hdlg, idLon, &sz[0]);
X  SetCombo(idLon, "122W20"); SetCombo(idLon, "0E00");
X  SetEditSz(hdlg, idLat, &sz[8]);
X  SetCombo(idLat, "47N36"); SetCombo(idLat, "0S00");
}
X
X
/* Set the contents of a combo control in a dialog indicating a color   */
/* field to the given value, and fill its dropdown with the color list. */
X
void SetEditColor(hdlg, id, ki)
HWND hdlg;
int id;
KI ki;
{
X  int i;
X
X  SetEdit(id, szColor[ki]);
X  for (i = 0; i < cColor; i++)
X    SetCombo(id, szColor[i]);
}
X
X
/* Return the contents of a dialog edit control as a floating point value. */
X
real GetEditR(hdlg, id)
HWND hdlg;
int id;
{
X  char sz[cchSzDef];
X
X  GetEdit(id, sz);
X  return atof(sz);
}
X
X
/* Bring up an error box indicating an illegal value for a dialog field. */
X
void ErrorEnsure(n, sz)
int n;
char *sz;
{
X  char szT[cchSzDef];
X
X  sprintf(szT, "The value %d is not a valid %s setting.", n, sz);
X  PrintWarning(szT);
}
X
X
/* Take many of the user visible settings, and write them out to a new     */
/* command switch file, which may be read in to restore those settings.    */
/* Most often this would be used to create a new astrolog.dat default      */
/* settings file. This is called from the File Save Settings menu command. */
X
bool FOutputSettings()
{
X  char sz[cchSzDef];
X  FILE *file;
X  int i;
X  bool fT;
X
X  if (us.fNoWrite)
X    return fFalse;
X  file = fopen(is.szFileOut, "w");  /* Create and open the file for output. */
X  if (file == NULL) {
X    sprintf(sz, "Settings file %s can not be created.", is.szFileOut);
X    PrintError(sz);
X    return fFalse;
X  }
X
X  sprintf(sz, "@0308  ; %s (%s) default settings file %s\n\n",
X    szAppName, szVersionCore, DEFAULT_INFOFILE); PrintFSz();
X
X  sprintf(sz, "-z0 %d             ", (int)us.dstDef); PrintFSz();
X  PrintF("; Default Daylight time setting   [0 standard, 1 daylight]\n");
X  sprintf(sz, "-z %s          ", SzZone(-us.zonDef)); PrintFSz();
X  PrintF("; Default time zone               [hours before GMT      ]\n");
X  fT = us.fAnsiChar; us.fAnsiChar = 3;
X  sprintf(sz, "-zl %s  ", SzLocation(us.lonDef, us.latDef)); PrintFSz();
X  us.fAnsiChar = fT;
X  PrintF("; Default longitude and latitude\n\n");
X
X  sprintf(sz, "-Yz %ld   ", us.lTimeAddition); PrintFSz();
X  PrintF(
X    "; Time minute addition to be used when \"now\" charts are off.\n-n");
X  PrintF(
X    "      ; Uncomment this line to start with the chart for \"now\".\n\n");
X
X  sprintf(sz, "%cs      ", ChDashF(us.fSidereal)); PrintFSz();
X  PrintF(
X    "; Zodiac selection          [\"_s\" is tropical, \"=s\" is sidereal]\n");
X  sprintf(sz, ":s %.0f    ", us.rZodiacOffset); PrintFSz();
X  PrintF(
X    "; Zodiac offset value       [Change \"0\" to desired offset      ]\n");
X  sprintf(sz, "-A %d    ", us.nAsp); PrintFSz();
X  PrintF(
X    "; Number of aspects         [Change \"5\" to desired number      ]\n");
X  sprintf(sz, "-c %d    ", us.nHouseSystem); PrintFSz();
X  PrintF(
X    "; House system              [Change \"0\" to desired system      ]\n");
X  sprintf(sz, "%ck      ", ChDashF(us.fAnsiColor)); PrintFSz();
X  PrintF(
X    "; Ansi color text           [\"=k\" is color, \"_k\" is normal     ]\n");
X  sprintf(sz, ":d %d   ", us.nDivision); PrintFSz();
X  PrintF(
X    "; Searching divisions       [Change \"12\" to desired divisions  ]\n");
X  sprintf(sz, "%cb0     ", ChDashF(us.fSeconds)); PrintFSz();
X  PrintF(
X    "; Print zodiac seconds      [\"_b0\" to minute, \"=b0\" to second  ]\n");
X  sprintf(sz, "%cb      ", ChDashF(us.fPlacalc)); PrintFSz();
X  PrintF(
X    "; Use ephemeris files       [\"=b\" uses them, \"_b\" doesn't      ]\n");
X  sprintf(sz, "%cC      ", ChDashF(us.fCusp)); PrintFSz();
X  PrintF(
X    "; Show house cusp objects   [\"_C\" hides them, \"=C\" shows them  ]\n");
X  sprintf(sz, ":w %d    ", us.nWheelRows); PrintFSz();
X  PrintF(
X    "; Wheel chart text rows     [Change \"4\" to desired wheel rows  ]\n");
X  sprintf(sz, ":I %d   ", us.nScreenWidth); PrintFSz();
X  PrintF(
X    "; Text screen columns       [Change \"80\" to desired columns    ]\n");
X  sprintf(sz, "-YQ %d  ", us.nScrollRow); PrintFSz();
X  PrintF(
X    "; Text screen scroll limit  [Change \"24\" or set to \"0\" for none]\n");
X  sprintf(sz, "%cYd     ", ChDashF(us.fEuroDate)); PrintFSz();
X  PrintF(
X    "; European date format      [\"_Yd\" is MDY, \"=Yd\" is DMY        ]\n");
X  sprintf(sz, "%cYt     ", ChDashF(us.fEuroTime)); PrintFSz();
X  PrintF(
X    "; European time format      [\"_Yt\" is AM/PM, \"=Yt\" is 24 hour  ]\n");
X  sprintf(sz, "%cYC     ", ChDashF(us.fSmartCusp)); PrintFSz();
X  PrintF(
X    "; Smart cusp displays       [\"=YC\" is smart, \"_YC\" is normal   ]\n");
X  sprintf(sz, "%cY8     ", ChDashF(us.fClip80)); PrintFSz();
X  PrintF(
X    "; Clip text to end of line  [\"=Y8\" clips, \"_Y8\" doesn't clip   ]\n");
X
X  PrintF("\n\n; DEFAULT RESTRICTIONS:\n\n-YR 1 10     ");
X  for (i = 1; i <= 10; i++) PrintF(SzNumF(ignore[i]));
X  PrintF("     ; Planets\n-YR 11 20    ");
X  for (i = 11; i <= 20; i++) PrintF(SzNumF(ignore[i]));
X  PrintF("     ; Minor planets\n-YR 21 32    ");
X  for (i = 21; i <= 32; i++) PrintF(SzNumF(ignore[i]));
X  PrintF(" ; House cusps\n-YR 33 40    ");
X  for (i = 33; i <= 40; i++) PrintF(SzNumF(ignore[i]));
X  PrintF("         ; Uranians\n\n");
X
X  PrintF("; DEFAULT TRANSIT RESTRICTIONS:\n\n-YRT 1 10    ");
X  for (i = 1; i <= 10; i++) PrintF(SzNumF(ignore2[i]));
X  PrintF("     ; Planets\n-YRT 11 20   ");
X  for (i = 11; i <= 20; i++) PrintF(SzNumF(ignore2[i]));
X  PrintF("     ; Minor planets\n-YRT 21 32   ");
X  for (i = 21; i <= 32; i++) PrintF(SzNumF(ignore2[i]));
X  PrintF(" ; House cusps\n-YRT 33 40   ");
X  for (i = 33; i <= 40; i++) PrintF(SzNumF(ignore2[i]));
X  PrintF("         ; Uranians\n\n");
X
X  sprintf(sz, "-YR0 %s%s ; Restrict sign, direction changes\n\n\n",
X    SzNumF(us.fIgnoreSign), SzNumF(us.fIgnoreDir)); PrintFSz();
X
X  PrintF("; DEFAULT ASPECT ORBS:\n\n-YAo 1 5    ");
X  for (i = 1; i <= 5; i++) { sprintf(sz, " %.1f", rAspOrb[i]); PrintFSz(); }
X  PrintF("      ; Major aspects\n-YAo 6 11   ");
X  for (i = 6; i <= 11; i++) { sprintf(sz, " %.1f", rAspOrb[i]); PrintFSz(); }
X  PrintF("    ; Minor aspects\n-YAo 12 18  ");
X  for (i = 12; i <= 18; i++) { sprintf(sz, " %.1f", rAspOrb[i]); PrintFSz(); }
X  PrintF("  ; Obscure aspects\n\n");
X
X  PrintF("; DEFAULT MAX PLANET ASPECT ORBS:\n\n-YAm 1 10   ");
X  for (i = 1; i <= 10; i++) { sprintf(sz, "%4.0f", rObjOrb[i]); PrintFSz(); }
X  PrintF("\n-YAm 11 20  ");
X  for (i = 11; i <= 20; i++) { sprintf(sz, "%4.0f", rObjOrb[i]); PrintFSz(); }
X  PrintF("\n-YAm 21 32  ");
X  for (i = 21; i <= 32; i++) { sprintf(sz, "%4.0f", rObjOrb[i]); PrintFSz(); }
X  PrintF("\n-YAm 33 40  ");
X  for (i = 33; i <= 40; i++) { sprintf(sz, "%4.0f", rObjOrb[i]); PrintFSz(); }
X
X  PrintF("\n\n; DEFAULT PLANET ASPECT ORB ADDITIONS:\n\n-YAd 1 10   ");
X  for (i = 1; i <= 10; i++) { sprintf(sz, " %.1f", rObjAdd[i]); PrintFSz(); }
X  PrintF("\n-YAd 11 20  ");
X  for (i = 11; i <= 20; i++) { sprintf(sz, " %.1f", rObjAdd[i]); PrintFSz(); }
X  PrintF("\n-YAd 21 32  ");
X  for (i = 21; i <= 32; i++) { sprintf(sz, " %.1f", rObjAdd[i]); PrintFSz(); }
X
X  PrintF("\n\n\n; DEFAULT INFLUENCES:\n\n-Yj 1 10   ");
X  for (i = 1; i <= 10; i++) { sprintf(sz, " %.0f", rObjInf[i]); PrintFSz(); }
X  PrintF("        ; Planets\n-Yj 11 20  ");
X  for (i = 11; i <= 20; i++) { sprintf(sz, " %.0f", rObjInf[i]); PrintFSz(); }
X  PrintF("                  ; Minor planets\n-Yj 21 32  ");
X  for (i = 21; i <= 32; i++) { sprintf(sz, " %.0f", rObjInf[i]); PrintFSz(); }
X  PrintF("  ; Cusp objects\n-Yj 33 40  ");
X  for (i = 33; i <= 40; i++) { sprintf(sz, " %.0f", rObjInf[i]); PrintFSz(); }
X  PrintF("                      ; Uranians\n\n-YjC 1 12  ");
X
X  for (i = 1; i <= 12; i++) { sprintf(sz, " %.0f", rHouseInf[i]); PrintFSz(); }
X  PrintF("  ; Houses\n\n-YjA 1 5   ");
X
X  for (i = 1; i <= 5; i++) { sprintf(sz, "%4.1f", rAspInf[i]); PrintFSz(); }
X  PrintF("          ; Major aspects\n-YjA 6 11  ");
X  for (i = 6; i <= 11; i++) { sprintf(sz, "%4.1f", rAspInf[i]); PrintFSz(); }
X  PrintF("      ; Minor aspects\n-YjA 12 18 ");
X  for (i = 12; i <= 18; i++) { sprintf(sz, "%4.1f", rAspInf[i]); PrintFSz(); }
X  PrintF("  ; Obscure aspects\n\n");
X
X  PrintF("; DEFAULT TRANSIT INFLUENCES:\n\n-YjT 1 10   ");
X  for (i = 1; i <= 10; i++)
X    { sprintf(sz, " %.0f", rTransitInf[i]); PrintFSz(); }
X  PrintF("  ; Planets\n-YjT 11 20  ");
X  for (i = 11; i <= 20; i++)
X    { sprintf(sz, " %.0f", rTransitInf[i]); PrintFSz(); }
X  PrintF("   ; Minor planets\n-YjT 33 40  ");
X  for (i = 33; i <= 40; i++)
X    { sprintf(sz, " %.0f", rTransitInf[i]); PrintFSz(); }
X
X  sprintf(sz, "     ; Uranians\n\n-Yj0 %.0f %.0f %.0f %.0f ",
X    rObjInf[oNorm + 1], rObjInf[oNorm + 2], rHouseInf[cSign + 1],
X    rHouseInf[cSign + 2]); PrintFSz();
X  PrintF("; In ruling sign, exalted sign, ruling house, exalted house.\n\n\n");
X
X  PrintF("; DEFAULT COLORS:\n\n-YkC");
X  for (i = eFir; i <= eWat; i++) { sprintf(sz, " %d", kElemA[i]); PrintFSz(); }
X  PrintF("                 ; Element colors\n-YkA 1 18 ");
X  for (i = 1; i <= cAspect; i++) { sprintf(sz, " %d", kAspA[i]); PrintFSz(); }
X  PrintF("  ; Aspect colors\n-Yk0 1 7  ");
X  for (i = 1; i <= 7; i++) { sprintf(sz, " %d", kRainbowA[i]); PrintFSz(); }
X  PrintF("    ; Rainbow colors\n-Yk  0 8  ");
X  for (i = 0; i <= 8; i++) { sprintf(sz, " %d", kMainA[i]); PrintFSz(); }
X  PrintF("  ; Main colors\n\n\n");
X
X  PrintF("; GRAPHICS DEFAULTS:\n\n");
X  sprintf(sz, "%cX              ", ChDashF(us.fGraphics)); PrintFSz();
X  PrintF("; Graphics chart flag [\"_X\" is text, \"=X\" is graphics]\n");
X  i = gs.xWin; if (fSidebar) i -= SIDESIZE;
X  sprintf(sz, ":Xw %d %d     ", i, gs.yWin); PrintFSz();
X  PrintF("; Default X and Y resolution\n");
X  sprintf(sz, ":Xb%c            ", ChUncap(gs.chBmpMode)); PrintFSz();
X  PrintF("; Bitmap file type\n");
X  sprintf(sz, ":YXG %d       ", gs.nGlyphs); PrintFSz();
X  PrintF("; Glyph selections\n");
X  sprintf(sz, ":YXg %d         ", gs.nGridCell); PrintFSz();
X  PrintF("; Aspect grid cells\n");
X  sprintf(sz, ":YXf %d          ", gs.fFont); PrintFSz();
X  PrintF("; Use actual fonts\n");
X  sprintf(sz, ":YXp %d          ", gs.nOrient); PrintFSz();
X  PrintF("; PostScript paper orientation\n");
X  sprintf(sz, ":YXp0 %.1f %.1f  ", gs.xInch, gs.yInch); PrintFSz();
X  PrintF("; PostScript paper X and Y inch sizes\n");
X  PrintF(":YX -1 16       ; PC hi-res and lo-res graphics modes\n\n");
X
X  sprintf(sz, "; %s\n", DEFAULT_INFOFILE); PrintFSz();
X  fclose(file);
X  return fTrue;
}
X
X
/*
******************************************************************************
** Windows Dialogs.
******************************************************************************
*/
X
/* Bring up the Windows standard file open dialog, and process the        */
/* command file specified if any. This is called from the File Open Chart */
/* and File Open Chart #2 menu commands.                                  */
X
bool API DlgOpenChart()
{
X  char sz[cchSzDef];
X  CI ciT;
X
X  /* Setup dialog title and settings and get the name of a file from it. */
X  if (us.fNoRead) {
X    PrintWarning("File input is not allowed now.");
X    return fFalse;
X  }
X  sprintf(sz, "Open Chart #%d", wi.nDlgChart);
X  if (wi.nDlgChart < 2)
X    sz[10] = chNull;
X  ofn.lpstrTitle = sz;
X  ofn.lpstrFilter = "All Files (*.*)\0*.*\0Data Files (*.DAT)\0*.DAT\0";
X  szFileName[0] = chNull;
X  if (!GetOpenFileName((LPOPENFILENAME)&ofn))
X    return fFalse;
X
X  /* Process the given file based on what open command is being run. */
X  ciT = ciCore;
X  FInputData(ofn.lpstrFileTitle);
X  if (wi.nDlgChart > 1) {
X    if (wi.nDlgChart == 2)
X      ciTwin = ciCore;
X    else if (wi.nDlgChart == 3)
X      ciThre = ciCore;
X    else
X      ciFour = ciCore;
X    ciCore = ciT;
X  }
X
X  wi.fCast = fTrue;
X  return fTrue;
}
X
X
/* Bring up the Windows standard file save dialog, get the name of a file   */
/* from the user, and save to it either right away or set variables to      */
/* ensure it will be done later. This is called from all six File Save menu */
/* commands: Save Info, Positions, Text, Bitmap, Picture, and PostScript.   */
X
bool API DlgSaveChart()
{
X  char *pch;
X
X  /* Setup dialog title and settings and get the name of a file from it. */
X  if (us.fNoWrite) {
X    PrintWarning("File output is not allowed now.");
X    return fFalse;
X  }
X  ofn.lpstrFilter = "All Files (*.*)\0*.*\0Data Files (*.DAT)\0*.DAT\0";
X  szFileName[0] = chNull;
X  switch (wi.wCmd) {
X  case cmdSaveChart:
X    ofn.lpstrTitle = "Save Chart Info";
X    break;
X  case cmdSavePositions:
X    ofn.lpstrTitle = "Save Chart Positions";
X    break;
X  case cmdSaveText:
X    ofn.lpstrTitle = "Save Chart Text";
X    ofn.lpstrFilter = "All Files (*.*)\0*.*\0Text Files (*.TXT)\0*.TXT\0";
X    break;
X  case cmdSaveBitmap:
X    ofn.lpstrTitle = "Save Chart Bitmap";
X    ofn.lpstrFilter =
X      "Windows Bitmap (*.BMP)\0*.BMP\0All Files (*.*)\0*.*\0";
X    break;
X  case cmdSavePicture:
X    ofn.lpstrTitle = "Save Chart Picture";
X    ofn.lpstrFilter =
X      "Windows Metafile (*.WMF)\0*.WMF\0All Files (*.*)\0*.*\0";
X    break;
X  case cmdSavePS:
X    ofn.lpstrTitle = "Save Chart PostScript";
X    ofn.lpstrFilter =
X      "PostScript Text (*.EPS)\0*.EPS\0All Files (*.*)\0*.*\0";
X    break;
X  case cmdSaveSettings:
X    ofn.lpstrTitle = "Save Settings";
X    ofn.lpstrFilter = "Data Files (*.DAT)\0*.DAT\0All Files (*.*)\0*.*\0";
X    sprintf(szFileName, "%s", DEFAULT_INFOFILE);
X    break;
X  }
X  if (wi.wCmd != cmdSaveWallTile && wi.wCmd != cmdSaveWallCenter) {
X    if (!GetSaveFileName((LPOPENFILENAME)&ofn))
X      return fFalse;
X  } else {
X    ofn.lpstrFile = PAllocate(cchSzDef, fTrue, NULL);
X    GetWindowsDirectory(ofn.lpstrFile, cchSzDef);
X    pch = ofn.lpstrFile + CchSz(ofn.lpstrFile);
X    sprintf(pch, "%c%s%s", '\\', szAppName, ".bmp");
X  }
X
X  /* Saving chart info, position, or setting command files can be done  */
X  /* here. Saving actual chart output isn't done until the next redraw. */
X  is.szFileOut = gi.szFileOut = ofn.lpstrFile;
X  switch (wi.wCmd) {
X  case cmdSaveChart:
X    us.fWritePos = fFalse;
X    return FOutputData();
X  case cmdSavePositions:
X    us.fWritePos = fTrue;
X    return FOutputData();
X  case cmdSaveText:
X    is.szFileScreen = ofn.lpstrFile;
X    us.fGraphics = fFalse;
X    wi.fRedraw = fTrue;
X    break;
X  case cmdSaveBitmap:
X  case cmdSaveWallTile:
X  case cmdSaveWallCenter:
X    gs.fBitmap = fTrue;
X    gs.fMeta = gs.fPS = fFalse;
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X  case cmdSavePicture:
X    gs.fMeta = fTrue;
X    gs.fBitmap = gs.fPS = fFalse;
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X  case cmdSavePS:
X    gs.fPS = fTrue;
X    gs.fBitmap = gs.fMeta = fFalse;
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X  case cmdSaveSettings:
X    return FOutputSettings();
X  }
X  return fTrue;
}
X
X
/* Bring up the Windows standard print dialog, receive any printing       */
/* settings from the user, and proceed to print the current graphics or   */
/* text chart as displayed in the window. Called from File Print command. */
X
bool API DlgPrint()
{
X  FARPROC lpAbortDlg, lpAbortProc;
X  HDC hdc;
X  LPDEVMODE lpDevMode = NULL;
X  LPDEVNAMES lpDevNames;
X  LPSTR lpszDriverName;
X  LPSTR lpszDeviceName;
X  LPSTR lpszPortName;
X  DOCINFO doci;
X  int xPrint, yPrint;
X  int xClient, yClient;
X
X  /* Bring up the Windows print dialog. */
X  wi.fNoUpdate = fFalse;
X  if (!PrintDlg((LPPRINTDLG)&prd))
X    return fTrue;
X
X  /* Get the printer DC. */
X  if (prd.hDC)
X    hdc = prd.hDC;
X  else {
X    /* If the dialog didn't just return the DC, try to make one manually. */
X    if (!prd.hDevNames)
X      return fFalse;
X    lpDevNames = (LPDEVNAMES)GlobalLock(prd.hDevNames);
X    lpszDriverName = (LPSTR)lpDevNames + lpDevNames->wDriverOffset;
X    lpszDeviceName = (LPSTR)lpDevNames + lpDevNames->wDeviceOffset;
X    lpszPortName = (LPSTR)lpDevNames + lpDevNames->wOutputOffset;
X    GlobalUnlock(prd.hDevNames);
X    if (prd.hDevMode)
X      lpDevMode = (LPDEVMODE)GlobalLock(prd.hDevMode);
X    hdc = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName,
X      (LPSTR)lpDevMode);
X    if (prd.hDevMode && lpDevMode)
X      GlobalUnlock(prd.hDevMode);
X  }
X  if (prd.hDevNames) {
X    GlobalFree(prd.hDevNames);
X    prd.hDevNames = (HGLOBAL)NULL;
X  }
X  if (prd.hDevMode) {
X    GlobalFree(prd.hDevMode);
X    prd.hDevMode = (HGLOBAL)NULL;
X  }
X
X  /* Setup the abort dialog and start the print job. */
X  lpAbortDlg = MakeProcInstance(DlgAbort, wi.hinst);
X  lpAbortProc = MakeProcInstance(DlgAbortProc, wi.hinst);
X  SetAbortProc(hdc, lpAbortProc);
X  doci.cbSize = sizeof(DOCINFO);
X  doci.lpszDocName = szAppName;
X  doci.lpszOutput = NULL;
X  if (StartDoc(hdc, &doci) < 0) {
X    FreeProcInstance(lpAbortDlg);
X    FreeProcInstance(lpAbortProc);
X    DeleteDC(hdc);
X    return fFalse;
X  }
X  wi.fAbort = FALSE;
X  wi.hwndAbort = CreateDialog(wi.hinst, MAKEINTRESOURCE(dlgAbort), wi.hwnd,
X    lpAbortDlg);
X  if (!wi.hwndAbort)
X    return fFalse;
X  ShowWindow(wi.hwndAbort, SW_NORMAL);
X  EnableWindow(wi.hwnd, fFalse);
X  StartPage(hdc);
X
X  /* Scale the chart to the page. */
X  if (us.fGraphics) {
X    gs.xWin *= METAMUL; gs.yWin *= METAMUL; gs.nScale *= METAMUL;
X  }
X  SetMapMode(hdc, MM_ANISOTROPIC);       /* So SetViewPortExt can be called */
X  xPrint = GetDeviceCaps(hdc, HORZRES);
X  yPrint = GetDeviceCaps(hdc, VERTRES);
X  SetViewportOrg(hdc, 0, 0);
X  SetViewportExt(hdc, xPrint, yPrint);
X  xClient = wi.xClient; yClient = wi.yClient;
X  wi.xClient = gs.xWin;
X  wi.yClient = NMultDiv(wi.xClient, yPrint, xPrint);
X  if (gs.yWin > wi.yClient) {
X    wi.yClient = gs.yWin;
X    wi.xClient = NMultDiv(wi.yClient, xPrint, yPrint);
X  }
X  wi.hdcPrint = hdc;
X
X  FRedraw();    /* Actually go "draw" the chart to the printer. */
X
X  /* Restore globals that were temporarily changed to print above. */
X  wi.hdcPrint = hdcNil;
X  wi.xClient = xClient; wi.yClient = yClient;
X  if (us.fGraphics) {
X    gs.xWin /= METAMUL; gs.yWin /= METAMUL; gs.nScale /= METAMUL;
X  }
X
X  /* Finalize and cleanup everything. */
X  if (!wi.fAbort) {
X    EndPage(hdc);
X    EndDoc(hdc);
X  }
X  EnableWindow(wi.hwnd, fTrue);
X  DestroyWindow(wi.hwndAbort);
X  FreeProcInstance(DlgAbort);
X  FreeProcInstance(DlgAbortProc);
X  DeleteDC(hdc);
X
X  return fTrue;
}
X
X
/* Message loop function for the printing abort dialog. Loops until       */
/* printing is completed or the user hits cancel, returning which result. */
X
bool API EXPORT DlgAbortProc(hdc, nCode)
HDC hdc;
int nCode;
{
X  MSG msg;
X
X  if (wi.hwndAbort == (HWND)NULL)
X    return fTrue;
X  while (!wi.fAbort && PeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE))
X    if (!IsDialogMessage(wi.hwndAbort, &msg)) {
X      TranslateMessage(&msg);
X      DispatchMessage(&msg);
X    }
X  return !wi.fAbort;
}
X
X
/* Processing function for the printing abort modeless dialog, as brought */
/* up temporarily when printing via the File Print menu command.          */
X
bool API DlgAbort(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  switch (message) {
X  case WM_INITDIALOG:
X    SetFocus(GetDlgItem(hdlg, IDCANCEL));
X    return fFalse;
X
X  case WM_COMMAND:
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      wi.fAbort = fTrue;
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the command switch entry dialog, as brought up */
/* with the Edit Enter Command Line menu command.                         */
X
bool API DlgCommand(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  char sz[cchSzDef];
X
X  switch (message) {
X  case WM_INITDIALOG:
X    SetFocus(GetDlgItem(hdlg, deCo));
X    return fFalse;
X
X  case WM_COMMAND:
X    if (wParam == IDOK) {
X      GetDlgItemText(hdlg, deCo, sz, cchSzDef);
X      FProcessCommandLine(sz);
X      wi.fCast = wi.fMenuAll = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the color customization dialog, as brought up */
/* with the View Set Colors menu command.                                */
X
bool API DlgColor(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  char sz[cchSzDef];
X  int i, j, k, l;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    for (i = 0; i < 4; i++)
X      SetEditColor(hdlg, dce0 + i, kElemA[i]);
X    for (i = 1; i <= cAspect; i++)
X      SetEditColor(hdlg, dca01 + i - 1, kAspA[i]);
X    for (i = 0; i < cColor; i++) {
X      j = ikPalette[i];
X      SetEditColor(hdlg, dck00 + i, j <= 0 ? kMainA[-j] : kRainbowA[j]);
X    }
X    return fTrue;
X
X  case WM_COMMAND:
X    if (wParam == IDOK) {
X      for (k = 0; k <= 1; k++) {
X        for (i = 0; i < 4; i++) {
X          GetEdit(dce0 + i, sz);
X          l = NParseSz(sz, pmColor);
X          if (k)
X            kElemA[i] = l;
X          else
X            EnsureN(l, FValidColor(l), "element color");
X        }
X        for (i = 1; i <= cAspect; i++) {
X          GetEdit(dca01 + i - 1, sz);
X          l = NParseSz(sz, pmColor);
X          if (k)
X            kAspA[i] = l;
X          else
X            EnsureN(l, FValidColor(l), "aspect color");
X        }
X        for (i = 0; i < cColor; i++) {
X          GetEdit(dck00 + i, sz);
X          l = NParseSz(sz, pmColor);
X          if (k) {
X            j = ikPalette[i];
X            if (j <= 0)
X              kMainA[-j] = l;
X            else
X              kRainbowA[j] = l;
X          } else
X            EnsureN(l, FValidColor(l), "palette color");
X        }
X      }
X      wi.fRedraw = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the chart info entry dialog, as brought up by  */
/* both the Info Set Chart Info and Info Set Chart #2 Info menu commands. */
X
bool API DlgInfo(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  CI ci;
X  char sz[cchSzDef];
X
X  switch (message) {
X  case WM_INITDIALOG:
X    if (wi.nDlgChart < 2)
X      ci = ciMain;
X    else {
X      sprintf(sz, "Enter Chart #%d Info", wi.nDlgChart);
X      SetWindowText(hdlg, sz);
X      if (wi.nDlgChart == 2)
X        ci = ciTwin;
X      else if (wi.nDlgChart == 3)
X        ci = ciThre;
X      else
X        ci = ciFour;
X    }
LInit:
X    SetEditMDYT(hdlg, dcInMon, dcInDay, dcInYea, dcInTim,
X      ci.mon, ci.day, ci.yea, ci.tim);
X    SetEditSZOA(hdlg, dcInDst, dcInZon, dcInLon, dcInLat,
X      ci.dst, ci.zon, ci.lon, ci.lat);
X    SetEditSz(hdlg, deInNam, ciMain.nam);
X    SetEditSz(hdlg, deInLoc, ciMain.loc);
X    SetFocus(GetDlgItem(hdlg, dcInMon));
X    return fFalse;
X
X  case WM_COMMAND:
X    if (wParam == dbInNow || wParam == dbInSet) {
X      if (wParam == dbInNow) {
X        GetTimeNow(&ci.mon, &ci.day, &ci.yea, &ci.tim, us.zonDef-us.dstDef);
X        ci.dst = us.dstDef; ci.zon = us.zonDef;
X        ci.lon = us.lonDef; ci.lat = us.latDef;
X      } else
X        ci = ciSave;
X      goto LInit;
X    }
X
X    if (wParam == IDOK) {
X      GetEdit(dcInMon, sz); ci.mon = NParseSz(sz, pmMon);
X      GetEdit(dcInDay, sz); ci.day = NParseSz(sz, pmDay);
X      GetEdit(dcInYea, sz); ci.yea = NParseSz(sz, pmYea);
X      GetEdit(dcInTim, sz); ci.tim = RParseSz(sz, pmTim);
X      GetEdit(dcInDst, sz); ci.dst = RParseSz(sz, pmDst);
X      GetEdit(dcInZon, sz); ci.zon = RParseSz(sz, pmZon);
X      GetEdit(dcInLon, sz); ci.lon = RParseSz(sz, pmLon);
X      GetEdit(dcInLat, sz); ci.lat = RParseSz(sz, pmLat);
X      EnsureN(ci.mon, FValidMon(ci.mon), "month");
X      EnsureN(ci.yea, FValidYea(ci.yea), "year");
X      EnsureN(ci.day, FValidDay(ci.day, ci.mon, ci.yea), "day");
X      EnsureR(ci.tim, FValidTim(ci.tim), "time");
X      EnsureR(ci.dst, FValidZon(ci.dst), "daylight");
X      EnsureR(ci.zon, FValidZon(ci.zon), "zone");
X      EnsureR(ci.lon, FValidLon(ci.lon), "longitude");
X      EnsureR(ci.lat, FValidLat(ci.lat), "latitude");
X      GetEdit(deInNam, sz);
X      ci.nam = SzPersist(sz);
X      GetEdit(deInLoc, sz);
X      ci.loc = SzPersist(sz);
X      switch (wi.nDlgChart) {
X      case 1:  ciMain = ciCore = ci; break;
X      case 2:  ciTwin = ci; break;
X      case 3:  ciThre = ci; break;
X      default: ciFour = ci; break;
X      }
X      wi.fCast = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the default chart info dialog, as brought up */
/* with the Info Default Chart Info menu command.                       */
X
bool API DlgDefault(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  CI ci;
X  char sz[cchSzDef];
X
X  switch (message) {
X  case WM_INITDIALOG:
X    SetEditSZOA(hdlg, dcDeDst, dcDeZon, dcDeLon, dcDeLat,
X      us.dstDef, us.zonDef, us.lonDef, us.latDef);
X    SetEditN(dcDeCor, (int)us.lTimeAddition);
X    SetCombo(dcDeCor, "60"); SetCombo(dcDeCor, "-60");
X    SetFocus(GetDlgItem(hdlg, dcDeDst));
X    return fFalse;
X
X  case WM_COMMAND:
X    if (wParam == IDOK) {
X      GetEdit(dcDeDst, sz); ci.dst = RParseSz(sz, pmDst);
X      GetEdit(dcDeZon, sz); ci.zon = RParseSz(sz, pmZon);
X      GetEdit(dcDeLon, sz); ci.lon = RParseSz(sz, pmLon);
X      GetEdit(dcDeLat, sz); ci.lat = RParseSz(sz, pmLat);
X      GetEdit(dcDeCor, sz); us.lTimeAddition = atol(sz);
X      EnsureR(ci.dst, FValidZon(ci.dst), "daylight");
X      EnsureR(ci.zon, FValidZon(ci.zon), "zone");
X      EnsureR(ci.lon, FValidLon(ci.lon), "longitude");
X      EnsureR(ci.lat, FValidLat(ci.lat), "latitude");
X      us.dstDef = ci.dst; us.zonDef = ci.zon;
X      us.lonDef = ci.lon; us.latDef = ci.lat;
X      wi.fCast = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the charts #3 and #4 info entry dialog, as */
/* brought up by the Info Charts #3 and #4 menu commands.             */
X
bool API DlgInfoAll(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  DLGPROC dlgproc;
X  int i;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    i = us.nRel;
X    if (i > rcDual)
X      i = 0;
X    else if (i < rcQuadWheel)
X      i = rcDual;
X    SetRadio(dr01-i, dr01, dr04);
X    return fTrue;
X
X  case WM_COMMAND:
X    if (FBetween(wParam, dbIa_o1, dbIa_o4)) {
X      wi.nDlgChart = wParam - dbIa_o1 + 1;
X      DlgOpenChart();
X    } else if (FBetween(wParam, dbIa_i1, dbIa_i4)) {
X      wi.nDlgChart = wParam - dbIa_i1 + 1;
X      WiDoDialog(DlgInfo, dlgInfo);
X    }
X    if (wParam == IDOK) {
X      i = GetCheck(dr01) ? 1 : (GetCheck(dr02) ? 2 : (GetCheck(dr03) ? 3 : 4));
X      SetRel(-(i-1));
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the aspect settings dialog, as brought up with */
/* the Setting Aspect Settings menu command.                              */
X
bool API DlgAspect(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  int i, j;
X  real r;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    for (i = 1; i <= cAspect; i++) {
X      SetCheck(dxa01 - 1 + i, i > us.nAsp);
X      SetEditR(hdlg, deo01 - 1 + i, rAspOrb[i], 2);
X      SetEditR(hdlg, dea01 - 1 + i, rAspAngle[i], 6);
X      SetEditR(hdlg, dei01 - 1 + i, rAspInf[i], 2);
X    }
X    return fTrue;
X
X  case WM_COMMAND:
X    switch (wParam) {
X    case dbAs_RA0:
X      for (i = 1; i <= cAspect; i++)
X        SetCheck(dxa01 - 1 + i, fTrue);
X      break;
X    case dbAs_RA1:
X      for (i = 1; i <= cAspect; i++)
X        SetCheck(dxa01 - 1 + i, fFalse);
X      break;
X    case dbAs_RA:
X      for (i = 1; i <= 5; i++)
X        SetCheck(dxa01 - 1 + i, !GetCheck(dxa01 - 1 + i));
X      break;
X    }
X
X    if (wParam == IDOK) {
X      for (j = 0; j <= 1; j++) {
X        for (i = 1; i <= cAspect; i++) {
X          r = GetEditR(hdlg, deo01 - 1 + i);
X          if (j)
X            rAspOrb[i] = r;
X          else
X            EnsureR(r, r >= -rDegMax && r <= rDegMax, "orb");
X        }
X        for (i = 1; i <= cAspect; i++) {
X          r = GetEditR(hdlg, dea01 - 1 + i);
X          if (j)
X            rAspAngle[i] = r;
X          else
X            EnsureR(r, r >= -rDegMax && r <= rDegMax, "angle");
X        }
X        for (i = 1; i <= cAspect; i++) {
X          r = GetEditR(hdlg, dei01 - 1 + i);
X          if (j)
X            rAspInf[i] = r;
X        }
X      }
X      for (us.nAsp = cAspect; us.nAsp > 0 && GetCheck(dxa01 - 1 + us.nAsp);
X        us.nAsp--)
X        ;
X      for (i = 1; i <= us.nAsp; i++) {
X        if (GetCheck(dxa01 - 1 + i))
X          rAspOrb[i] = -rDegHalf;
X      }
X      wi.fRedraw = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the object settings dialog, as brought up with */
/* the Setting Object Settings menu command.                              */
X
bool API DlgObject(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  int i, j;
X  real r;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    for (i = 1; i <= oCore; i++) {
X      SetEditR(hdlg, deo01 - 1 + i, rObjOrb[i], 2);
X      SetEditR(hdlg, dea01 - 1 + i, rObjAdd[i], 1);
X      SetEditR(hdlg, dei01 - 1 + i, rObjInf[i], 2);
X    }
X    return fTrue;
X
X  case WM_COMMAND:
X    if (wParam == IDOK) {
X      for (j = 0; j <= 1; j++) {
X        for (i = 1; i <= oCore; i++) {
X          r = GetEditR(hdlg, deo01 - 1 + i);
X          if (j)
X            rObjOrb[i] = r;
X          else
X            EnsureR(r, r >= -rDegMax && r <= rDegMax, "max orb");
X        }
X        for (i = 1; i <= oCore; i++) {
X          r = GetEditR(hdlg, dea01 - 1 + i);
X          if (j)
X            rObjAdd[i] = r;
X          else
X            EnsureR(r, r >= -rDegMax && r <= rDegMax, "orb addition");
X        }
X        for (i = 1; i <= oCore; i++) {
X          r = GetEditR(hdlg, dei01 - 1 + i);
X          if (j)
X            rObjInf[i] = r;
X        }
X      }
X      wi.fRedraw = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the cuap and uranian object settings dialog, as */
/* brought up with the Setting More Object Settings menu command.          */
X
bool API DlgObject2(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  int i, j;
X  real r;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    for (i = oAsc; i <= uranHi; i++) {
X      SetEditR(hdlg, deo01 - oAsc + i, rObjOrb[i], 2);
X      SetEditR(hdlg, dea01 - oAsc + i, rObjAdd[i], 1);
X      SetEditR(hdlg, dei01 - oAsc + i, rObjInf[i], 2);
X    }
X    return fTrue;
X
X  case WM_COMMAND:
X    if (wParam == IDOK) {
X      for (j = 0; j <= 1; j++) {
X        for (i = oAsc; i <= uranHi; i++) {
X          r = GetEditR(hdlg, deo01 - oAsc + i);
X          if (j)
X            rObjOrb[i] = r;
X          else
X            EnsureR(r, r >= -rDegMax && r <= rDegMax, "max orb");
X        }
X        for (i = oAsc; i <= uranHi; i++) {
X          r = GetEditR(hdlg, dea01 - oAsc + i);
X          if (j)
X            rObjAdd[i] = r;
X          else
X            EnsureR(r, r >= -rDegMax && r <= rDegMax, "orb addition");
X        }
X        for (i = oAsc; i <= uranHi; i++) {
X          r = GetEditR(hdlg, dei01 - oAsc + i);
X          if (j)
X            rObjInf[i] = r;
X        }
X      }
X      wi.fRedraw = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the object restrictions dialog, as invoked with */
/* both the Setting Restrictions and Transit Restrictions menu commands.   */
X
bool API DlgRestrict(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  byte *lpb, *lpb2;
X  int i;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    if (wi.wCmd == cmdRes)
X      lpb = ignore;
X    else {
X      SetWindowText(hdlg, "Transit Object Restrictions");
X      lpb = ignore2;
X    }
X    for (i = 1; i <= oNorm; i++)
X      SetCheck(dx01 - 1 + i, lpb[i]);
X    return fTrue;
X
X  case WM_COMMAND:
X    switch (wParam) {
X    case dbRe_R0:
X      for (i = 1; i <= oNorm; i++)
X        SetCheck(dx01 - 1 + i, fTrue);
X      break;
X    case dbRe_R1:
X      for (i = 1; i <= oNorm; i++)
X        SetCheck(dx01 - 1 + i, fFalse);
X      break;
X    case dbRe_R:
X      for (i = oMain+1; i <= oCore; i++)
X        SetCheck(dx01 - 1 + i, !GetCheck(dx01 - 1 + i));
X      break;
X    case dbRe_RC:
X      for (i = cuspLo; i <= cuspHi; i++)
X        SetCheck(dx01 - 1 + i, !GetCheck(dx01 - 1 + i));
X      break;
X    case dbRe_Ru:
X      for (i = uranLo; i <= uranHi; i++)
X        SetCheck(dx01 - 1 + i, !GetCheck(dx01 - 1 + i));
X      break;
X    case dbRT:
X      lpb2 = wi.wCmd == cmdRes ? ignore2 : ignore;
X      for (i = 1; i <= oNorm; i++)
X        SetCheck(dx01 - 1 + i, lpb2[i]);
X      break;
X    }
X
X    if (wParam == IDOK) {
X      lpb = wi.wCmd == cmdRes ? ignore : ignore2;
X      for (i = 1; i <= oNorm; i++)
X        lpb[i] = GetCheck(dx01 - 1 + i);
X      if (!us.fCusp) {
X        for (i = cuspLo; i <= cuspHi; i++)
X          if (!ignore[i] || !ignore2[i]) {
X            us.fCusp = fTrue;
X            WiCheckMenu(cmdResCusp, fTrue);
X            break;
X          }
X      } else {
X        for (i = cuspLo; i <= cuspHi; i++)
X          if (!ignore[i] || !ignore2[i])
X            break;
X        if (i > cuspHi) {
X          us.fCusp = fFalse;
X          WiCheckMenu(cmdResCusp, fFalse);
X        }
X      }
X      if (!us.fUranian) {
X        for (i = uranLo; i <= uranHi; i++)
X          if (!ignore[i] || !ignore2[i]) {
X            us.fUranian = fTrue;
X            WiCheckMenu(cmdResUranian, fTrue);
X            break;
X          }
X      } else {
X        for (i = uranLo; i <= uranHi; i++)
X          if (!ignore[i] || !ignore2[i])
X            break;
X        if (i > uranHi) {
X          us.fUranian = fFalse;
X          WiCheckMenu(cmdResUranian, fFalse);
X        }
X      }
X      wi.fCast = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the star restrictions dialog, as brought up with */
/* the Setting Star Restrictions menu command.                              */
X
bool API DlgStar(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  int i;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    for (i = 1; i <= cStar; i++)
X      SetCheck(dx01 - 1 + i, ignore[oNorm + i]);
X    return fTrue;
X
X  case WM_COMMAND:
X    switch (wParam) {
X    case dbSt_RU0:
X      for (i = 1; i <= cStar; i++)
X        SetCheck(dx01 - 1 + i, fTrue);
X      break;
X    case dbSt_RU1:
X      for (i = 1; i <= cStar; i++)
X        SetCheck(dx01 - 1 + i, fFalse);
X      break;
X    }
X
X    if (wParam == IDOK) {
X      for (i = 1; i <= cStar; i++)
X        ignore[oNorm + i] = GetCheck(dx01 - 1 + i);
X      if (!us.nStar) {
X        for (i = starLo; i <= starHi; i++)
X          if (!ignore[i]) {
X            us.nStar = fTrue;
X            WiCheckMenu(cmdResStar, fTrue);
X            break;
X          }
X      } else {
X        for (i = starLo; i <= starHi; i++)
X          if (!ignore[i])
X            break;
X        if (i > starHi) {
X          us.nStar = fFalse;
X          WiCheckMenu(cmdResStar, fFalse);
X        }
X      }
X      wi.fCast = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the standard settings dialog, as brought up with */
/* the Setting Calculation Settings menu command.                           */
X
bool API DlgSetting(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  char sz[cchSzDef];
X  real r1;
X  int n2, n3, n4, n5, n6;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    SetCombo(dcSe_s, "0.0"); SetCombo(dcSe_s, "0.883333");
X    SetCombo(dcSe_s, "2.333333"); SetCombo(dcSe_s, "0.983333");
X    SetEditR(hdlg, dcSe_s, us.rZodiacOffset, 6);
X    SetEditN(deSe_A, us.nAsp);
X    SetEditN(deSe_x, us.nHarmonic);
X    SetEdit(deSe_h, szObjName[us.objCenter]);
X    SetRadio(us.objOnAsc == 0 ? dr01 : (us.objOnAsc > 0 ? dr02 : dr03),
X      dr01, dr03);
X    SetEdit(deSe_1, szObjName[us.objOnAsc == 0 ? oSun : abs(us.objOnAsc)]);
X    SetEditN(deSe_I, us.nScreenWidth);
X    SetCheck(dxSe_b, us.fPlacalc);
X    SetRadio(us.nDegForm == 0 ? dr04 : (us.nDegForm == 1 ? dr05 : dr06),
X      dr04, dr06);
X    SetCheck(dxSe_sr, us.fEquator);
X    return fTrue;
X
X  case WM_COMMAND:
X    if (wParam == IDOK) {
X      r1 = GetEditR(hdlg, dcSe_s);
X      GetEdit(deSe_A, sz); n2 = NParseSz(sz, pmAspect);
X      n3 = GetEditN(deSe_x);
X      GetEdit(deSe_h, sz); n4 = NParseSz(sz, pmObject);
X      GetEdit(deSe_1, sz); n5 = NParseSz(sz, pmObject);
X      n6 = GetEditN(deSe_I);
X      EnsureR(r1, FValidOffset(r1), "zodiac offset");
X      EnsureN(n2, FValidAspect(n2), "aspect count");
X      EnsureN(n3, FValidHarmonic(n3), "harmonic factor");
X      EnsureN(n4, FValidCenter(n4), "central planet");
X      EnsureN(n5, FItem(n5), "Solar chart planet");
X      EnsureN(n6, FValidScreen(n6), "text columns");
X      us.rZodiacOffset = r1;
X      us.nAsp = n2;
X      us.nHarmonic = n3;
X      us.objCenter = n4;
X      us.objOnAsc = GetCheck(dr01) ? 0 : (GetCheck(dr02) ? n5 : -n5);
X      us.nScreenWidth = n6;
X      us.fPlacalc = GetCheck(dxSe_b);
X      us.nDegForm = GetCheck(dr04) ? 0 : (GetCheck(dr05) ? 1 : 2);
X      us.fEquator = GetCheck(dxSe_sr);
X      WiCheckMenu(cmdHeliocentric, us.objCenter != oEar);
X      wi.fCast = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the obscure settings dialog, as brought up with */
/* the Setting Obscure Settings menu command.                              */
X
bool API DlgObscure(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  int i, n1;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    SetCheck(dxOb_Yn, us.fTrueNode);
X    SetCheck(dxOb_Yd, us.fEuroDate);
X    SetCheck(dxOb_Yt, us.fEuroTime);
X    SetCheck(dxOb_YC, us.fSmartCusp);
X    SetCheck(dxOb_Y8, us.fClip80);
X    SetCheck(dxOb_Yo, us.fWriteOld);
X    SetCheck(dxOb_Yc0, us.fHouseAngle);
X    SetCheck(dxOb_YR0_s, us.fIgnoreSign);
X    SetCheck(dxOb_YR0_d, us.fIgnoreDir);
X    SetEditN(deOb_YXg, gs.nGridCell);
X    SetCheck(dxOb_YXf, gs.fFont);
X    SetEditR(hdlg, deOb_YXp0_x, gs.xInch, 2);
X    SetEditR(hdlg, deOb_YXp0_y, gs.yInch, 2);
X    SetRadio(gs.nOrient == 0 ? dr11 : (gs.nOrient > 0 ? dr09 : dr10),
X      dr09, dr11);
X    SetRadio(dr01 + (gs.nGlyphs/1000 == 2), dr01, dr02);
X    SetRadio(dr03 + ((gs.nGlyphs/100)%10 == 2), dr03, dr04);
X    SetRadio(dr05 + ((gs.nGlyphs/10)%10 == 2), dr05, dr06);
X    SetRadio(dr07 + (gs.nGlyphs%10 == 2), dr07, dr08);
X    for (i = 0; i < 4; i++)
X      SetCheck(dx01 + i, ignorez[i]);
X    return fTrue;
X
X  case WM_COMMAND:
X    if (wParam == IDOK) {
X      n1 = GetEditN(deOb_YXg);
X      EnsureN(n1, FValidGrid(n1), "grid cell");
X      us.fTrueNode = GetCheck(dxOb_Yn);
X      us.fEuroDate = GetCheck(dxOb_Yd);
X      us.fEuroTime = GetCheck(dxOb_Yt);
X      us.fSmartCusp = GetCheck(dxOb_YC);
X      us.fClip80 = GetCheck(dxOb_Y8);
X      us.fWriteOld = GetCheck(dxOb_Yo);
X      us.fHouseAngle = GetCheck(dxOb_Yc0);
X      us.fIgnoreSign = GetCheck(dxOb_YR0_s);
X      us.fIgnoreDir = GetCheck(dxOb_YR0_d);
X      gs.nGridCell = n1;
X      gs.fFont = GetCheck(dxOb_YXf);
X      gs.xInch = GetEditR(hdlg, deOb_YXp0_x);
X      gs.yInch = GetEditR(hdlg, deOb_YXp0_y);
X      gs.nOrient = GetCheck(dr11) ? 0 : (GetCheck(dr09) ? 1 : -1);
X      gs.nGlyphs = (GetCheck(dr01) ? 1 : 2) * 1000 + (GetCheck(dr03) ? 1 : 2) *
X        100 + (GetCheck(dr05) ? 1 : 2) * 10 + (GetCheck(dr07) ? 1 : 2);
X      for (i = 0; i < 4; i++)
X        ignorez[i] = GetCheck(dx01 + i);
X      wi.fCast = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the transit chart dialog, as brought up with the */
/* Chart Transits menu command.                                             */
X
bool API DlgTransit(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  char sz[cchSzDef];
X  int mon, day, yea, n1, n2;
X  real tim;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    if (us.fInDay)           n1 = 1;
X    else if (us.fInDayInf)   n1 = 2;
X    else if (us.fTransit)    n1 = 3;
X    else if (us.fTransitInf) n1 = 4;
X    else                     n1 = 0;
X    SetRadio(dr01 + n1, dr01, dr05);
X    SetCheck(dxTr_p, is.fProgress);
X    SetCheck(dxTr_r, is.fReturn);
X    SetEditMDYT(hdlg, dcTrMon, dcTrDay, dcTrYea, dcTrTim,
X      MonT, DayT, YeaT, TimT);
X    if (n1 == 1) {
X      n2 = is.fProgress || us.fInDayMonth;
X      if (n2 == 1 && MonT == 0)
X        n2 += 1 + (us.nEphemYears > 1);
X    } else if (n1 == 3)
X      n2 = 1 + (MonT <= 0) + (MonT < 0);
X    else
X      n2 = 0;
X    SetRadio(dr06 + n2, dr06, dr09);
X    SetEditN(deTr_tY, us.nEphemYears);
X    SetEditN(deTr_d, us.nDivision);
X    SetFocus(GetDlgItem(hdlg, dcTrMon));
X    return fFalse;
X
X  case WM_COMMAND:
X    if (wParam == dbTr_tn) {
X      GetTimeNow(&mon, &day, &yea, &tim, us.zonDef-us.dstDef);
X      SetEditMDYT(hdlg, dcTrMon, dcTrDay, dcTrYea, dcTrTim,
X        mon, day, yea, tim);
X    }
X
X    if (wParam == IDOK) {
X      GetEdit(dcTrMon, sz); mon = NParseSz(sz, pmMon);
X      GetEdit(dcTrDay, sz); day = NParseSz(sz, pmDay);
X      GetEdit(dcTrYea, sz); yea = NParseSz(sz, pmYea);
X      GetEdit(dcTrTim, sz); tim = RParseSz(sz, pmTim);
X      n1 = GetEditN(deTr_tY);
X      n2 = GetEditN(deTr_d);
X      EnsureN(mon, FValidMon(mon), "month");
X      EnsureN(yea, FValidYea(yea), "year");
X      EnsureN(day, FValidDay(day, mon, yea), "day");
X      EnsureR(tim, FValidTim(tim), "time");
X      EnsureN(n2, FValidDivision(n2), "searching divisions");
X      SetCI(ciTran, mon, day, yea, tim,
X        us.dstDef, us.zonDef, us.lonDef, us.latDef);
X      us.nEphemYears = n1;
X      us.nDivision = n2;
X      is.fProgress = GetCheck(dxTr_p);
X      is.fReturn = GetCheck(dxTr_r);
X      n1 = GetCheck(dr01) ? 0 : (GetCheck(dr02) ? 1 : (GetCheck(dr03) ? 2 :
X        (GetCheck(dr04) ? 3 : 4)));
X      switch (n1) {
X      case 1: wi.nMode = gTraTraHit; break;
X      case 2: wi.nMode = gTraTraInf; break;
X      case 3: wi.nMode = gTraNatHit; break;
X      case 4: wi.nMode = gTraNatInf; break;
X      default: wi.nMode = gWheel;
X      }
X      n2 = GetCheck(dr06) ? 0 : (GetCheck(dr07) ? 1 :
X        (GetCheck(dr08) ? 2 : 3));
X      if (n1 == 1) {
X        us.fInDayMonth = (is.fProgress || n2 >= 1);
X        if (n2 >= 2) {
X          MonT = 0;
X          if (n2 == 2)
X            us.nEphemYears = 1;
X        }
X      } else if (n1 == 3) {
X        if (n2 == 2)
X          MonT = 0;
X        else if (n2 == 3) {
X          MonT = -1; DayT = us.nEphemYears;
X        }
X      } else if (n1 == 2) {
X        us.fProgress = is.fProgress;
X        wi.fCast = fTrue;
X      }
X      us.fGraphics = fFalse;
X      wi.fRedraw = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the progression settings dialog, as brought up */
/* with the Chart Progressions menu command.                              */
X
bool API DlgProgress(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  char sz[cchSzDef];
X  int mon, day, yea;
X  real tim, r1;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    SetCheck(dxPr_p, us.fProgress);
X    SetEditMDYT(hdlg, dcPrMon, dcPrDay, dcPrYea, dcPrTim,
X      MonT, DayT, YeaT, TimT);
X    SetRadio(dr01 + us.fSolarArc, dr01, dr02);
X    SetEditR(hdlg, dcPr_pd, us.rProgDay, 5);
X    SetCombo(dcPr_pd, "365.25");
X    SetCombo(dcPr_pd, "27.321661");
X    SetCombo(dcPr_pd, "29.530588");
X    SetFocus(GetDlgItem(hdlg, dcPrMon));
X    return fFalse;
X
X  case WM_COMMAND:
X    if (wParam == dbPr_pn) {
X      GetTimeNow(&mon, &day, &yea, &tim, us.zonDef-us.dstDef);
X      SetEditMDYT(hdlg, dcPrMon, dcPrDay, dcPrYea, dcPrTim,
X        mon, day, yea, tim);
X    }
X
X    if (wParam == IDOK) {
X      GetEdit(dcPrMon, sz); mon = NParseSz(sz, pmMon);
X      GetEdit(dcPrDay, sz); day = NParseSz(sz, pmDay);
X      GetEdit(dcPrYea, sz); yea = NParseSz(sz, pmYea);
X      GetEdit(dcPrTim, sz); tim = RParseSz(sz, pmTim);
X      r1 = GetEditR(hdlg, dcPr_pd);
X      EnsureN(mon, FValidMon(mon), "month");
X      EnsureN(yea, FValidYea(yea), "year");
X      EnsureN(day, FValidDay(day, mon, yea), "day");
X      EnsureR(tim, FValidTim(tim), "time");
X      EnsureR(r1, r1 != 0.0, "degree per day");
X      SetCI(ciTran, mon, day, yea, tim,
X        us.dstDef, us.zonDef, us.lonDef, us.latDef);
X      us.rProgDay = r1;
X      us.fProgress = GetCheck(dxPr_p);
X      us.fSolarArc = GetCheck(dr02);
X      is.JDp = MdytszToJulian(MonT, DayT, YeaT, TimT, us.dstDef, us.zonDef);
X      wi.fCast = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the chart subsettings dialog, as brought up with */
/* the Chart Chart Settings menu command.                                   */
X
bool API DlgChart(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  int n1, n2, n3;
X  bool f;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    SetCheck(dxCh_v0, us.fVelocity);
X    SetEditN(deCh_w, us.nWheelRows);
X    SetCheck(dxCh_w0, us.fWheelReverse);
X    SetCheck(dxCh_g0, us.fGridConfig);
X    SetCheck(dxCh_a0, us.fAspSummary);
X    SetCheck(dxCh_m0, us.fMidSummary);
X    SetCheck(dxCh_ma, us.fMidAspect);
X    SetCheck(dxCh_Z0, us.fPrimeVert);
X    SetCheck(dxCh_l, us.fSectorApprox);
X    SetCheck(dxCh_j0, us.fInfluenceSign);
X    SetEditN(deCh_L, us.nAstroGraphStep);
X    SetCheck(dxCh_L0, us.fLatitudeCross);
X    SetCheck(dxCh_Ky, us.fCalendarYear);
X    SetEditN(deCh_P, us.nArabicParts);
X    SetCheck(dxCh_P0, us.fArabicFlip);
X    switch (us.nStar) {
X    case 'z': n1 = dr02; break;
X    case 'l': n1 = dr03; break;
X    case 'n': n1 = dr04; break;
X    case 'b': n1 = dr05; break;
X    default:  n1 = dr01;
X    }
X    SetRadio(n1, dr01, dr05);
X    switch (us.nArabic) {
X    case 'z': n2 = dr07; break;
X    case 'n': n2 = dr08; break;
X    case 'f': n2 = dr09; break;
X    default:  n2 = dr06;
X    }
X    SetRadio(n2, dr06, dr09);
X    return fTrue;
X
X  case WM_COMMAND:
X    if (wParam == IDOK) {
X      n1 = GetEditN(deCh_w);
X      n2 = GetEditN(deCh_L);
X      n3 = GetEditN(deCh_P);
X      EnsureN(n1, FValidWheel(n1), "wheel row");
X      EnsureN(n2, FValidAstrograph(n2), "astro-graph step");
X      EnsureN(n3, FValidPart(n3), "Arabic part");
X      f = GetCheck(dxCh_v0);
X      if (us.fVelocity != f) {
X        us.fVelocity = f;
X        WiCheckMenu(cmdGraphicsSidebar, !f);
X      }
X      us.nWheelRows = n1;
X      us.fWheelReverse = GetCheck(dxCh_w0);
X      us.fGridConfig = GetCheck(dxCh_g0);
X      us.fAspSummary = GetCheck(dxCh_a0);
X      us.fMidSummary = GetCheck(dxCh_m0);
X      us.fMidAspect = GetCheck(dxCh_ma);
X      us.fPrimeVert = GetCheck(dxCh_Z0);
X      us.fSectorApprox = GetCheck(dxCh_l);
X      us.fInfluenceSign = GetCheck(dxCh_j0);
X      us.nAstroGraphStep = n2;
X      us.fLatitudeCross = GetCheck(dxCh_L0);
X      us.fCalendarYear = GetCheck(dxCh_Ky);
X      us.nArabicParts = n3;
X      us.fArabicFlip = GetCheck(dxCh_P0);
X      if (us.nStar)
X        us.nStar = GetCheck(dr02) ? 'z' : (GetCheck(dr03) ? 'l' :
X          (GetCheck(dr04) ? 'n' : (GetCheck(dr05) ? 'b' : fTrue)));
X      if (us.nArabic)
X        us.nArabic = GetCheck(dr07) ? 'z' : (GetCheck(dr08) ? 'n' :
X          (GetCheck(dr09) ? 'f' : fTrue));
X      wi.fCast = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the graphic settings dialog, as brought up with */
/* the Graphics Graphics Settings menu command.                            */
X
bool API DlgGraphics(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  char sz[cchSzDef];
X  int n1, n2, n3, n5, n6;
X  real r4;
X
X  switch (message) {
X  case WM_INITDIALOG:
X    SetEditN(deGr_Xw_x, gs.xWin);
X    SetEditN(deGr_Xw_y, gs.yWin);
X    SetEditN(deGr_XW, gs.nRot);
X    SetEditR(hdlg, deGr_XG, gs.rTilt, 2);
X    SetCheck(dxGr_XW0, gs.fMollewide);
X    SetEditN(deGr_WN, wi.nTimerDelay);
X    SetRadio(gs.objLeft > 0 ? dr02 :
X      (gs.objLeft < 0 ? dr03 : dr01), dr01, dr03);
X    SetEdit(deGr_X1, szObjName[gs.objLeft == 0 ? oSun : abs(gs.objLeft)]);
X    SetCheck(dxGr_Wn, wi.fNoUpdate);
X    return fTrue;
X
X  case WM_COMMAND:
X    if (wParam == IDOK) {
X      n1 = GetEditN(deGr_Xw_x);
X      n2 = GetEditN(deGr_Xw_y);
X      n3 = GetEditN(deGr_XW);
X      r4 = GetEditR(hdlg, deGr_XG);
X      n5 = GetEditN(deGr_WN);
X      GetEdit(deGr_X1, sz); n6 = NParseSz(sz, pmObject);
X      EnsureN(n1, FValidGraphx(n1), "horizontal size");
X      EnsureN(n2, FValidGraphy(n2), "vertical size");
X      EnsureN(n3, FValidRotation(n3), "horizontal rotation");
X      EnsureR(r4, FValidTilt(r4), "vertical tilt");
X      EnsureN(n5, FValidTimer(n5), "animation delay");
X      EnsureN(n5, FItem(n6), "rotation planet");
X      if (gs.xWin != n1 || gs.yWin != n2) {
X        gs.xWin = n1; gs.yWin = n2;
X        if (wi.fWindowChart)
X          ResizeWindowToChart();
X      }
X      gs.nRot = n3; gs.rTilt = r4;
X      if (wi.nTimerDelay != (UINT)n5) {
X        wi.nTimerDelay = n5;
X        if (wi.nTimer != 0)
X          KillTimer(wi.hwnd, 1);
X        wi.nTimer = SetTimer(wi.hwnd, 1, wi.nTimerDelay, NULL);
X      }
X      gs.objLeft = GetCheck(dr01) ? 0 : (GetCheck(dr02) ? n6 : -n6);
X      gs.fMollewide = GetCheck(dxGr_XW0);
X      wi.fNoUpdate = GetCheck(dxGr_Wn);
X      us.fGraphics = wi.fRedraw = fTrue;
X    }
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
X
X
/* Processing function for the about dialog, showing copyrights and  */
/* credits, as brought up with the Help About Astrolog menu command. */
X
bool API DlgAbout(hdlg, message, wParam, lParam)
HWND hdlg;
_int message;
WORD wParam;
LONG lParam;
{
X  switch (message) {
X  case WM_INITDIALOG:
X    return fTrue;
X
X  case WM_COMMAND:
X    if (wParam == IDOK || wParam == IDCANCEL) {
X      EndDialog(hdlg, fTrue);
X      return fTrue;
X    }
X    break;
X  }
X  return fFalse;
}
#endif /* WIN */
X
/* wdialog.c */
SHAR_EOF
  $shar_touch -am 1223232998 'wdialog.c' &&
  chmod 0644 'wdialog.c' ||
  echo 'restore of wdialog.c failed'
  shar_count="`wc -c < 'wdialog.c'`"
  test 55456 -eq "$shar_count" ||
    echo "wdialog.c: original size 55456, current size $shar_count"
fi
# ============= wdriver.c ==============
if test -f 'wdriver.c' && test X"$1" != X"-c"; then
  echo 'x - skipping wdriver.c (File already exists)'
else
  echo 'x - extracting wdriver.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'wdriver.c' &&
/*
** Astrolog (Version 5.40) File: wdriver.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
#ifdef WIN
/*
******************************************************************************
** Windows Command Processing.
******************************************************************************
*/
X
/* Process one command line switch passed to the program dealing with the   */
/* Windows features. This is just like the processing of each switch in the */
/* main program, however here each switch has been prefixed with an 'W'.    */
X
int NProcessSwitchesW(argc, argv, pos, fOr, fAnd, fNot)
int argc, pos;
bool fOr, fAnd, fNot;
char **argv;
{
X  int darg = 0, i;
X  char sz[cchSzDef], ch1;
X
X  ch1 = argv[0][pos+1];
X  switch (argv[0][pos]) {
X  case chNull:
X    if (argc <= 1) {
X      ErrorArgc("W");
X      return tcError;
X    }
X    i = atoi(argv[1]);
X    PostMessage(wi.hwnd, WM_COMMAND, i, 0L);
X    darg++;
X    break;
X
X  case 'N':
X    if (argc <= 1) {
X      ErrorArgc("WN");
X      return tcError;
X    }
X    i = atoi(argv[1]);
X    if (!FValidTimer(i)) {
X      ErrorValN("WN", i);
X      return tcError;
X    }
X    wi.nTimerDelay = i;
X    darg++;
X    break;
X
X  case 'M':
X    if (argc <= 2) {
X      ErrorArgc("WM");
X      return tcError;
X    }
X    i = atoi(argv[1]);
X    if (!FValidMacro(i)) {
X      ErrorValN("WM", i);
X      return tcError;
X    }
X    i--;
X    sprintf(sz, "%s\t%sF%d", argv[2], i < 12 ? "" : (i < 24 ? "Shift+" :
X      (i < 36 ? "Ctrl+" : "Alt+")), i % 12 + 1);
X    ModifyMenu(wi.hmenu, (WORD)(cmdMacro01 + i), MF_BYCOMMAND | MF_STRING,
X      (WORD)(cmdMacro01 + i), sz);
X    darg += 2;
X    break;
X
X  case 'n':
X    SwitchF(wi.fNoUpdate);
X    break;
X
X  default:
X    ErrorSwitch(argv[0]);
X    return tcError;
X  }
X  /* 'darg' contains the value to be added to argc when we return. */
X  return darg;
}
X
X
/* Change the pixel size of the window so its internal drawable area is the */
/* dimensions of the current graphics chart. Both the upper left and lower  */
/* right corners of the window may change depending on the scroll position. */
X
void ResizeWindowToChart()
{
X  RECT rcOld, rcNew;
X  int xScr, yScr;
X  HDC hdc;
X
X  if (!us.fGraphics || gs.xWin == 0 || gs.yWin == 0)
X    return;
X  GetWindowRect(wi.hwnd, &rcOld);
X  hdc = GetDC(wi.hwnd);
X  xScr = GetDeviceCaps(hdc, HORZRES);
X  yScr = GetDeviceCaps(hdc, VERTRES);
X  ReleaseDC(wi.hwnd, hdc);
X  rcNew.left = rcOld.left + gi.xOffset;
X  rcNew.top  = rcOld.top + gi.yOffset;
X  rcNew.right = rcNew.left + gs.xWin + (gi.nMode == 0 ? SIDESIZE : 0) + 24;
X  rcNew.bottom = rcNew.top + gs.yWin + 62;
X  if (rcNew.right > xScr)
X    OffsetRect(&rcNew, xScr - rcNew.right, 0);
X  if (rcNew.bottom > yScr)
X    OffsetRect(&rcNew, 0, yScr - rcNew.bottom);
X  if (rcNew.left < 0)
X    OffsetRect(&rcNew, -rcNew.left, 0);
X  if (rcNew.top < 0)
X    OffsetRect(&rcNew, 0, -rcNew.top);
X  MoveWindow(wi.hwnd, rcNew.left, rcNew.top,
X    rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, fTrue);
}
X
X
/* Given a relationship chart mode, return the menu command that sets it. */
X
WORD WCmdFromRc(int rc)
{
X  switch (rc) {
X  case rcTriWheel: case rcQuadWheel: /* Fall through */
X  case rcDual:       return cmdRelComparison;
X  case rcSynastry:   return cmdRelSynastry;
X  case rcComposite:  return cmdRelComposite;
X  case rcMidpoint:   return cmdRelMidpoint;
X  case rcDifference: return cmdRelDate;
X  case rcBiorhythm:  return cmdRelBiorhythm;
X  case rcTransit:    return cmdRelTransit;
X  case rcProgress:   return cmdRelProgressed;
X  default:           return cmdRelNo;
X  }
}
X
X
/* Change relationship chart modes. Given a new mode, we put a check by its */
/* menu command, and erase the check by the menu command for the old mode.  */
X
void SetRel(int rc)
{
X  CheckMenu(WCmdFromRc(us.nRel), fFalse);
X  CheckMenu(WCmdFromRc(rc), fTrue);
X  us.nRel = rc;
X  wi.fCast = fTrue;
}
X
X
/* The main program, the starting point of Astrolog for Windows, follows.   */
/* This is like the "main" function in standard C. The program initializes  */
/* here, then spins in a tight message processing loop until it terminates. */
X
int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpszCmdLine;
int nCmdShow;
{
X  MSG msg;
X  WNDCLASS wndclass;
#ifdef BETA
X  char sz[cchSzMax];
#endif
X
X  /* Set up the window class shared by all instances of Astrolog. */
X
X  wi.hinst = hInstance;
X  if (!hPrevInstance) {
X    ClearB((lpbyte)&wndclass, sizeof(WNDCLASS));
X    wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
X    wndclass.lpfnWndProc = WndProc;
X    wndclass.cbClsExtra = 0;
X    wndclass.cbWndExtra = 0;
X    wndclass.hInstance = wi.hinst;
X    wndclass.hIcon = LoadIcon(wi.hinst, MAKEINTRESOURCE(icon));
X    wndclass.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
X    wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
X    wndclass.lpszMenuName = MAKEINTRESOURCE(menu);
X    wndclass.lpszClassName = szAppName;
X    if (!RegisterClass(&wndclass)) {
X      PrintError("The window class could not be registered.");
X      return -1L;
X    }
X  }
X
X  /* Create the actual window to be used and drawn on by this instance. */
X
X  wi.hmenu = LoadMenu(wi.hinst, MAKEINTRESOURCE(menu));
X  wi.hwndMain = CreateWindow(
X    szAppName,
X    "Astrolog 5.40",
X    WS_CAPTION |
X    WS_SYSMENU |
X    WS_MINIMIZEBOX |
X    WS_MAXIMIZEBOX |
X    WS_THICKFRAME |
X    WS_VSCROLL |
X    WS_HSCROLL |
X    WS_CLIPCHILDREN |
X    WS_OVERLAPPED,
X    CW_USEDEFAULT, 0,
X    CW_USEDEFAULT, 0,
X    (HWND)NULL,
X    wi.hmenu,
X    wi.hinst,
X    (LPSTR)NULL);
X  if (wi.hwndMain == (HWND)NULL) {
X    PrintError("The window could not be created.");
X    return -1L;
X  }
X
X  /* Set up some globals that can't be initialized at compile time. */
X
X  is.S = stdout;
X  ofn.hwndOwner = wi.hwndMain;
X  ofn.lpstrFile = szFileName;
X  ofn.lpstrFileTitle = szFileTitle;
X  prd.hwndOwner = wi.hwndMain;
X  wi.haccel = LoadAccelerators(wi.hinst, MAKEINTRESOURCE(accelerator));
X  wi.kiPen = gi.kiLite;
X
X  /* Process the astrolog.dat file and the Windows command line. */
X
X  FProcessSwitchFile(DEFAULT_INFOFILE, NULL);
X  FProcessCommandLine(lpszCmdLine);
X  ciTran = ciFour = ciThre = ciTwin = ciCore;
X
X  /* Actually bring up and display the window for the first time. */
X
X  ResizeWindowToChart();
X  ShowWindow(wi.hwndMain, nCmdShow);
X  RedoMenu();
X  wi.nTimer = SetTimer(wi.hwnd, 1, wi.nTimerDelay, NULL);
#ifdef BETA
X  sprintf(sz, "This is a beta version of %s %s! "
X    "That means changes are still being made and testing is not complete. "
X    "If this is being run after %s %d, %d, "
X    "it should be replaced with the finished release.",
X    szAppName, szVersionCore, szMonth[ciSave.mon], ciSave.day, ciSave.yea);
X  PrintWarning(sz);
#endif
X
X  /* Process window messages until the program is told to terminate. */
X
X  while (GetMessage(&msg, (HWND)NULL, 0, 0)) {
X    if (!TranslateAccelerator(wi.hwndMain, wi.haccel, &msg))
X      TranslateMessage(&msg);
X    DispatchMessage(&msg);
X  }
X
X  /* Cleanup and exit Astrolog for Windows. */
X
X  UnregisterClass(szAppName, wi.hinst);
X  return msg.wParam;
}
X
X
/* This is the main message processor for the Astrolog window. Given a */
/* user input or other message, do the appropriate action and updates. */
X
LONG API WndProc(hwnd, wMsg, wParam, lParam)
HWND hwnd;
WORD wMsg;
WORD wParam;
LONG lParam;
{
X  HDC hdc;
X  HPEN hpen, hpenOld;
X  HBRUSH hbr;
X  RECT rc;
X  int x, y;
X
X  wi.hwnd = hwnd;
X  switch (wMsg) {
X
X    /* A command, most likely a menu option, was given. */
X
X    case WM_COMMAND:
X      switch (NWmCommand(wParam)) {
X      case 1:
X        goto LWM_CLOSE;
X      case -1:
X        return DefWindowProc(hwnd, wMsg, wParam, lParam);
X      default:
X        ProcessState();
X      }
X      break;
X
X    /* When a part of a window is uncovered, Windows quickly blanks it out, */
X    /* usually with white, before having the app redraw that section. Most  */
X    /* apps don't do anything here, however Astrolog can quickly draw with  */
X    /* a more appropriate color since we know our chart's background color. */
X
X    case WM_ERASEBKGND:
X      if (!(wi.fNoUpdate & 1)) {
X        GetClipBox((HDC)wParam, &rc);
X        hbr = CreateSolidBrush(rgbbmp[gs.fInverse ? kWhite : kBlack]);
X        FillRect((HDC)wParam, &rc, hbr);
X        DeleteObject(hbr);
X      }
X      return fTrue;
X
X    /* The window was just created. Setup the scrollbars. */
X
X    case WM_CREATE:
X      SetScrollRange(hwnd, SB_HORZ, 0, nScrollDiv, fFalse);
X      SetScrollRange(hwnd, SB_VERT, 0, nScrollDiv, fFalse);
X      break;
X
X    /* The window has been resized. Change the chart size if need be. */
X
X    case WM_SIZE:
X      wi.xClient = LOWORD(lParam);
X      wi.yClient = HIWORD(lParam);
X      if (wi.fWindowChart || wi.fChartWindow) {
X        gs.xWin = wi.xClient; gs.yWin = wi.yClient;
X      }
X      break;
X
X    /* All or part of the window needs to be redrawn. Go do so. */
X
X    case WM_PAINT:
X      if (!(wi.fNoUpdate & 1))
X        FRedraw();
X      break;
X
X    /* The mouse has been left clicked or dragged over the window. */
X
X    case WM_LBUTTONDOWN:
X    case WM_MOUSEMOVE:
X
X      /* Treat dragging with the mouse down as a Shift+left click. */
X      if (wMsg == WM_MOUSEMOVE) {
X        if ((wParam & MK_LBUTTON) == 0 ||
X          (wParam & MK_SHIFT) || (wParam & MK_CONTROL))
X          break;
X        wParam = MK_SHIFT;
X      }
X      x = WLo(lParam);
X      y = WHi(lParam);
X
X      /* Alt+click on a world map chart means relocate the chart there. */
X      if (wMsg == WM_LBUTTONDOWN && GetKeyState(VK_MENU) < 0) {
X        if (fMap && gs.nRot == 0 && !gs.fConstel && !gs.fMollewide) {
X          Lon = DegToDec(rDegHalf-(real)(x-gi.xOffset)/(real)gs.xWin*rDegMax);
X          if (Lon < -rDegHalf)
X            Lon = -rDegHalf;
X          else if (Lon > rDegHalf)
X            Lon = rDegHalf;
X          Lat = DegToDec(rDegQuad-(real)(y-gi.yOffset)/(real)gs.yWin*180.0);
X          if (Lat < -rDegQuad)
X            Lat = -rDegQuad;
X          else if (Lat > rDegQuad)
X            Lat = rDegQuad;
X          wi.xMouse = -1;
X          wi.fCast = fTrue;
X        }
X        break;
X      }
X      hdc = GetDC(hwnd);
X      hpen = CreatePen(PS_SOLID, 0, (COLORREF)rgbbmp[wi.kiPen]);
X      hpenOld = SelectObject(hdc, hpen);
X
X      /* Ctrl+click means draw a rectangle. Ctrl+Shift+click does ellipse. */
X      if (wParam & MK_CONTROL) {
X        SelectObject(hdc, GetStockObject(NULL_BRUSH));
X        if (wParam & MK_SHIFT)
X          Ellipse(hdc, wi.xMouse, wi.yMouse, x, y);
X        else
X          Rectangle(hdc, wi.xMouse, wi.yMouse, x, y);
X
X      /* Shift+click means draw a line from the last to current position. */
X      } else if (wParam & MK_SHIFT) {
X        if (wi.xMouse >= 0) {
X          MoveTo(hdc, wi.xMouse, wi.yMouse);
X          LineTo(hdc, x, y);
X          if (wMsg == WM_MOUSEMOVE) {
X            wi.xMouse = x; wi.yMouse = y;
X          }
X        }
X
X      /* A simple click means set a pixel and remember that location. */
X      } else {
X        SetPixel(hdc, x, y, (COLORREF)rgbbmp[wi.kiPen]);
X        wi.xMouse = x; wi.yMouse = y;
X      }
X      SelectObject(hdc, hpenOld);
X      DeleteObject(hpen);
X      ReleaseDC(hwnd, hdc);
X      break;
X
X    /* The mouse has been right clicked on the window. If on a world map  */
X    /* or astro-graph chart, relocate the chart to the mouse coordinates. */
X
X    case WM_RBUTTONDOWN:
X      x = WLo(lParam);
X      y = WHi(lParam);
X      if (us.fGraphics && (us.fAstroGraph || gi.nMode == gWorldMap) &&
X        gs.nRot == 0 && !gs.fConstel && !gs.fMollewide) {
X        Lon = DegToDec(rDegHalf-(real)(x-gi.xOffset)/
X          (real)gs.xWin*rDegMax);
X        if (Lon < -rDegHalf)
X          Lon = -rDegHalf;
X        else if (Lon > rDegHalf)
X          Lon = rDegHalf;
X        Lat = DegToDec(rDegQuad-(real)(y-gi.yOffset)/
X          (real)gs.yWin*181.0);
X        if (Lat < -rDegQuad)
X          Lat = -rDegQuad;
X        else if (Lat > rDegQuad)
X          Lat = rDegQuad;
X        ciCore = ciMain;
X        wi.fCast = fTrue;
X        ProcessState();
X      }
X      break;
X
X    /* A timer message is received at a defined regular interval. */
X
X    case WM_TIMER:
X      if (!gs.nAnim || wi.fPause)
X        break;
X      Animate(gs.nAnim, wi.nDir);  /* Update chart if animation mode on. */
X      wi.fRedraw = fTrue;
X      ProcessState();
X      break;
X
X    /* Define the minimum and maximum size the window may be resized to. */
X
X    case WM_GETMINMAXINFO:
X      ((MINMAXINFO FAR *)lParam)->ptMinTrackSize.x = BITMAPX1;
X      ((MINMAXINFO FAR *)lParam)->ptMinTrackSize.y = BITMAPY1;
X      ((MINMAXINFO FAR *)lParam)->ptMaxTrackSize.x = BITMAPX;
X      ((MINMAXINFO FAR *)lParam)->ptMaxTrackSize.x = BITMAPY;
X      break;
X
X    /* The horizontal scrollbar was clicked on or used in some way. */
X
X    case WM_HSCROLL:
X      x = wi.xScroll;
X      switch (wParam) {
X      case SB_LINEUP:
X        wi.xScroll--;
X        break;
X      case SB_LINEDOWN:
X        wi.xScroll++;
X        break;
X      case SB_PAGEUP:
X        wi.xScroll -= nScrollPage;
X        break;
X      case SB_PAGEDOWN:
X        wi.xScroll += nScrollPage;
X        break;
X      case SB_THUMBPOSITION:
X        wi.xScroll = LOWORD(lParam);
X        break;
X      default:
X        return fFalse;
X      }
X      wi.xScroll = max(0, min(wi.xScroll, nScrollDiv));
X      if (wi.xScroll == x)
X        break;
X      SetScrollPos(hwnd, SB_HORZ, wi.xScroll, fTrue);
X      wi.fRedraw = fTrue;
X      ProcessState();
X      break;
X
X    /* The vertical scrollbar was clicked on or used in some way. */
X
X    case WM_VSCROLL:
X      y = wi.yScroll;
X      switch(wParam) {
X      case SB_LINEUP:
X        wi.yScroll--;
X        break;
X      case SB_LINEDOWN:
X        wi.yScroll++;
X        break;
X      case SB_PAGEUP:
X        wi.yScroll -= nScrollPage;
X        break;
X      case SB_PAGEDOWN:
X        wi.yScroll += nScrollPage;
X        break;
X      case SB_THUMBPOSITION:
X        wi.yScroll = LOWORD(lParam);
X        break;
X      default:
X        return fFalse;
X      }
X      wi.yScroll = max(0, min(wi.yScroll, nScrollDiv));
X      if (wi.yScroll == y)
X        break;
X      SetScrollPos(hwnd, SB_VERT, wi.yScroll, fTrue);
X      wi.fRedraw = fTrue;
X      ProcessState();
X      break;
X
X    /* The window is being terminated. Clean up and free program data. */
X
X    case WM_CLOSE:
LWM_CLOSE:
X      if (us.fNoQuit) {
X        PrintWarning("Program exiting is not allowed now.");
X        break;
X      }
X      if (wi.hpen != (HPEN)NULL)
X        DeleteObject(wi.hpen);
X      if (wi.nTimer != 0)
X        KillTimer(hwnd, 1);
X      DestroyWindow(hwnd);
X      if (hwnd == wi.hwndMain)
X        PostQuitMessage(0);
X      break;
X
X    /* Messages not processed here are handled by Windows in a default way. */
X
X    default:
X      return DefWindowProc(hwnd, wMsg, wParam, lParam);
X    }
X  return fFalse;
}
X
X
/* This is called after some action has been done that probably changed the */
/* chart state, such as a menu command was run. Update anything needing it. */
X
void ProcessState()
{
X  if (wi.fMenuAll) {       /* Redetermine all menu checks if need be. */
X    RedoMenu();
X    wi.fMenu = fTrue;
X  }
X  if (wi.fMenu) {          /* Update menu if we added/removed check marks. */
X    DrawMenuBar(wi.hwnd);
X    wi.fMenu = fFalse;
X  }
X  if (wi.fCast)            /* Recasting a chart implies redrawing it too. */
X    wi.fRedraw = fTrue;
X
X  /* If the chart type was changed, clear all the setting flags, then set */
X  /* the appropriate core switch settings based on the new chart type.    */
X
X  if (wi.nMode) {
X    ClearB((lpbyte)&us.fListing,
X      (int)((lpbyte)&us.fVelocity - (lpbyte)&us.fListing));
X    ClearB((lpbyte)&us.fCredit,
X      (int)((lpbyte)&us.fLoop - (lpbyte)&us.fCredit));
X    us.nArabic = gi.nMode = 0;
X    switch (wi.nMode) {
X      case gBiorhythm:
X      case gWheel:      us.fListing    = fTrue; break;
X      case gHouse:      us.fWheel      = fTrue; break;
X      case gGrid:       us.fGrid       = fTrue; break;
X      case gHorizon: us.fHorizon = fTrue; us.fHorizonSearch = fFalse; break;
X      case gOrbit:      us.fOrbit      = fTrue; break;
X      case gSector:     us.fSector     = fTrue; break;
X      case gAstroGraph: us.fAstroGraph = fTrue; break;
X      case gEphemeris:  us.fEphemeris  = fTrue; break;
X      case gWorldMap:   gi.nMode = gWorldMap; break;
X      case gGlobe:      gi.nMode = gGlobe;    break;
X      case gPolar:      gi.nMode = gPolar;    break;
X      case gCalendar:   us.fCalendar   = fTrue; break;
X      case gDisposit:   us.fInfluence  = fTrue; break;
X      case gAspect:     us.fAspList    = fTrue; break;
X      case gMidpoint:   us.fMidpoint   = fTrue; break;
X      case gArabic:     us.nArabic     = 1; break;
X      case gSign:       us.fSign       = fTrue; break;
X      case gObject:     us.fObject     = fTrue; break;
X      case gHelpAsp:    us.fAspect     = fTrue; break;
X      case gConstel:    us.fConstel    = fTrue; break;
X      case gPlanet:     us.fOrbitData  = fTrue; break;
X      case gMeaning:    us.fMeaning    = fTrue; break;
X      case gSwitch:     us.fSwitch     = fTrue; break;
X      case gObscure:    us.fSwitchRare = fTrue; break;
X      case gKeystroke:  us.fKeyGraph   = fTrue; break;
X      case gCredit:     us.fCredit     = fTrue; break;
X      case gRising:     us.fHorizon = us.fHorizonSearch = fTrue; break;
X      case gTraTraHit:  us.fInDay      = fTrue; break;
X      case gTraTraInf:  us.fInDayInf   = fTrue; break;
X      case gTraNatHit:  us.fTransit    = fTrue; break;
X      case gTraNatInf:  us.fTransitInf = fTrue; break;
X    }
X    wi.nMode = 0;
X    wi.fRedraw = fTrue;
X  }
X  if (wi.fRedraw)    /* Send the window a redraw message if need be. */
X    RedrawWindow(wi.hwnd, NULL, (HRGN)NULL, RDW_INVALIDATE);
}
X
X
/* Given a command, process it, changing any appropriate program settings. */
/* Return values are 0, meaning it was one of Astrolog's menu commands and */
/* action was taken; 1, meaning it's the special end program command; or   */
/* -1, meaning it's not a custom command and Windows can deal with it.     */
X
int NWmCommand(wCmd)
WORD wCmd;
{
X  char sz[cchSzDef];
X  DLGPROC dlgproc;
X  int i;
X  long l;
X  bool fGraphics, fT;
X
X  wi.wCmd = wCmd;
X  fGraphics = us.fGraphics;
X  switch (wCmd) {
X
X  /* File Menu */
X
X  case cmdFileExit:
X    return 1;
X
X  case cmdOpenChart:
X    wi.nDlgChart = 1;
X    DlgOpenChart();
X    break;
X
X  case cmdOpenChart2:
X    wi.nDlgChart = 2;
X    DlgOpenChart();
X    break;
X
X  case cmdSaveChart:
X  case cmdSavePositions:
X  case cmdSaveText:
X  case cmdSaveBitmap:
#ifdef META
X  case cmdSavePicture:
#endif
#ifdef PS
X  case cmdSavePS:
#endif
X  case cmdSaveSettings:
X  case cmdSaveWallTile:
X  case cmdSaveWallCenter:
X    DlgSaveChart();
X    break;
X
X  case cmdPrint:
X    if (!DlgPrint())
X      PrintWarning("The printing was not completed successfully.");
X    break;
X
X  case cmdPrintSetup:
X    l = prd.Flags;
X    prd.Flags |= PD_PRINTSETUP;
X    PrintDlg((LPPRINTDLG)&prd);
X    prd.Flags = l;
X    break;
X
X  /* Edit Menu */
X
X  case cmdCommand:
X    WiDoDialog(DlgCommand, dlgCommand);
X    break;
X
X  case cmdColor:
X    WiDoDialog(DlgColor, dlgColor);
X    break;
X
X  case cmdCopyText:
X    is.szFileScreen = szFileTemp;
X    us.fGraphics = fFalse;
X    wi.fRedraw = fTrue;
X    break;
X
X  case cmdCopyBitmap:
#ifdef META
X  case cmdCopyPicture:
#endif
#ifdef PS
X  case cmdCopyPS:
#endif
X    if (us.fNoWrite)
X      break;
X    gi.szFileOut = szFileTemp;
X    gs.fBitmap = wi.wCmd == cmdCopyBitmap;
X    gs.fMeta = wi.wCmd == cmdCopyPicture;
X    gs.fPS = wi.wCmd == cmdCopyPS;
X    if (wCmd == cmdCopyBitmap)
X      gs.chBmpMode = 'B';
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  /* View Menu */
X
X  case cmdGraphics:
X    not(us.fGraphics);
X    wi.fRedraw = fTrue;
X    break;
X
X  case cmdColoredText:
X    not(us.fAnsiColor); not(us.fAnsiChar);
X    WiCheckMenu(cmdColoredText, us.fAnsiColor);
X    us.fGraphics = fFalse;
X    wi.fRedraw = fTrue;
X    break;
X
X  case cmdWinBuffer:
X    not(wi.fBuffer);
X    WiCheckMenu(cmdWinBuffer, wi.fBuffer);
X    break;
X
X  case cmdWinRedraw:
X    if (wi.fNoUpdate)
X      wi.fNoUpdate = 2;
X    wi.fMenuAll = wi.fRedraw = fTrue;
X    break;
X
X  case cmdWinClear:
X    fT = gs.fJetTrail;
X    gs.fJetTrail = fFalse;
X    wi.hdc = GetDC(wi.hwnd);
X    if (us.fGraphics)
X      DrawClearScreen();
X    else
X      TextClearScreen();
X    ReleaseDC(wi.hwnd, wi.hdc);
X    gs.fJetTrail = fT;
X    break;
X
X  case cmdWinHourglass:
X    not(wi.fHourglass);
X    WiCheckMenu(cmdWinHourglass, wi.fHourglass);
X    break;
X
X  case cmdChartResizesWindow:
X    not(wi.fChartWindow);
X    WiCheckMenu(cmdChartResizesWindow, wi.fChartWindow);
X    wi.fRedraw = fTrue;
X    break;
X
X  case cmdWindowResizesChart:
X    not(wi.fWindowChart);
X    WiCheckMenu(cmdWindowResizesChart, wi.fWindowChart);
X    wi.fRedraw = fTrue;
X    break;
X
X  case cmdSizeChartToWindow:
X    gs.xWin = wi.xClient;
X    gs.yWin = wi.yClient;
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  case cmdSizeWindowToChart:
X    ResizeWindowToChart();
X    break;
X
X  case cmdScrollPageUp:
X    PostMessage(wi.hwnd, WM_VSCROLL, SB_PAGEUP, 0);
X    break;
X
X  case cmdScrollPageDown:
X    PostMessage(wi.hwnd, WM_VSCROLL, SB_PAGEDOWN, 0);
X    break;
X
X  case cmdScrollHome:
X    PostMessage(wi.hwnd, WM_HSCROLL, SB_THUMBPOSITION, 0);
X    PostMessage(wi.hwnd, WM_VSCROLL, SB_THUMBPOSITION, 0);
X    break;
X
X  case cmdScrollEnd:
X    PostMessage(wi.hwnd, WM_HSCROLL, SB_THUMBPOSITION, nScrollDiv);
X    PostMessage(wi.hwnd, WM_VSCROLL, SB_THUMBPOSITION, nScrollDiv);
X    break;
X
#ifdef INTERPRET
X  case cmdInterpret:
X    not(us.fInterpret);
X    WiCheckMenu(cmdInterpret, us.fInterpret);
X    us.fGraphics = fFalse;
X    wi.fRedraw = fTrue;
X    break;
#endif
X
X  case cmdSecond:
X    not(us.fSeconds);
X    is.fSeconds = us.fSeconds;
X    WiCheckMenu(cmdSecond, us.fSeconds);
X    wi.fRedraw = fTrue;
X    break;
X
X  case cmdApplying:
X    not(us.fAppSep);
X    WiCheckMenu(cmdApplying, us.fAppSep);
X    wi.fRedraw = fTrue;
X    break;
X
X  case cmdParallel:
X    not(us.fParallel);
X    WiCheckMenu(cmdParallel, us.fParallel);
X    wi.fRedraw = fTrue;
X    break;
X
X  /* Info Menu */
X
X  case cmdSetInfo:
X    wi.nDlgChart = 1;
X    WiDoDialog(DlgInfo, dlgInfo);
X    break;
X
#ifdef TIME
X  case cmdNow:
X    FInputData(szNowCore);
X    wi.fCast = fTrue;
X    break;
#endif
X
X  case cmdDefaultInfo:
X    WiDoDialog(DlgDefault, dlgDefault);
X    break;
X
X  case cmdSetInfo2:
X    wi.nDlgChart = 2;
X    WiDoDialog(DlgInfo, dlgInfo);
X    break;
X
X  case cmdSetInfoAll:
X    WiDoDialog(DlgInfoAll, dlgInfoAll);
X    break;
X
X  case cmdRelNo:
X  case cmdRelComparison:
X    SetRel(us.nRel ? 0 : rcDual);
X    break;
X
X  case cmdRelSynastry:
X    SetRel(rcSynastry);
X    break;
X
X  case cmdRelComposite:
X    SetRel(rcComposite);
X    break;
X
X  case cmdRelMidpoint:
X    SetRel(rcMidpoint);
X    break;
X
X  case cmdRelDate:
X    SetRel(rcDifference);
X    gi.nMode = gWheel;
X    us.fGraphics = fFalse;
X    break;
X
#ifdef BIORHYTHM
X  case cmdRelBiorhythm:
X    SetRel(rcBiorhythm);
X    gi.nMode = gBiorhythm;
X    break;
#endif
X
X  case cmdRelTransit:
X    SetRel(rcTransit);
X    break;
X
X  case cmdRelProgressed:
X    SetRel(rcProgress);
X    break;
X
X  /* Settings Menu */
X
X  case cmdSidereal:
X    not(us.fSidereal);
X    WiCheckMenu(cmdSidereal, us.fSidereal);
X    wi.fCast = fTrue;
X    break;
X
X  case cmdHeliocentric:
X    not(us.objCenter);
X    WiCheckMenu(cmdHeliocentric, us.objCenter != oEar);
X    wi.fCast = fTrue;
X    break;
X
X  case cmdHouse00:
X  case cmdHouse01:
X  case cmdHouse02:
X  case cmdHouse03:
X  case cmdHouse04:
X  case cmdHouse05:
X  case cmdHouse06:
X  case cmdHouse07:
X  case cmdHouse08:
X  case cmdHouse09:
X  case cmdHouse10:
X  case cmdHouse11:
X  case cmdHouse12:
X  case cmdHouse13:
X  case cmdHouse14:
X    WiCheckMenu(cmdHouse00 + us.nHouseSystem, fFalse);
X    us.nHouseSystem = (int)(wCmd - cmdHouse00);
X    WiCheckMenu(wCmd, fTrue);
X    wi.fCast = fTrue;
X    break;
X
X  case cmdHouseSetSolar:
X    not(us.objOnAsc);
X    WiCheckMenu(cmdHouseSetSolar, us.objOnAsc);
X    wi.fCast = fTrue;
X    break;
X
X  case cmdHouseSetDecan:
X    not(us.fDecan);
X    WiCheckMenu(cmdHouseSetDecan, us.fDecan);
X    wi.fCast = fTrue;
X    break;
X
X  case cmdHouseSetFlip:
X    not(us.fFlip);
X    WiCheckMenu(cmdHouseSetFlip, us.fFlip);
X    wi.fCast = fTrue;
X    break;
X
X  case cmdHouseSetGeodetic:
X    not(us.fGeodetic);
X    WiCheckMenu(cmdHouseSetGeodetic, us.fGeodetic);
X    wi.fCast = fTrue;
X    break;
X
X  case cmdHouseSetVedic:
X    not(us.fVedic);
X    WiCheckMenu(cmdHouseSetVedic, us.fVedic);
X    wi.fRedraw = fTrue;
X    break;
X
X  case cmdHouseSetNavamsa:
X    not(us.fNavamsa);
X    WiCheckMenu(cmdHouseSetNavamsa, us.fNavamsa);
X    wi.fCast = fTrue;
X    break;
X
X  case cmdAspect:
X    WiDoDialog(DlgAspect, dlgAspect);
X    break;
X
X  case cmdObject:
X    WiDoDialog(DlgObject, dlgObject);
X    break;
X
X  case cmdObject2:
X    WiDoDialog(DlgObject2, dlgObject2);
X    break;
X
X  case cmdRes:
X  case cmdResTransit:
X    WiDoDialog(DlgRestrict, dlgRestrict);
X    break;
X
X  case cmdResMinor:
X    for (i = oChi; i <= oVes; i++)
X      not(ignore[i]);
X    for (i = oLil; i <= oEP; i++)
X      not(ignore[i]);
X    WiCheckMenu(cmdResMinor, !ignore[oChi]);
X    wi.fCast = fTrue;
X    break;
X
X  case cmdResCusp:
X    not(us.fCusp);
X    for (i = cuspLo; i <= cuspHi; i++)
X      ignore[i] = !us.fCusp || !ignore[i];
X    WiCheckMenu(cmdResCusp, us.fCusp);
X    wi.fCast = fTrue;
X    break;
X
X  case cmdResUranian:
X    not(us.fUranian);
X    for (i = uranLo; i <= uranHi; i++)
X      ignore[i] = !us.fUranian || !ignore[i];
X    WiCheckMenu(cmdResUranian, us.fUranian);
X    wi.fCast = fTrue;
X    break;
X
X  case cmdResStar:
X    us.nStar = !us.nStar;
X    for (i = starLo; i <= starHi; i++)
X      ignore[i] = !us.nStar || !ignore[i];
X    WiCheckMenu(cmdResStar, us.nStar);
X    wi.fCast = fTrue;
X    break;
X
X  case cmdStar:
X    WiDoDialog(DlgStar, dlgStar);
X    break;
X
X  case cmdSettingMore:
X    WiDoDialog(DlgSetting, dlgSetting);
X    break;
X
X  case cmdObscure:
X    WiDoDialog(DlgObscure, dlgObscure);
X    break;
X
X  /* Chart Menu */
X
X  case cmdChartList:
X    wi.nMode = gWheel;
X    break;
X
X  case cmdChartWheel:
X    wi.nMode = gHouse;
X    break;
X
X  case cmdChartGrid:
X    wi.nMode = gGrid;
X    break;
X
X  case cmdChartAspect:
X    wi.nMode = gAspect;
X    us.fGraphics = fFalse;
X    break;
X
X  case cmdChartMidpoint:
X    wi.nMode = gMidpoint;
X    us.fGraphics = fFalse;
X    break;
X
X  case cmdChartHorizon:
X    wi.nMode = gHorizon;
X    break;
X
X  case cmdChartOrbit:
X    wi.nMode = gOrbit;
X    break;
X
X  case cmdChartSector:
X    wi.nMode = gSector;
X    break;
X
X  case cmdChartCalendar:
X    wi.nMode = gCalendar;
X    break;
X
X  case cmdChartInfluence:
X    wi.nMode = gDisposit;
X    break;
X
X  case cmdChartAstroGraph:
X    wi.nMode = gAstroGraph;
X    break;
X
X  case cmdChartEphemeris:
X    wi.nMode = gEphemeris;
X    break;
X
#ifdef ARABIC
X  case cmdChartArabic:
X    wi.nMode = gArabic;
X    us.fGraphics = fFalse;
X    break;
#endif
X
X  case cmdChartRising:
X    wi.nMode = gRising;
X    us.fGraphics = fFalse;
X    break;
X
X  case cmdProgress:
X    WiDoDialog(DlgProgress, dlgProgress);
X    break;
X
X  case cmdTransit:
X    WiDoDialog(DlgTransit, dlgTransit);
X    break;
X
X  case cmdChartSettings:
X    WiDoDialog(DlgChart, dlgChart);
X    break;
X
X  /* Graphics Menu */
X
X  case cmdChartMap:
X    wi.nMode = gWorldMap;
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  case cmdChartGlobe:
X    wi.nMode = gGlobe;
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  case cmdChartPolar:
X    wi.nMode = gPolar;
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
#ifdef CONSTEL
X  case cmdConstellation:
X    if (!fMap && gi.nMode != gGlobe && gi.nMode != gPolar)
X      wi.nMode = gWorldMap;
X    not(gs.fConstel);
X    WiCheckMenu(cmdConstellation, gs.fConstel);
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
#endif
X
X  case cmdGraphicsReverse:
X    not(gs.fInverse);
X    WiCheckMenu(cmdGraphicsReverse, gs.fInverse);
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  case cmdGraphicsMonochrome:
X    not(gs.fColor);
X    WiCheckMenu(cmdGraphicsMonochrome, !gs.fColor);
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  case cmdGraphicsBorder:
X    not(gs.fBorder);
X    WiCheckMenu(cmdGraphicsBorder, gs.fBorder);
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  case cmdGraphicsText:
X    not(gs.fText);
X    WiCheckMenu(cmdGraphicsText, gs.fText);
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  case cmdGraphicsSidebar:
X    not(us.fVelocity);
X    if (!us.fVelocity) {
X      gs.fText = fTrue;
X      WiCheckMenu(cmdGraphicsText, fTrue);
X    }
X    WiCheckMenu(cmdGraphicsSidebar, !us.fVelocity);
X    wi.nMode = gWheel;
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  case cmdGraphicsLabel:
X    not(gs.fLabel);
X    WiCheckMenu(cmdGraphicsLabel, gs.fLabel);
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  case cmdGraphicsSquare:
X    SquareX(&gs.xWin, &gs.yWin, fTrue);
X    ResizeWindowToChart();
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  case cmdScale1:
X  case cmdScale2:
X  case cmdScale3:
X  case cmdScale4:
X    WiCheckMenu(cmdScale1 + gs.nScale/100 - 1, fFalse);
X    gs.nScale = (int)(wCmd - cmdScale1) + 1;
X    gs.nScale *= 100;
X    WiCheckMenu(wCmd, fTrue);
X    wi.fRedraw = fTrue;
X    break;
X
X  case cmdScaleDecrease:
X    if (gs.nScale > 100) {
X      WiCheckMenu(cmdScale1 + gs.nScale/100 - 1, fFalse);
X      gs.nScale -= 100;
LScale:
X      WiCheckMenu(cmdScale1 + gs.nScale/100 - 1, fTrue);
X      wi.fRedraw = fTrue;
X    }
X    break;
X
X  case cmdScaleIncrease:
X    if (gs.nScale < MAXSCALE) {
X      WiCheckMenu(cmdScale1 + gs.nScale/100 - 1, fFalse);
X      gs.nScale += 100;
X      goto LScale;
X    }
X    break;
X
X  case cmdTiltZero:
X    if (gi.nMode != gGlobe)
X      wi.nMode = gGlobe;
X    if (gs.rTilt != 0.0) {
X      gs.rTilt = 0.0;
X      wi.fRedraw = fTrue;
X    }
X    us.fGraphics = fTrue;
X    break;
X
X  case cmdTiltDecrease:
X    if (gi.nMode != gGlobe)
X      wi.nMode = gGlobe;
X    if (gs.rTilt > -rDegQuad) {
X      gs.rTilt = gs.rTilt > -rDegQuad ? gs.rTilt-TILTSTEP : -rDegQuad;
X      wi.fRedraw = fTrue;
X    }
X    us.fGraphics = fTrue;
X    break;
X
X  case cmdTiltIncrease:
X    if (gi.nMode != gGlobe)
X      wi.nMode = gGlobe;
X    if (gs.rTilt < rDegQuad) {
X      gs.rTilt = gs.rTilt < rDegQuad ? gs.rTilt+TILTSTEP : rDegQuad;
X      wi.fRedraw = fTrue;
X    }
X    us.fGraphics = fTrue;
X    break;
X
X  case cmdGraphicsModify:
X    not(gs.fAlt);
X    WiCheckMenu(cmdGraphicsModify, gs.fAlt);
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  case cmdChartModify:
X    not(us.fPrimeVert);
X    not(us.fCalendarYear);
X    not(us.nEphemYears);
X    not(gs.fMollewide);
X    gi.nMode = (gi.nMode == gWheel ? gHouse :
X      (gi.nMode == gHouse ? gWheel : gi.nMode));
X    us.fGraphics = wi.fRedraw = fTrue;
X    break;
X
X  case cmdPen00:
X  case cmdPen01:
X  case cmdPen02:
X  case cmdPen03:
X  case cmdPen04:
X  case cmdPen05:
X  case cmdPen06:
X  case cmdPen07:
X  case cmdPen08:
X  case cmdPen09:
X  case cmdPen10:
X  case cmdPen11:
X  case cmdPen12:
X  case cmdPen13:
X  case cmdPen14:
X  case cmdPen15:
X    WiCheckMenu(cmdPen00 + wi.kiPen, fFalse);
X    wi.kiPen = (int)(wCmd - cmdPen00);
X    WiCheckMenu(wCmd, fTrue);
X    break;
X
X  case cmdSettingGraphics:
X    WiDoDialog(DlgGraphics, dlgGraphics);
X    break;
X
X  /* Animate Menu */
X
X  case cmdAnimateNo:
X  case cmdAnimateNow:
X    WiCheckMenu(cmdAnimateNo + gs.nAnim, fFalse);
X    if (gs.nAnim)
X      gs.nAnim = 0;
X    else {
X      gs.nAnim = 10;
X      WiCheckMenu(cmdWinBuffer, fTrue);
X      wi.fBuffer = fTrue;
X    }
X    WiCheckMenu(cmdAnimateNo + gs.nAnim, fTrue);
X    wi.fRedraw = fTrue;
X    break;
X
X  case cmdAnimateS1:
X  case cmdAnimateS2:
X  case cmdAnimateS3:
X  case cmdAnimateS4:
X  case cmdAnimateS5:
X  case cmdAnimateS6:
X  case cmdAnimateS7:
X  case cmdAnimateS8:
X  case cmdAnimateS9:
X    WiCheckMenu(cmdAnimateNo + gs.nAnim, fFalse);
X    gs.nAnim = (int)(wCmd - cmdAnimateS1) + 1;
X    WiCheckMenu(wCmd, fTrue);
X    WiCheckMenu(cmdWinBuffer, fTrue);
X    wi.fBuffer = wi.fRedraw = fTrue;
X    break;
X
X  case cmdAnimateF1:
X  case cmdAnimateF2:
X  case cmdAnimateF3:
X  case cmdAnimateF4:
X  case cmdAnimateF5:
X  case cmdAnimateF6:
X  case cmdAnimateF7:
X  case cmdAnimateF8:
X  case cmdAnimateF9:
X    WiCheckMenu(cmdAnimateF1 + abs(wi.nDir) - 1, fFalse);
X    wi.nDir = (wi.nDir > 0 ? 1 : -1)*(int)(wCmd - cmdAnimateF1) + 1;
X    WiCheckMenu(wCmd, fTrue);
X    break;
X
X  case cmdAnimateReverse:
X    neg(wi.nDir);
X    WiCheckMenu(cmdAnimateReverse, wi.nDir < 0);
X    if (gs.nAnim == 0) {
X      gs.nAnim = 10;
X      WiCheckMenu(cmdWinBuffer, fTrue);
X      WiCheckMenu(cmdAnimateNo, fFalse);
X      WiCheckMenu(cmdAnimateNow, fTrue);
X      wi.fBuffer = fTrue;
X    }
X    wi.fRedraw = fTrue;
X    break;
X
X  case cmdAnimatePause:
X    not(wi.fPause);
X    WiCheckMenu(cmdAnimatePause, wi.fPause);
X    break;
X
X  case cmdTimedExposure:
X    not(gs.fJetTrail);
X    WiCheckMenu(cmdTimedExposure, gs.fJetTrail);
X    break;
X
X  case cmdStepForward:
X    Animate(gs.nAnim, abs(wi.nDir));
X    wi.fCast = fTrue;
X    break;
X
X  case cmdStepBackward:
X    Animate(gs.nAnim, -abs(wi.nDir));
X    wi.fCast = fTrue;
X    break;
X
X  case cmdStore:
X    ciSave = ciMain;
X    break;
X
X  case cmdRecall:
X    ciMain = ciSave;
X    wi.fCast = fTrue;
X    break;
X
X  /* Help Menu */
X
X  case cmdDocDefault:
X    WinExec("NOTEPAD ASTROLOG.DAT", SW_SHOW);
X    break;
X
X  case cmdDocSummary:
X    WinExec("NOTEPAD FILE_ID.DIZ", SW_SHOW);
X    break;
X
X  case cmdDocReadme:
X    WinExec("NOTEPAD README.540", SW_SHOW);
X    break;
X
X  case cmdDocUpdate:
X    WinExec("NOTEPAD UPDATE.540", SW_SHOW);
X    break;
X
X  case cmdDocHelpfile:
X    WinExec("WRITE HELPFILE.540", SW_SHOW);
X    break;
X
X  case cmdDocHomepage:
X    WinExec("START ASTROLOG.URL", SW_SHOW);
X    break;
X
X  case cmdHelpSign:
X    wi.nMode = gSign;
X    us.fGraphics = fFalse;
X    break;
X
X  case cmdHelpObject:
X    wi.nMode = gObject;
X    us.fGraphics = fFalse;
X    break;
X
X  case cmdHelpAspect:
X    wi.nMode = gHelpAsp;
X    us.fGraphics = fFalse;
X    break;
X
#ifdef CONSTEL
X  case cmdHelpConstellation:
X    wi.nMode = gConstel;
X    us.fGraphics = fFalse;
X    break;
#endif
X
X  case cmdHelpPlanetInfo:
X    wi.nMode = gPlanet;
X    us.fGraphics = fFalse;
X    break;
X
#ifdef INTERPRET
X  case cmdHelpMeaning:
X    wi.nMode = gMeaning;
X    us.fGraphics = fFalse;
X    break;
#endif
X
X  case cmdHelpSwitch:
X    wi.nMode = gSwitch;
X    us.fGraphics = fFalse;
X    break;
X
X  case cmdHelpObscure:
X    wi.nMode = gObscure;
X    us.fGraphics = fFalse;
X    break;
X
X  case cmdHelpKeystroke:
X    wi.nMode = gKeystroke;
X    us.fGraphics = fFalse;
X    break;
X
X  case cmdHelpCredit:
X    wi.nMode = gCredit;
X    us.fGraphics = fFalse;
X    break;
X
X  case cmdHelpAbout:
X    WiDoDialog(DlgAbout, dlgAbout);
X    break;
X
X  default:
X    if (FBetween(wCmd, cmdMacro01, cmdMacro48)) {
X      i = (int)(wCmd - cmdMacro01);
X      if (szMacro[i]) {
X        FProcessCommandLine(szMacro[i]);
X        wi.fCast = wi.fMenuAll = fTrue;
X      } else {
X        sprintf(sz, "Macro number %d is not defined.", i+1);
X        PrintWarning(sz);
X      }
X      break;
X    }
X    return -1;
X  }
X
X  if (us.fNoGraphics)
X    us.fGraphics = fFalse;
X  if (us.fGraphics != fGraphics)
X    WiCheckMenu(cmdGraphics, us.fGraphics);
X  return 0;
}
X
X
/* For each menu command that can have a check mark by it, determine its   */
/* state and set or clear appropriately. This is called when the program   */
/* is first started, and after commands that may change many settings that */
/* can't be kept track of, such as running macro commands or script files. */
X
void API RedoMenu()
{
X  WORD cmd;
X
X  CheckMenu(cmdGraphics, us.fGraphics);
X  CheckMenu(cmdColoredText, us.fAnsiColor);
X  CheckMenu(cmdWinBuffer, wi.fBuffer);
X  CheckMenu(cmdWinHourglass, wi.fHourglass);
X  CheckMenu(cmdChartResizesWindow, wi.fChartWindow);
X  CheckMenu(cmdWindowResizesChart, wi.fWindowChart);
#ifdef INTERPRET
X  CheckMenu(cmdInterpret, us.fInterpret);
#endif
X  CheckMenu(cmdSecond, us.fSeconds);
X  CheckMenu(cmdApplying, us.fAppSep);
X  CheckMenu(cmdParallel, us.fParallel);
X  for (cmd = cmdRelNo; cmd <= cmdRelProgressed; cmd++)
X    CheckMenu(cmd, fFalse);
X  CheckMenu(WCmdFromRc(us.nRel), fTrue);
X  CheckMenu(cmdSidereal, us.fSidereal);
X  CheckMenu(cmdHeliocentric, us.objCenter != oEar);
X  for (cmd = cmdHouse00; cmd <= cmdHouse13; cmd++)
X    CheckMenu(cmd, fFalse);
X  CheckMenu(cmdHouse00 + us.nHouseSystem, fTrue);
X  CheckMenu(cmdHouseSetSolar, us.objOnAsc);
X  CheckMenu(cmdHouseSetDecan, us.fDecan);
X  CheckMenu(cmdHouseSetFlip, us.fFlip);
X  CheckMenu(cmdHouseSetGeodetic, us.fGeodetic);
X  CheckMenu(cmdHouseSetVedic, us.fVedic);
X  CheckMenu(cmdHouseSetNavamsa, us.fNavamsa);
X  CheckMenu(cmdResMinor, !ignore[oChi]);
X  CheckMenu(cmdResCusp, us.fCusp);
X  CheckMenu(cmdResUranian, us.fUranian);
X  CheckMenu(cmdResStar, us.nStar);
#ifdef CONSTEL
X  CheckMenu(cmdConstellation, gs.fConstel);
#endif
X  CheckMenu(cmdGraphicsReverse, gs.fInverse);
X  CheckMenu(cmdGraphicsMonochrome, !gs.fColor);
X  CheckMenu(cmdGraphicsBorder, gs.fBorder);
X  CheckMenu(cmdGraphicsText, gs.fText);
X  CheckMenu(cmdGraphicsSidebar, !us.fVelocity);
X  CheckMenu(cmdGraphicsLabel, gs.fLabel);
X  for (cmd = cmdScale1; cmd <= cmdScale4; cmd++)
X    CheckMenu(cmd, fFalse);
X  CheckMenu(cmdScale1 + gs.nScale/100 - 1, fTrue);
X  CheckMenu(cmdGraphicsModify, gs.fAlt);
X  for (cmd = cmdPen00; cmd <= cmdPen15; cmd++)
X    CheckMenu(cmd, fFalse);
X  CheckMenu(cmdPen00 + wi.kiPen, fTrue);
X  CheckMenu(cmdAnimateNow, fFalse);
X  for (cmd = cmdAnimateNo; cmd <= cmdAnimateS9; cmd++)
X    CheckMenu(cmd, fFalse);
X  CheckMenu(cmdAnimateNo + gs.nAnim, fTrue);
X  for (cmd = cmdAnimateF1; cmd <= cmdAnimateF9; cmd++)
X    CheckMenu(cmd, fFalse);
X  CheckMenu(cmdAnimateF1 + abs(wi.nDir) - 1, fTrue);
X  CheckMenu(cmdAnimateReverse, wi.nDir < 0);
X  CheckMenu(cmdAnimatePause, wi.fPause);
X  CheckMenu(cmdTimedExposure, gs.fJetTrail);
X  wi.fMenuAll = fFalse;
}
X
X
/* This important routine is the bottleneck to redraw the window and call */
/* into the program to draw or do action with a particular chart type.    */
X
bool API FRedraw(void)
{
X  /* Local variables used in drawing on the screen. */
X  PAINTSTRUCT ps;
X  HDC hdcWin;
X  HCURSOR hcurOld;
X  HBITMAP hbmp, hbmpOld;
X  HFONT hfontOld;
X  int nScrollRow, i;
X
X  /* Local variables used for copying to the Windows clipboard. */
X  HFILE hfile;
X  LONG lSize, l;
X  HGLOBAL hglobal, hmfp;
X  byte HPTR *hpb;
X  METAFILEPICT mfp;
X
X  if (wi.fHourglass)
X    hcurOld = SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
X  ClearB((lpbyte)&ps, sizeof(PAINTSTRUCT));
X  if (wi.hdcPrint != hdcNil)
X    wi.hdc = wi.hdcPrint;
X  else {
X    hdcWin = BeginPaint(wi.hwnd, &ps);
X    if (wi.fBuffer) {
X      wi.hdc = CreateCompatibleDC(hdcWin);
X      hbmp = CreateCompatibleBitmap(hdcWin, wi.xClient, wi.yClient);
X      hbmpOld = SelectObject(wi.hdc, hbmp);
X      if (gs.fJetTrail)
X        BitBlt(wi.hdc, 0, 0, wi.xClient, wi.yClient, hdcWin, 0, 0, SRCCOPY);
X    } else
X      wi.hdc = hdcWin;
X  }
X
X  if (us.fGraphics) {
X    /* Set up a graphics chart. */
X    if (wi.fWindowChart && wi.hdcPrint == hdcNil) {
X      gs.xWin = wi.xClient; gs.yWin = wi.yClient;
X    }
X    gi.nScale = gs.nScale/100;
X    gi.kiCur = -1;
X  } else {
X    /* Set up a text chart. */
X    SetWindowOrg(wi.hdc, 0, 0);
X    SetWindowExt(wi.hdc, wi.xClient, wi.yClient);
X    SetBkMode(wi.hdc, TRANSPARENT);
X    if (wi.hdcPrint == hdcNil)
X      TextClearScreen();
X    i = gs.nScale/100;
X    wi.xChar = i < 2 ? 6 : (i < 3 ? 8 : (i < 4 ? 10 : 12));
X    wi.yChar = i < 2 ? 8 : (i < 3 ? 12 : (i < 4 ? 18 : 16));
X    wi.hfont = CreateFont(wi.yChar /*nHeight*/, wi.xChar /*nWidth*/,
X      0 /*nEscapement*/, 0 /*nOrientation*/, FW_DONTCARE,
X      0 /*fbItalic*/, 0 /*fbUnderline*/, 0 /*fbStrikeOut*/,
X      DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_DEFAULT_PRECIS,
X      DRAFT_QUALITY, FIXED_PITCH | FF_DONTCARE, "Terminal");
X    hfontOld = SelectObject(wi.hdc, wi.hfont);
X    /* If printing, set the number of text rows per page. */
X    if (wi.hdcPrint != hdcNil) {
X      nScrollRow = us.nScrollRow;
X      us.nScrollRow = wi.yClient / wi.yChar;
X    }
X  }
X
X  Action();    /* Actually go and create the chart here. */
X
X  /* Cleanup and copy from the buffer to the screen if need be. */
X
X  if (!us.fGraphics) {
X    if (wi.hdcPrint != hdcNil)
X      us.nScrollRow = nScrollRow;
X    SelectObject(wi.hdc, hfontOld);
X    DeleteObject(wi.hfont);
X  }
X  if (wi.hdcPrint == hdcNil) {
X    if (wi.fBuffer) {
X      BitBlt(hdcWin, 0, 0, wi.xClient, wi.yClient, wi.hdc, 0, 0, SRCCOPY);
X      SelectObject(wi.hdc, hbmpOld);
X      DeleteObject(hbmp);
X      DeleteDC(wi.hdc);
X    }
X    EndPaint(wi.hwnd, &ps);
X  }
X  if (wi.fHourglass)
X    SetCursor(hcurOld);
X
X  /* If all text was scrolled off the top of the screen, scroll up. */
X
X  if (!us.fGraphics && is.S == stdout && is.cchRow - wi.yScroll * 10 < 0)
X    PostMessage(wi.hwnd, WM_VSCROLL, SB_THUMBPOSITION, is.cchRow / 10 - 2);
X
X  /* Sometimes creating a chart means saving it to a file instead of     */
X  /* drawing it on screen. If we were in file mode, cleanup things here. */
X
X  if (is.szFileScreen != NULL || gs.fBitmap || gs.fMeta || gs.fPS) {
X    is.szFileScreen = NULL;
X    if (gs.fMeta) {
X      gs.xWin /= METAMUL; gs.yWin /= METAMUL; gs.nScale /= METAMUL;
X    } else if (gs.fPS) {
X      gs.xWin /= PSMUL; gs.yWin /= PSMUL; gs.nScale /= PSMUL;
X    }
X    gs.fBitmap = gs.fMeta = gs.fPS = fFalse;
X
X    /* To copy charts to the clipboard, Astrolog saves the chart to a temp */
X    /* file, then copies the contents of that file to the clipboard.       */
X
X    if (wi.wCmd == cmdCopyText || wi.wCmd == cmdCopyBitmap ||
X      wi.wCmd == cmdCopyPicture || wi.wCmd == cmdCopyPS) {
X      hfile = _lopen(szFileTemp, READ);
X      if (hfile == HFILE_ERROR)
X        return fFalse;
X      lSize = _llseek(hfile, 0, 2);
X      /* For bitmap and metafile charts, skip over the file header bytes. */
X      l = wi.wCmd == cmdCopyBitmap ? sizeof(BITMAPFILEHEADER) :
X        (wi.wCmd == cmdCopyPicture ? 22 : 0);
X      hglobal = GlobalAlloc(GMEM_MOVEABLE, lSize - l);
X      if (hglobal == (HGLOBAL)NULL)
X        return fFalse;
X      hpb = GlobalLock(hglobal);
X      _llseek(hfile, l, 0);
X      _hread(hfile, hpb, lSize - l);
X      _lclose(hfile);
X      GlobalUnlock(hglobal);
X      if (!OpenClipboard(wi.hwnd))
X        return fFalse;
X      EmptyClipboard();
X      if (wi.wCmd == cmdCopyText || wi.wCmd == cmdCopyPS)
X        SetClipboardData(CF_TEXT, hglobal);
X      else if (wi.wCmd == cmdCopyBitmap)
X        SetClipboardData(CF_DIB, hglobal);
X      else {
X        mfp.mm = MM_ANISOTROPIC;  /* For metafiles a special structure  */
X        mfp.xExt = -gs.xWin;      /* with a pointer to the picture data */
X        mfp.yExt = -gs.yWin;      /* needs to be allocated and used.    */
X        mfp.hMF = hglobal;
X        hmfp = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT));
X        if (hmfp == (HGLOBAL)NULL)
X          return fFalse;
X        hpb = GlobalLock(hmfp);
X        *(METAFILEPICT FAR *)hpb = mfp;
X        GlobalUnlock(hmfp);
X        SetClipboardData(CF_METAFILEPICT, hmfp);
X      }
X      CloseClipboard();
X      _unlink(szFileTemp);
X      wi.wCmd = 0;
X    }
X    ProcessState();
X  }
X
X  wi.fRedraw = fFalse;
X  if (wi.fNoUpdate)
X    wi.fNoUpdate = fTrue;
X  return fTrue;
}
#endif /* WIN */
X
/* wdriver.c */
SHAR_EOF
  $shar_touch -am 1223232998 'wdriver.c' &&
  chmod 0644 'wdriver.c' ||
  echo 'restore of wdriver.c failed'
  shar_count="`wc -c < 'wdriver.c'`"
  test 44609 -eq "$shar_count" ||
    echo "wdriver.c: original size 44609, current size $shar_count"
fi
# ============= xcharts0.c ==============
if test -f 'xcharts0.c' && test X"$1" != X"-c"; then
  echo 'x - skipping xcharts0.c (File already exists)'
else
  echo 'x - extracting xcharts0.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'xcharts0.c' &&
/*
** Astrolog (Version 5.40) File: xcharts0.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
#ifdef GRAPH
/*
******************************************************************************
** Subchart Graphics Routines.
******************************************************************************
*/
X
/* Given a string, draw it on the screen using the given color. The       */
/* position of the text is based the saved positions of where we drew the */
/* text the last time the routine was called, being either directly below */
/* in the same column or in the same row just to the right. This is used  */
/* by the sidebar drawing routine to print a list of text on the chart.   */
X
int DrawPrint(sz, m, n)
char *sz;
int m, n;
{
X  static int x0, x, y;
X
X  if (sz == NULL) {    /* Null string means just initialize position. */
X    x0 = x = m; y = n;
X    return y;
X  }
X  if (y >= gs.yWin-1)  /* Don't draw if we've scrolled off the chart bottom. */
X    return y;
X  DrawColor(m);
X  DrawSz(sz, x, y, dtLeft | dtBottom);
X
X  /* If the second parameter is TRUE, we stay on the same line, otherwise */
X  /* when FALSE we go to the next line at the original column setting.    */
X
X  if (n)
X    x += CchSz(sz)*xFont*gi.nScaleT;
X  else {
X    x = x0;
X    n = y;
X    y += yFont*gi.nScaleT;
X  }
X  return y;
}
X
X
/* Print text showing the chart information and house and planet positions */
/* of a chart in a "sidebar" to the right of the chart in question. This   */
/* is always done for the -v and -w graphic wheel charts unless the -v0    */
/* switch flag is also set, in which case none of the stuff here is done.  */
X
void DrawInfo()
{
X  char sz[cchSzDef];
X  ET et;
X  CI ciT;
X  int i, y, a, s;
X  real r;
X
#ifdef INTERPRET
X  int tot, abo, lef;
X
X  /* Hack: Just for fun, if interpretation is active (which normally has  */
X  /* no effect whatsoever on graphics) we'll decorate the chart a little. */
X
X  if (us.fInterpret) {
X    if (us.nScreenWidth & 1) {
X
X      /* If screenwidth value is odd, draw a moire pattern in each corner. */
X
X      abo = gs.yWin/(us.nScreenWidth/10);
X      lef = gs.xWin/(us.nScreenWidth/10);
X      for (y = 0; y <= 1; y++)
X        for (i = 0; i <= 1; i++)
X          for (s = 0; s <= 1; s++)
X            for (a = 1; a < (s ? lef : abo)*2; a++) {
X              DrawColor(a & 1 ? gi.kiGray : gi.kiOff);
X              DrawLine(i ? gs.xWin-1-lef : lef, y ? gs.yWin-1-abo : abo,
X                s ? (i ? gs.xWin-1-a : a) : i*(gs.xWin-1),
X                s ? y*(gs.yWin-1) : (y ? gs.yWin-1-a : a));
X            }
X    } else {
X
X      /* If screenwidth is even, draw spider web lines in each corner. */
X
X      DrawColor(gi.kiGray);
X      tot = us.nScreenWidth*3/20;
X      abo = gs.yWin/4;
X      lef = gs.xWin/4;
X      for (y = 0; y <= 1; y++)
X        for (i = 0; i <= 1; i++)
X          for (a = 1; a < tot; a++)
X            DrawLine(i*(gs.xWin-1), y ? (gs.yWin-1-a*abo/tot) : a*abo/tot,
X              i ? gs.xWin-1-lef+a*lef/tot : lef-a*lef/tot, y*(gs.yWin-1));
X    }
X  }
#endif
X  if (!gs.fText || us.fVelocity)    /* Don't draw sidebar if */
X    return;                         /* -v0 flag is set.      */
X
X  a = us.fAnsiChar;
X  us.fAnsiChar = (!gs.fFont || (!gs.fMeta && !gs.fPS)) << 1;
X  if (us.nRel == rcTransit) {
X    ciT = ciMain; ciMain = ciTwin;
X  }
X  DrawColor(gi.kiLite);
X  if (gs.fBorder)
X    DrawLine(gs.xWin-1, 0, gs.xWin-1, gs.yWin-1);
X  gs.xWin += xSideT;
X  DrawPrint(NULL, gs.xWin-xSideT+xFontT-gi.nScaleT, yFont*7/5*gi.nScaleT);
X
X  /* Print chart header and setting information. */
X
X  sprintf(sz, "%s %s", szAppName, szVersionCore);
X  DrawPrint(sz, gi.kiOn, fFalse);
X  if (*ciMain.nam)
X    DrawPrint(ciMain.nam, gi.kiLite, fFalse);
X  if (fNoTimeOrSpace)
X    sprintf(sz, "No time or space.");
X  else if (us.nRel == rcComposite)
X    sprintf(sz, "Composite chart.");
X  else {
X    sprintf(sz, "%c%c%c %s", chDay3(DayOfWeek(Mon, Day, Yea)),
X      SzDate(Mon, Day, Yea, fTrue));
X    DrawPrint(sz, gi.kiLite, fFalse);
X    DrawPrint(SzTim(Tim), gi.kiLite, fTrue);
X    sprintf(sz, " (%cT %s GMT)", ChDst(Dst), SzZone(Zon));
X  }
X  DrawPrint(sz, gi.kiLite, fFalse);
X  if (*ciMain.loc)
X    DrawPrint(ciMain.loc, gi.kiLite, fFalse);
X  if (Mon != -1)
X    DrawPrint(SzLocation(Lon, Lat), gi.kiLite, fFalse);
X  sprintf(sz, "%s houses.", szSystem[us.nHouseSystem]);
X  DrawPrint(sz, gi.kiLite, fFalse);
X  sprintf(sz, "%s, %s.", us.fSidereal ? "Sidereal" : "Tropical",
X    us.objCenter == oSun ? "Heliocentric" :
X    (us.objCenter == oEar ? "Geocentric" : szObjName[us.objCenter]));
X  DrawPrint(sz, gi.kiLite, fFalse);
X  sprintf(sz, "Julian Day = %11.4f", JulianDayFromTime(is.T));
X  DrawPrint(sz, gi.kiLite, fFalse);
X
X  /* Print house cusp positions. */
X
X  DrawPrint("", gi.kiLite, fFalse);
X  for (i = 1; i <= cSign; i++) {
X    sprintf(sz, "%2d%s house: ", i, szSuffix[i]);
X    y = DrawPrint(sz, kSignB(i), fTrue);
X    if (!is.fSeconds && (gs.nScale == 100 ||
X      !gs.fFont || !gi.fFile || gs.fBitmap) && y < gs.yWin-1) {
X      s = gi.nScale;
X      gi.nScale = gi.nScaleT;
X      DrawSign(SFromZ(chouse[i]), gs.xWin-12*gi.nScaleT,
X        y-(yFont/2-1)*gi.nScaleT);
X      gi.nScale = s;
X    }
X    DrawPrint(SzZodiac(chouse[i]), kSignB(SFromZ(chouse[i])), fFalse);
X  }
X
X  /* Print planet positions. */
X
X  DrawPrint("", gi.kiLite, fFalse);
X  for (i = 0; i <= oNorm; i++) if (FProper2(i) && !FCusp(i)) {
X    sprintf(sz, is.fSeconds ? "%3.3s: " : "%4.4s: ", szObjName[i]);
X    DrawPrint(sz, kObjB[i], fTrue);
X    y = DrawPrint(SzZodiac(planet[i]), kSignB(SFromZ(planet[i])), fTrue);
X    if (!is.fSeconds && i < starLo && gi.nMode != gSector && (gs.nScale ==
X      100 || !gs.fFont || !gi.fFile || gs.fBitmap) && y < gs.yWin-1) {
X      s = gi.nScale;
X      gi.nScale = gi.nScaleT;
X      DrawObject(i, gs.xWin-12*gi.nScaleT, y-(yFont/2-1)*gi.nScaleT);
X      gi.nScale = s;
X    }
X    sprintf(sz, "%c ", ret[i] < 0.0 ? chRet : ' ');
X    DrawPrint(sz, gi.kiOn, fTrue);
X    if (gi.nMode != gSector || !is.fSeconds) {
X      if (FThing(i)) {
X        is.fSeconds = fFalse;
X        DrawPrint(SzAltitude(planetalt[i]), gi.kiLite, fTrue);
X        is.fSeconds = us.fSeconds;
X      } else
X        DrawPrint("       ", gi.kiOn, fTrue);
X    }
X    if (gi.nMode == gSector) {
X      r = GFromO(i); s = (int)r + 1;
X      if (!is.fSeconds)
X        sprintf(sz, " %2d", s);
X      else
X        sprintf(sz, "%6.3f%c", r + 1.0, pluszone[s] ? '+' : '-');
X      DrawPrint(sz, pluszone[s] ? kRainbowB[1] : kMainB[5], fFalse);
X    } else
X      DrawPrint("", gi.kiOn, fFalse);
X  }
X
X  /* Print star positions. */
X
X  for (i = starLo; i <= starHi; i++) if (FProper(i)) {
X    s = oNorm+starname[i-oNorm];
X    sprintf(sz, is.fSeconds ? "%3.3s: " : "%4.4s: ", szObjName[s]);
X    DrawPrint(sz, kObjB[s], fTrue);
X    DrawPrint(SzZodiac(planet[s]), kSignB(SFromZ(planet[s])), fTrue);
X    DrawPrint("  ", gi.kiOn, fTrue);
X    if (gi.nMode != gSector || !is.fSeconds)
X      DrawPrint(SzAltitude(planetalt[s]), gi.kiLite, fTrue);
X    if (gi.nMode == gSector) {
X      r = GFromO(s); s = (int)r + 1;
X      if (!is.fSeconds)
X        sprintf(sz, " %2d", s);
X      else
X        sprintf(sz, "%6.3f%c", r + 1.0, pluszone[s] ? '+' : '-');
X      DrawPrint(sz, pluszone[s] ? kRainbowB[1] : kMainB[5], fFalse);
X    } else
X      DrawPrint("", gi.kiOn, fFalse);
X  }
X
X  /* Print element table information. */
X
X  DrawPrint("", gi.kiLite, fFalse);
X  CreateElemTable(&et);
X  sprintf(sz, "Fire: %d, Earth: %d,", et.coElem[eFir], et.coElem[eEar]);
X  DrawPrint(sz, gi.kiLite, fFalse);
X  sprintf(sz, "Air : %d, Water: %d", et.coElem[eAir], et.coElem[eWat]);
X  DrawPrint(sz, gi.kiLite, fFalse);
X  sprintf(sz, "Car: %d, Fix: %d, Mut: %d",
X    et.coMode[0], et.coMode[1], et.coMode[2]);
X  DrawPrint(sz, gi.kiLite, fFalse);
X  sprintf(sz, "Yang: %d, Yin: %d", et.coYang, et.coYin);
X  DrawPrint(sz, gi.kiLite, fFalse);
X  sprintf(sz, "M: %d, N: %d, A: %d, D: %d",
X    et.coMC, et.coIC, et.coAsc, et.coDes);
X  DrawPrint(sz, gi.kiLite, fFalse);
X  sprintf(sz, "Ang: %d, Suc: %d, Cad: %d",
X    et.coModeH[0], et.coModeH[1], et.coModeH[2]);
X  DrawPrint(sz, gi.kiLite, fFalse);
X  sprintf(sz, "Learn: %d, Share: %d", et.coLearn, et.coShare);
X  DrawPrint(sz, gi.kiLite, fFalse);
X  us.fAnsiChar = a;
X  if (us.nRel == rcTransit)
X    ciMain = ciT;
}
X
X
/* This is a subprocedure of XChartWheel() and XChartWheelRelation(). Draw  */
/* the outer sign and house rings for a wheel chart at the specified zodiac */
/* locations and at the given radius values.                                */
X
void DrawWheel(xsign, xhouse, cx, cy, unitx, unity, asc, r1, r2, r3, r4, r5)
real *xsign, *xhouse;
int cx, cy;
real unitx, unity, asc, r1, r2, r3, r4, r5;
{
X  int i;
X  real px, py, temp;
X
X  /* Draw Ascendant/Descendant and Midheaven/Nadir lines across whole chart. */
X
X  DrawColor(gi.kiLite);
X  DrawDash(cx+POINT1(unitx, 0.99, PX(xhouse[sAri])),
X           cy+POINT1(unity, 0.99, PY(xhouse[sAri])),
X           cx+POINT1(unitx, 0.99, PX(xhouse[sLib])),
X           cy+POINT1(unity, 0.99, PY(xhouse[sLib])), !gs.fColor);
X  DrawDash(cx+POINT1(unitx, 0.99, PX(xhouse[sCap])),
X           cy+POINT1(unity, 0.99, PY(xhouse[sCap])),
X           cx+POINT1(unitx, 0.99, PX(xhouse[sCan])),
X           cy+POINT1(unity, 0.99, PY(xhouse[sCan])), !gs.fColor);
X
X  /* Draw small five or one degree increments around the zodiac sign ring. */
X
X  for (i = 0; i < nDegMax; i++) {
X    temp = PZ(HousePlaceInX((real)i));
X    px = PX(temp); py = PY(temp);
X    DrawColor(i%5 ? gi.kiGray : gi.kiOn);
X    DrawDash(cx+POINT1(unitx, r3, px), cy+POINT1(unity, r3, py),
X      cx+POINT2(unitx, r4, px), cy+POINT2(unity, r4, py),
X      ((!gs.fColor || gs.fPS || gs.fMeta) && i%5)*2);
X  }
X
X  /* Draw circles for the zodiac sign and house rings. */
X
X  DrawColor(gi.kiOn);
X  DrawCircle(cx, cy, (int)(unitx*0.95+rRound), (int)(unity*0.95+rRound));
X  DrawCircle(cx, cy, (int)(unitx*r4+rRound), (int)(unity*r4+rRound));
X  DrawCircle(cx, cy, (int)(unitx*r3+rRound), (int)(unity*r3+rRound));
X  DrawCircle(cx, cy, (int)(unitx*r1+rRound), (int)(unity*r1+rRound));
X
X  /* Draw the glyphs for the signs and houses themselves. */
X
X  for (i = 1; i <= cSign; i++) {
X    temp = xsign[i];
X    DrawColor(gi.kiOn);
X    DrawLine(cx+POINT2(unitx, 0.95, PX(temp)),    /* Draw lines separating */
X      cy+POINT2(unity, 0.95, PY(temp)),           /* each sign and house   */
X      cx+POINT1(unitx, r4, PX(temp)),             /* from each other.      */
X      cy+POINT1(unity, r4, PY(temp)));
X    DrawLine(cx+POINT2(unitx, r3, PX(xhouse[i])),
X      cy+POINT2(unity, r3, PY(xhouse[i])),
X      cx+POINT1(unitx, r1, PX(xhouse[i])),
X      cy+POINT1(unity, r1, PY(xhouse[i])));
X    if (gs.fColor && i%3 != 1) {                             /* Lines from */
X      DrawColor(gi.kiGray);                                  /* each house */
X      DrawDash(cx, cy, cx+POINT2(unitx, r1, PX(xhouse[i])),  /* to center  */
X        cy+POINT2(unity, r1, PY(xhouse[i])), 1);             /* of wheel.  */
X    }
X    temp = Midpoint(temp, xsign[Mod12(i+1)]);
X    DrawColor(kSignB(i));
X    DrawSign(i, cx+POINT1(unitx, r5, PX(temp)),
X      cy+POINT1(unity, r5, PY(temp)));
X    temp = Midpoint(xhouse[i], xhouse[Mod12(i+1)]);
X    DrawHouse(i, cx+POINT1(unitx, r2, PX(temp)),
X      cy+POINT1(unity, r2, PY(temp)));
X  }
}
X
X
/* Another subprocedure of XChartWheel() and XChartWheelRelation(). Draw */
/* a set of planets in a wheel chart, drawing each glyph and a line from */
/* it to a dot indicating the planet's actual location.                  */
X
void DrawSymbolRing(symbol, xplanet, dir, cx, cy, unitx, unity, r1, r2, r3, r4)
real *symbol, *xplanet, *dir;
int cx, cy;
real unitx, unity, r1, r2, r3, r4;
{
X  int i;
X  real temp;
X
X  for (i = cObj; i >= 0; i--) if (FProper(i)) {
X    if (gs.fLabel) {
X      temp = symbol[i];
X      DrawColor(dir[i] < 0.0 ? gi.kiGray : gi.kiOn);
X      DrawDash(cx+POINT1(unitx, r2, PX(xplanet[i])),
X        cy+POINT1(unity, r2, PY(xplanet[i])),
X        cx+POINT1(unitx, r3, PX(temp)),
X        cy+POINT1(unity, r3, PY(temp)),
X        (ret[i] < 0.0 ? 1 : 0) - gs.fColor);
X      DrawObject(i, cx+POINT1(unitx, r4, PX(temp)),
X        cy+POINT1(unity, r4, PY(temp)));
X    } else
X      DrawColor(kObjB[i]);
X    DrawPoint(cx+POINT1(unitx, r1, PX(xplanet[i])),
X      cy+POINT1(unity, r1, PY(xplanet[i])));
X  }
}
X
X
/*
******************************************************************************
** Map Chart Routines.
******************************************************************************
*/
X
/* Another stream reader, this one is used by the globe drawing routine: */
/* for the next body of land/water, return its name (and color), its     */
/* longitude and latitude, and a vector description of its outline.      */
X
bool FReadWorldData(nam, loc, lin)
char FPTR **nam, FPTR **loc, FPTR **lin;
{
X  static char FPTR **psz = (char FPTR **)szWorldData;
X  int i;
X
X  *loc = *psz++;
X  *lin = *psz++;
X  *nam = *psz++;
X  if (*loc[0]) {
X    if (gs.fPrintMap && gi.fFile) {
X      i = **nam - '0';
X      AnsiColor(i ? kRainbowA[i] : kMainA[7]);
X      PrintSz(*nam+1); PrintL();
X    }
X    return fTrue;
X  }
X  psz = (char FPTR **)szWorldData;  /* Reset stream when no data left. */
X  return fFalse;
}
X
X
/* Given longitude and latitude values on a globe, return the window        */
/* coordinates corresponding to them. In other words, project the globe     */
/* onto the view plane, and return where our coordinates got projected to,  */
/* as well as whether our location is hidden on the back side of the globe. */
X
bool FGlobeCalc(x1, y1, u, v, cx, cy, rx, ry, deg)
real x1, y1;
int *u, *v, cx, cy, rx, ry, deg;
{
X  real j, siny1;
X
X  /* Compute coordinates for a general globe invoked with -XG switch. */
X
X  if (gi.nMode == gGlobe) {
X    x1 = Mod(x1+(real)deg);    /* Shift by current globe rotation value. */
X    if (gs.rTilt != 0.0) {
X      /* Do another coordinate shift if the globe's equator is tilted any. */
X      x1 = RFromD(x1); y1 = RFromD(rDegQuad-y1);
X      CoorXform(&x1, &y1, RFromD(gs.rTilt));
X      x1 = Mod(DFromR(x1)); y1 = rDegQuad-DFromR(y1);
X    }
X    *v = cy + (int)((real)ry*-RCosD(y1)-rRound);
X    *u = cx + (int)((real)rx*-RCosD(x1)*RSinD(y1)-rRound);
X    return x1 > rDegHalf;
X  }
X
X  /* Compute coordinates for a polar globe invoked with -XP switch. */
X
X  siny1 = RSinD(y1);
X  j = gs.fAlt ? rDegQuad+x1+deg : 270.0-x1-deg;
X  *v = cy + (int)(siny1*(real)ry*RSinD(j)-rRound);
X  *u = cx + (int)(siny1*(real)rx*RCosD(j)-rRound);
X  return gs.fAlt ? y1 < rDegQuad : y1 > rDegQuad;
}
X
X
/* Draw one "Ley line" on the world map, based coordinates given in terms of */
/* longitude and vertical fractional distance from the center of the earth.  */
X
void DrawLeyLine(l1, f1, l2, f2)
real l1, f1, l2, f2;
{
X  l1 = Mod(l1); l2 = Mod(l2);
X
X  /* Convert vertical fractional distance to a corresponding coordinate. */
X
X  f1 = rDegQuad-RAsin(f1)/rPiHalf*rDegQuad;
X  f2 = rDegQuad-RAsin(f2)/rPiHalf*rDegQuad;
X  DrawWrap((int)(l1*(real)gi.nScale+rRound),
X           (int)(f1*(real)gi.nScale+rRound),
X           (int)(l2*(real)gi.nScale+rRound),
X           (int)(f2*(real)gi.nScale+rRound), 0, gs.xWin-1);
}
X
X
/* Draw the main set of planetary Ley lines on the map of the world. This */
/* consists of drawing an icosahedron and then a dodecahedron lattice.    */
X
void DrawLeyLines(deg)
int deg;
{
X  real off = (real)deg, phi, h, h1, h2, r, i;
X
X  phi = (RSqr(5.0)+1.0)/2.0;                   /* Icosahedron constants. */
X  h = 1.0/(phi*2.0-1.0);
X  DrawColor(kMainB[6]);
X  for (i = off; i < rDegMax+off; i += 72.0) {  /* Draw icosahedron edges. */
X    DrawLeyLine(i, h, i+72.0, h);
X    DrawLeyLine(i-36.0, -h, i+36.0, -h);
X    DrawLeyLine(i, h, i, 1.0);
X    DrawLeyLine(i+36.0, -h, i+36.0, -1.0);
X    DrawLeyLine(i, h, i+36.0, -h);
X    DrawLeyLine(i, h, i-36.0, -h);
X  }
X  r = 1.0/RSqr(3.0)/phi/RCos(RFromD(54.0));    /* Dodecahedron constants. */
X  h2 = RSqr(1.0-r*r); h1 = h2/(phi*2.0+1.0);
X  DrawColor(kMainB[4]);
X  for (i = off; i < rDegMax+off; i += 72.0) {  /* Draw docecahedron edges. */
X    DrawLeyLine(i-36.0, h2, i+36.0, h2);
X    DrawLeyLine(i, -h2, i+72.0, -h2);
X    DrawLeyLine(i+36.0, h2, i+36.0, h1);
X    DrawLeyLine(i, -h2, i, -h1);
X    DrawLeyLine(i+36.0, h1, i+72.0, -h1);
X    DrawLeyLine(i+36.0, h1, i, -h1);
X  }
}
X
X
/* This major routine draws all of Astrolog's map charts. This means       */
/* either the world map or the constellations, in either rectangular or    */
/* globe hemisphere form. The rectangular chart may also be done in a      */
/* Mollewide projection, for six total combinations. We shift the chart by */
/* specified rotational and tilt values, and may draw on the chart each    */
/* planet at its zenith position on Earth or location in constellations.   */
X
void DrawMap(fSky, fGlobe, deg)
bool fSky, fGlobe;
int deg;
{
X  char *nam, *loc, *lin, chCmd;
X  int X[objMax], Y[objMax], M[objMax], N[objMax],
X    cx = gs.xWin/2, cy = gs.yWin/2, rx, ry, lon, lat, unit = 12*gi.nScale,
X    x, y, xold, yold, m, n, u, v, i, j, k, l, nScl = gi.nScale;
X  bool fNext = fTrue, fCan;
X  real planet1[objMax], planet2[objMax], x1, y1, rT;
#ifdef CONSTEL
X  char *pch;
X  bool fBlank;
X  int isz = 0, nC, xT, yT, xDelta, yDelta, xLo, xHi, yLo, yHi;
#endif
X
X  /* Set up some variables. */
X  rx = cx-1; ry = cy-1;
X  if (fGlobe)
X    fCan = (gs.rTilt == 0.0 && gi.nMode != gPolar);
X
#ifdef CONSTEL
X  /* Draw a dot grid for large rectangular constellation charts. */
X  if (fSky && !fGlobe && !gs.fMollewide && gi.nScale/gi.nScaleT > 2)
X    for (yT = 5; yT < nDegHalf; yT += 5)
X      for (xT = 5; xT <= nDegMax; xT += 5) {
X        DrawColor(xT % 15 == 0 && yT % 10 == 0 ? gi.kiOn : gi.kiGray);
X        x = xT+deg;
X        if (x > nDegMax)
X          x -= nDegMax;
X        DrawPoint(x*nScl, yT*nScl);
X      }
#endif
X
X  loop {
X
X    /* Get the next chunk of data to process. Get the starting position, */
X    /* map it to the screen, and set the drawing color appropriately.    */
X
X    if (fNext) {
X      fNext = fFalse;
X
X      /* For constellations, get data for the next constellation shape. */
X
X      if (fSky) {
#ifdef CONSTEL
X        isz++;
X        if (isz > cCnstl)
X          break;
X        DrawColor(gs.fAlt && gi.nMode != gPolar && (gi.nMode != gWorldMap ||
X          !gs.fMollewide) ? kMainB[7] : kRainbowB[6]);
X        pch = (char *)szDrawConstel[isz];
X        lon = nDegMax -
X          (((pch[2]-'0')*10+(pch[3]-'0'))*15+(pch[4]-'0')*10+(pch[5]-'0'));
X        lat = 90-((pch[6] == '-' ? -1 : 1)*((pch[7]-'0')*10+(pch[8]-'0')));
X        pch += 9;
X        xLo = xHi = xT = xold = x = lon;
X        yLo = yHi = yT = yold = y = lat;
X        nC = 0;
X        if (fGlobe) {
X          FGlobeCalc((real)x, (real)y, &m, &n, cx, cy, rx, ry, deg);
X          k = l = fTrue;
X        } else {
X          xold += deg;
X          x += deg;
X        }
#else
X        ;
#endif
X
X      /* For world maps, get data for the next coastline piece. */
X
X      } else {
X        if (!FReadWorldData(&nam, &loc, &lin))
X          break;
X        i = nam[0]-'0';
X        DrawColor((!fGlobe && gi.nMode == gAstroGraph) ? gi.kiOn :
X          (gi.nMode == gGlobe && gs.fAlt) ? gi.kiGray :
X          (i ? kRainbowB[i] : kMainB[7]));
X        lon = (loc[0] == '+' ? 1 : -1)*
X          ((loc[1]-'0')*100 + (loc[2]-'0')*10 + (loc[3]-'0'));
X        lat = (loc[4] == '+' ? 1 : -1)*((loc[5]-'0')*10 + (loc[6]-'0'));
X        if (fGlobe) {
X          x = 180-lon;
X          y = 90-lat;
X          FGlobeCalc((real)x, (real)y, &m, &n, cx, cy, rx, ry, deg);
X          k = l = fTrue;
X        } else {
X          xold = x = 181-lon+deg;
X          yold = y = 90-lat;
X        }
X      }
X    }
X
X    /* Get the next unit from the string to draw on the screen as a line. */
X
X    if (fSky) {
X
X      /* For constellations we have a cache of how long we should keep    */
X      /* going in the previous direction, as say "u5" for up five should  */
X      /* move our pointer up five times without advancing string pointer. */
X
#ifdef CONSTEL
X      if (nC <= 0) {
X        if (!(chCmd = *pch)) {
X          fNext = fTrue;
X          if (gs.fText) {
X
X            /* If we've reached the end of current constellation, compute */
X            /* the center location in it based on lower and upper bounds  */
X            /* we've maintained, and print the name of the constel there. */
X
X            xT = xLo + (xHi - xLo)*(szDrawConstel[isz][0]-'1')/8;
X            yT = yLo + (yHi - yLo)*(szDrawConstel[isz][1]-'1')/8;
X            if (xT < 0)
X              xT += nDegMax;
X            else if (xT > nDegMax)
X              xT -= nDegMax;
X            if (fGlobe) {
X              if (FGlobeCalc((real)xT, (real)yT, &x, &y, cx, cy, rx, ry, deg))
X                continue;
X            } else {
X              xT += deg;
X              if (xT > nDegMax)
X                xT -= nDegMax;
X              if (gs.fMollewide)
X                x = 180*nScl + NMultDiv(xT-180, NMollewide(yT-91), 180L);
X              else
X                x = xT*nScl;
X              y = yT*nScl;
X            }
X            DrawColor(gs.fAlt && gi.nMode != gPolar && (gi.nMode !=
X              gWorldMap || !gs.fMollewide) ? gi.kiGray : kMainB[5]);
X            DrawSz(szCnstlAbbrev[isz], x, y, dtCent);
X          }
X          continue;
X        }
X        pch++;
X
X        /* Get the next direction and distance from constellation string. */
X
X        if (fBlank = (chCmd == 'b'))
X          chCmd = *pch++;
X        xDelta = yDelta = 0;
X        switch (chCmd) {
X        case 'u': yDelta = -1; break;    /* Up    */
X        case 'd': yDelta =  1; break;    /* Down  */
X        case 'l': xDelta = -1; break;    /* Left  */
X        case 'r': xDelta =  1; break;    /* Right */
X        case 'U': yDelta = -1; nC = (yT-1)%10+1;    break;  /* Up until    */
X        case 'D': yDelta =  1; nC = 10-yT%10;       break;  /* Down until  */
X        case 'L': xDelta = -1; nC = (xT+599)%15+1;  break;  /* Left until  */
X        case 'R': xDelta =  1; nC = 15-(xT+600)%15; break;  /* Right until */
X        default: PrintError("Bad draw.");             /* Shouldn't happen. */
X        }
X        if (chCmd >= 'a')
X          nC = NFromPch(&pch);    /* Figure out how far to draw. */
X      }
X      nC--;
X      xT += xDelta; x += xDelta;
X      yT += yDelta; y += yDelta;
X      if (fBlank) {
X        xold = x; yold = y;    /* We occasionally want to move the pointer */
X        l = fFalse;            /* without drawing the line on the screen.  */
X        continue;
X      }
X      if (xT < xLo)         /* Maintain our bounding rectangle for this */
X        xLo = xT;           /* constellation if we crossed over it any. */
X      else if (xT > xHi)
X        xHi = xT;
X      if (yT < yLo)
X        yLo = yT;
X      else if (yT > yHi)
X        yHi = yT;
#else
X      ;
#endif
X
X    } else {
X
X      /* Get the next unit from the much simpler world map strings. */
X
X      if (!(chCmd = *lin)) {
X        fNext = fTrue;
X        continue;
X      }
X      lin++;
X
X      /* Each unit is exactly one character in the coastline string. */
X
X      if (chCmd == 'L' || chCmd == 'H' || chCmd == 'G')
X        x--;
X      else if (chCmd == 'R' || chCmd == 'E' || chCmd == 'F')
X        x++;
X      if (chCmd == 'U' || chCmd == 'H' || chCmd == 'E')
X        y--;
X      else if (chCmd == 'D' || chCmd == 'G' || chCmd == 'F')
X        y++;
X    }
X
X    /* Transform map coordinates to screen coordinates and draw a line. */
X
X    while (x >= nDegMax)    /* Take care of coordinate wrap around. */
X      x -= nDegMax;
X    while (x < 0)
X      x += nDegMax;
X    if (abs(x-xold) > nDegHalf)
X      xold = x;
X
X    if (fGlobe) {
X
X      /* For globes, we have to go do a complicated transformation, and not */
X      /* draw when we're hidden on the back side of the sphere. We're smart */
X      /* and try to only do the slow stuff when we know we'll be visible.   */
X
X      if (fCan) {
X        k = x+deg;
X        if (k >= nDegMax)
X          k -= nDegMax;
X        k = (k <= 180);
X      }
X      if (k && !FGlobeCalc((real)x, (real)y, &u, &v, cx, cy, rx, ry, deg)) {
X        if (l)
X          DrawLine(m, n, u, v);
X        m = u; n = v;
X        l = fTrue;
X      } else
X        l = fFalse;
X    } else {
X
X      /* Rectangular maps are much simpler, with screen coordinates      */
X      /* proportional to internal coords. For the Mollewide projection   */
X      /* we have to apply a factor to the horizontal positioning though. */
X
X      if (gs.fMollewide && gi.nMode != gAstroGraph)
X        DrawLine(180*nScl + NMultDiv(xold-180,
X          NMollewide(yold-91), 180L), (yold-1)*nScl,
X          180*nScl + NMultDiv(x-180, NMollewide(y-91), 180L), (y-1)*nScl);
X      else
X        DrawLine(xold*nScl, (yold-1)*nScl, x*nScl, (y-1)*nScl);
X      xold = x; yold = y;
X    }
X  }
X
X  /* Draw the outline of the map, either a circle around globes or a */
X  /* Mollewide type ellipse for that type of rectangular chart.      */
X
X  DrawColor(gi.kiOn);
X  if (!fGlobe) {
X    if (gs.fMollewide && gi.nMode != gAstroGraph)
X      if (!gs.fAlt)
X        for (j = -1; j <= 1; j += 2)
X          for (xold = 0, y = 89; y >= 0; y--, xold = x)
X            for (x = NMollewide(y), i = -1; i <= 1; i += 2)
X              {
X              DrawLine(180*nScl + i*xold - (i==1), (90+j*(y+1))*nScl - (j==1),
X                180*nScl + i*x - (i==1), (90+j*y)*nScl - (j==1));
X              }
X  } else
X    DrawEllipse(0, 0, gs.xWin-1, gs.yWin-1);
X
X  /* Now, if we are in an appropriate bonus chart mode, draw each planet at */
X  /* its zenith or visible location on the globe or map, if not hidden.     */
X
X  if (!gs.fAlt || (gi.nMode != gGlobe &&
X    (!fSky || gi.nMode != gWorldMap || gs.fMollewide)))
X    return;
X  rT = gs.fConstel ? rDegHalf - (fGlobe ? 0.0 : (real)deg) : Lon;
X  if (rT < 0.0)
X    rT += rDegMax;
X  for (i = 1; i <= cObj; i++) {
X    planet1[i] = RFromD(Tropical(planet[i]));
X    planet2[i] = RFromD(planetalt[i]);
X    EclToEqu(&planet1[i], &planet2[i]);    /* Calculate zenith long. & lat. */
X  }
X
X  /* Compute screen coordinates of each object, if it's even visible. */
X
X  for (i = 1; i <= cObj; i++) if (FProper(i)) {
X    if (fSky)
X      x1 = planet1[i];
X    else
X      x1 = planet1[oMC]-planet1[i];
X    if (x1 < 0.0)
X      x1 += 2.0*rPi;
X    if (x1 > rPi)
X      x1 -= 2.0*rPi;
X    x1 = Mod(rDegHalf-rT-DFromR(x1));
X    y1 = rDegQuad-DFromR(planet2[i]);
X    if (fGlobe) {
X      X[i] = FGlobeCalc(x1, y1, &u, &v, cx, cy, rx, ry, deg) ? -1000 : u;
X      Y[i] = v;
X    } else {
X      X[i] = (int)(x1 * (real)nScl);
X      Y[i] = (int)(y1 * (real)nScl);
X    }
X    M[i] = X[i]; N[i] = Y[i]+unit/2;
X  }
X
X  /* Now that we have the coordinates of each object, figure out where to   */
X  /* draw the glyphs. Again we try not to draw glyphs on top of each other. */
X
X  for (i = 1; i <= cObj; i++) if (FProper(i)) {
X    k = l = gs.xWin+gs.yWin;
X
X    /* For each planet, we draw the glyph either right over or right under */
X    /* the actual zenith location point. So, find out the closest distance */
X    /* of any other planet assuming we place ours at both possibilities.   */
X
X    for (j = 1; j < i; j++) if (FProper(j)) {
X      k = Min(k, abs(M[i]-M[j])+abs(N[i]-N[j]));
X      l = Min(l, abs(M[i]-M[j])+abs(N[i]-unit-N[j]));
X    }
X
X    /* Normally, we put the glyph right below the actual point. If however  */
X    /* another planet is close enough to have their glyphs overlap, and the */
X    /* above location is better, then we'll draw the glyph above instead.   */
X
X    if (k < unit || l < unit)
X      if (k < l)
X        N[i] -= unit;
X  }
X  for (i = cObj; i >= 1; i--) if (X[i] >= 0 && FProper(i))      /* Draw the */
X    DrawObject(i, M[i], N[i]);                                  /* glyphs.  */
X  for (i = cObj; i >= 1; i--) if (X[i] >= 0 && FProper(i)) {
X    DrawColor(kObjB[i]);
X    DrawSpot(X[i], Y[i]);
X  }
}
X
X
/* Create a chart in the window based on the current graphics chart mode. */
/* This is the main dispatch routine for all of the program's graphics.   */
X
void DrawChartX()
{
X  char sz[cchSzDef];
X  int i;
X  bool fT;
X
X  gi.nScale = gs.nScale/100;
X
X  if (gs.fBitmap || gs.fMeta)
X    PrintNotice("Creating graphics chart in memory.");
X  DrawClearScreen();
#ifdef CONSTEL
X  fT = gs.fConstel;
#else
X  fT = fFalse;
#endif
X  switch (gi.nMode) {
X  case gWheel:
X  case gHouse:
X    if (us.nRel > rcDual)
X      XChartWheel();
X    else if (us.nRel == rcTriWheel || us.nRel == rcQuadWheel)
X      XChartWheelThreeFour();
X    else
X      XChartWheelRelation();
X    break;
X  case gGrid:
X    if (us.nRel > rcDual)
X      XChartGrid();
X    else
X      XChartGridRelation();
X    break;
X  case gHorizon:
X    if (us.fPrimeVert)
X      XChartHorizonSky();
X    else
X      XChartHorizon();
X    break;
X  case gOrbit:
X    XChartOrbit();
X    break;
X  case gSector:
X    XChartSector();
X    break;
X  case gDisposit:
X    XChartDispositor();
X    break;
X  case gAstroGraph:
X    DrawMap(fFalse, fFalse, gs.nRot);  /* First draw map of world.           */
X    XChartAstroGraph();                /* Then draw astro-graph lines on it. */
X    break;
X  case gCalendar:
X    XChartCalendar();
X    break;
X  case gEphemeris:
X    XChartEphemeris();
X    break;
X  case gWorldMap:
X    DrawMap(fT, fFalse, gs.nRot);           /* First draw map of world. */
X    if (!fT && gs.fAlt && !gs.fMollewide)   /* Then maybe Ley lines.    */
X      DrawLeyLines(gs.nRot);
X    break;
X  case gGlobe:
X  case gPolar:
X    DrawMap(fT, fTrue, gs.nRot);
X    break;
#ifdef BIORHYTHM
X  case gBiorhythm:
X    XChartBiorhythm();
X    break;
#endif
X  }
X
X  /* Print text showing chart information at bottom of window. */
X
X  DrawColor(gi.kiLite);
X  if (fDrawText) {
X    if (fNoTimeOrSpace)
X      sprintf(sz, "(No time or space)");
X    else if (us.nRel == rcComposite)
X      sprintf(sz, "(Composite)");
X    else {
X      fT = us.fAnsiChar;
X      us.fAnsiChar = (!gs.fFont || (!gs.fMeta && !gs.fPS)) << 1;
X      i = DayOfWeek(Mon, Day, Yea);
X      sprintf(sz, "%c%c%c %s %s (%cT %s GMT) %s", chDay3(i),
X        SzDate(Mon, Day, Yea, 2), SzTim(Tim), ChDst(Dst),
X        SzZone(Zon), SzLocation(Lon, Lat));
X      us.fAnsiChar = fT;
X    }
X    DrawSz(sz, gs.xWin/2, gs.yWin-3*gi.nScaleT, dtBottom | dtErase);
X  }
X
X  /* Draw a border around the chart if the mode is set and appropriate. */
X
X  if (fDrawBorder)
X    DrawEdgeAll();
}
#endif /* GRAPH */
X
/* xcharts0.c */
SHAR_EOF
  $shar_touch -am 1223232998 'xcharts0.c' &&
  chmod 0644 'xcharts0.c' ||
  echo 'restore of xcharts0.c failed'
  shar_count="`wc -c < 'xcharts0.c'`"
  test 31760 -eq "$shar_count" ||
    echo "xcharts0.c: original size 31760, current size $shar_count"
fi
# ============= xcharts1.c ==============
if test -f 'xcharts1.c' && test X"$1" != X"-c"; then
  echo 'x - skipping xcharts1.c (File already exists)'
else
  echo 'x - extracting xcharts1.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'xcharts1.c' &&
/*
** Astrolog (Version 5.40) File: xcharts1.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
#ifdef GRAPH
/*
******************************************************************************
** Single Chart Graphics Routines.
******************************************************************************
*/
X
/* Draw a wheel chart, in which the 12 signs and houses are delineated, and  */
/* the planets are inserted in their proper places. This is the default      */
/* graphics chart to generate, as is done when the -v or -w (or no) switches */
/* are included with -X. Draw the aspects in the middle of chart, too.       */
X
void XChartWheel()
{
X  real xsign[cSign+1], xhouse[cSign+1], xplanet[objMax], symbol[objMax];
X  int cx, cy, i, j;
X  real unitx, unity;
X
X  /* Set up variables and temporarily automatically decrease the horizontal */
X  /* chart size to leave room for the sidebar if that mode is in effect.    */
X
X  if (gs.fText && !us.fVelocity)
X    gs.xWin -= xSideT;
X  cx = gs.xWin/2 - 1; cy = gs.yWin/2 - 1;
X  unitx = (real)cx; unity = (real)cy;
X  gi.rAsc = gs.objLeft ? planet[abs(gs.objLeft)]+rDegQuad*(gs.objLeft < 0) :
X    chouse[1];
X  if (us.fVedic)
X    gi.rAsc = gs.objLeft ? (gs.objLeft < 0 ? 120.0 : -60.0)-gi.rAsc : 0.0;
X
X  /* Fill out arrays with the angular degree on the circle of where to */
X  /* place each object, cusp, and sign glyph based on the chart mode.  */
X
X  if (gi.nMode == gWheel) {
X    for (i = 1; i <= cSign; i++)
X      xhouse[i] = PZ(chouse[i]);
X  } else {
X    gi.rAsc -= chouse[1];
X    for (i = 1; i <= cSign; i++)
X      xhouse[i] = PZ(ZFromS(i));
X  }
X  for (i = 1; i <= cSign; i++)
X    xsign[i] = PZ(HousePlaceInX(ZFromS(i)));
X  for (i = 0; i <= cObj; i++)
X    xplanet[i] = PZ(HousePlaceInX(planet[i]));
X
X  /* Go draw the outer sign and house rings. */
X
X  DrawWheel(xsign, xhouse, cx, cy, unitx, unity, gi.rAsc,
X    0.65, 0.70, 0.75, 0.80, 0.875);
X
X  for (i = 0; i <= cObj; i++)    /* Figure out where to put planet glyphs. */
X    symbol[i] = xplanet[i];
X  FillSymbolRing(symbol, 1.0);
X
X  /* For each planet, draw a small dot indicating where it is, and then */
X  /* a line from that point to the planet's glyph.                      */
X
X  DrawSymbolRing(symbol, xplanet, ret, cx, cy, unitx, unity,
X    0.50, 0.52, 0.56, 0.60);
X
X  /* Draw lines connecting planets which have aspects between them. */
X
X  if (!gs.fAlt) {                /* Don't draw aspects in bonus mode. */
X    if (!FCreateGrid(fFalse))
X      return;
X    for (j = cObj; j >= 1; j--)
X      for (i = j-1; i >= 0; i--)
X        if (grid->n[i][j] && FProper(i) && FProper(j)) {
X          DrawColor(kAspB[grid->n[i][j]]);
X          DrawDash(cx+POINT1(unitx, 0.48, PX(xplanet[i])),
X            cy+POINT1(unity, 0.48, PY(xplanet[i])),
X            cx+POINT1(unitx, 0.48, PX(xplanet[j])),
X            cy+POINT1(unity, 0.48, PY(xplanet[j])),
X            abs(grid->v[i][j]/60/2));
X        }
X  }
X
X  /* Go draw sidebar with chart information and positions if need be. */
X
X  DrawInfo();
}
X
X
/* Draw an astro-graph chart on a map of the world, i.e. the draw the     */
/* Ascendant, Descendant, Midheaven, and Nadir lines corresponding to the */
/* time in the chart. This chart is done when the -L switch is combined   */
/* with the -X switch.                                                    */
X
void XChartAstroGraph()
{
X  real planet1[objMax], planet2[objMax],
X    end1[cObj*2+1], end2[cObj*2+1],
X    symbol1[cObj*2+1], symbol2[cObj*2+1],
X    lon = Lon, longm, x, y, z, ad, oa, am, od, dm, lat;
X  int unit = gi.nScale, fStroke, lat1 = -60, lat2 = 75, y1, y2, xold1, xold2,
X    i, j, k, l;
X
X  /* Erase top and bottom parts of map. We don't draw the astro-graph lines */
X  /* above certain latitudes, and this gives us room for glyph labels, too. */
X
X  y1 = (91-lat1)*gi.nScale;
X  y2 = (91-lat2)*gi.nScale;
X  DrawColor(gi.kiOff);
X  DrawBlock(0, 1, gs.xWin-1, y2-1);
X  DrawBlock(0, y1+1, gs.xWin-1, gs.yWin-2);
X  DrawColor(gi.kiLite);
X  DrawDash(0, gs.yWin/2, gs.xWin-2, gs.yWin/2, 4);    /* Draw equator. */
X  DrawColor(gi.kiOn);
X  DrawLine(1, y2, gs.xWin-2, y2);
X  DrawLine(1, y1, gs.xWin-2, y1);
X  for (i = 1; i <= cObj*2; i++)
X    end1[i] = end2[i] = -rLarge;
X
X  /* Draw small hatches every 5 degrees along edges of world map. */
X
X  DrawColor(gi.kiLite);
X  for (i = lat1; i <= lat2; i += 5) {
X    j = (91-i)*gi.nScale;
X    k = (2+(i%10 == 0)+2*(i%30 == 0))*gi.nScaleT;
X    DrawLine(1, j, k, j);
X    DrawLine(gs.xWin-2, j, gs.xWin-1-k, j);
X  }
X  for (i = -180; i < 180; i += 5) {
X    j = (180-i)*gi.nScale;
X    k = (2+(i%10 == 0)+2*(i%30 == 0)+(i%90 == 0))*gi.nScaleT;
X    DrawLine(j, y2+1, j, y2+k);
X    DrawLine(j, y1-1, j, y1-k);
X  }
X  if (us.fLatitudeCross) {
X    DrawColor(kRainbowB[7]);
X    i = (int)((91.0-Lat)*(real)gi.nScale);
X    DrawLine(0, i, gs.xWin-1, i);
X  }
X
#ifdef MATRIX
X  /* Calculate zenith locations of each planet. */
X
X  for (i = 1; i <= cObj; i++) if (!ignore[i] || i == oMC) {
X    planet1[i] = RFromD(Tropical(i == oMC ? is.MC : planet[i]));
X    planet2[i] = RFromD(planetalt[i]);
X    EclToEqu(&planet1[i], &planet2[i]);
X  }
X
X  /* Draw the Midheaven lines and zenith location markings. */
X
X  if (lon < 0.0)
X    lon += rDegMax;
X  for (i = 1; i <= cObj; i++) if (FProper(i)) {
X    x = planet1[oMC]-planet1[i];
X    if (x < 0.0)
X      x += 2.0*rPi;
X    if (x > rPi)
X      x -= 2.0*rPi;
X    z = lon+DFromR(x);
X    if (z > rDegHalf)
X      z -= rDegMax;
X    j = (int)(Mod(rDegHalf-z+gs.nRot)*(real)gi.nScale);
X    DrawColor(kElemB[eEar]);
X    DrawLine(j, y1+unit*4, j, y2-unit*1);
X    end2[i*2-1] = (real)j;
X    y = DFromR(planet2[i]);
X    k = (int)((91.0-y)*(real)gi.nScale);
X    if (FBetween((int)y, lat1, lat2)) {
X      DrawColor(gi.kiLite);
X      DrawBlock(j-gi.nScaleT, k-gi.nScaleT, j+gi.nScaleT, k+gi.nScaleT);
X      DrawColor(gi.kiOff);
X      DrawBlock(j, k, j, k);
X    }
X
X    /* Draw Nadir lines assuming we aren't in bonus chart mode. */
X
X    if (!gs.fAlt) {
X      j += 180*gi.nScale;
X      if (j > gs.xWin-2)
X        j -= (gs.xWin-2);
X      end1[i*2-1] = (real)j;
X      DrawColor(kElemB[eWat]);
X      DrawLine(j, y1+unit*2, j, y2-unit*2);
X    }
X  }
X
X  /* Now, normally, unless we are in bonus chart mode, we will go on to draw */
X  /* the Ascendant and Descendant lines here.                                */
X
X  longm = RFromD(Mod(DFromR(planet1[oMC])+lon));
X  if (!gs.fAlt) for (i = 1; i <= cObj; i++) if (FProper(i)) {
X    xold1 = xold2 = -1000;
X
X    /* Hack: Normally we draw the Ascendant and Descendant line segments  */
X    /* simultaneously. However, for the PostScript and metafile stroke    */
X    /* graphics, this will case the file to get inordinately large due to */
X    /* the constant thrashing between the Asc and Desc colors. Hence for  */
X    /* these charts only, we'll do two passes for Asc and Desc.           */
X    fStroke = gs.fPS || gs.fMeta;
X    for (l = 0; l <= fStroke; l++)
X
X    for (lat = (real)lat1; lat <= (real)lat2;
X      lat += 1.0/(real)(gi.nScale/gi.nScaleT)) {
X
X      /* First compute and draw the current segment of Ascendant line. */
X
X      j = (int)((91.0-lat)*(real)gi.nScale);
X      ad = RTan(planet2[i])*RTan(RFromD(lat));
X      if (ad*ad > 1.0)
X        ad = rLarge;
X      else {
X        ad = RAsin(ad);
X        oa = planet1[i]-ad;
X        if (oa < 0.0)
X          oa += 2.0*rPi;
X        am = oa-rPiHalf;
X        if (am < 0.0)
X          am += 2.0*rPi;
X        z = longm-am;
X        if (z < 0.0)
X          z += 2.0*rPi;
X        if (z > rPi)
X          z -= 2.0*rPi;
X        z = DFromR(z);
X        k = (int)(Mod(rDegHalf-z+gs.nRot)*(real)gi.nScale);
X        if (!fStroke || !l) {
X          DrawColor(kElemB[eFir]);
X          DrawWrap(xold1, j+gi.nScaleT, k, j, 1, gs.xWin-2);
X          if (lat == (real)lat1) {                          /* Line segment */
X            DrawLine(k, y1, k, y1+unit*4);                  /* pointing to  */
X            end2[i*2] = (real)k;                            /* Ascendant.   */
X          }
X        } else if (lat == (real)lat1)
X          end2[i*2] = (real)k;
X        xold1 = k;
X      }
X
X      /* The curving Ascendant and Descendant lines actually touch at low or */
X      /* high latitudes. Sometimes when we start out, a particular planet's  */
X      /* lines haven't appeared yet, i.e. we are scanning at a latitude      */
X      /* where our planet's lines don't exist. If this is the case, then     */
X      /* when they finally do start, draw a thin horizontal line connecting  */
X      /* the Ascendant and Descendant lines so they don't just start in      */
X      /* space. Note that these connected lines aren't labeled with glyphs.  */
X
X      if (ad == rLarge) {
X        if (xold1 >= 0) {
X          if (!fStroke || !l) {
X            DrawColor(gi.kiGray);
X            DrawWrap(xold1, j+1, xold2, j+1, 1, gs.xWin-2);
X          }
X          lat = rDegQuad;
X        }
X      } else {
X
X      /* Then compute and draw corresponding segment of Descendant line. */
X
X        od = planet1[i]+ad;
X        dm = od+rPiHalf;
X        z = longm-dm;
X        if (z < 0.0)
X          z += 2.0*rPi;
X        if (z > rPi)
X          z -= 2.0*rPi;
X        z = DFromR(z);
X        k = (int)(Mod(rDegHalf-z+gs.nRot)*(real)gi.nScale);
X        if (xold2 < 0 && lat > (real)lat1 && (!fStroke || l)) {
X          DrawColor(gi.kiGray);
X          DrawWrap(xold1, j, k, j, 1, gs.xWin-2);
X        }
X        if (!fStroke || l) {
X          DrawColor(kElemB[eAir]);
X          DrawWrap(xold2, j+gi.nScaleT, k, j, 1, gs.xWin-2);
X          if (lat == (real)lat1)                            /* Line segment */
X            DrawLine(k, y1, k, y1+unit*2);                  /* pointing to  */
X        }                                                   /* Descendant.  */
X        xold2 = k;
X      }
X    }
#endif /* MATRIX */
X
X    /* Draw segments pointing to top of Ascendant and Descendant lines. */
X
X    if (ad != rLarge) {
X      DrawColor(kElemB[eFir]);
X      DrawLine(xold1, y2, xold1, y2-unit*1);
X      DrawColor(kElemB[eAir]);
X      DrawLine(k, y2, k, y2-unit*2);
X      end1[i*2] = (real)k;
X    }
X  }
X
X  DrawColor(kMainB[8]);
X  i = (int)((181.0-Lon)*(real)gi.nScale);
X  j = (int)((91.0-Lat)*(real)gi.nScale);
X  if (us.fLatitudeCross)
X    DrawSpot(i, j);
X  else
X    DrawPoint(i, j);
X
X  /* Determine where to draw the planet glyphs. We have four sets of each    */
X  /* planet - each planet's glyph appearing in the chart up to four times -  */
X  /* one for each type of line. The Midheaven and Ascendant lines are always */
X  /* labeled at the bottom of the chart, while the Nadir and Midheaven lines */
X  /* at the top. Therefore we need to place two sets of glyphs, twice.       */
X
X  for (i = 1; i <= cObj*2; i++) {
X    symbol1[i] = end1[i];
X    symbol2[i] = end2[i];
X  }
X  FillSymbolLine(symbol1);
X  FillSymbolLine(symbol2);
X
X  /* Now actually draw the planet glyphs. */
X
X  for (i = 1; i <= cObj*2; i++) {
X    j = (i+1)/2;
X    if (FProper(j)) {
X      if ((gi.xTurtle = (int)symbol1[i]) > 0 && gs.fLabel) {
X        DrawColor(ret[j] < 0.0 ? gi.kiGray : gi.kiOn);
X        DrawDash((int)end1[i], y2-unit*2, (int)symbol1[i], y2-unit*4,
X          (ret[i] < 0.0 ? 1 : 0) - gs.fColor);
X        DrawObject(j, gi.xTurtle, y2-unit*10);
X      }
X      if ((gi.xTurtle = (int)symbol2[i]) > 0) {
X        DrawColor(ret[j] < 0.0 ? gi.kiGray : gi.kiOn);
X        DrawDash((int)end2[i], y1+unit*4, (int)symbol2[i], y1+unit*8,
X          (ret[i] < 0.0 ? 1 : 0) - gs.fColor);
X        DrawObject(j, gi.xTurtle, y1+unit*14);
X        DrawTurtle(szDrawObject[i & 1 ? oMC : oAsc], (int)symbol2[i],
X          y1+unit*24-gi.nScaleT);
X      }
X    }
X  }
}
X
X
/* Draw an aspect and midpoint grid in the window, with planets labeled down */
/* the diagonal. This chart is done when the -g switch is combined with the  */
/* -X switch. The chart always has a certain number of cells; hence based    */
/* how the restrictions are set up, there may be blank columns and rows,     */
/* or else only the first number of unrestricted objects will be included.   */
X
void XChartGrid()
{
X  char sz[cchSzDef];
X  int unit, siz, x, y, i, j, k;
X  KI c;
X
X  unit = CELLSIZE*gi.nScale; siz = gs.nGridCell*unit;
X  if (!FCreateGrid(gs.fAlt))
X    return;
X
X  /* Loop through each cell in each row and column of grid. */
X
X  for (y = 1, j = oEar-1; y <= gs.nGridCell; y++) {
X    do {
X      j++;
X    } while (!FProper(j) && j <= cObj);
X    DrawColor(gi.kiGray);
X    DrawDash(0, y*unit, siz, y*unit, !gs.fColor);
X    DrawDash(y*unit, 0, y*unit, siz, !gs.fColor);
X    if (j <= cObj) for (x = 1, i = oEar-1; x <= gs.nGridCell; x++) {
X      do {
X        i++;
X      } while (!FProper(i) && i <= cObj);
X      if (i <= cObj) {
X        gi.xTurtle = x*unit-unit/2;
X        gi.yTurtle = y*unit-unit/2 -
X          (gi.nScale/gi.nScaleT > 2 ? 5*gi.nScaleT : 0);
X        k = grid->n[i][j];
X
X        /* If this is an aspect cell, draw glyph of aspect in effect. */
X
X        if (gs.fAlt ? x > y : x < y) {
X          if (k) {
X            DrawColor(c = kAspB[k]);
X            DrawAspect(k, gi.xTurtle, gi.yTurtle);
X          }
X
X        /* If this is a midpoint cell, draw glyph of sign of midpoint. */
X
X        } else if (gs.fAlt ? x < y : x > y) {
X          DrawColor(c = kSignB(grid->n[i][j]));
X          DrawSign(grid->n[i][j], gi.xTurtle, gi.yTurtle);
X
X        /* For cells on main diagonal, draw glyph of planet. */
X
X        } else {
X          DrawColor(gi.kiLite);
X          DrawEdge((y-1)*unit, (y-1)*unit, y*unit, y*unit);
X          DrawObject(i, gi.xTurtle, gi.yTurtle);
X        }
X
X        /* When the scale size is 300+, we can print text in each cell: */
X
X        if (gi.nScale/gi.nScaleT > 2 && gs.fLabel) {
X          k = abs(grid->v[i][j]);
X
X          /* For the aspect portion, print the orb in degrees and minutes. */
X
X          if (gs.fAlt ? x > y : x < y) {
X            if (grid->n[i][j])
X              sprintf(sz, "%c%d %02d'", k != grid->v[i][j] ? (us.fAppSep ?
X                'a' : '-') : (us.fAppSep ? 's' : '+'), k/60, k%60);
X            else
X              sprintf(sz, "");
X
X          /* For the midpoint portion, print the degrees and minutes. */
X
X          } else if (gs.fAlt ? x < y : x > y)
X            sprintf(sz, "%2d %02d'", k/60, k%60);
X
X          /* For the main diagonal, print degree and sign of each planet. */
X
X          else {
X            c = kSignB(grid->n[i][j]);
X            sprintf(sz, "%c%c%c %02d", chSig3(grid->n[i][j]), k);
X          }
X          DrawColor(c);
X          DrawSz(sz, x*unit-unit/2, y*unit-3*gi.nScaleT, dtBottom);
X        }
X      }
X    }
X  }
}
X
X
/* Draw the local horizon, and draw in the planets where they are at the */
/* time in question, as done when the -Z is combined with the -X switch. */
X
void XChartHorizon()
{
X  real lat, lonz[objMax], latz[objMax], azi[objMax], alt[objMax];
X  int x[objMax], y[objMax], m[objMax], n[objMax],
X    cx, cy, unit, x1, y1, x2, y2, xs, ys, i, j, k, l;
X  char sz[2];
X
X  unit = Max(12, 6*gi.nScale);
X  x1 = unit; y1 = unit; x2 = gs.xWin-1-unit; y2 = gs.yWin-1-unit;
X  unit = 12*gi.nScale;
X  xs = x2-x1; ys = y2-y1; cx = (x1+x2)/2; cy = (y1+y2)/2;
X
X  /* Make a slightly smaller rectangle within the window to draw the planets */
X  /* in. Make segments on all four edges marking 5 degree increments.        */
X
X  DrawColor(gi.kiLite);
X  for (i = 5; i < 180; i += 5) {
X    j = y1+(int)((real)i*(real)ys/rDegHalf);
X    k = (2+(i%10 == 0)+2*(i%30 == 0))*gi.nScaleT;
X    DrawLine(x1+1, j, x1+1+k, j);
X    DrawLine(x2-1, j, x2-1-k, j);
X  }
X  sz[1] = chNull;
X  for (i = 5; i < nDegMax; i += 5) {
X    j = x1+(int)((real)i*(real)xs/rDegMax);
X    k = (2+(i%10 == 0)+2*(i%30 == 0))*gi.nScaleT;
X    DrawLine(j, y1+1, j, y1+1+k);
X    DrawLine(j, y2-1, j, y2-1-k);
X    if (i % 90 == 0) {
X      *sz = *szDir[i/90 & 3];
X      DrawSz(sz, j, y1-2*gi.nScaleT, dtBottom);
X    }
X  }
X
X  /* Draw vertical lines dividing our rectangle into four areas. In our     */
X  /* local space chart, the middle line represents due south, the left line */
X  /* due east, the right line due west, and the edges due north. A fourth   */
X  /* horizontal line divides that which is above and below the horizon.     */
X
X  DrawColor(gi.kiGray);
X  DrawDash(cx, y1, cx, y2, 1);
X  DrawDash((cx+x1)/2, y1, (cx+x1)/2, y2, 1);
X  DrawDash((cx+x2)/2, y1, (cx+x2)/2, y2, 1);
X  DrawColor(gi.kiOn);
X  DrawEdge(x1, y1, x2, y2);
X  DrawDash(x1, cy, x2, cy, 1);
X
X  /* Calculate the local horizon coordinates of each planet. First convert */
X  /* zodiac position and declination to zenith longitude and latitude.     */
X
X  lat = RFromD(Lat);
X  for (i = 0; i <= cObj; i++) if (!ignore[i] || i == oMC) {
X    lonz[i] = RFromD(Tropical(planet[i])); latz[i] = RFromD(planetalt[i]);
X    EclToEqu(&lonz[i], &latz[i]);
X  }
X  for (i = 0; i <= cObj; i++) if (FProper(i)) {
X    lonz[i] = RFromD(Mod(DFromR(lonz[oMC]-lonz[i]+rPiHalf)));
X    EquToLocal(&lonz[i], &latz[i], rPiHalf-lat);
X    azi[i] = rDegMax-DFromR(lonz[i]); alt[i] = DFromR(latz[i]);
X    x[i] = x1+(int)((real)xs*(Mod(rDegQuad-azi[i]))/rDegMax+rRound);
X    y[i] = y1+(int)((real)ys*(rDegQuad-alt[i])/rDegHalf+rRound);
X    m[i] = x[i]; n[i] = y[i]+unit/2;
X  }
X
X  /* As in the DrawGlobe() routine, we now determine where to draw the   */
X  /* glyphs in relation to the actual points, so that the glyphs aren't  */
X  /* drawn on top of each other if possible. Again, we assume that we'll */
X  /* put the glyph right under the point, unless there would be some     */
X  /* overlap and the above position is better off.                       */
X
X  for (i = 0; i <= cObj; i++) if (FProper(i)) {
X    k = l = gs.xWin+gs.yWin;
X    for (j = 1; j < i; j++) if (FProper(j)) {
X      k = Min(k, abs(m[i]-m[j])+abs(n[i]-n[j]));
X      l = Min(l, abs(m[i]-m[j])+abs(n[i]-unit-n[j]));
X    }
X    if (k < unit || l < unit)
X      if (k < l)
X        n[i] -= unit;
X  }
X  for (i = cObj; i >= 0; i--) if (FProper(i))    /* Draw planet's glyph. */
X    DrawObject(i, m[i], n[i]);
X  for (i = cObj; i >= 0; i--) if (FProper(i)) {
X    DrawColor(kObjB[i]);
X    if (!gs.fAlt || i > oNorm)
X      DrawPoint(x[i], y[i]);      /* Draw small or large dot */
X    else                          /* near glyph indicating   */
X      DrawSpot(x[i], y[i]);       /* exact local location.   */
X  }
}
X
X
/* Draw the local horizon, and draw in the planets where they are at the  */
/* time in question. This chart is done when the -Z0 is combined with the */
/* -X switch. This is an identical function to XChartHorizon(); however,  */
/* that routine's chart is entered on the horizon and meridian. Here we   */
/* center the chart around the center of the sky straight up from the     */
/* local horizon, with the horizon itself being an encompassing circle.   */
X
void XChartHorizonSky()
{
X  real lat, rx, ry, s, sqr2,
X    lonz[objMax], latz[objMax], azi[objMax], alt[objMax];
X  int x[objMax], y[objMax], m[objMax], n[objMax],
X    cx, cy, unit, x1, y1, x2, y2, xs, ys, i, j, k, l;
X
X  unit = Max(12, 6*gi.nScale);
X  x1 = unit; y1 = unit; x2 = gs.xWin-1-unit; y2 = gs.yWin-1-unit;
X  unit = 12*gi.nScale;
X  xs = x2-x1; ys = y2-y1; cx = (x1+x2)/2; cy = (y1+y2)/2;
X
X  /* Draw a circle in window to indicate horizon line, lines dividing   */
X  /* the window into quadrants to indicate n/s and w/e meridians, and   */
X  /* segments on these lines and the edges marking 5 degree increments. */
X
X  sqr2 = RSqr(2.0);
X  DrawColor(gi.kiGray);
X  DrawDash(cx, y1, cx, y2, 1);
X  DrawDash(x1, cy, x2, cy, 1);
X  DrawColor(gi.kiLite);
X  for (i = -125; i <= 125; i += 5) {
X    k = (2+(i/10*10 == i ? 1 : 0)+(i/30*30 == i ? 2 : 0))*gi.nScaleT;
X    s = 1.0/(rDegQuad*sqr2);
X    j = cy+(int)(s*ys/2*i);
X    DrawLine(cx-k, j, cx+k, j);
X    j = cx+(int)(s*xs/2*i);
X    DrawLine(j, cy-k, j, cy+k);
X  }
X  for (i = 5; i < 55; i += 5) {
X    k = (2+(i/10*10 == i ? 1 : 0)+(i/30*30 == i ? 2 : 0))*gi.nScaleT;
X    s = 1.0/(rDegHalf-rDegQuad*sqr2);
X    j = (int)(s*ys/2*i);
X    DrawLine(x1, y1+j, x1+k, y1+j);
X    DrawLine(x1, y2-j, x1+k, y2-j);
X    DrawLine(x2, y1+j, x2-k, y1+j);
X    DrawLine(x2, y2-j, x2-k, y2-j);
X    j = (int)(s*xs/2*i);
X    DrawLine(x1+j, y1, x1+j, y1+k);
X    DrawLine(x2-j, y1, x2-j, y1+k);
X    DrawLine(x1+j, y2, x1+j, y2-k);
X    DrawLine(x2-j, y2, x2-j, y2-k);
X  }
X  DrawSz("N", cx, y1-2*gi.nScaleT, dtBottom);
X  DrawSz("E", x1/2, cy+2*gi.nScaleT, dtCent);
X  DrawSz("W", (gs.xWin+x2)/2, cy+2*gi.nScaleT, dtCent);
X  if (!gs.fText)
X    DrawSz("S", cx, gs.yWin-3*gi.nScaleT, dtBottom);
X  rx = xs/2/sqr2; ry = ys/2/sqr2;
X  DrawColor(gi.kiOn);
X  DrawEdge(x1, y1, x2, y2);
X  DrawCircle(cx, cy, (int)rx, (int)ry);
X  for (i = 0; i < nDegMax; i += 5) {
X    k = (2+(i/10*10 == i ? 1 : 0)+(i/30*30 == i ? 2 : 0))*gi.nScaleT;
X    DrawLine(cx+(int)((rx-k)*RCosD((real)i)), cy+(int)((ry-k)*RSinD((real)i)),
X      cx+(int)((rx+k)*RCosD((real)i)), cy+(int)((ry+k)*RSinD((real)i)));
X  }
X
X  /* Calculate the local horizon coordinates of each planet. First convert */
X  /* zodiac position and declination to zenith longitude and latitude.     */
X
X  lat = RFromD(Lat);
X  for (i = 0; i <= cObj; i++) if (!ignore[i] || i == oMC) {
X    lonz[i] = RFromD(Tropical(planet[i])); latz[i] = RFromD(planetalt[i]);
X    EclToEqu(&lonz[i], &latz[i]);
X  }
X  for (i = 0; i <= cObj; i++) if (FProper(i)) {
X    lonz[i] = RFromD(Mod(DFromR(lonz[oMC]-lonz[i]+rPiHalf)));
X    EquToLocal(&lonz[i], &latz[i], rPiHalf-lat);
X    azi[i] = rDegMax-DFromR(lonz[i]); alt[i] = rDegQuad-DFromR(latz[i]);
X    s = alt[i]/rDegQuad;
X    x[i] = cx+(int)(rx*s*RCosD(rDegHalf+azi[i])+rRound);
X    y[i] = cy+(int)(ry*s*RSinD(rDegHalf+azi[i])+rRound);
X    if (!FOnWin(x[i], y[i]))
X      x[i] = -1000;
X    m[i] = x[i]; n[i] = y[i]+unit/2;
X  }
X
X  /* As in the DrawGlobe() routine, we now determine where to draw the   */
X  /* glyphs in relation to the actual points, so that the glyphs aren't  */
X  /* drawn on top of each other if possible. Again, we assume that we'll */
X  /* put the glyph right under the point, unless there would be some     */
X  /* overlap and the above position is better off.                       */
X
X  for (i = 0; i <= cObj; i++) if (FProper(i)) {
X    k = l = gs.xWin+gs.yWin;
X    for (j = 0; j < i; j++) if (FProper(j)) {
X      k = Min(k, abs(m[i]-m[j])+abs(n[i]-n[j]));
X      l = Min(l, abs(m[i]-m[j])+abs(n[i]-unit-n[j]));
X    }
X    if (k < unit || l < unit)
X      if (k < l)
X        n[i] -= unit;
X  }
X  for (i = cObj; i >= 0; i--) if (m[i] >= x1 && FProper(i))  /* Draw glyph. */
X    DrawObject(i, m[i], n[i]);
X  for (i = cObj; i >= 0; i--) if (x[i] >= y1 && FProper(i)) {
X    DrawColor(kObjB[i]);
X    if (!gs.fAlt || i > oNorm)
X      DrawPoint(x[i], y[i]);      /* Draw small or large dot */
X    else                          /* near glyph indicating   */
X      DrawSpot(x[i], y[i]);       /* exact local location.   */
X  }
}
X
X
/* Draw a chart depicting an aerial view of the solar system in space, with */
/* all the planets drawn around the Sun, and the specified central planet   */
/* in the middle, as done when the -S is combined with the -X switch.       */
X
void XChartOrbit()
{
X  int x[objMax], y[objMax], m[objMax], n[objMax],
X    cx = gs.xWin / 2, cy = gs.yWin / 2, unit, x1, y1, x2, y2, i, j, k, l;
X  real sx, sy, sz = 30.0, xp, yp, a;
X
X  unit = Max(gs.fText*12, 6*gi.nScale);
X  x1 = unit; y1 = unit; x2 = gs.xWin-1-unit; y2 = gs.yWin-1-unit;
X  unit = 12*gi.nScale;
X
X  /* Determine the scale of the chart. For a scale size of 400+, make the */
X  /* graphic 1 AU in radius (just out to Earth's orbit). For 300, make    */
X  /* the chart 6 AU in radius (enough for inner planets out to asteroid   */
X  /* belt). For a scale of 200, make window 30 AU in radius (enough for   */
X  /* planets out to Neptune). For scale of 100, make it 90 AU in radius   */
X  /* (enough for all planets including the orbits of the uranians.)       */
X
X  if (gi.nScale/gi.nScaleT < 2)
X    sz = 90.0;
X  else if (gi.nScale/gi.nScaleT == 3)
X    sz = 6.0;
X  else if (gi.nScale/gi.nScaleT > 3)
X    sz = 1.0;
X  sx = (real)(cx-x1)/sz; sy = (real)(cy-y1)/sz;
X  for (i = 0; i <= oNorm; i++) if (FProper(i)) {
X    xp = spacex[i]; yp = spacey[i];
X    x[i] = cx-(int)(xp*sx); y[i] = cy+(int)(yp*sy);
X    m[i] = x[i]; n[i] = y[i]+unit/2;
X  }
X
X  /* As in the DrawGlobe() routine, we now determine where to draw the   */
X  /* glyphs in relation to the actual points, so that the glyphs aren't  */
X  /* drawn on top of each other if possible. Again, we assume that we'll */
X  /* put the glyph right under the point, unless there would be some     */
X  /* overlap and the above position is better off.                       */
X
X  for (i = 0; i <= oNorm; i++) if (FProper(i)) {
X    k = l = gs.xWin+gs.yWin;
X    for (j = 0; j < i; j++) if (FProper(j)) {
X      k = Min(k, abs(m[i]-m[j])+abs(n[i]-n[j]));
X      l = Min(l, abs(m[i]-m[j])+abs(n[i]-unit-n[j]));
X    }
X    if (k < unit || l < unit)
X      if (k < l)
X        n[i] -= unit;
X  }
X
X  /* Draw the 12 sign boundaries from the center body to edges of screen. */
X
X  a = Mod(DFromR(Angle(spacex[oJup], spacey[oJup]))-planet[oJup]);
X  DrawColor(gi.kiGray);
X  for (i = 0; i < cSign; i++) {
X    k = cx+2*(int)((real)cx*RCosD((real)i*30.0+a));
X    l = cy+2*(int)((real)cy*RSinD((real)i*30.0+a));
X    DrawClip(cx, cy, k, l, x1, y1, x2, y2, 1);
X  }
X  DrawColor(gi.kiLite);
X  DrawEdge(x1, y1, x2, y2);
X  for (i = oNorm; i >= 0; i--)
X    if (FProper(i) && FInRect(m[i], n[i], x1, y1, x2, y2))
X      DrawObject(i, m[i], n[i]);
X  for (i = oNorm; i >= 0; i--)
X    if (FProper(i) && FInRect(x[i], y[i], x1, y1, x2, y2)) {
X      DrawColor(kObjB[i]);
X      if (!gs.fAlt || i > oNorm)
X        DrawPoint(x[i], y[i]);      /* Draw small or large dot */
X      else                          /* near glyph indicating   */
X        DrawSpot(x[i], y[i]);       /* exact orbital location. */
X    }
}
X
X
/* Draw a chart showing the 36 Gauquelin sectors, with all the planets    */
/* positioned in their appropriate sector (and at the correct fracton     */
/* across the sector) as done when the -l is combined with the -X switch. */
X
void XChartSector()
{
X  real xplanet[objMax], symbol[objMax];
X  char sz[3];
X  int cx, cy, i, j, k;
X  real unitx, unity, px, py, temp;
X
X  if (gs.fText && !us.fVelocity)
X    gs.xWin -= xSideT;
X  cx = gs.xWin/2 - 1; cy = gs.yWin/2 - 1;
X  unitx = (real)cx; unity = (real)cy;
X
X  /* Draw lines across the whole chart at the four angles. */
X
X  DrawColor(gi.kiLite);
X  DrawDash(cx+POINT1(unitx, 0.99, PX(0.0)),
X           cy+POINT1(unity, 0.99, PY(0.0)),
X           cx+POINT1(unitx, 0.99, PX(180.0)),
X           cy+POINT1(unity, 0.99, PY(180.0)), !gs.fColor);
X  DrawDash(cx+POINT1(unitx, 0.99, PX(90.0)),
X           cy+POINT1(unity, 0.99, PY(90.0)),
X           cx+POINT1(unitx, 0.99, PX(270.0)),
X           cy+POINT1(unity, 0.99, PY(270.0)), !gs.fColor);
X
X  /* Draw circles and radial lines delineating the 36 sectors. */
X
X  DrawColor(gi.kiOn);
X  for (i = 0; i < nDegMax; i += 10) {
X    px = PX((real)i); py = PY((real)i);
X    DrawLine(cx+POINT1(unitx, 0.81, px), cy+POINT1(unity, 0.81, py),
X      cx+POINT2(unitx, 0.95, px), cy+POINT2(unity, 0.95, py));
X  }
X  DrawCircle(cx, cy, (int)(unitx*0.95+rRound), (int)(unity*0.95+rRound));
X  DrawCircle(cx, cy, (int)(unitx*0.81+rRound), (int)(unity*0.81+rRound));
X
X  /* Label the 36 sectors, with plus zones in red and normal in dark green. */
X
X  k = pluszone[cSector];
X  for (i = 1; i <= cSector; i++) {
X    j = pluszone[i];
X    DrawColor(j ? kRainbowB[1] : kMainB[5]);
X    sprintf(sz, "%d", i);
X    DrawSz(sz, cx+POINT1(unitx, 0.88, PX((real)(i*10+175)))+
X      (FBetween(i, 12, 19) ? -(gi.nScale/* *gi.nScaleT*/) : 0),
X      cy+POINT1(unity, 0.88, PY((real)(i*10+175)))+(gi.nScale/* *gi.nScaleT*/),
X      dtCent | dtScale);
X    sprintf(sz, "%c", j ? '+' : '-');
X    DrawSz(sz, cx+POINT1(unitx, 0.97, PX((real)(i*10+175))),
X      cy+POINT1(unity, 0.97, PY((real)(i*10+175)))+gi.nScaleT*2, dtCent);
X    if (j != k) {
X      DrawColor(gi.kiGray);
X      DrawDash(cx, cy, cx+POINT2(unitx, 0.81, PX((real)(i*10+170))),
X        cy+POINT2(unity, 0.81, PY((real)(i*10+170))), 1);
X    }
X    k = j;
X  }
X
X  if (!gs.fAlt && !FCreateGrid(fFalse))
X      return;
X  CastSectors();    /* Go compute the planets' sector positions. */
X
X  for (i = 0; i <= cObj; i++)    /* Figure out where to put planet glyphs. */
X    symbol[i] = xplanet[i] = Mod(rDegHalf - planet[i]);
X  FillSymbolRing(symbol, 1.0);
X
X  /* For each planet, draw a small dot indicating where it is, and then */
X  /* a line from that point to the planet's glyph.                      */
X
X  for (i = cObj; i >= 0; i--) if (FProper(i)) {
X    if (gs.fLabel) {
X      temp = symbol[i];
X      DrawColor(ret[i] < 0.0 ? gi.kiGray : gi.kiOn);
X      DrawDash(cx+POINT1(unitx, 0.67, PX(xplanet[i])),
X        cy+POINT1(unity, 0.67, PY(xplanet[i])),
X        cx+POINT1(unitx, 0.71, PX(temp)),
X        cy+POINT1(unity, 0.71, PY(temp)),
X        (ret[i] < 0.0 ? 1 : 0) - gs.fColor);
X      DrawObject(i, cx+POINT1(unitx, 0.75, PX(temp)),
X        cy+POINT1(unity, 0.75, PY(temp)));
X    } else
X      DrawColor(kObjB[i]);
X    DrawPoint(cx+POINT1(unitx, 0.65, PX(xplanet[i])),
X      cy+POINT1(unity, 0.65, PY(xplanet[i])));
X  }
X
X  /* Draw lines connecting planets which have aspects between them. */
X
X  if (!gs.fAlt) {                  /* Don't draw aspects in bonus mode. */
X    for (j = cObj; j >= 1; j--)
X      for (i = j-1; i >= 0; i--)
X        if (grid->n[i][j] && FProper(i) && FProper(j)) {
X          DrawColor(kAspB[grid->n[i][j]]);
X          DrawDash(cx+POINT1(unitx, 0.63, PX(xplanet[i])),
X            cy+POINT1(unity, 0.63, PY(xplanet[i])),
X            cx+POINT1(unitx, 0.63, PX(xplanet[j])),
X            cy+POINT1(unity, 0.63, PY(xplanet[j])),
X            abs(grid->v[i][j]/60/2));
X        }
X  }
X
X  DrawInfo();
X  CastChart(fTrue);
}
X
X
/* Draw an arrow from one point to another, a line with an arrowhead at the */
/* ending point. The size of the arrowhead is based on current scale size,  */
/* and the line segment is actually shorter and doesn't touch either        */
/* endpoint by the same amount. This is used by XChartDispositor() below.   */
X
void DrawArrow(x1, y1, x2, y2)
int x1, y1, x2, y2;
{
X  real r, s, a;
X
X  r = DFromR(Angle((real)(x2-x1), (real)(y2-y1)));
X  s = (real)(gi.nScale*8);
X  x1 += (int)(s*RCosD(r)); y1 += (int)(s*RSinD(r));    /* Shrink line by    */
X  x2 -= (int)(s*RCosD(r)); y2 -= (int)(s*RSinD(r));    /* the scale amount. */
X  s = (real)(gi.nScale)*4.5;
X  DrawLine(x1, y1, x2, y2);                            /* Main segment. */
X  for (a = -1.0; a <= 1.0; a += 2.0)
X    DrawLine(x2, y2, x2 + (int)(s*RCosD(r + a*135.0)), /* The two arrow     */
X      y2 + (int)(s*RSinD(r + a*135.0)));               /* head line pieces. */
}
X
X
/* Draw dispositor graphs for the 10 main planets, as done when the -j is   */
/* combined with the -X switch. Four graphs are drawn, one in each screen   */
/* quadrant. A dispositor graph may be based on the sign or house position, */
/* and the planets may be arranged in a hierarchy or a wheel format.        */
X
void XChartDispositor()
{
X  int oDis[oMain+1], dLev[oMain+1], cLev[oMain+1], xo[oMain+1], yo[oMain+1];
X  real xCirc[oMain+1], yCirc[oMain+1];
X  char sz[cchSzDef];
X  int xLev, yLev, xSub, ySub, cx0, cy0, cx, cy, i, j, k;
X
X  /* Set up screen positions of the 10 planets for the wheel graphs. */
X
X  cx0 = gs.xWin / 2; cy0 = gs.yWin / 2;
X  for (i = 1; i <= oMain; i++) {
X    if ((j = (180-(i-1)*360/oMain)) < 0)
X      j += nDegMax;
X    xCirc[i] = (real)cx0*0.4*RCosD((real)j);
X    yCirc[i] = (real)cy0*0.4*RSinD((real)j);
X  }
X
X  /* Loop over the two basic dispositor types: sign based and house based. */
X
X  for (xSub = 0; xSub <= 1; xSub++) {
X    cx = xSub * cx0 + cx0 / 2;
X
X    /* For each planet, get its dispositor planet for current graph type. */
X
X    for (i = 1; i <= oMain; i++) {
X      oDis[i] = rules[xSub ? inhouse[i] : SFromZ(planet[i])];
X      dLev[i] = 1;
X    }
X
X    /* Determine the final dispositors (including mutual reception loops). */
X
X    do {
X      j = fFalse;
X      for (i = 1; i <= oMain; i++)
X        cLev[i] = fFalse;
X      for (i = 1; i <= oMain; i++)
X        if (dLev[i])
X          cLev[oDis[i]] = fTrue;
X      for (i = 1; i <= oMain; i++)    /* A planet isn't a final dispositor */
X        if (dLev[i] && !cLev[i]) {    /* if nobody is pointing to it.      */
X          dLev[i] = 0;
X          j = fTrue;
X        }
X    } while (j);
X
X    /* Determine the level of each planet, i.e. how many times you have to */
X    /* jump to your dispositor before reaching a final, with finals == 1.  */
X
X    do {
X      j = fFalse;
X      for (i = 1; i <= oMain; i++)
X        if (!dLev[i]) {
X          if (!dLev[oDis[i]])
X            j = fTrue;
X          else                              /* If my dispositor already has */
X            dLev[i] = dLev[oDis[i]] + 1;    /* a level, mine is one more.   */
X        }
X    } while (j);
X
X    /* Count the number of planets at each dispositor level. */
X
X    for (i = 1; i <= oMain; i++)
X      cLev[i] = 0;
X    for (i = 1; i <= oMain; i++)
X      cLev[dLev[i]]++;
X
X    /* Count the number of levels total, and max planets on any one level. */
X
X    xLev = yLev = 0;
X    for (i = 1; i <= oMain; i++)
X      if (cLev[i]) {
X        yLev = i;
X        if (cLev[i] > xLev)
X          xLev = cLev[i];
X      }
X
X    /* Loop over our two dispositor display formats: hierarchy and wheel. */
X
X    for (ySub = 0; ySub <= 1; ySub++) {
X      cy = ySub * cy0 + cy0 / 2;
X      sprintf(sz, "%s dispositor %s.", xSub ? "House" : "Sign",
X        ySub ? "wheel" : "hierarchy");
X      DrawColor(gi.kiLite);
X      DrawSz(sz, cx, ySub * cy0 + 3*gi.nScaleT, dtTop);
X
X      if (ySub) {
X
X        /* Draw a graph in wheel format. */
X
X        for (i = 1; i <= oMain; i++) {
X          DrawObject(i, cx + (int)xCirc[i], cy + (int)yCirc[i]);
X          j = oDis[i];
X          if (j != i) {
X            if (dLev[i] < 2)
X              DrawColor(gi.kiOn);
X            else
X              DrawColor(kObjB[i]);
X            DrawArrow(cx + (int)xCirc[i], cy + (int)yCirc[i],
X              cx + (int)xCirc[j], cy + (int)yCirc[j]);
X          }
X          if (!gs.fAlt && (j == i || dLev[i] < 2)) {
X            DrawColor(j == i ? gi.kiOn : gi.kiGray);
X            DrawCircle(cx + (int)xCirc[i], cy + (int)yCirc[i],
X              7*gi.nScale, 7*gi.nScale);
X          }
X        }
X      } else {
X
X        /* For level hierarchies, first figure out the screen coordinates    */
X        /* for each planet, based on its level, total levels, and max width. */
X
X        for (i = 1; i <= oMain; i++) {
X          yo[i] = cy0*(dLev[i]*2-1)/(yLev*2);
X          k = 0;
X          for (j = 1; j < i; j++)
X            if (dLev[i] == dLev[j])
X              k = j;
X          if (k)
X            xo[i] = xo[k] + cx0/xLev;    /* One right of last one on level. */
X          else
X            xo[i] = cx - ((cx0/xLev)*(cLev[dLev[i]]-1)/2);
X        }
X
X        /* Draw graph in level hierarchy format. */
X
X        for (i = 1; i <= oMain; i++) {
X          DrawObject(i, xo[i], yo[i]);
X          j = oDis[i];
X          if (j != i) {
X            if (dLev[i] < 2) {
X              if (abs(xo[i] - xo[j]) < cx0/xLev*3/2) {
X                DrawColor(gi.kiOn);
X                DrawArrow(xo[i], yo[i], xo[j], yo[j]);
X              }
X              DrawColor(gi.kiGray);
X            } else {
X              DrawColor(kObjB[i]);
X              DrawArrow(xo[i], yo[i], xo[j], yo[j]);
X            }
X          } else
X            DrawColor(gi.kiOn);
X          if (!gs.fAlt && dLev[i] < 2)
X            DrawCircle(xo[i], yo[i], 7*gi.nScale, 7*gi.nScale);
X        }
X      }
X    }
X  }
X
X  /* Draw boundary lines between the four separate dispositor graphs. */
X
X  if (gs.fBorder) {
X    DrawColor(gi.kiLite);
X    DrawBlock(cx0, 0, cx0, gs.yWin);
X    DrawBlock(0, cy0, gs.xWin, cy0);
X  }
}
X
X
/* Draw a graphical calendar for a given month, with numbers in boxes,  */
/* scaled to fit within the given bounds. This is used for single month */
/* -K switch images and is called 12 times for a full year -Ky image.   */
X
void DrawCalendar(mon, X1, Y1, X2, Y2)
int mon, X1, Y1, X2, Y2;
{
X  char sz[cchSzDef];
X  int day, cday, dayHi, cweek, xunit, yunit, xs, ys, x1, y1, x, y, s;
X
X  xs = X2 - X1; ys = Y2 - Y1;
X  day = DayOfWeek(mon, 1, Yea);    /* Day of week of 1st of month.     */
X  cday = DaysInMonth(mon, Yea);    /* Count of days in the month.      */
X  dayHi = DayInMonth(mon, Yea);    /* Number of last day in the month. */
X  cweek = us.fCalendarYear ? 6 : (day + cday + 6) / 7;   /* Week rows. */
X  xunit = xs/8;                    /* Hor. pixel size of each day box. */
X  yunit = ys/(cweek+2);            /* Ver. pixel size of each day box. */
X  x1 = X1 + (xs - xunit*7) / 2;    /* Blank space to left of calendar. */
X  y1 = Y1 + yunit*3/2;             /* Blank space to top of calendar.  */
X
X  /* Print the month and year in big letters at top of chart. */
X
X  DrawColor(gi.kiOn);
X  sprintf(sz, "%s, %d", szMonth[mon], Yea);
X  s = gi.nScale;
X  gi.nScale = Min((yunit*3/2-yFont*s) / yFont, xs/9/*CchSz(sz)*/ / xFont);
X  gi.nScale = Max(gi.nScale-1, 1);
X  DrawSz(sz, X1 + xs/2, Y1 + (yunit*3/2-yFont*s)/2, dtCent | dtScale);
X  gi.nScale = s;
X
X  /* Draw the grid of boxes for the days. */
X
X  for (x = 0; x <= cWeek; x++) {
X
X    /* Print days of week at top of each column (abbreviated if need be). */
X
X    if (x < cWeek) {
X      if (xunit / (xFont*gi.nScale) < 9)
X        sprintf(sz, "%c%c%c", chDay3(x));
X      else
X        sprintf(sz, "%s", szDay[x]);
X      DrawColor(kRainbowB[3]);
X      DrawSz(sz, x1 + x*xunit + xunit/2, y1 - s*3, dtBottom | dtScale);
X      DrawColor(kRainbowB[5]);
X    }
X    DrawLine(x1 + x*xunit, y1, x1 + x*xunit, y1 + cweek*yunit);
X  }
X  for (y = 0; y <= cweek; y++)
X    DrawLine(x1, y1 + y*yunit, x1 + 7*xunit, y1 + y*yunit);
X
X  /* Actually draw the day numbers in their appropriate boxes. */
X
X  x = day; y = 0;
X  for (day = 1; day <= dayHi; day = AddDay(mon, day, Yea, 1)) {
X    sprintf(sz, gs.fText ? "%2d" : "%d", day);
X    DrawColor(day == Day && mon == Mon && gs.fLabel ? kRainbowB[4] :
X      (x <= 0 || x >= cWeek-1 ? kRainbowB[1] : gi.kiLite));
X    if (!gs.fAlt)
X      DrawSz(sz, x1 + x*xunit + s*2, y1 + y*yunit + s*4,
X        dtLeft | dtTop | dtScale);
X    else
X      DrawSz(sz, x1 + x*xunit + xunit/2,
X        y1 + y*yunit + yunit/2 + gi.nScale, dtCent | dtScale);
X    if (++x >= cWeek) {
X      x = 0;
X      y++;
X    }
X  }
}
X
X
/* Draw a graphical calendar on the screen for the chart month or entire */
/* year, as done when the -K or -Ky is combined with the -X switch.      */
X
void XChartCalendar()
{
X  int xs, ys, xunit, yunit, x1, y1, x, y;
X
X  if (!us.fCalendarYear) {
X    DrawCalendar(Mon, 0, 0, gs.xWin, gs.yWin);
X    return;
X  }
X
X  /* Determine the best sized rectangle of months to draw the year in based */
X  /* on the chart dimensions: Either do 6x2 months, or 4x3, 3x4, or 2x6.    */
X
X  if (gs.xWin > gs.yWin) {
X    if (gs.xWin > gs.yWin * 3) {
X      xs = 6; ys = 2;
X    } else {
X      xs = 4; ys = 3;
X    }
X  } else {
X    if (gs.yWin > gs.xWin * 2) {
X      xs = 2; ys = 6;
X    } else {
X      xs = 3; ys = 4;
X    }
X  }
X  xunit = gs.xWin / xs; yunit = gs.yWin / ys;
X  x1 = (gs.xWin - xunit*xs) / 2;
X  y1 = (gs.yWin - yunit*ys) / 2;
X  for (y = 0; y < ys; y++)
X    for (x = 0; x < xs; x++) {
X      DrawCalendar(y * xs + x + 1, x1 + x*xunit, y1 + y*yunit,
X        x1 + (x+1)*xunit, y1 + (y+1)*yunit);
X    }
}
#endif /* GRAPH */
X
/* xcharts1.c */
SHAR_EOF
  $shar_touch -am 1223232998 'xcharts1.c' &&
  chmod 0644 'xcharts1.c' ||
  echo 'restore of xcharts1.c failed'
  shar_count="`wc -c < 'xcharts1.c'`"
  test 40811 -eq "$shar_count" ||
    echo "xcharts1.c: original size 40811, current size $shar_count"
fi
# ============= xcharts2.c ==============
if test -f 'xcharts2.c' && test X"$1" != X"-c"; then
  echo 'x - skipping xcharts2.c (File already exists)'
else
  echo 'x - extracting xcharts2.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'xcharts2.c' &&
/*
** Astrolog (Version 5.40) File: xcharts2.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
#ifdef GRAPH
/*
******************************************************************************
** Chart Graphics Utility Procedures.
******************************************************************************
*/
X
/* Return whether the specified object should be displayed in the current */
/* graphics chart type. For example, don't include the Moon in the solar  */
/* system charts when Placalc is off, don't include house cusps in        */
/* astro-graph charts, and so on, in addition to checking restrictions.   */
X
bool FProper(i)
int i;
{
X  bool f;
X
X  f = !ignore[i] && (gi.nMode == gOrbit || i != us.objCenter);
X  if (gi.nMode == gHorizon || fMap || gi.nMode == gGlobe ||
X    gi.nMode == gPolar)                      /* Horizon and map charts */
X    f &= FObject(i);
X  else if (gi.nMode == gOrbit)               /* Solar system charts */
X    f &= FObject(i) && (i != oMoo || us.fPlacalc);
X  else if (gi.nMode == gSector || gi.nMode == gEphemeris)
X    f &= FThing(i);                          /* Sector amd ephemeris charts */
X  return f;
}
X
X
/* Adjust an array of zodiac positions so that no two positions are within   */
/* a certain orb of each other. This is used by the wheel drawing chart      */
/* routines in order to make sure that we don't draw any planet glyphs on    */
/* top of each other. We'll later draw the glyphs at the adjusted positions. */
X
void FillSymbolRing(symbol, factor)
real *symbol;
real factor;
{
X  real orb = DEFORB*256.0/(real)gs.yWin*(real)gi.nScale*factor, k1, k2, temp;
X  int i, j, k = 1, l;
X
X  /* Keep adjusting as long as we can still make changes, or until we do 'n' */
X  /* rounds. (With many objects, there just may not be enough room for all.) */
X
X  for (l = 0; k && l < us.nDivision*2; l++) {
X    k = 0;
X    for (i = 0; i <= cObj; i++) if (FProper(i)) {
X
X      /* For each object, determine who is closest on either side. */
X
X      k1 = rLarge; k2 = -rLarge;
X      for (j = 0; j <= cObj; j++)
X        if (FProper(j) && i != j) {
X          temp = symbol[j]-symbol[i];
X          if (RAbs(temp) > rDegHalf)
X            temp -= rDegMax*RSgn(temp);
X          if (temp < k1 && temp > 0.0)
X            k1 = temp;
X          else if (temp > k2 && temp <= 0.0)
X            k2 = temp;
X        }
X
X      /* If an object's too close on one side, then we move to the other. */
X
X      if (k2 > -orb && k1 > orb) {
X        k = 1; symbol[i] = Mod(symbol[i]+orb*0.51+k2*0.49);
X      } else if (k1 < orb && k2 < -orb) {
X        k = 1; symbol[i] = Mod(symbol[i]-orb*0.51+k1*0.49);
X
X      /* If we are bracketed by close objects on both sides, then let's move */
X      /* to the midpoint, so we are as far away as possible from either one. */
X
X      } else if (k2 > -orb && k1 < orb) {
X        k = 1; symbol[i] = Mod(symbol[i]+(k1+k2)*0.5);
X      }
X    }
X  }
}
X
X
/* Adjust an array of longitude positions so that no two are within a    */
/* certain orb of each other. This is used by the astro-graph routine to */
/* make sure we don't draw any planet glyphs marking the lines on top of */
/* each other. This is almost identical to the FillSymbolRing() routine  */
/* used by the wheel charts; however, there the glyphs are placed in a   */
/* continuous ring, while here we have the left and right screen edges.  */
/* Also, here we are placing two sets of planets at the same time.       */
X
void FillSymbolLine(symbol)
real *symbol;
{
X  real orb = DEFORB*1.35*(real)gi.nScale, max = rDegMax, k1, k2, temp;
X  int i, j, k = 1, l;
X
X  if (gi.nMode != gEphemeris)
X    max *= (real)gi.nScale;
X  else
X    orb *= rDegMax/(real)gs.xWin;
X
X  /* Keep adjusting as long as we can still make changes. */
X
X  for (l = 0; k && l < us.nDivision*2; l++) {
X    k = 0;
X    for (i = 1; i <= cObj*2; i++)
X      if (FProper((i+1)/2) && symbol[i] >= 0.0) {
X
X        /* For each object, determine who is closest to the left and right. */
X
X        k1 = max-symbol[i]; k2 = -symbol[i];
X        for (j = 1; j <= cObj*2; j++) {
X          if (FProper((j+1)/2) && i != j) {
X            temp = symbol[j]-symbol[i];
X            if (temp < k1 && temp > 0.0)
X              k1 = temp;
X            else if (temp > k2 && temp <= 0.0)
X              k2 = temp;
X          }
X        }
X
X        /* If an object's too close on one side, then we move to the other. */
X
X        if (k2 > -orb && k1 > orb) {
X          k = 1; symbol[i] = symbol[i]+orb*0.51+k2*0.49;
X        } else if (k1 < orb && k2 < -orb) {
X          k = 1; symbol[i] = symbol[i]-orb*0.51+k1*0.49;
X        } else if (k2 > -orb && k1 < orb) {
X          k = 1; symbol[i] = symbol[i]+(k1+k2)*0.5;
X        }
X      }
X  }
}
X
X
/* Given a zodiac position, return the degree on the current wheel chart */
/* circle where that position falls, rotating based on the Ascendant and */
/* adding in the opposite direction for Vedic mode wheels.               */
X
real PlaceInX(deg)
real deg;
{
X  if (us.fVedic)
X    deg = -chouse[1]*(gi.nMode != gWheel)*2.0-deg-60.0;
X  return Mod(rDegHalf-deg+gi.rAsc);
}
X
X
/* Given a zodiac degree, adjust it if need be to account for the expanding */
/* and compacting of parts the zodiac that happen when we display a graphic */
/* wheel chart such that all the houses appear the same size.               */
X
real HousePlaceInX(deg)
real deg;
{
X  int in;
X
X  if (gi.nMode == gWheel)    /* We only adjust for the -w -X combination. */
X    return deg;
X  in = HousePlaceIn(deg);
X  return Mod(ZFromS(in)+MinDistance(chouse[in], deg)/
X    MinDistance(chouse[in], chouse[Mod12(in+1)])*30.0);
}
X
X
/*
******************************************************************************
** Multiple Chart Graphics Routines.
******************************************************************************
*/
X
/* Draw another wheel chart; however, this time we have two rings of planets */
/* because we are doing a relationship chart between two sets of data. This  */
/* chart is obtained when the -r0 is combined with the -X switch.            */
X
void XChartWheelRelation()
{
X  real xsign[cSign+1], xhouse1[cSign+1], xplanet1[objMax], xplanet2[objMax],
X    symbol[objMax];
X  byte ignoreT[objMax];
X  int cx, cy, i, j;
X  real unitx, unity, temp;
X  CI ciT;
X
X  /* Set up variables and temporarily automatically decrease the horizontal */
X  /* chart size to leave room for the sidebar if that mode is in effect.    */
X
X  if (gs.fText && !us.fVelocity)
X    gs.xWin -= xSideT;
X  cx = gs.xWin/2 - 1; cy = gs.yWin/2 - 1;
X  unitx = (real)cx; unity = (real)cy;
X  gi.rAsc = gs.objLeft ? cp1.obj[abs(gs.objLeft)]+rDegQuad*(gs.objLeft < 0) :
X    cp1.cusp[1];
X  if (us.fVedic)
X    gi.rAsc = gs.objLeft ? (gs.objLeft < 0 ? 120.0 : -60.0)-gi.rAsc : 0.0;
X
X  /* Fill out arrays with the degree of each object, cusp, and sign glyph. */
X
X  if (gi.nMode == gWheel) {
X    for (i = 1; i <= cSign; i++)
X      xhouse1[i] = PZ(cp1.cusp[i]);
X  } else {
X    gi.rAsc -= cp1.cusp[1];
X    for (i = 1; i <= cSign; i++)
X      xhouse1[i] = PZ(ZFromS(i));
X  }
X  for (i = 1; i <= cSign; i++)
X    xsign[i] = PZ(HousePlaceInX(ZFromS(i)));
X  for (i = 0; i <= cObj; i++)
X    xplanet1[i] = PZ(HousePlaceInX(cp1.obj[i]));
X  for (i = 0; i <= cObj; i++)
X    xplanet2[i] = PZ(HousePlaceInX(cp2.obj[i]));
X
X  /* Go draw the outer sign and house rings. We are drawing only the */
X  /* houses of one of the two charts in the relationship, however.   */
X
X  DrawWheel(xsign, xhouse1, cx, cy, unitx, unity, gi.rAsc,
X    0.70, 0.74, 0.78, 0.82, 0.885);
X
X  /* Draw the outer ring of planets (based on the planets in the chart     */
X  /* which the houses do not reflect - the houses belong to the inner ring */
X  /* below). Draw each glyph, a line from it to its actual position point  */
X  /* in the outer ring, and then draw another line from this point to a    */
X  /* another dot at the same position in the inner ring as well.           */
X
X  for (i = 0; i <= cObj; i++)
X    symbol[i] = xplanet2[i];
X  if (us.nRel == rcTransit)
X    for (i = 0; i <= cObj; i++) {
X      ignoreT[i] = ignore[i];
X      ignore[i] = ignore2[i];
X    }
X  FillSymbolRing(symbol, 1.0);
X  if (us.nRel == rcTransit)
X    for (i = 0; i <= cObj; i++)
X      ignore[i] = ignoreT[i];
X
X  for (i = cObj; i >= 0; i--) if (FProper2(i)) {
X    if (gs.fLabel) {
X      temp = symbol[i];
X      DrawColor(cp2.dir[i] < 0.0 ? gi.kiGray : gi.kiOn);
X      DrawDash(cx+POINT1(unitx, 0.58, PX(xplanet2[i])),
X        cy+POINT1(unity, 0.58, PY(xplanet2[i])),
X        cx+POINT2(unitx, 0.61, PX(temp)),
X        cy+POINT2(unity, 0.61, PY(temp)),
X        (cp2.dir[i] < 0.0 ? 1 : 0) - gs.fColor);
X      DrawObject(i, cx+POINT1(unitx, 0.65, PX(temp)),
X        cy+POINT1(unity, 0.65, PY(temp)));
X    }
X    DrawColor(kObjB[i]);
X    DrawPoint(cx+POINT1(unitx, 0.56, PX(xplanet2[i])),
X      cy+POINT1(unity, 0.56, PY(xplanet2[i])));
X    DrawPoint(cx+POINT1(unitx, 0.43, PX(xplanet2[i])),
X      cy+POINT1(unity, 0.43, PY(xplanet2[i])));
X    DrawColor(cp2.dir[i] < 0.0 ? gi.kiGray : gi.kiOn);
X    DrawDash(cx+POINT1(unitx, 0.45, PX(xplanet2[i])),
X      cy+POINT1(unity, 0.45, PY(xplanet2[i])),
X      cx+POINT2(unitx, 0.54, PX(xplanet2[i])),
X      cy+POINT2(unity, 0.54, PY(xplanet2[i])), 2-gs.fColor);
X  }
X
X  /* Now draw the inner ring of planets. If it weren't for the outer ring,  */
X  /* this would be just like the standard non-relationship wheel chart with */
X  /* only one set of planets. Again, draw glyph, and a line to true point.  */
X
X  for (i = 0; i <= cObj; i++)
X    symbol[i] = xplanet1[i];
X  FillSymbolRing(symbol, 1.1);
X  DrawSymbolRing(symbol, xplanet1, cp1.dir, cx, cy, unitx, unity,
X    0.43, 0.45, 0.48, 0.52);
X
X  /* Draw lines connecting planets between the two charts that have aspects. */
X
X  if (!gs.fAlt) {                      /* Don't draw aspects in bonus mode. */
X    if (!FCreateGridRelation(fFalse))
X      return;
X    for (j = cObj; j >= 0; j--)
X      for (i = cObj; i >= 0; i--)
X        if (grid->n[i][j] && FProper2(i) && FProper(j)) {
X          DrawColor(kAspB[grid->n[i][j]]);
X          DrawDash(cx+POINT1(unitx, 0.41, PX(xplanet1[j])),
X            cy+POINT1(unity, 0.41, PY(xplanet1[j])),
X            cx+POINT1(unitx, 0.41, PX(xplanet2[i])),
X            cy+POINT1(unity, 0.41, PY(xplanet2[i])),
X            abs(grid->v[i][j]/60/2));
X        }
X  }
X
X  /* Go draw sidebar with chart information and positions if need be. */
X
X  if (us.nRel == rcTransit) {
X    ciT = ciMain;
X    ciMain = ciTwin;
X  }
X  DrawInfo();
X  if (us.nRel == rcTransit)
X    ciMain = ciT;
}
X
X
/* Draw a tri-wheel chart or quad-wheel chart, where we have three or four */
/* rings, among three or four sets of data we're comparing. This chart is  */
/* obtained when the -r3 or -r4 switch is combined with the -X switch.     */
X
void XChartWheelThreeFour()
{
X  real xsign[cSign+1], xhouse1[cSign+1], xplanet1[objMax], xplanet2[objMax],
X    symbol[objMax];
X  int cx, cy, i, fQuad;
X  real unitx, unity, base;
X  CP cpT;
X
X  /* Set up variables and temporarily automatically decrease the horizontal */
X  /* chart size to leave room for the sidebar if that mode is in effect.    */
X
X  if (gs.fText && !us.fVelocity)
X    gs.xWin -= xSideT;
X  cx = gs.xWin/2 - 1; cy = gs.yWin/2 - 1;
X  unitx = (real)cx; unity = (real)cy;
X  gi.rAsc = gs.objLeft ? cp1.obj[abs(gs.objLeft)]+rDegQuad*(gs.objLeft < 0) :
X    cp1.cusp[1];
X  if (us.fVedic)
X    gi.rAsc = gs.objLeft ? (gs.objLeft < 0 ? 120.0 : -60.0)-gi.rAsc : 0.0;
X  fQuad = (us.nRel == rcQuadWheel);
X  base = (fQuad ? 0.22 : 0.35);
X
X  /* Fill out arrays with the degrees of the cusps and sign glyphs, and the */
X  /* positions of the outer two rings.                                      */
X
X  if (gi.nMode == gWheel) {
X    for (i = 1; i <= cSign; i++)
X      xhouse1[i] = PZ(cp1.cusp[i]);
X  } else {
X    gi.rAsc -= cp1.cusp[1];
X    for (i = 1; i <= cSign; i++)
X      xhouse1[i] = PZ(ZFromS(i));
X  }
X  for (i = 1; i <= cSign; i++)
X    xsign[i] = PZ(HousePlaceInX(ZFromS(i)));
X  for (i = 0; i <= cObj; i++)
X    xplanet1[i] = PZ(HousePlaceInX(cp1.obj[i]));
X  for (i = 0; i <= cObj; i++)
X    xplanet2[i] = PZ(HousePlaceInX(cp2.obj[i]));
X
X  /* Go draw the outer sign and house rings. We are drawing the houses */
X  /* of only the outermost ring of the wheel, however.                 */
X
X  DrawWheel(xsign, xhouse1, cx, cy, unitx, unity, gi.rAsc,
X    0.745, 0.78, 0.815, 0.84, 0.895);
X
X  /* Draw the outer ring of planets (i.e. the one the house cusps reflect). */
X  /* Draw each glyph, a line from it to its actual position point in the    */
X  /* outer ring, and then draw another line from this point to a another    */
X  /* dot at the same position on the innermost ring as well.                */
X
X  for (i = 0; i <= cObj; i++)
X    symbol[i] = xplanet1[i];
X  FillSymbolRing(symbol, 0.9);
X  DrawSymbolRing(symbol, xplanet1, ret, cx, cy, unitx, unity,
X    0.61, 0.63, 0.66, 0.70);
X  for (i = cObj; i >= 0; i--) if (FProper(i)) {
X    DrawColor(kObjB[i]);
X    DrawPoint(cx+POINT1(unitx, base, PX(xplanet1[i])),
X      cy+POINT1(unity, base, PY(xplanet1[i])));
X    if (gs.fAlt) {
X      DrawColor(ret[i] < 0.0 ? gi.kiGray : gi.kiOn);
X      DrawDash(cx+POINT1(unitx, base+0.02, PX(xplanet1[i])),
X        cy+POINT1(unity, base+0.02, PY(xplanet1[i])),
X        cx+POINT2(unitx, 0.59, PX(xplanet1[i])),
X        cy+POINT2(unity, 0.59, PY(xplanet1[i])), 3+fQuad-gs.fColor);
X    }
X  }
X
X  /* Now draw the second to outermost ring of planets. Again, draw each */
X  /* glyph, a line to its true point, and a line to the innermost ring. */
X
X  for (i = 0; i <= cObj; i++)
X    symbol[i] = xplanet2[i];
X  FillSymbolRing(symbol, 1.1);
X  DrawSymbolRing(symbol, xplanet2, cp2.dir, cx, cy, unitx, unity,
X    0.48, 0.50, 0.53, 0.57);
X  for (i = cObj; i >= 0; i--) if (FProper(i)) {
X    DrawColor(kObjB[i]);
X    DrawPoint(cx+POINT1(unitx, base, PX(xplanet2[i])),
X      cy+POINT1(unity, base, PY(xplanet2[i])));
X    if (gs.fAlt) {
X      DrawColor(cp2.dir[i] < 0.0 ? gi.kiGray : gi.kiOn);
X      DrawDash(cx+POINT1(unitx, base+0.02, PX(xplanet2[i])),
X        cy+POINT1(unity, base+0.02, PY(xplanet2[i])),
X        cx+POINT2(unitx, 0.46, PX(xplanet2[i])),
X        cy+POINT2(unity, 0.46, PY(xplanet2[i])), 2+fQuad-gs.fColor);
X    }
X  }
X
X  /* The third ring (either the innermost or second to innermost) is next.   */
X  /* Cast the chart on the fly, and draw the glyphs and lines to true point. */
X
X  ciCore = ciThre;
X  cpT = cp0;
X  CastChart(fTrue);
X  for (i = 0; i <= cObj; i++)
X    xplanet1[i] = PZ(HousePlaceInX(planet[i]));
X  cp0 = cpT;
X  for (i = 0; i <= cObj; i++)
X    symbol[i] = xplanet1[i];
X  FillSymbolRing(symbol, 1.4);
X  DrawSymbolRing(symbol, xplanet1, ret, cx, cy, unitx, unity,
X    0.35, 0.37, 0.40, 0.44);
X
X  if (fQuad) {
X
X    /* If a fourth ring is being done, first finish the third one by */
X    /* drawing lines from the true positions to the inner ring.      */
X
X    for (i = cObj; i >= 0; i--) if (FProper(i)) {
X      DrawColor(kObjB[i]);
X      DrawPoint(cx+POINT1(unitx, base, PX(xplanet1[i])),
X        cy+POINT1(unity, base, PY(xplanet1[i])));
X      if (gs.fAlt) {
X        DrawColor(ret[i] < 0.0 ? gi.kiGray : gi.kiOn);
X        DrawDash(cx+POINT1(unitx, base+0.02, PX(xplanet1[i])),
X          cy+POINT1(unity, base+0.02, PY(xplanet1[i])),
X          cx+POINT2(unitx, 0.33, PX(xplanet1[i])),
X          cy+POINT2(unity, 0.33, PY(xplanet1[i])), 2-gs.fColor);
X      }
X    }
X
X    /* If the fourth (innermost) ring is being done, cast the chart on the */
X    /* fly, and draw the glyphs and lines to the true positions.           */
X
X    ciCore = ciFour;
X    cpT = cp0;
X    CastChart(fTrue);
X    for (i = 0; i <= cObj; i++)
X      xplanet2[i] = PZ(HousePlaceInX(planet[i]));
X    cp0 = cpT;
X    for (i = 0; i <= cObj; i++)
X      symbol[i] = xplanet2[i];
X    FillSymbolRing(symbol, 1.8);
X    DrawSymbolRing(symbol, xplanet2, ret, cx, cy, unitx, unity,
X      0.22, 0.24, 0.27, 0.31);
X  }
X
X  /* Go draw sidebar with chart information and positions if need be. */
X
X  ciCore = ciMain;
X  DrawInfo();
}
X
X
/* Draw an aspect (or midpoint) grid in the window, between the planets in  */
/* two different charts, with the planets labeled at the top and side. This */
/* chart is done when the -g switch is combined with the -r0 and -X switch. */
/* Like above, the chart always has a (definable) fixed number of cells.    */
X
void XChartGridRelation()
{
X  char sz[cchSzDef];
X  int unit, siz, x, y, i, j, k, l;
X  KI c;
X
X  unit = CELLSIZE*gi.nScale; siz = (gs.nGridCell+1)*unit;
X  if (!FCreateGridRelation(gs.fAlt != us.fGridConfig))
X    return;
X  for (y = 0, j = -1; y <= gs.nGridCell; y++) {
X    do {
X      j++;
X    } while (ignore[j] && j <= cObj);
X    DrawColor(gi.kiGray);
X    DrawDash(0, (y+1)*unit, siz, (y+1)*unit, !gs.fColor);
X    DrawDash((y+1)*unit, 0, (y+1)*unit, siz, !gs.fColor);
X    DrawColor(gi.kiLite);
X    DrawEdge(0, y*unit, unit, (y+1)*unit);
X    DrawEdge(y*unit, 0, (y+1)*unit, unit);
X    DrawEdge(y*unit, y*unit, (y+1)*unit, (y+1)*unit);
X    if (j <= cObj) for (x = 0, i = -1; x <= gs.nGridCell; x++) {
X      do {
X        i++;
X      } while (ignore[i] && i <= cObj);
X
X      /* Again, we are looping through each cell in each row and column. */
X
X      if (i <= cObj) {
X        gi.xTurtle = x*unit+unit/2;
X        gi.yTurtle = y*unit+unit/2 -
X          (gi.nScale/gi.nScaleT > 2 ? 5*gi.nScaleT : 0);
X        k = grid->n[i][j];
X
X        /* If current cell is on top row or left hand column, draw glyph */
X        /* of planet owning the particular row or column in question.    */
X
X        if (y == 0 || x == 0) {
X          if (x+y > 0)
X            DrawObject(j == 0 ? i : j, gi.xTurtle, gi.yTurtle);
X        } else {
X
X        /* Otherwise, draw glyph of aspect in effect, or glyph of */
X        /* sign of midpoint, between the two planets in question. */
X
X          if (gs.fAlt == us.fGridConfig) {
X            if (k) {
X              DrawColor(c = kAspB[k]);
X              DrawAspect(k, gi.xTurtle, gi.yTurtle);
X            }
X          } else {
X            DrawColor(c = kSignB(grid->n[i][j]));
X            DrawSign(grid->n[i][j], gi.xTurtle, gi.yTurtle);
X          }
X        }
X
X        /* Again, when scale size is 300+, print some text in current cell: */
X
X        if (gi.nScale/gi.nScaleT > 2 && gs.fLabel) {
X
X          /* For top and left edges, print sign and degree of the planet. */
X
X          if (y == 0 || x == 0) {
X            if (x+y > 0) {
X              k = SFromZ(y == 0 ? cp2.obj[i] : cp1.obj[j]);
X              l = (int)((y == 0 ? cp2.obj[i] : cp1.obj[j])-ZFromS(k));
X              c = kSignB(k);
X              sprintf(sz, "%c%c%c %02d", chSig3(k), l);
X
X              /* For extreme upper left corner, print some little arrows */
X              /* pointing out chart1's planets and chart2's planets.     */
X
X            } else {
X              c = gi.kiLite;
X              sprintf(sz, "1v 2->");
X            }
X          } else {
X            k = abs(grid->v[i][j]);
X
X            /* For aspect cells, print the orb in degrees and minutes. */
X
X            if (gs.fAlt == us.fGridConfig) {
X              if (grid->n[i][j])
X                sprintf(sz, "%c%d %02d'", k != grid->v[i][j] ?
X                  (us.fAppSep ? 'a' : '-') : (us.fAppSep ? 's' : '+'),
X                  k/60, k%60);
X              else
X                sprintf(sz, "");
X
X            /* For midpoint cells, print degree and minute. */
X
X            } else
X              sprintf(sz, "%2d %02d'", k/60, k%60);
X          }
X          DrawColor(c);
X          DrawSz(sz, x*unit+unit/2, (y+1)*unit-3*gi.nScaleT, dtBottom);
X        }
X      }
X    }
X  }
}
X
X
/* Draw a chart showing a graphical ephemeris for the given month (or year */
/* if -Ey in effect), with the date on the vertical access and the zodiac  */
/* on the horizontal, as done when the -E is combined with the -X switch.  */
X
void XChartEphemeris()
{
X  real symbol[cObj*2+1], objSav[objMax];
X  char sz[4];
X  int yea, unit = 6*gi.nScale, daytot, d = 1, day, mon, monsiz,
X    x1, y1, x2, y2, xs, ys, m, n, u, v, i, j;
X
X  yea = us.nEphemYears;    /* Is this -Ey -X or just -E -X? */
X  if (yea) {
X    daytot = DayInYearHi(Yea);
X    day = 1; mon = 1; monsiz = 31;
X  } else
X    daytot = DayInMonth(Mon, Yea);
X  x1 = (yea ? 30 : 24)*gi.nScaleT; y1 = unit*2;
X  x2 = gs.xWin - x1; y2 = gs.yWin - y1;
X  xs = x2 - x1; ys = y2 - y1;
X
X  /* Display glyphs of the zodiac along the bottom axis. */
X
X  for (i = 1; i <= cSign+1; i++) {
X    m = x1 + NMultDiv(xs, i-1, 12);
X    j = i > cSign ? 1 : i;
X    DrawColor(kSignB(j));
X    DrawSign(j, m, y2 + unit);
X    DrawColor(gi.kiGray);
X    DrawDash(m, y1, m, y2, 2);
X  }
X
X  /* Loop and display planet movements for one day segment. */
X
X  while (d <= daytot + 1) {
X    n = v;
X    v = y1 + NMultDiv(ys, d-1, daytot);
X    if (!yea || day == 1) {
X      DrawColor(gi.kiGray);
X      DrawDash(x1, v, x2, v, 1);    /* Marker line for day or month. */
X    }
X    if (d > 1)
X      for (i = 1; i <= cObj; i++)
X        objSav[i] = planet[i];
X    ciCore = ciMain;
X    if (yea) {
X      MM = mon; DD = day;
X    } else {
X      MM = Mon; DD = d;
X    }
X    CastChart(fTrue);
X
X    /* Draw planet glyphs along top of chart. */
X
X    if (d < 2) {
X      for (i = 1; i <= cObj; i++) {
X        j = !FProper(i) || (i == oMoo && gs.fAlt);
X        symbol[i*2-1] = (j || us.nRel > rcDual) ? -rLarge : cp2.obj[i];
X        symbol[i*2] = (j ? -rLarge : planet[i]);
X      }
X      FillSymbolLine(symbol);
X      for (i = cObj*2; i >= 1; i--) {
X        j = (i+1) >> 1;
X        if (symbol[i] >= 0.0)
X          DrawObject(j, x1 + (int)((real)xs * symbol[i] / rDegMax), unit);
X      }
X      if (us.nRel <= rcDual) {
X        for (i = cObj; i >= 1; i--) {
X          if (!FProper(i) || (i == oMoo && gs.fAlt))
X            continue;
X          j = x1 + (int)((real)xs * cp2.obj[i] / rDegMax);
X          DrawColor(kObjB[i]);
X          DrawDash(j, y1, j, y2, 1);
X        }
X      }
X
X    /* Draw a line segment for each object during this time section. */
X
X    } else
X      for (i = cObj; i >= 1; i--) {
X        if (!FProper(i) || (i == oMoo && gs.fAlt))
X          continue;
X        m = x1 + (int)((real)xs * objSav[i] / rDegMax);
X        u = x1 + (int)((real)xs * planet[i] / rDegMax);
X        DrawColor(kObjB[i]);
X        DrawWrap(m, n, u, v, ret[i] > 0.0 ? -x1 : x1, x2);
X      }
X
X    /* Label months or days in the month along the left and right edges. */
X
X    if (d <= daytot && (!yea || day == 1)) {
X      if (yea) {
X        sprintf(sz, "%c%c%c", chMon3(mon));
X        i = (mon == Mon);
X      } else {
X        sprintf(sz, "%2d", d);
X        i = (d == Day);
X      }
X      DrawColor(i ? gi.kiOn : gi.kiLite);
X      DrawSz(sz,     xFont   *gi.nScaleT, v + (yFont-2)*gi.nScaleT,
X        dtLeft | dtBottom);
X      DrawSz(sz, x2+(xFont-1)*gi.nScaleT, v + (yFont-2)*gi.nScaleT,
X        dtLeft | dtBottom);
X    }
X
X    /* Now increment the day counter. For a month we always go up by one. */
X    /* For a year we go up by four or until the end of the month reached. */
X
X    if (yea) {
X      i = us.fSeconds ? 2 : 4;
X      day += i;
X      if (day > monsiz) {
X        d += i-(day-monsiz-1);
X        if (d <= daytot + 1) {
X          mon++;
X          monsiz = DayInMonth(mon, Yea);
X          day = 1;
X        }
X      } else
X        d += i;
X    } else
X      d++;
X  }
X  DrawColor(gi.kiLite);
X  DrawEdge(x1, y1, x2, y2);
X
X  ciCore = ciMain;    /* Recast original chart. */
X  CastChart(fTrue);
}
X
X
#ifdef BIORHYTHM
/* Draw a graphic biorhythm chart on the screen, as is done when the -rb    */
/* switch is combined with -X. This is technically a relationship chart in  */
/* that biorhythm status is determined by a natal chart time at another     */
/* later time. For the day in question, and for two weeks before and after, */
/* the Physical, Emotional, and Mental percentages are plotted.             */
X
void XChartBiorhythm()
{
X  char sz[6], *c;
X  real jd, r, a;
X  int x1, x2, xs, cx, y1, y2, ys, cy, i, j, k, x, y, x0, y0;
X
X  k = xFont*6*gi.nScaleT;
X  x1 = k; x2 = gs.xWin-k; xs = x2-x1; cx = (x1+x2)/2;
X  k = CELLSIZE;
X  y1 = k; y2 = gs.yWin-k; ys = y2-y1; cy = (y1+y2)/2;
X
X  /* Create a dotted day/percentage grid to graph on. */
X  DrawColor(gi.kiGray);
X  DrawDash(x1, cy, x2, cy, 1);
X  DrawDash(cx, y1, cx, y2, 1);
X  for (j = -us.nBioday+1; j <= us.nBioday-1; j++) {
X    x = x1 + NMultDiv(xs, j+us.nBioday, us.nBioday*2);
X    for (k = -90; k <= 90; k += 10) {
X      y = y1 + NMultDiv(ys, 100+k, 200);
X      DrawPoint(x, y);
X    }
X  }
X
X  /* Now actually draw the three biorhythm curves. */
X  for (i = 1; i <= 3; i++) {
X    jd = RFloor(is.JD + rRound);
X    switch (i) {
X    case 1: r = brPhy; c = "PHYS"; j = eFir; break;
X    case 2: r = brEmo; c = "EMOT"; j = eWat; break;
X    case 3: r = brInt; c = "INTE"; j = eEar; break;
X    }
X    DrawColor(kElemB[j]);
X    for (jd -= (real)us.nBioday, j = -us.nBioday; j <= us.nBioday;
X      j++, jd += 1.0) {
X      a = RBiorhythm(jd, r);
X      x = x1 + NMultDiv(xs, j+us.nBioday, us.nBioday*2);
X      y = y1 + (int)((real)ys * (100.0-a) / 200.0);
X      if (j > -us.nBioday)
X        DrawLine(x0, y0, x, y);
X      else
X        DrawSz(c, x1/2, y+2*gi.nScaleT, dtCent);
X      x0 = x; y0 = y;
X    }
X  }
X
X  DrawColor(gi.kiLite);
X  /* Label biorhythm percentages along right vertical axis. */
X  for (k = -100; k <= 100; k += 10) {
X    sprintf(sz, "%c%3d%%", k < 0 ? '-' : '+', abs(k));
X    y = y1 + NMultDiv(ys, 100-k, 200);
X    DrawSz(sz, (x2+gs.xWin)/2, y+2*gi.nScaleT, dtCent);
X  }
X  /* Label days on top horizontal axis. */
X  k = Max(us.nBioday/7, 1);
X  for (j = -us.nBioday+k; j < us.nBioday; j += k) {
X    x = x1 + NMultDiv(xs, j+us.nBioday, us.nBioday*2);
X    sprintf(sz, "%c%d", j < 0 ? '-' : '+', abs(j));
X    DrawSz(sz, x, y1-2*gi.nScaleT, dtBottom);
X  }
X  DrawEdge(x1, y1, x2, y2);
}
#endif /* BIORHYTHM */
#endif /* GRAPH */
X
/* xcharts2.c */
SHAR_EOF
  $shar_touch -am 1223232998 'xcharts2.c' &&
  chmod 0644 'xcharts2.c' ||
  echo 'restore of xcharts2.c failed'
  shar_count="`wc -c < 'xcharts2.c'`"
  test 27339 -eq "$shar_count" ||
    echo "xcharts2.c: original size 27339, current size $shar_count"
fi
# ============= xdata.c ==============
if test -f 'xdata.c' && test X"$1" != X"-c"; then
  echo 'x - skipping xdata.c (File already exists)'
else
  echo 'x - extracting xdata.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'xdata.c' &&
/*
** Astrolog (Version 5.40) File: xdata.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
#ifdef GRAPH
/*
******************************************************************************
** Graphics Global Variables.
******************************************************************************
*/
X
GS NPTR gs = {
#ifdef ISG
X  fFalse,
#else
X  fTrue,
#endif
X  fFalse, fFalse, fTrue, fFalse, fFalse, fTrue, fTrue, fFalse,
X  fTrue, fTrue, fFalse, fTrue, fFalse, fFalse, fFalse,
X  DEFAULTX, DEFAULTY, 0, 200, 0, 0, 0, 0.0,
X  BITMAPMODE, 0, 8.5, 11.0, NULL, oCore, 1111
#ifdef PCG
X  , DEFHIRESMODE, DEFLORESMODE
#endif
X  };
X
GI NPTR gi = {
X  0, fFalse, -1,
X  NULL, 0, NULL, NULL, 0, 0.0, fFalse,
X  2, 1, 10, kWhite, kBlack, kLtGray, kDkGray, 0, 0, 0, 0, -1, -1
#ifdef X11
X  , NULL, 0, 0, 0, 0, 0, 0, 0, 0
#endif
#ifdef PS
X  , fFalse, 0, fFalse, 0, 0, 1.0
#endif
#ifdef META
X  , NULL, NULL, MAXMETA, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
#endif
#ifdef MSG
X  , -1000
#endif
#ifdef BGI
X  , -1000, fFalse, VGA, VGAHI, 1, 0
#endif
#ifdef MACG
#endif
X  };
X
#ifdef WIN
WI NPTR wi = {
X  (HWND)NULL, (HWND)NULL, (HWND)NULL, (HMENU)NULL, (HACCEL)NULL,
X  hdcNil, hdcNil, (HWND)NULL, (HPEN)NULL, (HBRUSH)NULL, (HFONT)NULL,
X  0, 0, 0, 0, 0, 0, 0, -1, -1,
X  0, 0, fFalse, fTrue, fFalse, fTrue, fFalse, 1,
X  fFalse, fFalse, fTrue, fFalse, fTrue, fFalse, kBlack, 1, 1000};
X
OPENFILENAME ofn = {
X  sizeof(OPENFILENAME), (HWND)NULL, (HINSTANCE)NULL, NULL, NULL, 0, 1, NULL,
X  cchSzMaxFile, NULL, cchSzMaxFile, NULL, NULL, OFN_OVERWRITEPROMPT, 0, 0,
X  NULL, 0L, NULL, NULL};
X
PRINTDLG prd = {
X  sizeof(PRINTDLG), (HWND)NULL, (HGLOBAL)NULL, (HGLOBAL)NULL, hdcNil,
X  PD_NOPAGENUMS | PD_NOSELECTION | PD_RETURNDC | PD_USEDEVMODECOPIES,
X  0, 0, 0, 0, 1, (HINSTANCE)NULL, 0L, NULL, NULL, (LPCSTR)NULL, (LPCSTR)NULL,
X  (HGLOBAL)NULL, (HGLOBAL)NULL};
X
char szFileName[cchSzMaxFile];
char szFileTitle[cchSzMaxFile];
char *szFileTemp = szFileTempCore;
#endif
X
/* Color tables for Astrolog's graphics palette. */
X
CONST KV ARR rgbbmp[cColor] = {
X  0x000000L, 0x00007FL, 0x007F00L, 0x007F7FL,
X  0x7F0000L, 0x7F007FL, 0x7F7F00L, 0xBFBFBFL,
X  0x7F7F7FL, 0x0000FFL, 0x00FF00L, 0x00FFFFL,
X  0xFF0000L, 0xFF00FFL, 0xFFFF00L, 0xFFFFFFL};
#ifdef MSG
CONST KV rgb[cColor] = {
X  _BLACK, _RED, _GREEN, _BROWN,
X  _BLUE, _MAGENTA, _CYAN, _WHITE,
X  _GRAY, _LIGHTRED, _LIGHTGREEN, _YELLOW,
X  _LIGHTBLUE, _LIGHTMAGENTA, _LIGHTCYAN, _BRIGHTWHITE};
#endif
#ifdef BGI
CONST KV ARR rgb[cColor] = {
X  EGA_BLACK, EGA_RED, EGA_GREEN, EGA_BROWN,
X  EGA_BLUE, EGA_MAGENTA, EGA_CYAN, EGA_LIGHTGRAY,
X  EGA_DARKGRAY, EGA_LIGHTRED, EGA_LIGHTGREEN, EGA_YELLOW,
X  EGA_LIGHTBLUE, EGA_LIGHTMAGENTA, EGA_LIGHTCYAN, EGA_WHITE};
#endif
#ifdef X11
CONST char *szColorX[cColor] = {
X  "black", "orangered3", "green4", "darkorange2",
X  "blue4", "violet", "cyan4", "grey65",
X  "grey35", "orangered1", "green1", "yellow1",
X  "blue1", "pink", "cyan1", "white"};
KV rgbind[cColor], fg, bg;
#endif
#ifdef WIN
int ikPalette[cColor] =
X  {-0, -1, 1, 4, 6, 3, -8, 5, -3, -2, -4, -5, -7, 2, 7, -6};
#endif
X
/* These are the actual color arrays and variables used by the program.      */
/* Technically, Astrolog always assumes we are drawning on a color terminal; */
/* for B/W graphics, all the values below are filled with black or white.    */
X
KI kMainB[9], kRainbowB[8], kElemB[4], kAspB[cAspect+1], kObjB[objMax];
X
/* Some physical X window variables dealing with the window itself. */
X
#ifdef X11
XXSizeHints hint;
#if FALSE
XXWMHints *wmhint;
#endif
char xkey[10];
#endif
X
X
/*
******************************************************************************
** Graphics Table Data.
******************************************************************************
*/
X
#ifdef STROKE
CONST char szObjectFont[oNorm+2] = ";QRSTUVWXYZ     <    a  c     b  >";
CONST char szAspectFont[cAspect+1] = "!\"#$'&%()+-       ";
#endif
X
CONST char * ARR szDrawSign[cSign+2] = {"",
X  "ND4HU2HLGDFBR6EUHLGD2G",                /* Aries       */
X  "BL3D2F2R2E2U2H2NE2L2NH2G2",             /* Taurus      */
X  "BLU3LHBR7GLNL3D6NL3RFBL7ERU3",          /* Gemini      */
X  "BGNDHLGDFRNEFR2EREBU3NHDGLHUENRHL2GLG", /* Cancer      */
X  "BF4H2UEU2H2L2G2D2FDGH",                 /* Leo         */
X  "BF4BLHNGNHEU5G2ND3U2HGND6HGND6H",       /* Virgo       */
X  "BGNL3HUER2FDGR3BD2L8",                  /* Libra       */
X  "BH4FND6EFND6EFD6FREU",                  /* Scorpio     */
X  "BG4E3NH2NF2E5NL2D2",                    /* Sagittarius */
X  "BH3BLED4FND2EU2ENF2UFERFDGLF2D2G",      /* Capricorn #1 */
X  "BG4EUEDFDEUEDFDEUEBU5GDGUHUGDGUHUGDG",  /* Aquarius    */
X  "NL4NR4BH4F2D4G2BR8H2U4E2",              /* Pisces      */
X  "BH4RFR2ER3G3D2GDFR2EU2HL3G2DG"};        /* Capricorn #2 */
X
CONST char * ARR szDrawSign2[cSign+2] = {"",
X  "BD8U7HU3HU2H2L2G2D2F2BR12E2U2H2L2G2D2GD3G",     /* Aries  */
X  "BH6BU2FDFRFNR4GLGDGD4FDFRFR4EREUEU4HUHLHEREUE", /* Taurus */
X  "", /* Gemini */
X  "BG5NRLH2U2E2R2F2D2G2F2R4ER2E3BH6NE2D2F2R2E2U2H2L2H2L4GL2G3", /* Cancer */
X  "", /* Leo   */
X  "", /* Virgo */
X  "", /* Libra */
X  "BH8F2ND12E2F2ND12E2F2D12F2RE2U3NGF", /* Scorpio */
X  "", /* Sagittarius  */
X  "", /* Capricorn #1 */
X  "BG8EUE2UEDFD2FDEUE2UEDFD2FDEUE2UEBU10GDG2DGUHU2HUGDG2DGUHU2HUGDG2DG",
X  "NL8NR8BH8F3DFD6GDG3BR16H3UHU6EUE3", /* Pisces */
X  ""}; /* Capricorn #2 */
X
CONST char * ARR szDrawObject[oNorm+5] = {
X  "ND4NL4NR4U4LGLDGD2FDRFR2ERUEU2HULHL",    /* Earth   */
X  "U0BH3DGD2FDRFR2ERUEU2HULHL2GL",          /* Sun     */
X  "BG3E2U2H2ER2FRDFD2GDLGL2H",              /* Moon    */
X  "BD4UNL2NR2U2REU2HNEL2NHGD2FR",           /* Mercury */
X  "LHU2ER2FD2GLD2NL2NR2D2",                 /* Venus   */
X  "HLG2DF2RE2UHE4ND2L2",                    /* Mars    */
X  "BH3RFDGDGDR5NDNR2U6E",                   /* Jupiter */
X  "BH3R2NUNR2D3ND3RERFDGDF",                /* Saturn  */
X  "BD4NEHURBFULU3NUNR2L2NU2DGBU5NFBR6GD3F", /* Uranus #1 */
X  "BD4U2NL2NR2U5NUNRLBL2NUNLDF2R2E2UNRU",   /* Neptune   */
X  "D2NL2NR2D2BU8GFEHBL3D2F2R2E2U2",         /* Pluto  #1 */
X  "BG2LDFEULU3NURFRFBU5GLGLU2",             /* Chiron          */
X  "BD4UNL3NR3U2RE2UH2L2G",                  /* Ceres           */
X  "BD4UNL3NR3UE2HUHNUGDGF2",                /* Pallas Athena   */
X  "BD4UNL2NR2U4NL4NR4NE3NF3NG3NH3U3",       /* Juno            */
X  "BU4DBG3NLFDF2E2UERBH2GDGHUH",            /* Vesta           */
X  "BG2LGFEU2HU2E2R2F2D2GD2FEHL",            /* North Node      */
X  "BG4E8BG2FD2G2L2H2U2E2R2F",               /* Lilith #1       */
X  "NE2NF2NG2H2GD2F2R2E2U2H2L2G",            /* Part of Fortune */
X  "U2NHNEBD4NGNFU2L2NHNGR4NEF",             /* Vertex          */
X  "BH4NR3D4NR2D4R3BR2U8R2FD2GL2",           /* East Point      */
X  "BG4U4NR2U3EFD7BR2NURU2HU2RDBR3ULD5RU",   /* Ascendant  */
X  "BH3ER4FD2GLGLG2DR6",                     /* 2nd Cusp   */
X  "BH3ER4FD2GNL3FD2GL4H",                   /* 3rd Cusp   */
X  "BH4R2NR2D8NL2R2BR4NUL2U8R2D",            /* Nadir      */
X  "BG3FR4EU2HL5U4R6",                       /* 5th Cusp   */
X  "BE3HL4GD6FR4EU2HL4G",                    /* 6th Cusp   */
X  "BH4D8REU6HLBF7DRU2HU2RDBG4NRU3NRU2R",    /* Descendant */
X  "BL2GD2FR4EU2HNL4EU2HL4GD2F",             /* 8th Cusp   */
X  "BG3FR4EU6HL4GD2FR4E",                    /* 9th Cusp   */
X  "BG4U8F2ND6E2D8BR4NUL2U8R2D",             /* Midheaven  */
X  "BH3ED8NLRBR2RNRU8G",                     /* 11th Cusp  */
X  "BG4RNRU8GBR4ER2FD2GLG2D2R4",             /* 12th Cusp  */
X  "BH4BRFDG2DR8BG3UNL2NR2U5LUEFDL",         /* Cupido    */
X  "BENUNL2NR2D3ND2NR2L2H2U2E2R4",           /* Hades     */
X  "BU4NG2NF2D7NDBLHLBR6LGL2GLBR6LHL",       /* Zeus      */
X  "BU2D3ND3NR2L2BH2UE2R4F2D",               /* Kronos    */
X  "U3NLR2NRD3NL2NR2D4NRL2NLU4L4UEUH",       /* Apollon   */
X  "BUNU2NL2NR2D2ND3LHU2ENHR2NEFD2GL",       /* Admetos   */
X  "G2DGR6HUH2U4NG2F2",                      /* Vulcanus  */
X  "ND4U4BL3DF2R2E2UBD8UH2L2G2D",            /* Poseidon  */
X  "BD2D0BU6NG2NF2D4LGD2FR2EU2HL",           /* Uranus #2 */
X  "BL3R5EU2HL5D8R5",                        /* Pluto  #2 */
X  "UERHL2G2D2F2R2ELHU",                     /* Lilith #2 */
X  "BH2LHEFD2GD2F2R2E2U2HU2EFGL"             /* Lilith #3 */
X  };
X
CONST char * ARR szDrawObject2[oNorm+5] = {
X  "ND8NL8NR8U8L2GLG3DGD4FDF3RFR4ERE3UEU4HUH3LHL2", /* Earth */
X  "U0BU8L2GLG3DGD4FDF3RFR4ERE3UEU4HUH3LHL2",       /* Sun   */
X  "BG6E3UEU2HUH3E2R4FRF3DFD4GDG3LGL4H2",           /* Moon  */
X  "", /* Mercury */
X  "", /* Venus   */
X  "BELHL4G3D4F3R4E3U4HUE7ND5L5",      /* Mars    */
X  "BH6BRRF2D2GDGDGDGDR10ND2NR4U12E2", /* Jupiter */
X  "", /* Saturn  */
X  "BD4LGD2FR2EU2HLU6NU2NR4L4NU4D2G2BU10NF2BR12G2D6F2",     /* Uranus #1 */
X  "BD8U4NL4NR4U10NU2NR2L2BL3LNU2NLD2FDFRFR4EREUEU2NLNRU2", /* Neptune   */
X  "D4NL4NR4D4BU16LGD2FR2EU2HLBL6D4FDFRFR4EREUEU4",         /* Pluto  #1 */
X  "BG4LGD2FR2EU2HLU7RF2RF2RFBU10GLG2LG2BLU5",     /* Chiron        */
X  "BD8U2NL6NR6U4R3E3U4H3L4G2",                    /* Ceres         */
X  "BD8U2NL6NR6U2E4HUHUHUHNUGDGDGDGF4",            /* Pallas Athena */
X  "BD8U2NL4NR4U8NL7NR7NE5NF5NG5NH5U6",            /* Juno          */
X  "BU8D3BG5NL3DF2DF2DFEUE2UE2UR3BH4GDG2DGHUH2UH", /* Vesta         */
X  "", /* North Node      */
X  "", /* Lilith #1       */
X  "", /* Part of Fortune */
X  "", /* Vertex          */
X  "", /* East Point      */
X  "BG8U8NR4U6E2F2D14BR4NHREU3HLHU3ERFBR6HLGD8FRE", /* Ascendant */
X  "", /* 2nd Cusp   */
X  "", /* 3rd Cusp   */
X  "BH8R4NR4D16NL4R4BR8BUNUGL3HU14ER3FD", /* Nadir */
X  "", /* 5th Cusp   */
X  "", /* 6th Cusp   */
X  "BH8D16R2E2U12H2L2BF14BGFREU3HLHU3ERFBG9NR3U5NR3U5R3", /* Descendant */
X  "", /* 8th Cusp   */
X  "", /* 9th Cusp   */
X  "BG8U16F4ND12E4D16BR8BUNUGL3HU14ER3FD", /* Midheaven */
X  "", /* 11th Cusp  */
X  "", /* 12th Cusp  */
X  "", /* Cupido    */
X  "", /* Hades     */
X  "", /* Zeus      */
X  "", /* Kronos    */
X  "", /* Apollon   */
X  "", /* Admetos   */
X  "", /* Vulcanus  */
X  "", /* Poseidon  */
X  "", /* Uranus #2 */
X  "", /* Pluto  #2 */
X  "", /* Lilith #2 */
X  ""  /* Lilith #3 */
X  };
X
CONST char * ARR szDrawHouse[cSign+1] = {"",
X  "BD2NLNRU4L", "BHBUR2D2L2D2R2", "BHBUR2D2NL2D2L2",
X  "BHBUD2R2NU2D2", "BEBUL2D2R2D2L2", "NLRD2L2U4R2",
X  "BHBUR2DG2D", "NRLU2R2D4L2U2", "NRLU2R2D4L2",
X  "BH2NLD4NLRBR2U4R2D4L2", "BH2NLD4NLRBR2RNRU4L", "BH2NLD4NLRBR2NR2U2R2U2L2"};
X
CONST char * ARR szDrawHouse2[cSign+1] = {"",
X  "BD4NL2NR2U8G2", "BH2BUER2FD2G4DR4", "BH2BUER2FD2GNLFD2GL2H",
X  "BH2BU2D4R3NU4NRD4", "BE2BU2L4D4R3FD2GL2H", "NL2RFD2GL2HU6ER2F",
X  "", "NRLHU2ER2FD2GFD2GL2HU2E", "NR2LHU2ER2FD6GL2H",
X  "BH4NG2D8NL2R2BR5HU6ER2FD6GL2", "BH4NG2D8NL2R2BR4R2NR2U8G2",
X  "BH4NG2D8NL2R2BR4NR4UE4U2HL2G"};
X
CONST char * ARR szDrawAspect[cAspect+3] = {"",
X  "HLG2DF2RE2UHE4",                        /* Conjunction      */
X  "BGL2GDFREU2E2U2ERFDGL2",                /* Opposition       */
X  "BH4R8D8L8U8",                           /* Square           */
X  "BU4GDGDGDGDR8UHUHUHUH",                 /* Trine            */
X  "BLNH3NG3RNU4ND4RNE3F3",                 /* Sextile          */
X  "BG4EUEUEUEUNL4NR4BDFDFDFDF",            /* Inconjunct       */
X  "BH4FDFDFDFDNL4NR4BUEUEUEUE",            /* Semisextile      */
X  "BE4G8R8",                               /* Semisquare       */
X  "BD2L3U6R6D6L3D2R2",                     /* Sesquiquadrature */
X  "F4BU3U2HULHL2GLDGD2FDRFR2E3",           /* Quintile         */
X  "BD2U3NR3NU3L3BD5R6",                    /* Biquintile       */
X  "BU2D3NR3ND3L3BU5R6",                    /* Semiquintile     */
X  "BH3R6G6",                               /* Septile      */
X  "BR3L5HUER4FD4GL4H",                     /* Novile       */
X  "BF2UHL2GFR3DGL3BE6LNLU2NRLBL4LNLD2NLR", /* Binovile     */
X  "BL2R4G4BE6LNLU2NRLBL4LNLD2NLR",         /* Biseptile    */
X  "BL2R4G4BE6L7NLU2NLR3ND2R3ND2R",         /* Triseptile   */
X  "BF2UHL2GFR3DGL3BU6LNLU2NLRBR2F2E2",     /* Quatronovile */
X  "BU4BLD8BR2U8",                          /* Parallel       */
X  "BU4BLD8BR2U8BF3BLL6BD2R6"};             /* Contraparallel */
X
CONST char * ARR szDrawAspect2[cAspect+3] = {"",
X  "BELHL4G3D4F3R4E3U4HUE7",                /* Conjunction */
X  "BG3HL2G2D2F2R2E2U2HE6HU2E2R2F2D2G2L2H", /* Opposition  */
X  "", /* Square           */
X  "BU8GDGDGDGDGDGDGDGDR16UHUHUHUHUHUHUHUH",     /* Trine       */
X  "BU8D16BL8BU2E3RE3R2E3RE3BL16F3RF3R2F3RF3",   /* Sextile     */
X  "BG8EUEUEUEUEUEUEUEUNL8NR8BDFDFDFDFDFDFDFDF", /* Inconjunct  */
X  "BH8FDFDFDFDFDFDFDFDNL8NR8BUEUEUEUEUEUEUEUE", /* Semisextile */
X  "", /* Semisquare       */
X  "", /* Sesquiquadrature */
X  "BFF7BU6U4HUH3LHL4GLG3DGD4FDF3RFR4E6", /* Quintile */
X  "", /* Biquintile   */
X  "", /* Semiquintile */
X  "", /* Septile      */
X  "", /* Novile       */
X  "", /* Binovile     */
X  "", /* Biseptile    */
X  "", /* Triseptile   */
X  "", /* Quatronovile */
X  "", /* Parallel        */
X  ""}; /* Contraparallel */
X
CONST char * ARR szDrawCh[128-32+1] = {"",
X  "BR2D4BD2D0", "BRD2BR2U2", "BD2R4BD2L4BFU4BR2D4", "BR2D6BENL3EHL2HER3",
X  "RDLNUBR4G4BR4DLUR", "BD2NF4UEFDG2DFRE2", "BR2DG", "BR3G2D2F2", "BRF2D2G2",
X  "BD2FNGRNU2ND2RNEF", "BD3R2NU2ND2R2", "BD5BR2DG", "BD3R4", "BD6BRRULD",
X  "BD5E4", /* Special Characters */
X
X  "BDD4NE4FR2EU4HL2G", "BFED6NLR", "BDER2FDG4R4", "BDER2FDGNLFDGL2H",
X  "D3R3NU3ND3R", "NR4D3R3FDGL2H", "BR3NFL2GD4FR2EUHL3", "R4DG4D",
X  "BDDFNR2GDFR2EUHEUHL2G", "BD5FR2EU4HL2GDFR3", /* Numbers */
X
X  "BR2BD2D0BD2D0", "BR2BD2D0BD2G", "BR3G3F3", "BD2R4BD2L4", "BRF3G3",
X  "BDER2FDGLDBD2D0", "BF2DFEU2HL2GD4FR2", /* Special Characters */
X
X  "BD6U4E2F2D2NL4D2", "D6R3EUHNL3EUHL3", "BR3NFL2GD4FR2E", "D6R2E2U2H2L2",
X  "NR4D3NR3D3R4", "NR4D3NR3D3", "BR3NFL2GD4FR2EU2L2", "D3ND3R4NU3D3",
X  "BRRNRD6NLR", "BD4DFR2EU5", "D3ND3RNE3F3", "D6R4", "ND6F2NDE2D6",
X  "ND6F4ND2U4", "BDD4FR2EU4HL2G", "R3FDGL3NU3D3", "BDD4FRENHNFEU3HL2G",
X  "ND6R3FDGL2NLF3", "BR3NFL2GDFR2FDGL2H", "R2NR2D6", "D5FR2EU5",
X  "D2FDFNDEUEU2", "D6E2NUF2U6", "DF4DBL4UE4U", "D2FRND3REU2",
X  "R4DG4DR4", /* Upper Case Letters */
X
X  "BR3L2D6R2", "BDF4", "BRR2D6L2", "BD2E2F2", "BD6R4", "BR2DF", /* Symbols */
X
X  "BF4G2LHU2ER2FD3", "D5NDFR2EU2HL2G", "BF4BUHL2GD2FR2E", "BR4D5NDGL2HU2ER2F",
X  "BD4R4UHL2GD2FR3", "BD3RNR3ND3U2ERF", "BD8R3EU4HL2GD2FR2E", "D3ND3ER2FD3",
X  "BR2D0BD2D4", "BR2D0BD2D5GLH", "D4ND2REREBD4HLH", "BR2D6",
X  "BD2DND3EFNDEFD3", "BD2DND3ER2FD3", "BD3D2FR2EU2HL2G", "BD2DND5ER2FD2GL2H",
X  "BR4BD8U5HL2GD2FR2E", "BD2DND3ER2F", "BD6R3EHL2HER3", "BR2D2NL2NR2D4",
X  "BD2D3FRE2NU2D2", "BD2DFDFEUEU", "BD2D3FENUFEU3", "BD2F2NG2NE2F2",
X  "BD2D3FR2ENU3D2GL3", "BD2R4G4R4", /* Lower Case Letters */
X
X  "BR3GDGFDF", "BR2D2BD2D2", "BRFDFGDG", "BFEFE", "BD6R4",
X  "BR2FGHE"}; /* Symbols */
X
CONST char * ARR szWorldData[62*3] = {
"-031+70",
"LLRRHLLLLDULLGLLLDULGLLLGLRREDEGGLGGLGLGLLGDRLDRLFFRRERFDFRRREUEEHLUERERUERR\
FGLGLDDFRRRRREFRLGLLLLLGEFDLHGDDLGHLGLLHGLHURDLRRELLLRHUGLDFDLGLLFHGGLGLLLDLL\
LDRRFFDDGLLLLLLGDFGDDRRFRERREEUEREUEFRRERRFFFRFRDDLLLLRFRUREURULHLHHHEF",
"5EUROPE",
"+006+50", "RRERRRRUELLUHHLLREULLELLDGHDUFDEGRDRRLFDLLRGRRGGL", "5ENGLAND",
"+008+55", "GLFGRRREUULL", "5IRELAND",
"+023+64", "RRFRERRREHLLLLLGHLLRFLLRFL", "5ICELAND",
"-011+80", "DDURFRERLGRRLLFRRREEFRRRLHGELLLHRRFRRRRERLLLLLLLLLLLDHGULLL",
"5SVALBARD",
"-014+45",
"FRFRFDDFRDRRLLFRURFHHUERRRRRHUUEERRRRGRDERRLHLRRERRGGRFRFFGLLLLHLLLLGLLDLLLF\
GRFFRERFRERDDDGDGLLDFFEUDDFFDFFDDFFFDFDDDRRERRERRRUERRERURUEEHHLHUGGLLLUUGUHU\
HURRFFRFRRRDRRFRRRRRRRF",
"5MIDDLE EAST",
"-009+41", "DDRUULEUGD", "5SARDINIA",
"-024+35", "RRLL", "5CRETE",
"-032+35", "RRLL", "5CYPRUS",
"-052+37", "LLHUURHUHUHERERRRDDLLLFFDDURFLLDFDDL", "0CASPAIN SEA",
"-060+44", "LLUEERDFLDL", "0ARAL SEA",
"-068+24",
"FRGFRREDDDDDFDFDDFDDFERUEUUUUEEEEEREURRREFDFRDDDDRREFDDFDDGDDRFDDFDFFRUHUUHH\
HULUEUUURDRFDFRDEEREUUUHHHUUEERRDDEURRERREREEEUEULLREUHUHLEERRHLGLULUREERDLDR\
ERRFGRFDGRRREUHHUREUE",
"6ASIA S",
"-140+36",
"DEUUEUHURREREEGLLHHDDGLDRGDDGGLGLLLGGLDLRDFEUHRRGEERDLLRGLRERRERRE",
"6JAPAN",
"-121+25", "GDFUEUL", "6TAIWAN",
"-080+10", "DDDDREUHH", "6SRI LANKA",
"-121+18", "LDDDRDDRHRRFFDDDLLEHDULRHDFDDGERDDREUUULUUHHLHEUUL",
"2PHILIPPINES",
"-131+43",
"EFREEREEEUUUEUHLLUDLULEERERERRRRRRERRFLRRRRLUERERRRDRERURRGDLGLGLGLGGDDFDFEU\
RRUERUURULEEREDERRFRERERRRERRHLHLRRRREURDRRFRFRUURRHLLLDHHLLHLLHLLLLLLLDLLHRL\
LLLLLLGHULLLLLLLLLLULLLGL",
"6SIBERIA",
"-145+71",
"RELLRHLLLLGDHGHLLLLGLLHUHLLLLLDLLLLHLLLLLDULUDLGLLLLRRERERRRELHLLLLLLLELLLLG\
DLLLLLUDLLLLLGLLLDLLLLLLLDFRDDHELLLLLLDRRLLHUDLGFGRRRRFRLHLLDGLGLLHRRREUHUUUL\
LGGLDRFGHLLLHLLLLRFGHLGLLLULGLLLGLLHRHLDDDLLLLDLLLFLLHUHLRRFRRRREHLLHLLLHLLL",
"6RUSSIA",
"-143+54", "GDDDDDDDEDUUURUUHUU", "6SAKHALIN",
"-180+72", "GRRRRULLL", "6WRANGEL I.",
"-137+76", "DRRRRRRRELLLLLLLL", "6SIBERIAN I.",
"-091+80", "FERDRRRRRRULLLLLRRULLLLGL", "6SEVERNAYA",
"-101+79", "GRRRRELLLL", "6ZEMLYA",
"-068+77", "LLGLLLLLLGLLGGLGLRFRRRRLHERERERRRERRRREL", "6NOVAYA",
"+123+49",
"FGULLFDDDGFDDDFFDFRFRFDFFFDLFFRDFFEHHHHUHHUFRDFFFRDFFFDFGFRFRFRRFRRRRFFRRFRF\
FDRFFRFEUUGLHHUUEUHLLLLLEUUEULLLGDLLGLHHUHUUUEHEERERRFRRHRREFRRFDFDFEUUHUUUEE\
RERUUUHFDEUHFEURRRELUERRE",
"4NORTH AMERICA S",
"+113+42", "FH", "0SALT LAKE",
"+156+20", "DRULHLHL", "4HAWAII",
"+085+22", "RERFRRFRGRRRRHLHLHLLLLLG", "4CUBA",
"+070+18", "RRHHLLLFLLLFRRRRRR", "4HAITI",
"+078+18", "RRHLLF", "4JAMAICA",
"+066+18", "ELLDR", "4PUERTO RICO",
"+078+24", "UD", "4NASSAU",
"+067+45",
"REFLGDERERREHDLLLHUELLLGLGLREEERRRRRRREERRGGDGRRRFEFUUHLLLEUUHHGLRELLHHUHHHD\
GLGHHULLHLLLLLDFGFDDGLLFDDGHHUULLLLHLLHLLLUHUUEREEREERRRREUUHLLLDDGHULLLHLUHL\
GDRFGGULLLLLLLLLHLLGFLHLLLLLRHLLLLLHLLLLLLHGLLLLGUGLLLHLL",
"4CANADA",
"+088+49",
"LGLGRRRRRRRFLLLGRGDDREUURUFRGRFGFERERREEREERLGGLGLLLGRLLGLEUERHLLLHULHL",
"0GREAT LAKES",
"+117+61", "REHRFRRERGLGLLLL", "0SLAVE LAKE",
"+125+66", "RRERRRGREDLFHGLLLERLLLL", "0BEAR LAKE",
"+097+50", "UULHURFDFG", "0LAKE WINNIPEG",
"+090+72",
"FRRLLFRRRRRRRRRRFRRGLLGRREEFRFLGLFLLLLFRERFRFRRFRRHLHFRRRUHLHRRFRURELLHLLLHR\
RHLHLHGHLHLLGLLEHFRRRHLLLLLLGLDFHLUELLGG",
"4BAFFIN I.",
"+125+72",
"RFRREERRRLLGFFRRRRRLLLLLFRRRRRRRREFRRRRHRRLHLHHLRRULGLFLHLDLLULLLLHLLLLLLLDG",
"4VICTORIA I.",
"+141+70",
"LLLLLLLLHGLHLLLHGLLGLLGLLDRRFRRDLLLULGLLFRRRRRRDLGLLGFDRRRDRRRRRGGGLLGLLGGLL\
RRERERRRERREERRELEERRRLLGDRERRURRFRRRRRFRRFUDRUDDHFDURDURLURDDLFRULURDHFFRGFE\
GRFFRFRFLHLHLFFRFE",
"4ALASKA",
"+045+60",
"REUEREUERRRRERERRRERRRRERLLLLLLHRRRGERHFRRRRHLUDLLHLRERFRERLEUHRRHLEERLLURRR\
RRRRRELLLLLLLLLLGLLLRERHGLRELLLLLLLELLLLLLLLLLGLLLLLLGLLLLLLGLULLLLLLLFRLLLLL\
GLRRRGLLLLLLLGRRRRRRRGLLLLRRFRRRRRRRRRRFDFDLFREFRDLLLDERRFGLLGFFDRFFFRRRF",
"4GREENLAND",
"+080+10",
"DRFDFDDGGGDDGRDGDDFFDFDFFDFFRFFFDDDDDDGDDDDGDDDDGDGFGDDDEUDDDGUDDLDRGDDDFDFR\
FRRFERRLHLUHUURUEELHEREURULURREURREREUHUUDFRREEEEEUEUUEERERRREUEUEUUUUUEEEEUU\
UHLHLHLLLLHLHLGEHLGEUHUUHLHLLLHHLHULEDLLELLGHLLHLGDDHUELLGLGDGHHL",
"3SOUTH AMERICA",
"+060-51", "LDRRELL", "3FALKLAND ISLANDS",
"+092+00", "FUL", "3GALAPAGOS I.",
"-032+32",
"LLGLHLLLLHLGDGHLLHHLLHLEUULLLLLLLLLGLGLLLLHDGLGDGDGGLDGGGDGDFDDDDGDDFFFFDFRF\
FRRRRRRRRERERRFFRRFFDDDGDFFFDFDDDFDGDGDDDFDFDFDDDFDFDFDDFFERRRRREEEEEEEUUEREU\
UHUEEEREEUUUUHUUUHUEUEEEEEREEUEUEEUUULLLLGLLHUHHLHUHHUUHHUUHUHHUU",
"1AFRICA",
"-049-12", "DGGGLGDDDDGDDFFREUEUEUUUEUUUUH", "1MADAGASCAR",
"-032+00", "DDDREUELLL", "0LAKE VICTORIA",
"-014+14", "LRFLU", "0LAKE CHAD",
"-124-16",
"LGDGGLGLLGLDDDGFDDFDFDGFRRRERRRRURERRRRRRRFFFEEDDRFDFRFREFRERRUUEUEEUUUUUUUH\
HHHHHHUUHHHUULDDDDGDGHLHLHEUELLLHLFLLULDRGDDLLHLGG",
"2AUSTRALIA",
"-173-35", "FFDGFDREURULHHHL", "2NEW ZEALAND N",
"-174-41", "LLDGLGLGGRFREEUREEU", "2NEW ZEALAND S",
"-145-41", "DFRRUUUDLLL", "2TASMANIA",
"-178-17", "GRRURUGDH", "2FIJI",
"-130+00", "FRFRLGFEFRFRFDGRRFRRUERFFFRRRLHHHHRHLHHLHLLHGGLHUHLGH",
"2NEW GUINEA",
"-115-04", "RUUEEURHUUEHHGGGGLLDDHLDDFDDRRDERF", "2BORNEO",
"-095+06", "DFFFFFFDFFFFRUUUHFRHLHLUHHHHHLLH", "2SUMATRA",
"-106-06", "GRFRRRRRRFRRHLHLLLLLHL", "2JAVA",
"-120+00", "DGDDRDFHUEDFRHUHREFHLGHURRRRELLLLG", "2CELEBES",
"+000-70",
"ULDLLLLLLLLGLLGLLLGLLGLLLLGLGLLGLLLLGLLLLLHLGLLLLLHLLLLLHLLLLHLLUERLEUUUUUUE\
ERRRULLGLLLLGLGGLLLDRUDRDLGHLLGLLFGRRFLLLLLLLDHLLLLHLLLLLGLLLLHLLLLLLLGRFDLLL\
ULLLGHLLLLLLLLLLHGHLLGLLLLLLLGLLLLLLLLLLLGLLLGLLLLLLLLGLLLLLLLLLLLLLLLLLLLLL",
"7ANTARCTICA W",
"+180-78",
"LLLLLLLHLLGHLLGHLUEERRERREHLLLLHLLLLLLHLLLLLLLLLLLHLHLLLLLHLLULDLLLLLDLLHLLL\
LGHFLLLLLHLLLLLLGLHLLHLGLLLLHLGLLGLLLULLLGLLHDFLLLGLGLLLELLLLHLLLLLLLLLLHLLLH\
LLLLGGHGHGLLLGLDLLLLHLLGHGLLLLLLLLLLLLLLHLGLLLLLLLLLLLLLL",
"7ANTARCTICA E",
"", "", ""};
X
#ifdef CONSTEL
CONST char * ARR szDrawConstel[cCnstl+1] = {"",
"550210+51DDd3r8d2Rr7d2Rr3Dd5l2d3r10uru6rUu2Rr2ur4u2RrUUu3Ll7d2l3DdLl5d2Lu2l4\
Uul8Dd2Ll3Uul7", /* Andromeda */
"660913-25d2Ll5Dl5d2l4d4LlDRRr8Uu5l6", /* Antila */
"561804-68DDd3RRRRRr2Uu9LLLLl3Uu2Ll4", /* Apus */
"362213+02Dd3Ll14DDd5RRrUUur7Dd4Rr6UUu2Ll9ul3dLl13", /* Aquarius */
"562003+16Ddl3d7l3Dd9r7Dd2RRUu6r5Uu2l4u4r3Uu2l3u7Lld2l13dLl3", /* Aquila */
"641803-45Dd7Rr5Dd8Ru3rur2u3r3UUu5LLl3", /* Ara */
"560307+31DDrd9RRr3Uu6Llu2l7UuLl7", /* Aries */
"650604+56d2l6Dl4d6Ll7Dd5Rr5Dd2RuRr2Ur4u6l3UUu3Ll3u3Ll4", /* Auriga */
"431504+55d2l8DDdr4d7r4Dd5rDDd2RRr6UUu8LlUlUUu5Ll4", /* Bootes */
"560501-27DDd3Rr2d3r5d3r4Uu3l5Ul2u3Ll", /* Caelum */
"751407+86DdRr6d3RRr6u3Rr2UuRr9Dd7Rr12DDRr12u2Rr11Dd4Rr12d3RRr8u2r2u2rUu8l6Uu\
7lULLl6u5LLLl5uLLLLLLl7", /* Camelopardalis */
"550906+33DDDd3Rr14URrULu8l2Uu3Ll6", /* Cancer */
"551309+52Dd2Ll2DDrd2Rr9UuRr8u2r5Uu4lUu2Ll9", /* Canes Venatici */
"550707-11DDd3Rr12UUu9Ll7", /* Canis Major */
"660714+13DLld3l2DRr10ur3Uu2l7ul5", /* Canis Minor */
"562114-09DDd5r7d2Rr13UUul7Dd4Ll7Uul7", /* Capricornus */
"360804-51d2l4d2l5d2LLLl5DDd5RRRUu6RRr2Uu2r4u3r6u2r2u2LLl4", /* Carina */
"440310+77Dd2r6Dd3Rr6u2Rdr3d3r4d4r4DdRd2r10u2Rr5Uur3u2RrULl4u4l6u3Ll6Uu7LLLl1\
0", /* Cassiopeia */
"551501-30Dd3Rr11Dd5l6Dd4RRrUu5RrDd4r9Uu3r4UUu4Ll5u2l5ULLLl", /* Centaurus */
"850805+88d3RRRr9DRRr4d3RRRr9Dd3Rr5d3r6DRrd3r7dr3d3r3u2RRr5UurdRu2l7u5l3Uu5r9\
Uul12u5LLl14u2LLLLLLLLLLl5", /* Cepheus */
"560306+11DDdRr4DDd4Rr4dRRrUUu4Ll7Uu3LLl2UuLl6", /* Cetus */
"561313-75Dd3RRRRRRr6Uu5LLLLLLl13", /* Chamaeleon */
"341507-55Ddr2d3r3d4RrDdRr2Uu5r2uLl10Uu5Ll7", /* Circinus */
"660603-27Dd3l7Dd3Rr14UUu3Ll3", /* Columba */
"561207+33d2Ll6Dd2l3Dd6RrdRUu8l2Uu3l5", /* Coma Berenices */
"561905-37Dd5RRUu3Ll5", /* Corona Australis */
"451606+39Dd4r2dRr11Uu2l4u7Ll6", /* Corona Borealis */
"551214-12Dd3r4d2RrUu8Ll14", /* Corvus */
"551114-07DDd5RrUrUu3Ll14", /* Crater */
"561214-55Dd4RrUu5Ll14", /* Crux */
"552010+61Dd5LLlDd5RdrDd4r2Dd2RuRr4d2r6Ulu7lUu4r4u4rUu6l5u2l5ULl9ul",
/* Cygnus */
"542010+21DLl2d8RrDd4rd4r7u7r3Uu6l2Uul5", /* Delphinus */
"570408-49Dd4Lld3l7DdLd3l8DRRr6Uur3u3r5u3Rr2u2Ll2Uul6", /* Dorado */
"352013+86d5r12Dd5l9Dd3r3d5RDr3d2r5d2r5Dd2Rr10UuRr14uRRr3ur8u2Rr8Uu2Rr7uRr14u\
3Rr8Uu3RRr9UuLl13DdLl9d3LLlDdLd4Ll10ULl8u5Ll7Ul7u6LLLl13", /* Draco */
"562107+13Dd8Rr2u4lUu2Ll3ul4", /* Equuleus */
"430411+00d4Ll3DdRd3rDd7r3Dr2d7r5DRrd4r7d2r6d3Rr4Ddr4d3r4d4Rr8u5l3u2l4Uu2Ll6U\
Llul7u4l4Uu6Rr4UUu9Ll10ULl11", /* Eridanus */
"550312-24Dd5r4d4r7DRRr4Uu6LLl12", /* Fornax */
"560713+35d2Ll2Dd2RDrd7r5dr7Dru2Rr9u6rUu2Ru6l10Uu5Ll13", /* Gemini */
"442307-36DDd6Rr13UuRr8Uu4LLl7", /* Grus */
"551805+51Dd2rDDl3d4l7Dd8r8u2Rr9dRr2Dd6r10Uu6RUu2l2u3l2ul2Uu9Rr3UUu2LLldLl5",
/* Hercules */
"770404-40d9r2DdRr2d2r5d4r4Dd7Rr12Uu6l4u3l4UuLlu3l6u2l7ULl4", /* Horologium */
"760910+07DDd2Ll13Dld5LLl10u2LLl6d2LlDRRRr5d4r5d2RRru4r4Ur5u3Rr2u2r10URr5u2r3\
u7r4UUu7Ll10", /* Hydra */
"560203-58Dd7LLl9Dd5Rr8Dd2RRRr14Uu6l12dLl6UUu2Ll3", /* Hydrus */
"742107-45d4Ll2DDd7Ll7Dd4RRr8UURr8Uu5Ll7", /* Indus */
"562214+57DDd5r13uRrUu4LulUu3l3u3l3ul7", /* Lacerta */
"551200+28DDr6Dd7Rr2Uu7Rr9UUUu3LDd2l9d5l4u2Ll2u3L", /* Leo */
"451004+41Ddl9d6Ll2Dd5Rr2d2r4u5RUu3r9u6l5UuLl4", /* Leo Minor */
"550603-11Dd7RRrUu6Lu3Ll3", /* Lepus */
"551600-04DDdr3Dr11u5Rr9UUu2l6u7Ll3d3L", /* Libra */
"331602-30Dd2Rr3d6r5Dd4r4dRr11Uu7LlUULl2", /* Lupus */
"640703+62DLl9Dd4Ll5d5l6Ddr5d6RRr2u2r6Uu4RrUr4u4r6Uu2Ll3", /* Lynx */
"551903+48d4l4Dd3rDrd5Rrur7Ur3Uu8Ll3", /* Lyra */
"560608-70d5Ll9Dd5RRRRr8Uu5Ll9ULLl8", /* Mensa */
"552107-27DDd5Rr8UUu3Ll7", /* Microscopium */
"470701+12Dld9l3DLl3DdRRRrUu6Ll5UUlu2Ll", /* Monoceros */
"561311-64dl2Dd5RRr10Uu6LLl11", /* Musca */
"561609-42DDRr8u5r4ul4Uu2l5u6Ll9", /* Norma */
"270000-74lDd2LLLl7d3LLLLl9u2LLLLLLLLLLLl4Uu6LLLLLL", /* Octans */
"641806+14d2l5Dd4r5d2l2dr2DRrd4LlDRr3d2rUr7d6l7DDRr2u5r7UlurUu2Ru4l6Uu4l7Uu3L\
l6uLl6", /* Ophiuchus */
"560600+23dl5Dd2lDrDd4RrDdr11Uu6Rr4UrUu5Llul5dl4d3l3u6rUu3L", /* Orion */
"552007-57DLl7Dd4RRRr11Uu2Rr5Uu3LLLl7", /* Pavo */
"552201+36dLl9d2l4dLl2Ddld6lDd7r2d2RrDd2Rr2d6Rr3ur3dr2Uu3r4drUl3u4l3u4l4Uu6Ll\
", /* Pegasus */
"460209+59d2Ll5d2l2d2Ll12DDd4r3d5RRr2u3r2u3rUUur7Dd2Rr3Uur4u4l4u3Lul9",
/* Perseus */
"650206-40d8RrDdr4d2r3d5RRr8UULLLl6", /* Phoenix */
"640601-43Dd3l2d2l6d3l4Dd4Ru3r7Uu3r7u3Rr7Uu4l5u3LLl", /* Pictor */
"450108+33Ddl4Dd9Ll2Dd7RRr8Dd6Rru3Rr2Uu8Ll14UuLl2u2l2Uu2l10u3r2Uu3Ll8",
/* Pisces */
"562302-25Dd6RRr8Uu5LLl2", /* Piscis Austrinus */
"570807-11DDDd3r6DdRRr14Uu7l9Uu7Ll7UUu9Ll7", /* Puppis */
"560810-18DLl3d5l4Dd7Rr8UUu2l3", /* Pyxis */
"560401-53d3l5d3l3Dd7Rr11Uu3l4u4Ll", /* Reticulum */
"452005+22Dd4Rrur13u2RrUu2Ll5Dl9u2Ll5", /* Sagitta */
"552002-12Dd7l5DDd5Rr10Uu3RRUr4Uu4LLu4Ll2", /* Sagittarius */
"471606-08Dd9lDrd5l7DLLDd5Rr6u3r7UURr3u9LUUu2l6", /* Scorpius */
"560111-25DDRRr8u4r5Uu5LLl11", /* Sculptor */
"551900-04Dd6r9Uu6L", /* Scutum */
"861814+06d4r4Dd4r4Dd6Rr11Ul7d2lu2Llu6RrULl6u3l2ur2u2l8bRbRbRbUbUd4l3Dd6l3Dd4\
Rr12UUUu5Ll2d3RD", /* Serpens */
"551013+07DDd2Rr5UUu7Ll13", /* Sextans */
"640600+29d6r3Dd2ld6r3u3r4ur5dRr5DDRr5dr4UUUlUuLl9Dl4dLL", /* Taurus */
"552007-45Dd7RRr12Uu5LLl7", /* Telescopium */
"560211+37d3l2d3r5Dd2r7d2Rr3u3r4Uu5Ll2u2l9", /* Triangulum */
"561609-60dl3d3l2dLd3l3DdRRRrUu2Ll2u4l3u3l2ULl9", /* Triangulum Australe */
"360106-58DDd5Rr2uRr8Uu3Rr13Uu4Ll7d2LLl6", /* Tucana */
"641107+73Dd4Lld3Ll8dLl7Dd5r5Dd2Rr6Uu2Rr12Dd6rDDd2Rr13Uu3Rr2u6r9UuRr10u5Rr6UU\
r6Uu3LLLl7", /* Ursa Major */
"342200+86RRRRrDr7d5Rr7DRr5d5RRu4r14Uu6l8u3Ll7Uu6RRRRRRr10u2RRRRRRRRRRrd2R",
/* Ursa Minor */
"560907-37DLLlDd7RRRr2u2r5u2r4u2r3Uu7l6Uu3Ll7", /* Vela */
"551309+14Dd2LLl3DdRr3d7r6DDd3RRrUu8RrUu3r5UULu3l14uLl9", /* Virgo */
"560900-64Dd5RRr7Uu6LLL", /* Volans */
"462100+29dl8d4r3DRr5ur5uRrDr9u2Rru3Ll5u2l6u2LL"}; /* Vulpecula */
#endif /* CONSTEL */
#endif /* GRAPH */
X
/* xdata.c */
SHAR_EOF
  $shar_touch -am 1223232998 'xdata.c' &&
  chmod 0644 'xdata.c' ||
  echo 'restore of xdata.c failed'
  shar_count="`wc -c < 'xdata.c'`"
  test 27797 -eq "$shar_count" ||
    echo "xdata.c: original size 27797, current size $shar_count"
fi
# ============= xdevice.c ==============
if test -f 'xdevice.c' && test X"$1" != X"-c"; then
  echo 'x - skipping xdevice.c (File already exists)'
else
  echo 'x - extracting xdevice.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'xdevice.c' &&
/*
** Astrolog (Version 5.40) File: xdevice.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
#ifdef GRAPH
/*
******************************************************************************
** Bitmap File Routines.
******************************************************************************
*/
X
/* Write the bitmap array to a previously opened file in a format that   */
/* can be read in by the Unix X commands bitmap and xsetroot. The 'mode' */
/* parameter defines how much white space is put in the file.            */
X
void WriteXBitmap(file, name, mode)
FILE *file;
char *name, mode;
{
X  int x, y, i, temp = 0;
X  _int value;
X
X  fprintf(file, "#define %s_width %d\n" , name, gs.xWin);
X  fprintf(file, "#define %s_height %d\n", name, gs.yWin);
X  fprintf(file, "static %s %s_bits[] = {",
X    mode != 'V' ? "char" : "short", name);
X  for (y = 0; y < gs.yWin; y++) {
X    x = 0;
X    do {
X
X      /* Process each row, eight columns at a time. */
X
X      if (y + x > 0)
X        fprintf(file, ",");
X      if (temp == 0)
X        fprintf(file, "\n%s",
X          mode == 'N' ? "  " : (mode == 'C' ? " " : ""));
X      value = 0;
X      for (i = (mode != 'V' ? 7 : 15); i >= 0; i--)
X        value = (value << 1) + (!(FBmGet(gi.bm, x+i, y)^
X          (gs.fInverse*15))^gs.fInverse && (x + i < gs.xWin));
X      if (mode == 'N')
X        putc(' ', file);
X      fprintf(file, "0x");
X      if (mode == 'V')
X        fprintf(file, "%c%c",
X          ChHex(value >> 12), ChHex((value >> 8) & 15));
X      fprintf(file, "%c%c",
X        ChHex((value >> 4) & 15), ChHex(value & 15));
X      temp++;
X
X      /* Is it time to skip to the next line while writing the file yet? */
X
X      if ((mode == 'N' && temp >= 12) ||
X          (mode == 'C' && temp >= 15) ||
X          (mode == 'V' && temp >= 11))
X        temp = 0;
X      x += (mode != 'V' ? 8 : 16);
X    } while (x < gs.xWin);
X  }
X  fprintf(file, "};\n");
}
X
X
/* Write the bitmap array to a previously opened file in a simple boolean    */
/* Ascii rectangle, one char per pixel, where '#' represents an off bit and  */
/* '-' an on bit. The output format is identical to the format generated by  */
/* the Unix bmtoa command, and it can be converted into a bitmap with atobm. */
X
void WriteAscii(file)
FILE *file;
{
X  int x, y, i;
X
X  for (y = 0; y < gs.yWin; y++) {
X    for (x = 0; x < gs.xWin; x++) {
X      i = FBmGet(gi.bm, x, y);
X      if (gs.fColor)
X        putc(ChHex(i), file);
X      else
X        putc(i ? '-' : '#', file);
X    }
X    putc('\n', file);
X  }
}
X
X
/* Write the bitmap array to a previously opened file in the bitmap format  */
/* used in Microsoft Windows for its .bmp extension files. This is a pretty */
/* efficient format, only requiring a small header, and one bit per pixel   */
/* for monochrome graphics, or four bits per pixel for full color.          */
X
void WriteBmp(file)
FILE *file;
{
X  int x, y;
X  dword value;
X
X  /* Note that we sometimes only write a part of the full bitmap to disk   */
X  /* during the call, as done when the bitmap is being generated in bands. */
X
X  if (gi.yBand == 0 || gi.yOffset + gi.yBand >= gs.yWin) {
X    /* BitmapFileHeader */
X    PutByte('B'); PutByte('M');
X    PutLong(14+40 + (gs.fColor ? 64 : 8) +
X      (long)4*gs.yWin*((gs.xWin-1 >> (gs.fColor ? 3 : 5))+1));
X    PutWord(0); PutWord(0);
X    PutLong(14+40 + (gs.fColor ? 64 : 8));
X    /* BitmapInfo / BitmapInfoHeader */
X    PutLong(40);
X    PutLong(gs.xWin); PutLong(gs.yWin);
X    PutWord(1); PutWord(gs.fColor ? 4 : 1);
X    PutLong(0 /*BI_RGB*/); PutLong(0);
X    PutLong(0); PutLong(0);
X    PutLong(0); PutLong(0);
X    /* RgbQuad */
X    if (gs.fColor)
X      for (x = 0; x < 16; x++) {
X        PutByte(RGBB(rgbbmp[x])); PutByte(RGBG(rgbbmp[x]));
X        PutByte(RGBR(rgbbmp[x])); PutByte(0);
X      }
X    else {
X      PutLong(0);
X      PutByte(255); PutByte(255); PutByte(255); PutByte(0);
X    }
X  }
X  /* Data */
X  for (y = (gi.yBand ? Min(gi.yBand, gs.yWin - gi.yOffset) : gs.yWin) - 1;
X    y >= 0; y--) {
X    value = 0;
X    for (x = 0; x < gs.xWin; x++) {
X      if ((x & (gs.fColor ? 7 : 31)) == 0 && x > 0) {
X        PutLong(value);
X        value = 0;
X      }
X      if (gs.fColor)
X        value |= (dword)FBmGet(gi.bm, x, y) << ((x & 7 ^ 1) << 2);
X      else
X        if (FBmGet(gi.bm, x, y))
X          value |= (dword)1 << (x & 31 ^ 7);
X    }
X    PutLong(value);
X  }
}
X
X
/* Begin the work of creating a graphics file. Prompt for a filename if */
/* need be, and if valid, create the file and open it for writing.      */
X
void BeginFileX()
{
X  char line[cchSzDef];
X
X  if (us.fNoWrite)
X    return;
#ifndef WIN
X  if (gi.szFileOut == NULL && (
#ifdef PS
X    gi.fEps ||
#endif
X    gs.fMeta || (gs.fBitmap && gs.chBmpMode == 'B'))) {
X    sprintf(line, "(It is recommended to specify an extension of '.%s'.)\n",
X      gs.fBitmap ? "bmp" :
#ifdef PS
X      (gi.fEps ? "eps" : "wmf")
#else
X      "wmf"
#endif
X      );
X    PrintSzScreen(line);
X  }
#endif /* WIN */
X  loop {
X    if (gi.szFileOut == NULL) {
X      sprintf(line, "Enter name of file to write %s to",
X        gs.fBitmap ? "bitmap" : (gs.fPS ? "PostScript" : "metafile"));
X      InputString(line, line);
X      gi.szFileOut = line;
X    }
X    gi.file = fopen(gi.szFileOut, gs.fPS ? "w" : "wb");
X    if (gi.file != NULL)
X      break;
X    else {
X      PrintWarning("Couldn't create output file.");
X      gi.szFileOut = NULL;
X    }
X  }
}
X
X
/* Finish up the work of creating a graphics file. This basically consists */
/* of just calling the appropriate routine to actually write the data in   */
/* memory to a file for bitmaps and metafiles, although for PostScript we  */
/* just close file as we were already writing while creating the chart.    */
X
void EndFileX()
{
X  char sz[cchSzDef];
X
X  if (gs.fBitmap) {
X    if (gi.yBand) {
X      sprintf(sz, "Writing part %d of chart bitmap to file.",
X        gi.yOffset / gi.yBand + 1);
X      PrintNotice(sz);
X    } else
X      PrintNotice("Writing chart bitmap to file.");
X    if (gs.chBmpMode == 'B')
X      WriteBmp(gi.file);
X    else if (gs.chBmpMode == 'A')
X      WriteAscii(gi.file);
X    else
X      WriteXBitmap(gi.file, gi.szFileOut, gs.chBmpMode);
X  }
#ifdef PS
X  else if (gs.fPS)
X    PsEnd();
#endif
#ifdef META
X  else {
X    PrintNotice("Writing metafile to disk.");
X    WriteMeta(gi.file);
X  }
#endif
X  if (!gs.fBitmap || gi.yOffset == 0) {
X    fclose(gi.file);
X    gi.yBand = 0;
X  }
#ifdef WIN
X  if (wi.wCmd == cmdSaveWallTile || wi.wCmd == cmdSaveWallCenter) {
X    WriteProfileString("Desktop", "TileWallpaper",
X      wi.wCmd == cmdSaveWallTile ? "1" : "0");
X    SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, gi.szFileOut,
X      SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
X    wi.wCmd = 0;
X  }
#endif
}
X
X
#ifdef PS
/*
******************************************************************************
** PostScript File Routines.
******************************************************************************
*/
X
/* Table of PostScript header alias lines used by the program. */
X
CONST char FPTR szPsFunctions[] =
"/languagelevel where{pop languagelevel}{1}ifelse\
X 2 lt{\n\
/sf{exch findfont exch\
X dup type/arraytype eq{makefont}{scalefont}ifelse setfont}bind def\n\
/rf{gsave newpath\n\
4 -2 roll moveto\
X dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath\n\
fill grestore}bind def\n\
/rc{newpath\n\
4 -2 roll moveto\
X dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath\n\
clip newpath}bind def\n\
}{/sf/selectfont load def/rf/rectfill load def\
/rc/rectclip load def}ifelse\n\
/center{0 begin gsave dup 4 2 roll\
X translate newpath 0 0 moveto\
X false charpath flattenpath pathbbox\
X /URy exch def/URx exch def/LLy exch def/LLx exch def\
X URx LLx sub 0.5 mul LLx add neg URy LLy sub 0.5 mul LLy add neg\
X 0 0 moveto rmoveto\
X show grestore end}bind def\n\
/center load 0 4 dict put\n\
/c{setrgbcolor}bind def\n\
/d{moveto 0 0 rlineto}bind def\n\
/l{4 2 roll moveto lineto}bind def\n\
/t{lineto}bind def\n\
/el{newpath matrix currentmatrix 5 1 roll translate scale\
X 0 0 1 0 360 arc setmatrix stroke}bind def\n";
X
X
/* Write a command to flush the PostScript buffer. */
X
void PsStrokeForce()
{
X  if (gi.cStroke > 0) {              /* render any existing path */
X    fprintf(gi.file, "stroke\n");
X    gi.cStroke = 0;
X    gi.xPen = -1;                    /* Invalidate PolyLine cache */
X  }
}
X
X
/* Indicate that a certain number of PostScript commands have been done. */
X
void PsStroke(n)
int n;
{
X  gi.cStroke += n;
X  if (gi.cStroke > 2000)    /* Whenever we reach a certain limit, flush. */
X    PsStrokeForce();
}
X
X
/* Set the type of line end to be used by PostScript commands. If linecap */
/* is true, then the line ends are rounded, otherwise they are squared.   */
X
void PsLineCap(fLineCap)
bool fLineCap;
{
X  if (fLineCap != gi.fLineCap) {
X    PsStrokeForce();
X    fprintf(gi.file, "%d setlinecap\n", fLineCap);
X    gi.fLineCap = fLineCap;
X  }
}
X
X
/* Set the dash length to be used by PostScript line commands. */
X
void PsDash(dashoff)
int dashoff;
{
X  if (dashoff != gi.nDash) {
X    PsStrokeForce();
X    if (dashoff)
X      fprintf(gi.file, "[%d %d", PSMUL, dashoff * PSMUL);
X    else
X      fprintf(gi.file, "[");
X    fprintf(gi.file, "]0 setdash\n");
X    gi.nDash = dashoff;
X  }
}
X
X
/* Set a linewidth size to be used by PostScript figure primitive commands. */
X
void PsLineWidth(linewidth)
int linewidth;
{
X  if ((real)linewidth != gi.rLineWid) {
X    PsStrokeForce();
X    fprintf(gi.file, "%d setlinewidth\n", linewidth);
X    gi.rLineWid = (real)linewidth;
X  }
}
X
X
/* Set a system font and size to be used by PostScript text commands. */
X
void PsFont(psfont)
int psfont;
{
X  int z;
X
X  if (psfont != gi.nFont && gs.fFont) {
X    if (psfont <= 2) {
X      z = psfont == 1 ? 32*PSMUL : 23*PSMUL;
X      fprintf(gi.file, "/Astro[%d 0 0 -%d 0 0]sf\n", z, z);
X    } else if (psfont == 3) {
X      z = 26*PSMUL;
X      fprintf(gi.file, "/Times-Roman[%d 0 0 -%d 0 0]sf\n", z, z);
X    } else {
X      z = 10*PSMUL;
X      fprintf(gi.file, "/Courier[%d 0 0 -%d 0 0]sf\n", z, z);
X    }
X    gi.nFont = psfont;
X  }
}
X
X
/* Prompt the user for the name of a file to write the PostScript file to */
/* (if not already specified), open it, and write out file header info.   */
X
void PsBegin()
{
X  fprintf(gi.file, "%%!PS-Adobe-2.0");
X  if (gi.fEps)
X    fprintf(gi.file, " EPSF-2.0");
X  fprintf(gi.file, "\n%%%%Title: %s\n", gi.szFileOut);
X  fprintf(gi.file, "%%%%Creator: %s %s\n", szAppName, szVersionCore);
X  fprintf(gi.file, "%%%%CreationDate: %s\n", szDateCore);
X  if (gi.fEps) {
X    fprintf(gi.file, "%%%%BoundingBox: 0 0 %d %d\n", gs.xWin, gs.yWin);
X    fprintf(gi.file, "%%%%EndComments\n");
X    fprintf(gi.file, "%%%%BeginSetup\n");
X    fprintf(gi.file, szPsFunctions, 6 * PSMUL, 6 * PSMUL);
X    fprintf(gi.file, "%%%%EndSetup\n");
X    fprintf(gi.file, "0 0 %d %d rc\n", gs.xWin, gs.yWin);
X  } else {
X    fprintf(gi.file, "%%%%Pages: 1 1\n");
X    fprintf(gi.file, "%%%%DocumentFonts: (atend)\n");
X    fprintf(gi.file, "%%%%BoundingBox: %d %d %d %d\n", PSGUTTER, PSGUTTER,
X      (int)(gs.xInch*72.0+rRound)-PSGUTTER,
X      (int)(gs.yInch*72.0+rRound)-PSGUTTER);
X    fprintf(gi.file, "%%%%EndComments\n");
X    fprintf(gi.file, "%%%%BeginProcSet: common\n");
X    fprintf(gi.file, szPsFunctions, 6 * PSMUL, 6 * PSMUL);
X    fprintf(gi.file, "%%%%EndProcSet\n");
X    fprintf(gi.file, "%%%%Page: 1 1\n");
X  }
X  PsFont(2);
X  fprintf(gi.file, "gsave\n");
X  PsLineWidth(gi.nPenWid/2);
X  gi.xPen = -1;
X  PrintNotice("Creating PostScript chart file.");
}
X
X
/* Write out trailing information to the PostScript file and close it. */
X
void PsEnd()
{
X  PsStrokeForce();
X  if (gi.fEps)
X    fprintf(gi.file, "%%%%EOF\n");
X  else {
X    fprintf(gi.file, "showpage\n");
X    fprintf(gi.file, "%%%%PageTrailer\n");
X    fprintf(gi.file, "%%%%Trailer\n");
X    fprintf(gi.file, "%%%%DocumentFonts: Times-Roman\n");
X    if (gs.fFont) {
X      fprintf(gi.file, "%%%%+ Courier\n");
X      fprintf(gi.file, "%%%%+ Astro\n");
X    }
X  }
X  fclose(gi.file);
}
#endif /* PS */
X
X
#ifdef META
/*
******************************************************************************
** Metafile Routines.
******************************************************************************
*/
X
/* Output one 16 bit or 32 bit value into the metafile buffer stream. */
X
void MetaWord(w)
word w;
{
X  char sz[cchSzDef];
X
X  if ((hpbyte)gi.pwMetaCur - gi.bm >= gi.cbMeta) {
X    sprintf(sz, "Metafile would be more than %ld bytes.", gi.cbMeta);
X    PrintError(sz);
X    Terminate(tcFatal);
X  }
X  *gi.pwMetaCur = w;
X  gi.pwMetaCur++;
}
X
void MetaLong(l)
long l;
{
X  MetaWord(WLo(l));
X  MetaWord(WHi(l));
}
X
X
/* Output any necessary metafile records to make the current actual     */
/* settings of line color, fill color, etc, be those that we know are   */
/* desired. This is generally called by the primitives routines before  */
/* any figure record is actually written into a metafile. We wait until */
/* the last moment before changing any settings to ensure that we don't */
/* output any unnecessary records, e.g. two select colors in a row.     */
X
void MetaSelect()
{
X  if (gi.kiLineDes != gi.kiLineAct) {
X    MetaSelectObject(gi.kiLineDes);
X    gi.kiLineAct = gi.kiLineDes;
X  }
X  if (gi.kiFillDes != gi.kiFillAct) {
X    MetaSelectObject(16*4 + gi.kiFillDes);
X    gi.kiFillAct = gi.kiFillDes;
X  }
X  if (gi.nFontDes != gi.nFontAct) {
X    MetaSelectObject(16*5 + gi.nFontDes);
X    gi.nFontAct = gi.nFontDes;
X  }
X  if (gi.kiTextDes != gi.kiTextAct) {
X    MetaTextColor(rgbbmp[gi.kiTextDes]);
X    gi.kiTextAct = gi.kiTextDes;
X  }
X  if (gi.nAlignDes != gi.nAlignAct) {
X    MetaTextAlign(gi.nAlignDes);
X    gi.nAlignAct = gi.nAlignDes;
X  }
X  gi.xPen = -1;    /* Invalidate PolyLine cache */
}
X
X
/* Output initial metafile header information into our metafile buffer. */
/* We also setup and create all pen, brush, and font objects that may   */
/* possibly be used in the generation and playing of the picture.       */
X
void MetaInit()
{
X  int i, j, k;
X
X  gi.pwMetaCur = (word HPTR *)gi.bm;
X  /* Placable Metaheader */
X  MetaLong(0x9AC6CDD7L);
X  MetaWord(0);      /* Not used */
X  MetaWord(0); MetaWord(0);
X  MetaWord(gs.xWin); MetaWord(gs.yWin);
X  MetaWord(gs.xWin/6);                     /* Units per inch */
X  MetaLong(0L);     /* Not used */
X  MetaWord(0x9AC6 ^ 0xCDD7 ^ gs.xWin ^ gs.yWin ^ gs.xWin/6);  /* Checksum */
X  /* Metaheader */
X  MetaWord(1);                      /* Metafile type                    */
X  MetaWord(9);                      /* Size of header in words          */
X  MetaWord(0x300);                  /* Windows version                  */
X  MetaLong(0L);                     /* Size of entire metafile in words */
X  MetaWord(16*5+1+(gs.fFont>0)*4);  /* Number of objects in metafile    */
X  MetaLong(17L);                    /* Size of largest record in words  */
X  MetaWord(0);                      /* Not used                         */
X  /* Setup */
X  MetaEscape(17);
X  MetaLong(LFromBB('A', 's', 't', 'r'));  /* "Astr" */
X  MetaWord(4);                            /* Creator */
X  MetaLong(14L);                          /* Bytes in string */
X  MetaLong(LFromBB('A', 's', 't', 'r'));  /* "Astr" */
X  MetaLong(LFromBB('o', 'l', 'o', 'g'));  /* "olog" */
X  MetaLong(LFromBB(' ', '5', '.', '4'));  /* " 5.4" */
X  MetaWord(WFromBB('0', 0));              /* "0"    */
X  MetaSaveDc();
X  MetaWindowOrg(0, 0);
X  MetaWindowExt(gs.xWin, gs.yWin);
X  MetaBkMode(1 /* Transparent */);
X  /* Colors */
X  for (j = 1; j <= 4; j++)
X    for (i = 0; i < 16; i++) {
X      k = j <= 1 ? gi.nPenWid : 0;
X      MetaCreatePen(j <= 2 ? 0 : j-2 /* PS_SOLID; PS_DASH; PS_DOT */,
X        k, rgbbmp[i]);
X    }
X  for (i = 0; i < 16; i++) {
X    MetaCreateBrush(0 /* BS_SOLID */, rgbbmp[i]);
X  }
X  MetaCreateBrush(1 /* BS_NULL */, 0L);
X  /* Fonts */
X  if (gs.fFont) {
X    MetaCreateFont(5, 0, -8*gi.nScale, 2 /* Symbol Charset */);
X    MetaWord(WFromBB(1 /* Draft */, 1 | 0x10 /* Fixed | Roman */));
X    MetaLong(LFromBB('W', 'i', 'n', 'g'));
X    MetaLong(LFromBB('d', 'i', 'n', 'g'));
X    MetaWord(WFromBB('s', 0));
X
X    MetaCreateFont(8, 0, -6*gi.nScale, 0 /* Ansi Charset */);
X    MetaWord(WFromBB(0 /* Default */, 2 | 0x10 /* Variable | Roman */));
X    MetaLong(LFromBB('T', 'i', 'm', 'e'));
X    MetaLong(LFromBB('s', ' ', 'N', 'e'));
X    MetaLong(LFromBB('w', ' ', 'R', 'o'));
X    MetaLong(LFromBB('m', 'a', 'n', 0));
X
X    MetaCreateFont(6, 6*METAMUL, 10*METAMUL, 0 /* Ansi Charset */);
X    MetaWord(WFromBB(1 /* Draft */, 1 | 0x30 /* Fixed | Modern */));
X    MetaLong(LFromBB('C', 'o', 'u', 'r'));
X    MetaLong(LFromBB('i', 'e', 'r', ' '));
X    MetaLong(LFromBB('N', 'e', 'w', 0));
X
X    MetaCreateFont(8, 0, -11*gi.nScale, 0 /* Ansi Charset */);
X    MetaWord(WFromBB(0 /* Default */, 2 | 0 /* Variable | Don't Care */));
X    MetaLong(LFromBB('A', 's', 't', 'r'));
X    MetaLong(LFromBB('o', '-', 'S', 'e'));
X    MetaLong(LFromBB('m', 'i', 'B', 'o'));
X    MetaLong(LFromBB('l', 'd', 0, 0));
X  }
}
X
X
/* Output trailing records to indicate the end of the metafile and then */
/* actually write out the entire buffer to the specifed file.           */
X
void WriteMeta(file)
FILE *file;
{
X  word HPTR *w;
#if FALSE
X  int i;
X
X  for (i = 16*5+1+(gs.fFont>0)*4; i >= 0; i--) {
X    MetaDeleteObject(i);
X  }
#endif
X  MetaRestoreDc();
X  MetaRecord(3, 0);    /* End record */
X  *(long HPTR *)(gi.bm + 22 + 6) =
X    ((long)((hpbyte)gi.pwMetaCur - gi.bm) - 22) / 2;
X  for (w = (word HPTR *)gi.bm; w < gi.pwMetaCur; w++) {
X    PutWord(*w);
X  }
}
#endif /* META */
X
X
#ifdef MOUSE
#ifdef PC
/*
******************************************************************************
** Mouse Routines.
******************************************************************************
*/
X
static union REGS dosreg;
X
X
/* Setup and initialize the PC graphics mouse, returning the number of    */
/* buttons available, or zero for no mouse at all. Passed in is the pixel */
/* size of the screen the mouse pointer is to be contained within.        */
X
int MouseInit(x, y)
int x, y;
{
X  int dx, cBtn;
X
X  if (!gs.fMouse)
X    return 0;
X  dosreg.x.ax = 0;
X  int86(0x33, &dosreg, &dosreg);
X  if (!(gs.fMouse = dosreg.x.ax))
X    return 0;
X  cBtn = dosreg.x.bx;
X  dx = x - 1;
X  dosreg.x.ax = 7;
X  dosreg.x.cx = 0;
X  dosreg.x.dx = dx;
X  int86(0x33, &dosreg, &dosreg);
X  dx = y - 1;
X  dosreg.x.ax = 8;
X  dosreg.x.cx = 0;
X  dosreg.x.dx = dx;
X  int86(0x33, &dosreg, &dosreg);
X  return cBtn;
}
X
X
/* Turn on or hide the PC graphics mouse pointer. */
X
void MouseShow(fShow)
bool fShow;
{
X  int ax;
X
X  if (!gs.fMouse)
X    return;
X  ax = fShow ? 1 : 2;
X  dosreg.x.ax = ax;
X  int86(0x33, &dosreg, &dosreg);
}
X
X
/* Fill out the current status of the mouse: its horizontal and vertical  */
/* position, and button press status. We return false if the mouse hasn't */
/* changed any from the last call (assuming that the previous values are  */
/* stored in the input parameters) or if the mouse isn't active at all.   */
X
bool MouseStatus(x, y, btn)
int *x, *y, *btn;
{
X  int bx, cx, dx, fChange;
X
X  if (!gs.fMouse)
X    return fFalse;
X  dosreg.x.ax = 3;
X  int86(0x33, &dosreg, &dosreg);
X  bx = dosreg.x.bx;
X  cx = dosreg.x.cx;
X  dx = dosreg.x.dx;
X  fChange = (cx != *x || dx != *y || bx != *btn);
X  *x = cx;
X  *y = dx;
X  *btn = bx;
X  return fChange;
}
#endif /* PC */
#endif /* MOUSE */
#endif /* GRAPH */
X
/* xdevice.c */
SHAR_EOF
  $shar_touch -am 1223232998 'xdevice.c' &&
  chmod 0644 'xdevice.c' ||
  echo 'restore of xdevice.c failed'
  shar_count="`wc -c < 'xdevice.c'`"
  test 20948 -eq "$shar_count" ||
    echo "xdevice.c: original size 20948, current size $shar_count"
fi
# ============= xgeneral.c ==============
if test -f 'xgeneral.c' && test X"$1" != X"-c"; then
  echo 'x - skipping xgeneral.c (File already exists)'
else
  echo 'x - extracting xgeneral.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'xgeneral.c' &&
/*
** Astrolog (Version 5.40) File: xgeneral.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
#ifdef GRAPH
/*
******************************************************************************
** Core Graphic Procedures.
******************************************************************************
*/
X
/* Set the current color to use in drawing on the screen or bitmap array. */
X
void DrawColor(col)
KI col;
{
#ifdef WIN
X  HPEN hpenT;
#endif
#ifdef MACG
X  RGBColor kv;
#endif
X
X  if (gi.fFile) {
#ifdef PS
X    if (gs.fPS) {
X      if (gi.kiCur != col) {
X        PsStrokeForce();      /* Render existing path with current color */
X        fprintf(gi.file, "%.2f %.2f %.2f c\n",
X          (real)RGBR(rgbbmp[col])/255.0, (real)RGBG(rgbbmp[col])/255.0,
X          (real)RGBB(rgbbmp[col])/255.0);
X      }
X    }
#endif
#ifdef META
X    if (gs.fMeta)
X      gi.kiLineDes = col;
#endif
X  }
#ifdef X11
X  else
X    XSetForeground(gi.disp, gi.gc, rgbind[col]);
#endif
#ifdef WIN
X  else {
X    if (gi.kiCur != col) {
X      hpenT = wi.hpen;
X      wi.hpen = CreatePen(PS_SOLID, gi.nScaleT, (COLORREF)rgbbmp[col]);
X      SelectObject(wi.hdc, wi.hpen);
X      if (hpenT != (HPEN)NULL)
X        DeleteObject(hpenT);
X    }
X  }
#endif
#ifdef MSG
X  else
X    _setcolor(col);
#endif
#ifdef BGI
X  else
X    setcolor(col);
#endif
#ifdef MACG
X  else {
X    kv.red   = RGBR(rgbbmp[col]) << 8;
X    kv.green = RGBG(rgbbmp[col]) << 8;
X    kv.blue  = RGBB(rgbbmp[col]) << 8;
X    RGBForeColor(&kv);
X    RGBBackColor(&kv);
X  }
#endif
X  gi.kiCur = col;
}
X
X
/* Set a single point on the screen. This is the most basic graphic function */
/* and is called by all the more complex routines. Based on what mode we are */
/* in, we either set a cell in the bitmap array or a pixel on the window.    */
X
void DrawPoint(x, y)
int x, y;
{
X  if (gi.fFile) {
X    if (gs.fBitmap) {
X      /* Force the coordinates to be within the bounds of the bitmap array. */
X
X      if (x < 0)
X        x = 0;
X      else if (x >= gs.xWin)
X        x = gs.xWin-1;
X      if (y < 0)
X        y = 0;
X      else if (y >= gs.yWin)
X        y = gs.yWin-1;
X      if (gi.yBand) {
X        y -= gi.yOffset;
X        if (y < 0 || y >= gi.yBand)
X          return;
X      }
X      BmSet(gi.bm, x, y, gi.kiCur);
X    }
#ifdef PS
X    else if (gs.fPS) {
X      DrawColor(gi.kiCur);
X      PsLineCap(fTrue);
X      fprintf(gi.file, "%d %d d\n", x, y);
X      PsStroke(2);
X    }
#endif
#ifdef META
X    else {
X      gi.kiFillDes = gi.kiCur;
X      MetaSelect();
X      MetaEllipse(x-gi.nPenWid/2, y-gi.nPenWid/2,
X        x+gi.nPenWid/2, y+gi.nPenWid/2);
X    }
#endif
X  }
#ifdef X11
X  else
X    XDrawPoint(gi.disp, gi.pmap, gi.gc, x, y);
#endif
#ifdef WIN
X  else {
X    if (wi.hdcPrint == hdcNil)
X      SetPixel(wi.hdc, x, y, (COLORREF)rgbbmp[gi.kiCur]);
X    else {
X      MoveTo(wi.hdc, x, y);
X      LineTo(wi.hdc, x, y);
X    }
X  }
#endif
#ifdef MSG
X  else
X    _setpixel(gi.xOffset + x, gi.yOffset + y);
#endif
#ifdef BGI
X  else
X    putpixel(gi.xOffset + x, gi.yOffset + y, gi.kiCur);
#endif
#ifdef MACG
X  else {
X    MoveTo(x, y); LineTo(x, y);
X  }
#endif
}
X
X
/* Draw dot a little larger than just a single pixel at specified location. */
X
void DrawSpot(x, y)
int x, y;
{
#ifdef PS
X  if (gs.fPS) {
X    PsLineWidth((int)(gi.rLineWid*3.0));
X    DrawPoint(x, y);
X    PsLineWidth((int)(gi.rLineWid/3.0));
X    return;
X  }
#endif
#ifdef META
X  if (gs.fMeta) {
X    gi.kiFillDes = gi.kiCur;
X    MetaSelect();
X    MetaEllipse(x-gi.nPenWid, y-gi.nPenWid, x+gi.nPenWid, y+gi.nPenWid);
X    return;
X  }
#endif
X  DrawPoint(x, y);
X  DrawPoint(x, y-1);
X  DrawPoint(x-1, y);
X  DrawPoint(x+1, y);
X  DrawPoint(x, y+1);
}
X
X
/* Draw a filled in block, defined by the corners of its rectangle. */
X
void DrawBlock(x1, y1, x2, y2)
int x1, y1, x2, y2;
{
X  int x, y;
#ifdef MACG
X  Rect rc;
#endif
X
X  if (gi.fFile) {
X    if (gs.fBitmap) {
X      /* Force the coordinates to be within the bounds of the bitmap band. */
X
X      if (x1 < 0)
X        x1 = 0;
X      if (x2 >= gs.xWin)
X        x2 = gs.xWin-1;
X      if (gi.yBand) {
X        y1 -= gi.yOffset;
X        if (y1 < 0)
X          y1 = 0;
X        y2 -= gi.yOffset;
X        if (y2 >= gi.yBand)
X          y2 = gi.yBand-1;
X      }
X      for (y = y1; y <= y2; y++)           /* For bitmap, we have to  */
X        for (x = x1; x <= x2; x++)         /* just fill in the array. */
X          BmSet(gi.bm, x, y, gi.kiCur);
X    }
#ifdef PS
X    else if (gs.fPS) {
X      DrawColor(gi.kiCur);
X      fprintf(gi.file, "%d %d %d %d rf\n",
X        Max(x1-gi.nPenWid/4, 0), Max(y1-gi.nPenWid/4, 0),
X        x2-x1+gi.nPenWid/4, y2-y1+gi.nPenWid/4);
X    }
#endif
#ifdef META
X    else {
X      gi.kiFillDes = gi.kiCur;
X      MetaSelect();
X      MetaRectangle(x1-gi.nPenWid/2, y1-gi.nPenWid/2,
X        x2+gi.nPenWid/2, y2+gi.nPenWid/2);
X    }
#endif
X  }
#ifdef X11
X  else
X    XFillRectangle(gi.disp, gi.pmap, gi.gc, x1, y1, x2-x1, y2-y1);
#endif
#ifdef WIN
X  else {
X    wi.hbrush = CreateSolidBrush((COLORREF)rgbbmp[gi.kiCur]);
X    SelectObject(wi.hdc, wi.hbrush);
X    PatBlt(wi.hdc, x1, y1, x2-x1 + 1, y2-y1 + 1, PATCOPY);
X    SelectObject(wi.hdc, GetStockObject(NULL_BRUSH));
X    DeleteObject(wi.hbrush);
X  }
#endif
#ifdef MSG
X  else
X    _rectangle(_GFILLINTERIOR,
X      gi.xOffset + x1, gi.yOffset + y1, gi.xOffset + x2, gi.yOffset + y2);
#endif
#ifdef BGI
X  else {
X    setfillstyle(SOLID_FILL, gi.kiCur);
X    bar(gi.xOffset + x1, gi.yOffset + y1, gi.xOffset + x2, gi.yOffset + y2);
X  }
#endif
#ifdef MACG
X  else {
X    SetRect(&rc, x1, y1, x2+1, y2+1);
X    EraseRect(&rc);
X  }
#endif
}
X
X
/* Draw a rectangle on the screen with specified thickness. This is just   */
/* like DrawBlock() except that we are only drawing the edges of the area. */
X
void DrawBox(x1, y1, x2, y2, xsiz, ysiz)
int x1, y1, x2, y2, xsiz, ysiz;
{
#ifdef META
X  if (gs.fMeta)
X    /* For thin boxes in metafiles, we can just output one rectangle record */
X    /* instead of drawing each side separately as we have to do otherwise.  */
X    if (xsiz <= 1 && ysiz <= 1) {
X      gi.kiFillDes = kNull;          /* Specify a hollow fill brush. */
X      MetaSelect();
X      MetaRectangle(x1, y1, x2, y2);
X      return;
X    }
#endif
X  DrawBlock(x1, y1, x2, y1 + ysiz - 1);
X  DrawBlock(x1, y1 + ysiz, x1 + xsiz - 1, y2 - ysiz);
X  DrawBlock(x2 - xsiz + 1, y1 + ysiz, x2, y2 - ysiz);
X  DrawBlock(x1, y2 - ysiz + 1, x2, y2);
}
X
X
/* Clear and erase the graphics screen or bitmap contents. */
X
void DrawClearScreen()
{
#ifdef PS
X  if (gs.fPS) {
X    /* For PostScript charts first output page orientation information. */
X    if (!gi.fEps) {
X      if (gs.nOrient == 0)
X        gs.nOrient = gs.xWin > gs.yWin ? -1 : 1;
X      if (gs.nOrient < 0) {
X        /* chartx and charty are reversed for Landscape mode. */
X        fprintf(gi.file, "%d %d translate\n",
X          ((int)(gs.xInch*72.0+rRound) + gs.yWin)/2,
X          ((int)(gs.yInch*72.0+rRound) + gs.xWin)/2);
X        fprintf(gi.file, "-90 rotate\n");
X      } else {
X        /* Most charts are in Portrait mode */
X        fprintf(gi.file, "%d %d translate\n",
X          ((int)(gs.xInch*72.0+rRound) - gs.xWin)/2,
X          ((int)(gs.yInch*72.0+rRound) + gs.yWin)/2);
X      }
X    } else
X      fprintf(gi.file, "0 %d translate\n", gs.yWin);
X    fprintf(gi.file, "1 -1 scale\n");
X    gs.nScale *= PSMUL; gs.xWin *= PSMUL; gs.yWin *= PSMUL; gi.nScale *= PSMUL;
X    fprintf(gi.file, "1 %d div dup scale\n", PSMUL);
X  }
#endif
#ifdef META
X  if (gs.fMeta)
X    MetaInit();    /* For metafiles first go write our header information. */
#endif
X
X  /* Don't actually erase the screen if the -Xj switch is in effect. */
X  if (gs.fJetTrail)
X    return;
X
#ifdef MSG
X  if (!gi.fFile)
X    _clearscreen(_GCLEARSCREEN);
#endif
#ifdef BGI
X  if (!gi.fFile)
X    clearviewport();
#endif
X  DrawColor(gi.kiOff);
X  DrawBlock(0, 0, gs.xWin - 1, gs.yWin - 1);    /* Clear bitmap screen. */
}
X
X
/* Draw a line on the screen, specified by its endpoints. In addition, we */
/* have specified a skip factor, which allows us to draw dashed lines.    */
X
void DrawDash(x1, y1, x2, y2, skip)
int x1, y1, x2, y2, skip;
{
X  int x = x1, y = y1, xadd, yadd, yinc, xabs, yabs, i, j = 0;
X
X  if (skip < 0)
X    skip = 0;
#ifdef ISG
X  if (!gi.fFile) {
X    if (!skip) {
#ifdef X11
X      /* For non-dashed X window lines, let's have the Xlib do it for us. */
X
X      XDrawLine(gi.disp, gi.pmap, gi.gc, x1, y1, x2, y2);
#endif
#ifdef WIN
X      /* For Windows lines, we have to manually draw the last pixel. */
X
X      MoveTo(wi.hdc, x1, y1);
X      LineTo(wi.hdc, x2, y2);
X      SetPixel(wi.hdc, x2, y2, (COLORREF)rgbbmp[gi.kiCur]);
#endif
#ifdef PCG
X      /* For non-dashed lines, let's have the graphics library do it for us. */
X
X      PcMoveTo(gi.xOffset + x1, gi.yOffset + y1);
X      PcLineTo(gi.xOffset + x2, gi.yOffset + y2);
#endif
#ifdef MACG
X      MoveTo(x1, y1);
X      LineTo(x2, y2);
#endif
X      return;
X    }
#ifdef WIN
X    if (skip && wi.hdcPrint != hdcNil)
X      skip = (skip + 1)*METAMUL - 1;
#endif
X  }
#endif /* ISG */
X
#ifdef PS
X  if (gs.fPS) {
X
X    /* For PostScript charts we can save file size if we output a LineTo  */
X    /* command when the start vertex is the same as the end vertex of the */
X    /* previous line drawn, instead of writing out both vertices.         */
X
X    PsLineCap(fTrue);
X    PsDash(skip);
X    if (gi.xPen != x1 || gi.yPen != y1)
X      fprintf(gi.file, "%d %d %d %d l\n", x1, y1, x2, y2);
X    else
X      fprintf(gi.file, "%d %d t\n", x2, y2);
X    gi.xPen = x2; gi.yPen = y2;
X    PsStroke(2);
X    return;
X  }
#endif
X
#ifdef META
X  if (gs.fMeta) {
X
X    /* For metafile charts we can really save file size for consecutive */
X    /* lines sharing endpoints by consolidating them into a PolyLine.   */
X
X    if (gi.xPen != x1 || gi.yPen != y1) {
X      gi.kiLineDes = (gi.kiLineDes & 15) + 16*(skip > 3 ? 3 : skip);
X      MetaSelect();
X      gi.pwPoly = gi.pwMetaCur;
X      MetaRecord(8, 0x325);      /* Polyline */
X      MetaWord(2); MetaWord(x1); MetaWord(y1);
X    } else {
X      *gi.pwPoly += 2;
X      (*(gi.pwPoly+3))++;
X      /* Note: We should technically update the max record size in the   */
X      /* file header if need be here too, but it doesn't seem necessary. */
X    }
X    MetaWord(x2); MetaWord(y2);
X    gi.xPen = x2; gi.yPen = y2;
X    return;
X  }
#endif
X
X  /* If none of the above cases hold, we have to draw the line dot by dot. */
X
X  xadd = x2 - x1 >= 0 ? 1 : 3;
X  yadd = y2 - y1 >= 0 ? 2 : 4;
X  xabs = abs(x2 - x1);
X  yabs = abs(y2 - y1);
X
X  /* Technically what we're doing here is drawing a line which is more    */
X  /* horizontal then vertical. We always increment x by 1, and increment  */
X  /* y whenever a fractional variable passes a certain amount. For lines  */
X  /* that are more vertical than horizontal, we just swap x and y coords. */
X
X  if (xabs < yabs) {
X    SwapN(xadd, yadd);
X    SwapN(xabs, yabs);
X  }
X  yinc = (xabs >> 1) - ((xabs & 1 ^ 1) && xadd > 2);
X  for (i = xabs + 1; i; i--) {
X    if (j < 1)
X      DrawPoint(x, y);
X    j = j < skip ? j+1 : 0;
X    switch (xadd) {
X    case 1: x++; break;
X    case 2: y++; break;
X    case 3: x--; break;
X    case 4: y--; break;
X    }
X    yinc += yabs;
X    if (yinc - xabs >= 0) {
X      yinc -= xabs;
X      switch (yadd) {
X      case 1: x++; break;
X      case 2: y++; break;
X      case 3: x--; break;
X      case 4: y--; break;
X      }
X    }
X  }
}
X
X
/* Draw a normal line on the screen; however, if the x coordinates are close */
/* to either of the two given bounds, then we assume that the line runs off  */
/* one side and reappears on the other, so draw the appropriate two lines    */
/* instead. This is used by the Ley line and astro-graph routines, which     */
/* draw lines running around the world and hence off the edges of the maps.  */
X
void DrawWrap(x1, y1, x2, y2, xmin, xmax)
int x1, y1, x2, y2, xmin, xmax;
{
X  int xmid, ymid, i, j, k;
X
X  if (x1 < 0) {           /* Special case for drawing world map. */
X    DrawPoint(x2, y2);
X    return;
X  }
X  j = (xmin < 0);    /* Negative xmin means always draw forward. */
X  if (j)
X    neg(xmin);
X  xmid = (xmax-xmin) / 2;
X  if (j)
X    k = (x1 < x2 ? xmid*7 : xmid)/4;
X  else
X    k = xmid;
X
X  /* If endpoints aren't near opposite edges, just draw the line and return. */
X
X  if (abs(x2-x1) < k-xmin) {
X    DrawLine(x1, y1, x2, y2);
X    return;
X  }
X  if ((i = (xmax-xmin+1) + (!j && x1 < xmid ? x1-x2 : x2-x1)) == 0)
X    i = 1;
X
X  /* Determine vertical coordinate where our line runs off edges of screen. */
X
X  ymid = y1+(int)((real)(y2-y1)*
X    (!j && x1 < xmid ? (real)(x1-xmin) : (real)(xmax-x1))/(real)i + rRound);
X  DrawLine(x1, y1, !j && x1 < xmid ? xmin : xmax, ymid);
X  DrawLine(j || x2 < xmid ? xmin : xmax, ymid, x2, y2);
}
X
X
/* This routine, and its companion below, clips a line defined by its  */
/* endpoints to either above some line y=c, or below some line y=c. By */
/* passing in parameters in different orders, we can clip to vertical  */
/* lines, too. These are used by the DrawClip() routine below.         */
X
void ClipLesser(x1, y1, x2, y2, s)
int *x1, *y1, *x2, *y2, s;
{
X  *x1 -= (int)((long)(*y1-s)*(*x2-*x1)/(*y2-*y1));
X  *y1 = s;
}
X
void ClipGreater(x1, y1, x2, y2, s)
int *x1, *y1, *x2, *y2, s;
{
X  *x1 += (int)((long)(s-*y1)*(*x2-*x1)/(*y2-*y1));
X  *y1 = s;
}
X
X
/* Draw a line on the screen. This is just like DrawLine() routine earlier; */
/* however, first clip the endpoints to the given viewport before drawing.  */
X
void DrawClip(x1, y1, x2, y2, xl, yl, xh, yh, skip)
int x1, y1, x2, y2, xl, yl, xh, yh, skip;
{
X  if (x1 < xl)
X    ClipLesser (&y1, &x1, &y2, &x2, xl);    /* Check left side of window. */
X  if (x2 < xl)
X    ClipLesser (&y2, &x2, &y1, &x1, xl);
X  if (y1 < yl)
X    ClipLesser (&x1, &y1, &x2, &y2, yl);    /* Check top side of window.  */
X  if (y2 < yl)
X    ClipLesser (&x2, &y2, &x1, &y1, yl);
X  if (x1 > xh)
X    ClipGreater(&y1, &x1, &y2, &x2, xh);    /* Check right of window.  */
X  if (x2 > xh)
X    ClipGreater(&y2, &x2, &y1, &x1, xh);
X  if (y1 > yh)
X    ClipGreater(&x1, &y1, &x2, &y2, yh);    /* Check bottom of window. */
X  if (y2 > yh)
X    ClipGreater(&x2, &y2, &x1, &y1, yh);
X  DrawDash(x1, y1, x2, y2, skip);           /* Go draw the line.       */
}
X
X
/* Draw a circle or ellipse inside the given bounding rectangle. */
X
void DrawEllipse(x1, y1, x2, y2)
int x1, y1, x2, y2;
{
X  int x, y, rx, ry, m, n, u, v, i;
#ifdef MACG
X  Rect rc;
#endif
X
X  if (gi.fFile) {
X    x = (x1+x2)/2; y = (y1+y2)/2; rx = (x2-x1)/2; ry = (y2-y1)/2;
X    if (gs.fBitmap) {
X      m = x + rx; n = y;
X      for (i = 0; i <= nDegMax; i += DEGINC) {
X        u = x + (int)(((real)rx+rRound)*RCosD((real)i));
X        v = y + (int)(((real)ry+rRound)*RSinD((real)i));
X        DrawLine(m, n, u, v);
X        m = u; n = v;
X      }
X    }
#ifdef PS
X    else if (gs.fPS) {
X      PsLineCap(fFalse);
X      PsStrokeForce();
X      PsDash(0);
X      fprintf(gi.file, "%d %d %d %d el\n", rx, ry, x, y);
X    }
#endif
#ifdef META
X    else {
X      gi.kiFillDes = kNull;    /* Specify a hollow fill brush. */
X      MetaSelect();
X      MetaEllipse(x1+gi.nPenWid/3, y1+gi.nPenWid/3,
X        x2+gi.nPenWid/3, y2+gi.nPenWid/3);
X    }
#endif
X  }
#ifdef X11
X  else
X    XDrawArc(gi.disp, gi.pmap, gi.gc, x1, y1, x2-x1, y2-y1, 0, nDegMax*64);
#endif
#ifdef WIN
X  else
X    Ellipse(wi.hdc, x1, y1, x2+1, y2+1);
#endif
#ifdef MSG
X  else
X    _ellipse(_GBORDER, gi.xOffset + x1, gi.yOffset + y1,
X      gi.xOffset + x2, gi.yOffset + y2);
#endif
#ifdef BGI
X  else
X    ellipse(gi.xOffset + (x1+x2)/2, gi.yOffset + (y1+y2)/2,
X      0, 360, (x2-x1)/2, (y2-y1)/2);
#endif
#ifdef MACG
X  else {
X    SetRect(&rc, x1, y1, x2, y2);
X    FrameOval(&rc);
X  }
#endif
}
X
X
/* Print a string of text on the graphic window at specified location. To  */
/* do this we either use Astrolog's own "font" (6x10) and draw each letter */
/* separately, or else specify system fonts for PostScript and metafiles.  */
X
void DrawSz(sz, x, y, dt)
CONST char *sz;
int x, y, dt;
{
X  int s = gi.nScale, c = gi.kiCur, cch, i;
X
X  cch = CchSz(sz);
X  if (!(dt & dtScale))
X    gi.nScale = gi.nScaleT;
X  x += gi.nScale;
X  if (!(dt & dtLeft))
X    x -= cch*xFont*gi.nScale/2;
X  if (dt & dtBottom)
X    y -= (yFont-3)*gi.nScale;
X  else if (!(dt & dtTop))
X    y -= yFont*gi.nScale/2;
X  if (dt & dtErase) {
X    DrawColor(gi.kiOff);
X    DrawBlock(x, y, x+xFont*gi.nScale*cch-1, y+(yFont-2)*gi.nScale);
X  }
X  DrawColor(c);
#ifdef PS
X  if (gs.fPS && gs.fFont) {
X    PsFont(4);
X    fprintf(gi.file, "%d %d(%s)center\n",
X      x + xFont*gi.nScale*cch/2, y + yFont*gi.nScale/2, sz);
X    gi.nScale = s;
X    return;
X  }
#endif
X  while (*sz) {
#ifdef META
X    if (gs.fMeta && gs.fFont) {
X      gi.nFontDes = 3;
X      gi.kiTextDes = gi.kiCur;
X      gi.nAlignDes = 0x6 | 0 /* Center | Top */;
X      MetaSelect();
X      MetaTextOut(x, y, 1);
X      MetaWord(WFromBB(*sz, 0));
X    } else
#endif
X    {
X      i = (_char)*sz-' ';
X      if (i < 128-32+1)
X        DrawTurtle(szDrawCh[i], x, y);
X    }
X    x += xFont*gi.nScale;
X    sz++;
X  }
X  gi.nScale = s;
}
X
X
/* Draw the glyph of a sign at particular coordinates on the screen.    */
/* To do this we either use Astrolog's turtle vector representation or  */
/* we may specify a system font character for PostScript and metafiles. */
X
void DrawSign(i, x, y)
int i, x, y;
{
#ifdef PS
X  if (gs.fPS && gs.fFont) {
X    PsFont(1);
X    fprintf(gi.file, "%d %d(%c)center\n", x, y, 'A' + i - 1);
X    return;
X  }
#endif
#ifdef META
X  if (gs.fMeta && gs.fFont) {
X    gi.nFontDes = 1;
X    gi.kiTextDes = gi.kiCur;
X    gi.nAlignDes = 0x6 | 0x8 /* Center | Bottom */;
X    MetaSelect();
X    MetaTextOut(x, y+4*gi.nScale, 1);
X    MetaWord(WFromBB('^' + i - 1, 0));
X    return;
X  }
#endif
X  if (i == sCap && gs.nGlyphs/1000 > 1)
X    i = cSign+1;
X  if ((gi.nScale & 1) || !szDrawSign2[i][0])
X    DrawTurtle(szDrawSign[i], x, y);
X  else {
X    gi.nScale >>= 1;
X    DrawTurtle(szDrawSign2[i], x, y);  /* Special hi-res sign glyphs. */
X    gi.nScale <<= 1;
X  }
}
X
X
/* Draw the number of a house at particular coordinates on the screen. */
/* We either use a turtle vector or write a number in a system font.   */
X
void DrawHouse(i, x, y)
int i, x, y;
{
#ifdef PS
X  if (gs.fPS && gs.fFont) {
X    PsFont(3);
X    fprintf(gi.file, "%d %d(%d)center\n", x, y, i);
X    return;
X  }
#endif
#ifdef META
X  if (gs.fMeta && gs.fFont) {
X    gi.nFontDes = 2;
X    gi.kiTextDes = gi.kiCur;
X    gi.nAlignDes = 0x6 | 0x8 /* Center | Bottom */;
X    MetaSelect();
X    MetaTextOut(x, y+3*gi.nScale, 1 + (i>9));
X    MetaWord(WFromBB(i > 9 ? '1' : '0'+i, i > 9 ? '0'+i-10 : 0));
X    return;
X  }
#endif
X  if ((gi.nScale & 1) || !szDrawHouse2[i][0])
X    DrawTurtle(szDrawHouse[i], x, y);
X  else {
X    gi.nScale >>= 1;
X    DrawTurtle(szDrawHouse2[i], x, y);  /* Special hi-res house numbers. */
X    gi.nScale <<= 1;
X  }
}
X
X
/* Draw the glyph of an object at particular coordinates on the screen. */
X
void DrawObject(obj, x, y)
int obj, x, y;
{
X  char szGlyph[4];
X  int ich;
X
X  if (!gs.fLabel)    /* If we are inhibiting labels, then do nothing. */
X    return;
X  DrawColor(kObjB[obj]);
X  if (obj <= oNorm) {
#ifdef STROKE
X    ich = (obj == oSou && fSouthNode ? oNorm+1 : obj);
#endif
#ifdef PS
X    if (gs.fPS && gs.fFont == 1 && obj < uranLo && szObjectFont[ich] != ' ') {
X      PsFont(2);
X      fprintf(gi.file, "%d %d(%c)center\n", x, y, szObjectFont[ich]);
X      return;
X    }
#endif
#ifdef META
X    if (gs.fMeta && gs.fFont == 1 &&
X      obj < uranLo && szObjectFont[ich] != ' ') {
X      gi.nFontDes = 4;
X      gi.kiTextDes = gi.kiCur;
X      gi.nAlignDes = 0x6 | 0x8 /* Center | Bottom */;
X      MetaSelect();
X      MetaTextOut(x, y+5*gi.nScale, 1);
X      MetaWord(WFromBB(szObjectFont[ich], 0));
X      return;
X    }
#endif
X    if (obj == oUra) {
X      if ((gs.nGlyphs/100)%10 > 1)
X        obj = oNorm+1;
X    } else if (obj == oPlu) {
X      if ((gs.nGlyphs/10)%10 > 1)
X        obj = oNorm+2;
X    } else if (obj == oLil) {
X      if (fSouthNode)
X        obj = oNorm+4;
X      else if (gs.nGlyphs%10 > 1)
X        obj = oNorm+1+gs.nGlyphs%10;
X    }
X    if ((gi.nScale & 1) || !szDrawObject2[obj][0])
X      DrawTurtle(szDrawObject[obj], x, y);
X    else {
X      gi.nScale >>= 1;
X      DrawTurtle(szDrawObject2[obj], x, y); /* Special hi-res object glyphs. */
X      gi.nScale <<= 1;
X    }
X
X  /* Normally we can just go draw the glyph; however, stars don't have */
X  /* glyphs, so for these draw their three letter abbreviation.        */
X
X  } else {
X    sprintf(szGlyph, "%c%c%c", chObj3(obj));
#ifdef CONSTEL
X    /* If doing constellations, give a couple stars more correct */
X    /* astronomical names.                                       */
X
X    if (gs.fConstel) {
X      if (obj == oOri)
X        sprintf(szGlyph, "Aln");    /* Alnilam, normally "Orion" */
X      else if (obj == oAnd)
X        sprintf(szGlyph, "M31");    /* M31, normally "Andromeda" */
X    }
#endif
X    DrawSz(szGlyph, x, y, dtCent);
X  }
}
X
X
/* Draw the glyph of an aspect at particular coordinates on the screen. */
/* Again we either use Astrolog's turtle vector or a system Astro font. */
X
void DrawAspect(asp, x, y)
int asp, x, y;
{
#ifdef PS
X  if (gs.fPS && gs.fFont == 1 && szAspectFont[asp-1] != ' ') {
X    PsFont(2);
X    fprintf(gi.file, "%d %d(%s%c)center\n", x, y,
X      asp == aSSq || asp == aSes ? "\\" : "", szAspectFont[asp-1]);
X    return;
X  }
#endif
#ifdef META
X  if (gs.fMeta && gs.fFont == 1 && szAspectFont[asp-1] != ' ') {
X    gi.nFontDes = 4;
X    gi.kiTextDes = gi.kiCur;
X    gi.nAlignDes = 0x6 | 0x8 /* Center | Bottom */;
X    MetaSelect();
X    MetaTextOut(x, y+5*gi.nScale, 1);
X    MetaWord(WFromBB(szAspectFont[asp-1], 0));
X    return;
X  }
#endif
X  if (us.fParallel && asp <= aOpp)
X    asp += cAspect;
X  if ((gi.nScale & 1) || !szDrawAspect2[asp][0])
X    DrawTurtle(szDrawAspect[asp], x, y);
X  else {
X    gi.nScale >>= 1;
X    DrawTurtle(szDrawAspect2[asp], x, y);  /* Special hi-res aspect glyphs. */
X    gi.nScale <<= 1;
X  }
}
X
X
/* Convert a string segment to a positive number, updating the string to  */
/* point beyond the number chars. Return 1 if the string doesn't point to */
/* a numeric value. This is used by the DrawTurtle() routine to extract   */
/* motion vector quantities from draw strings, e.g. the "12" in "U12".    */
X
int NFromPch(str)
CONST char **str;
{
X  int num = 0, i = 0;
X
X  loop {
X    if (**str < '0' || **str > '9')
X      return num > 0 ? num : (i < 1 ? 1 : 0);
X    num = num*10+(**str)-'0';
X    (*str)++;
X    i++;
X  }
}
X
X
/* This routine is used to draw complicated objects composed of lots of line */
/* segments on the screen, such as all the glyphs and coastline pieces. It   */
/* is passed in a string of commands defining what to draw in relative       */
/* coordinates. This is a copy of the format of the BASIC draw command found */
/* in PC's. For example, "U5R10D5L10" means go up 5 dots, right 10, down 5,  */
/* and left 10 - draw a box twice as wide as it is high.                     */
X
void DrawTurtle(sz, x0, y0)
CONST char *sz;
int x0, y0;
{
X  int i, x, y, deltax, deltay;
X  bool fBlank, fNoupdate;
X  char chCmd;
X
X  gi.xTurtle = x0; gi.yTurtle = y0;
X  while (chCmd = ChCap(*sz)) {
X    sz++;
X
X    /* 'B' prefixing a command means just move the cursor, and don't draw. */
X
X    if (fBlank = (chCmd == 'B')) {
X      chCmd = ChCap(*sz);
X      sz++;
X    }
X
X    /* 'N' prefixing a command means don't update cursor when done drawing. */
X
X    if (fNoupdate = (chCmd == 'N')) {
X      chCmd = ChCap(*sz);
X      sz++;
X    }
X
X    /* Here we process the eight directional commands. */
X
X    switch (chCmd) {
X    case 'U': deltax =  0; deltay = -1; break;      /* Up    */
X    case 'D': deltax =  0; deltay =  1; break;      /* Down  */
X    case 'L': deltax = -1; deltay =  0; break;      /* Left  */
X    case 'R': deltax =  1; deltay =  0; break;      /* Right */
X    case 'E': deltax =  1; deltay = -1; break;      /* NorthEast */
X    case 'F': deltax =  1; deltay =  1; break;      /* SouthEast */
X    case 'G': deltax = -1; deltay =  1; break;      /* SouthWest */
X    case 'H': deltax = -1; deltay = -1; break;      /* NorthWest */
X    default: PrintError("Bad draw.");       /* Shouldn't happen. */
X    }
X    x = gi.xTurtle;
X    y = gi.yTurtle;
X    i = NFromPch(&sz)*gi.nScale;    /* Figure out how far to draw. */
X    if (fBlank) {
X      gi.xTurtle += deltax*i;
X      gi.yTurtle += deltay*i;
X    } else {
X      gi.xTurtle += deltax*i;
X      gi.yTurtle += deltay*i;
X      DrawLine(x, y, gi.xTurtle, gi.yTurtle);
X      if (fNoupdate) {
X        gi.xTurtle = x;
X        gi.yTurtle = y;
X      }
X    }
X  }
}
#endif /* GRAPH */
X
/* xgeneral.c */
SHAR_EOF
  $shar_touch -am 1223232998 'xgeneral.c' &&
  chmod 0644 'xgeneral.c' ||
  echo 'restore of xgeneral.c failed'
  shar_count="`wc -c < 'xgeneral.c'`"
  test 26099 -eq "$shar_count" ||
    echo "xgeneral.c: original size 26099, current size $shar_count"
fi
# ============= xscreen.c ==============
if test -f 'xscreen.c' && test X"$1" != X"-c"; then
  echo 'x - skipping xscreen.c (File already exists)'
else
  echo 'x - extracting xscreen.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'xscreen.c' &&
/*
** Astrolog (Version 5.40) File: xscreen.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1998 by Walter D. Pullen
** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
** Permission is granted to freely use and distribute these routines
** provided one doesn't sell, restrict, or profit from them in any way.
** Modification is allowed provided these notices remain with any
** altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/20/1998.
*/
X
#include "astrolog.h"
X
X
#ifdef GRAPH
/*
******************************************************************************
** Astrolog Icon.
******************************************************************************
*/
X
#ifdef X11
/* This information used to define Astrolog's X icon (Rainbow over Third */
/* Eye) is identical to the output format used by the bitmap program.    */
/* You could extract this section and run xsetroot -bitmap on it.        */
X
#define icon_width 63
#define icon_height 32
static char icon_bits[] = {
X 0x00,0x00,0x00,0xa8,0x0a,0x00,0x00,0x00,0x00,0x00,0x40,0x55,0x55,0x01,0x00,
X 0x00,0x00,0x00,0xa8,0xaa,0xaa,0x0a,0x00,0x00,0x00,0x00,0x54,0xf5,0x57,0x15,
X 0x00,0x00,0x00,0x80,0xaa,0xaa,0xaa,0xaa,0x00,0x00,0x00,0x40,0xd5,0xff,0xff,
X 0x55,0x01,0x00,0x00,0xa0,0xaa,0xaa,0xaa,0xaa,0x02,0x00,0x00,0x50,0xfd,0xff,
X 0xff,0x5f,0x05,0x00,0x00,0xa8,0xaa,0x2a,0xaa,0xaa,0x0a,0x00,0x00,0xd4,0xff,
X 0xaf,0xfa,0xff,0x15,0x00,0x00,0xaa,0x2a,0x00,0x00,0xaa,0x2a,0x00,0x00,0xf5,
X 0xbf,0xaa,0xaa,0xfe,0x57,0x00,0x80,0xaa,0x02,0x00,0x00,0xa0,0xaa,0x00,0x40,
X 0xfd,0xab,0xfa,0xaf,0xea,0x5f,0x01,0xa0,0xaa,0x80,0xff,0xff,0x80,0xaa,0x02,
X 0x50,0xff,0xea,0xff,0xff,0xab,0x7f,0x05,0xa0,0x2a,0xf0,0xff,0xff,0x07,0xaa,
X 0x02,0xd0,0xbf,0xfa,0x0f,0xf8,0xaf,0x7e,0x05,0xa8,0x0a,0xfc,0x01,0xc0,0x1f,
X 0xa8,0x0a,0xd4,0xaf,0x7e,0x00,0x00,0xbf,0xfa,0x15,0xa8,0x0a,0x3f,0x00,0x00,
X 0x7e,0xa8,0x0a,0xf4,0xaf,0x1f,0xe0,0x03,0xfc,0xfa,0x15,0xaa,0x82,0x0f,0xdc,
X 0x1d,0xf8,0xa0,0x2a,0xf4,0xab,0x07,0x23,0x62,0xf0,0xea,0x17,0xaa,0xc2,0x87,
X 0x91,0xc4,0xf0,0xa1,0x2a,0xf4,0xeb,0xc3,0xd0,0x85,0xe1,0xeb,0x17,0xaa,0xe0,
X 0x83,0x91,0xc4,0xe0,0x83,0x2a,0xf5,0xeb,0x03,0x23,0x62,0xe0,0xeb,0x57,0xaa,
X 0xe0,0x01,0xdc,0x1d,0xc0,0x83,0x2a,0xf5,0xeb,0x01,0xe0,0x03,0xc0,0xeb,0x57,
X 0xaa,0xe0,0x01,0x00,0x00,0xc0,0x83,0x2a,0xfd,0xeb,0x01,0x00,0x00,0xc0,0xeb,
X 0x5f};
#endif
X
X
/*
******************************************************************************
** Interactive Screen Graphics Routines.
******************************************************************************
*/
X
/* Set up all the colors used by the program, i.e. the foreground and   */
/* background colors, and all the colors in the object arrays, based on */
/* whether or not we are in monochrome and/or reverse video mode.       */
X
void InitColorsX()
{
X  int i;
#ifdef X11
X  Colormap cmap;
X  XColor xcol;
X
X  if (!gi.fFile) {
X    cmap = XDefaultColormap(gi.disp, gi.screen);
X
X    /* Allocate a color from the present X11 colormap. Given a string like */
X    /* "violet", allocate this color and return a value specifying it.     */
X
X    for (i = 0; i < 16; i++) {
X      XParseColor(gi.disp, cmap, szColorX[i], &xcol);
X      XAllocColor(gi.disp, cmap, &xcol);
X      rgbind[i] = xcol.pixel;
X    }
X  }
#endif
X  gi.kiOn   = kMainA[!gs.fInverse];
X  gi.kiOff  = kMainA[gs.fInverse];
X  gi.kiLite = gs.fColor ? kMainA[2+gs.fInverse] : gi.kiOn;
X  gi.kiGray = gs.fColor ? kMainA[3-gs.fInverse] : gi.kiOn;
X  for (i = 0; i <= 8; i++)
X    kMainB[i]    = gs.fColor ? kMainA[i]    : gi.kiOn;
X  for (i = 0; i <= 7; i++)
X    kRainbowB[i] = gs.fColor ? kRainbowA[i] : gi.kiOn;
X  for (i = 0; i < 4; i++)
X    kElemB[i]    = gs.fColor ? kElemA[i]    : gi.kiOn;
X  for (i = 0; i <= cAspect; i++)
X    kAspB[i]     = gs.fColor ? kAspA[i]     : gi.kiOn;
X  for (i = 0; i <= cObj; i++)
X    kObjB[i]     = gs.fColor ? kObjA[i]     : gi.kiOn;
#ifdef X11
X  if (!gi.fFile) {
X    XSetBackground(gi.disp, gi.gc,   rgbind[gi.kiOff]);
X    XSetForeground(gi.disp, gi.pmgc, rgbind[gi.kiOff]);
X  }
#endif
}
X
X
#ifdef ISG
/* This routine opens up and initializes a window and prepares it to be */
/* drawn upon, and gets various information about the display, too.     */
X
void BeginX()
{
#ifdef X11
X  gi.disp = XOpenDisplay(gs.szDisplay);
X  if (gi.disp == NULL) {
X    PrintError("Can't open display.");
X    Terminate(tcFatal);
X  }
X  gi.screen = DefaultScreen(gi.disp);
X  bg = BlackPixel(gi.disp, gi.screen);
X  fg = WhitePixel(gi.disp, gi.screen);
X  hint.x = gi.xOffset; hint.y = gi.yOffset;
X  hint.width = gs.xWin; hint.height = gs.yWin;
X  hint.min_width = BITMAPX1; hint.min_height = BITMAPY1;
X  hint.max_width = BITMAPX;  hint.max_height = BITMAPY;
X  hint.flags = PPosition | PSize | PMaxSize | PMinSize;
#if FALSE
X  wmhint = XGetWMHints(gi.disp, gi.wind);
X  wmhint->input = True;
X  XSetWMHints(gi.disp, gi.wind, wmhint);
#endif
X  gi.depth = DefaultDepth(gi.disp, gi.screen);
X  if (gi.depth < 5) {
X    gi.fMono = fTrue;      /* Is this a monochrome monitor? */
X    gs.fColor = fFalse;
X  }
X  gi.root = RootWindow(gi.disp, gi.screen);
X  if (gs.fRoot)
X    gi.wind = gi.root;     /* If -XB in effect, we'll use the root window. */
X  else
X    gi.wind = XCreateSimpleWindow(gi.disp, DefaultRootWindow(gi.disp),
X      hint.x, hint.y, hint.width, hint.height, 5, fg, bg);
X  gi.pmap = XCreatePixmap(gi.disp, gi.wind, gs.xWin, gs.yWin, gi.depth);
X  gi.icon = XCreateBitmapFromData(gi.disp, DefaultRootWindow(gi.disp),
X    icon_bits, icon_width, icon_height);
X  if (!gs.fRoot)
X    XSetStandardProperties(gi.disp, gi.wind, szAppName, szAppName, gi.icon,
X      (char **)xkey, 0, &hint);
X
X  /* We have two graphics workareas. One is what the user currently sees in */
X  /* the window, and the other is what we are currently drawing on. When    */
X  /* done, we can quickly copy this to the viewport for a smooth look.      */
X
X  gi.gc = XCreateGC(gi.disp, gi.wind, 0, 0);
X  XSetGraphicsExposures(gi.disp, gi.gc, 0);
X  gi.pmgc = XCreateGC(gi.disp, gi.wind, 0, 0);
X  InitColorsX();                                  /* Go set up colors. */
X  if (!gs.fRoot)
X    XSelectInput(gi.disp, gi.wind, KeyPressMask | StructureNotifyMask |
X      ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask);
X  XMapRaised(gi.disp, gi.wind);
X  XSync(gi.disp, 0);
X  XFillRectangle(gi.disp, gi.pmap, gi.pmgc, 0, 0, gs.xWin, gs.yWin);
#endif /* X11 */
X
#ifdef WIN
X  if (wi.fChartWindow && (wi.xClient != gs.xWin ||
X    wi.yClient != gs.yWin) && wi.hdcPrint == hdcNil)
X    ResizeWindowToChart();
X  gi.xOffset = NMultDiv(wi.xClient - gs.xWin, wi.xScroll, nScrollDiv);
X  gi.yOffset = NMultDiv(wi.yClient - gs.yWin, wi.yScroll, nScrollDiv);
X  SetWindowOrg(wi.hdc, -gi.xOffset, -gi.yOffset);
X  SetWindowExt(wi.hdc, wi.xClient, wi.yClient);
X  SetMapMode(wi.hdc, MM_ANISOTROPIC);
X  SelectObject(wi.hdc, GetStockObject(NULL_PEN));
X  SelectObject(wi.hdc, GetStockObject(NULL_BRUSH));
X  if (!gs.fJetTrail || wi.hdcPrint != hdcNil)
X    PatBlt(wi.hdc, -gi.xOffset, -gi.yOffset, wi.xClient, wi.yClient,
X      gs.fInverse ? WHITENESS : BLACKNESS);
X  InitColorsX();
#endif /* WIN */
X
#ifdef MSG
X  if (!FValidResmode(gi.nRes))    /* Initialize graphics mode to hi-res. */
X    gi.nRes = gs.nResHi;
X  _setvideomode(gi.nRes == -1 ? _VRES16COLOR : gi.nRes);
X  if (_grstatus()) {
X    PrintError("Can't enter graphics mode.");
X    Terminate(tcFatal);
X  }
X  _getvideoconfig((struct videoconfig far *) &gi.cfg);
X  if (gi.cfg.numcolors < 16) {
X    gi.fMono  = fTrue;
X    gs.fColor = fFalse;
X  }
X  _remapallpalette((long FPTR *) rgb);
X  _setactivepage(0);
X  _setvisualpage(0);
X  InitColorsX();
#ifdef MOUSE
X  MouseInit(xPcScreen, yPcScreen);
#endif
X  /* Make sure we reset textrows upon restart. */
X  gs.nTextRows = abs(gs.nTextRows);
#endif /* MSG */
X
#ifdef BGI
X  int i;
X  static struct palettetype pal;
X
X  if (!FValidResmode(gi.nRes))    /* Initialize graphics mode to hi-res. */
X    gi.nRes = gs.nResHi;
X  if (!gi.fLoaded) {
X    registerfarbgidriver(ATT_driver_far);      /* attf.obj     */
X    registerfarbgidriver(CGA_driver_far);      /* cgaf.obj     */
X    registerfarbgidriver(EGAVGA_driver_far);   /* egavgaf.obj  */
X    registerfarbgidriver(Herc_driver_far);     /* hercf.obj    */
X    registerfarbgidriver(IBM8514_driver_far);  /* ibm8514f.obj */
X    registerfarbgidriver(PC3270_driver_far);   /* pc3270f.obj  */
X    gi.nDriver = DETECT;
X    initgraph(&gi.nDriver, &gi.nGraph, "");
X    gi.fLoaded = fTrue;
X  }
X  if (gi.nRes <= 0) {
X    switch (gi.nDriver) {
X    case CGA:      gi.nGraph = CGAHI;      break;
X    case MCGA:     gi.nGraph = MCGAHI;     break;
X    case EGA:      gi.nGraph = EGAHI;      break;
X    case EGA64:    gi.nGraph = EGA64HI;    break;
X    case EGAMONO:  gi.nGraph = EGAMONOHI;  break;
X    case HERCMONO: gi.nGraph = HERCMONOHI; break;
X    case ATT400:   gi.nGraph = ATT400HI;   break;
X    case VGA:      gi.nGraph = VGAHI;      break;
X    case PC3270:   gi.nGraph = PC3270HI;   break;
X    case IBM8514:  gi.nGraph = IBM8514HI;  break;
X    default:       gi.nGraph = 0;
X    }
X  } else {
X    switch (gi.nDriver) {
X    case CGA:      gi.nGraph = CGAHI;      break;
X    case MCGA:     gi.nGraph = MCGAHI;     break;
X    case EGA:      gi.nGraph = EGAHI;      break;
X    case EGA64:    gi.nGraph = EGA64HI;    break;
X    case EGAMONO:  gi.nGraph = EGAMONOHI;  break;
X    case HERCMONO: gi.nGraph = HERCMONOHI; break;
X    case ATT400:   gi.nGraph = ATT400HI;   break;
X    case VGA:      gi.nGraph = VGAMED;     break;
X    case PC3270:   gi.nGraph = PC3270HI;   break;
X    case IBM8514:  gi.nGraph = IBM8514LO;  break;
X    default:       gi.nGraph = 0;
X    }
X  }
X  setgraphmode(gi.nGraph);
X  if (graphresult()) {
X    PrintError("Can't enter graphics mode.");
X    Terminate(tcFatal);
X  }
X  gi.nPages = 1 + (gi.nDriver == HERCMONO ||
X    (gi.nDriver == VGA && gi.nGraph != VGAHI) || gi.nDriver == EGA);
X  if (getmaxcolor()+1 < 16) {
X    gi.fMono  = fTrue;
X    gs.fColor = fFalse;
X  }
X  getpalette(&pal);
X  for (i = 0; i < pal.size; i++)
X    pal.colors[i] = (char)rgb[i];
X  setallpalette(&pal);
X  setactivepage(0);
X  setvisualpage(0);
X  gi.nPageCur = 0;
X  InitColorsX();
#ifdef MOUSE
X  MouseInit(xPcScreen, yPcScreen);
#endif
X  /* Make sure we reset textrows upon restart. */
X  gs.nTextRows = abs(gs.nTextRows);
#endif /* BGI */
X
#ifdef MACG
X  MaxApplZone();
X  InitGraf(&thePort);
X  InitFonts();
X  FlushEvents(everyEvent, 0);
X  InitWindows();
X  InitMenus();
X  TEInit();
X  InitDialogs(0L);
X  InitCursor();
X
X  gi.rcDrag = screenBits.bounds;
X  gi.rcBounds.left = 20;
X  gi.rcBounds.top = 20 + GetMBarHeight();
X  gi.rcBounds.right = gi.rcBounds.left + gs.xWin;
X  gi.rcBounds.bottom = gi.rcBounds.top + gs.yWin;
X  gi.wpAst = NewCWindow(0L, &gi.rcBounds, "\pAstrolog 5.40", true,
X    noGrowDocProc, (WindowPtr)-1L, true, 0);
X  SetPort(gi.wpAst);
X  InitColorsX();
#endif /* MACG */
}
X
X
/* Add a certain amount of time to the current hour/day/month/year quantity */
/* defining the present chart. This is used by the chart animation feature. */
/* We can add or subtract anywhere from 1 to 9 seconds, minutes, hours,     */
/* days, months, years, decades, centuries, or millenia in any one call.    */
/* This is mainly just addition to the appropriate quantity, but we have    */
/* to check for overflows, e.g. Dec 30 + 3 days = Jan 2 of Current year + 1 */
X
void AddTime(mode, toadd)
int mode, toadd;
{
X  int d;
X  real h, m;
X
X  if (!FBetween(mode, 1, 9))
X    mode = 4;
X
X  h = RFloor(TT);
X  m = RFract(TT)*100.0;
X  if (mode == 1)
X    m += 1.0/60.0*(real)toadd;    /* Add seconds. */
X  else if (mode == 2)
X    m += (real)toadd;             /* add minutes. */
X
X  /* Add hours, either naturally or if minute value overflowed. */
X
X  if (m < 0.0 || m >= 60.0 || mode == 3) {
X    if (m >= 60.0) {
X      m -= 60.0; toadd = NSgn(toadd);
X    } else if (m < 0.0) {
X      m += 60.0; toadd = NSgn(toadd);
X    }
X    h += (real)toadd;
X  }
X
X  /* Add days, either naturally or if hour value overflowed. */
X
X  if (h >= 24.0 || h < 0.0 || mode == 4) {
X    if (h >= 24.0) {
X      h -= 24.0; toadd = NSgn(toadd);
X    } else if (h < 0.0) {
X      h += 24.0; toadd = NSgn(toadd);
X    }
X    DD = AddDay(MM, DD, YY, toadd);
X  }
X
X  /* Add months, either naturally or if day value overflowed. */
X
X  if (DD > (d = DayInMonth(MM, YY)) || DD < 1 || mode == 5) {
X    if (DD > d) {
X      DD -= d; toadd = NSgn(toadd);
X    } else if (DD < 1) {
X      DD += DayInMonth(Mod12(MM - 1), YY);
X      toadd = NSgn(toadd);
X    }
X    MM += toadd;
X  }
X
X  /* Add years, either naturally or if month value overflowed. */
X
X  if (MM > 12 || MM < 1 || mode == 6) {
X    if (MM > 12) {
X      MM -= 12; toadd = NSgn(toadd);
X    } else if (MM < 1) {
X      MM += 12; toadd = NSgn(toadd);
X    }
X    YY += toadd;
X  }
X  if (mode == 7)
X    YY += 10 * toadd;      /* Add decades.   */
X  else if (mode == 8)
X    YY += 100 * toadd;     /* Add centuries. */
X  else if (mode == 9)
X    YY += 1000 * toadd;    /* Add millenia.  */
X  TT = h+m/100.0;          /* Recalibrate hour time. */
}
X
X
/* Animate the current chart based on the given values indicating how much  */
/* to update by. We update and recast the current chart info appropriately. */
/* Note animation mode for comparison charts will update the second chart.  */
X
void Animate(mode, toadd)
int mode, toadd;
{
X  if (gi.nMode == gWorldMap || gi.nMode == gGlobe || gi.nMode == gPolar) {
X    gs.nRot += toadd;
X    if (gs.nRot >= nDegMax)     /* For animating globe display, add */
X      gs.nRot -= nDegMax;       /* in appropriate degree value.     */
X    else if (gs.nRot < 0)
X      gs.nRot += nDegMax;
X  } else {
X    if (mode == 10) {
#ifdef TIME
X      /* For the continuous chart update to present moment */
X      /* animation mode, go get whatever time it is now.   */
X      FInputData(szNowCore);
#else
X      if (us.nRel <= rcDual)
X        ciCore = ciTwin;
X      else
X        ciCore = ciMain;
X      AddTime(1, toadd);
#endif
X    } else {  /* Otherwise add on appropriate time vector to chart info. */
X      if (us.nRel <= rcDual)
X        ciCore = ciTwin;
X      else
X        ciCore = ciMain;
X      AddTime(mode, toadd);
X    }
X    if (us.nRel <= rcDual) {
X      ciTwin = ciCore;
X      ciCore = ciMain;
X    } else
X      ciMain = ciCore;
X    if (us.nRel)
X      CastRelation();
X    else
X      CastChart(fTrue);
X  }
}
X
X
/* This routine exits graphics mode, prompts the user for a set of command */
/* switches, processes them, and returns to the previous graphics with the */
/* new settings in effect, allowing one to change most any setting without */
/* having to lose their graphics state or fall way back to a -Q loop.      */
X
void CommandLineX()
{
X  char szCommandLine[cchSzMax], *rgsz[MAXSWITCHES];
X  int argc, fT, fPause = fFalse;
X
X  ciCore = ciMain;
#ifdef MSG
X  _setvideomode(_DEFAULTMODE);
X  _settextrows(gs.nTextRows);
#endif
#ifdef BGI
X  restorecrtmode();
X  if (gs.nTextRows > 25)
X    textmode(C4350);
#endif
X  fT = us.fLoop; us.fLoop = fTrue;
X  argc = NPromptSwitches(szCommandLine, rgsz);
X  is.cchRow = 0;
X  is.fSzInteract = fTrue;
X  if (!FProcessSwitches(argc, rgsz))
X    fPause = fTrue;
X  else {
X    is.fMult = fFalse;
X    FPrintTables();
X    if (is.fMult) {
X      ClearB((lpbyte)&us.fCredit,
X        (int)((lpbyte)&us.fLoop - (lpbyte)&us.fCredit));
X      fPause = fTrue;
X    }
X  }
X
#ifdef PCG
X  /* Pause for the user if there was either an error processing the    */
X  /* switches, or one of the informational text tables was brought up. */
X
X  if (fPause) {
X    AnsiColor(kDefault);
X    is.cchRow = 0;
X    PrintSz("Press any key to return to graphics.\n");
X    while (!kbhit())
X      ;
X    getch();
X  }
#endif
X  is.fSzInteract = fFalse;
X  us.fLoop = fT;
X  ciMain = ciCore;
X  BeginX();
}
X
X
/* Given two chart size values, adjust them such that the chart will look */
/* "square". We round the higher value down and check certain conditions. */
X
void SquareX(x, y, force)
int *x, *y, force;
{
X  if (!force && !fSquare)    /* Unless we want to force a square, realize */
X    return;                  /* that some charts look better rectangular. */
X  if (*x > *y)
X    *x = *y;
X  else
X    *y = *x;
#ifdef PCG
X  if (FEgaRes(gi.nRes))         /* Scale horizontal size if we're in a PC */
X    *x = VgaFromEga(*x);        /* graphics mode without "square" pixels. */
X  else if (FCgaRes(gi.nRes))
X    *x = VgaFromCga(*x);
#endif
X  if (fSidebar)      /* Take into account chart's sidebar, if any. */
X    *x += xSideT;
}
X
X
#ifndef WIN
/* This routine gets called after graphics are brought up and displayed     */
/* on the screen. It loops, processing key presses, mouse clicks, etc, that */
/* the window receives, until the user specifies they want to exit program. */
X
void InteractX()
{
#ifdef X11
X  char sz[cchSzDef];
X  XEvent xevent;
X  KeySym keysym;
X  int fResize = fFalse, fRedraw = fTrue;
#endif
#ifdef PCG
#ifdef MOUSE
X  int eventx, eventy, eventbtn;
#endif
X  int fResize = fTrue, fRedraw = fFalse;
#endif /* PCG */
#ifdef MACG
X  EventRecord erCur;
X  WindowPtr wpCur;
X  int wc, fEvent, fResize = fFalse, fRedraw = fTrue;
#endif
X  int fBreak = fFalse, fPause = fFalse, fCast = fFalse, xcorner = 7,
X    mousex = -1, mousey = -1, buttonx = -1, buttony = -1, dir = 1,
X    length, key, i;
X  bool fT;
X  KI coldrw = gi.kiLite;
X
X  neg(gs.nAnim);
X  while (!fBreak) {
X    gi.nScale = gs.nScale/100;
X
X    /* Some chart windows, like the world maps and aspect grids, should */
X    /* always be a certian size, so correct if a resize was attempted.  */
X
X    if (fMap) {
X      length = nDegMax*gi.nScale;
X      if (gs.xWin != length) {
X        gs.xWin = length;
X        fResize = fTrue;
X      }
X      length = nDegHalf*gi.nScale;
X      if (gs.yWin != length) {
X        gs.yWin = length;
X        fResize = fTrue;
X      }
X    } else if (gi.nMode == gGrid) {
X      if (gs.xWin != (length =
X        (gs.nGridCell + (us.nRel <= rcDual))*CELLSIZE*gi.nScale+1)) {
X        gs.xWin = length;
X        fResize = fTrue;
X      } if (gs.yWin != length) {
X        gs.yWin = length;
X        fResize = fTrue;
X      }
X
X    /* Make sure the window isn't too large or too small. */
X
X    } else {
X      if (gs.xWin < BITMAPX1) {
X        gs.xWin = BITMAPX1;
X        fResize = fTrue;
X      } else if (gs.xWin > BITMAPX) {
X        gs.xWin = BITMAPX;
X        fResize = fTrue;
X      }
X      if (gs.yWin < BITMAPY1) {
X        gs.yWin = BITMAPY1;
X        fResize = fTrue;
X      } else if (gs.yWin > BITMAPY) {
X        gs.yWin = BITMAPY;
X        fResize = fTrue;
X      }
X    }
X
X    /* If in animation mode, ensure we are in the flicker free resolution. */
X
X    if (gs.nAnim < 0) {
X      neg(gs.nAnim);
#ifdef PCG
X      if (gi.nRes == gs.nResHi && !gs.fJetTrail) {
X        gi.nRes = gs.nResLo;
X        BeginX();
X        gs.xWin = xPcScreen;
X        gs.yWin = yPcScreen;
X        SquareX(&gs.xWin, &gs.yWin, fFalse);
X        fResize = fTrue;
X      }
#endif
X    }
X
X    /* Physically resize window if we've changed the size parameters. */
X
X    if (fResize) {
X      fResize = fFalse;
#ifdef X11
X      XResizeWindow(gi.disp, gi.wind, gs.xWin, gs.yWin);
X      XFreePixmap(gi.disp, gi.pmap);
X      gi.pmap = XCreatePixmap(gi.disp, gi.wind, gs.xWin, gs.yWin, gi.depth);
#endif
#ifdef PCG
X      if (xPcScreen > gs.xWin)
X        gi.xOffset = (xPcScreen - gs.xWin) / 2;
X      else {
X        if (xcorner % 3 == 1)
X          gi.xOffset = 0;
X        else if (xcorner % 3 == 0)
X          gi.xOffset = -gs.xWin + xPcScreen;
X        else
X          gi.xOffset = -(gs.xWin - xPcScreen) / 2;
X      }
X      if (yPcScreen > gs.yWin)
X        gi.yOffset = (yPcScreen - gs.yWin) / 2;
X      else {
X        if (xcorner > 6)
X          gi.yOffset = 0;
X        else if (xcorner < 4)
X          gi.yOffset = -gs.yWin + yPcScreen;
X        else
X          gi.yOffset = -(gs.yWin - yPcScreen) / 2;
X      }
#endif
#ifdef MACG
X      SizeWindow(gi.wpAst, gs.xWin, gs.yWin, fTrue);
#endif
X      fRedraw = fTrue;
X    }
X
X    /* Recast chart if the chart information has changed any. */
X
X    if (fCast) {
X      fCast = fFalse;
X      ciCore = ciMain;
X      if (us.nRel)
X        CastRelation();
X      else
X        CastChart(fTrue);
X      fRedraw = fTrue;
X    }
X    if (gs.nAnim && !fPause)
X      fRedraw = fTrue;
X
X    /* Update the screen if anything has changed since last time around. */
X
X    if (fRedraw && (!fPause || gs.nAnim)) {
X      fRedraw = fFalse;
X
X      /* If we're in animation mode, change the chart info appropriately. */
X
X      if (gs.nAnim && !fPause)
X        Animate(gs.nAnim, dir);
X
X      /* Clear the screen and set up a buffer to draw in. */
X
#ifdef X11
X      XFillRectangle(gi.disp, gi.pmap, gi.pmgc, 0, 0, gs.xWin, gs.yWin);
#endif
#ifdef PCG
#ifdef MOUSE
X      MouseShow(fFalse);
#endif
#ifdef MSG
X      if (gi.cfg.numvideopages > 1)
X        _setactivepage(_getactivepage() == gs.fJetTrail);
#else
X      if (gi.nPages > 1) {
X        gi.nPageCur = (gi.nPageCur == gs.fJetTrail);
X        setactivepage(gi.nPageCur);
X      }
#endif
#endif /* PCG */
#ifdef MACG
X      SetPort(gi.wpAst);
X      InvalRect(&gi.wpAst->portRect);
X      BeginUpdate(gi.wpAst);
X      EraseRect(&gi.wpAst->portRect);
#endif
X
X      DrawChartX();
X
X      /* Make the drawn chart visible in the current screen buffer. */
X
#ifdef X11
X      XSync(gi.disp, 0);
X      XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc,
X        0, 0, gs.xWin, gs.yWin, 0, 0);
#endif
#ifdef PCG
#ifdef MSG
X      if (gi.cfg.numvideopages > 1)
X        _setvisualpage(_getactivepage());
#else
X      if (gi.nPages > 1)
X        setvisualpage(gi.nPageCur);
#endif
#ifdef MOUSE
X      if (!gs.nAnim || fPause)
X        MouseShow(fTrue);
#endif
#endif /* PCG */
#ifdef MACG
X      EndUpdate(gi.wpAst);
#endif
X    }  /* if */
X
X    /* Now process what's on the event queue, i.e. any keys pressed, etc. */
X
#ifdef X11
X    if (XEventsQueued(gi.disp, QueuedAfterFlush /*QueuedAfterReading*/) ||
X      !gs.nAnim || fPause) {
X      XNextEvent(gi.disp, &xevent);
X
X      /* Restore what's on window if a part of it gets uncovered. */
X
X      if (xevent.type == Expose && xevent.xexpose.count == 0) {
X        XSync(gi.disp, 0);
X        XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc,
X          0, 0, gs.xWin, gs.yWin, 0, 0);
X      }
X      switch (xevent.type) {
X
X      /* Check for a manual resize of window by user. */
X
X      case ConfigureNotify:
X        gs.xWin = xevent.xconfigure.width;
X        gs.yWin = xevent.xconfigure.height;
X        XFreePixmap(gi.disp, gi.pmap);
X        gi.pmap = XCreatePixmap(gi.disp, gi.wind, gs.xWin, gs.yWin, gi.depth);
X        fRedraw = fTrue;
X        break;
X      case MappingNotify:
X        XRefreshKeyboardMapping((XMappingEvent *)&xevent);
X        break;
X
#ifdef MOUSE
X      /* Process any mouse buttons the user pressed. */
X
X      case ButtonPress:
X        mousex = xevent.xbutton.x; mousey = xevent.xbutton.y;
X        if (xevent.xbutton.button == Button1) {
X          DrawColor(gi.kiLite);
X          DrawPoint(mousex, mousey);
X          XSync(gi.disp, 0);
X          XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc,
X            0, 0, gs.xWin, gs.yWin, 0, 0);
X        } else if (xevent.xbutton.button == Button2 && (gi.nMode ==
X          gAstroGraph || gi.nMode == gWorldMap) && gs.nRot == 0) {
X          Lon = DegToDec(rDegHalf -
X            (real)(xevent.xbutton.x-1)/(real)(gs.xWin-2)*rDegMax);
X          Lat = DegToDec(rDegQuad -
X            (real)(xevent.xbutton.y-1)/(real)(gs.yWin-2)*181.0);
X          sprintf(sz, "Mouse is at %s.", SzLocation(Lon, Lat));
X          PrintNotice(sz);
X        } else if (xevent.xbutton.button == Button3)
X          fBreak = fTrue;
X        break;
X
X      /* Check for user dragging any of the mouse buttons across window. */
X
X      case MotionNotify:
X        DrawColor(coldrw);
X        DrawLine(mousex, mousey, xevent.xbutton.x, xevent.xbutton.y);
X        XSync(gi.disp, 0);
X        XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc,
X          0, 0, gs.xWin, gs.yWin, 0, 0);
X        mousex = xevent.xbutton.x; mousey = xevent.xbutton.y;
X        break;
#endif
X
X      /* Process any keys user pressed in window. */
X
X      case KeyPress:
X        length = XLookupString((XKeyEvent *)&xevent, xkey, 10, &keysym, 0);
X        if (length == 1) {
X          key = xkey[0];
#endif /* X11 */
X
#ifdef PCG
#ifdef MOUSE
X      if ((!gs.nAnim || fPause) && MouseStatus(&eventx, &eventy, &eventbtn)) {
X
X        /* If the left button is down, draw on the screen. */
X        if (eventbtn == mfLeft && mousex >= 0) {
X          MouseShow(fFalse);
X          DrawColor(coldrw);
X          PcMoveTo(mousex, mousey);
X          buttonx = eventx; buttony = eventy;
X          PcLineTo(buttonx, buttony);
X
X        /* If the right button is down, change the default location. */
X        } else if (eventbtn == mfRight) {
X          if (fMap && gs.nRot == 0 && !gs.fConstel && !gs.fMollewide) {
X            Lon = DegToDec(rDegHalf-(real)(eventx-gi.xOffset)/
X              (real)gs.xWin*rDegMax);
X            if (Lon < -rDegHalf)
X              Lon = -rDegHalf;
X            else if (Lon > rDegHalf)
X              Lon = rDegHalf;
X            Lat = DegToDec(rDegQuad-(real)(eventy-gi.yOffset)/
X              (real)gs.yWin*181.0);
X            if (Lat < -rDegQuad)
X              Lat = -rDegQuad;
X            else if (Lat > rDegQuad)
X              Lat = rDegQuad;
X            fCast = fTrue;
X
X          /* Right button means draw lines if not in a world map mode. */
X          } else if (buttonx >= 0) {
X            MouseShow(fFalse);
X            DrawColor(coldrw);
X            PcMoveTo(buttonx, buttony);
X            PcLineTo(eventx, eventy);
X          }
X
X        /* Middle button (which most PC's don't have) means exit program. */
X        } else if (eventbtn == mfMiddle)
X          fBreak = fTrue;
X
X        mousex = eventx; mousey = eventy;
X        MouseShow(fTrue);
X      } else
#endif /* MOUSE */
X        if (kbhit()) {
X          key = getch();
#endif /* PCG */
X
#ifdef MACG
X      HiliteMenu(0);
X      SystemTask();
X      fEvent = GetNextEvent(everyEvent, &erCur);
X      if (fEvent) {
X        switch (erCur.what) {
X        case mouseDown:
X          wc = FindWindow(erCur.where, &wpCur);
X          switch (wc) {
X          case inSysWindow:
X            SystemClick(&erCur, wpCur);
X            break;
X          case inMenuBar:
X            MenuSelect(erCur.where);
X            break;
X          case inDrag:
X            if (wpCur == gi.wpAst)
X              DragWindow(gi.wpAst, erCur.where, &gi.rcDrag);
X            break;
X          case inContent:
X            if (wpCur == gi.wpAst && wpCur != FrontWindow())
X              SelectWindow(gi.wpAst);
X            break;
X          case inGoAway:
X            if (wpCur == gi.wpAst && TrackGoAway(gi.wpAst, erCur.where))
X              HideWindow(gi.wpAst);
X            break;
X          }
X          break;
X        case updateEvt:
X          /*fRedraw = fTrue;*/
X          break;
X        case keyDown:
X        case autoKey:
X          key = (char)(erCur.message & charCodeMask);
#endif /* MACG */
X
LSwitch:
X          switch (key) {
#ifdef PCG
X          case chNull:
X            key = NFromAltN(getch());
X            goto LSwitch;
#endif
X          case ' ':
X            fRedraw = fTrue;
X            break;
X          case 'p':
X            not(fPause);
X            break;
X          case 'r':
X            neg(dir);
X            break;
X          case 'x':
X            not(gs.fInverse);
X            InitColorsX();
X            fRedraw = fTrue;
X            break;
X          case 'm':
X            if (!gi.fMono) {
X              not(gs.fColor);
#ifdef MSG
X              _getvideoconfig((struct videoconfig far *) &gi.cfg);
#endif
X              InitColorsX();
X              fRedraw = fTrue;
X            }
X            break;
X          case 'B':
#ifdef X11
X            XSetWindowBackgroundPixmap(gi.disp, gi.root, gi.pmap);
X            XClearWindow(gi.disp, gi.root);
#endif
#ifdef PCG
X            gs.xWin = xPcScreen;
X            gs.yWin = yPcScreen;
X            SquareX(&gs.xWin, &gs.yWin, fFalse);
X            fResize = fTrue;
#endif
X            break;
X          case 't':
X            not(gs.fText);
X            fRedraw = fTrue;
X            break;
X          case 'i':
X            not(gs.fAlt);
X            fRedraw = fTrue;
X            break;
X          case 'b':
X            not(gs.fBorder);
X            fRedraw = fTrue;
X            break;
X          case 'l':
X            not(gs.fLabel);
X            fRedraw = fTrue;
X            break;
X          case 'j':
X            not(gs.fJetTrail);
X            break;
X          case '<':
X            if (gs.nScale > 100) {
X              gs.nScale -= 100;
X              fResize = fTrue;
X            }
X            break;
X          case '>':
X            if (gs.nScale < MAXSCALE) {
X              gs.nScale += 100;
X              fResize = fTrue;
X            }
X            break;
X          case '[':
X            if (gi.nMode == gGlobe && gs.rTilt > -rDegQuad) {
X              gs.rTilt = gs.rTilt > -rDegQuad ? gs.rTilt-TILTSTEP : -rDegQuad;
X              fRedraw = fTrue;
X            }
X            break;
X          case ']':
X            if (gi.nMode == gGlobe && gs.rTilt < rDegQuad) {
X              gs.rTilt = gs.rTilt < rDegQuad ? gs.rTilt+TILTSTEP : rDegQuad;
X              fRedraw = fTrue;
X            }
X            break;
X          case 'Q':
X            SquareX(&gs.xWin, &gs.yWin, fTrue);
X            fResize = fTrue;
X            break;
X          case 'R':
X            for (i = oChi; i <= oVes; i++)
X              not(ignore[i]);
X            for (i = oLil; i <= oEP; i++)
X              not(ignore[i]);
X            fCast = fTrue;
X            break;
X          case 'C':
X            not(us.fCusp);
X            for (i = cuspLo; i <= cuspHi; i++)
X              ignore[i] = !us.fCusp || !ignore[i];
X            fCast = fTrue;
X            break;
X          case 'u':
X            not(us.fUranian);
X            for (i = uranLo; i <= uranHi; i++)
X              ignore[i] = !us.fUranian || !ignore[i];
X            fCast = fTrue;
X            break;
X          case 'U':
X            us.nStar = !us.nStar;
X            for (i = starLo; i <= starHi; i++)
X              ignore[i] = !us.nStar || !ignore[i];
X            fCast = fTrue;
X            break;
X          case 'c':
X            us.nRel = us.nRel ? 0 : rcDual;
X            fCast = fTrue;
X            break;
X          case 's':
X            not(us.fSidereal);
X            fCast = fTrue;
X            break;
X          case 'h':
X            not(us.objCenter);
X            fCast = fTrue;
X            break;
X          case 'f':
X            not(us.fFlip);
X            fCast = fTrue;
X            break;
X          case 'g':
X            not(us.fDecan);
X            fCast = fTrue;
X            break;
X          case 'z':
X            not(us.fVedic);
X            fRedraw = fTrue;
X            break;
X          case 'y':
X            not(us.fNavamsa);
X            fCast = fTrue;
X            break;
X          case '+':
X            Animate(gs.nAnim, abs(dir));
X            fCast = fTrue;
X            break;
X          case '-':
X            Animate(gs.nAnim, -abs(dir));
X            fCast = fTrue;
X            break;
X          case 'o':
X            ciSave = ciMain;
X            break;
X          case 'O':
X            ciMain = ciSave;
X            fCast = fTrue;
X            break;
#ifdef TIME
X          case 'n':
X            FInputData(szNowCore);
X            ciMain = ciCore;
X            fCast = fTrue;
X            break;
#endif
X          case 'N':                     /* The continuous update animation. */
X            gs.nAnim = gs.nAnim ? 0 : -10;
X            break;
X
X          /* These are the nine different "add time to chart" animations. */
X          case '!': gs.nAnim = -1; break;
X          case '@': gs.nAnim = -2; break;
X          case '#': gs.nAnim = -3; break;
X          case '$': gs.nAnim = -4; break;
X          case '%': gs.nAnim = -5; break;
X          case '^': gs.nAnim = -6; break;
X          case '&': gs.nAnim = -7; break;
X          case '*': gs.nAnim = -8; break;
X          case '(': gs.nAnim = -9; break;
X
X          /* Should we go switch to a new chart type? */
X          case 'V': gi.nMode = gWheel;      fRedraw = fTrue; break;
X          case 'A': gi.nMode = gGrid;       fRedraw = fTrue; break;
X          case 'Z': gi.nMode = gHorizon;    fRedraw = fTrue; break;
X          case 'S': gi.nMode = gOrbit;      fRedraw = fTrue; break;
X          case 'M': gi.nMode = gSector;     fRedraw = fTrue; break;
X          case 'K': gi.nMode = gCalendar;   fRedraw = fTrue; break;
X          case 'J': gi.nMode = gDisposit;   fRedraw = fTrue; break;
X          case 'L': gi.nMode = gAstroGraph; fRedraw = fTrue; break;
X          case 'E': gi.nMode = gEphemeris;  fRedraw = fTrue; break;
X          case 'W': gi.nMode = gWorldMap;   fRedraw = fTrue; break;
X          case 'G': gi.nMode = gGlobe;      fRedraw = fTrue; break;
X          case 'P': gi.nMode = gPolar;      fRedraw = fTrue; break;
#ifdef BIORHYTHM
X          case 'Y':            /* Should we switch to biorhythm chart? */
X            us.nRel = rcBiorhythm;
X            gi.nMode = gBiorhythm;
X            fCast = fTrue;
X            break;
#endif
#ifdef CONSTEL
X          case 'F':
X            if (!fMap && gi.nMode != gGlobe && gi.nMode != gPolar)
X              gi.nMode = gWorldMap;
X            not(gs.fConstel);
X            fRedraw = fTrue;
X            break;
#endif
X          case '0':
X            not(us.fPrimeVert);
X            not(us.fCalendarYear);
X            not(us.nEphemYears);
X            not(gs.fMollewide);
X            gi.nMode = (gi.nMode == gWheel ? gHouse :
X              (gi.nMode == gHouse ? gWheel : gi.nMode));
X            fRedraw = fTrue;
X            break;
X          case 'v': case 'H': case '?':
#ifdef MSG
X            _setvideomode(_DEFAULTMODE);
X            if (key != 'v')
X              _settextrows(50);
#endif
#ifdef BGI
X            restorecrtmode();
X            if (key != 'v')
X              textmode(C4350);
#endif
X            length = us.nScrollRow;
X            us.nScrollRow = 0;
X            if (key == 'v')
X              ChartListing();
X            else
X              DisplayKeysX();
X            us.nScrollRow = length;
#ifdef PCG
X            while (!kbhit())
X              ;
X            key = getch();
X            if (key == 'q' || key == chEscape || key == chBreak) {
X              fBreak = fTrue;
X              break;
X            }
X            BeginX();
X            fResize = fTrue;
#endif
X            break;
X          case chReturn:
X            CommandLineX();
X            fResize = fCast = fTrue;
X            break;
#ifdef PCG
X          case chTab:
X            if (gi.nRes == gs.nResHi)
X              gi.nRes = gs.nResLo;
X            else
X              gi.nRes = gs.nResHi;
X            BeginX();
X            gs.xWin = xPcScreen;
X            gs.yWin = yPcScreen;
X            SquareX(&gs.xWin, &gs.yWin, fFalse);
X            fResize = fTrue;
X            break;
#endif
X          case chDelete:
#ifdef PCG
#ifdef MOUSE
X            MouseShow(fFalse);
#endif
#endif /* PCG */
X            fT = gs.fJetTrail;
X            gs.fJetTrail = fFalse;
X            DrawClearScreen();
X            gs.fJetTrail = fT;
X            break;
#ifdef MOUSE
X          case 'z'-'`': coldrw = kBlack;   break;
X          case 'e'-'`': coldrw = kMaroon;  break;
X          case 'f'-'`': coldrw = kDkGreen; break;
X          case 'o'-'`': coldrw = kOrange;  break;
X          case 'n'-'`': coldrw = kDkBlue;  break;
X          case 'u'-'`': coldrw = kPurple;  break;
X          case 'k'-'`': coldrw = kDkCyan;  break;
X          case 'l'-'`': coldrw = kLtGray;  break;
X          case 'd'-'`': coldrw = kDkGray;  break;
X          case 'r'-'`': coldrw = kRed;     break;
X          case 'g'-'`': coldrw = kGreen;   break;
X          case 'y'-'`': coldrw = kYellow;  break;
X          case 'b'-'`': coldrw = kBlue;    break;
X          case 'v'-'`': coldrw = kMagenta; break;
X          case 'j'-'`': coldrw = kCyan;    break;
X          case 'a'-'`': coldrw = kWhite;   break;
#ifdef PCG
X          case 't'-'`':
X            MouseShow(fFalse);
X            if (buttonx >= 0)
#ifdef MSG
X              _rectangle(_GBORDER, buttonx, buttony, mousex, mousey);
#else
X              DrawEdge(Min(buttonx, mousex) - gi.xOffset,
X                Min(buttony, mousey) - gi.yOffset,
X                Max(mousex, buttonx) - gi.xOffset,
X                Max(mousey, buttony) - gi.yOffset);
#endif
X            MouseShow(fTrue);
X            break;
X          case 'x'-'`':
X            MouseShow(fFalse);
X            if (buttonx >= 0)
#ifdef MSG
X              _ellipse(_GBORDER, buttonx, buttony, mousex, mousey);
#else
X              DrawEllipse(Min(buttonx, mousex) - gi.xOffset,
X                Min(buttony, mousey) - gi.yOffset,
X                Max(mousex, buttonx) - gi.xOffset,
X                Max(mousey, buttony) - gi.yOffset);
#endif
X            MouseShow(fTrue);
X            break;
#endif /* PCG */
#endif /* MOUSE */
X          case 'q': case chEscape: case chBreak:
X            fBreak = fTrue;
X            break;
X          default:
X            if (key > '0' && key <= '9') {
#ifdef PCG
X              if (gs.nAnim && !fPause)
#endif
X                /* Process numbers 1..9 signifying animation rate. */
X                dir = (dir > 0 ? 1 : -1)*(key-'0');
#ifdef PCG
X              else {
X                /* If we aren't in animation mode, then 1..9 refers to the */
X                /* clipping "quadrant" to use if chart size > screen size. */
X                xcorner = key-'0';
X                fResize = fTrue;
X              }
#endif
X              break;
X            } else if (FBetween(key, 201, 248)) {
X              is.fSzInteract = fTrue;
X              if (szMacro[key-201]) {
X                FProcessCommandLine(szMacro[key-201]);
X                fResize = fCast = fTrue;
X              }
X              is.fSzInteract = fFalse;
X              break;
X            }
X            putchar(chBell);    /* Any key not bound will sound a beep. */
X          }  /* switch */
X        }  /* if */
#ifdef X11
X      default:
X        ;
X      }  /* switch */
X    }  /* if */
#endif
#ifdef MACG
X    }  /* if */
#endif
X  }  /* while */
}
X
X
/* This is called right before program termination to get rid of the window. */
X
void EndX()
{
#ifdef X11
X  XFreeGC(gi.disp, gi.gc);
X  XFreeGC(gi.disp, gi.pmgc);
X  XFreePixmap(gi.disp, gi.pmap);
X  XDestroyWindow(gi.disp, gi.wind);
X  XCloseDisplay(gi.disp);
#endif
#ifdef MSG
X  _setvideomode(_DEFAULTMODE);
#endif
#ifdef BGI
X  restorecrtmode();
#endif
#ifdef MACG
X  DisposeWindow(gi.wpAst);
#endif
}
#endif /* ISG */
#endif /* WIN */
X
X
/*
******************************************************************************
** Main Graphics Processing.
******************************************************************************
*/
X
/* Process one command line switch passed to the program dealing with the    */
/* graphics features. This is just like the processing of each switch in the */
/* main program, however here each switch has been prefixed with an 'X'.     */
X
int NProcessSwitchesX(argc, argv, pos, fOr, fAnd, fNot)
int argc, pos;
bool fOr, fAnd, fNot;
char **argv;
{
X  int darg = 0, i, j;
X  real rT;
X  char ch1;
X
X  ch1 = argv[0][pos+1];
X  switch (argv[0][pos]) {
X  case chNull:
X    break;
X
X  case 'b':
X    if (us.fNoWrite || is.fSzInteract) {
X      ErrorArgv("Xb");
X      return tcError;
X    }
X    ch1 = ChCap(ch1);
X    if (FValidBmpmode(ch1))
X      gs.chBmpMode = ch1;
X    SwitchF2(gs.fBitmap);
X    gs.fPS = gs.fMeta = fFalse;
X    break;
X
#ifdef PS
X  case 'p':
X    if (us.fNoWrite || is.fSzInteract) {
X      ErrorArgv("Xp");
X      return tcError;
X    }
X    gs.fPS = fTrue + (ch1 != '0');
X    gs.fBitmap = gs.fMeta = fFalse;
X    break;
#endif
X
#ifdef META
X  case 'M':
X    if (us.fNoWrite || is.fSzInteract) {
X      ErrorArgv("XM");
X      return tcError;
X    }
X    if (ch1 == '0')
X      SwitchF(gs.fFont);
X    SwitchF2(gs.fMeta);
X    gs.fBitmap = gs.fPS = fFalse;
X    break;
#endif
X
X  case 'o':
X    if (us.fNoWrite || is.fSzInteract) {
X      ErrorArgv("Xo");
X      return tcError;
X    }
X    if (argc <= 1) {
X      ErrorArgc("Xo");
X      return tcError;
X    }
X    if (!gs.fBitmap && !gs.fPS && !gs.fMeta)
X      gs.fBitmap = fTrue;
X    gi.szFileOut = SzPersist(argv[1]);
X    darg++;
X    break;
X
#ifdef X11
X  case 'B':
X    if (is.fSzInteract) {
X      ErrorArgv("XB");
X      return tcError;
X    }
X    SwitchF(gs.fRoot);
X    break;
#endif
X
X  case 'm':
X    SwitchF(gs.fColor);
X    break;
X
X  case 'r':
X    SwitchF(gs.fInverse);
X    break;
X
X  case 'w':
X    if (argc <= 1) {
X      ErrorArgc("Xw");
X      return tcError;
X    }
X    i = atoi(argv[1]);
X    if (argc > 2 && ((j = atoi(argv[2])) || argv[2][0] == '0')) {
X      argc--; argv++;
X      darg++;
X    } else
X      j = i;
X    if (!FValidGraphx(i)) {
X      ErrorValN("Xw", i);
X      return tcError;
X    }
X    if (!FValidGraphy(j)) {
X      ErrorValN("Xw", j);
X      return tcError;
X    }
X    gs.xWin = i; gs.yWin = j;
X    darg++;
X    break;
X
X  case 's':
X    if (argc <= 1) {
X      ErrorArgc("Xs");
X      return tcError;
X    }
X    i = atoi(argv[1]);
X    if (i < 100)
X      i *= 100;
X    if (!FValidScale(i)) {
X      ErrorValN("Xs", i);
X      return tcError;
X    }
X    gs.nScale = i;
X    darg++;
X    break;
X
X  case 'i':
X    SwitchF(gs.fAlt);
X    break;
X
X  case 't':
X    SwitchF(gs.fText);
X    break;
X
X  case 'u':
X    SwitchF(gs.fBorder);
X    break;
X
X  case 'l':
X    SwitchF(gs.fLabel);
X    break;
X
X  case 'j':
X    SwitchF(gs.fJetTrail);
X    break;
X
X  case '1':
X    if (argc <= 1) {
X      ErrorArgc("X1");
X      return tcError;
X    }
X    i = NParseSz(argv[1], pmObject);
X    if (!FItem(i)) {
X      ErrorValN("X1", i);
X      return tcError;
X    }
X    gs.objLeft = i;
X    darg++;
X    break;
X
X  case '2':
X    if (argc <= 1) {
X      ErrorArgc("X2");
X      return tcError;
X    }
X    i = NParseSz(argv[1], pmObject);
X    if (!FItem(i)) {
X      ErrorValN("X2", i);
X      return tcError;
X    }
X    gs.objLeft = -i;
X    darg++;
X    break;
X
#ifdef X11
X  case 'd':
X    if (is.fSzInteract) {
X      ErrorArgv("Xd");
X      return tcError;
X    }
X    if (argc <= 1) {
X      ErrorArgc("Xd");
X      return tcError;
X    }
X    gs.szDisplay = SzPersist(argv[1]);
X    darg++;
X    break;
#endif
X
X  case 'W':
X    if (argc > 1 && ((i = atoi(argv[1])) || argv[1][0] == '0')) {
X      darg++;
X      if (!FValidRotation(i)) {
X        ErrorValN("XW", i);
X        return tcError;
X      }
X      gs.nRot = i;
X    }
X    gi.nMode = gWorldMap;
X    if (ch1 == '0')
X      gs.fMollewide = fTrue;
X    is.fHaveInfo = fTrue;
X    break;
X
X  case 'G':
X    if (argc > 1 && ((i = atoi(argv[1])) || argv[1][0] == '0')) {
X      darg++;
X      if (!FValidRotation(i)) {
X        ErrorValN("XG", i);
X        return tcError;
X      }
X      gs.nRot = i;
X      if (argc > 2 && ((rT = atof(argv[2])) || argv[2][0] == '0')) {
X        darg++;
X        if (!FValidTilt(rT)) {
X          ErrorValR("XG", rT);
X          return tcError;
X        }
X        gs.rTilt = rT;
X      }
X    }
X    gi.nMode = gGlobe;
X    is.fHaveInfo = fTrue;
X    break;
X
X  case 'P':
X    if (argc > 1 && ((i = atoi(argv[1])) || argv[1][0] == '0')) {
X      darg++;
X      if (!FValidRotation(i)) {
X        ErrorValN("XP", i);
X        return tcError;
X      }
X    } else
X      i = 0;
X    gs.nRot = i;
X    gi.nMode = gPolar;
X    if (ch1 == '0')
X      gs.fPrintMap = fTrue;
X    is.fHaveInfo = fTrue;
X    break;
X
#ifdef CONSTEL
X  case 'F':
X    if (!fMap && gi.nMode != gGlobe && gi.nMode != gPolar)
X      gi.nMode = gWorldMap;
X    not(gs.fConstel);
X    is.fHaveInfo = fTrue;
X    break;
#endif
X
#ifdef ISG
X  case 'n':
X    if (argc > 1 && (i = atoi(argv[1])))
X      darg++;
X    else
X      i = 10;
X    if (i < 1 || i > 10) {
X      ErrorValN("Xn", i);
X      return tcError;
X    }
X    gs.nAnim = i;
X    break;
#endif
X
X  default:
X    ErrorSwitch(argv[0]);
X    return tcError;
X  }
X  /* 'darg' contains the value to be added to argc when we return. */
X  return darg;
}
X
X
/* Process one command line switch passed to the program dealing with more  */
/* obscure graphics options. This is structured very much like the function */
/* NProcessSwitchesX(), except here we know each switch begins with 'YX'.   */
X
int NProcessSwitchesRareX(argc, argv, pos)
int argc, pos;
char **argv;
{
X  int darg = 0, i;
#ifdef PS
X  char ch1;
X
X  ch1 = argv[0][pos+1];
#endif
X  switch (argv[0][pos]) {
X  case chNull:
X    if (argc <= 2) {
X      ErrorArgc("YX");
X      return tcError;
X    }
#ifdef PCG
X    i = atoi(argv[1]);
X    if (!FValidResmode(i)) {
X      ErrorValN("YX", i);
X      return tcError;
X    }
X    gs.nResHi = i;
X    i = atoi(argv[2]);
X    if (!FValidResmode(i)) {
X      ErrorValN("YX", i);
X      return tcError;
X    }
X    gs.nResLo = i;
X    gs.fBitmap = gs.fPS = gs.fMeta = fFalse;
#endif
X    darg += 2;
X    break;
X
X  case 'G':
X    if (argc <= 1) {
X      ErrorArgc("YXG");
X      return tcError;
X    }
X    i = atoi(argv[1]);
X    if (!FValidGlyphs(i)) {
X      ErrorValN("YXg", i);
X      return tcError;
X    }
X    gs.nGlyphs = i;
X    darg++;
X    break;
X
X  case 'g':
X    if (argc <= 1) {
X      ErrorArgc("YXg");
X      return tcError;
X    }
X    i = atoi(argv[1]);
X    if (!FValidGrid(i)) {
X      ErrorValN("YXg", i);
X      return tcError;
X    }
X    gs.nGridCell = i;
X    darg++;
X    break;
X
X  case 'f':
X    if (argc <= 1) {
X      ErrorArgc("YXf");
X      return tcError;
X    }
X    gs.fFont = atoi(argv[1]);
X    darg++;
X    break;
X
#ifdef PS
X  case 'p':
X    if (ch1 == '0') {
X      if (argc <= 2) {
X        ErrorArgc("YXp0");
X        return tcError;
X      }
X      gs.xInch = atof(argv[1]);
X      gs.yInch = atof(argv[2]);
X      darg += 2;
X      break;
X    }
X    if (argc <= 1) {
X      ErrorArgc("YXp");
X      return tcError;
X    }
X    gs.nOrient = atoi(argv[1]);
X    darg++;
X    break;
#endif
X
X  default:
X    ErrorSwitch(argv[0]);
X    return tcError;
X  }
X  /* 'darg' contains the value to be added to argc when we return. */
X  return darg;
}
X
X
/* This is the main interface to all the graphics features. This routine     */
/* is called from the main program if any of the -X switches were specified, */
/* and it sets up for and goes and generates the appropriate graphics chart. */
/* We return fTrue if successfull, fFalse if some non-fatal error occurred.  */
X
bool FActionX()
{
X  gi.fFile = (gs.fBitmap || gs.fPS || gs.fMeta);
#ifdef PS
X  gi.fEps = gs.fPS > fTrue;
#endif
X
X  /* First figure out what graphic mode to generate the chart in, based on */
X  /* various non-X command switches, e.g. -L combined with -X, -g combined */
X  /* with -X, and so on, and determine the size the window is to be, too.  */
X
X  if (gi.nMode == 0) {
X    if (us.fWheel)
X      gi.nMode = gHouse;
X    else if (us.fGrid || us.fMidpoint)
X      gi.nMode = gGrid;
X    else if (us.fHorizon)
X      gi.nMode = gHorizon;
X    else if (us.fOrbit)
X      gi.nMode = gOrbit;
X    else if (us.fSector)
X      gi.nMode = gSector;
X    else if (us.fInfluence)
X      gi.nMode = gDisposit;
X    else if (us.fAstroGraph)
X      gi.nMode = gAstroGraph;
X    else if (us.fCalendar)
X      gi.nMode = gCalendar;
X    else if (us.fEphemeris)
X      gi.nMode = gEphemeris;
X    else if (us.nRel == rcBiorhythm)
X      gi.nMode = gBiorhythm;
X    else
X      gi.nMode = gWheel;
X  }
X  if (gi.nMode == gGrid) {
X    if (us.nRel <= rcDual && us.fMidpoint && !us.fAspList)
X      us.fGridConfig = fTrue;
X    gs.xWin = gs.yWin =
X      (gs.nGridCell + (us.nRel <= rcDual))*CELLSIZE*gi.nScale + 1;
X  } else if (fMap) {
X    gs.xWin = nDegMax*gi.nScale;
X    gs.yWin = nDegHalf*gi.nScale;
X  }
#ifdef WIN
X  if (fSidebar)
X    gs.xWin -= SIDESIZE;
#endif
X  gi.nScaleT = gs.fPS ? PSMUL : (gs.fMeta ? METAMUL : 1);
#ifdef WIN
X  if (wi.hdcPrint != hdcNil)
X    gi.nScaleT = METAMUL;
#endif
X
X  if (gi.fFile) {
X    if (gs.xWin == 0)
X      gs.xWin = DEFAULTX;
X    if (gs.yWin == 0)
X      gs.yWin = DEFAULTY;
X    if (fSidebar)
X      gs.xWin += SIDESIZE;
X    if (gs.xWin > BITMAPX)
X      gs.xWin = BITMAPX;
X    if (gs.yWin > BITMAPY)
X      gs.yWin = BITMAPY;
X    BeginFileX();
X    if (gs.fBitmap) {
X      gi.cbBmpRow = (gs.xWin + 1) >> 1;
X      gi.yBand = gs.yWin;
X      if (!FEnsureGrid())
X        return fFalse;
X      while ((gi.bm = PAllocate((long)gi.cbBmpRow * gi.yBand, fTrue, NULL)) ==
X        NULL) {
X        PrintWarning("The bitmap must be generated in multiple stages.");
X        gi.yBand = (gi.yBand + 1) / 2;
X        if (gi.yBand < 1 || gs.chBmpMode != 'B')
X          return fFalse;
X      }
X      if (gi.yBand == gs.yWin)
X        gi.yBand = 0;
X      else {
X        gi.yOffset = gs.yWin - gs.yWin % gi.yBand;
X        if (gi.yOffset == gs.yWin)
X          gi.yOffset -= gi.yBand;
X      }
X    }
#ifdef PS
X    else if (gs.fPS)
X      PsBegin();
#endif
#ifdef META
X    else {
X      if (!FEnsureGrid())
X        return fFalse;
X      for (gi.cbMeta = MAXMETA; gi.cbMeta > 0 &&
X        (gi.bm = PAllocate(gi.cbMeta, fTrue, NULL)) == NULL;
X        gi.cbMeta -= MAXMETA/8)
X        PrintWarning("Attempting to get maximum memory for metafile.");
X      if (gi.cbMeta == 0)
X        return fFalse;
X      gs.xWin   *= METAMUL;  /* Increase chart sizes and scales behind the */
X      gs.yWin   *= METAMUL;  /* scenes to make graphics look smoother.     */
X      gs.nScale *= METAMUL;
X    }
#endif
X    InitColorsX();
X  }
#ifdef ISG
X  else {
#ifdef PCG
X    BeginX();
X    if (gs.xWin == 0 || gs.yWin == 0) {
X      if (gs.xWin == 0)
X        gs.xWin = xPcScreen;
X      if (gs.yWin == 0)
X        gs.yWin = yPcScreen;
X      SquareX(&gs.xWin, &gs.yWin, fFalse);
X    } else if (fSidebar)
X      gs.xWin += SIDESIZE;
#else
X    if (gs.xWin == 0 || gs.yWin == 0) {
X      if (gs.xWin == 0)
X        gs.xWin = DEFAULTX;
X      if (gs.yWin == 0)
X        gs.yWin = DEFAULTY;
X      SquareX(&gs.xWin, &gs.yWin, fFalse);
X    } else if (fSidebar)
X      gs.xWin += SIDESIZE;
X    BeginX();
#endif
X  }
#endif /* ISG */
X
X  if (gi.fFile || gs.fRoot)    /* Go draw the graphic chart. */
X    DrawChartX();
X  if (gi.fFile) {    /* Write bitmap to file if in that mode. */
X    EndFileX();
X    while (gi.yBand) {
X      gi.yOffset -= gi.yBand;
X      DrawChartX();
X      EndFileX();
X    }
X    if (!gs.fPS)
X      DeallocateHuge(gi.bm);
X  }
#ifdef ISG
X  else {
#ifdef X11
X    if (gs.fRoot) {                                         /* Process -XB. */
X      XSetWindowBackgroundPixmap(gi.disp, gi.root, gi.pmap);
X      XClearWindow(gi.disp, gi.root);
X
X      /* If -Xn in effect with -XB, then enter infinite loop where we */
X      /* calculate and animate chart, displaying on the root window.  */
X      while (gs.nAnim) {
X        Animate(gs.nAnim, 1);
X        if (!gs.fJetTrail)
X          XFillRectangle(gi.disp, gi.pmap, gi.pmgc, 0, 0, gs.xWin, gs.yWin);
X        DrawChartX();
X        XSetWindowBackgroundPixmap(gi.disp, gi.root, gi.pmap);
X        XClearWindow(gi.disp, gi.root);
X      }
X    } else
#endif
#ifndef WIN
X      InteractX();    /* Window's up; process commands given to window now. */
X    EndX();
#else
X    DrawChartX();
#endif
X  }
#endif /* ISG */
X  return fTrue;
}
#endif /* GRAPH */
X
/* xscreen.c */
SHAR_EOF
  $shar_touch -am 1223232998 'xscreen.c' &&
  chmod 0644 'xscreen.c' ||
  echo 'restore of xscreen.c failed'
  shar_count="`wc -c < 'xscreen.c'`"
  test 51783 -eq "$shar_count" ||
    echo "xscreen.c: original size 51783, current size $shar_count"
fi
exit 0
