- moved stuff from gamesession to world
[supertux.git] / src / gameloop.cpp
index 6df7eb7..e0cbe6a 100644 (file)
   April 11, 2000 - March 15, 2004
 */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
+#include <math.h>
 #include <time.h>
 #include <SDL.h>
 
 #include "level.h"
 #include "scene.h"
 #include "collision.h"
+#include "tile.h"
+#include "particlesystem.h"
 
 /* extern variables */
 
-st_level current_level;
 int game_started = false;
 
 /* Local variables: */
-
-static texture_type img_waves[3], img_water, img_pole, img_poletop, img_flag[2];
-static texture_type img_cloud[2][4];
 static SDL_Event event;
 static SDLKey key;
 static char level_subset[100];
-static char str[60];
 static float fps_fps;
 static int st_gl_mode;
 static unsigned int last_update_time;
@@ -59,8 +58,9 @@ static unsigned int update_time;
 static int pause_menu_frame;
 static int debug_fps;
 
-/* Local function prototypes: */
+GameSession* GameSession::current_ = 0;
 
+/* Local function prototypes: */
 void levelintro(void);
 void loadshared(void);
 void unloadshared(void);
@@ -68,16 +68,87 @@ void drawstatus(void);
 void drawendscreen(void);
 void drawresultscreen(void);
 
-void levelintro(void)
+GameSession::GameSession()
 {
-  /* Level Intro: */
+  current_ = this;
+  assert(0);
+}
+
+GameSession::GameSession(const std::string& filename)
+{
+  current_ = this;
+
+  world = &::world;
+
+  timer_init(&fps_timer, true);
+  timer_init(&frame_timer, true);
+
+  world->load(filename);
+}
+
+GameSession::GameSession(const std::string& subset, int levelnb, int mode)
+{
+  current_ = this;
 
+  world = &::world;
+
+  timer_init(&fps_timer, true);
+  timer_init(&frame_timer, true);
+
+  game_started = true;
+
+  st_gl_mode = mode;
+  level = levelnb;
+
+  /* Init the game: */
+  world->arrays_free();
+  set_defaults();
+
+  strcpy(level_subset, subset.c_str());
+
+  if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
+    {
+      if (world->load(level_subset))
+        exit(1);
+    }
+  else
+    {
+      if(world->load(level_subset, level) != 0)
+        exit(1);
+    }
+
+  world->get_level()->load_gfx();
+  loadshared();
+  activate_bad_guys(world->get_level());
+  world->activate_particle_systems();
+  world->get_level()->load_song();
+
+  tux.init();
+
+  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();
+
+  timer_init(&time_left,true);
+  start_timers();
+
+  if(st_gl_mode == ST_GL_LOAD_GAME)
+    loadgame(levelnb);
+}
+
+void
+GameSession::levelintro(void)
+{
+  char str[60];
+  /* Level Intro: */
   clearscreen(0, 0, 0);
 
   sprintf(str, "LEVEL %d", level);
   text_drawf(&blue_text, str, 0, 200, A_HMIDDLE, A_TOP, 1);
 
-  sprintf(str, "%s", current_level.name.c_str());
+  sprintf(str, "%s", world->get_level()->name.c_str());
   text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1);
 
   sprintf(str, "TUX x %d", tux.lives);
@@ -85,43 +156,38 @@ void levelintro(void)
 
   flipscreen();
 
-  SDL_Delay(1000);
+  SDL_Event event;
+  wait_for_event(event,1000,3000,true);
 }
 
 /* Reset Timers */
-void start_timers(void)
+void
+GameSession::start_timers()
 {
-  timer_start(&time_left,current_level.time_left*1000);
+  timer_start(&time_left, world->get_level()->time_left*1000);
   st_pause_ticks_init();
   update_time = st_get_ticks();
 }
 
-void activate_bad_guys(void)
+void activate_bad_guys(Level* plevel)
 {
-  int x,y;
-
-  /* Activate bad guys: */
-
-  for (y = 0; y < 15; y++)
+  for (std::vector<BadGuyData>::iterator i = plevel->badguy_data.begin();
+       i != plevel->badguy_data.end();
+       ++i)
     {
-      for (x = 0; x < current_level.width; x++)
-        {
-          if (current_level.tiles[y][x] >= '0' && current_level.tiles[y][x] <= '9')
-            {
-              add_bad_guy(x * 32, y * 32, static_cast<BadGuyKind>(current_level.tiles[y][x] - '0'));
-              current_level.tiles[y][x] = '.';
-            }
-        }
+      world.add_bad_guy(i->x, i->y, i->kind);
     }
-
 }
 
-/* --- GAME EVENT! --- */
-
-void game_event(void)
+void
+GameSession::process_events()
 {
   while (SDL_PollEvent(&event))
     {
+      /* Check for menu-events, if the menu is shown */
+      if(show_menu)
+        menu_event(event);
+
       switch(event.type)
         {
         case SDL_QUIT:        /* Quit event - quit: */
@@ -130,11 +196,7 @@ void game_event(void)
         case SDL_KEYDOWN:     /* A keypress! */
           key = event.key.keysym.sym;
 
-          /* Check for menu-events, if the menu is shown */
-          if(show_menu)
-            menu_event(&event.key.keysym);
-
-          if(player_key_event(&tux,key,DOWN))
+          if(tux.key_event(key,DOWN))
             break;
 
           switch(key)
@@ -165,7 +227,7 @@ void game_event(void)
         case SDL_KEYUP:      /* A keyrelease! */
           key = event.key.keysym.sym;
 
-          if(player_key_event(&tux,key,UP))
+          if(tux.key_event(key, UP))
             break;
 
           switch(key)
@@ -223,9 +285,9 @@ void game_event(void)
             case SDLK_f:
               if(debug_fps)
                 debug_fps = false;
-             else
+              else
                 debug_fps = true;
-              break;         
+              break;
             default:
               break;
             }
@@ -258,16 +320,8 @@ void game_event(void)
                 tux.input.down = UP;
               else
                 tux.input.down = UP;
-
-              /* Handle joystick for the menu */
-              if(show_menu)
-                {
-                  if(tux.input.down == DOWN)
-                    menuaction = MENU_ACTION_DOWN;
-                  else
-                    menuaction = MENU_ACTION_UP;
-                }
-              break;
+              
+             break;
             default:
               break;
             }
@@ -283,9 +337,7 @@ void game_event(void)
             tux.input.up = UP;
           else if (event.jbutton.button == JOY_B)
             tux.input.fire = UP;
-
-          if(show_menu)
-            menuaction = MENU_ACTION_HIT;
+           
           break;
 
         default:
@@ -296,20 +348,14 @@ void game_event(void)
     } /* while */
 }
 
