home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / EFFO / pd8.lzh / SRC / altmenus.c < prev    next >
Text File  |  1990-04-13  |  11KB  |  384 lines

  1. /* printing routines for the three alternative bottom half menus,
  2.  * "menu1", "menu2" and "menu3".
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <math.h>
  7. #include "astro.h"
  8. #include "circum.h"
  9. #include "screen.h"
  10.  
  11. static int altmenu = F_MNU1;    /* which alternate menu is up; one of F_MNUi */
  12. static int alt2_stdhzn;    /* whether to use STDHZN (aot ADPHZN) horizon algthm  */
  13. static int alt3_geoc;    /* whether to use geocentric (aot topocentric) vantage*/
  14.  
  15. /* table of screen rows given a body #define from astro/h or screen.h */
  16. static short bodyrow[NOBJ] = {
  17.     R_MERCURY, R_VENUS, R_MARS, R_JUPITER, R_SATURN,
  18.     R_URANUS, R_NEPTUNE, R_PLUTO, R_SUN, R_MOON, R_OBJX, R_OBJY
  19. };
  20. /* table of screen cols for third menu format, given body #define ... */
  21. static short bodycol[NOBJ] = {
  22.     C_MERCURY, C_VENUS, C_MARS, C_JUPITER, C_SATURN,
  23.     C_URANUS, C_NEPTUNE, C_PLUTO, C_SUN, C_MOON, C_OBJX, C_OBJY
  24. };
  25.  
  26. /* let op decide which alternate menu should be up,
  27.  * including any menu-specific setup they might require.
  28.  * return 0 if things changed to require updating the alt menu; else -1.
  29.  */
  30. altmenu_setup()
  31. {
  32.     static char *flds[5] = {
  33.         "Data menu", "Rise/Set menu", "Separations menu"
  34.     };
  35.     int newmenu = altmenu, newhzn = alt2_stdhzn, newgeoc = alt3_geoc;
  36.     int new;
  37.     int fn = altmenu == F_MNU1 ? 0 : altmenu == F_MNU2 ? 1 : 2;
  38.  
  39.     ask:
  40.     flds[3]= newhzn ? "Standard hzn" : "Adaptive hzn";
  41.     flds[4]= newgeoc? "Geocentric" : "Topocentric";
  42.  
  43.     switch (popup (flds, fn, 5)) {
  44.     case 0: newmenu = F_MNU1; break;
  45.     case 1: newmenu = F_MNU2; break;
  46.     case 2: newmenu = F_MNU3; break;
  47.     case 3: newhzn ^= 1; fn = 3; goto ask;
  48.     case 4: newgeoc ^= 1; fn = 4; goto ask;
  49.     default: return (-1);
  50.     }
  51.  
  52.     new = 0;
  53.     if (newmenu != altmenu) {
  54.         altmenu = newmenu;
  55.         new++;
  56.     }
  57.     if (newhzn != alt2_stdhzn) {
  58.         alt2_stdhzn = newhzn;
  59.         if (newmenu == F_MNU2)
  60.         new++;
  61.     }
  62.     if (newgeoc != alt3_geoc) {
  63.         alt3_geoc = newgeoc;
  64.         if (newmenu == F_MNU3)
  65.         new++;
  66.     }
  67.     return (new ? 0 : -1);
  68. }
  69.  
  70. /* erase the info for the given planet */
  71. alt_nobody (p)
  72. int p;
  73. {
  74.     f_eol (bodyrow[p], C_RA);
  75. }
  76.  
  77. alt_body (b, force, np)
  78. int b;        /* which body, ala astro.h and screen.h defines */
  79. int force;    /* if !0 then draw for sure, else just if changed since last */
  80. Now *np;
  81. {
  82.     switch (altmenu) {
  83.     case F_MNU1: alt1_body (b, force, np); break;
  84.     case F_MNU2: alt2_body (b, force, np); break;
  85.     case F_MNU3: alt3_body (b, force, np); break;
  86.     }
  87. }
  88.  
  89. /* draw the labels for the current alternate menu format */
  90. alt_labels ()
  91. {
  92.     switch (altmenu) {
  93.     case F_MNU1: alt1_labels (); break;
  94.     case F_MNU2: alt2_labels (); break;
  95.     case F_MNU3: alt3_labels (); break;
  96.     }
  97. }
  98.  
  99. /* erase the labels for the current alternate menu format */
  100. alt_nolabels ()
  101. {
  102.     int i;
  103.  
  104.     f_string (R_ALTM, C_ALTMV, "             ");
  105.     for (i = R_PLANTAB; i < R_SUN; i++)
  106.         f_eol (i, C_RA);
  107. }
  108.  
  109. alt_menumask()
  110. {
  111.     return (altmenu);
  112. }
  113.  
  114. /* handy function to return the next planet in the order in which they are
  115.  * displayed in the lower half of the screen.
  116.  * input is a given planet, return is the next planet.
  117.  * if input is not legal, then first planet is returned; when input is the
  118.  * last planet, then -1 is returned.
  119.  * typical usage is something like:
  120.  *   for (p = nxtbody(-1); p != -1; p = nxtbody(p))
  121.  */
  122. nxtbody(p)
  123. int p;
  124. {
  125.     static short nxtpl[NOBJ] = {
  126.         VENUS, MARS, JUPITER, SATURN, URANUS,
  127.         NEPTUNE, PLUTO, OBJX, MOON, MERCURY, OBJY, -1
  128.     };
  129.  
  130.     if (p < MERCURY || p >= NOBJ)
  131.         return (SUN);
  132.     else
  133.         return (nxtpl[p]);
  134. }
  135.  
  136. static
  137. alt1_labels()
  138. {
  139.     f_string (R_ALTM, C_ALTMV, "  Planet Data");
  140.  
  141.     f_string (R_PLANTAB,    C_RA+2,    "R.A.");
  142.     f_string (R_PLANTAB,    C_DEC+2,"Dec");
  143.     f_string (R_PLANTAB,    C_AZ+2,    "Az");
  144.     f_string (R_PLANTAB,    C_ALT+2,"Alt");
  145.     f_string (R_PLANTAB,    C_HLONG,"H Long");
  146.     f_string (R_PLANTAB,    C_HLAT,    "H Lat");
  147.     f_string (R_PLANTAB,    C_EDIST,"Ea Dst");
  148.     f_string (R_PLANTAB,    C_SDIST,"Sn Dst");
  149.     f_string (R_PLANTAB,    C_ELONG,"Elong");
  150.     f_string (R_PLANTAB,    C_SIZE,    "Size");
  151.     f_string (R_PLANTAB,    C_MAG,    "VMag");
  152.     f_string (R_PLANTAB,    C_PHASE,"Phs");
  153. }
  154.  
  155. static
  156. alt2_labels()
  157. {
  158.     f_string (R_ALTM, C_ALTMV, "Rise/Set Info");
  159.  
  160.     f_string (R_PLANTAB,    C_RISETM-2,    "Rise Time");
  161.     f_string (R_PLANTAB,    C_RISEAZ,    "Rise Az");
  162.     f_string (R_PLANTAB,    C_TRANSTM-2,    "Trans Time");
  163.     f_string (R_PLANTAB,    C_TRANSALT-1,    "Trans Alt");
  164.     f_string (R_PLANTAB,    C_SETTM-1,    "Set Time");
  165.     f_string (R_PLANTAB,    C_SETAZ,    "Set Az");
  166.     f_string (R_PLANTAB,    C_TUP-1,    "Hours Up");
  167. }
  168.  
  169. static
  170. alt3_labels()
  171. {
  172.     f_string (R_ALTM, C_ALTMV, "  Separations");
  173.  
  174.     f_string (R_PLANTAB,    C_SUN,        " Sun");
  175.     f_string (R_PLANTAB,    C_MOON,        "Moon");
  176.     f_string (R_PLANTAB,    C_MERCURY,    "Merc");
  177.     f_string (R_PLANTAB,    C_VENUS,    "Venus");
  178.     f_string (R_PLANTAB,    C_MARS,        "Mars");
  179.     f_string (R_PLANTAB,    C_JUPITER,    " Jup");
  180.     f_string (R_PLANTAB,    C_SATURN,    " Sat");
  181.     f_string (R_PLANTAB,    C_URANUS,    "Uranus");
  182.     f_string (R_PLANTAB,    C_NEPTUNE,    " Nep");
  183.     f_string (R_PLANTAB,    C_PLUTO,    "Pluto");
  184.     f_string (R_PLANTAB,    C_OBJX,        "  X");
  185.     f_string (R_PLANTAB,    C_OBJY,        "  Y");
  186. }
  187.  
  188. /* print body info in first menu format */
  189. static
  190. alt1_body (p, force, np)
  191. int p;        /* which body, as in astro.h/screen.h defines */
  192. int force;    /* whether to print for sure or only if things have changed */
  193. Now *np;
  194. {
  195.     Sky sky;
  196.     double as = plot_ison() || srch_ison() ? 0.0 : 60.0;
  197.     int row = bodyrow[p];
  198.  
  199.     if (body_cir (p, as, np, &sky) || force) {
  200.         f_ra (row, C_RA, sky.s_ra);
  201.         f_angle (row, C_DEC, sky.s_dec);
  202.         if (p != MOON && sky.s_hlong != NOHELIO) {
  203.         f_angle (row, C_HLONG, sky.s_hlong);
  204.         if (p != SUN)
  205.             f_angle (row, C_HLAT, sky.s_hlat);
  206.         }
  207.  
  208.         if (p == MOON) {
  209.         /* distance is on km, show in miles */
  210.         f_double (R_MOON, C_EDIST, "%6.0f", sky.s_edist/1.609344);
  211.         } else if (sky.s_edist > 0.0) {
  212.         /* show distance in au */
  213.         f_double (row, C_EDIST,(sky.s_edist>=10.0)?"%6.3f":"%6.4f",
  214.                                 sky.s_edist);
  215.         }
  216.         if (sky.s_sdist > 0.0)
  217.         f_double (row, C_SDIST, (sky.s_sdist>=10.0)?"%6.3f":"%6.4f",
  218.                                 sky.s_sdist);
  219.         if (p != SUN)
  220.         f_double (row, C_ELONG, "%6.1f", sky.s_elong);
  221.         if (p != OBJX && p != OBJY)
  222.         f_double (row, C_SIZE, (p==MOON||p==SUN)?"%4.0f":"%4.1f",
  223.                                 sky.s_size);
  224.         f_double (row, C_MAG, (p==MOON||p==SUN)?"%4.0f":"%4.1f",
  225.                                     sky.s_mag);
  226.         if (sky.s_sdist > 0.0) {
  227.         /* some terminals scroll when write a char in low-right corner.
  228.          * TODO: is there a nicer way to handle this maybe?
  229.          */
  230.         int col = row == NR ? C_PHASE - 1 : C_PHASE;
  231.         /* would just do this if Turbo-C 2.0 "%?.0f" worked:
  232.          * f_double (row, col, "%3.0f", sky.s_phase);
  233.          */
  234.         f_int (row, col, "%3d", sky.s_phase);
  235.         }
  236.     }
  237.  
  238.     f_angle (row, C_AZ, sky.s_az);
  239.     f_angle (row, C_ALT, sky.s_alt);
  240. }
  241.  
  242. /* print body info in the second menu format */
  243. static
  244. alt2_body (p, force, np)
  245. int p;        /* which body, as in astro.h/screen.h defines */
  246. int force;    /* whether to print for sure or only if things have changed */
  247. Now *np;
  248. {
  249.     double ltr, lts, ltt, azr, azs, altt;
  250.     int row = bodyrow[p];
  251.     int status;
  252.     double tmp;
  253.     int today_tup = 0;
  254.  
  255.     /* always recalc OBJX and Y since we don't know it's the same object */
  256.     if (!riset_cir (p, np, p==OBJX || p==OBJY, alt2_stdhzn?STDHZN:ADPHZN,
  257.         <r, <s, <t, &azr, &azs, &altt, &status) && !force)
  258.         return;
  259.  
  260.     alt_nobody (p);
  261.  
  262.     if (status & RS_ERROR) {
  263.         /* can not find where body is! */
  264.         f_string (row, C_RISETM, "?Error?");
  265.         return;
  266.     }
  267.     if (status & RS_CIRCUMPOLAR) {
  268.         /* body is up all day */
  269.         f_string (row, C_RISETM, "Circumpolar");
  270.         if (status & RS_NOTRANS)
  271.         f_string (row, C_TRANSTM, "No transit");
  272.         else {
  273.         f_mtime (row, C_TRANSTM, ltt);
  274.         if (status & RS_2TRANS)
  275.             f_char (row, C_TRANSTM+5, '+');
  276.         f_angle (row, C_TRANSALT, altt);
  277.         }
  278.         f_string (row, C_TUP, "24:00"); /*f_mtime() changes to 0:00 */
  279.         return;
  280.     }
  281.     if (status & RS_NEVERUP) {
  282.         /* body never up at all today */
  283.         f_string (row, C_RISETM, "Never up");
  284.         f_mtime (row, C_TUP, 0.0);
  285.         return;
  286.     }
  287.  
  288.     if (status & RS_NORISE) {
  289.         /* object does not rise as such today */
  290.         f_string (row, C_RISETM, "Never rises");
  291.         ltr = 0.0; /* for TUP */
  292.         today_tup = 1;
  293.     } else {
  294.         f_mtime (row, C_RISETM, ltr);
  295.         if (status & RS_2RISES) {
  296.         /* object rises more than once today */
  297.         f_char (row, C_RISETM+5, '+');
  298.         }
  299.         f_angle (row, C_RISEAZ, azr);
  300.     }
  301.  
  302.     if (status & RS_NOTRANS)
  303.         f_string (row, C_TRANSTM, "No transit");
  304.     else {
  305.         f_mtime (row, C_TRANSTM, ltt);
  306.         if (status & RS_2TRANS)
  307.         f_char (row, C_TRANSTM+5, '+');
  308.         f_angle (row, C_TRANSALT, altt);
  309.     }
  310.  
  311.     if (status & RS_NOSET) {
  312.         /* object does not set as such today */
  313.         f_string (row, C_SETTM, "Never sets");
  314.         lts = 24.0;    /* for TUP */
  315.         today_tup = 1;
  316.     } else {
  317.         f_mtime (row, C_SETTM, lts);
  318.         if (status & RS_2SETS)
  319.         f_char (row, C_SETTM+5, '+');
  320.         f_angle (row, C_SETAZ, azs);
  321.     }
  322.  
  323.     tmp = lts - ltr;
  324.     if (tmp < 0)
  325.         tmp = 24.0 + tmp;
  326.     f_mtime (row, C_TUP, tmp);
  327.     if (today_tup)
  328.         f_char (row, C_TUP+5, '+');
  329. }
  330.  
  331. /* print body info in third menu format. this may be either the geocentric
  332.  *   or topocentric angular separation between object p and each of the others.
  333.  *   the latter, of course, includes effects of refraction and so can change
  334.  *   quite rapidly near the time of each planets rise or set.
  335.  * for now, we don't save old values so we always redo everything and ignore
  336.  *  the "force" argument. this isn't that bad since body_cir() has memory and
  337.  *   will avoid most computations as we hit them again in the lower triangle.
  338.  * we are limited to only 5 columns per object. to make it fit, we display
  339.  *   degrees:minutes if less than 100 degrees, otherwise just whole degrees.
  340.  */
  341. /*ARGSUSED*/
  342. static
  343. alt3_body (p, force, np)
  344. int p;        /* which body, as in astro.h/screen.h defines */
  345. int force;    /* whether to print for sure or only if things have changed */
  346. Now *np;
  347. {
  348.     int row = bodyrow[p];
  349.     Sky skyp, skyq;
  350.     double spy, cpy, px, *qx, *qy;
  351.     int wantx = obj_ison(OBJX);
  352.     int wanty = obj_ison(OBJY);
  353.     double as = plot_ison() || srch_ison() ? 0.0 : 60.0;
  354.     int q;
  355.  
  356.     (void) body_cir (p, as, np, &skyp);
  357.     if (alt3_geoc) {
  358.         /* use ra for "x", dec for "y". */
  359.         spy = sin (skyp.s_dec);
  360.         cpy = cos (skyp.s_dec);
  361.         px = skyp.s_ra;
  362.         qx = &skyq.s_ra;
  363.         qy = &skyq.s_dec;
  364.     } else {
  365.         /* use azimuth for "x", altitude for "y". */
  366.         spy = sin (skyp.s_alt);
  367.         cpy = cos (skyp.s_alt);
  368.         px = skyp.s_az;
  369.         qx = &skyq.s_az;
  370.         qy = &skyq.s_alt;
  371.     }
  372.     for (q = nxtbody(-1); q != -1; q = nxtbody(q))
  373.         if (q != p && (q != OBJX || wantx) && (q != OBJY || wanty)) {
  374.         double sep, dsep;
  375.         (void) body_cir (q, as, np, &skyq);
  376.         sep = acos(spy*sin(*qy) + cpy*cos(*qy)*cos(px-*qx));
  377.         dsep = raddeg(sep);
  378.         if (dsep >= (100.0 - 1.0/60.0/2.0))
  379.             f_int (row, bodycol[q], "%5d:", dsep);
  380.         else
  381.             f_angle (row, bodycol[q], sep);
  382.         }
  383. }
  384.