home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Astrolog (Version 4.00) File: general.c
- **
- ** IMPORTANT NOTICE: the graphics database and chart display routines
- ** used in this program are Copyright (C) 1991-1993 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 12/31/1993.
- */
-
- #include "astrolog.h"
-
-
- /*
- ******************************************************************************
- ** General Functions.
- ******************************************************************************
- */
-
- /* Swap two real floating point values. */
-
- void SwapReal(d1, d2)
- real *d1, *d2;
- {
- real temp;
-
- temp = *d1; *d1 = *d2; *d2 = temp;
- }
-
-
- /* Return the length of a string. */
-
- int StringLen(line)
- char *line;
- {
- int i;
-
- for (i = 0; *line++; i++)
- ;
- return i;
- }
-
-
- /* Return whether one string is greater than another. */
-
- int StringCmp(s1, s2)
- char *s1, *s2;
- {
- while (*s1 && *s1 == *s2)
- s1++, s2++;
- return *s1 - *s2;
- }
-
-
- /* Determine the sign of a number: -1 if value negative, +1 if value */
- /* positive, and 0 if it's zero. */
-
- real Sgn(d)
- real d;
- {
- return d == 0.0 ? 0.0 : SGN2(d);
- }
-
-
- /* Given an x and y coordinate, return the angle formed by a line from the */
- /* origin to this coordinate. This is just converting from rectangular to */
- /* polar coordinates; however, we don't determine the radius here. */
-
- real Angle(x, y)
- real x, y;
- {
- real a;
-
- if (x != 0.0)
- a = ATAN(y/x);
- else
- a = Sgn(y)*PI/2.0;
- if (a < 0.0)
- a += PI;
- if (y < 0.0)
- a += PI;
- return a;
- }
-
-
- /* Modulus function for floating point values. The modulus value itself */
- /* has been specified earlier: it is usually either 360.0 or PI/2.0. */
-
- real Mod(d)
- real d;
- {
- if (d > modulus) /* In most cases, our value is only slightly */
- d -= modulus; /* out of range, so we can test for it and */
- else if (d < modulus) /* avoid the more complicated arithmetic. */
- d += modulus;
- if (d >= 0 && d < modulus)
- return d;
- return (d - floor(d/modulus)*modulus);
- }
-
-
- /*
- ******************************************************************************
- ** General Astrology Functions.
- ******************************************************************************
- */
-
- /* A similar modulus function: convert an integer to value from 1..12. */
-
- int Mod12(i)
- int i;
- {
- while (i > SIGNS)
- i -= SIGNS;
- while (i < 1)
- i += SIGNS;
- return i;
- }
-
-
- /* Convert an inputed fractional degrees/minutes value to a true decimal */
- /* degree quantity. For example, the user enters the decimal value "10.30" */
- /* to mean 10 degrees and 30 minutes; this will return 10.5, i.e. 10 */
- /* degrees and 30 minutes expressed as a floating point degree value. */
-
- real DecToDeg(d)
- real d;
- {
- return Sgn(d)*(floor(dabs(d))+FRACT(dabs(d))*100.0/60.0);
- }
-
-
- /* This is the inverse of the above function. Given a true decimal value */
- /* for a zodiac degree, adjust it so the degrees are in the integer part */
- /* and the minute expressed as hundredths, e.g. 10.5 degrees -> 10.30 */
-
- real DegToDec(d)
- real d;
- {
- return Sgn(d)*(floor(dabs(d))+FRACT(dabs(d))*60.0/100.0);
- }
-
-
- /* Return the shortest distance between two degrees in the zodiac. This is */
- /* normally their difference, but we have to check if near the Aries point. */
-
- real MinDistance(deg1, deg2)
- real deg1, deg2;
- {
- real i;
-
- i = dabs(deg1-deg2);
- return i < DEGHALF ? i : DEGREES - i;
- }
-
-
- /* This is just like the above routine, except the min distance value */
- /* returned will either be positive or negative based on whether the */
- /* second value is ahead or behind the first one in a circular zodiac. */
-
- real MinDifference(deg1, deg2)
- real deg1, deg2;
- {
- real i;
-
- i = deg2 - deg1;
- if (dabs(i) < DEGHALF)
- return i;
- return Sgn(i)*(dabs(i) - DEGREES);
- }
-
-
- /* Return the degree of the midpoint between two zodiac positions, making */
- /* sure we return the true midpoint closest to the positions in question. */
-
- real Midpoint(deg1, deg2)
- real deg1, deg2;
- {
- real mid;
-
- mid = (deg1+deg2)/2.0;
- return MinDistance(deg1, mid) < DEGQUAD ? mid : Mod(mid+DEGHALF);
- }
-
-
- /* Given a planet and sign, determine whether: The planet rules the sign, */
- /* the planet has its fall in the sign, the planet exalts in the sign, or */
- /* is debilitated in the sign; and return an appropriate character. */
-
- char Dignify(body, sign)
- int body, sign;
- {
- if (body > U_HI)
- return ' ';
- if (ruler1[body] == sign || ruler2[body] == sign)
- return 'R';
- if (ruler1[body] == Mod12(sign+6) || ruler2[body] == Mod12(sign+6))
- return 'F';
- if (exalt[body] == sign)
- return 'e';
- if (exalt[body] == Mod12(sign+6))
- return 'd';
- return '-';
- }
-
-
- /* Determine the number of days in a particular month. The year is needed, */
- /* too, because we have to check for leap years in the case of February. */
-
- int DayInMonth(month, year)
- int month, year;
- {
- return (month == 9 || month == 4 || month == 6 || month == 11 ? 30 :
- (month != 2 ? 31 : 28 +
- (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))));
- }
-
-
- /* Given an aspect and two objects making that aspect with each other, */
- /* return the maximum orb allowed for such an aspect. Normally this only */
- /* depends on the aspect itself, but some objects require narrow orbs, */
- /* and some allow wider orbs, so check for these cases. */
-
- real Orb(body1, body2, aspect)
- int body1, body2, aspect;
- {
- real orb, i;
-
- orb = aspectorb[aspect];
- i = body1 > BASE ? 2.0 : planetorb[body1];
- orb = MIN(orb, i);
- i = body2 > BASE ? 2.0 : planetorb[body2];
- orb = MIN(orb, i);
- if (body1 <= BASE)
- orb += planetadd[body1];
- if (body2 <= BASE)
- orb += planetadd[body2];
- return orb;
- }
-
-
- /*
- ******************************************************************************
- ** File IO Routines.
- ******************************************************************************
- */
-
- /* Exit the program, and do any cleanup necessary. Note that if we had */
- /* a non-fatal error, and we are in the -Q loop mode, then we won't */
- /* actually terminate the program, but drop back to the command line loop. */
-
- void Terminate(value)
- int value;
- {
- if (value == _FORCE) {
- AnsiColor(WHITE);
- fprintf(stdout, "\n%s terminated.\n", appname);
- }
- if (value == _ERROR && (operation & DASHQ) > 0)
- return;
- if (ansi)
- fprintf(S, "%c[0m", ESCAPE); /* Get out of any Ansi color mode. */
- exit(abs(value));
- }
-
-
- /* Print a warning message given a string. This is called in non-fatal */
- /* cases where we return to normal execution after printing the string. */
-
- void PrintWarning(string)
- char *string;
- {
- AnsiColor(RED);
- fprintf(stderr, "%s\n", string);
- AnsiColor(DEFAULT);
- }
-
-
- /* Print an error message. This is called in more serious cases which halt */
- /* running of the current chart sequence, which can terminate the program */
- /* but isn't a fatal error in that we can still fall back to the -Q loop. */
-
- void PrintError(string)
- char *string;
- {
- AnsiColor(RED);
- fprintf(stderr, "%s: %s\n", appname, string);
- Terminate(_ERROR);
- AnsiColor(DEFAULT);
- }
-
-
- /* Simplification for a commonly printed error message. */
-
- void TooFew(option)
- char *option;
- {
- char string[STRING];
-
- sprintf(string, "Too few options to switch -%s", option);
- PrintError(string);
- }
-
-
- /* Another simplification for a commonly printed error message. */
-
- void BadVal(option, value)
- char *option;
- int value;
- {
- char string[STRING];
-
- sprintf(string, "Value %d passed to switch -%s out of range.\n",
- value, option);
- PrintError(string);
- }
-
-
- /* A simple procedure used throughout Astrolog: Print a particular */
- /* character on the screen 'n' times. */
-
- void PrintTab(chr, count)
- char chr;
- int count;
- {
- int i;
-
- for (i = 0; i < count; i++)
- printc(chr);
- }
-
-
- /* Set an Ansi text color. */
-
- void AnsiColor(col)
- int col;
- {
- /* Special case: If we are passed the value REVERSE, and ansi is not */
- /* only on but set to a value > 1, then we'll enter reverse video mode. */
-
- if (!ansi || (col == REVERSE && ansi < 2))
- return;
- fprintf(S, "%c[", ESCAPE);
- if (col == DEFAULT)
- printc('0');
- else if (col == REVERSE) {
- printc('7');
- } else
- fprintf(S, "%c;%d", col > 7 ? '1' : '0', 30 + (col & 7));
- printc('m');
- }
-
-
- /* Print a zodiac position on the screen. This is basically just auto- */
- /* matically prints the string returned from CharZodiac() below, except */
- /* we round here to the nearest minute or second and take care of color. */
-
- void PrintZodiac(deg)
- real deg;
- {
- if (!(operation & DASHs0))
- deg = Mod(deg + (seconds < 0 ? 1.0/60.0/60.0/2.0 : 1.0/60.0/2.0));
- else
- deg = Mod(deg + (seconds < 0 ? 1.0/4.0/60.0/2.0 : 1.0/4.0/2.0));
- AnsiColor(elemansi[(int) (deg / 30.0) & 3]);
- fprintf(S, "%s", CharZodiac(deg));
- AnsiColor(DEFAULT);
- }
-
-
- /* Given a zodiac position, return a string containing it as it's */
- /* formatted for display to the user. */
-
- char *CharZodiac(deg)
- real deg;
- {
- static char zod[11];
- int sign, d, m;
- real s;
-
- if (!(operation & DASHs0)) {
-
- /* Normally, we format the position in degrees/sign/minutes format: */
-
- sign = (int) (deg / 30.0);
- d = (int) deg - sign*30;
- m = (int) (FRACT(deg)*60.0);
- sprintf(zod, "%2d%c%c%c%02d", d, SIGNAM(sign + 1), m);
- if (seconds < 0) {
- s = FRACT(deg)*60.0; s = FRACT(s)*60.0;
- sprintf(zod, "%s'%02d\"", zod, (int)s);
- }
- } else {
-
- /* However, if -s0 switch in effect, get position in hours/minutes: */
-
- d = (int) (deg / 15.0);
- m = (int) ((deg - (real)d*15.0)*60.0/24.0);
- sprintf(zod, "%2dh,%02dm", d, m);
- if (seconds < 0) {
- s = FRACT(deg)*4.0; s = FRACT(s)*60.0;
- sprintf(zod, "%s,%02ds", zod, (int)s);
- }
- }
- return zod;
- }
-
-
- /* This is similar to formatting a zodiac degree, but here we return a */
- /* string of a (signed) declination value in degrees and minutes. */
-
- char *CharAltitude(deg)
- real deg;
- {
- static char alt[8];
- int d, m;
-
- while (deg > DEGQUAD) /* Ensure declination is from -90..+90 degrees. */
- deg -= DEGHALF;
- while (deg < -DEGQUAD)
- deg += DEGHALF;
- sprintf(alt, "%c", deg < 0.0 ? '-' : '+');
- deg = dabs(deg) + 1.0/60.0/2.0;
- d = (int) deg;
- m = (int) (FRACT(deg)*60.0);
- sprintf(alt, "%s%2d%c%02d'", alt, d, DEGR2, m);
- return alt;
- }
-
-
- /* Another string formatter, here we return a date string given a month, */
- /* day, and year. We format with the day or month first based on whether */
- /* the "European" date variable is set or not. The routine also takes a */
- /* parameter to indicate how much the string should be abbreviated, if any. */
-
- char *CharDate(mon, day, yea, full)
- int mon, day, yea, full;
- {
- static char dat[20];
-
- if (full > FALSE) {
- if (eurodate) {
- if (full > TRUE)
- sprintf(dat, "%2d %c%c%c%5d", day, MONNAM(mon), yea);
- else
- sprintf(dat, "%d %s %d", day, monthname[mon], yea);
- } else {
- if (full > TRUE)
- sprintf(dat, "%c%c%c %2d%5d", MONNAM(mon), day, yea);
- else
- sprintf(dat, "%s %d, %d", monthname[mon], day, yea);
- }
- } else {
- if (eurodate) {
- if (full)
- sprintf(dat, "%2d-%2d-%2d", day, mon, yea%100);
- else
- sprintf(dat, "%2d-%2d-%4d", day, mon, yea);
- } else {
- if (full)
- sprintf(dat, "%2d/%2d/%2d", mon, day, yea%100);
- else
- sprintf(dat, "%2d/%2d/%4d", mon, day, yea);
- }
- }
- return dat;
- }
-
-
- /* Return a string containing the given time expressed as an hour and */
- /* minute quantity. This is formatted in 24 hour or am/pm time based */
- /* on whether the "European" time format flag is set or not. */
-
- char *CharTime(hr, min)
- int hr, min;
- {
- static char tim[8];
-
- if (eurotime)
- sprintf(tim, "%2d:%02d", hr, min);
- else
- sprintf(tim, "%2d:%02d%cm", Mod12(hr), min, hr < 12 ? 'a' : 'p');
- return tim;
- }
-
-
- /* Nicely format the given longitude and latitude locations and return */
- /* them in a string. Various parts of the program display a chart header, */
- /* and this allows the similar computations to be coded only once. */
-
- char *CharLocation(lon, lat, norm)
- real lon, lat, norm;
- {
- static char loc[14];
- int i, j;
-
- i = (int) (FRACT(dabs(lon))*norm+ROUND);
- j = (int) (FRACT(dabs(lat))*norm+ROUND);
- sprintf(loc, "%3.0f%c%02d%c%3.0f%c%02d%c",
- floor(dabs(lon)), DEGR3, i, lon < 0.0 ? 'E' : 'W',
- floor(dabs(lat)), DEGR3, j, lat < 0.0 ? 'S' : 'N');
- return loc;
- }
-
-
- #ifdef TIME
- /* Compute the date and time it is right now as the program is running */
- /* using the computer's internal clock. We do this by getting the number */
- /* of seconds which have passed since January 1, 1970 and going from there. */
- /* The time return value filled is expressed in the given zone parameter. */
-
- void GetTimeNow(Mon, Day, Yea, Tim, Zon)
- int *Mon, *Day, *Yea;
- real *Tim, Zon;
- {
- dword curtimer;
- int min, sec;
- real hr;
-
- time(&curtimer);
- sec = (int) (curtimer % 60);
- curtimer /= 60;
- min = (int) (curtimer % 60);
- curtimer /= 60;
- hr = (real) (curtimer % 24) - Zon;
- curtimer /= 24;
- while (hr < 0.0) {
- curtimer--;
- hr += 24.0;
- }
- while (hr >= 24.0) {
- curtimer++;
- hr -= 24.0;
- }
- #ifdef PC
- curtimer += 2415020L; /* Number of days between 1/1/1970 and 1/1/4713 BC. */
- #else
- curtimer += 2440588L; /* Number of days in 70 years different than above. */
- #endif
- JulianToMdy((real)curtimer, Mon, Day, Yea);
- *Tim = hr + (real) min / 100.0 + (real) sec / 6000.0;
- }
- #endif
-
-
- /* Stop and wait for the user to enter a line of text given a prompt to */
- /* display and a string buffer to fill with it. */
-
- void InputString(prompt, string)
- char *prompt, *string;
- {
- FILE *data;
-
- data = S; S = stdout;
- fprintf(S, "%s", prompt);
- AnsiColor(YELLOW);
- fprintf(S, " > ");
- AnsiColor(DEFAULT);
- if (gets(string) == NULL) /* Pressing control-D will terminate the */
- Terminate(_FORCE); /* program (at least on some machines.) */
- S = data;
- }
-
-
- /* Prompt the user for a floating point value, and make sure it conforms */
- /* to the specified bounds before returning it. If a non-numeric value is */
- /* entered, then assume it's the name of a month, and try to convert it */
- /* to the appropriate number from 1 to 12; and also check for an "AM" or */
- /* "PM" suffix to hour values, and adjust the number appropriately. */
-
- real Input(prompt, low, high)
- char *prompt;
- real low, high;
- {
- char line[STRING], c;
- real x;
- int i, j;
-
- loop {
- InputString(prompt, line);
- i = StringLen(line);
- for (j = 0; j < i; j++)
- if (line[j] == ':') /* Convert all colons in the */
- line[j] = '.'; /* entered line to periods. */
- c = CAP(line[0]);
-
- /* If they entered a string, then check to see if it's a month name. */
-
- if (c >= 'A' && c <= 'Z') {
- switch (c) {
- case 'J': x = CAP(line[1]) == 'U' ? /* January, */
- (CAP(line[2]) == 'L' ? 7.0 : 6.0) : 1.0; break; /* June,July */
- case 'F': x = 2.0; break; /* February */
- case 'M': x = CAP(line[2]) == 'Y' ? 5.0 : 3.0; break; /* March,May */
- case 'A': x = CAP(line[1]) == 'U' ? 8.0 : 4.0; break; /* April,August */
- case 'S': x = 9.0; break; /* September */
- case 'O': x = 10.0; break; /* October */
- case 'N': x = 11.0; break; /* November */
- case 'D': x = 12.0; break; /* December */
- default: x = 0.0;
- }
- } else {
- sscanf(line, "%lf", &x); /* Convert entered line to number. */
- i = StringLen(line)-1;
- if (i > 0 && CAP(line[i]) == 'M')
- i--;
- if (i > 0) {
- c = CAP(line[i]);
- if (c == 'A') /* Adjust value appropriately */
- x = x >= 12.0 ? x-12.0 : x; /* if 'AM' or 'PM' suffix. */
- else if (c == 'P')
- x = x >= 12.0 ? x : x+12.0;
- }
- }
- if (x >= low && x <= high)
- return x;
- sprintf(line, "Value out of range of from %.0f to %.0f.", low, high);
- PrintWarning(line);
- }
- }
-
-
- /* Given a string representing the complete pathname to a file, strip off */
- /* all the path information leaving just the filename itself. This is called */
- /* by the main program to determine the name of the Astrolog executable. */
-
- char *ProcessProgname(name)
- char *name;
- {
- char *b, *c, *e;
-
- b = c = name;
- while (*c) {
- #ifdef PC
- *c = UNCAP(*c); /* Because DOS filenames are case insensitive. */
- #endif
- c++;
- }
- e = c;
- while (c > b && *c != '.')
- c--;
- if (c > b)
- *c = 0;
- else
- c = e;
- while (c > b && *c != '/' && *c != '\\')
- c--;
- if (c > b)
- name = c+1;
- return name;
- }
-
-
- /* This important procedure gets all the parameters defining the chart that */
- /* will be worked with later. Given a "filename", it gets from it all the */
- /* pertinent chart information. This is more than just reading from a file - */
- /* the procedure also takes care of the cases of prompting the user for the */
- /* information and using the time functions to determine the date now - the */
- /* program considers these cases "virtual" files. Furthermore, when reading */
- /* from a real file, we have to check if it was written in the -o0 format. */
-
- bool InputData(filename)
- char *filename;
- {
- FILE *data;
- char name[STRING], c;
- int i;
- real k, l, m;
-
- /* If we are to read from the virtual file "set" then that means use a */
- /* particular set of chart information generated earlier in the program. */
-
- if (StringCmp(filename, "set") == 0) {
- autom = 1;
- SetCore(MonX, DayX, YeaX, TimX, ZonX, LonX, LatX);
- return TRUE;
- }
-
- #ifdef TIME
- /* If we are to read from the file "now" then that means use the time */
- /* functions to calculate the present date and time. */
-
- if (StringCmp(filename, "now") == 0) {
- autom = 1;
- ZZ = defzone; OO = deflong; AA = deflat;
- GetTimeNow(&MM, &DD, &YY, &TT, ZZ);
- return TRUE;
- }
- #endif
-
- /* If we are to read from the file "tty" then that means prompt the user */
- /* for all the chart information. */
-
- if (StringCmp(filename, "tty") == 0) {
- if (!noswitches) {
- /* Temporarily disable and internal redirection of output to a file */
- /* because we always want user headers and prompts to be displayed. */
- 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, " Invoke as '%s %cH' for list of command line options.\n",
- progname, DASH);
- S = data;
- }
- MM = (int)Input("Enter month of birth (e.g. '7', 'Jul')", 1.0, 12.0);
- DD = (int)Input("Enter day of birth (e.g. '1', '31') ", 1.0,
- (real) DayInMonth(MM, 0));
- YY = (int)Input("Enter year of birth (e.g. '1993') ", -5000.0, 5000.0);
- if (YY >= 0 && YY <= 99) {
- sprintf(name,
- "Assuming first century A.D. is really meant instead of %d.",
- 1900 + YY);
- PrintWarning(name);
- }
- fprintf(stdout, "Subtract one hour if Daylight Saving time in effect.\n");
- TT = Input("Enter time of birth (e.g. '18:30' '6:30pm')", -2.0, 24.0);
- fprintf(stdout,
- "Negative values indicate time zones east of Greenwich.\n");
- ZZ = Input("Time zone in hours before GMT (5=Eastern, 8=Pacific)",
- -24.0, 24.0);
- fprintf(stdout,
- "Negative values indicate eastern and southern locations.\n");
- OO = Input("Longitude west of place (i.e. DEG:MIN)", -DEGHALF, DEGHALF);
- AA = Input("Latitude north of place (i.e. DEG:MIN)", -DEGQUAD, DEGQUAD);
- printl();
- return TRUE;
- }
-
- /* Now that the special cases are taken care of, we can assume we are */
- /* to read from a real file. */
-
- autom = 1;
- data = fopen(filename, "r"); /* Look for file in current directory. */
- if (data == NULL) {
- sprintf(name, "%s%s", CHART_DIR, filename); /* Look for file in */
- data = fopen(name, "r"); /* default directory. */
- if (data == NULL) {
- sprintf(name, "File '%s' not found.", filename);
- PrintError(name);
- return FALSE;
- }
- }
-
- /* Read the chart parameters from a normal file. */
-
- if ((c = getc(data)) != 'S') {
- ungetc(c, data);
- fscanf(data, "%d%d%d", &MM, &DD, &YY);
- fscanf(data, "%lf%lf%lf%lf", &TT, &ZZ, &OO, &AA);
-
- /* Read the actual chart positions from a file produced with the -o0. */
-
- } else {
-
- /* Hack: A negative month value means the chart parameters are invalid, */
- /* hence -o0 is in effect and we can assume the chart positions are */
- /* already in memory so we don't have to calculate them later. */
-
- MM = -1;
- for (i = 1; i <= BASE; i++) {
- fscanf(data, "%s%lf%lf%lf", name, &k, &l, &m);
- planet[i] = (l-1.0)*30.0+k+m/60.0;
- fscanf(data, "%s%lf%lf", name, &k, &l);
- planetalt[i] = k+l/60.0;
- ret[i] = DTOR(name[1] == 'D' ? 1.0 : -1.0);
-
- /* -o0 files from version 3.05 and before don't have the uranians in */
- /* them. Be prepared to skip over them in old files for compatibility. */
-
- if (i == OBJECTS) {
- while (getc(data) >= ' ')
- ;
- if ((c = getc(data)) != 'H')
- i = C_HI;
- else
- i = total;
- }
- }
- for (i = 1; i <= SIGNS/2; i++) {
- fscanf(data, "%s%lf%lf%lf", name, &k, &l, &m);
- house[i+6] = Mod((house[i] = Mod((l-1.0)*30.0+k+m/60.0))+DEGHALF);
- }
- }
- fclose(data);
- return TRUE;
- }
-
- /* general.c */
-