-/* --- GAME ACTION! --- */
-
-int game_action(void)
+int
+GameSession::action()
 {
-  unsigned int i;
-
-  /* (tux_dying || next_level) */
-  if (tux.dying || next_level)
+  if (tux.is_dead() || next_level)
     {
       /* Tux either died, or reached the end of a level! */
-
       halt_music();
-
-
+      
       if (next_level)
         {
           /* End of a level! */
@@ -322,17 +368,17 @@ int game_action(void)
           else
             {
               level_free_gfx();
-              level_free(&current_level);
+              world->get_level()->cleanup();
               level_free_song();
               unloadshared();
-              arrays_free();
+              world->arrays_free();
               return(0);
             }
-          player_level_begin(&tux);
+          tux.level_begin();
         }
       else
         {
-          player_dying(&tux);
+          tux.is_dying();
 
           /* No more lives!? */
 
@@ -347,38 +393,38 @@ int game_action(void)
                     save_hs(score);
                 }
               level_free_gfx();
-              level_free(&current_level);
+              world->get_level()->cleanup();
               level_free_song();
               unloadshared();
-              arrays_free();
+              world->arrays_free();
               return(0);
             } /* if (lives < 0) */
         }
 
       /* Either way, (re-)load the (next) level... */
 
-      player_level_begin(&tux);
+      tux.level_begin();
       set_defaults();
-      level_free(&current_level);
+      world->get_level()->cleanup();
 
       if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
         {
-          if(level_load(&current_level, level_subset) != 0)
+          if(world->get_level()->load(level_subset) != 0)
             return 0;
         }
       else
         {
-          if(level_load(&current_level,level_subset,level) != 0)
+          if(world->get_level()->load(level_subset,level) != 0)
             return 0;
         }
 
-      arrays_free();
-      arrays_init();
-      activate_bad_guys();
+      world->arrays_free();
+      activate_bad_guys(world->get_level());
+      world->activate_particle_systems();
       level_free_gfx();
-      level_load_gfx(&current_level);
+      world->get_level()->load_gfx();
       level_free_song();
-      level_load_song(&current_level);
+      world->get_level()->load_song();
       if(st_gl_mode != ST_GL_TEST)
         levelintro();
       start_timers();
@@ -386,71 +432,15 @@ int game_action(void)
       play_current_music();
     }
 
-  player_action(&tux);
-
-  /* Handle bouncy distros: */
-
-  for (i = 0; i < bouncy_distros.size(); i++)
-    {
-      bouncy_distro_action(&bouncy_distros[i]);
-    }
-
-
-  /* Handle broken bricks: */
-
-  for (i = 0; i < broken_bricks.size(); i++)
-    {
-      broken_brick_action(&broken_bricks[i]);
-    }
-
-
-  /* Handle distro counting: */
-
-  if (counting_distros)
-    {
-      distro_counter--;
-
-      if (distro_counter <= 0)
-        counting_distros = -1;
-    }
-
-
-  /* Handle bouncy bricks: */
-
-  for (i = 0; i < bouncy_bricks.size(); i++)
-    {
-      bouncy_brick_action(&bouncy_bricks[i]);
-    }
-
+  tux.action();
 
-  /* Handle floating scores: */
+  world->action();
 
-  for (i = 0; i < floating_scores.size(); i++)
+  /* update particle systems */
+  std::vector<ParticleSystem*>::iterator p;
+  for(p = world->particle_systems.begin(); p != world->particle_systems.end(); ++p)
     {
-      floating_score_action(&floating_scores[i]);
-    }
-
-
-  /* Handle bullets: */
-
-  for (i = 0; i < bullets.size(); ++i)
-    {
-      bullet_action(&bullets[i]);
-    }
-
-  /* Handle upgrades: */
-
-  for (i = 0; i < upgrades.size(); i++)
-    {
-      upgrade_action(&upgrades[i]);
-    }
-
-
-  /* Handle bad guys: */
-
-  for (i = 0; i < bad_guys.size(); i++)
-    {
-      badguy_action(&bad_guys[i]);
+      (*p)->simulate(frame_ratio);
     }
 
   /* Handle all possible collisions. */
@@ -459,110 +449,19 @@ int game_action(void)
   return -1;
 }
 
-/* --- GAME DRAW! --- */
-
-void game_draw(void)
+void 
+GameSession::draw()
 {
-  int y, s;
-  unsigned int i,x;
-
-  /* Draw screen: */
-
-  if (tux.dying && (frame % 4) == 0)
-    clearscreen(255, 255, 255);
-  else if(timer_check(&super_bkgd_timer))
-    texture_draw(&img_super_bkgd, 0, 0);
-  else
-    {
-      /* Draw the real background */
-      if(current_level.bkgd_image[0] != '\0')
-        {
-          s = (int)scroll_x / 30;
-          texture_draw_part(&img_bkgd,s,0,0,0,img_bkgd.w - s, img_bkgd.h);
-          texture_draw_part(&img_bkgd,0,0,screen->w - s ,0,s,img_bkgd.h);
-        }
-      else
-        {
-          clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue);
-        }
-    }
-
-  /* Draw background: */
-
-  for (y = 0; y < 15; ++y)
-    {
-      for (x = 0; x < 21; ++x)
-        {
-          drawshape(32*x - fmodf(scroll_x, 32), y * 32,
-                    current_level.tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
-        }
-    }
-
-
-  /* (Bouncy bricks): */
-
-  for (i = 0; i < bouncy_bricks.size(); ++i)
-    {
-      bouncy_brick_draw(&bouncy_bricks[i]);
-    }
-
-
-  /* (Bad guys): */
-
-  for (i = 0; i < bad_guys.size(); ++i)
-    {
-      badguy_draw(&bad_guys[i]);
-    }
-
-  /* (Tux): */
-
-  player_draw(&tux);
-
-  /* (Bullets): */
-
-  for (i = 0; i < bullets.size(); ++i)
-    {
-      bullet_draw(&bullets[i]);
-    }
 
-  /* (Floating scores): */
-
-  for (i = 0; i < floating_scores.size(); ++i)
-    {
-      floating_score_draw(&floating_scores[i]);
-    }
-
-
-  /* (Upgrades): */
-
-  for (i = 0; i < upgrades.size(); ++i)
-    {
-      upgrade_draw(&upgrades[i]);
-    }
-
-
-  /* (Bouncy distros): */
-
-  for (i = 0; i < bouncy_distros.size(); ++i)
-    {
-      bouncy_distro_draw(&bouncy_distros[i]);
-    }
-
-
-  /* (Broken bricks): */
-
-  for (i = 0; i < broken_bricks.size(); ++i)
-    {
-      broken_brick_draw(&broken_bricks[i]);
-    }
+  
+  world->draw();
 
   drawstatus();
 
-
   if(game_pause)
     {
-      x = screen->h / 20;
-      for(i = 0; i < x; ++i)
+      int x = screen->h / 20;
+      for(int i = 0; i < x; ++i)
         {
           fillrect(i % 2 ? (pause_menu_frame * i)%screen->w : -((pause_menu_frame * i)%screen->w) ,(i*20+pause_menu_frame)%screen->h,screen->w,10,20,20,20, rand() % 20 + 1);
         }
@@ -571,91 +470,47 @@ void game_draw(void)
     }
 
   if(show_menu)
+  {
     menu_process_current();
+    mouse_cursor->draw();
+  }
 
   /* (Update it all!) */
-
   updatescreen();
-
-
 }
 
