This is driver.c in view mode; [Download] [Up]
/* ** 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 */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.