fix cr/lfs and remove trailing whitespaces...
[supertux.git] / src / mainloop.cpp
index 523db81..9f8be24 100644 (file)
 #include "control/joystickkeyboardcontroller.hpp"
 #include "gui/menu.hpp"
 #include "audio/sound_manager.hpp"
+#include "scripting/time_scheduler.hpp"
+#include "scripting/squirrel_util.hpp"
 #include "gameconfig.hpp"
 #include "main.hpp"
 #include "resources.hpp"
-#include "script_manager.hpp"
 #include "screen.hpp"
+#include "screen_fade.hpp"
 #include "timer.hpp"
+#include "player_status.hpp"
+#include "random_generator.hpp"
 
 // the engine will be run with a logical framerate of 64fps.
 // We chose 64fps here because it is a power of 2, so 1/64 gives an "even"
@@ -41,12 +45,18 @@ static const float LOGICAL_FPS = 64.0;
 MainLoop* main_loop = NULL;
 
 MainLoop::MainLoop()
-  : speed(1.0)
+  : speed(1.0), nextpop(false), nextpush(false)
 {
+  using namespace Scripting;
+  TimeScheduler::instance = new TimeScheduler();
 }
 
 MainLoop::~MainLoop()
 {
+  using namespace Scripting;
+  delete TimeScheduler::instance;
+  TimeScheduler::instance = NULL;
+
   for(std::vector<Screen*>::iterator i = screen_stack.begin();
       i != screen_stack.end(); ++i) {
     delete *i;
@@ -54,30 +64,42 @@ MainLoop::~MainLoop()
 }
 
 void
-MainLoop::push_screen(Screen* screen)
+MainLoop::push_screen(Screen* screen, ScreenFade* screen_fade)
 {
   this->next_screen.reset(screen);
-  nextpush = true;
+  this->screen_fade.reset(screen_fade);
+  if(nextpop)
+    nextpush = false;
+  else
+    nextpush = true;
+  nextpop = false;
   speed = 1.0;
 }
 
 void
-MainLoop::exit_screen()
+MainLoop::exit_screen(ScreenFade* screen_fade)
 {
-  if (screen_stack.size() < 1) {
-    quit();
-    return;
-  }
-  next_screen.reset(screen_stack.back());
+  next_screen.reset(NULL);
+  this->screen_fade.reset(screen_fade);
+  nextpop = true;
   nextpush = false;
-  screen_stack.pop_back();
-  speed = 1.0;
 }
 
 void
-MainLoop::quit()
+MainLoop::set_screen_fade(ScreenFade* screen_fade)
 {
-  running = false;
+  this->screen_fade.reset(screen_fade);
+}
+
+void
+MainLoop::quit(ScreenFade* screen_fade)
+{
+  for(std::vector<Screen*>::iterator i = screen_stack.begin();
+          i != screen_stack.end(); ++i)
+    delete *i;
+  screen_stack.clear();
+
+  exit_screen(screen_fade);
 }
 
 void
@@ -87,35 +109,61 @@ MainLoop::set_speed(float speed)
 }
 
 void
+MainLoop::draw_fps(DrawingContext& context, float fps_fps)
+{
+  char str[60];
+  snprintf(str, sizeof(str), "%3.1f", fps_fps);
+  const char* fpstext = "FPS";
+  context.draw_text(white_text, fpstext, Vector(SCREEN_WIDTH - white_text->get_text_width(fpstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), LEFT_ALLIGN, LAYER_FOREGROUND1);
+  context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), RIGHT_ALLIGN, LAYER_FOREGROUND1);
+}
+
+void
 MainLoop::run()
 {
-  DrawingContext context; 
-  
-  unsigned int frame_count;
-  float fps_fps;
+  DrawingContext context;
+
+  unsigned int frame_count = 0;
+  float fps_fps = 0;
   Uint32 fps_ticks = SDL_GetTicks();
   Uint32 fps_nextframe_ticks = SDL_GetTicks();
   Uint32 ticks;
   bool skipdraw = false;
-  
+
   running = true;
   while(running) {
-    if(next_screen.get() != NULL) {
-      if(nextpush && current_screen.get() != NULL) {
+    while( (next_screen.get() != NULL || nextpop == true) &&
+            (screen_fade.get() == NULL || screen_fade->done())) {
+      if(current_screen.get() != NULL) {
         current_screen->leave();
+      }
+
+      if(nextpop) {
+        if(screen_stack.empty()) {
+          running = false;
+          break;
+        }
+        next_screen.reset(screen_stack.back());
+        screen_stack.pop_back();
+      }
+      if(nextpush && current_screen.get() != NULL) {
         screen_stack.push_back(current_screen.release());
       }
-      
-      next_screen->setup();
-      ScriptManager::instance->fire_wakeup_event(ScriptManager::SCREEN_SWITCHED);
-      current_screen.reset(next_screen.release());
-      next_screen.reset(NULL);
+
       nextpush = false;
+      nextpop = false;
+      speed = 1.0;
+      if(next_screen.get() != NULL)
+        next_screen->setup();
+      current_screen.reset(next_screen.release());
+      screen_fade.reset(NULL);
+
+      waiting_threads.wakeup();
     }
 
-    if(current_screen.get() == NULL)
-        break;
-      
+    if(!running || current_screen.get() == NULL)
+      break;
+
     float elapsed_time = 1.0 / LOGICAL_FPS;
     ticks = SDL_GetTicks();
     if(ticks > fps_nextframe_ticks) {
@@ -133,8 +181,8 @@ MainLoop::run()
         /* just wait */
         // If we really have to wait long, then do an imprecise SDL_Delay()
         Uint32 diff = fps_nextframe_ticks - ticks;
-        if(diff > 15) {
-          SDL_Delay(diff - 10);
+        if(diff > 10) {
+          SDL_Delay(diff - 2);
         }
         ticks = SDL_GetTicks();
       }
@@ -144,16 +192,21 @@ MainLoop::run()
     if(!skipdraw) {
       current_screen->draw(context);
       if(Menu::current() != NULL)
-          Menu::current()->draw(context);
+        Menu::current()->draw(context);
+      if(screen_fade.get() != NULL)
+        screen_fade->draw(context);
       Console::instance->draw(context);
 
+      if(config->show_fps)
+        draw_fps(context, fps_fps);
+
       context.do_drawing();
 
       /* Calculate frames per second */
       if(config->show_fps)
       {
         ++frame_count;
-        
+
         if(SDL_GetTicks() - fps_ticks >= 500)
         {
           fps_fps = (float) frame_count / .5;
@@ -163,13 +216,17 @@ MainLoop::run()
       }
     }
 
+    real_time += elapsed_time;
     elapsed_time *= speed;
-
     game_time += elapsed_time;
-    ScriptManager::instance->update();
+
+    Scripting::update_debugger();
+    Scripting::TimeScheduler::instance->update(game_time);
     current_screen->update(elapsed_time);
+    if(screen_fade.get() != NULL)
+      screen_fade->update(elapsed_time);
     Console::instance->update(elapsed_time);
+
     main_controller->update();
     SDL_Event event;
     while(SDL_PollEvent(&event)) {
@@ -181,6 +238,7 @@ MainLoop::run()
     }
 
     sound_manager->update();
+
+    //log_info << "== periodic rand() = " << systemRandom.rand() << std::endl;
   }
 }
-