-/* --- GAME LOOP! --- */
 
-int gameloop(const char * subset, int levelnb, int mode)
+int
+GameSession::run()
 {
-  int fps_cnt, jump, done;
-  timer_type fps_timer, frame_timer;
-  timer_init(&fps_timer, true);
-  timer_init(&frame_timer, true);
-
-  game_started = true;
-
-  st_gl_mode = mode;
-  level = levelnb;
-
-  /* Init the game: */
-  arrays_init();
-  set_defaults();
-
-  strcpy(level_subset,subset);
-
-  if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
-    {
-      if (level_load(&current_level, level_subset))
-        exit(1);
-    }
-  else
-    {
-      if(level_load(&current_level, level_subset, level) != 0)
-        exit(1);
-    }
-
-  level_load_gfx(&current_level);
-  activate_bad_guys();
-  level_load_song(&current_level);
-
-  player_init(&tux);
-
-  if(st_gl_mode != ST_GL_TEST)
-    load_hs();
-
-  loadshared();
-
-  if(st_gl_mode == ST_GL_PLAY || st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
-    levelintro();
-
-  timer_init(&time_left,true);
-  start_timers();
-
-  if(st_gl_mode == ST_GL_LOAD_GAME)
-    loadgame(levelnb);
-
+  current_ = this;
+  
+  int  fps_cnt;
+  bool jump;
+  bool done;
 
   /* --- MAIN GAME LOOP!!! --- */
-
   jump = false;
-  done = 0;
+  done = false;
   quit = 0;
-  frame = 0;
+  global_frame_counter = 0;
   game_pause = 0;
   timer_init(&fps_timer,true);
   timer_init(&frame_timer,true);
+  last_update_time = st_get_ticks();
   fps_cnt = 0;
 
   /* Clear screen: */
-
   clearscreen(0, 0, 0);
   updatescreen();
 
   /* Play music: */
   play_current_music();
 
-
   while (SDL_PollEvent(&event))
-    {}
+  {}
 
-  game_draw();
+  draw();
   do
     {
       jump = false;
@@ -664,18 +519,18 @@ int gameloop(const char * subset, int levelnb, int mode)
       frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
       if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */
         frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85;
-      
+
       if(!timer_check(&frame_timer))
         {
           timer_start(&frame_timer,25);
-          ++frame;
+          ++global_frame_counter;
         }
 
       /* Handle events: */
 
       tux.input.old_fire = tux.input.fire;
 
-      game_event();
+      process_events();
 
       if(show_menu)
         {
@@ -694,7 +549,7 @@ int gameloop(const char * subset, int levelnb, int mode)
                   break;
                 case 7:
                   st_pause_ticks_stop();
-                  done = 1;
+                  done = true;
                   break;
                 }
             }
@@ -704,11 +559,11 @@ int gameloop(const char * subset, int levelnb, int mode)
             }
           else if(current_menu == save_game_menu )
             {
-              process_save_load_game_menu(true);
+              process_save_game_menu();
             }
           else if(current_menu == load_game_menu )
             {
-              process_save_load_game_menu(false);
+              process_load_game_menu();
             }
         }
 
@@ -721,14 +576,14 @@ int gameloop(const char * subset, int levelnb, int mode)
             frame_ratio = 1;
             while(z >= 1)
             {*/
-          if (game_action() == 0)
+          if (action() == 0)
             {
               /* == 0: no more lives */
               /* == -1: continues */
               return 0;
             }
-         /*  --z;
-              }*/
+          /*  --z;
+                     }*/
         }
       else
         {
@@ -736,7 +591,7 @@ int gameloop(const char * subset, int levelnb, int mode)
           SDL_Delay(50);
         }
 
-      if(debug_mode && debug_fps == true)
+      if(debug_mode && debug_fps)
         SDL_Delay(60);
 
       /*Draw the current scene to the screen */
@@ -747,7 +602,7 @@ int gameloop(const char * subset, int levelnb, int mode)
         game_draw();
         else
         jump = true;*/ /*FIXME: Implement this tweak right.*/
-      game_draw();
+      draw();
 
       /* Time stops in pause mode */
       if(game_pause || show_menu )
@@ -759,12 +614,13 @@ int gameloop(const char * subset, int levelnb, int mode)
       last_update_time = update_time;
       update_time = st_get_ticks();
 
-
       /* Pause till next frame, if the machine running the game is too fast: */
       /* FIXME: Works great for in OpenGl mode, where the CPU doesn't have to do that much. But
          the results in SDL mode aren't perfect (thought the 100 FPS are reached), even on an AMD2500+. */
-      if(last_update_time >= update_time - 12 && !jump)
+      if(last_update_time >= update_time - 12 && !jump) {
         SDL_Delay(10);
+        update_time = st_get_ticks();
+      }
       /*if((update_time - last_update_time) < 10)
         SDL_Delay((11 - (update_time - last_update_time))/2);*/
 
