home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Issue 2 / Freelog_HS_3_Setp_Oct_Nov_2000_CD2.mdx / Arcade / Orbit / src / orbit.c < prev    next >
C/C++ Source or Header  |  1999-10-02  |  14KB  |  708 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. #define ALLOCATE
  23. #include "orbit.h"
  24.  
  25. int tm, frames, total_frames;
  26.  
  27. main (argc, argv)
  28. int argc;
  29. char *argv[];
  30. {
  31.     /* Kick random number generator */
  32.     srand (time(NULL));
  33.  
  34.     /* Check for joystick */
  35.     InitJoy();
  36.  
  37.     /* Init the performance timer */
  38.     InitTimer();
  39.  
  40.     /* Set up the player viewpoint, etc */
  41.     InitPlayer();
  42.  
  43.     /* Initialize all sorts of other stuff */
  44.     InitStuff();
  45.  
  46.     /* Open a window */
  47.     OpenWindow (argc, argv);
  48.  
  49.     frames = 0;
  50.     total_frames = 1;
  51.     tm = time(NULL);
  52.  
  53.     /* Loop forever */
  54.     glutMainLoop();
  55. }
  56.  
  57. OpenWindow (argc, argv)
  58. int argc;
  59. char *argv[];
  60. /*
  61.  *  Open a window
  62.  */
  63. {
  64.     char *p;
  65.  
  66.     glutInit (&argc, argv);
  67.     glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  68.  
  69.     glutInitWindowPosition (0, 0);
  70.     glutInitWindowSize (ScreenWidth, ScreenHeight);
  71.  
  72.     if (!strcasecmp (gamemode, "no"))
  73.     {
  74.         glutCreateWindow ("Orbit");
  75.     }
  76.     else
  77.     {
  78.         glutGameModeString (gamemode);
  79.         glutEnterGameMode();
  80.     }
  81.  
  82.     if (fullscreen) glutFullScreen ();
  83.  
  84.     glutDisplayFunc (DrawScene);
  85.     glutReshapeFunc (Reshape);
  86.  
  87.     /* Define lights, etc */
  88.     Lights();
  89.     glEnable (GL_DEPTH_TEST);
  90.     glEnable (GL_CULL_FACE);
  91.  
  92.     /* Put up some driver info */
  93.     p = (char *) glGetString (GL_VENDOR);
  94.     Log ("OpenWindow: OpenGL vendor: %s", p);
  95.     p = (char *) glGetString (GL_RENDERER);
  96.     Log ("OpenWindow: OpenGL renderer: %s", p);
  97.     p = (char *) glGetString (GL_VERSION);
  98.     Log ("OpenWindow: OpenGL version: %s", p);
  99. }
  100.  
  101. CreateUniverse ()
  102. /*
  103.  *  And Then There Was Light
  104.  */
  105. {
  106.     /* Initialize keyboard */
  107.     InitKeyboard();
  108.  
  109.     /* Initialize the mouse */
  110.     InitMouse();
  111.  
  112.     /* Construct the starfield display list */
  113.     MakeStarList();
  114.  
  115.     /* Initialize planets */
  116.     InitPlanets();
  117.  
  118.     /* Init AC3D textures */
  119.     InitTextures();
  120.  
  121.     /* Ring stuff */
  122.     InitRings();
  123.  
  124.     /* Init the HUD */
  125.     InitHud();
  126.  
  127.     /* Initialize sound */
  128.     InitSound();
  129.  
  130.     /* Initialize the network */
  131.     InitNetwork();
  132.  
  133.     /* Okay, load a mission */
  134.     if (mission.fn[0] != 0)
  135.     {
  136.         /* Load mission from prefs file */
  137.         ReadMission (mission.fn);
  138.     }
  139.     else
  140.     {
  141.         /* Read default mission */
  142.         ReadMission ("train01.msn");
  143.     }
  144. }
  145.  
  146. void DrawScene()
  147. /*
  148.  *  Draw the scene
  149.  */
  150. {
  151.     double v[3], t;
  152.  
  153. /*    if (am_client) Log ("!!! DrawScene()");    */
  154.  
  155.     /* Are we still initializing? */
  156.     if (state == STATE_INIT)
  157.     {
  158.         /* Create everything */
  159.         CreateUniverse();
  160.  
  161.         /* Mark new state */
  162.         state = STATE_NORMAL;
  163.     }
  164.  
  165.     /* Figure out how many seconds (in deltaT) have elapsed since the last
  166.        time we were here */
  167. /*    if (am_client) Log ("!!! DeltaTime()");    */
  168.     DeltaTime();
  169.  
  170.     /* Handle the network */
  171. /*    if (am_client) Log ("!!! DoNetwork()");    */
  172.     DoNetwork();
  173.  
  174.     /* Read the keyboard */
  175. /*    if (am_client) Log ("!!! Keyboard()");    */
  176.     Keyboard();
  177.  
  178.     /* Handle the joystick */
  179. /*    if (am_client) Log ("!!! Joystick()");    */
  180.     if (joy_available && !paused) JoyStick();
  181.  
  182.     /* Do the mouse */
  183. /*    if (am_client) Log ("!!! DoMouse()");    */
  184.     if (mouse_control && !paused) DoMouse();
  185.  
  186.     /* Move the planets */
  187.     if (orbit) MovePlanets();
  188.  
  189.     /* Move the player */
  190. /*    if (am_client) Log ("!!! UpdatePlayer()");    */
  191.     if (!paused) UpdatePlayer ();
  192.  
  193.     /* Move the targets */
  194. /*    if (am_client) Log ("!!! MoveTargets()");    */
  195.     if (!paused) MoveTargets ();
  196.  
  197.     /* Move the missiles */
  198. /*    if (am_client) Log ("!!! MoveMissiles()");    */
  199.     if (!paused) MoveMissiles ();
  200.  
  201.     /* Process any outstanding events */
  202. /*    if (am_client) Log ("!!! DoEvents()");    */
  203.     DoEvents();
  204.  
  205.     /* Clear the screen */
  206.     if (palette_flash == 2)
  207.     {
  208.         /* Flash red */
  209.         palette_flash = 0;
  210.         glClearColor (1.0, 0.0, 0.0, 0.0);
  211.     }
  212.     else if (palette_flash > 0)
  213.     {
  214.         /* Flash white */
  215.         palette_flash = 0;
  216.         glClearColor (1.0, 1.0, 1.0, 0.0);
  217.     }
  218.     else
  219.     {
  220.         glClearColor (0.0, 0.0, 0.0, 0.0);
  221.     }
  222.     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  223.  
  224.     /* Set up viewing transformation */
  225.     glMatrixMode (GL_MODELVIEW);
  226.     glLoadIdentity();
  227.  
  228.     /* Compute a point along line of sight */
  229.     Vadd (v, player.pos, player.view);
  230.  
  231.     gluLookAt (0.0, 0.0, 0.0,
  232.         player.view[0], player.view[1], player.view[2],
  233.         player.up[0], player.up[1], player.up[2]);
  234.  
  235.     /* Draw the star field here */
  236.     if (starfield) DrawStars();
  237.  
  238.     Lights();
  239.  
  240.     /* Draw the world */
  241. /*    if (am_client) Log ("!!! DrawWorld()");    */
  242.     DrawWorld();
  243.  
  244.     /* Do some 2-D stuff just to prove I can */
  245. /*    if (am_client) Log ("!!! Hud()");    */
  246.     Hud();
  247.  
  248.     /* Swap buffers */
  249.     glFlush();
  250.     glutSwapBuffers();
  251.  
  252.     /* Keep on Displayin' */
  253.     glutPostRedisplay();
  254.  
  255.     frames++;
  256.     total_frames++;
  257.     if (0 == (frames % 50))
  258.     {
  259.         t = Time();
  260.  
  261.         fps = 50.0 / t;
  262.         frames = 0;
  263.  
  264.         recv_bps = ((double) recv_bytes) / t;
  265.         xmit_bps = ((double) xmit_bytes) / t;
  266.         recv_bytes = xmit_bytes = 0;
  267.  
  268.         tm = time (NULL);
  269.     }
  270. }
  271.  
  272. void DrawSplash()
  273. /*
  274.  *  Draw minimal screen for startup splash
  275.  */
  276. {
  277.     double v[3];
  278.     int tmphud;
  279.  
  280.     Reshape (ScreenWidth, ScreenHeight);
  281.  
  282.     glClearColor (0.0, 0.0, 0.0, 0.0);
  283.     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  284.  
  285.     /* Set up viewing transformation */
  286.     glMatrixMode (GL_MODELVIEW);
  287.     glLoadIdentity();
  288.  
  289.     /* Compute a point along line of sight */
  290.     Vadd (v, player.pos, player.view);
  291.  
  292.     gluLookAt (player.pos[0], player.pos[1], player.pos[2],
  293.         v[0], v[1], v[2],
  294.         player.up[0], player.up[1], player.up[2]);
  295.  
  296.     /* Draw the star field here */
  297. /*    if (starfield) DrawStars();    */
  298.  
  299.     /* Do some 2-D stuff just to prove I can */
  300.     tmphud = drawhud;
  301.     drawhud = 0;
  302.     Hud();
  303.     drawhud = tmphud;
  304.  
  305.     /* Swap buffers */
  306.     glFlush();
  307.     glutSwapBuffers();
  308.  
  309.     /* Keep on Displayin' */
  310.     glutPostRedisplay();
  311. }
  312.  
  313. void Reshape (w, h)
  314. GLsizei w, h;
  315. {
  316.     double ratio;
  317.  
  318.     ScreenWidth = w;
  319.     ScreenHeight = h;
  320.     ratio = (double) w / (double) h;
  321.  
  322.     glMatrixMode (GL_PROJECTION);
  323.     glLoadIdentity();
  324.     gluPerspective (fov, ratio, clipnear, clipfar);
  325.     glMatrixMode (GL_MODELVIEW);
  326.     glViewport (0, 0, w, h);
  327.  
  328.     /* Recompute the HUD stuff */
  329.     InitHud();
  330. }
  331.  
  332. static float MaterialColor[] = {1.0, 1.0, 1.0, 1.0};
  333. static float JunkColor[] = {0.7, 0.7, 0.7, 1.0};
  334. static double MissileColor[] = {1.0, 1.0, 0.0, 1.0};
  335. static float TargetColor[] = {1.0, 0.5, 0.0, 1.0};
  336.  
  337. DrawWorld ()
  338. /*
  339.  *  Draw the world
  340.  */
  341. {
  342.     /* Draw planet */
  343.     DrawPlanets();
  344.  
  345.     /* Draw space junk */
  346.     if (junk)
  347.     {
  348.         glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, JunkColor);
  349.         Junk();
  350.     }
  351.  
  352.     /* Draw missiles */
  353.     DrawMissiles ();
  354.  
  355.     /* Draw targets */
  356.     DrawTargets();
  357.  
  358.     /* Draw explosions */
  359.     DrawBooms ();
  360.  
  361.     /* Draw planetary rings */
  362.     DrawRings();
  363.  
  364.     /* Show names of things */
  365.     if (show_names) ShowNames();
  366. }
  367.  
  368. Print (font, string)
  369. void *font;
  370. char *string;
  371. {
  372.     int len, i;
  373.  
  374.     len = strlen (string);
  375.     for (i=0; i<len; i++)
  376.     {
  377.         glutBitmapCharacter (font, string[i]);
  378.     }
  379. }
  380.  
  381. InitStuff()
  382. /*
  383.  *  Misc initilization
  384.  *
  385.  *  DON'T PUT ANY OPENGL STUFF IN HERE!  THE WINDOW HASN'T EVEN BEEN OPENED YET!!!
  386.  */
  387. {
  388.     vulnerable = 1;
  389.     joy_throttle = 0;
  390.     deadzone = DEADZONE;
  391.     absT = 0.0;
  392.     starfield = 1;
  393.     drawhud = 1;
  394.     showfps = 0;
  395.     gravity = 0;
  396.     junk = 1;
  397.     palette_flash = 0;
  398.     sound = 1;
  399.     show_names = 0;
  400.     screen_shot_num = 0;
  401.     rings = 1;
  402.     textures = 1;
  403.     mission.fn[0] = 0;
  404.     paused = 0;
  405.     mouse_control = 1;
  406.     strcpy (gamemode, "no");
  407.     fullscreen = 0;
  408.     player.flightmodel = FLIGHT_NEWTONIAN;
  409.     strcpy (player.name, "Sparky");
  410.     strcpy (player.model, "light2.tri");
  411.     ring_sectors = RING_SECTORS;
  412.     stacks0 = 3;
  413.     slices0 = 7;
  414.     stacks1 = 6;
  415.     slices1 = 13;
  416.     stacks2 = 12;
  417.     slices2 = 24;
  418.     mouse.flipx = 0;
  419.     mouse.flipy = 0;
  420.     state = STATE_INIT;
  421.     realdistances = 0;
  422.     fov = 90.0;
  423.     text.yes = 0;
  424.     text.buf[0] = 0;
  425.     text.index = 0;
  426.     text.prompt[0] = 0;
  427.     text.func = NULL;
  428.     fullstop = 1;
  429.     player.still = 1;
  430.     draw_orbits = 0;
  431.     orbit = 0;
  432.     compression = 1.0;
  433.     player.viewlock = 0.0;
  434.     server.port = ORBIT_PORT;
  435.     superwarp = 1;
  436.     clipnear = 0.01;
  437.     clipfar = 100000.0;
  438. /*    clipnear = 0.001;
  439.     clipfar = 100000.0; */
  440.  
  441.     /* Set initial screen size */
  442.     ScreenWidth = SCREENWIDTH;
  443.     ScreenHeight = SCREENHEIGHT;
  444.  
  445.     /* Initialize the log file */
  446.     InitLog();
  447.  
  448.     Log ("InitStuff: ORBIT Version %s", VERSION);
  449.  
  450.     /* Read the preferences file */
  451.     ReadPrefs();
  452.  
  453.     /* Read stars data file */
  454.     ReadStars();
  455.  
  456.     /* Initialize the message console */
  457.     InitConsole();
  458.  
  459.     /* Initialize the message system */
  460.     InitMessage();
  461.  
  462.     /* Initialize the object models */
  463.     InitModels();
  464.  
  465.     /* Initialize the missiles */
  466.     InitMissiles();
  467.  
  468.     /* Weapons */
  469.     InitWeapons();
  470.  
  471.     /* Initialize explosions */
  472.     InitBooms();
  473.  
  474.     /* Initialize lights */
  475.     InitLights();
  476.  
  477.     /* Initialize targets */
  478.     InitTargets();
  479.  
  480.     /* Initialize events */
  481.     InitEvents();
  482.  
  483.     /* Self-promotion */
  484.     Cprint ("Orbit %s, by Steve Belczyk <orbit@genesis.nred.ma.us>", VERSION);
  485.     Cprint ("http://genesis.ne.mediaone.net/orbit");
  486. }
  487.  
  488. double Theta (v)
  489. double v[3];
  490. /*
  491.  *  Compute angle vector v points to
  492.  */
  493. {
  494.     double th;
  495.  
  496.     th = (double) acos ((double) v[0]);
  497.     th = th * 180.0 / 3.14159;
  498.     if (v[1] < 0.0) th = (-th);
  499.  
  500.     return (th);
  501. }
  502.  
  503. #ifdef WIN32MOUSE
  504. Mouse()
  505. /*
  506.  *  Process the mouse
  507.  */
  508. {
  509.     GetCursorPos (&point);
  510.     mouse_x = point.x;
  511.     mouse_y = point.y;
  512.  
  513.     if (mouse_x > last_mouse_x) player.move_right = 1.0;
  514.     if (mouse_x < last_mouse_x) player.move_left = 1.0;
  515.     if (mouse_y > last_mouse_y) player.move_up = 1.0;
  516.     if (mouse_y < last_mouse_y) player.move_down = 1.0;
  517.  
  518.     last_mouse_x = last_mouse_y = 400;
  519.  
  520.     SetCursorPos (400, 400);
  521. }
  522. #endif
  523.  
  524. Gravity (deltav, pos)
  525. double deltav[3], pos[3];
  526. /*
  527.  *  Compute change in velocity due to planet's gravity
  528.  */
  529. {
  530.     double r, rr, dv, dp[3], v[3];
  531.     int p;
  532.  
  533.     deltav[0] = deltav[1] = deltav[2] = 0.0;
  534.  
  535.     for (p=0; p<NPLANETS; p++)
  536.     {
  537.         /* Distance to planet */
  538.         Vsub (dp, planet[p].pos, pos);
  539.  
  540.         rr = Mag2 (dp);
  541.  
  542.         /* Ignore planets too far away */
  543.         if (rr > 200.0*200.0) continue;
  544.  
  545.         /* Don't stand so close to me */
  546.         if (rr < RMIN) rr = RMIN;
  547.  
  548.         r = sqrt (rr);
  549.         dv = G * planet[p].mass / rr;
  550.  
  551.         Vmul (v, dp, dv);
  552.         Vdiv (v, v, r);
  553.  
  554.         Vadd (deltav, deltav, v);
  555.     }
  556. }
  557.  
  558. Junk()
  559. /*
  560.  *  Draw space junk to give visual cues of motion
  561.  */
  562. {
  563.     double x, y, z;
  564.  
  565.     glDisable (GL_LIGHTING);
  566.     glDisable (GL_CULL_FACE);
  567.     glColor3d (0.5, 0.5, 0.5);
  568.  
  569.     x = (double) (int) player.pos[0];
  570.     y = (double) (int) player.pos[1];
  571.     z = (double) (int) player.pos[2];
  572.  
  573.     PieceOfJunk (x+0.5, y+0.5, z+0.5);
  574.     PieceOfJunk (x-0.5, y+0.5, z+0.5);
  575.     PieceOfJunk (x-0.5, y-0.5, z+0.5);
  576.     PieceOfJunk (x+0.5, y-0.5, z+0.5);
  577.  
  578.     PieceOfJunk (x+0.5, y+0.5, z-0.5);
  579.     PieceOfJunk (x-0.5, y+0.5, z-0.5);
  580.     PieceOfJunk (x-0.5, y-0.5, z-0.5);
  581.     PieceOfJunk (x+0.5, y-0.5, z-0.5);
  582.  
  583.     glEnable (GL_CULL_FACE);
  584.     glEnable (GL_LIGHTING);
  585. }
  586.  
  587. PieceOfJunk (x, y, z)
  588. double x, y, z;
  589. /*
  590.  *  Draw a single piece of space junk
  591.  */
  592. {
  593.     double r, v1[3], v2[3];
  594.  
  595.     glPushMatrix();
  596.  
  597.     /* Figure how much to spin junk */
  598.     r = absT - ((double)(int)absT);
  599.     r = 360.0 * r;
  600.  
  601.     /* Draw the junk */
  602.     v1[0] = x; v1[1] = y; v1[2] = z;
  603.     Vsub (v2, v1, player.pos);
  604.     glTranslated (v2[0], v2[1], v2[2]);
  605.  
  606.     glRotated (r, 0.0, 1.0, 0.0);
  607.     glBegin (GL_POLYGON);
  608.     glNormal3d (0.0, 0.0, 1.0);
  609.     glVertex3d (-.003, -.003, 0.0);
  610.     glVertex3d (.003, -.003, 0.0);
  611.     glVertex3d (0.0, .003, 0.0);
  612.     glEnd();
  613.  
  614.     glPopMatrix();
  615. }
  616.  
  617. ShowNames()
  618. /*
  619.  *  Show the names of things
  620.  */
  621. {
  622.     glDisable (GL_DEPTH_TEST);
  623.     glDisable (GL_LIGHTING);
  624.     ShowPlanetNames();
  625.     ShowTargetNames();
  626.     glEnable (GL_LIGHTING);
  627.     glEnable (GL_DEPTH_TEST);
  628. }
  629.  
  630. LookAt (view, up)
  631. double view[3], up[3];
  632. /*
  633.  *  Set up a transformation so a model will be drawn pointing the
  634.  *  right direction (view) and upright (up)
  635.  */
  636. {
  637.     double v1[3], v2[3], cos, th, thd, up2[3];
  638.  
  639.     /*
  640.      *  This thing is really ugly and inefficient.  It does sqrt's,
  641.      *  sin's, cos's, acos's, and asin's like there's no tomorrow.
  642.      *
  643.      *  In theory we should be able to build a little matrix like
  644.      *  gluLookAt() does, but I could never get that to work.  I
  645.      *  suspect what's needed is the inverse or transpose of the
  646.      *  gluLookAt() matrix, but I don't understand linear algebra
  647.      *  well enough to know.
  648.      *
  649.      *  If you can improve this thing please let me know.
  650.      */
  651.  
  652.     /* Make vector along positive X axis */
  653.     v1[0] = 1.0;
  654.     v1[1] = 0.0;
  655.     v1[2] = 0.0;
  656.  
  657.     /* Cross-product of X-axis and view vector is vector to
  658.        rotate about */
  659.     Crossp (v2, v1, view);
  660.  
  661.     /* Check for special case of null v2 (vectors are the same) */
  662.     if (0.0 == Mag2 (v2))
  663.     {
  664.         v2[1] = 1.0;
  665.     }
  666.  
  667.     /* Get cosine of angle between X axis and view vector */
  668.     cos = Dotp (view, v1);
  669.  
  670.     /* Normalize the vector to rotate about */
  671.     Normalize (v2);
  672.  
  673.     /* Compute angle to rotate */
  674.     th = acos (cos);
  675.     thd = th * 180.0 / 3.1415926535;
  676.  
  677.     /* Now we've got the model pointed in the right direction,
  678.        but the up vector is probably wrong.  This is the only
  679.        way I could think of to do this but boy it's ugly. */
  680.  
  681.     /* Figure out new up vector in up2 */
  682.     v1[0] = v1[1] = 0.0;
  683.     v1[2] = 1.0;
  684.     RotateAbout (up2, v1, v2, -th);
  685.     Normalize (up2);
  686.  
  687.     /* Rotate */
  688.     glRotated (thd, v2[0], v2[1], v2[2]);
  689.  
  690.     /* Cross product of current up and desired up is vector
  691.        to rotate about */
  692.     Crossp (v2, up2, up);
  693.  
  694.     /* If v2 is null, we're already facing the right way */
  695.     if (0.0 == Mag2 (v2)) return;
  696.  
  697.     Normalize (v2);
  698.     thd = acos (Dotp (up2, up)) * 180.0 / 3.1415926535;
  699.  
  700.     /* We rotate around the (rotated) view vector or negative view
  701.        vector depending which way v2 points */
  702.     if (Dotp (v2, view) > 0.0)
  703.         glRotated (thd, 1.0, 0.0, 0.0);
  704.     else
  705.         glRotated (thd, -1.0, 0.0, 0.0);
  706. }
  707.  
  708.