home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Issue 2 / Freelog_HS_3_Setp_Oct_Nov_2000_CD2.mdx / Arcade / Orbit / src / planet.c < prev    next >
C/C++ Source or Header  |  1999-09-30  |  23KB  |  976 lines

  1. /*
  2.  
  3. ORBIT, a freeware space combat simulator
  4. Copyright (C) 1999  Steve Belczyk <steve1@genesis.nred.ma.us>
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20. */
  21.  
  22. #include "orbit.h"
  23.  
  24. static float MaterialColor[] = {1.0, 1.0, 1.0, 1.0};
  25. static float specular[] = {0.0, 0.0, 0.0, 1.0};
  26. static float emission[] = {0.0, 0.0, 0.0, 1.0};
  27.  
  28. DrawPlanets()
  29. /*
  30.  *  Draw all the planets
  31.  */
  32. {
  33.     int p;
  34.  
  35.     /* Draw orbits */
  36.     if (draw_orbits) DrawOrbits();
  37.  
  38.     for (p=0; p<NPLANETS; p++)
  39.     {
  40.         if (!planet[p].hidden) DrawPlanet (p);
  41.     }
  42. }
  43.  
  44. DrawPlanet (p)
  45. int p;
  46. /*
  47.  *  Draw the pretty planet
  48.  */
  49. {
  50.     double th, r2, v[3];
  51.     int pr;
  52.  
  53.     /* Set color to white, will be modulated with texture */
  54.     if (textures)
  55.     {
  56.         glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor);
  57.         glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, MaterialColor);
  58.     }
  59.     else
  60.     {
  61.         glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, planet[p].color);
  62.         glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, planet[p].color);
  63.     }
  64.  
  65.     glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular);
  66.     glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, emission);
  67.     glMaterialf  (GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
  68.  
  69.     glPushMatrix();
  70.  
  71.     /* How far away from view is this planet? */
  72.     Vsub (v, planet[p].pos, player.pos);
  73.     planet[p].absrange2 = Mag2(v);
  74.     planet[p].range2 = r2 = planet[p].absrange2 / planet[p].radius2;
  75.  
  76.     /* Translate to where the planet is */
  77.     Vsub (v, planet[p].pos, player.pos);
  78.     glTranslated (v[0], v[1], v[2]);
  79.     th = fmod (absT, 120.0);
  80.     th = 360.0*th / 120.0;
  81.  
  82.     /* Don't bother with oblicity or rotation if it's just a point */
  83.     if (r2 < 200.0*200.0)
  84.     {
  85.         /* Planet oblicity */
  86.         glRotated (planet[p].oblicity, 1.0, 0.0, 0.0);
  87.  
  88.         /* Moons get their primary's oblicity as well */
  89.         if (planet[p].is_moon)
  90.         {
  91.             pr = planet[p].primary;
  92.             glRotated (planet[pr].oblicity, 1.0, 0.0, 0.0);
  93.         }
  94.     }
  95.  
  96.     glPushMatrix();        /* Save un-rotated matrix */
  97.  
  98.     /* Planet rotation */
  99.     if (r2 < 200.0*200.0) glRotated (th, 0.0, 0.0, 1.0);
  100.  
  101.     if (r2 < 5.0 * 5.0)
  102.     {
  103.         if (textures) glEnable (GL_TEXTURE_2D);
  104.         glBindTexture (GL_TEXTURE_2D, planet[p].texid);
  105.         glCallList (planet[p].list320);
  106.     }
  107.     else if (r2 < 25.0 * 25.0)
  108.     {
  109.         if (textures) glEnable (GL_TEXTURE_2D);
  110.         glBindTexture (GL_TEXTURE_2D, planet[p].texid);
  111.         glCallList (planet[p].list80);
  112.     }
  113.     else if (r2 < 200.0 * 200.0)
  114.     {
  115.         if (textures) glEnable (GL_TEXTURE_2D);
  116.         glBindTexture (GL_TEXTURE_2D, planet[p].texid);
  117.         glCallList (planet[p].list20);
  118.     }
  119.     else if (r2 < (5000.0 * 5000.0))
  120.     {
  121.         glDisable (GL_TEXTURE_2D);
  122.         glDisable (GL_LIGHTING);
  123.         glPointSize (2.0);
  124.         glBegin (GL_POINTS);
  125.         glColor3fv (planet[p].color);
  126.         glVertex3d (0.0, 0.0, 0.0);
  127.         glEnd();
  128.     }
  129.     else if (r2 < (50000.0 * 50000.0))
  130.     {
  131.         glDisable (GL_TEXTURE_2D);
  132.         glDisable (GL_LIGHTING);
  133.         glPointSize (1.0);
  134.         glBegin (GL_POINTS);
  135.         glColor3fv (planet[p].color);
  136.         glVertex3d (0.0, 0.0, 0.0);
  137.         glEnd();
  138.     }
  139.  
  140.     glDisable (GL_TEXTURE_2D);
  141.     glEnable (GL_LIGHTING);
  142.  
  143.     /* Pop rotate matrix */
  144.     glPopMatrix();
  145.  
  146.     glPopMatrix();
  147. }
  148.  
  149. MakePlanetLists()
  150. /*
  151.  *  Define planet display lists
  152.  */
  153. {
  154.     int p;
  155.  
  156.     for (p=0; p<NPLANETS; p++)
  157.     {
  158.         /* Sun is special */
  159.         if (p == 0)
  160.         {
  161.             MakeSunList();
  162.         }
  163.         else
  164.         {
  165.             MakePlanetList (p);
  166.         }
  167.     }
  168.  
  169.     /* Make orbit lists */
  170.     MakeOrbitLists();
  171. }
  172.  
  173. MakePlanetList (p)
  174. int p;
  175. /*
  176.  *  Make planet lists for planet p
  177.  */
  178. {
  179.     /* We make three different versions of the planet for display at various
  180.        distances */
  181.     if (glIsList (planet[p].list20)) glDeleteLists (planet[p].list20, 1);
  182.     planet[p].list20 = glGenLists (1);
  183.  
  184.     glNewList (planet[p].list20, GL_COMPILE);
  185.     maxtdiff = 0.47;
  186.     Sphere (planet[p].radius, stacks0, slices0);
  187.     glEndList();
  188.  
  189.     if (glIsList (planet[p].list80)) glDeleteLists (planet[p].list80, 1);
  190.     planet[p].list80 = glGenLists (1);
  191.  
  192.     glNewList (planet[p].list80, GL_COMPILE);
  193.     maxtdiff = 0.609384;
  194.     Sphere (planet[p].radius, stacks1, slices1);
  195.     glEndList();
  196.  
  197.     if (glIsList (planet[p].list320)) glDeleteLists (planet[p].list320, 1);
  198.     planet[p].list320 = glGenLists (1);
  199.  
  200.     glNewList (planet[p].list320, GL_COMPILE);
  201.     maxtdiff = 0.414069;
  202.     Sphere (planet[p].radius, stacks2, slices2);
  203.     glEndList();
  204. }
  205.  
  206. MakeSunList()
  207. /*
  208.  *  Make Sol's display list
  209.  */
  210. {
  211.     if (glIsList (planet[0].list20)) glDeleteLists (planet[0].list20, 1);
  212.     planet[0].list20 = glGenLists (1);
  213.  
  214.     glNewList (planet[0].list20, GL_COMPILE);
  215.     glDisable (GL_LIGHTING);
  216.     glDisable (GL_TEXTURE_2D);
  217.     glColor3d (0.8, 0.8, 0.6);
  218.     Sphere (planet[0].radius, stacks0, slices0);
  219.     glEnable (GL_TEXTURE_2D);
  220.     glEnable (GL_LIGHTING);
  221.     glEndList();
  222.  
  223.     if (glIsList (planet[0].list80)) glDeleteLists (planet[0].list80, 1);
  224.     planet[0].list80 = glGenLists (1);
  225.  
  226.     glNewList (planet[0].list80, GL_COMPILE);
  227.     glDisable (GL_LIGHTING);
  228.     glDisable (GL_TEXTURE_2D);
  229.     glColor3d (0.8, 0.8, 0.6);
  230.     Sphere (planet[0].radius, stacks1, slices1);
  231.     glEnable (GL_TEXTURE_2D);
  232.     glEnable (GL_LIGHTING);
  233.     glEndList();
  234.  
  235.     if (glIsList (planet[0].list320)) glDeleteLists (planet[0].list320, 1);
  236.     planet[0].list320 = glGenLists (1);
  237.  
  238.     glNewList (planet[0].list320, GL_COMPILE);
  239.     glDisable (GL_LIGHTING);
  240.     glDisable (GL_TEXTURE_2D);
  241.     glColor3d (0.8, 0.8, 0.6);
  242.     Sphere (planet[0].radius, stacks2, slices2);
  243.     glEnable (GL_TEXTURE_2D);
  244.     glEnable (GL_LIGHTING);
  245.     glEndList();
  246. }
  247.  
  248. ReadPlanetTexture (p)
  249. int p;
  250. /*
  251.  *  Read in the planet's texture
  252.  */
  253. {
  254.     FILE *fd;
  255.     int x, y, c, i;
  256.     char fn[64];
  257.  
  258.     /* Sun is special */
  259.     if (p == 0)
  260.     {
  261.         planet[p].color[0] = planet[p].color[1] = planet[p].color[2] = 1.0;
  262.         return;
  263.     }
  264.  
  265.     /* Zero planet average color */
  266.     planet[p].color[0] = planet[p].color[1] = planet[p].color[2] = 0.0;
  267.  
  268.     /* Get id for this texture */
  269.     if (planet[p].texid == (-1)) glGenTextures (1, &planet[p].texid);
  270.     glBindTexture (GL_TEXTURE_2D, planet[p].texid);
  271.  
  272.     glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
  273.  
  274.     /* Put up a progress message */
  275.     Mprint ("Reading %s", planet[p].texfname);
  276.     Log ("ReadPlanetTexture: Reading texture file %s", planet[p].texfname);
  277.     DrawSplash();
  278.  
  279.     /* Open file */
  280.     sprintf (fn, "maps/%s", planet[p].texfname);
  281.     if (NULL == (fd = fopen (fn, "rb")))
  282.     {
  283.         Log ("ReadPlanetTexture: Can't open %s", planet[p].texfname);
  284.         FinishSound();
  285.         CloseLog();
  286.         exit (0);
  287.     }
  288.  
  289.     /* Read past PPM header */
  290.     while (10 != fgetc(fd));
  291.     while (10 != fgetc(fd));
  292.     while (10 != fgetc(fd));
  293.  
  294.     /* Read in the color data */
  295.     for (y=0; y<256; y++)
  296.     {
  297.         for (x=0; x<256; x++)
  298.         {
  299.             for (i=0; i<3; i++)
  300.             {
  301.                 c = fgetc (fd);
  302.                 if ( (c < 0) || (c > 255) )
  303.                 {
  304.                     Log ("ReadPlanetTexture: Error reading texture file %s", planet[p].texfname);
  305.                     Log ("ReadPlanetTexture: x,y,i,c; %d %d %d %d", x, y, i, c);
  306.                     FinishSound();
  307.                     CloseLog();
  308.                     exit (0);
  309.                 }
  310.  
  311.                 planet[p].tex[255-y][x][i] = 0xff & c;
  312.                 planet[p].color[i] += (float) c;
  313.             }
  314.         }
  315.     }
  316.  
  317.     /* Compute average color */
  318.     for (i=0; i<3; i++) planet[p].color[i] /= (256.0 * 256.0 * 256.0);
  319.  
  320.     /* Set the texture */
  321.     glTexImage2D (GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, planet[p].tex);
  322.     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  323.     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  324.     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  325.     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  326.     glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  327.  
  328.     fclose (fd);
  329. }
  330.  
  331. InitPlanets()
  332. /*
  333.  *  All sorts of planet initialization
  334.  */
  335. {
  336.     int p;
  337.  
  338.     for (p=0; p<NPLANETS; p++)
  339.     {
  340.         planet[p].custom = 1;
  341.         planet[p].texid = (-1);
  342.         planet[p].orbitlist = (-1);
  343.     }
  344.  
  345.     /* Randomize theta for each planet */
  346.     RandomPlanets();
  347.  
  348.     /* Reset planets */
  349.     ResetPlanets();
  350. }
  351.  
  352. ResetPlanets()
  353. /*
  354.  *  Set planets back to the way they should be at start
  355.  */
  356. {
  357.     int p;
  358.  
  359.     p = 0;
  360.  
  361.     Log ("ResetPlanets: resetting planets");
  362.  
  363.     strcpy (planet[p].name, "Sol");
  364.     strcpy (planet[p].texfname, "sol.ppm");
  365.     planet[p].radius = 696000.000000 / KM_TO_UNITS1;
  366.     planet[p].dist = 0.000000 / KM_TO_UNITS2;
  367.     planet[p].is_moon = 0;
  368.     planet[p].primary = 0;
  369.     planet[p].oblicity = 0.0;
  370.     planet[p].angvel = 0.0;
  371.     p++;
  372.  
  373.     strcpy (planet[p].name, "Mercury");
  374.     strcpy (planet[p].texfname, "mercury.ppm");
  375.     planet[p].radius = 2440.000000 / KM_TO_UNITS1;
  376.     planet[p].dist = (realdistances ? 50.79 : 05.7900002) / KM_TO_UNITS2;
  377.     planet[p].is_moon = 0;
  378.     planet[p].primary = 0;
  379.     planet[p].angvel = 0.004166 / 87.969;
  380.     p++;
  381.  
  382.     strcpy (planet[p].name, "Venus");
  383.     strcpy (planet[p].texfname, "venus.ppm");
  384.     planet[p].radius = 6052.000000 / KM_TO_UNITS1;
  385.     planet[p].dist = (realdistances ? 108.2 : 10.8199997) / KM_TO_UNITS2;
  386.     planet[p].is_moon = 0;
  387.     planet[p].primary = 0;
  388.     planet[p].oblicity = 177.3;
  389.     planet[p].angvel = 0.004166 / 224.7;
  390.     p++;
  391.  
  392.     strcpy (planet[p].name, "Earth");
  393.     strcpy (planet[p].texfname, "earth.ppm");
  394.     planet[p].radius = 6371.000000 / KM_TO_UNITS1;
  395.     planet[p].dist = (realdistances ? 149.6 : 14.9600006) / KM_TO_UNITS2;
  396.     planet[p].is_moon = 0;
  397.     planet[p].primary = 0;
  398.     planet[p].oblicity = 23.45;
  399.     planet[p].angvel = 0.004166 / 365.256;
  400.     p++;
  401.  
  402.     strcpy (planet[p].name, "Moon");
  403.     strcpy (planet[p].texfname, "moon.ppm");
  404.     planet[p].radius = 1737.500000 / KM_TO_UNITS1;
  405.     planet[p].dist = 0.384400 / KM_TO_UNITS2;
  406.     planet[p].is_moon = 1;
  407.     planet[p].primary = 3;
  408.     planet[p].oblicity = 0.0;
  409.     planet[p].angvel = 0.004166 / 27.3;
  410.     p++;
  411.  
  412.     strcpy (planet[p].name, "Mars");
  413.     strcpy (planet[p].texfname, "mars.ppm");
  414.     planet[p].radius = 3390.000000 / KM_TO_UNITS1;
  415.     planet[p].dist = (realdistances ? 227.9 : 22.7899994) / KM_TO_UNITS2;
  416.     planet[p].is_moon = 0;
  417.     planet[p].primary = 0;
  418.     planet[p].oblicity = 25.19;
  419.     planet[p].angvel = 0.004166 / 686.98;
  420.     p++;
  421.  
  422.     strcpy (planet[p].name, "Phobos");
  423.     strcpy (planet[p].texfname, "phobos.ppm");
  424.     planet[p].radius = 13.000000 / KM_TO_UNITS1;
  425.     planet[p].dist = 0.009380 / KM_TO_UNITS2;
  426.     planet[p].is_moon = 1;
  427.     planet[p].primary = 5;
  428.     planet[p].oblicity = 0.0;
  429.     planet[p].angvel = 0.004166 / 0.319;
  430.     p++;
  431.  
  432.     strcpy (planet[p].name, "Deimos");
  433.     strcpy (planet[p].texfname, "deimos.ppm");
  434.     planet[p].radius = 8.000000 / KM_TO_UNITS1;
  435.     planet[p].dist = 0.022340 / KM_TO_UNITS2;
  436.     planet[p].is_moon = 1;
  437.     planet[p].primary = 5;
  438.     planet[p].oblicity = 0.0;
  439.     planet[p].angvel = 0.004166 / 1.262;
  440.     p++;
  441.  
  442.     strcpy (planet[p].name, "Jupiter");
  443.     strcpy (planet[p].texfname, "jupiter.ppm");
  444.     planet[p].radius = 69911.000000 / KM_TO_UNITS1;
  445. /*    planet[p].dist = 77.8400024 / KM_TO_UNITS2;    */
  446.     planet[p].dist = (realdistances ? 778.4 : 50.0) / KM_TO_UNITS2;
  447.     planet[p].is_moon = 0;
  448.     planet[p].primary = 0;
  449.     planet[p].oblicity = 3.12;
  450.     planet[p].angvel = 0.004166 / 4332.0;
  451.     p++;
  452.  
  453.     strcpy (planet[p].name, "Io");
  454.     strcpy (planet[p].texfname, "io.ppm");
  455.     planet[p].radius = 1821.000000 / KM_TO_UNITS1;
  456.     planet[p].dist = 0.421000 / KM_TO_UNITS2;
  457.     planet[p].is_moon = 1;
  458.     planet[p].primary = 8;
  459.     planet[p].oblicity = 0.0;
  460.     planet[p].angvel = 0.004166 / 1.769;
  461.     p++;
  462.  
  463.     strcpy (planet[p].name, "Europa");
  464.     strcpy (planet[p].texfname, "europa.ppm");
  465.     planet[p].radius = 1565.000000 / KM_TO_UNITS1;
  466.     planet[p].dist = 0.671000 / KM_TO_UNITS2;
  467.     planet[p].is_moon = 1;
  468.     planet[p].primary = 8;
  469.     planet[p].oblicity = 0.0;
  470.     planet[p].angvel = 0.004166 / 3.552;
  471.     p++;
  472.  
  473.     strcpy (planet[p].name, "Ganymede");
  474.     strcpy (planet[p].texfname, "ganymede.ppm");
  475.     planet[p].radius = 2634.000000 / KM_TO_UNITS1;
  476.     planet[p].dist = 1.070000 / KM_TO_UNITS2;
  477.     planet[p].is_moon = 1;
  478.     planet[p].primary = 8;
  479.     planet[p].oblicity = 0.0;
  480.     planet[p].angvel = 0.004166 / 7.155;
  481.     p++;
  482.  
  483.     strcpy (planet[p].name, "Callisto");
  484.     strcpy (planet[p].texfname, "callisto.ppm");
  485.     planet[p].radius = 2403.000000 / KM_TO_UNITS1;
  486.     planet[p].dist = 1.883000 / KM_TO_UNITS2;
  487.     planet[p].is_moon = 1;
  488.     planet[p].primary = 8;
  489.     planet[p].oblicity = 0.0;
  490.     planet[p].angvel = 0.004166 / 16.69;
  491.     p++;
  492.  
  493.     strcpy (planet[p].name, "Saturn");
  494.     strcpy (planet[p].texfname, "saturn.ppm");
  495.     planet[p].radius = 58232.000000 / KM_TO_UNITS1;
  496. /*    planet[p].dist = 142.7000000 / KM_TO_UNITS2;    */
  497.     planet[p].dist = (realdistances ? 1427.0 : 75.0) / KM_TO_UNITS2;
  498.     planet[p].is_moon = 0;
  499.     planet[p].primary = 0;
  500.     planet[p].oblicity = 26.73;
  501.     planet[p].angvel = 0.004166 / 10759.0;
  502.     p++;
  503.  
  504.     strcpy (planet[p].name, "Mimas");
  505.     strcpy (planet[p].texfname, "mimas.ppm");
  506.     planet[p].radius = 198.800003 / KM_TO_UNITS1;
  507.     planet[p].dist = 0.185000 / KM_TO_UNITS2;
  508.     planet[p].is_moon = 1;
  509.     planet[p].primary = 13;
  510.     planet[p].oblicity = 0.0;
  511.     planet[p].angvel = 0.004166 / 0.942;
  512.     p++;
  513.  
  514.     strcpy (planet[p].name, "Enceladus");
  515.     strcpy (planet[p].texfname, "enceladus.ppm");
  516.     planet[p].radius = 249.100006 / KM_TO_UNITS1;
  517.     planet[p].dist = 0.238000 / KM_TO_UNITS2;
  518.     planet[p].is_moon = 1;
  519.     planet[p].primary = 13;
  520.     planet[p].oblicity = 0.0;
  521.     planet[p].angvel = 0.004166 / 1.37;
  522.     p++;
  523.  
  524.     strcpy (planet[p].name, "Tethys");
  525.     strcpy (planet[p].texfname, "tethys.ppm");
  526.     planet[p].radius = 529.900024 / KM_TO_UNITS1;
  527.     planet[p].dist = 0.294000 / KM_TO_UNITS2;
  528.     planet[p].is_moon = 1;
  529.     planet[p].primary = 13;
  530.     planet[p].oblicity = 0.0;
  531.     planet[p].angvel = 0.004166 / 1.888;
  532.     p++;
  533.  
  534.     strcpy (planet[p].name, "Dione");
  535.     strcpy (planet[p].texfname, "dione.ppm");
  536.     planet[p].radius = 560.000000 / KM_TO_UNITS1;
  537.     planet[p].dist = 0.377000 / KM_TO_UNITS2;
  538.     planet[p].is_moon = 1;
  539.     planet[p].primary = 13;
  540.     planet[p].oblicity = 0.0;
  541.     planet[p].angvel = 0.004166 / 2.737;
  542.     p++;
  543.  
  544.     strcpy (planet[p].name, "Rhea");
  545.     strcpy (planet[p].texfname, "rhea.ppm");
  546.     planet[p].radius = 764.000000 / KM_TO_UNITS1;
  547.     planet[p].dist = 0.527000 / KM_TO_UNITS2;
  548.     planet[p].is_moon = 1;
  549.     planet[p].primary = 13;
  550.     planet[p].oblicity = 0.0;
  551.     planet[p].angvel = 0.004166 / 4.518;
  552.     p++;
  553.  
  554.     strcpy (planet[p].name, "Titan");
  555.     strcpy (planet[p].texfname, "titan.ppm");
  556.     planet[p].radius = 2575.000000 / KM_TO_UNITS1;
  557.     planet[p].dist = 1.221000 / KM_TO_UNITS2;
  558.     planet[p].is_moon = 1;
  559.     planet[p].primary = 13;
  560.     planet[p].oblicity = 0.0;
  561.     planet[p].angvel = 0.004166 / 15.9;
  562.     p++;
  563.  
  564.     strcpy (planet[p].name, "Iapetus");
  565.     strcpy (planet[p].texfname, "iapetus.ppm");
  566.     planet[p].radius = 718.000000 / KM_TO_UNITS1;
  567.     planet[p].dist = 3.561000 / KM_TO_UNITS2;
  568.     planet[p].is_moon = 1;
  569.     planet[p].primary = 13;
  570.     planet[p].oblicity = 0.0;
  571.     planet[p].angvel = 0.004166 / 79.33;
  572.     p++;
  573.  
  574.     strcpy (planet[p].name, "Uranus");
  575.     strcpy (planet[p].texfname, "uranus.ppm");
  576.     planet[p].radius = 25362.000000 / KM_TO_UNITS1;
  577. /*    planet[p].dist = 287.1000000 / KM_TO_UNITS2;    */
  578.     planet[p].dist = (realdistances ? 2871.0 : 100.0) / KM_TO_UNITS2;
  579.     planet[p].is_moon = 0;
  580.     planet[p].primary = 0;
  581.     planet[p].oblicity = 97.86;
  582.     planet[p].angvel = 0.004166 / 30685.0;
  583.     p++;
  584.  
  585.     strcpy (planet[p].name, "Miranda");
  586.     strcpy (planet[p].texfname, "miranda.ppm");
  587.     planet[p].radius = 235.000000 / KM_TO_UNITS1;
  588.     planet[p].dist = 0.130000 / KM_TO_UNITS2;
  589.     planet[p].is_moon = 1;
  590.     planet[p].primary = 21;
  591.     planet[p].oblicity = 0.0;
  592.     planet[p].angvel = 0.004166 / 1.413;
  593.     p++;
  594.  
  595.     strcpy (planet[p].name, "Ariel");
  596.     strcpy (planet[p].texfname, "ariel.ppm");
  597.     planet[p].radius = 580.000000 / KM_TO_UNITS1;
  598.     planet[p].dist = 0.191000 / KM_TO_UNITS2;
  599.     planet[p].is_moon = 1;
  600.     planet[p].primary = 21;
  601.     planet[p].oblicity = 0.0;
  602.     planet[p].angvel = 0.004166 / 2.52;
  603.     p++;
  604.  
  605.     strcpy (planet[p].name, "Umbriel");
  606.     strcpy (planet[p].texfname, "umbriel.ppm");
  607.     planet[p].radius = 585.000000 / KM_TO_UNITS1;
  608.     planet[p].dist = 0.266000 / KM_TO_UNITS2;
  609.     planet[p].is_moon = 1;
  610.     planet[p].primary = 21;
  611.     planet[p].oblicity = 0.0;
  612.     planet[p].angvel = 0.004166 / 4.144;
  613.     p++;
  614.  
  615.     strcpy (planet[p].name, "Titania");
  616.     strcpy (planet[p].texfname, "titania.ppm");
  617.     planet[p].radius = 789.000000 / KM_TO_UNITS1;
  618.     planet[p].dist = 0.436000 / KM_TO_UNITS2;
  619.     planet[p].is_moon = 1;
  620.     planet[p].primary = 21;
  621.     planet[p].oblicity = 0.0;
  622.     planet[p].angvel = 0.004166 / 8.706;
  623.     p++;
  624.  
  625.     strcpy (planet[p].name, "Oberon");
  626.     strcpy (planet[p].texfname, "oberon.ppm");
  627.     planet[p].radius = 761.000000 / KM_TO_UNITS1;
  628.     planet[p].dist = 0.583000 / KM_TO_UNITS2;
  629.     planet[p].is_moon = 1;
  630.     planet[p].primary = 21;
  631.     planet[p].oblicity = 0.0;
  632.     planet[p].angvel = 0.004166 / 13.463;
  633.     p++;
  634.  
  635.     strcpy (planet[p].name, "Neptune");
  636.     strcpy (planet[p].texfname, "neptune.ppm");
  637.     planet[p].radius = 24766.000000 / KM_TO_UNITS1;
  638. /*    planet[p].dist = 449.8000000 / KM_TO_UNITS2;    */
  639.     planet[p].dist = (realdistances ? 4498.0 : 125.0) / KM_TO_UNITS2;
  640.     planet[p].is_moon = 0;
  641.     planet[p].primary = 0;
  642.     planet[p].oblicity = 29.56;
  643.     planet[p].angvel = 0.004166 / 60189.0;
  644.     p++;
  645.  
  646.     strcpy (planet[p].name, "Triton");
  647.     strcpy (planet[p].texfname, "triton.ppm");
  648.     planet[p].radius = 1352.599976 / KM_TO_UNITS1;
  649.     planet[p].dist = 0.355000 / KM_TO_UNITS2;
  650.     planet[p].is_moon = 1;
  651.     planet[p].primary = 27;
  652.     planet[p].oblicity = 0.0;
  653.     planet[p].angvel = 0.004166 / -5.877;
  654.     p++;
  655.  
  656.     strcpy (planet[p].name, "Proteus");
  657.     strcpy (planet[p].texfname, "proteus.ppm");
  658.     planet[p].radius = 218.000000 / KM_TO_UNITS1;
  659.     planet[p].dist = 0.118000 / KM_TO_UNITS2;
  660.     planet[p].is_moon = 1;
  661.     planet[p].primary = 27;
  662.     planet[p].oblicity = 0.0;
  663.     planet[p].angvel = 0.004166 / 1.122;
  664.     p++;
  665.  
  666.     strcpy (planet[p].name, "Pluto");
  667.     strcpy (planet[p].texfname, "pluto.ppm");
  668.     planet[p].radius = 1137.000000 / KM_TO_UNITS1;
  669. /*    planet[p].dist = 590.6000000 / KM_TO_UNITS2;    */
  670.     planet[p].dist = (realdistances ? 5906.0 : 150.0) / KM_TO_UNITS2;
  671.     planet[p].is_moon = 0;
  672.     planet[p].primary = 0;
  673.     planet[p].oblicity = 122.0;
  674.     planet[p].angvel = 0.004166 / 90465.0;
  675.     p++;
  676.  
  677.     strcpy (planet[p].name, "Charon");
  678.     strcpy (planet[p].texfname, "charon.ppm");
  679.     planet[p].radius = 586.000000 / KM_TO_UNITS1;
  680.     planet[p].dist = 0.019000 / KM_TO_UNITS2;
  681.     planet[p].is_moon = 1;
  682.     planet[p].primary = 30;
  683.     planet[p].oblicity = 0.0;
  684.     planet[p].angvel = 0.004166 / 6.387;
  685.     p++;
  686.  
  687.     /* Randomize planet positions */
  688.     PositionPlanets();
  689.  
  690.     /* Read textures, etc */
  691.     for (p=0; p<NPLANETS; p++)
  692.     {
  693.         if (planet[p].custom)
  694.         {
  695.             ReadPlanetTexture (p);
  696.             planet[p].custom = 0;
  697.         }
  698.  
  699.         planet[p].radius2 = planet[p].radius * planet[p].radius;
  700.         planet[p].hidden = 0;
  701.  
  702.         /* Set planet's mass */
  703.         planet[p].mass = planet[p].radius * planet[p].radius * planet[p].radius;
  704.     }
  705.  
  706.     /* Define planet display lists */
  707.     MakePlanetLists();
  708. }
  709.  
  710. RandomPlanets()
  711. /*
  712.  *  Randomly set solar angle for each planet
  713.  */
  714. {
  715.     int p;
  716.  
  717.     Log ("RandomPlanets: Randomizing planets");
  718.  
  719.     for (p=0; p<NPLANETS; p++)
  720.     {
  721.         planet[p].theta = 2.0 * rnd (6.28);
  722.     }
  723. }
  724.  
  725. PositionPlanets()
  726. /*
  727.  *  Turn planet angles into Cartesian coordinates
  728.  */
  729. {
  730.     int p, pr;
  731.     double th, v[3], v1[3];
  732.  
  733.     /* Position the planets */
  734.     for (p=0; p<NPLANETS; p++)
  735.     {
  736.         th = planet[p].theta;
  737.  
  738.         planet[p].pos[0] = planet[p].dist * sin (th);
  739.         planet[p].pos[1] = planet[p].dist * cos (th);
  740.         planet[p].pos[2] = 0.0;
  741.  
  742.         /* If moon, compute absolute position based on primary's
  743.            position and oblicity */
  744.         if (planet[p].is_moon)
  745.         {
  746.             pr = planet[p].primary;
  747.             th = -planet[pr].oblicity * 3.1415926535 / 180.0;
  748.             v[0] = 1.0;
  749.             v[1] = 0.0;
  750.             v[2] = 0.0;
  751.             RotateAbout (v1, planet[p].pos, v, th);
  752.             Vset (planet[p].pos, v1);
  753.             Vadd (planet[p].pos, planet[p].pos, planet[pr].pos);
  754.         }
  755.     }
  756. }
  757.  
  758. int InsidePlanet (v)
  759. double v[3];
  760. /*
  761.  *  Check if v is inside a planet.  If yes, return planet
  762.  *  index, else -1
  763.  */
  764. {
  765.     int p;
  766.     double v1[3], r2;
  767.  
  768.     for (p=0; p<NPLANETS; p++)
  769.     {
  770.         if (!planet[p].hidden)
  771.         {
  772.             Vsub (v1, v, planet[p].pos);
  773.             r2 = Mag2 (v1);
  774.  
  775.             /* Inside? */
  776.             if (r2 < planet[p].radius2)
  777.             {
  778.                 /* Yep */
  779.                 return (p);
  780.             }
  781.         }
  782.     }
  783.  
  784.     /* Nope */
  785.     return (-1);
  786. }
  787.  
  788. ShowPlanetNames()
  789. {
  790.     int p;
  791.     unsigned char v;
  792.     double v1[3];
  793.     char buf[128];
  794.  
  795.     for (p=0; p<NPLANETS; p++)
  796.     {
  797.         if (!planet[p].hidden)
  798.         {
  799.             if (planet[p].is_moon)
  800.                 glColor3d (0.0, 0.8, 0.8);
  801.             else
  802.                 glColor3d (0.0, 0.0, 0.8);
  803.  
  804.             Vsub (v1, planet[p].pos, player.pos);
  805.             glRasterPos3dv (v1);
  806.             glGetBooleanv (GL_CURRENT_RASTER_POSITION_VALID, &v);
  807.             if (v)
  808.             {
  809.                 if (!planet[p].is_moon)
  810.                 {
  811.                     if (planet[p].absrange2 < 100.0*planet[p].radius*planet[p].radius)
  812.                     {
  813.                         sprintf (buf, "%s:%.0lf", planet[p].name,
  814.                             KM_TO_UNITS1*(sqrt(planet[p].absrange2)-planet[p].radius));
  815.                     }
  816.                     else
  817.                     {
  818.                         strcpy (buf, planet[p].name);
  819.                     }
  820.                     Print (GLUT_BITMAP_HELVETICA_10, buf);
  821.                 }
  822.                 else
  823.                 {
  824.                     if (planet[p].range2 < (2000.0 * 2000.0))
  825.                     {
  826.                         if (planet[p].absrange2 < 100.0*planet[p].radius*planet[p].radius)
  827.                         {
  828.                             sprintf (buf, "%s:%.0lf", planet[p].name,
  829.                                 KM_TO_UNITS1*(sqrt(planet[p].absrange2)-planet[p].radius));
  830.                         }
  831.                         else
  832.                         {
  833.                             strcpy (buf, planet[p].name);
  834.                         }
  835.                         Print (GLUT_BITMAP_HELVETICA_10, buf);
  836.                     }
  837.                 }
  838.             }
  839.         }
  840.     }
  841. }
  842.  
  843. Sphere (r, slices, sectors)
  844. double r;
  845. int slices, sectors;
  846. {
  847.     GLUquadricObj *obj;
  848.  
  849.     obj = gluNewQuadric();
  850.     
  851.     gluQuadricDrawStyle (obj, GLU_FILL);
  852.     gluQuadricNormals (obj, GLU_SMOOTH);
  853.     gluQuadricTexture (obj, GL_TRUE);
  854.     gluSphere (obj, (float)r, sectors, slices);
  855. }
  856.  
  857. int FindPlanetByName (c)
  858. char *c;
  859. /*
  860.  *  Find planet given name, else -1
  861.  */
  862. {
  863.     int p;
  864.  
  865.     for (p=0; p<NPLANETS; p++)
  866.     {
  867.         if (!strcasecmp (c, planet[p].name)) return (p);
  868.     }
  869.  
  870.     return (-1);
  871. }
  872.  
  873. MakeOrbitLists()
  874. /*
  875.  *  Construct display lists for orbits
  876.  */
  877. {
  878.     int p;
  879.     double th, d, s, c;
  880.  
  881.     d = 360.0 / ((double) ORBIT_SECTORS);
  882.  
  883.     /* Loop through planets */
  884.     for (p=1; p<NPLANETS; p++)
  885.     {
  886.         /* Delete old list */
  887.         if (glIsList (planet[p].orbitlist)) glDeleteLists (planet[p].orbitlist, 1);
  888.  
  889.         /* Make new list */
  890.         planet[p].orbitlist = glGenLists (1);
  891.         glNewList (planet[p].orbitlist, GL_COMPILE);
  892.  
  893.         glBegin (GL_LINE_LOOP);
  894.  
  895.         /* Set color */
  896.         if (planet[p].is_moon)
  897.         {
  898.             glColor3f (0.0, 0.8, 0.8);
  899.         }
  900.         else
  901.         {
  902.             glColor3f (0.0, 0.0, 1.0);
  903.         }
  904.  
  905.         /* Loop through circle */
  906.         for (th=0.0; th<360.0; th+=d)
  907.         {
  908.             s = sin (th*3.1415926535/180.0);
  909.             c = cos (th*3.1415926535/180.0);
  910.  
  911.             glVertex3d (planet[p].dist*s, planet[p].dist*c, 0.0);
  912.         }
  913.  
  914.         glEnd();
  915.         glEndList();
  916.     }
  917. }
  918.  
  919. DrawOrbits()
  920. /*
  921.  *  Draw orbital paths
  922.  */
  923. {
  924.     int p;
  925.     double v[3];
  926.  
  927.     glDisable (GL_TEXTURE_2D);
  928.     glDisable (GL_LIGHTING);
  929.  
  930.     glPushMatrix();
  931.     Vsub (v, planet[0].pos, player.pos);
  932.     glTranslated (v[0], v[1], v[2]);
  933.  
  934.     for (p=1; p<NPLANETS; p++)
  935.     {
  936.         if (!planet[p].hidden)
  937.         {
  938.             if (planet[p].is_moon)
  939.             {
  940.                 if (planet[planet[p].primary].range2 > 200.0*200.0) continue;
  941.  
  942.                 glPushMatrix();
  943.                 Vsub (v, player.pos, planet[0].pos);
  944.                 glTranslated (v[0], v[1], v[2]);
  945.  
  946.                 Vsub (v, planet[planet[p].primary].pos, player.pos);
  947.                 glTranslated (v[0], v[1], v[2]);
  948.  
  949.                 glRotated (planet[planet[p].primary].oblicity, 1.0, 0.0, 0.0);
  950.             }
  951.             glCallList (planet[p].orbitlist);
  952.             if (planet[p].is_moon) glPopMatrix();
  953.         }
  954.     }
  955.  
  956.     glPopMatrix();
  957. }
  958.  
  959. MovePlanets()
  960. /*
  961.  *  Move planets in their orbits
  962.  */
  963. {
  964.     int p;
  965.  
  966.     for (p=1; p<NPLANETS; p++)
  967.     {
  968.         planet[p].theta -= planet[p].angvel * deltaT * compression
  969.                            * 3.1415926535 / 180.0;
  970.         if (planet[p].theta < 0.0) planet[p].theta += 2.0 * 3.1415926535;
  971.     }
  972.  
  973.     PositionPlanets();
  974. }
  975.  
  976.