@@ -784,7 +640,7 @@ int gameloop(const char * subset, int levelnb, int mode)
 
         }
       else
-        player_kill(&tux,KILL);
+        tux.kill(KILL);
 
 
       /* Calculate frames per second */
@@ -806,786 +662,54 @@ int gameloop(const char * subset, int levelnb, int mode)
   halt_music();
 
   level_free_gfx();
-  level_free(&current_level);
+  world->get_level()->cleanup();
   level_free_song();
   unloadshared();
-  arrays_free();
+  world->arrays_free();
 
   game_started = false;
 
   return(quit);
 }
 
-
-/* Load graphics/sounds shared between all levels: */
-
-void loadshared(void)
-{
-  int i;
-
-  /* Tuxes: */
-  texture_load(&tux_right[0], datadir + "/images/shared/tux-right-0.png", USE_ALPHA);
-  texture_load(&tux_right[1], datadir + "/images/shared/tux-right-1.png", USE_ALPHA);
-  texture_load(&tux_right[2], datadir + "/images/shared/tux-right-2.png", USE_ALPHA);
-
-  texture_load(&tux_left[0], datadir + "/images/shared/tux-left-0.png", USE_ALPHA);
-  texture_load(&tux_left[1], datadir + "/images/shared/tux-left-1.png", USE_ALPHA);
-  texture_load(&tux_left[2], datadir + "/images/shared/tux-left-2.png", USE_ALPHA);
-
-  texture_load(&firetux_right[0], datadir + "/images/shared/firetux-right-0.png", USE_ALPHA);
-  texture_load(&firetux_right[1], datadir + "/images/shared/firetux-right-1.png", USE_ALPHA);
-  texture_load(&firetux_right[2], datadir + "/images/shared/firetux-right-2.png", USE_ALPHA);
-
-  texture_load(&firetux_left[0], datadir + "/images/shared/firetux-left-0.png", USE_ALPHA);
-  texture_load(&firetux_left[1], datadir + "/images/shared/firetux-left-1.png", USE_ALPHA);
-  texture_load(&firetux_left[2], datadir + "/images/shared/firetux-left-2.png", USE_ALPHA);
-
-
-  texture_load(&cape_right[0], datadir + "/images/shared/cape-right-0.png",
-               USE_ALPHA);
-
-  texture_load(&cape_right[1], datadir + "/images/shared/cape-right-1.png",
-               USE_ALPHA);
-
-  texture_load(&cape_left[0], datadir + "/images/shared/cape-left-0.png",
-               USE_ALPHA);
-
-  texture_load(&cape_left[1], datadir + "/images/shared/cape-left-1.png",
-               USE_ALPHA);
-
-  texture_load(&bigtux_right[0], datadir + "/images/shared/bigtux-right-0.png",
-               USE_ALPHA);
-
-  texture_load(&bigtux_right[1], datadir + "/images/shared/bigtux-right-1.png",
-               USE_ALPHA);
-
-  texture_load(&bigtux_right[2], datadir + "/images/shared/bigtux-right-2.png",
-               USE_ALPHA);
-
-  texture_load(&bigtux_right_jump, datadir + "/images/shared/bigtux-right-jump.png", USE_ALPHA);
-
-  texture_load(&bigtux_left[0], datadir + "/images/shared/bigtux-left-0.png",
-               USE_ALPHA);
-
-  texture_load(&bigtux_left[1], datadir + "/images/shared/bigtux-left-1.png",
-               USE_ALPHA);
-
-  texture_load(&bigtux_left[2], datadir + "/images/shared/bigtux-left-2.png",
-               USE_ALPHA);
-
-  texture_load(&bigtux_left_jump, datadir + "/images/shared/bigtux-left-jump.png", USE_ALPHA);
-
-  texture_load(&bigcape_right[0], datadir + "/images/shared/bigcape-right-0.png",
-               USE_ALPHA);
-
-  texture_load(&bigcape_right[1], datadir + "/images/shared/bigcape-right-1.png",
-               USE_ALPHA);
-
-  texture_load(&bigcape_left[0], datadir + "/images/shared/bigcape-left-0.png",
-               USE_ALPHA);
-
-  texture_load(&bigcape_left[1], datadir + "/images/shared/bigcape-left-1.png",
-               USE_ALPHA);
-
-  texture_load(&bigfiretux_right[0], datadir + "/images/shared/bigfiretux-right-0.png",
-               USE_ALPHA);
-
-  texture_load(&bigfiretux_right[1], datadir + "/images/shared/bigfiretux-right-1.png",
-               USE_ALPHA);
-
-  texture_load(&bigfiretux_right[2], datadir + "/images/shared/bigfiretux-right-2.png",
-               USE_ALPHA);
-
-  texture_load(&bigfiretux_right_jump, datadir + "/images/shared/bigfiretux-right-jump.png", USE_ALPHA);
-
-  texture_load(&bigfiretux_left[0], datadir + "/images/shared/bigfiretux-left-0.png",
-               USE_ALPHA);
-
-  texture_load(&bigfiretux_left[1], datadir + "/images/shared/bigfiretux-left-1.png",
-               USE_ALPHA);
-
-  texture_load(&bigfiretux_left[2], datadir + "/images/shared/bigfiretux-left-2.png",
-               USE_ALPHA);
-
-  texture_load(&bigfiretux_left_jump, datadir + "/images/shared/bigfiretux-left-jump.png", USE_ALPHA);
-
-  texture_load(&bigcape_right[0], datadir + "/images/shared/bigcape-right-0.png",
-               USE_ALPHA);
-
-  texture_load(&bigcape_right[1], datadir + "/images/shared/bigcape-right-1.png",
-               USE_ALPHA);
-
-  texture_load(&bigcape_left[0], datadir + "/images/shared/bigcape-left-0.png",
-               USE_ALPHA);
-
-  texture_load(&bigcape_left[1], datadir + "/images/shared/bigcape-left-1.png",
-               USE_ALPHA);
-
-
-  texture_load(&ducktux_right, datadir +
-               "/images/shared/ducktux-right.png",
-               USE_ALPHA);
-
-  texture_load(&ducktux_left, datadir +
-               "/images/shared/ducktux-left.png",
-               USE_ALPHA);
-
-  texture_load(&skidtux_right, datadir +
-               "/images/shared/skidtux-right.png",
-               USE_ALPHA);
-
-  texture_load(&skidtux_left, datadir +
-               "/images/shared/skidtux-left.png",
-               USE_ALPHA);
-
-  texture_load(&duckfiretux_right, datadir +
-               "/images/shared/duckfiretux-right.png",
-               USE_ALPHA);
-
-  texture_load(&duckfiretux_left, datadir +
-               "/images/shared/duckfiretux-left.png",
-               USE_ALPHA);
-
-  texture_load(&skidfiretux_right, datadir +
-               "/images/shared/skidfiretux-right.png",
-               USE_ALPHA);
-
-  texture_load(&skidfiretux_left, datadir +
-               "/images/shared/skidfiretux-left.png",
-               USE_ALPHA);
-
-
-  /* Boxes: */
-
-  texture_load(&img_box_full, datadir + "/images/shared/box-full.png",
-               IGNORE_ALPHA);
-  texture_load(&img_box_empty, datadir + "/images/shared/box-empty.png",
-               IGNORE_ALPHA);
-
-
-  /* Water: */
-
-
-  texture_load(&img_water, datadir + "/images/shared/water.png", IGNORE_ALPHA);
-
-  texture_load(&img_waves[0], datadir + "/images/shared/waves-0.png",
-               USE_ALPHA);
-
-  texture_load(&img_waves[1], datadir + "/images/shared/waves-1.png",
-               USE_ALPHA);
-
-  texture_load(&img_waves[2], datadir + "/images/shared/waves-2.png",
-               USE_ALPHA);
-
-
-  /* Pole: */
-
-  texture_load(&img_pole, datadir + "/images/shared/pole.png", USE_ALPHA);
-  texture_load(&img_poletop, datadir + "/images/shared/poletop.png",
-               USE_ALPHA);
-
-
-  /* Flag: */
-
-  texture_load(&img_flag[0], datadir + "/images/shared/flag-0.png",
-               USE_ALPHA);
-  texture_load(&img_flag[1], datadir + "/images/shared/flag-1.png",
-               USE_ALPHA);
-
-
-  /* Cloud: */
-
-  texture_load(&img_cloud[0][0], datadir + "/images/shared/cloud-00.png",
-               USE_ALPHA);
-
-  texture_load(&img_cloud[0][1], datadir + "/images/shared/cloud-01.png",
-               USE_ALPHA);
-
-  texture_load(&img_cloud[0][2], datadir + "/images/shared/cloud-02.png",
-               USE_ALPHA);
-
-  texture_load(&img_cloud[0][3], datadir + "/images/shared/cloud-03.png",
-               USE_ALPHA);
-
-
-  texture_load(&img_cloud[1][0], datadir + "/images/shared/cloud-10.png",
-               USE_ALPHA);
-
-  texture_load(&img_cloud[1][1], datadir + "/images/shared/cloud-11.png",
-               USE_ALPHA);
-
-  texture_load(&img_cloud[1][2], datadir + "/images/shared/cloud-12.png",
-               USE_ALPHA);
-
-  texture_load(&img_cloud[1][3], datadir + "/images/shared/cloud-13.png",
-               USE_ALPHA);
-
-
-  /* Bad guys: */
-
-  /* (BSOD) */
-
-  texture_load(&img_bsod_left[0], datadir +
-               "/images/shared/bsod-left-0.png",
-               USE_ALPHA);
-
-  texture_load(&img_bsod_left[1], datadir +
-               "/images/shared/bsod-left-1.png",
-               USE_ALPHA);
-
-  texture_load(&img_bsod_left[2], datadir +
-               "/images/shared/bsod-left-2.png",
-               USE_ALPHA);
-
-  texture_load(&img_bsod_left[3], datadir +
-               "/images/shared/bsod-left-3.png",
-               USE_ALPHA);
-
-  texture_load(&img_bsod_right[0], datadir +
-               "/images/shared/bsod-right-0.png",
-               USE_ALPHA);
-
-  texture_load(&img_bsod_right[1], datadir +
-               "/images/shared/bsod-right-1.png",
-               USE_ALPHA);
-
-  texture_load(&img_bsod_right[2], datadir +
-               "/images/shared/bsod-right-2.png",
-               USE_ALPHA);
-
-  texture_load(&img_bsod_right[3], datadir +
-               "/images/shared/bsod-right-3.png",
-               USE_ALPHA);
-
-  texture_load(&img_bsod_squished_left, datadir +
-               "/images/shared/bsod-squished-left.png",
-               USE_ALPHA);
-
-  texture_load(&img_bsod_squished_right, datadir +
-               "/images/shared/bsod-squished-right.png",
-               USE_ALPHA);
-
-  texture_load(&img_bsod_falling_left, datadir +
-               "/images/shared/bsod-falling-left.png",
-               USE_ALPHA);
-
-  texture_load(&img_bsod_falling_right, datadir +
-               "/images/shared/bsod-falling-right.png",
-               USE_ALPHA);
-
-
-  /* (Laptop) */
-
-  texture_load(&img_laptop_left[0], datadir +
-               "/images/shared/laptop-left-0.png",
-               USE_ALPHA);
-
-  texture_load(&img_laptop_left[1], datadir +
-               "/images/shared/laptop-left-1.png",
-               USE_ALPHA);
-
-  texture_load(&img_laptop_left[2], datadir +
-               "/images/shared/laptop-left-2.png",
-               USE_ALPHA);
-
-  texture_load(&img_laptop_right[0], datadir +
-               "/images/shared/laptop-right-0.png",
-               USE_ALPHA);
-
-  texture_load(&img_laptop_right[1], datadir +
-               "/images/shared/laptop-right-1.png",
-               USE_ALPHA);
-
-  texture_load(&img_laptop_right[2], datadir +
-               "/images/shared/laptop-right-2.png",
-               USE_ALPHA);
-
-  texture_load(&img_laptop_flat_left, datadir +
-               "/images/shared/laptop-flat-left.png",
-               USE_ALPHA);
-
-  texture_load(&img_laptop_flat_right, datadir +
-               "/images/shared/laptop-flat-right.png",
-               USE_ALPHA);
-
-  texture_load(&img_laptop_falling_left, datadir +
-               "/images/shared/laptop-falling-left.png",
-               USE_ALPHA);
-
-  texture_load(&img_laptop_falling_right, datadir +
-               "/images/shared/laptop-falling-right.png",
-               USE_ALPHA);
-
-
-  /* (Money) */
-
-  texture_load(&img_money_left[0], datadir +
-               "/images/shared/bag-left-0.png",
-               USE_ALPHA);
-
-  texture_load(&img_money_left[1], datadir +
-               "/images/shared/bag-left-1.png",
-               USE_ALPHA);
-
-  texture_load(&img_money_right[0], datadir +
-               "/images/shared/bag-right-0.png",
-               USE_ALPHA);
-
-  texture_load(&img_money_right[1], datadir +
-               "/images/shared/bag-right-1.png",
-               USE_ALPHA);
-
-
-
-  /* Upgrades: */
-
-  texture_load(&img_mints, datadir + "/images/shared/mints.png", USE_ALPHA);
-  texture_load(&img_coffee, datadir + "/images/shared/coffee.png", USE_ALPHA);
-
-
-  /* Weapons: */
-
-  texture_load(&img_bullet, datadir + "/images/shared/bullet.png", USE_ALPHA);
-
-  texture_load(&img_red_glow, datadir + "/images/shared/red-glow.png",
-               USE_ALPHA);
-
-
-
-  /* Distros: */
-
-  texture_load(&img_distro[0], datadir + "/images/shared/distro-0.png",
-               USE_ALPHA);
-
-  texture_load(&img_distro[1], datadir + "/images/shared/distro-1.png",
-               USE_ALPHA);
-
-  texture_load(&img_distro[2], datadir + "/images/shared/distro-2.png",
-               USE_ALPHA);
-
-  texture_load(&img_distro[3], datadir + "/images/shared/distro-3.png",
-               USE_ALPHA);
-
-
-  /* Tux life: */
-
-  texture_load(&tux_life, datadir + "/images/shared/tux-life.png",
-               USE_ALPHA);
-
-  /* Herring: */
-
-  texture_load(&img_golden_herring, datadir + "/images/shared/golden-herring.png",
-               USE_ALPHA);
-
-
-  /* Super background: */
-
-  texture_load(&img_super_bkgd, datadir + "/images/shared/super-bkgd.png",
-               IGNORE_ALPHA);
-
-
-  /* Sound effects: */
-
-  /* if (use_sound) // this will introduce SERIOUS bugs here ! because "load_sound"
-                    // initialize sounds[i] with the correct pointer's value:
-                    // NULL or something else. And it will be dangerous to
-                    // play with not-initialized pointers.
-                    // This is also true with if (use_music)
-                    Send a mail to me: neoneurone@users.sf.net, if you have another opinion. :)
-  */
-  for (i = 0; i < NUM_SOUNDS; i++)
-    sounds[i] = load_sound(datadir + soundfilenames[i]);
-
-  /* Herring song */
-  herring_song = load_song(datadir + "/music/SALCON.MOD");
-}
-
-
-/* Free shared data: */
-
-void unloadshared(void)
-{
-  int i;
-
-  for (i = 0; i < 3; i++)
-    {
-      texture_free(&tux_right[i]);
-      texture_free(&tux_left[i]);
-      texture_free(&bigtux_right[i]);
-      texture_free(&bigtux_left[i]);
-    }
-
-  texture_free(&bigtux_right_jump);
-  texture_free(&bigtux_left_jump);
-
-  for (i = 0; i < 2; i++)
-    {
-      texture_free(&cape_right[i]);
-      texture_free(&cape_left[i]);
-      texture_free(&bigcape_right[i]);
-      texture_free(&bigcape_left[i]);
-    }
-
-  texture_free(&ducktux_left);
-  texture_free(&ducktux_right);
-
-  texture_free(&skidtux_left);
-  texture_free(&skidtux_right);
-
-  for (i = 0; i < 4; i++)
-    {
-      texture_free(&img_bsod_left[i]);
-      texture_free(&img_bsod_right[i]);
-    }
-
-  texture_free(&img_bsod_squished_left);
-  texture_free(&img_bsod_squished_right);
-
-  texture_free(&img_bsod_falling_left);
-  texture_free(&img_bsod_falling_right);
-
-  for (i = 0; i < 3; i++)
-    {
-      texture_free(&img_laptop_left[i]);
-      texture_free(&img_laptop_right[i]);
-    }
-
-  texture_free(&img_laptop_flat_left);
-  texture_free(&img_laptop_flat_right);
-
-  texture_free(&img_laptop_falling_left);
-  texture_free(&img_laptop_falling_right);
-
-  for (i = 0; i < 2; i++)
-    {
-      texture_free(&img_money_left[i]);
-      texture_free(&img_money_right[i]);
-    }
-
-  texture_free(&img_box_full);
-  texture_free(&img_box_empty);
-
-  texture_free(&img_water);
-  for (i = 0; i < 3; i++)
-    texture_free(&img_waves[i]);
-
-  texture_free(&img_pole);
-  texture_free(&img_poletop);
-
-  for (i = 0; i < 2; i++)
-    texture_free(&img_flag[i]);
-
-  texture_free(&img_mints);
-  texture_free(&img_coffee);
-
-  for (i = 0; i < 4; i++)
-    {
-      texture_free(&img_distro[i]);
-      texture_free(&img_cloud[0][i]);
-      texture_free(&img_cloud[1][i]);
-    }
-
-  texture_free(&img_golden_herring);
-
-  for (i = 0; i < NUM_SOUNDS; i++)
-    free_chunk(sounds[i]);
-
-  /* free the herring song */
-  free_music( herring_song );
-}
-
-
 /* Draw a tile on the screen: */
 
