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

📄 options.c

📁 一个占星术算命游戏
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
** Astrolog (Version 4.00) File: options.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"


/*
******************************************************************************
** Display Subroutines.
******************************************************************************
*/

/* This is a subprocedure of CreateGrid() and CreateGridRelation(). Given */
/* two planets, determine what aspect, if any, is present between them,   */
/* and save the aspect name and orb in the specified grid cell.           */

void GetAspect(planet1, planet2, ret1, ret2, i, j)
real *planet1, *planet2, *ret1, *ret2;
int i, j;
{
  int k;
  real l, m;

  grid->v[i][j] = grid->n[i][j] = 0;
  l = MinDistance(planet2[i], planet1[j]);
  for (k = aspects; k >= 1; k--) {
    m = l-aspectangle[k];
    if (dabs(m) < Orb(i, j, k)) {
      grid->n[i][j] = k;

      /* If -ga switch in effect, then change the sign of the orb to    */
      /* correspond to whether the aspect is applying or separating.    */
      /* To do this, we check the velocity vectors to see if the        */
      /* planets are moving toward, away, or are overtaking each other. */

      if (exdisplay & DASHga)
        m = SGN2(ret1[j]-ret2[i])*
          SGN2(MinDifference(planet2[i], planet1[j]))*SGN2(m)*dabs(m);
      grid->v[i][j] = (int) (m*60.0);
    }
  }
}


/* Set up the aspect/midpoint grid. Allocate memory for this array, if not */
/* already done. Allocation is only done once, first time this is called.  */

bool EnsureGrid()
{
  char string[STRING];

  if (grid != NULL)
    return TRUE;
  Allocate(grid, sizeof(gridstruct), gridstruct PTR);
  if (grid == NULL
#ifdef PC
    /* For PC's the grid better not cross a segment boundary. */
    || HIWORD(LOWORD(grid) + sizeof(gridstruct)) > 0
#endif
    ) {
    sprintf(string, "Not enough memory for grid (%d bytes).",
      sizeof(gridstruct));
    PrintError(string);
    return FALSE;
  }
  return TRUE;
}


/* Fill in the aspect grid based on the aspects taking place among the */
/* planets in the present chart. Also fill in the midpoint grid.       */

void CreateGrid(acc)
int acc;
{
  int i, j, k;
  real l;

  if (!EnsureGrid())
    return;
  for (j = 1; j <= total; j++) if (!ignore[j])
    for (i = 1; i <= total; i++) if (!ignore[i])

      /* The parameter 'acc' determine what half of the grid is filled in */
      /* with the aspects and what half is filled in with the midpoints.  */

      if (acc ? i > j : i < j)
        GetAspect(planet, planet, ret, ret, i, j);
      else if (acc ? i < j : i > j) {
        l = Mod(Midpoint(planet[i], planet[j])); k = (int)l;    /* Calculate */
        grid->n[i][j] = k/30+1;                                 /* midpoint. */
        grid->v[i][j] = (int)((l-(real)(k/30)*30.0)*60.0);
      } else {
        grid->n[i][j] = ZTOS(planet[j]);
        grid->v[i][j] = (int)(planet[j]-(real)(grid->n[i][j]-1)*30.0);
      }
}


/* This is similar to the previous function; however, this time fill in the */
/* grid based on the aspects (or midpoints if 'acc' set) taking place among */
/* the planets in two different charts, as in the -g -r0 combination.       */

void CreateGridRelation(acc)
int acc;
{
  int i, j, k;
  real l;

  if (!EnsureGrid())
    return;
  for (j = 1; j <= total; j++) if (!ignore[j])
    for (i = 1; i <= total; i++) if (!ignore[i])
      if (!acc)
        GetAspect(planet1, planet2, ret1, ret2, i, j);
      else {
        l = Mod(Midpoint(planet2[i], planet1[j])); k = (int)l;  /* Calculate */
        grid->n[i][j] = k/30+1;                                 /* midpoint. */
        grid->v[i][j] = (int)((l-(real)(k/30)*30.0)*60.0);
      }
}


/*
******************************************************************************
** Multiple Chart Display Subprograms.
******************************************************************************
*/

/* Print out an aspect (or midpoint if -g0 switch in effect) grid of a      */
/* relationship chart. This is similar to the ChartGrid() routine; however, */
/* here we have both axes labeled with the planets for the two charts in    */
/* question, instead of just a diagonal down the center for only one chart. */

