home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume42
/
astrolog
/
part08
/
driver.c
Wrap
C/C++ Source or Header
|
1994-03-25
|
56KB
|
1,808 lines
/*
** Astrolog (Version 4.10) File: driver.c
**
** IMPORTANT NOTICE: the graphics database and chart display routines
** used in this program are Copyright (C) 1991-1994 by Walter D. Pullen
** (cruiser1@stein.u.washington.edu). 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 3/19/1994.
*/
#include "astrolog.h"
char *filenamescreen = NULL, *filenameout, **extralines;
int prog = FALSE, extracount = 0;
/*
******************************************************************************
** Table Display Routines.
******************************************************************************
*/
/* 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. */
#define CREDITWIDTH 74
void PrintW(string, col)
char *string;
int col;
{
int i;
if (!string) {
/* Null string means print the top, bottom, or a separator row. */
if (col < 0)
AnsiColor(RED);
printc(col ? (col > 0 ? BOXSW : BOXNW) : BOXJE);
PrintTab(BOXH, CREDITWIDTH);
printc(col ? (col > 0 ? BOXSE : BOXNE) : BOXJW);
} else {
i = StringLen(string);
printc(BOXV);
PrintTab(' ', (CREDITWIDTH-i)/2 + (i&1));
AnsiColor(col);
fprintf(S, "%s", string);
PrintTab(' ', (CREDITWIDTH-i)/2);
AnsiColor(RED);
printc(BOXV);
}
printl();
}
/* 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. */
void DisplayCredits()
{
char string[STRING];
PrintW(NULL, -1);
sprintf(string, "%s version %s", appname, VERSION);
PrintW(string, WHITE);
sprintf(string, "As of %s.", DATE);
PrintW(string, LTGRAY);
PrintW("By Walter D. Pullen (cruiser1@stein.u.washington.edu)", CYAN);
PrintW(NULL, 0);
PrintW("Main planetary calculation formulas were converted from", GREEN);
PrintW(
"routines by James Neely, as listed in 'Manual of Computer Programming",
GREEN);
PrintW(
"for Astrologers' by Michael Erlewine, available from Matrix Software.",
GREEN);
PrintW("PostScript graphics routines by Brian D. Willoughby", YELLOW);
PrintW(
"Extended ephemeris calculation and formulas are by Alois Treindl,",
MAGENTA);
PrintW(
"as in the package 'Placalc', available from Astrodienst AG.", MAGENTA);
PrintW(
"IMPORTANT: Astrolog is 'freeware', but is copyrighted and not in public",
LTGRAY);
PrintW(
"domain. Permission is granted to freely use and distribute these",
LTGRAY);
PrintW(
"routines provided one does not sell, restrict, or profit from the",
LTGRAY);
PrintW(
"program or its output in any way. Modification is allowed provided",
LTGRAY);
PrintW(
"these exact notices remain with any altered or edited versions of the",
LTGRAY);
PrintW(
"program. These conditions are true of both the program in whole and of",
LTGRAY);
PrintW(
"all parts by any individual author. Violators are subject to copyright",
LTGRAY);
PrintW(
"law penalties, and negative karmic debts to aforementioned contributors.",
LTGRAY);
PrintW(NULL, 0);
PrintW(
"Special thanks to all those unmentioned, seen and unseen, who have",
BLUE);
PrintW(
"pointed out problems, suggested featues, and sent many positive vibes!",
BLUE);
PrintW(NULL, 1);
AnsiColor(DEFAULT);
}
/* 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. */
void Prints(string)
char *string;
{
int dash;
char c;
dash = string[1];
if (*string != ' ')
AnsiColor(RED);
else if (dash != ' ')
AnsiColor(dash == 'P' || string[3] == ' ' || string[3] == ':' ?
GREEN : DKGREEN);
else
AnsiColor(DEFAULT);
while ((c = *string) && c != ':' &&
(dash != 'P' || (c != ' ' || *(string+1) != 't'))) {
if (c != '_')
printc(c);
else
printc(DASH);
string++;
}
if (*string)
printc(*string++);
AnsiColor(DEFAULT);
while (c = *string) {
if (c != '_')
printc(c);
else
printc(DASH);
string++;
}
printl();
}
/* 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. */
void DisplaySwitches()
{
char string[STRING];
sprintf(string, "%s (version %s) command switches:", appname, VERSION);
Prints(string);
Prints(" _H: Display this help list.");
Prints(" _Hc: Display program credits and copyrights.");
Prints(" _H0: Display names of zodiac signs and houses.");
Prints(" _O: Display available planets and other celestial objects.");
Prints(" _O0: Like _O but ignore object restrictions.");
Prints(" _A: Display available aspects, their angles, and present orbs.");
#ifdef INTERPRET
Prints(" _I0: Display meanings of signs, houses, planets, and aspects.");
#endif
Prints(" _Q: Prompt for more command switches after display finished.");
#ifdef SWITCHES
Prints(" _Q0: Like _Q but prompt for additional switches on startup.");
#endif
Prints("\nSwitches which determine the type of chart to display:");
Prints(" _v: Display list of object positions (chosen by default).");
Prints(" _v0: Like _v but express velocities relative to average speed.");
Prints(" _w [<rows>]: Display chart in a graphic house wheel format.");
Prints(" _w0 [..]: Like _w but reverse order of objects in houses 4..9.");
Prints(" _g: Display aspect and midpoint grid among planets.");
Prints(" _g0: Like _g but flag aspect configurations (e.g. Yod's) too.");
Prints(" _g0: For comparison charts, show midpoints instead of aspects.");
Prints(" _ga: Like _g but indicate applying instead of difference orbs.");
Prints(" _m: Display all object midpoints in sorted zodiac order.");
Prints(" _m0: Like _m but list aspects ordered by influence instead.");
Prints(" _m[0]a: Like _m0 but indicate applying and separating orbs.");
Prints(" _Z: Display planet locations with respect to the local horizon.");
#ifdef GRAPH
Prints(" _Z0: Like _Z but express coordinates relative to polar center.");
#endif
Prints(" _Zd: Search day for object local rising and setting times.");
Prints(" _S: Display x,y,z coordinate positions of planets in space.");
Prints(" _j: Display astrological influences of each object in chart.");
Prints(" _j0: Like _j but include influences of each zodiac sign as well.");
Prints(" _L [<step>]: Display astro-graph locations of planetary angles.");
Prints(" _L0 [..]: Like _L but display list of latitude crossings too.");
Prints(" _K: Display a calendar for given month.");
Prints(" _Ky: Like _K but display a calendar for the entire year.");
Prints(" _d [<step>]: Print all aspects and changes occurring in a day.");
Prints(" _dm: Like _d but print all aspects for the entire month.");
Prints(" _dy: Like _d but print all aspects for the entire year.");
Prints(" _dp <month> <year>: Print aspects within progressed chart.");
Prints(" _dpy <year>: Like _dp but search for aspects within entire year.");
Prints(" _dp[y]n: Search for progressed aspects in current month/year.");
Prints(" _D: Like _d but display aspects by influence instead of time.");
Prints(" _E: Display planetary ephemeris for given month.");
Prints(" _Ey: Display planetary ephemeris for the entire year.");
Prints(" _e: Print all charts together (i.e. _v_w_g0_m_Z_S_j0_L0_K_d_D_E).");
Prints(
" _t <month> <year>: Compute all transits to natal planets in month.");
Prints(
" _tp <month> <year>: Compute progressions in month for chart.");
Prints(" _t[p]y: <year>: Compute transits/progressions for entire year.");
Prints(" _t[p]Y: <year> <years>: Compute transits for a number of years.");
#ifdef TIME
Prints(" _t[py]n: Compute transits to natal planets for current time now.");
#endif
Prints(" _T <month> <day> <year>: Display transits ordered by influence.");
Prints(" _Tp <month> <day> <year>: Print progressions instead of transits.");
#ifdef TIME
Prints(" _T[p]n: Display transits ordered by influence for current date.");
#endif
#ifdef INTERPRET
Prints(" _I [<columns>]: Print interpretation of selected charts.");
#endif
Prints("\nSwitches which affect how the chart parameters are obtained:");
#ifdef TIME
Prints(" _n: Compute chart for this exact moment using current time.");
Prints(" _n[d,m,y]: Compute chart for start of current day, month, year.");
#endif
Prints(" _z: Assume Daylight time (change default zone appropriately).");
Prints(" _z <zone>: Change the default time zone (for _d_E_t_q options).");
Prints(" _l <long> <lat>: Change the default longitude & latitude.");
Prints(" _q <month> <date> <year> <time>: Compute chart with defaults.");
Prints(" _qd <month> <date> <year>: Compute chart for noon on date.");
Prints(" _qm <month> <year>: Compute chart for first of month.");
Prints(" _qy <year>: Compute chart for first day of year.");
Prints(" _qa <month> <date> <year> <time> <zone> <long> <lat>:");
Prints(" Compute chart automatically given specified data.");
Prints(" _qj <day>: Compute chart for time of specified Julian day.");
Prints(" _i <file>: Compute chart based on info in file.");
Prints(" _o <file> [..]: Write parameters of current chart to file.");
Prints(" _o0 <file> [..]: Like _o but output planet/house positions.");
Prints(" _os <file>: Redirect output of text charts to file.");
Prints("\nSwitches which affect what information is used in a chart:");
Prints(" _R [<obj1> [<obj2> ..]]: Restrict specific bodies from displays.");
Prints(" _R0 [<obj1> ..]: Like _R but restrict everything first.");
Prints(" _R1 [<obj1> ..]: Like _R0 but unrestrict and show all objects.");
Prints(" _R[C,u,U]: Restrict all minor cusps, all uranians, or stars.");
Prints(" _RT[0,1,C,u,U] [..]: Restrict transiting planets in _t lists.");
Prints(" _C: Include non-angular house cusps in charts.");
Prints(" _u: Include transneptunian/uranian bodies in charts.");
Prints(" _U: Include locations of fixed background stars in charts.");
Prints(" _U[z,l,n,b]: Order by azimuth, altitude, name, or brightness.");
Prints(" _A <0-18>: Specify the number of aspects to use in charts.");
Prints(" _Ao <aspect> <orb>: Specify maximum orb for an aspect.");
Prints(" _Am <planet> <orb>: Specify maximum orb allowed to a planet.");
Prints(" _Ad <planet> <orb>: Specify orb addition given to a planet.");
Prints(" _Aa <aspect> <angle>: Change the actual angle of an aspect.");
Prints("\nSwitches which affect how a chart is computed:");
#ifdef PLACALC
Prints(" _b: Use ephemeris files for more accurate location computations.");
Prints(" _b0: Like _b but display locations to the nearest second too.");
#endif
Prints(" _c <value>: Select a different default system of houses.");
Prints(" (0 = Placidus, 1 = Koch, 2 = Equal, 3 = Campanus,");
Prints(" 4 = Meridian, 5 = Regiomontanus, 6 = Porphyry, 7 = Morinus,");
Prints(
" 8 = Topocentric, 9 = Equal (MC), 10 = Neo-Porphyry, 11 = None.)");
Prints(" _s [..]: Compute a sidereal instead of the normal tropical chart.");
Prints(" _s0: Display locations as right ascension instead of degrees.");
Prints(" _h [<objnum>]: Compute positions centered on specified object.");
Prints(" _p <month> <day> <year>: Cast 2ndary progressed chart for date.");
Prints(" _p0 <month> <day> <year>: Cast solar arc chart for date.");
#ifdef TIME
Prints(" _p[0]n: Cast progressed chart based on current date now.");
#endif
Prints(" _pd <days>: Set no. of days to progress / day (default 365.25).");
Prints(" _x <1-360>: Cast harmonic chart based on specified factor.");
Prints(" _1 [<objnum>]: Cast chart with specified object on Ascendant.");
Prints(" _2 [<objnum>]: Cast chart with specified object on Midheaven.");
Prints(" _3: Display objects in their zodiac decan positions.");
Prints(" _f: Display houses as sign positions (flip them).");
Prints(" _G: Compute houses based on geographic location only.");
Prints(" _F <objnum> <sign> <deg>: Force object's position to be value.");
Prints(" _+ [<days>]: Cast chart for specified no. of days in the future.");
Prints(" _- [<days>]: Cast chart for specified no. of days in the past.");
Prints(" _+[m,y] [<value>]: Cast chart for no. of months/years in future.");
Prints("\nSwitches for relationship and comparison charts:");
Prints(" _r <file1> <file2>: Compute a relationship synastry chart.");
Prints(" _rc <file1> <file2>: Compute a composite chart.");
Prints(" _rm <file1> <file2>: Compute a time space midpoint chart.");
Prints(" _r[c,m]0 <file1> <file2> <ratio1> <ratio2>: Weighted chart.");
Prints(" _rd <file1> <file2>: Print time span between files' dates.");
#ifdef BIORHYTHM
Prints(" _rb <file1> <file2>: Display biorhythm for file1 at time file2.");
#endif
Prints(" _r0 <file1> <file2>: Keep the charts separate in comparison.");
Prints(" _rp <file1> <file2>: Like _r0 but do file1 with progr. to file2.");
#ifdef TIME
Prints(" _y <file>: Display current house transits for particular chart.");
#ifdef BIORHYTHM
Prints(" _y[b,d,p] <file>: Print biorhythm/datediff for current time now.");
#endif
#endif /* TIME */
Prints("\nSwitches to access graphics options:");
Prints(" _k: Display text charts using Ansi characters and color.");
#ifdef MSG
Prints(" _V: <25,43,50>: Start up with text mode set to number of rows.");
#endif
/* If graphics features are compiled in, call an additional procedure to */
/* display the command switches offered dealing with the graphics stuff. */
#ifdef GRAPH
XDisplaySwitches();
#endif
}
/* 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. */
void PrintObjects(all)
int all;
{
int i, j;
real Off;
if (!(operation & DASHC))
for (i = C_LO; i <= C_HI; i++) /* Set up restrictions properly: Minor */
ignore[i] = TRUE; /* cusps and uranians included only if */
if (!(operation & DASHu)) /* -C and -u switches are in effect. */
for (i = U_LO; i <= U_HI; i++)
ignore[i] = TRUE;
fprintf(S, "%s planets and objects:\n", appname);
fprintf(S, "No. Name Rule Co-Rule Fall Co-Fall Exalt Debilitate\n\n");
for (i = 1; i <= BASE; i++) if (all || !ignore[i]) {
AnsiColor(objectansi[i]);
fprintf(S, "%2d %-12s", i, objectname[i]);
if (i <= OBJECTS) { /* Print rulerships, etc */
if (ruler1[i]) { /* for the planets. */
j = ruler2[i];
fprintf(S, "%c%c%c %c%c%c ", SIGNAM(ruler1[i]),
j ? signname[j][0] : ' ', j ? signname[j][1] : ' ',
j ? signname[j][2] : ' ');
fprintf(S, "%c%c%c %c%c%c ", SIGNAM(Mod12(ruler1[i]+6)),
j ? signname[Mod12(j+6)][0] : ' ',
j ? signname[Mod12(j+6)][1] : ' ',
j ? signname[Mod12(j+6)][2] : ' ');
fprintf(S, "%c%c%c %c%c%c", SIGNAM(exalt[i]),
SIGNAM(Mod12(exalt[i]+6)));
}
} else {
if (ruler1[i]) {
fprintf(S, "%c%c%c %c%c%c", SIGNAM(ruler1[i]),
SIGNAM(Mod12(ruler1[i]+6)));
fprintf(S, " %c%c%c %c%c%c", SIGNAM(exalt[i]),
SIGNAM(Mod12(exalt[i]+6)));
}
if (i <= C_HI)
fprintf(S, " Minor House Cusp #%d", i-OBJECTS);
else
fprintf(S, " Uranian #%d", i-U_LO+1);
}
printl();
}
/* Now, if -U in effect, read in and display stars in specified order. */
if (all || universe) {
Off = ProcessInput(TRUE);
ComputeStars(operation & DASHs ? 0.0 : -Off);
for (i = S_LO; i <= S_HI; i++) if (all | !ignore[i]) {
j = BASE+starname[i-BASE];
AnsiColor(objectansi[j]);
fprintf(S, "%2d %-12s", i, objectname[j]);
fprintf(S, "Star #%2d ", i-BASE);
PrintZodiac(planet[j]);
fprintf(S, " ");
PrintAltitude(planetalt[j]);
fprintf(S, " %5.2f\n", starbright[j-BASE]);
}
}
AnsiColor(DEFAULT);
}
/* 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). */
void PrintAspects()
{
int i;
fprintf(S, "%s aspects:\nNo. Name Abbrev. Angle Orb", appname);
fprintf(S, " Description of glyph\n\n");
for (i = 1; i <= ASPECTS; i++) {
AnsiColor(aspectansi[i]);
fprintf(S, "%2d %-15s(%s) %6.2f +/- %1.0f degrees - %s\n",
i, aspectname[i], aspectabbrev[i],
aspectangle[i], aspectorb[i], aspectglyph[i]);
}
AnsiColor(DEFAULT);
}
/* 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. */
void PrintSigns()
{
int i;
fprintf(S, "%s signs and houses:\n", appname);
fprintf(S, "Sign English name House Traditional name\n\n");
for (i = 1; i <= SIGNS; i++) {
AnsiColor(signansi(i));
fprintf(S, "%-12sthe %-14s%2d%s House of %s\n",
signname[i], signenglish[i], i, post[i], housetradition[i]);
}
AnsiColor(DEFAULT);
}
/*
******************************************************************************
** File IO Routines.
******************************************************************************
*/
/* Print an error message signifying that a particular option in the */
/* defaults file is invalid. This is a subprocedure of InputDefaults below. */
void BadDef(option)
char *option;
{
char string[STRING];
sprintf(string, "Bad default %s in %s.", option, DEFAULT_INFOFILE);
PrintError(string);
}
/* Read in a set of default program values used in the program, such as */
/* present location, time zone, the system of houses to use, the number */
/* of aspects and what orbs to use, and so on. These values are always */
/* read in at the beginning of program execution. */
/* The NEXTDEFAULT macro means to skip all comments in the file until we */
/* reach the beginning of the next set of data, delimited with a '=' sign. */
#define NEXTDEFAULT while(getc(data) != '=');
bool InputDefaults()
{
FILE *data;
char name[STRING];
int i, j;
filename = DEFAULT_INFOFILE;
data = OpenFile(filename, 0); /* First lets open the info file. */
if (data == NULL) /* If file not found anywhere, then forget */
return FALSE; /* it and use the compile time defaults. */
NEXTDEFAULT; fscanf(data, "%s", name);
if (StringCmp(name, VERSION) != 0) {
sprintf(name, "%s: Bad information in default parameter file '%s'.",
appname, filename);
PrintWarning(name);
PrintWarning(
"Delete this file or obtain one compatible with current version.");
Terminate(_ERROR);
return FALSE;
}
NEXTDEFAULT; fscanf(data, "%lf", &defzone); /* Time zone */
if (!IsValidZon(defzone))
BadDef("Time Zone");
NEXTDEFAULT; fscanf(data, "%lf", &deflong); /* Longitude */
if (!IsValidLon(deflong))
BadDef("Longitude");
NEXTDEFAULT; fscanf(data, "%lf", &deflat); /* Latitude */
if (!IsValidLat(deflat))
BadDef("Latitude");
NEXTDEFAULT; fscanf(data, "%d", &i); /* Zodiac system */
if (i)
operation |= DASHs;
NEXTDEFAULT; fscanf(data, "%lf", &addfactor); /* Zodiac offset */
if (!IsValidLon(addfactor))
BadDef("Add Factor");
NEXTDEFAULT; fscanf(data, "%d", &aspects); /* # of aspects */
if (!IsValidAspect(aspects))
BadDef("Aspect Number");
NEXTDEFAULT; fscanf(data, "%d", &housesystem); /* House system */
if (!IsValidSystem(housesystem))
BadDef("House System");
NEXTDEFAULT; fscanf(data, "%d", &ansi); /* Ansi text? */
NEXTDEFAULT; fscanf(data, "%d", &divisions); /* For -d and -T */
if (!IsValidDivision(divisions))
BadDef("Searching Divisions");
NEXTDEFAULT; fscanf(data, "%d", &placalc); /* Use ephemeris */
NEXTDEFAULT; fscanf(data, "%d", &seconds); /* Zodiac seconds */
seconds = seconds != 0;
NEXTDEFAULT; fscanf(data, "%d", &wheelrows); /* For -w charts */
if (!IsValidWheel(wheelrows))
BadDef("Wheel Rows");
NEXTDEFAULT; fscanf(data, "%d", &screenwidth); /* For -I charts */
if (!IsValidScreen(screenwidth))
BadDef("Screen Width");
NEXTDEFAULT; fscanf(data, "%d", &eurodate); /* D/M/Y vs. M/D/Y? */
NEXTDEFAULT; fscanf(data, "%d", &eurotime); /* 24hr vs. 12hr clock? */
NEXTDEFAULT; fscanf(data, "%d", &smartcusp); /* Logical -C displays? */
NEXTDEFAULT; fscanf(data, "%d", &column80); /* Clip text at col 80? */
NEXTDEFAULT;
for (i = 1; i <= BASE; i++) { /* Object restrictions */
fscanf(data, "%d", &j);
ignore[i] = j > 0;
}
NEXTDEFAULT;
for (i = 1; i <= BASE; i++) { /* Transit object restrictions */
fscanf(data, "%d", &j);
ignore2[i] = j > 0;
}
NEXTDEFAULT;
fscanf(data, "%d", &j); ignore[0] = j > 0; /* Restrict sign changes */
NEXTDEFAULT;
fscanf(data, "%d", &j); ignore2[0] = j > 0; /* Restrict dir. changes */
NEXTDEFAULT;
for (i = 1; i <= ASPECTS; i++) /* Orbs for aspects */
fscanf(data, "%lf", &aspectorb[i]);
NEXTDEFAULT;
for (i = 1; i <= BASE; i++) /* Orbs for planets */
fscanf(data, "%lf", &planetorb[i]);
NEXTDEFAULT;
for (i = 1; i <= BASE; i++) /* Extra planet orbs */
fscanf(data, "%lf", &planetadd[i]);
NEXTDEFAULT; fscanf(data, "%lf", &objectinf[BASE+1]); /* Rules sign */
NEXTDEFAULT; fscanf(data, "%lf", &objectinf[BASE+2]); /* Exalts in */
NEXTDEFAULT; fscanf(data, "%lf", &houseinf[SIGNS+1]); /* Rules house */
NEXTDEFAULT; fscanf(data, "%lf", &houseinf[SIGNS+2]); /* Exalts in */
NEXTDEFAULT;
for (i = 1; i <= BASE; i++)
fscanf(data, "%lf", &objectinf[i]); /* Influence of each object */
for (i = 1; i <= SIGNS; i++)
fscanf(data, "%lf", &houseinf[i]); /* Influence of each house */
for (i = 1; i <= ASPECTS; i++)
fscanf(data, "%lf", &aspectinf[i]); /* Influence of each aspect */
NEXTDEFAULT;
for (i = 1; i <= BASE; i++)
fscanf(data, "%lf", &transitinf[i]); /* Each object when transiting */
/* Graphics defaults begin here. These are only read in with certain */
/* compile options. They need to be read in last for file compatibility. */
#ifdef GRAPH
NEXTDEFAULT; fscanf(data, "%d", &chartx); /* Horizontal graph size */
if (!IsValidGraphx(chartx))
BadDef("Horizontal Bitmap Size");
NEXTDEFAULT; fscanf(data, "%d", &charty); /* Vertical graph size */
if (!IsValidGraphx(chartx))
BadDef("Vertical Bitmap Size");
/* Setting value to select alternate graphic glyphs for certain objects. */
NEXTDEFAULT; fscanf(data, "%d", &i);
if (i%10 == 1)
signdraw[_CAP] = "BH4RFR2ER3G3D2GDFR2EU2HL3G2DG";
if (i%100/10 == 1)
objectdraw[_URA] = "BD2D0BU6NG2NF2D4LGD2FR2EU2HL";
if (i%1000/100 == 1)
objectdraw[_PLU] = "BL3R5EU2HL5D8R5";
NEXTDEFAULT; fscanf(data, "%d", &gridobjects); /* Aspect grid cells */
if (!IsValidGrid(gridobjects))
BadDef("Aspect Grid Cells");
NEXTDEFAULT;
do {
bitmapmode = getc(data);
} while (bitmapmode <= ' ');
if (!IsValidBmpmode(bitmapmode)) /* Bitmap file mode */
BadDef("Bitmap File Mode");
NEXTDEFAULT; fscanf(data, "%d", &xfont); /* Font simulation flag */
NEXTDEFAULT; fscanf(data, "%d", &psinchz); /* PostScript orientation */
NEXTDEFAULT; fscanf(data, "%lf", &psinchx); /* PS horizon. paper size */
NEXTDEFAULT; fscanf(data, "%lf", &psinchy); /* PS vertical paper size */
#ifdef MSG
NEXTDEFAULT; fscanf(data, "%d", &hiresmode); /* Normal graphics mode */
if (!IsValidResmode(hiresmode))
BadDef("High Resolution Size");
NEXTDEFAULT; fscanf(data, "%d", &loresmode); /* Animation graphics mode */
if (!IsValidResmode(loresmode))
BadDef("Low Resolution Size");
#endif
#endif /* GRAPH */
fclose(data);
return TRUE;
}
/* 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. */
bool OutputData()
{
char string[STRING];
FILE *data;
int i, j;
real k;
data = fopen(filenameout, "w"); /* Create and open the file for output. */
if (data == NULL) {
sprintf(string, "File %s can not be created.", filenameout);
PrintError(string);
return FALSE;
}
if (!(operation & DASHo0)) {
/* Write the chart information to the file. */
if (Mon < 1) {
fclose(data);
PrintError("Can't output chart with no time/space to file.");
return FALSE;
}
fprintf(data, "%d\n%d\n%d\n%.2f\n%.2f\n%.2f\n%.2f\n",
Mon, Day, Yea, Tim, Zon, Lon, Lat);
} else {
/* However, if the -o0 switch is in effect, then write the actual */
/* positions of the planets and houses to the file instead. */
for (i = 1; i <= BASE; i++) {
j = (int) planet[i];
fprintf(data, "%c%c%c: %2d %2d %10.7f\n", OBJNAM(i),
j%30, j/30+1, FRACT(planet[i])*60.0); /* Position */
k = planetalt[i];
fprintf(data, "[%c]: %3d %12.8f\n", /* Altitude */
ret[i] >= 0.0 ? 'D' : 'R', (int)(Sgn(k)*
floor(dabs(k))), (k-(real)(int)k)*60.0); /* Retrograde? */
if (i == OBJECTS) {
if (operation & DASHu) /* Skip minor cusps to write uranians */
i = C_HI;
else
i = total;
}
}
for (i = 1; i <= SIGNS/2; i++) { /* Write first six cusp positions */
j = (int) house[i];
fprintf(data, "H_%c: %2d %2d %10.7f\n",
'a'+i-1, j%30, j/30+1, FRACT(house[i])*60.0);
}
}
/* Now write any extra strings that were on the command line after the -o */
/* specification but before the next switch, to the file as comments. */
for (i = 1; i < extracount; i++) {
extralines++;
fprintf(data, "%s\n", extralines[1]);
}
fclose(data);
return TRUE;
}
/*
******************************************************************************
** Program Dispatch Procedures.
******************************************************************************
*/
/* Initialize an Ansi color array with the color to print each object in. */
void InitColors()
{
int i;
objectansi[0] = elemansi[_EAR];
for (i = 1; i <= 10; i++)
objectansi[i] = signansi(ruler1[i]);
for (i = 11; i <= 15; i++)
objectansi[i] = MAGENTA;
for (i = 16; i <= 20; i++)
objectansi[i] = DKCYAN;
objectansi[_MC] = elemansi[_EAR]; objectansi[_ASC] = elemansi[_FIR];
objectansi[21] = elemansi[_AIR]; objectansi[22] = elemansi[_WAT];
objectansi[23] = elemansi[_EAR]; objectansi[24] = elemansi[_AIR];
for (i = U_LO; i <= U_HI; i++)
objectansi[i] = PURPLE;
for (i = S_LO; i <= S_HI; i++)
objectansi[i] = starbright[i-BASE] < 1.0 ? ORANGE : MAROON;
}
/* 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. */
int PrintTables()
{
if (andisplay < 2)
return FALSE;
if (andisplay & DASHHc) {
DisplayCredits();
if (andisplay - (andisplay & DASHHc*2-1))
printl2();
}
if (andisplay & DASHH) {
DisplaySwitches();
if (andisplay - (andisplay & DASHH*2-1))
printl2();
}
if (andisplay & DASHH0) {
PrintSigns();
if (andisplay - (andisplay & DASHH0*2-1))
printl2();
}
if (andisplay & DASHO) {
PrintObjects((andisplay & DASHO0) > 0);
if (andisplay - (andisplay & DASHO*2-1))
printl2();
}
if (andisplay & DASHA) {
PrintAspects();
if (andisplay - (andisplay & DASHA*2-1))
printl2();
}
#ifdef INTERPRET
if (andisplay & DASHI0) {
InterpretGeneral();
InterpretAspectGeneral();
}
#endif
/* If we also already have enough information to generate a chart, */
/* then go on and do so, else exit. (So things like "-O -i file" will */
/* work, but things like just "-H" will print and exit right away.) */
if (autom)
printl2();
return !autom;
}
/* 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. */
void Action()
{
char string[STRING];
int i;
AnsiColor(DEFAULT);
InitColors();
/* First let's adjust the restriction status of the minor cusps, uranians, */
/* and fixed stars based on whether -C, -u, and -U switches are in effect. */
if (!(operation & DASHC))
for (i = C_LO; i <= C_HI; i++)
ignore[i] = ignore2[i] = TRUE;
if (!(operation & DASHu))
for (i = U_LO; i <= U_HI; i++)
ignore[i] = ignore2[i] = TRUE;
if (!universe)
for (i = S_LO; i <= S_HI; i++)
ignore[i] = ignore2[i] = TRUE;
/* If the -os switch is in effect, open a file and set a global to */
/* internally 'redirect' all screen output to. */
if (filenamescreen) {
S = fopen(filenamescreen, "w");
if (S == NULL) {
sprintf(string, "File %s can not be created.", filenamescreen);
PrintError(string);
S = stdout;
}
} else
S = stdout;
if (PrintTables()) /* Print out any generic tables specified. */
return; /* If nothing else to do, we can exit right away. */
/* If -+ or -- switches in effect, then add the specified delta value to */
/* the date and use that as a new date before proceeding to make chart. */
if (Delta != 0) {
JD = (real)MdyToJulian(MM, DD+Delta, YY);
JulianToMdy(JD, &MM, &DD, &YY);
}
/* Here we either do a normal chart or some kind of relationship chart. */
if (!relation) {
if (!autom && !InputData("tty")) /* If chart info not in mem yet, then */
return; /* prompt the user for the time, etc. */
SetMain(MM, DD, YY, TT, ZZ, OO, AA);
CastChart(TRUE);
} else
CastRelation(TRUE);
SetSave(Mon, Day, Yea, Tim, Zon, Lon, Lat);
#ifdef GRAPH
if (operation & DASHX) /* If any of the X window switches in effect, */
XAction(); /* then go make a graphics chart... */
else
#endif
PrintChart(prog); /* Otherwise print chart on text screen. */
if (operation & DASHo) /* If -o switch in effect, then write */
OutputData(); /* the chart information to a file. */
if (S != stdout) /* If we were internally directing chart display to a */
fclose(S); /* file as with the -os switch, close it here. */
}
/* 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. */
void InitVariables()
{
filenamescreen = NULL;
relation = Delta = 0;
todisplay = exdisplay = andisplay = operation = 0x0;
interpret = progress = autom = FALSE;
}
/* This routine is called by the main program to actually prompt the user */
/* for command switches and parameters, entered in the same format as they */
/* would be on a Unix command line. This is only executed for certain non- */
/* Unix 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 passed back to the */
/* main program which then processes it just like in a Unix system. */
#define MAXSWITCHES 32
int InputSwitches(line, argv)
char *line, *argv[MAXSWITCHES];
{
FILE *data;
int argc = 1, i = 0, j = 1;
char *c = line;
data = S; S = stdout;
AnsiColor(WHITE);
fprintf(S, "** %s version %s ", appname, VERSION);
fprintf(S, "(See '%cHc' switch for copyrights and credits.) **\n", DASH);
AnsiColor(DEFAULT);
fprintf(S, "Enter all parameter options below. ");
fprintf(S, "(Enter '%cH' for help. Enter '.' to exit.)\n", DASH);
S = data;
InputString("Input command line", line);
argv[0] = APPNAME;
/* Split the entered line up into its individual switch strings. */
while (*c) {
if (*c == ' ') {
if (j)
; /* Skip over the current run of spaces between strings. */
else {
*c = 0; /* First space after a string, end it here. */
j = TRUE;
}
} else {
if (j) {
argv[argc++] = c; /* First char after spaces, begin it here. */
j = FALSE;
} else
; /* Skip over the current string. */
}
c++;
}
argv[argc] = NULL; /* Set last string in switch array to Null. */
printl();
return argc;
}
/*
******************************************************************************
** Main Program.
******************************************************************************
*/
/* Process a command line switch passed to the program. Read each entry in */
/* the argument list and set all the program modes and charts to display. */
bool ProcessSwitches(argc, argv)
int argc;
char **argv;
{
int pos, i, j;
real k;
char string[STRING], cpos, *c;
argc--; argv++;
while (argc) {
pos = 1 + (argv[0][0] == '-' || argv[0][0] == '/'); /* Leading dash? */
cpos = argv[0][pos];
switch (argv[0][pos-1]) {
case 'H':
if (cpos == 'c')
andisplay ^= DASHHc;
else if (cpos == '0')
andisplay ^= DASHH0;
else
andisplay ^= DASHH;
break;
case 'O':
if (cpos == '0')
andisplay ^= DASHO0;
andisplay ^= DASHO;
break;
case 'Q':
if (cpos == '0')
operation ^= DASHQ0;
operation ^= DASHQ;
break;
/* Switches which determine the type of chart to display: */
case 'v':
if (cpos == '0')
exdisplay ^= DASHv0;
todisplay ^= DASHv;
break;
case 'w':
if (cpos == '0')
exdisplay ^= DASHw0;
if (argc > 1 && (i = atoi(argv[1]))) {
argc--; argv++;
if (!IsValidWheel(i)) {
BadVal("w", i);
return FALSE;
}
wheelrows = i;
}
todisplay ^= DASHw;
break;
case 'g':
if (cpos == '0')
exdisplay ^= DASHg0;
else if (cpos == 'a') {
exdisplay ^= DASHga;
if (argv[0][pos+1] == '0')
exdisplay ^= DASHg0;
}
#ifdef X11
else if (cpos == 'e') {
if (argc <= 1) {
TooFew("geometry");
return FALSE;
}
chartx = atoi(argv[1]);
if (argc > 2 && (charty = atoi(argv[2]))) {
argc--; argv++;
} else
charty = chartx;
if (!IsValidGraphx(chartx)) {
BadVal("geometry", chartx);
return FALSE;
}
if (!IsValidGraphy(charty)) {
BadVal("geometry", charty);
return FALSE;
}
argc--; argv++;
break;
}
#endif
todisplay ^= DASHg;
break;
case 'm':
if (cpos == '0') {
exdisplay ^= DASHm0;
if (argv[0][pos+1] == 'a')
exdisplay ^= DASHga;
} else if (cpos == 'a')
exdisplay ^= DASHm0 | DASHga;
todisplay ^= DASHm;
break;
case 'Z':
if (cpos == '0')
exdisplay ^= DASHZ0;
else if (cpos == 'd')
exdisplay ^= DASHZd;
todisplay ^= DASHZ;
break;
case 'S':
todisplay ^= DASHS;
break;
case 'j':
if (cpos == '0')
exdisplay ^= DASHj0;
todisplay ^= DASHj;
break;
case 'L':
if (cpos == '0')
exdisplay ^= DASHL0;
if (argc > 1 && (i = atoi(argv[1]))) {
argc--; argv++;
if (i < 1 || 160%i > 0) {
BadVal("L", i);
return FALSE;
}
graphstep = i;
}
todisplay ^= DASHL;
break;
case 'K':
if (cpos == 'y')
exdisplay ^= DASHKy;
todisplay ^= DASHK;
break;
case 'd':
if (cpos == 'p') {
i = (argv[0][pos+1] == 'y');
j = (argv[0][pos+i+1] == 'n');
if (!j && argc <= 2-i) {
TooFew("dp");
return FALSE;
}
prog = TRUE;
exdisplay |= DASHdm;
Zon2 = defzone; Lon2 = deflong; Lat2 = deflat;
if (j)
GetTimeNow(&Mon2, &Day2, &Yea2, &Tim2, Zon2);
if (i) {
Mon2 = 0;
if (!j)
Yea2 = atoi(argv[1]);
} else {
if (!j) {
Mon2 = atoi(argv[1]);
Yea2 = atoi(argv[2]);
if (!IsValidMon(Mon2)) {
BadVal("dp", Mon2);
return FALSE;
}
}
}
if (!IsValidYea(Yea2)) {
BadVal("dp", Yea2);
return FALSE;
}
if (!j) {
argc -= 2-i; argv += 2-i;
}
} else if (cpos == 'm' || cpos == 'y') {
Mon2 = (cpos == 'm');
exdisplay ^= DASHdm;
}
#ifdef X11
else if (cpos == 'i') { /* -display switch for X */
if (argc <= 1) {
TooFew("display");
return FALSE;
}
dispname = argv[1];
argc--; argv++;
break;
}
#endif
else if (argc > 1 && (i = atoi(argv[1]))) {
if (!IsValidDivision(i)) {
BadVal("d", i);
return FALSE;
}
divisions = i;
argc--; argv++;
}
todisplay ^= DASHd;
break;
case 'D':
todisplay ^= DASHD;
break;
case 'E':
if (cpos == 'y')
exdisplay ^= DASHEy;
todisplay ^= DASHE;
break;
case 'e':
todisplay ^= DASHe;
exdisplay ^= DASHg0 | DASHj0 | DASHL0;
break;
case 't':
todisplay ^= DASHt;
Zon2 = defzone; Lon2 = deflong; Lat2 = deflat;
if (cpos == 'p') {
prog = TRUE;
cpos = argv[0][++pos];
}
if (i = (cpos == 'y') + 2*(cpos == 'Y'))
cpos = argv[0][++pos];
#ifdef TIME
if (cpos == 'n') {
GetTimeNow(&Mon2, &Day2, &Yea2, &Tim2, Zon2);
if (i == 1)
Mon2 = 0;
else if (i > 1) {
Mon2 = -1; Day2 = atoi(argv[1]);
}
break;
}
#endif
if (argc <= 2 - (i & 1)) {
TooFew("t");
return FALSE;
}
if (i) {
if (i == 1)
Mon2 = 0;
else {
Mon2 = -1; Day2 = atoi(argv[2]);
}
} else {
Mon2 = atoi(argv[1]);
if (!IsValidMon(Mon2)) {
BadVal("t", Mon2);
return FALSE;
}
}
Yea2 = atoi(argv[2 - (i > 0)]);
argc -= 2 - (i & 1); argv += 2 - (i & 1);
break;
case 'T':
todisplay ^= DASHT;
Zon2 = defzone; Lon2 = deflong; Lat2 = deflat;
if (cpos == 'p') {
prog = TRUE;
cpos = argv[0][++pos];
}
#ifdef TIME
if (cpos == 'n') {
GetTimeNow(&Mon2, &Day2, &Yea2, &Tim2, Zon2);
break;
}
#endif
if (argc <= 3) {
TooFew("T");
return FALSE;
}
Mon2 = atoi(argv[1]);
Day2 = atoi(argv[2]);
Yea2 = atoi(argv[3]);
if (!IsValidMon(Mon2)) {
BadVal("T", Mon2);
return FALSE;
} else if (!IsValidDay(Day2, Mon2, Yea2)) {
BadVal("T", Day2);
return FALSE;
} else if (!IsValidYea(Yea2)) {
BadVal("T", Yea2);
return FALSE;
}
argc -= 3; argv += 3;
break;
#ifdef INTERPRET
case 'I':
if (argc > 1 && (i = atoi(argv[1]))) {
argc--; argv++;
if (!IsValidScreen(i)) {
BadVal("I", i);
return FALSE;
}
screenwidth = i;
}
if (cpos == '0') {
andisplay ^= DASHI0;
break;
}
interpret = !interpret;
break;
#endif
/* Switches which affect how the chart parameters are obtained: */
#ifdef TIME
case 'n':
InputData("now");
if (cpos == 'd')
TT = 0.0;
else if (cpos == 'm') {
DD = 1; TT = 0.0;
} else if (cpos == 'y') {
MM = DD = 1; TT = 0.0;
}
break;
#endif
case 'z':
if (argc <= 1 || (atoi(argv[1]) == 0 && argv[1][0] != '0'))
defzone -= 1.0;
else {
defzone = atof(argv[1]);
if (!IsValidZon(defzone)) {
BadVal2("z", defzone);
return FALSE;
}
argc--; argv++;
}
break;
case 'l':
if (argc <= 2) {
TooFew("l");
return FALSE;
}
deflong = atof(argv[1]);
deflat = atof(argv[2]);
if (!IsValidLon(deflong)) {
BadVal2("l", deflong);
return FALSE;
} else if (!IsValidLat(deflat)) {
BadVal2("l", deflat);
return FALSE;
}
argc -= 2; argv += 2;
break;
case 'q':
i = (cpos == 'y' || cpos == 'j') + 2*(cpos == 'm') + 3*(cpos == 'd') +
4*(cpos == '\0') + 7*(cpos == 'a');
if (argc <= i) {
TooFew("q");
return FALSE;
}
autom = TRUE;
if (cpos == 'j') {
JD = atof(argv[1])+ROUND;
TT = FRACT(JD);
JulianToMdy(JD-TT, &MM, &DD, &YY);
TT = DegToDec(TT * 24.0);
ZZ = 0.0; OO = deflong; AA = deflat;
} else {
MM = i > 1 ? atoi(argv[1]) : 1;
DD = i > 2 ? atoi(argv[2]) : 1;
YY = atoi(argv[3-(i<3)-(i<2)]);
TT = i > 3 ? atof(argv[4]) : (i < 3 ? 0.0 : 12.0);
ZZ = i > 6 ? atof(argv[5]) : defzone;
OO = i > 6 ? atof(argv[6]) : deflong;
AA = i > 6 ? atof(argv[7]) : deflat;
if (!IsValidMon(MM)) {
BadVal("q", MM);
return FALSE;
} else if (!IsValidDay(DD, MM, YY)) {
BadVal("q", DD);
return FALSE;
} else if (!IsValidYea(YY)) {
BadVal("q", YY);
return FALSE;
} else if (!IsValidTim(TT)) {
BadVal2("q", TT);
return FALSE;
} else if (!IsValidZon(ZZ)) {
BadVal2("a", ZZ);
return FALSE;
} else if (!IsValidLon(OO)) {
BadVal2("a", OO);
return FALSE;
} else if (!IsValidLat(AA)) {
BadVal2("a", AA);
return FALSE;
}
}
argc -= i; argv += i;
break;
case 'i':
if (argc <= 1) {
TooFew("i");
return FALSE;
}
if (!InputData(argv[1]))
return FALSE;
argc--; argv++;
break;
case 'o':
if (argc <= 1) {
TooFew("o");
return FALSE;
}
if (cpos == 's') {
filenamescreen = argv[1];
argc--; argv++;
break;
} else if (cpos == '0')
operation ^= DASHo0;
operation ^= DASHo;
filenameout = argv[1];
extralines = argv;
do {
argc--; argv++;
extracount++;
} while (argc > 1 && argv[1][0] != '-' && argv[1][0] != '/');
break;
/* Switches which affect what information is used in a chart: */
case 'R':
if (cpos == 'T') {
c = (char *)ignore2;
cpos = argv[0][++pos];
} else
c = (char *)ignore;
if (cpos == '0')
for (i = 0; i <= total; i++)
c[i] = TRUE;
else if (cpos == '1') {
for (i = 0; i <= total; i++)
c[i] = FALSE;
operation |= DASHC | DASHu;
universe = TRUE;
} else if (cpos == 'C')
for (i = C_LO; i <= C_HI; i++)
c[i] = !c[i];
else if (cpos == 'u')
for (i = U_LO; i <= U_HI; i++)
c[i] = !c[i];
else if (cpos == 'U')
for (i = S_LO; i <= S_HI; i++)
c[i] = !c[i];
else if (argc <= 1 || (!atoi(argv[1]))) {
for (i = 11; i <= 15; i++)
c[i] = !c[i];
c[_FOR] = !c[_FOR]; c[_VTX] = !c[_VTX];
}
while (argc > 1 && (i = atoi(argv[1])))
if (!IsItem(i)) {
BadVal("R", i);
return FALSE;
} else {
c[i] = !c[i];
argc--; argv++;
}
break;
case 'C':
operation ^= DASHC;
break;
case 'u':
operation ^= DASHu;
break;
case 'U':
if (cpos == 'n' || cpos == 'b' || cpos == 'z' || cpos == 'l')
universe = cpos;
else
universe = !universe;
break;
case 'A':
if (argc <= 1 || atoi(argv[1]) == 0) {
andisplay ^= DASHA;
break;
}
if (cpos != 'o' && cpos != 'm' && cpos != 'd' && cpos != 'a') {
i = atoi(argv[1]);
if (!IsValidAspect(i)) {
BadVal("A", i);
return FALSE;
}
aspects = i;
argc--; argv++;
} else {
if (argc <= 2) {
TooFew("A");
return FALSE;
}
i = atoi(argv[1]);
if (i < 1 || i > (cpos == 'o' || cpos == 'a' ? ASPECTS : BASE)) {
BadVal("A", i);
return FALSE;
}
k = atof(argv[2]);
if (k < -DEGREES || k > DEGREES) {
BadVal2("A", k);
return FALSE;
}
if (cpos == 'o')
aspectorb[i] = k;
else if (cpos == 'm')
planetorb[i] = k;
else if (cpos == 'd')
planetadd[i] = k;
else
aspectangle[i] = k;
argc -= 2; argv += 2;
}
break;
/* Switches which affect how a chart is computed: */
case 'b':
if (cpos == '0')
seconds = !seconds;
placalc = !placalc;
break;
case 'c':
if (argc <= 1) {
TooFew("c");
return FALSE;
}
i = atoi(argv[1]);
if (!IsValidSystem(i)) {
BadVal("c", i);
return FALSE;
}
housesystem = i;
argc--; argv++;
break;
case 's':
if (argc > 1 && (k = atof(argv[1])) != 0.0) {
argc--; argv++;
addfactor = k;
}
if (cpos != '0')
operation ^= DASHs;
else
operation ^= DASHs0;
break;
case 'h':
if (argc > 1 && (i = atoi(argv[1]))) {
argc--; argv++;
} else
i = 1;
if (i < 0 || i == _MOO || !IsObject(i) || i > U_HI) {
BadVal("h", i);
return FALSE;
}
centerplanet = i;
c = objectname[0];
objectname[0] = objectname[centerplanet];
objectname[centerplanet] = c;
if (centerplanet < _MOO)
centerplanet = 1-centerplanet;
break;
case 'p':
if (cpos == '0') {
operation |= DASHp0;
cpos = (argv[0][++pos]);
}
progress = TRUE;
#ifdef TIME
if (cpos == 'n') {
GetTimeNow(&Mon, &Day, &Yea, &Tim, defzone);
Jdp = (real)MdyToJulian(Mon, Day, Yea) + Tim / 24.0;
break;
}
#endif
if (cpos == 'd') {
if (argc <= 1) {
TooFew("pd");
return FALSE;
}
progday = atof(argv[1]);
if (progday == 0.0) {
BadVal2("pd", progday);
return FALSE;
}
argc--; argv++;
break;
}
if (argc <= 3) {
TooFew("p");
return FALSE;
}
Mon = atoi(argv[1]);
Day = atoi(argv[2]);
Yea = atoi(argv[3]);
if (!IsValidMon(Mon)) {
BadVal("p", Mon);
return FALSE;
} else if (!IsValidDay(Day, Mon, Yea)) {
BadVal("p", Day);
return FALSE;
} else if (!IsValidYea(Yea)) {
BadVal("p", Yea);
return FALSE;
}
Jdp = (real)MdyToJulian(Mon, Day, Yea) + defzone / 24.0;
argc -= 3; argv += 3;
break;
case 'x':
if (argc <= 1) {
TooFew("x");
return FALSE;
}
i = atoi(argv[1]);
if (i < 1 || i > DEGREES) {
BadVal("x", i);
return FALSE;
}
multiplyfactor = i;
argc--; argv++;
break;
case '1':
if (argc > 1 && (i = atoi(argv[1]))) {
argc--; argv++;
} else
i = _SUN;
if (!IsItem(i)) {
BadVal("1", i);
return FALSE;
}
onasc = i;
break;
case '2':
if (argc > 1 && (i = atoi(argv[1]))) {
argc--; argv++;
} else
i = _SUN;
if (!IsItem(i)) {
BadVal("2", i);
return FALSE;
}
onasc = -i;
break;
case '3':
operation ^= DASH3;
break;
case 'f':
operation ^= DASHf;
break;
case 'G':
operation ^= DASHG;
break;
case 'F':
if (argc <= 3) {
TooFew("F");
return FALSE;
}
i = atoi(argv[1]);
if (!IsItem(i)) {
BadVal("F", i);
return FALSE;
}
force[i] = (atof(argv[2])-1.0)*30.0+DecToDeg(atof(argv[3]));
if (force[i] < 0.0 || force[i] >= DEGREES) {
BadVal2("F", force[i]);
return FALSE;
} else
force[i] += DEGREES;
argc -= 3; argv += 3;
break;
case '+':
if (argc > 1 && (i = atoi(argv[1])) != 0) {
argc--; argv++;
} else
i = 1;
Delta += i * (cpos == 'y' ? 365 : (cpos == 'm' ? 30 : 1));
break;
case '-': case '\0':
if (argc > 1 && (i = atoi(argv[1])) != 0) {
argc--; argv++;
} else
i = 1;
Delta -= i * (cpos == 'y' ? 365 : (cpos == 'm' ? 30 : 1));
break;
/* Switches for relationship and comparison charts: */
case 'r':
i = 2 + 2*(cpos >= 'a' && argv[0][pos+1] == '0');
if (argc <= i) {
TooFew("r");
return FALSE;
}
if (cpos == 'c')
relation = DASHrc;
else if (cpos == 'm')
relation = DASHrm;
else if (cpos == 'd')
relation = DASHrd;
#ifdef BIORHYTHM
else if (cpos == 'b')
relation = DASHrb;
#endif
else if (cpos == '0')
relation = DASHr0;
else if (cpos == 'p')
relation = DASHrp;
else
relation = DASHr;
filename = argv[1]; filename2 = argv[2];
if (i > 2) {
ratio1 = atoi(argv[3]);
ratio2 = atoi(argv[4]);
if (ratio1 == ratio2)
ratio1 = ratio2 = 1;
}
argc -= i; argv += i;
break;
#ifdef TIME
case 'y':
if (argc <= 1) {
TooFew("y");
return FALSE;
}
if (cpos == 'd')
relation = DASHrd;
#ifdef BIORHYTHM
else if (cpos == 'b')
relation = DASHrb;
#endif
else if (cpos == 'p')
relation = DASHrp;
else
relation = DASHr0;
filename = argv[1]; filename2 = "now";
argc--; argv++;
break;
#endif
/* Switches to access graphics options: */
case 'k':
ansi = !ansi;
break;
#ifdef MSG
case 'V':
if (argc <= 1) {
TooFew("V");
return FALSE;
}
i = atoi(argv[1]);
if (!IsValidTextrows(i)) {
BadVal("V", i);
return FALSE;
}
textrows = i;
argc--; argv++;
break;
#endif
#ifdef GRAPH
case 'X':
i = XProcessSwitches(argc, argv, pos);
if (i < 0)
return FALSE;
operation |= DASHX;
argc -= i; argv += i;
break;
#endif
case '.': /* "-." is usually used to exit the -Q loop. */
Terminate(_FORCE);
case 'B': /* For no useful reason, -B will sound a beep. */
printc(BELL);
break;
default:
sprintf(string, "Unknown switch '%s'.", argv[0]);
PrintError(string);
return FALSE;
}
argc--; argv++;
}
return TRUE;
}
#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. */
#ifdef SWITCHES
void main(argc, argv)
int argc;
char **argv;
{
#else
void main()
{
int argc;
char **argv;
#endif
char commandline[256];
char *pointers[MAXSWITCHES];
InputDefaults(); /* Read in info from the astrolog.dat file. */
Begin:
#ifdef MSG
if (textrows > 0) {
_settextrows(textrows);
textrows = -textrows;
}
#endif
if (noswitches) { /* Go prompt for */
argc = InputSwitches(commandline, pointers); /* switches if we */
argv = pointers; /* don't have them. */
}
progname = argv[0];
if (ProcessSwitches(argc, argv)) {
if (!noswitches && (operation & DASHQ0)) {
noswitches = TRUE;
goto Begin;
}
#ifdef MSG
if (textrows > 0) {
_settextrows(textrows);
textrows = -textrows;
}
#endif
Action();
}
if (operation & DASHQ) { /* If -Q in effect, loop back and get switch */
printl2(); /* information for another chart to display. */
InitVariables();
operation |= DASHQ;
noswitches = TRUE;
goto Begin;
}
Terminate(_OK); /* The only standard place to exit Astrolog is here. */
}
#endif /* NOMAIN */
/* driver.c */