-void drawshape(float x, float y, unsigned char c)
-{
-  int z;
-
-  if (c == 'X' || c == 'x')
-    texture_draw(&img_brick[0], x, y);
-  else if (c == 'Y' || c == 'y')
-    texture_draw(&img_brick[1], x, y);
-  else if (c == 'A' || c =='B' || c == '!')
-    texture_draw(&img_box_full, x, y);
-  else if (c == 'a')
-    texture_draw(&img_box_empty, x, y);
-  else if (c >= 'C' && c <= 'F')
-    texture_draw(&img_cloud[0][c - 'C'], x, y);
-  else if (c >= 'c' && c <= 'f')
-    texture_draw(&img_cloud[1][c - 'c'], x, y);
-  else if (c >= 'G' && c <= 'J')
-    texture_draw(&img_bkgd_tile[0][c - 'G'], x, y);
-  else if (c >= 'g' && c <= 'j')
-    texture_draw(&img_bkgd_tile[1][c - 'g'], x, y);
-  else if (c == '#')
-    texture_draw(&img_solid[0], x, y);
-  else if (c == '[')
-    texture_draw(&img_solid[1], x, y);
-  else if (c == '=')
-    texture_draw(&img_solid[2], x, y);
-  else if (c == ']')
-    texture_draw(&img_solid[3], x, y);
-  else if (c == '$')
-    {
-      z = (frame / 2) % 6;
-
-      if (z < 4)
-        texture_draw(&img_distro[z], x, y);
-      else if (z == 4)
-        texture_draw(&img_distro[2], x, y);
-      else if (z == 5)
-        texture_draw(&img_distro[1], x, y);
-    }
-  else if (c == '^')
-    {
-      z = (frame / 3) % 3;
-
-      texture_draw(&img_waves[z], x, y);
-    }
-  else if (c == '*')
-    texture_draw(&img_poletop, x, y);
-  else if (c == '|')
-    {
-      texture_draw(&img_pole, x, y);
-
-    }
-  else if (c == '\\')
-    {
-      z = (frame / 3) % 2;
-
-      texture_draw(&img_flag[z], x + 16, y);
-    }
-  else if (c == '&')
-    texture_draw(&img_water, x, y);
-}
-
-
-/* What shape is at some position? */
-
-unsigned char shape(float x, float y)
-{
-
-  int xx, yy;
-  unsigned char c;
-
-  yy = ((int)y / 32);
-  xx = ((int)x / 32);
-
-  if (yy >= 0 && yy < 15 && xx >= 0 && xx <= current_level.width)
-    {
-      c = current_level.tiles[yy][xx];
-    }
-  else
-    c = '.';
-
-  return(c);
-}
-
-/* Is is ground? */
-
-
-bool issolid(float x, float y)
-{
-  return (isbrick(x, y) ||
-          isice(x, y) ||
-          (shape(x, y) == '[') ||
-          (shape(x, y) == '=') ||
-          (shape(x, y) == ']') ||
-          (shape(x, y) == 'A') ||
-          (shape(x, y) == 'B') ||
-          (shape(x, y) == '!') ||
-          (shape(x, y) == 'a'));
-}
-
-/* Is it a brick? */
-
-bool isbrick(float x, float y)
+void drawshape(float x, float y, unsigned int c, Uint8 alpha)
 {
-  return (shape(x, y) == 'X' ||
-          shape(x, y) == 'x' ||
-          shape(x, y) == 'Y' ||
-          shape(x, y) == 'y');
-}
-
-
-/* Is it ice? */
-
-bool isice(float x, float y)
-{
-  return (shape(x, y) == '#');
-}
-
-/* Is it a full box? */
-
-bool isfullbox(float x, float y)
-{
-  return (shape(x, y) == 'A' ||
-          shape(x, y) == 'B' ||
-          shape(x, y) == '!');
-}
-
-/* Break a brick: */
-
-void trybreakbrick(float x, float y)
-{
-  if (isbrick(x, y))
+  if (c != 0)
     {
-      if (shape(x, y) == 'x' || shape(x, y) == 'y')
+      Tile* ptile = TileManager::instance()->get(c);
+      if(ptile)
         {
-          /* Get a distro from it: */
-
-          add_bouncy_distro(((int)(x + 1) / 32) * 32,
-                            (int)(y / 32) * 32);
-
-          if (!counting_distros)
+          if(ptile->images.size() > 1)
             {
-              counting_distros = true;
-              distro_counter = 50;
+              texture_draw(&ptile->images[( ((global_frame_counter*25) / ptile->anim_speed) % (ptile->images.size()))],x,y, alpha);
+            }
+          else if (ptile->images.size() == 1)
+            {
+              texture_draw(&ptile->images[0],x,y, alpha);
+            }
+          else
+            {
+              //printf("Tile not dravable %u\n", c);
             }
-
-          if (distro_counter <= 0)
-            level_change(&current_level,x, y, 'a');
-
-          play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
-          score = score + SCORE_DISTRO;
-          distros++;
-        }
-      else
-        {
-          /* Get rid of it: */
-
-          level_change(&current_level,x, y,'.');
         }
-
-
-      /* Replace it with broken bits: */
-
-      add_broken_brick(((int)(x + 1) / 32) * 32,
-                       (int)(y / 32) * 32);
-
-
-      /* Get some score: */
-
-      play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
-      score = score + SCORE_BRICK;
     }
 }
 
