TODO update
[supertux.git] / src / gameloop.cpp
index 69f9f71..275c42f 100644 (file)
@@ -18,7 +18,6 @@
 //  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 <config.h>
 
 #include <iostream>
@@ -31,6 +30,7 @@
 #include <cerrno>
 #include <unistd.h>
 #include <ctime>
+#include <stdexcept>
 
 #include "SDL.h"
 
 #include "gameloop.h"
 #include "video/screen.h"
 #include "app/setup.h"
-#include "high_scores.h"
 #include "gui/menu.h"
 #include "sector.h"
-#include "player.h"
 #include "level.h"
 #include "scene.h"
-#include "collision.h"
 #include "tile.h"
-#include "particlesystem.h"
+#include "object/particlesystem.h"
+#include "object/background.h"
+#include "object/tilemap.h"
+#include "object/camera.h"
+#include "object/player.h"
+#include "lisp/lisp.h"
+#include "lisp/parser.h"
 #include "resources.h"
-#include "background.h"
-#include "tilemap.h"
 #include "app/gettext.h"
 #include "worldmap.h"
 #include "intro.h"
 #include "misc.h"
-#include "camera.h"
 #include "statistics.h"
 #include "timer.h"
 #include "object/fireworks.h"
@@ -80,10 +80,10 @@ bool compare_last(std::string& haystack, std::string needle)
   return false;
 }
 
-GameSession::GameSession(const std::string& levelname_, int mode,
-    bool flip_level_, Statistics* statistics)
+GameSession::GameSession(const std::string& levelfile_, int mode,
+    Statistics* statistics)
   : level(0), currentsector(0), st_gl_mode(mode),