void DisplayGridRelation()
{
  int i, j, k, tot = total, temp;

#ifdef INTERPRET
  if (interpret && !(exdisplay & DASHg0)) {
    InterpretGridRelation();
    return;
  }
#endif
  fprintf(S, " 2>");
  for (temp = 0, i = 1; i <= total; i++) if (!ignore[i]) {
    printc(BOXV);
    AnsiColor(objectansi[i]);
    fprintf(S, "%c%c%c", OBJNAM(i));
    AnsiColor(DEFAULT);
    temp++;
    if (column80 && temp >= 19) {
      tot = i;
      i = total;
    }
  }
  fprintf(S, "\n1  ");
  for (i = 1; i <= tot; i++) if (!ignore[i]) {
    printc(BOXV);
    AnsiColor(signansi(ZTOS(planet2[i])));
    fprintf(S, "%2d%c", (int)planet2[i] % 30, DEGR2);
    AnsiColor(DEFAULT);
  }
  fprintf(S, "\nV  ");
  for (i = 1; i <= tot; i++) if (!ignore[i]) {
    printc(BOXV);
    temp = ZTOS(planet2[i]);
    AnsiColor(signansi(temp));
    fprintf(S, "%c%c%c", SIGNAM(temp));
    AnsiColor(DEFAULT);
  }
  printl();
  for (j = 1; j <= total; j++) if (!ignore[j])
    for (k = 1; k <= 4; k++) {
      if (k < 2)
        PrintTab(BOXH, 3);
      else if (k == 2) {
        AnsiColor(objectansi[j]);
        fprintf(S, "%c%c%c", OBJNAM(j));
      } else {
        temp = ZTOS(planet1[j]);
        AnsiColor(signansi(temp));
        if (k == 3)
          fprintf(S, "%2d%c", (int)planet1[j] - (temp-1)*30, DEGR2);
        else
          fprintf(S, "%c%c%c", SIGNAM(temp));
      }
      if (k > 1)
        AnsiColor(DEFAULT);
      for (i = 1; i <= tot; i++) if (!ignore[i]) {
        printc(k < 2 ? BOXC : BOXV);
        temp = grid->n[i][j];
        if (k > 1) {
          if (i == j)
            AnsiColor(REVERSE);
          AnsiColor(exdisplay & DASHg0 ? signansi(temp) :
            aspectansi[temp]);
        }
        if (k < 2)
          PrintTab(BOXH, 3);
        else if (k == 2) {
          if (exdisplay & DASHg0)
            fprintf(S, "%c%c%c", SIGNAM(temp));
          else
            fprintf(S, "%s", temp ? aspectabbrev[temp] : "   ");
        } else if (k == 3) {
          if (exdisplay & DASHg0)
            fprintf(S, "%2d%c", grid->v[i][j]/60, DEGR2);
          else
            if (grid->n[i][j]) {
              if (grid->v[i][j] < 600)
                fprintf(S, "%c%2d", exdisplay & DASHga ?
                  (grid->v[i][j] < 0 ? 'a' : 's') :
                  (grid->v[i][j] < 0 ? '-' : '+'), abs(grid->v[i][j])/60);
              else
                fprintf(S, "%3d", abs(temp)/60);
            } else
              fprintf(S, "   ");
        } else {
          if (grid->n[i][j])
            fprintf(S, "%02d'", abs(grid->v[i][j])%60);
          else
            fprintf(S, "   ");
        }
        AnsiColor(DEFAULT);
      }
      printl();
    }
}


/* Display all aspects between objects in the relationship comparison chart, */
/* one per line, in sorted order based on the total "power" of the aspects,  */
/* as specified with the -r0 -m0 switch combination.                         */

void DisplayAspectRelation()
{
  int pcut = 30000, icut, jcut, phi, ihi, jhi, ahi, p, i, j, k, count = 0;
  real ip, jp;

  loop {
    phi = -1;

    /* Search for the next most powerful aspect in the aspect grid. */

    for (i = 1; i <= total; i++) if (!ignore[i])
      for (j = 1; j <= total; j++) if (!ignore[j])
        if (k = grid->n[i][j]) {
          ip = i <= OBJECTS ? objectinf[i] : 2.5;
          jp = j <= OBJECTS ? objectinf[j] : 2.5;
          p = (int) (aspectinf[k]*(ip+jp)/2.0*
            (1.0-dabs((real)(grid->v[i][j]))/60.0/aspectorb[k])*1000.0);
          if ((p < pcut || (p == pcut && (i > icut ||
            (i == icut && j > jcut)))) && p > phi) {
            ihi = i; jhi = j; phi = p; ahi = k;
          }
        }
    if (phi < 0)    /* Exit when no less powerful aspect found. */
      break;
    pcut = phi; icut = ihi; jcut = jhi;
    count++;                               /* Display the current aspect.   */
#ifdef INTERPRET
    if (interpret) {                       /* Interpret it if -I in effect. */
      InterpretAspectRelation(jhi, ihi);
      continue;
    }
#endif
    fprintf(S, "%3d: ", count);
    PrintAspect(jhi, ZTOS(planet1[jhi]), (int)Sgn(ret1[jhi]), ahi,
      ihi, ZTOS(planet2[ihi]), (int)Sgn(ret2[ihi]), 'A');
    k = grid->v[ihi][jhi];
    AnsiColor(k < 0 ? WHITE : LTGRAY);
    fprintf(S, "- orb: %c%d,%02d'",
      exdisplay & DASHga ? (k < 0 ? 'a' : 's') : (k < 0 ? '-' : '+'),
      abs(k)/60, abs(k)%60);
    AnsiColor(DKGREEN);
    fprintf(S, " - power:%6.2f\n", (real) phi/1000.0);
    AnsiColor(DEFAULT);
  }
}


