File : asteroids_v2.adb


     -- A version of the game Asteroids in Ada using OpenGL.
     -- COL Gene Ressler.
     --
     -- Last update: 10 December 2003
   5 --
     -- Roadmap to this program:
     --
     -- asteroids_v2.adb - The main program.  Initializes the graphical
     -- interface and then calls the GlutMainLoop, which processes all
  10 -- events (keystrokes, display requests, etc.) and calls the Idle
     -- callback repeatedly when there are no events occurring.
     --
     -- graphic_state.ads/.adb - Spec and implementation of the graphical
     -- user interface.  Initialized by the main program.  Initialization
  15 -- registers callback procedures with GLUT that are called by GLUT
     -- whenever a graphical event occurs.  These callback procedures
     -- communicate with the simulation state by calling its procedures
     -- that either change the simulation state (fire the space ship
     -- engine, thrusters, bullets, etc. in response to keystrokes) or
  20 -- retrieve geometry information about the world so it can be drawn on
     -- the display.  A special callback named "Idle" is called repeatedly
     -- by GLUT whenever no user interface event is occurring.  The Idle
     -- callback procedure calls GLUT to retrieve the real world time
     -- elapsed since the program started running.  It uses this time to
  25 -- advance the simulation clock a few times per second.  This causes
     -- the simulated world clock to advance in increments at the same rate
     -- as real time.  Since these increments are small, they look
     -- continuous to the user.
     --
  30 -- simulation_state.ads/.adb - Spec and implementation of the state of
     -- simulated world.  The world includes the space ship, rocks,
     -- bullets, and explosions.  Each of these is modeled according to the
     -- motion equations of Newtonian physics:
     --
  35 --   dV = a dT    (velocity differential = acceleration * time differential)
     --   V1 = V0 + dV (new velocity = old velocity + velocity differential)
     --   dX = V dT    (position differential = velocity * time differential)
     --   X1 = X0 + dX (new position = old position + position differential)
     --
  40 -- (Only the space ship accelerates; for other objects, a=dV=0.)
     -- These differential relationships are approximated by substituting
     -- small but finite Delta_T values (in this case about .05 second) for
     -- differential time increments, a technique known as Euler's method.
     -- Acceleration, spin rate, and creation of bullets occur when the
  45 -- graphical user interface calls procedures declared in
     -- simulation_state.ads.  This is in response to user inputs, which in
     -- turn causes GLUT to invoke callback procedures.  Through these
     -- procedure calls, the graphical interface effectively passes
     -- messages to the simulation, which change the world.  Information
  50 -- also passes in the opposite direction--from the simulation state
     -- back to the graphical interface---whenver the interface needs to
     -- redraw the display.  In this case, the graphical interface calls
     -- other procedures of simulation_state.ads to retrieve geometry
     -- information about the simulated world (position and orientation of
  55 -- space ship, whether engine is firing, position and size of rocks,
     -- and position and type of explosion particles).
     --
     -- bag.adb/.ads - A simple implementation of the bag abstract data type.
     -- A bag is just like a set (unordered collection of objects) except
  60 -- that a set can contain no repeated object, and a bag can.
     
     with Ada.Text_IO; use Ada.Text_IO;
     with Win32.Glut;  use Win32.Glut;
     with Interfaces.C.Strings;
  65 with Graphic_State;
     
     procedure Asteroids_V2 is
     
        -- This is "boilerplate" processing of command line arguments
  70    -- needed by GlutInit.  Just do it...
        Argc : aliased Integer;
        pragma Import(C, Argc, "gnat_argc");
     
        type Chars_Ptr_Ptr is access Interfaces.C.Strings.Chars_Ptr;
  75    Argv : Chars_Ptr_Ptr;
        pragma Import(C, Argv, "gnat_argv");
     
        use type Interfaces.C.Unsigned;  -- So we can "or" the GLUT_ constants below.
     begin
  80 
        -- Initialize GLUT and choose the display mode: Double buffering and RGB color.
        GlutInit (Argc'Access, Argv);
        GlutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB);
     
  85    -- Initialize the state of our own graphical interface.
        Graphic_State.Initialize;
     
        -- Enter the GLUT event processing loop.
        GlutMainLoop;
  90 
     exception
        when others =>
           Put_Line("Asteroids terminated. Bye!");
     
  95 end Asteroids_V2;