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

📄 xcharts.c

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

#ifdef GRAPH

/*
******************************************************************************
** Single Chart Graphics Subprograms.
******************************************************************************
*/

/* Given a string, draw it on the screen using the given color. The       */
/* position of the text is based the saved positions of where we drew the */
/* text the last time the routine was called, being either directly below */
/* in the same column or in the same row just to the right. This is used  */
/* by the sidebar drawing routine to print a list of text on the chart.   */

int DrawPrint(string, m, n)
char *string;
int m, n;
{
  static int x0, x, y;

  if (string == NULL) {    /* Null string means just initialize position. */
    x0 = x = m; y = n;
    return y;
  }
  if (y >= charty)    /* Don't draw if we've scrolled off the chart bottom. */
    return y;
  DrawColor(m);
  DrawText(string, x, y, -1);

  /* If the second parameter is TRUE, we stay on the same line, otherwise */
  /* when FALSE we go to the next line at the original column setting.    */

  if (n)
    x += StringLen(string)*FONTX*scalet;
  else {
    x = x0;
    n = y;
    y += FONTY*scalet;
  }
  return y;
}


/* Print text showing the chart information and house and planet positions */
/* of a chart in a "sidebar" to the right of the chart in question. This   */
/* is always done for the -v and -w graphic wheel charts unless the -v0    */
/* switch flag is also set, in which case none of the stuff here is done.  */

void DrawInfo()
{
  char string[STRING];
  int elemode[4][3], elem[4], mo[3], tot, pos, abo, lef, lea, i, y, a, s;

#ifdef INTERPRET
  /* Hack: Just for fun, if interpretation is active (which normally has  */
  /* no effect whatsoever on graphics) we'll decorate the chart a little. */

  if (interpret) {
    if (screenwidth & 1) {
      /* If screenwidth value is odd, draw a moire pattern in each corner. */
      abo = charty/(screenwidth/10);
      lef = chartx/(screenwidth/10);
      for (y = 0; y <= 1; y++)
        for (i = 0; i <= 1; i++)
          for (s = 0; s <= 1; s++)
            for (a = 1; a < (s ? lef : abo)*2; a++) {
              DrawColor(a & 1 ? gray : off);
              DrawLine(i ? chartx-1-lef : lef, y ? charty-1-abo : abo,
                s ? (i ? chartx-1-a : a) : i*(chartx-1),
                s ? y*(charty-1) : (y ? charty-1-a : a));
            }
    } else {
      /* If screenwidth is even, draw spider web lines in each corner. */
      DrawColor(gray);
      tot = screenwidth*3/20;
      abo = charty/4;
      lef = chartx/4;
      for (y = 0; y <= 1; y++)
        for (i = 0; i <= 1; i++)
          for (a = 1; a < tot; a++)
            DrawLine(i*(chartx-1), y ? (charty-1-a*abo/tot) : a*abo/tot,
              i ? chartx-1-lef+a*lef/tot : lef-a*lef/tot, y*(charty-1));
    }
  }
#endif
  if (!xtext || (exdisplay & DASHv0) > 0)    /* Don't draw sidebar if */
    return;                                  /* -v0 flag is set.      */

  a = ansi;
  ansi = FALSE;
  seconds = -seconds;
  DrawColor(hilite);
  if (xborder)
    DrawLine(chartx-1, 0, chartx-1, charty-1);
  chartx += SIDET;
  DrawPrint(NULL, chartx-SIDET+FONTX*scalet, FONTY*7/5*scalet);

  /* Print chart header and setting information. */
  sprintf(string, "%s %s", appname, VERSION);
  DrawPrint(string, on, FALSE);
  if (Mon == -1)
    sprintf(string, "No time or space.");
  else if (relation == DASHrc)
    sprintf(string, "Composite chart.");
  else {
    sprintf(string, "%c%c%c %s", DAYNAM(DayOfWeek(Mon, Day, Yea)),
      CharDate(Mon, Day, Yea, TRUE));
    DrawPrint(string, hilite, FALSE);
    DrawPrint(CharTime((int)floor(Tim), (int)(FRACT(dabs(Tim))*100.0)),
      hilite, TRUE);
    sprintf(string, " (%d:%02d GMT)", (int)(-Zon),
      (int)(FRACT(dabs(Zon))*100.0+ROUND));
  }
  DrawPrint(string, hilite, FALSE);
  DrawPrint(CharLocation(Lon, Lat, 100.0), hilite, FALSE);
  sprintf(string, "%s houses.", systemname[housesystem]);
  DrawPrint(string, hilite, FALSE);
  sprintf(string, "%s zodiac.", operation & DASHs ? "Siderial" : "Tropical");
  DrawPrint(string, hilite, FALSE);
  sprintf(string, "Julian Day = %10.3f", JulianDayFromTime(T));
  DrawPrint(string, hilite, FALSE);

  /* Print house cusp positions. */
  DrawPrint("", hilite, FALSE);
  for (i = 1; i <= SIGNS; i++) {
    sprintf(string, "%2d%s house: ", i, post[i]);
    y = DrawPrint(string, signcolor(i), TRUE);
    if (!seconds && (scale == 100 || !xfont || !xfile) && y < charty) {
      s = scale;
      scale = 100*scalet;
      DrawSign(i, chartx-12*scalet, y-(FONTY/2-1)*scalet);
      scale = s;
    }
    DrawPrint(CharZodiac(house[i]), signcolor(ZTOS(house[i])), FALSE);
  }

  /* Print planet positions. */
  DrawPrint("", hilite, FALSE);
  for (i = 1; i <= total; i++) if (!ignore[i]) {
    sprintf(string, seconds ? "%3.3s: " : "%4.4s: ", objectname[i]);
    DrawPrint(string, objectcolor[i], TRUE);
    y = DrawPrint(CharZodiac(planet[i]), signcolor(ZTOS(planet[i])), TRUE);
    if (!seconds && i < S_LO &&
      (scale == 100 || !xfont || !xfile) && y < charty) {
      s = scale;
      scale = 100*scalet;
      DrawObject(i, chartx-12*scalet, y-(FONTY/2-1)*scalet);
      scale = s;
    }
    sprintf(string, "%c ", ret[i] < 0.0 ? 'R' : ' ');
    DrawPrint(string, on, TRUE);
    DrawPrint(CharAltitude(planetalt[i]), hilite, FALSE);
  }

  /* Print element table information. */
  DrawPrint("", hilite, FALSE);
  CreateElemTable(elemode, elem, mo, &tot, &pos, &abo, &lef, &lea);
  sprintf(string, "Fire: %d, Earth: %d,", elem[_FIR], elem[_EAR]);
  DrawPrint(string, hilite, FALSE);
  sprintf(string, "Air : %d, Water: %d", elem[_AIR], elem[_WAT]);
  DrawPrint(string, hilite, FALSE);
  sprintf(string, "Car: %d, Fix: %d, Mut: %d", mo[0], mo[1], mo[2]);
  DrawPrint(string, hilite, FALSE);
  sprintf(string, "Yang: %d, Yin: %d", pos, tot-pos);
  DrawPrint(string, hilite, FALSE);
  sprintf(string, "N: %d, S: %d, W: %d, E: %d", abo, tot-abo, tot-lef, lef); 
  DrawPrint(string, hilite, FALSE);
  seconds = -seconds;
  ansi = a;
}


