Time is not stopped during menu display in gameloop (fix).
[supertux.git] / src / gameloop.cpp
index cfdefc1..40a609b 100644 (file)
@@ -1,14 +1,23 @@
-/*
-  gameloop.c
-  
-  Super Tux - Game Loop!
-  
-  by Bill Kendrick & Tobias Glaesser
-  bill@newbreedsoftware.com
-  http://www.newbreedsoftware.com/supertux/
-  
-  April 11, 2000 - March 15, 2004
-*/
+//  $Id$
+// 
+//  SuperTux
+//  Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
+//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+//  Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+// 
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include <iostream>
 #include <assert.h>
@@ -63,6 +72,13 @@ GameSession::restart_level()
   fps_timer.init(true);
   frame_timer.init(true);
 
+  float old_x_pos = -1;
+
+  if (world)
+    { // Tux has lost a life, so we try to respawn him at the nearest reset point
+      old_x_pos = world->get_tux()->base.x;
+    }
+  
   delete world;
 
   if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
@@ -77,12 +93,28 @@ GameSession::restart_level()
     {
       world = new World(subset, levelnb);
     }
+
+  // Set Tux to the nearest reset point
+  if (old_x_pos != -1)
+    {
+      ResetPoint best_reset_point = { -1, -1 };
+      for(std::vector<ResetPoint>::iterator i = get_level()->reset_points.begin();
+          i != get_level()->reset_points.end(); ++i)
+        {
+          if (i->x < old_x_pos && best_reset_point.x < i->x)
+            best_reset_point = *i;
+        }
+      
+      if (best_reset_point.x != -1)
+        {
+          world->get_tux()->base.x = best_reset_point.x;
+          world->get_tux()->base.y = best_reset_point.y;
+        }
+    }
+
     
   if (st_gl_mode != ST_GL_DEMO_GAME)
     {
-      if(st_gl_mode != ST_GL_TEST)
-        load_hs();
-
       if(st_gl_mode == ST_GL_PLAY || st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
         levelintro();
     }
@@ -138,7 +170,6 @@ GameSession::on_escape_press()
   else if (!Menu::current())
     {
       Menu::set_current(game_menu);
-      st_pause_ticks_stop();
     }
 }
 
@@ -154,9 +185,12 @@ GameSession::process_events()
       if (Menu::current())
         {
           Menu::current()->event(event);
+          st_pause_ticks_start();
         }
       else
         {
+          st_pause_ticks_stop();
+
           switch(event.type)
             {
             case SDL_QUIT:        /* Quit event - quit: */
@@ -248,15 +282,14 @@ GameSession::process_events()
               break;
 
             case SDL_JOYAXISMOTION:
-              switch(event.jaxis.axis)
+              if (event.jaxis.axis == joystick_keymap.x_axis)
                 {
-                case JOY_X:
-                  if (event.jaxis.value < -JOYSTICK_DEAD_ZONE)
+                  if (event.jaxis.value < -joystick_keymap.dead_zone)
                     {
                       tux.input.left  = DOWN;
                       tux.input.right = UP;
                     }
-                  else if (event.jaxis.value > JOYSTICK_DEAD_ZONE)
+                  else if (event.jaxis.value > joystick_keymap.dead_zone)
                     {
                       tux.input.left  = UP;
                       tux.input.right = DOWN;
@@ -266,32 +299,30 @@ GameSession::process_events()
                       tux.input.left  = DOWN;
                       tux.input.right = DOWN;
                     }
-                  break;
-                case JOY_Y:
-                  if (event.jaxis.value > JOYSTICK_DEAD_ZONE)
+                }
+              else if (event.jaxis.axis == joystick_keymap.y_axis)
+                {
+                  if (event.jaxis.value > joystick_keymap.dead_zone)
                     tux.input.down = DOWN;
-                  else if (event.jaxis.value < -JOYSTICK_DEAD_ZONE)
+                  else if (event.jaxis.value < -joystick_keymap.dead_zone)
                     tux.input.down = UP;
                   else
                     tux.input.down = UP;
-              
-                  break;
-                default:
-                  break;
                 }
               break;
+            
             case SDL_JOYBUTTONDOWN:
-              if (event.jbutton.button == JOY_A)
+              if (event.jbutton.button == joystick_keymap.a_button)
                 tux.input.up = DOWN;
-              else if (event.jbutton.button == JOY_B)
+              else if (event.jbutton.button == joystick_keymap.b_button)
                 tux.input.fire = DOWN;
-              else if (event.jbutton.button == JOY_START)
+              else if (event.jbutton.button == joystick_keymap.start_button)
                 on_escape_press();
               break;
             case SDL_JOYBUTTONUP:
-              if (event.jbutton.button == JOY_A)
+              if (event.jbutton.button == joystick_keymap.a_button)
                 tux.input.up = UP;
-              else if (event.jbutton.button == JOY_B)
+              else if (event.jbutton.button == joystick_keymap.b_button)
                 tux.input.fire = UP;
               break;
 
@@ -367,7 +398,6 @@ GameSession::draw()
 
   if(Menu::current())
     {
-      Menu::current()->action();
       Menu::current()->draw();
       mouse_cursor->draw();
     }
@@ -379,6 +409,7 @@ GameSession::draw()
 GameSession::ExitStatus
 GameSession::run()
 {
+  Menu::set_current(0);
   Player* tux = world->get_tux();
   current_ = this;
   
@@ -422,10 +453,13 @@ GameSession::run()
       tux->input.old_fire = tux->input.fire;
 
       process_events();
-
-      if(Menu::current())
+      
+      Menu* menu = Menu::current();
+      if(menu)
         {
-          if(Menu::current() == game_menu)
+          menu->action();
+
+          if(menu == game_menu)
             {
               switch (game_menu->check())
                 {
@@ -438,11 +472,11 @@ GameSession::run()
                   break;
                 }
             }
-          else if(Menu::current() == options_menu)
+          else if(menu == options_menu)
             {
               process_options_menu();
             }
-          else if(Menu::current() == load_game_menu )
+          else if(menu == load_game_menu )
             {
               process_load_game_menu();
             }