-
 /* Bounce a brick: */
-
 void bumpbrick(float x, float y)
 {
-  add_bouncy_brick(((int)(x + 1) / 32) * 32,
-                   (int)(y / 32) * 32);
+  world.add_bouncy_brick(((int)(x + 1) / 32) * 32,
+                         (int)(y / 32) * 32);
 
   play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
-
-}
-
-
-/* Empty a box: */
-
-void tryemptybox(float x, float y, int col_side)
-{
-  if (!isfullbox(x, y))
-    return;
-
-  // according to the collision side, set the upgrade direction
-
-  if(col_side == LEFT)
-    col_side = RIGHT;
-  else
-    col_side = LEFT;
-
-  switch(shape(x,y))
-    {
-    case 'A':      /* Box with a distro! */
-      add_bouncy_distro(((int)(x + 1) / 32) * 32, (int)(y / 32) * 32 - 32);
-      play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
-      score = score + SCORE_DISTRO;
-      distros++;
-      break;
-    case 'B':      /* Add an upgrade! */
-      if (tux.size == SMALL)     /* Tux is small, add mints! */
-        add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_MINTS);
-      else     /* Tux is big, add coffee: */
-        add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_COFFEE);
-      play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER);
-      break;
-    case '!':     /* Add a golden herring */
-      add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_HERRING);
-      break;
-    default:
-      break;
-    }
-
-  /* Empty the box: */
-  level_change(&current_level,x, y, 'a');
-}
-
-
-/* Try to grab a distro: */
-
-void trygrabdistro(float x, float y, int bounciness)
-{
-  if (shape(x, y) == '$')
-    {
-      level_change(&current_level,x, y, '.');
-      play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
-
-      if (bounciness == BOUNCE)
-        {
-          add_bouncy_distro(((int)(x + 1) / 32) * 32,
-                            (int)(y / 32) * 32);
-        }
-
-      score = score + SCORE_DISTRO;
-      distros++;
-    }
-}
-
-/* Try to bump a bad guy from below: */
-
-void trybumpbadguy(float x, float y)
-{
-  unsigned int i;
-
-  /* Bad guys: */
-  for (i = 0; i < bad_guys.size(); i++)
-    {
-      if (bad_guys[i].base.x >= x - 32 && bad_guys[i].base.x <= x + 32 &&
-          bad_guys[i].base.y >= y - 16 && bad_guys[i].base.y <= y + 16)
-        {
-          if (bad_guys[i].kind == BAD_BSOD ||
-              bad_guys[i].kind == BAD_LAPTOP)
-            {
-              bad_guys[i].dying = DYING_FALLING;
-              bad_guys[i].base.ym = -8;
-              play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
-            }
-        }
-    }
-
-
-  /* Upgrades: */
-  for (i = 0; i < upgrades.size(); i++)
-    {
-      if (upgrades[i].base.height == 32 &&
-          upgrades[i].base.x >= x - 32 && upgrades[i].base.x <= x + 32 &&
-          upgrades[i].base.y >= y - 16 && upgrades[i].base.y <= y + 16)
-        {
-          upgrades[i].base.xm = -upgrades[i].base.xm;
-          upgrades[i].base.ym = -8;
-          play_sound(sounds[SND_BUMP_UPGRADE], SOUND_CENTER_SPEAKER);
-        }
-    }
 }
 
 /* (Status): */
 void drawstatus(void)
 {
-  int i;
+  char str[60];
 
   sprintf(str, "%d", score);
   text_draw(&white_text, "SCORE", 0, 0, 1);
@@ -1602,7 +726,7 @@ void drawstatus(void)
       text_draw(&white_text,"Press ESC To Return",0,20,1);
     }
 
-  if (timer_get_left(&time_left) > TIME_WARNING || (frame % 10) < 5)
+  if (timer_get_left(&time_left) > TIME_WARNING || (global_frame_counter % 10) < 5)
     {
       sprintf(str, "%d", timer_get_left(&time_left) / 1000 );
       text_draw(&white_text, "TIME", 224, 0, 1);
@@ -1622,7 +746,7 @@ void drawstatus(void)
       text_draw(&gold_text, str, screen->h + 60, 40, 1);
     }
 
-  for(i=0; i < tux.lives; ++i)
+  for(int i=0; i < tux.lives; ++i)
     {
       texture_draw(&tux_life,565+(18*i),20);
     }
@@ -1644,7 +768,9 @@ void drawendscreen(void)
   text_drawf(&gold_text, str, 0, 256, A_HMIDDLE, A_TOP, 1);
 
   flipscreen();
-  SDL_Delay(2000);
+  
+  SDL_Event event;
+  wait_for_event(event,2000,5000,true);
 }
 
 void drawresultscreen(void)
@@ -1662,10 +788,13 @@ void drawresultscreen(void)
   text_drawf(&gold_text, str, 0, 256, A_HMIDDLE, A_TOP, 1);
 
   flipscreen();
-  SDL_Delay(2000);
+  
+  SDL_Event event;
+  wait_for_event(event,2000,5000,true);
 }
 