/* Draw a wheel chart, in which the 12 signs and houses are delineated, and  */
/* the planets are inserted in their proper places. This is the default      */
/* graphics chart to generate, as is done when the -v or -w (or no) switches */
/* are included with -X. Draw the aspects in the middle of chart, too.       */

void XChartWheel()
{
  real xsign[SIGNS+1], xhouse[SIGNS+1], xplanet[TOTAL+1], symbol[TOTAL+1];
  int cx, cy, i, j;
  real asc, orb = DEFORB*256.0/(real)charty*(real)SCALE,
    unitx, unity, px, py, temp;

  /* Set up variables and temporarily automatically decrease the horizontal */
  /* chart size to leave room for the sidebar if that mode is in effect.    */

  if (xtext && !(exdisplay & DASHv0))
    chartx -= SIDET;
  cx = chartx/2 - 1; cy = charty/2 - 1;
  unitx = (real)cx; unity = (real)cy;
  asc = xeast ? planet[abs(xeast)]+90*(xeast < 0) : house[1];
  InitCircle();

  /* Fill out arrays with the angular degree on the circle of where to    */
  /* place each object, cusp, and sign glyph based on how the chart mode. */

  if (modex == MODEv) {
    for (i = 1; i <= SIGNS; i++)
      xhouse[i] = PZ(house[i]);
  } else {
    asc -= house[1];
    for (i = 1; i <= SIGNS; i++)
      xhouse[i] = PZ(STOZ(i));
  }
  for (i = 1; i <= SIGNS; i++)
    xsign[i] = PZ(XHousePlaceIn(STOZ(i)));
  for (i = 1; i <= total; i++)
    xplanet[i] = PZ(XHousePlaceIn(planet[i]));

  /* Draw Ascendant/Descendant and Midheaven/Nadir lines across whole chart. */

  DrawColor(hilite);
  DrawDash(cx+POINT(unitx, 0.99, PX(xhouse[1])),
           cy+POINT(unity, 0.99, PY(xhouse[1])),
           cx+POINT(unitx, 0.99, PX(xhouse[7])),
           cy+POINT(unity, 0.99, PY(xhouse[7])), !xcolor);
  DrawDash(cx+POINT(unitx, 0.99, PX(xhouse[10])),
           cy+POINT(unity, 0.99, PY(xhouse[10])),
           cx+POINT(unitx, 0.99, PX(xhouse[4])),
           cy+POINT(unity, 0.99, PY(xhouse[4])), !xcolor);

  /* Draw small five or one degree increments around the zodiac sign ring. */

  for (i = 0; i < DEGR; i += 5-(xcolor || psfile || metafile)*4) {
    temp = PZ(XHousePlaceIn((real)i));
    px = PX(temp); py = PY(temp);
    DrawColor(i%5 ? gray : on);
    DrawDash(cx+POINT(unitx, 0.75, px), cy+POINT(unity, 0.75, py),
      cx+POINT(unitx, 0.80, px), cy+POINT(unity, 0.80, py),
      ((psfile || metafile) && i%5)*2);
  }

  /* Draw circles for the zodiac sign and house rings. */

  DrawColor(on);
  DrawCircle(cx, cy, (int)(unitx*0.95+ROUND), (int)(unity*0.95+ROUND));
  DrawCircle(cx, cy, (int)(unitx*0.80+ROUND), (int)(unity*0.80+ROUND));
  DrawCircle(cx, cy, (int)(unitx*0.75+ROUND), (int)(unity*0.75+ROUND));
  DrawCircle(cx, cy, (int)(unitx*0.65+ROUND), (int)(unity*0.65+ROUND));

  /* Draw the glyphs for the signs and houses themselves. */

  for (i = 1; i <= SIGNS; i++) {
    temp = xsign[i];
    DrawColor(on);
    DrawLine(cx+POINT(unitx, 0.95, PX(temp)),      /* Draw lines separating */
      cy+POINT(unity, 0.95, PY(temp)),             /* each sign and house   */
      cx+POINT(unitx, 0.80, PX(temp)),             /* from each other.      */
      cy+POINT(unity, 0.80, PY(temp)));
    DrawLine(cx+POINT(unitx, 0.75, PX(xhouse[i])),
      cy+POINT(unity, 0.75, PY(xhouse[i])),
      cx+POINT(unitx, 0.65, PX(xhouse[i])),
      cy+POINT(unity, 0.65, PY(xhouse[i])));
    if (xcolor && i%3 != 1) {                                 /* Lines from */
      DrawColor(gray);                                        /* each house */
      DrawDash(cx, cy, cx+POINT(unitx, 0.65, PX(xhouse[i])),  /* to center  */
        cy+POINT(unity, 0.65, PY(xhouse[i])), 1);             /* of wheel.  */
    }
    temp = Midpoint(temp, xsign[Mod12(i+1)]);
    DrawColor(signcolor(i));
    DrawSign(i, cx+POINT(unitx, 0.875, PX(temp)),
      cy+POINT(unity, 0.875, PY(temp)));
    temp = Midpoint(xhouse[i], xhouse[Mod12(i+1)]);
    DrawHouse(i, cx+POINT(unitx, 0.70, PX(temp)),
      cy+POINT(unity, 0.70, PY(temp)));
  }
  for (i = 1; i <= total; i++)    /* Figure out where to put planet glyphs. */
    symbol[i] = xplanet[i];
  FillSymbolRing(symbol);

  /* For each planet, draw a small dot indicating where it is, and then */
  /* a line from that point to the planet's glyph.                      */

  for (i = 1; i <= total; i++) if (Proper(i)) {
    if (xlabel) {
      temp = symbol[i];
      DrawColor(ret[i] < 0.0 ? gray : on);
      DrawDash(cx+POINT(unitx, 0.52, PX(xplanet[i])),
        cy+POINT(unity, 0.52, PY(xplanet[i])),
        cx+POINT(unitx, 0.56, PX(temp)),
        cy+POINT(unity, 0.56, PY(temp)),
        (ret[i] < 0.0 ? 1 : 0) - xcolor);
      DrawObject(i, cx+POINT(unitx, 0.60, PX(temp)),
        cy+POINT(unity, 0.60, PY(temp)));
    } else
      DrawColor(objectcolor[i]);
    DrawPoint(cx+POINT(unitx, 0.50, PX(xplanet[i])),
      cy+POINT(unity, 0.50, PY(xplanet[i])));
  }

  /* Draw lines connecting planets which have aspects between them. */

  if (!xbonus) {          /* Don't draw aspects in bonus mode. */
    CreateGrid(FALSE);
    for (j = total; j >= 2; j--)
      for (i = j-1; i >= 1; i--)
        if (grid->n[i][j] && Proper(i) && Proper(j)) {
          DrawColor(aspectcolor[grid->n[i][j]]);
          DrawDash(cx+POINT(unitx, 0.48, PX(xplanet[i])),
            cy+POINT(unity, 0.48, PY(xplanet[i])),
            cx+POINT(unitx, 0.48, PX(xplanet[j])),
            cy+POINT(unity, 0.48, PY(xplanet[j])),
            abs(grid->v[i][j]/60/2));
        }
  }

  /* Go draw sidebar with chart information and positions if need be. */

  DrawInfo();
}


/* Draw an astro-graph chart on a map of the world, i.e. the draw the     */
/* Ascendant, Descendant, Midheaven, and Nadir lines corresponding to the */
/* time in the chart. This chart is done when the -L switch is combined   */

⌨️ 快捷键说明

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