⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 general.c

📁 占星术4.0源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* 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 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -