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;