-void savegame(int slot)
+void
+GameSession::savegame(int slot)
 {
   char savefile[1024];
   FILE* fi;
@@ -1678,7 +807,6 @@ void savegame(int slot)
   if (fi == NULL)
     {
       fprintf(stderr, "Warning: I could not open the slot file ");
-
     }
   else
     {
@@ -1688,7 +816,7 @@ void savegame(int slot)
       fwrite(&score,sizeof(int),1,fi);
       fwrite(&distros,sizeof(int),1,fi);
       fwrite(&scroll_x,sizeof(float),1,fi);
-      fwrite(&tux,sizeof(player_type),1,fi);
+      fwrite(&tux,sizeof(Player),1,fi);
       timer_fwrite(&tux.invincible_timer,fi);
       timer_fwrite(&tux.skidding_timer,fi);
       timer_fwrite(&tux.safe_timer,fi);
@@ -1701,7 +829,8 @@ void savegame(int slot)
 
 }
 
-void loadgame(int slot)
+void
+GameSession::loadgame(int slot)
 {
   char savefile[1024];
   char str[100];
@@ -1725,37 +854,35 @@ void loadgame(int slot)
       fread(&level,sizeof(int),1,fi);
 
       set_defaults();
-      level_free(&current_level);
-      if(level_load(&current_level,level_subset,level) != 0)
+      world->get_level()->cleanup();
+      if(world->get_level()->load(level_subset,level) != 0)
         exit(1);
-      arrays_free();
-      arrays_init();
-      activate_bad_guys();
+      world->arrays_free();
+      activate_bad_guys(world->get_level());
+      world->activate_particle_systems();
       level_free_gfx();
-      level_load_gfx(&current_level);
+      world->get_level()->load_gfx();
       level_free_song();
-      level_load_song(&current_level);
+      world->get_level()->load_song();
       levelintro();
       update_time = st_get_ticks();
 
-      fread(&score,sizeof(int),1,fi);
-      fread(&distros,sizeof(int),1,fi);
+      fread(&score,   sizeof(int),1,fi);
+      fread(&distros, sizeof(int),1,fi);
       fread(&scroll_x,sizeof(float),1,fi);
-      fread(&tux,sizeof(player_type),1,fi);
+      fread(&tux,     sizeof(Player), 1, fi);
       timer_fread(&tux.invincible_timer,fi);
       timer_fread(&tux.skidding_timer,fi);
       timer_fread(&tux.safe_timer,fi);
       timer_fread(&tux.frame_timer,fi);
       timer_fread(&time_left,fi);
       fread(&ui,sizeof(int),1,fi);
-      tux.hphysic.start_time += st_get_ticks() - ui;
-      tux.vphysic.start_time += st_get_ticks() - ui;
       fclose(fi);
     }
 
 }
 
-void slotinfo(char **pinfo, int slot)
+std::string slotinfo(int slot)
 {
   FILE* fi;
   char slotfile[1024];
@@ -1784,7 +911,6 @@ void slotinfo(char **pinfo, int slot)
       fclose(fi);
     }
 
-  *pinfo = (char*) malloc(sizeof(char) * (strlen(tmp)+1));
-  strcpy(*pinfo,tmp);
+  return tmp;
 }