-    end_sequence(NO_ENDSEQUENCE), levelname(levelname_), flip_level(flip_level_),
+    end_sequence(NO_ENDSEQUENCE), levelfile(levelfile_),
     best_level_statistics(statistics)
 {
   current_ = this;
@@ -93,9 +93,6 @@ GameSession::GameSession(const std::string& levelname_, int mode,
 
   context = new DrawingContext();
 
-  if(flip_levels_mode)
-    flip_level = true;
-
   last_swap_point = Vector(-1, -1);
   last_swap_stats.reset();
 
@@ -124,9 +121,7 @@ GameSession::restart_level()
   currentsector = 0;
 
   level = new Level;
-  level->load(levelname);
-  if(flip_level)
-    level->do_vertical_flip();
+  level->load(levelfile);
 
   global_stats.reset();
   global_stats.set_total_points(COINS_COLLECTED_STAT, level->get_total_coins());
@@ -186,8 +181,13 @@ GameSession::levelintro(void)
   char str[60];
 
   DrawingContext context;
-  if(currentsector->background)
-    currentsector->background->draw(context);
+  for(Sector::GameObjects::iterator i = currentsector->gameobjects.begin();
+      i != currentsector->gameobjects.end(); ++i) {
+    Background* background = dynamic_cast<Background*> (*i);
+    if(background) {
+      background->draw(context);
+    }
+  }
 
 //  context.draw_text(gold_text, level->get_name(), Vector(screen->w/2, 160),
 //      CENTER_ALLIGN, LAYER_FOREGROUND1);
@@ -205,11 +205,6 @@ GameSession::levelintro(void)
       Vector(screen->w/2, 350), CENTER_ALLIGN, LAYER_FOREGROUND1);
 
 
-  if(flip_level)
-    context.draw_text(white_text,
-      _("Level Vertically Flipped!"),
-      Vector(screen->w/2, 310), CENTER_ALLIGN, LAYER_FOREGROUND1);
-
   if(best_level_statistics != NULL)
     best_level_statistics->draw_message_info(context, _("Best Level Statistics"));
 
@@ -466,6 +461,7 @@ GameSession::process_events()
                         if(compare_last(last_keys, "grid"))
                           {    // toggle debug grid
                           debug_grid = !debug_grid;
+                          last_keys.clear();
                           }
                         if(compare_last(last_keys, "hover"))
                           {    // toggle hover ability on/off
@@ -725,7 +721,8 @@ GameSession::run()
   while (exit_status == ES_NONE) {
     Uint32 ticks = SDL_GetTicks();
     float elapsed_time = float(ticks - lastticks) / 1000.;
-    global_time += elapsed_time;
+    if(!game_pause)
+      global_time += elapsed_time;
     lastticks = ticks;
 
     // 40fps is minimum
@@ -768,12 +765,11 @@ GameSession::run()
     //frame_rate.update();
     
     /* Handle time: */
-    if (time_left.check() && currentsector->player->dying == DYING_NOT
-        && !end_sequence)
+    if (time_left.check() && !end_sequence)
       currentsector->player->kill(Player::KILL);
     
     /* Handle music: */
-    if(currentsector->player->invincible_timer.check() && !end_sequence)
+    if (currentsector->player->invincible_timer.started() && !end_sequence)
     {
       currentsector->play_music(HERRING_MUSIC);
     }
@@ -853,7 +849,7 @@ GameSession::drawstatus(DrawingContext& context)
           LEFT_ALLIGN, LAYER_FOREGROUND1);
     }
 
-  if(time_left.check()) {
+  if(time_left.get_timeleft() < 0) {
     context.draw_text(white_text, _("TIME's UP"), Vector(screen->w/2, 0),
         CENTER_ALLIGN, LAYER_FOREGROUND1);
   } else if (time_left.get_timeleft() > TIME_WARNING
@@ -904,12 +900,18 @@ GameSession::drawstatus(DrawingContext& context)
 }
 
 void
-GameSession::drawresultscreen(void)
+GameSession::drawresultscreen()
 {
   char str[80];
 
   DrawingContext context;
-  currentsector->background->draw(context);  
+  for(Sector::GameObjects::iterator i = currentsector->gameobjects.begin();
+      i != currentsector->gameobjects.end(); ++i) {
+    Background* background = dynamic_cast<Background*> (*i);
+    if(background) {
+      background->draw(context);
+    }
+  }
 
   context.draw_text(blue_text, _("Result:"), Vector(screen->w/2, 200),
       CENTER_ALLIGN, LAYER_FOREGROUND1);
@@ -935,25 +937,21 @@ std::string slotinfo(int slot)
   stream << slot;
   slotfile = st_save_dir + "/slot" + stream.str() + ".stsg";
 
-  lisp_object_t* savegame = lisp_read_from_file(slotfile.c_str());
-  if (savegame)
-    {
-      LispReader reader(lisp_cdr(savegame));
-      reader.read_string("title", title);
-      lisp_free(savegame);
-    }
+  try {
+    lisp::Parser parser;
+    std::auto_ptr<lisp::Lisp> root (parser.parse(slotfile));
 
-  if (access(slotfile.c_str(), F_OK) == 0)
-    {
-      if (!title.empty())
-        tmp = "Slot " + stream.str() + " - " + title;
-      else
-        tmp = "Slot " + stream.str() + " - Savegame";
-    }
-  else
-    tmp = std::string(_("Slot")) + " " + stream.str() + " - " + std::string(_("Free"));
+    const lisp::Lisp* savegame = root->get_lisp("supertux-savegame");
+    if(!savegame)
+      throw std::runtime_error("file is not a supertux-savegame.");
 
-  return tmp;
+    savegame->get("title", title);
+  } catch(std::exception& e) {
+    return std::string(_("Slot")) + " " + stream.str() + " - " +
+      std::string(_("Free"));
+  }
+
+  return std::string("Slot ") + stream.str() + " - " + title;
 }
 
 bool process_load_game_menu()
@@ -966,12 +964,6 @@ bool process_load_game_menu()
       stream << slot;
       std::string slotfile = st_save_dir + "/slot" + stream.str() + ".stsg";
 
-      if (access(slotfile.c_str(), F_OK) != 0)
-        {
-          shrink_fade(Vector(screen->w/2,screen->h/2), 600);
-          draw_intro();
-        }
-
       fadeout(256);
       DrawingContext context;
       context.draw_text(white_text, "Loading...",
@@ -980,7 +972,7 @@ bool process_load_game_menu()
 
       WorldMapNS::WorldMap worldmap;
 
-      worldmap.set_map_filename("icyisland.stwm");
+      worldmap.set_map_filename("/levels/world1/worldmap.stwm");
       // Load the game or at least set the savegame_file variable
       worldmap.loadgame(slotfile);