Purple Martians
Technical Code Descriptions

Timers
Overview Game speed regulation Second timer Menu timer Mouse Timer
Overview Four timers are used in the game:
ALLEGRO_TIMER * fps_timer;  // used to control the speed of the game
ALLEGRO_TIMER * mnu_timer;  // used to control the speed of the menu
ALLEGRO_TIMER * sec_timer;  // used to do things on a 1Hz schedule
ALLEGRO_TIMER * mou_timer;  // used to control hiding the mouse cursor

void mwEventQueue::create_timers(void)
{
   // create timers
   fps_timer = al_create_timer(1 / (float) mLoop.frame_speed);
   mnu_timer = al_create_timer(.008); // 125 fps
   sec_timer = al_create_timer(1);    // 1s
   mou_timer = al_create_timer(1);    // 1s

   // register timer event source
   al_register_event_source(event_queue, al_get_timer_event_source(fps_timer));
   al_register_event_source(event_queue, al_get_timer_event_source(mnu_timer));
   al_register_event_source(event_queue, al_get_timer_event_source(sec_timer));
   al_register_event_source(event_queue, al_get_timer_event_source(mou_timer));

   // start timers
   al_start_timer(fps_timer);
   al_start_timer(mnu_timer);
   al_start_timer(sec_timer);
   al_start_timer(mou_timer);
}

void mwEventQueue::proc_events(ALLEGRO_EVENT ev)
{
   if (ev.type == ALLEGRO_EVENT_TIMER)
   {
      if (ev.timer.source == fps_timer) program_update = 1;
      if (ev.timer.source == sec_timer) program_update_1s = 1;
      if (ev.timer.source == mnu_timer) menu_update = 1;
      if (ev.timer.source == mou_timer)
      {
         if (mLoop.level_editor_running) al_set_timer_count(mou_timer, 0);
         if (al_get_timer_count(mou_timer) > 2) al_hide_mouse_cursor(mDisplay.display);
      }
   }
}
Game speed regulation Whenever fps_timer generates an event, program_update is set:
if (ev.timer.source == fps_timer) program_update = 1;
In the main loop, whenever 'mEventQueue.program_update' is true, the game loop will run once.
void mwLoop::main_loop(void)
{
...
   // ----------------------------------------------------------
   // do things based on the 40 Hz fps_timer event
   // ----------------------------------------------------------
   if (mEventQueue.program_update)
   {
      mEventQueue.program_update = 0;

      // do everything in the game loop
...
Second timer Used to do things on a 1 Hz schedule In the main loop, whenever 'mEventQueue.program_update_1s' is true, (which will be once per second) these tasks are performed:
void mwLoop::main_loop(void)
{
...
   // ----------------------------------------------------------
   // do things based on the 1 Hz sec_timer event
   // ----------------------------------------------------------
   if (mEventQueue.program_update_1s)
   {
      mEventQueue.program_update_1s = 0;
      if (state[1] == 11) // game loop running
      {
         // do stuff   

      }
   }
Menu timer 'mnu_timer' generates events every 0.008s, which is 125 frames per second. The game menu runs a loop that processes both the menu and the logo animation. This code is run in that loop to both process the event queue and act as speed regulation:
while (!mEventQueue.menu_update) mEventQueue.proc_menu();
mEventQueue.menu_update = 0;
Mouse Timer 'mou_timer' hides the mouse if it has been inactive for 1 second.
if (ev.timer.source == mou_timer)
{
   if (mLoop.level_editor_running) al_set_timer_count(mEventQueue.mou_timer, 0);
   if (al_get_timer_count(mEventQueue.mou_timer) > 2) al_hide_mouse_cursor(mDisplay.display);
}

if (ev.type == ALLEGRO_EVENT_MOUSE_AXES)
{
   mouse_x = ev.mouse.x / mDisplay.display_transform_double;
   mouse_y = ev.mouse.y / mDisplay.display_transform_double;
   mouse_z = ev.mouse.z / mDisplay.display_transform_double;
   mouse_dx = ev.mouse.dx;
   mouse_dy = ev.mouse.dy;
   mouse_dz = ev.mouse.dz;
   al_show_mouse_cursor(mDisplay.display);
   al_set_timer_count(mEventQueue.mou_timer, 0);
}
if (ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
{
   if (ev.mouse.button == 1) mouse_b[1][0] = true;
   if (ev.mouse.button == 2) mouse_b[2][0] = true;
   if (ev.mouse.button == 3) mouse_b[3][0] = true;
   if (ev.mouse.button == 4) mouse_b[4][0] = true;
   al_show_mouse_cursor(mDisplay.display);
   al_set_timer_count(mEventQueue.mou_timer, 0);
}