/* Display locations of all midpoints between objects in the relationship */
/* comparison chart, one per line, in sorted zodiac order from zero Aries */
/* onward, as specified with the -r0 -m switch combination.               */

void DisplayMidpointRelation()
{
  int mcut = -1, icut, jcut, mlo, ilo, jlo, m, i, j, count = 0;

  loop {
    mlo = 21600;

    /* Search for the next closest midpoint farther down in the zodiac. */ 

    for (i = 1; i <= total; i++) if (!ignore[i])
      for (j = 1; j <= total; j++) if (!ignore[j]) {
        m = (grid->n[j][i]-1)*30*60 + grid->v[j][i];
        if ((m > mcut || (m == mcut && (i > icut ||
          (i == icut && j > jcut)))) && m < mlo) {
          ilo = i; jlo = j; mlo = m;
        }
      }
    if (mlo >= 21600)    /* Exit when no midpoint farther in zodiac found. */
      break;
    mcut = mlo; icut = ilo; jcut = jlo;
    count++;                               /* Display the current midpoint. */
#ifdef INTERPRET
    if (interpret) {                       /* Interpret it if -I in effect. */
      InterpretMidpointRelation(ilo, jlo);
      continue;
    }
#endif
    fprintf(S, "%4d: ", count);
    PrintZodiac((real) mlo/60.0);
    printc(' ');
    PrintAspect(ilo, ZTOS(planet1[ilo]), (int)Sgn(ret1[ilo]), 0,
      jlo, ZTOS(planet2[jlo]), (int)Sgn(ret2[jlo]), 'M');
    AnsiColor(DEFAULT);
    fprintf(S, "-%4d degree span.\n",
      (int)MinDistance(planet1[ilo], planet2[jlo]));
  }
}


/* Calculate any of the various kinds of relationship charts. This involves */
/* reading in and storing the planet and house positions for both charts,   */
/* and then combining them in the main single chart in the proper manner.   */
/* If the parameter 'var' is set, then we read the info for the two charts  */
/* from files, otherwise use the info in preset "core" and "second" charts. */

void CastRelation(var)
int var;
{
  int mon, day, yea, i;
  real tim, zon, lon, lat, t1, t2, t;

  /* Read in and cast the first chart. */

  if (var)
    InputData(filename);
  mon = MM; day = DD; yea = YY; tim = TT; zon = ZZ; lon = OO; lat = AA;
  if (var) {
    SetTwin(MM, DD, YY, TT, ZZ, OO, AA);
  } else {
    SetCore(Mon2, Day2, Yea2, Tim2, Zon2, Lon2, Lat2);
  }
  t1 = CastChart(TRUE);
  for (i = 1; i <= SIGNS; i++) {
    house1[i] = house[i];
    inhouse1[i] = inhouse[i];
  }
  for (i = 1; i <= total; i++) {
    planet1[i] = planet[i];
    planetalt1[i] = planetalt[i];
    ret1[i] = ret[i];
  }

  /* Read in the second chart. */

  if (var) {
    InputData(filename2);
    if (relation == DASHrp) {
      progress = TRUE;
      Jdp = (real)MdyToJulian(MM, DD, YY) + TT / 24.0;
      SetCore(mon, day, yea, tim, zon, lon, lat);
    }
  } else {
    SetCore(mon, day, yea, tim, zon, lon, lat);
  }
  SetMain(MM, DD, YY, TT, ZZ, OO, AA);
  t2 = CastChart(TRUE);
  for (i = 1; i <= SIGNS; i++) {
    house2[i] = house[i];
    inhouse2[i] = inhouse[i];
  }
  for (i = 1; i <= total; i++) {
    planet2[i] = planet[i];
    planetalt2[i] = planetalt[i];
    ret2[i] = ret[i];
  }

  /* Now combine the two charts based on what relation we are doing.   */
  /* For the standard -r synastry chart, use the house cusps of chart1 */
  /* and the planets positions of chart2.                              */

  if (relation <= DASHr)
    for (i = 1; i <= SIGNS; i++)
      house[i] = house1[i];

  /* For the -rc composite chart, take the midpoints of the planets/houses. */

⌨️ 快捷键说明

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