- moved lots of code around, made gameloop even more into a class
authorIngo Ruhnke <grumbel@gmx.de>
Sat, 10 Apr 2004 22:01:27 +0000 (22:01 +0000)
committerIngo Ruhnke <grumbel@gmx.de>
Sat, 10 Apr 2004 22:01:27 +0000 (22:01 +0000)
SVN-Revision: 459

src/gameloop.cpp
src/gameloop.h
src/level.cpp
src/level.h
src/player.cpp
src/setup.cpp
src/special.cpp
src/title.cpp
src/world.cpp
src/world.h

index e9b402f..fc3e73c 100644 (file)
@@ -10,6 +10,7 @@
   April 11, 2000 - March 15, 2004
 */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
@@ -44,7 +45,6 @@
 
 /* extern variables */
 
-Level current_level;
 int game_started = false;
 
 /* Local variables: */
@@ -61,8 +61,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);
@@ -70,7 +71,74 @@ void drawstatus(void);
 void drawendscreen(void);
 void drawresultscreen(void);
 
-void levelintro(void)
+GameSession::GameSession()
+{
+  current_ = this;
+  assert(0);
+}
+
+GameSession::GameSession(const std::string& filename)
+{
+  current_ = this;
+
+  timer_init(&fps_timer, true);
+  timer_init(&frame_timer, true);
+
+  current_level.load(filename);
+}
+
+GameSession::GameSession(const std::string& subset, int levelnb, int mode)
+{
+  current_ = this;
+
+  timer_init(&fps_timer, true);
+  timer_init(&frame_timer, true);
+
+  game_started = true;
+
+  st_gl_mode = mode;
+  level = levelnb;
+
+  /* Init the game: */
+  arrays_free();
+  set_defaults();
+
+  strcpy(level_subset, subset.c_str());
+
+  if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
+    {
+      if (current_level.load(level_subset))
+        exit(1);
+    }
+  else
+    {
+      if(current_level.load(level_subset, level) != 0)
+        exit(1);
+    }
+
+  current_level.load_gfx();
+  loadshared();
+  activate_bad_guys(&current_level);
+  activate_particle_systems();
+  current_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: */
@@ -92,7 +160,8 @@ void levelintro(void)
 }
 
 /* Reset Timers */
-void start_timers(void)
+void
+GameSession::start_timers()
 {
   timer_start(&time_left,current_level.time_left*1000);
   st_pause_ticks_init();
@@ -109,7 +178,8 @@ void activate_bad_guys(Level* plevel)
     }
 }
 
-void activate_particle_systems(void)
+void
+GameSession::activate_particle_systems()
 {
   if(current_level.particle_system == "clouds")
     {
@@ -125,9 +195,8 @@ void activate_particle_systems(void)
     }
 }
 
-/* --- GAME EVENT! --- */
-
-void game_event(void)
+void
+GameSession::process_events()
 {
   while (SDL_PollEvent(&event))
     {
@@ -294,14 +363,9 @@ void game_event(void)
     } /* while */
 }
 
-/* --- GAME ACTION! --- */
-
 int
 GameSession::action()
 {
-  unsigned int i;
-
-  /* (tux.is_dead() || next_level) */
   if (tux.is_dead() || next_level)
     {
       /* Tux either died, or reached the end of a level! */
@@ -388,21 +452,14 @@ GameSession::action()
   tux.action();
 
   /* Handle bouncy distros: */
-  for (i = 0; i < bouncy_distros.size(); i++)
-    {
-      bouncy_distro_action(&bouncy_distros[i]);
-    }
-
+  for (unsigned int i = 0; i < bouncy_distros.size(); i++)
+    bouncy_distro_action(&bouncy_distros[i]);
 
   /* Handle broken bricks: */
-  for (i = 0; i < broken_bricks.size(); i++)
-    {
+  for (unsigned int i = 0; i < broken_bricks.size(); i++)
       broken_brick_action(&broken_bricks[i]);
-    }
-
 
   /* Handle distro counting: */
-
   if (counting_distros)
     {
       distro_counter--;
@@ -411,44 +468,21 @@ GameSession::action()
         counting_distros = -1;
     }
 
+  // Handle all kinds of game objects
+  for (unsigned int i = 0; i < bouncy_bricks.size(); i++)
+    bouncy_brick_action(&bouncy_bricks[i]);
+  
+  for (unsigned int i = 0; i < floating_scores.size(); i++)
+    floating_score_action(&floating_scores[i]);
 
-  /* Handle bouncy bricks: */
-
-  for (i = 0; i < bouncy_bricks.size(); i++)
-    {
-      bouncy_brick_action(&bouncy_bricks[i]);
-    }
-
-
-  /* Handle floating scores: */
-
-  for (i = 0; i < floating_scores.size(); i++)
-    {
-      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 (unsigned int i = 0; i < bullets.size(); ++i)
+    bullet_action(&bullets[i]);
+  
+  for (unsigned int i = 0; i < upgrades.size(); i++)
+    upgrade_action(&upgrades[i]);
 
-  for (i = 0; i < bad_guys.size(); i++)
-    {
-      bad_guys[i].action();
-    }
+  for (unsigned int i = 0; i < bad_guys.size(); i++)
+    bad_guys[i].action();
 
   /* update particle systems */
   std::vector<ParticleSystem*>::iterator p;
@@ -579,59 +613,12 @@ GameSession::draw()
   updatescreen();
 }
 
-/* --- GAME LOOP! --- */
-
-GameSession::GameSession(const char * subset, int levelnb, int mode)
-{
-  timer_init(&fps_timer, true);
-  timer_init(&frame_timer, true);
-
-  game_started = true;
-
-  st_gl_mode = mode;
-  level = levelnb;
-
-  /* Init the game: */
-  arrays_free();
-  set_defaults();
-
-  strcpy(level_subset,subset);
-
-  if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
-    {
-      if (current_level.load(level_subset))
-        exit(1);
-    }
-  else
-    {
-      if(current_level.load(level_subset, level) != 0)
-        exit(1);
-    }
-
-  current_level.load_gfx();
-  loadshared();
-  activate_bad_guys(&current_level);
-  activate_particle_systems();
-  current_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);
-}
 
 int
 GameSession::run()
 {
+  current_ = this;
+  
   int  fps_cnt;
   bool jump;
   bool done;
@@ -677,7 +664,7 @@ GameSession::run()
 
       tux.input.old_fire = tux.input.fire;
 
-      game_event();
+      process_events();
 
       if(show_menu)
         {
@@ -1198,50 +1185,7 @@ void drawshape(float x, float y, unsigned int c, Uint8 alpha)
     }
 }
 
-/* Break a brick: */
-void trybreakbrick(float x, float y, bool small)
-{
-  Tile* tile = gettile(x, y);
-  if (tile->brick)
-    {
-      if (tile->data > 0)
-        {
-          /* Get a distro from it: */
-          add_bouncy_distro(((int)(x + 1) / 32) * 32,
-                            (int)(y / 32) * 32);
-
-          if (!counting_distros)
-            {
-              counting_distros = true;
-              distro_counter = 50;
-            }
-
-          if (distro_counter <= 0)
-            current_level.change(x, y, TM_IA, tile->next_tile);
-
-          play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
-          score = score + SCORE_DISTRO;
-          distros++;
-        }
-      else if (!small)
-        {
-          /* Get rid of it: */
-          current_level.change(x, y, TM_IA, tile->next_tile);
-          
-          /* 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,
@@ -1250,95 +1194,6 @@ void bumpbrick(float x, float y)
   play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
 }
 
-/* Empty a box: */
-void tryemptybox(float x, float y, int col_side)
-{
-  Tile* tile = gettile(x,y);
-  if (!tile->fullbox)
-    return;
-
-  // according to the collision side, set the upgrade direction
-  if(col_side == LEFT)
-    col_side = RIGHT;
-  else
-    col_side = LEFT;
-
-  switch(tile->data)
-    {
-    case 1: //'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 2: // '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 3:// '!':     /* 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: */
-  current_level.change(x, y, TM_IA, tile->next_tile);
-}
-
-/* Try to grab a distro: */
-void trygrabdistro(float x, float y, int bounciness)
-{
-  Tile* tile = gettile(x, y);
-  if (tile && tile->distro)
-    {
-      current_level.change(x, y, TM_IA, tile->next_tile);
-      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)
-{
-  /* Bad guys: */
-  for (unsigned int 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)
-        {
-          bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_BUMP);
-        }
-    }
-
-
-  /* Upgrades: */
-  for (unsigned int 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)
 {
@@ -1426,7 +1281,8 @@ void drawresultscreen(void)
   wait_for_event(event,2000,5000,true);
 }
 
-void savegame(int slot)
+void
+GameSession::savegame(int slot)
 {
   char savefile[1024];
   FILE* fi;
@@ -1461,7 +1317,8 @@ void savegame(int slot)
 
 }
 
-void loadgame(int slot)
+void
+GameSession::loadgame(int slot)
 {
   char savefile[1024];
   char str[100];
@@ -1498,10 +1355,10 @@ void loadgame(int slot)
       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), 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);
index b7e048b..c0dfe07 100644 (file)
 #define ST_GL_LOAD_GAME 2
 #define ST_GL_LOAD_LEVEL_FILE  3
 
-// FIXME: Make this local to the gamesession
-extern Level current_level;
-
 extern int game_started;
 
 class GameSession
 {
  private:
   timer_type fps_timer, frame_timer;
+  Level current_level;
 
  public:
-  GameSession(const char * subset, int levelnb, int mode);
+  GameSession();
+  GameSession(const std::string& filename);
+  GameSession(const std::string& subset, int levelnb, int mode);
   int  run();
   void draw();
   int  action();
+  void process_events();
+
+  Level* get_level() { return &current_level; }
+
+  void  savegame(int slot);
+  void  loadgame(int slot);
+
+  static GameSession* current() { return current_; }
+ private:
+  static GameSession* current_;
+
+  void levelintro();
+  void start_timers();
+  void activate_particle_systems();
 };
 
 void  activate_bad_guys(Level* plevel);
-void  savegame(int slot);
-void  loadgame(int slot);
+
 std::string slotinfo(int slot);
 
 bool  rectcollision(base_type* one, base_type* two);
 void  drawshape(float x, float y, unsigned int c, Uint8 alpha = 255);
 void bumpbrick(float x, float y);
 
-/** Try to grab the coin at the given coordinates */
-void trygrabdistro(float x, float y, int bounciness);
-
-/** Try to break the brick at the given coordinates */
-void trybreakbrick(float x, float y, bool small);
-
-/** Try to get the content out of a bonus box, thus emptying it */
-void tryemptybox(float x, float y, int col_side);
-
-/** Try to bumb a badguy that might we walking above Tux, thus shaking
-    the tile which the badguy is walking on an killing him this way */
-void trybumpbadguy(float x, float y);
-
 #endif /*SUPERTUX_GAMELOOP_H*/
 
index 8aa7e64..a33080f 100644 (file)
@@ -245,14 +245,14 @@ Level::load(const  char *subset, int level)
 }
 
 int 
-Level::load(const char* filename)
+Level::load(const std::string& filename)
 {
   FILE * fi;
   lisp_object_t* root_obj = 0;
-  fi = fopen(filename, "r");
+  fi = fopen(filename.c_str(), "r");
   if (fi == NULL)
     {
-      perror(filename);
+      perror(filename.c_str());
       return -1;
     }
 
@@ -262,7 +262,7 @@ Level::load(const char* filename)
 
   if (root_obj->type == LISP_TYPE_EOF || root_obj->type == LISP_TYPE_PARSE_ERROR)
     {
-      printf("World: Parse Error in file %s", filename);
+      printf("World: Parse Error in file %s", filename.c_str());
     }
 
   vector<int> ia_tm;
@@ -691,7 +691,8 @@ Level::load_song()
 }
 
 
-unsigned int gettileid(float x, float y)
+unsigned int 
+Level::gettileid(float x, float y)
 {
   int xx, yy;
   unsigned int c;
@@ -699,8 +700,8 @@ unsigned int gettileid(float x, float y)
   yy = ((int)y / 32);
   xx = ((int)x / 32);
 
-  if (yy >= 0 && yy < 15 && xx >= 0 && xx <= current_level.width)
-    c = current_level.ia_tiles[yy][xx];
+  if (yy >= 0 && yy < 15 && xx >= 0 && xx <= width)
+    c = ia_tiles[yy][xx];
   else
     c = 0;
 
@@ -709,36 +710,36 @@ unsigned int gettileid(float x, float y)
 
 Tile* gettile(float x, float y)
 {
-  return TileManager::instance()->get(gettileid(x, y));
+  return TileManager::instance()->get(GameSession::current()->get_level()->gettileid(x, y));
 }
 
 bool issolid(float x, float y)
 {
-  Tile* tile = TileManager::instance()->get(gettileid(x,y));
+  Tile* tile = gettile(x,y);
   return tile && tile->solid;
 }
 
 bool isbrick(float x, float y)
 {
-  Tile* tile = TileManager::instance()->get(gettileid(x,y));
+  Tile* tile = gettile(x,y);
   return tile && tile->brick;
 }
 
 bool isice(float x, float y)
 {
-  Tile* tile = TileManager::instance()->get(gettileid(x,y));
+  Tile* tile = gettile(x,y);
   return tile && tile->ice;
 }
 
 bool isfullbox(float x, float y)
 {
-  Tile* tile = TileManager::instance()->get(gettileid(x,y));
+  Tile* tile = gettile(x,y);
   return tile && tile->fullbox;
 }
 
 bool isdistro(float x, float y)
 {
-  Tile* tile = TileManager::instance()->get(gettileid(x,y));
+  Tile* tile = gettile(x,y);
   return tile && tile->distro;
 }
 
index dc946ad..ad15356 100644 (file)
@@ -82,7 +82,7 @@ class Level
   void cleanup();
 
   int  load(const char* subset, int level);
-  int  load(const char* filename);
+  int  load(const std::string& filename);
 
   void load_gfx();
   void load_song();
@@ -94,15 +94,15 @@ class Level
 
   /** Resize the level to a new width */
   void change_size (int new_width);
+
+  /** Return the id of the tile at position x/y */
+  unsigned int gettileid(float x, float y);
 };
 
 void level_load_image(texture_type* ptexture, std::string theme, const char * file, int use_alpha);
 void level_free_song();
 void level_free_gfx();
 
-/** Return the id of the tile at the given x/y coordinates */
-unsigned int gettileid(float x, float y);
-
 /** Return a pointer to the tile at the given x/y coordinates */
 Tile* gettile(float x, float y);
 
index ea91fcd..d6b09bd 100644 (file)
@@ -914,6 +914,8 @@ Player::remove_powerups()
 void
 Player::keep_in_bounds()
 {
+  Level* plevel = GameSession::current()->get_level();
+
   /* Keep tux in bounds: */
   if (base.x< 0)
     base.x= 0;
@@ -928,14 +930,17 @@ Player::keep_in_bounds()
         scroll_x = 0;
 
     }
-  else if (base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w))
+  else if (base.x > screen->w / 2 + scroll_x
+           && scroll_x < ((GameSession::current()->get_level()->width * 32) - screen->w))
     {
-      // Scroll the screen in past center:
+      // FIXME: Scrolling needs to be handled by a seperate View
+      // class, doing it as a player huck is ugly
 
+      // Scroll the screen in past center:
       scroll_x = base.x - screen->w / 2;
 
-      if (scroll_x > ((current_level.width * 32) - screen->w))
-        scroll_x = ((current_level.width * 32) - screen->w);
+      if (scroll_x > ((plevel->width * 32) - screen->w))
+        scroll_x = ((plevel->width * 32) - screen->w);
     }
   else if (base.x> 608 + scroll_x)
     {
index 1e1b22b..421bcec 100644 (file)
@@ -453,7 +453,7 @@ void process_save_game_menu()
 {
   int slot = save_game_menu->check();
   if (slot != -1)
-    savegame(slot - 1);
+    GameSession::current()->savegame(slot - 1);
 }
 
 bool process_load_game_menu()
@@ -486,7 +486,8 @@ bool process_load_game_menu()
             }
           else
             {
-              loadgame(slot - 1);
+              //loadgame(slot - 1);
+              puts("Warning: Loading games isn't supported at the moment");
             }
         }
       st_pause_ticks_stop();
index 53b372f..2e5a05a 100644 (file)
@@ -52,28 +52,28 @@ void bullet_init(bullet_type* pbullet, float x, float y, float xm, int dir)
 
 void bullet_action(bullet_type* pbullet)
 {
-      pbullet->base.x = pbullet->base.x + pbullet->base.xm * frame_ratio;
-      pbullet->base.y = pbullet->base.y + pbullet->base.ym * frame_ratio;
+  pbullet->base.x = pbullet->base.x + pbullet->base.xm * frame_ratio;
+  pbullet->base.y = pbullet->base.y + pbullet->base.ym * frame_ratio;
 
-      collision_swept_object_map(&pbullet->old_base,&pbullet->base);
+  collision_swept_object_map(&pbullet->old_base,&pbullet->base);
       
-      if (issolid(pbullet->base.x, pbullet->base.y + 4) || issolid(pbullet->base.x, pbullet->base.y))
-        {
-              pbullet->base.ym = -pbullet->base.ym;
-             pbullet->base.y = (int)(pbullet->base.y / 32) * 32;
-        }
+  if (issolid(pbullet->base.x, pbullet->base.y + 4) || issolid(pbullet->base.x, pbullet->base.y))
+    {
+      pbullet->base.ym = -pbullet->base.ym;
+      pbullet->base.y = (int)(pbullet->base.y / 32) * 32;
+    }
 
-      pbullet->base.ym = pbullet->base.ym + GRAVITY;
+  pbullet->base.ym = pbullet->base.ym + GRAVITY;
 
-      if (pbullet->base.x < scroll_x ||
-          pbullet->base.x > scroll_x + screen->w ||
-         pbullet->base.y < 0 ||
-         pbullet->base.y > screen->h ||
-         issolid(pbullet->base.x + 4, pbullet->base.y + 2) ||
-         issolid(pbullet->base.x, pbullet->base.y + 2))
-        {
-          bullets.erase(static_cast<std::vector<bullet_type>::iterator>(pbullet));
-        }
+  if (pbullet->base.x < scroll_x ||
+      pbullet->base.x > scroll_x + screen->w ||
+      pbullet->base.y < 0 ||
+      pbullet->base.y > screen->h ||
+      issolid(pbullet->base.x + 4, pbullet->base.y + 2) ||
+      issolid(pbullet->base.x, pbullet->base.y + 2))
+    {
+      bullets.erase(static_cast<std::vector<bullet_type>::iterator>(pbullet));
+    }
 
 }
 
@@ -92,10 +92,10 @@ void bullet_collision(bullet_type* pbullet, int c_object)
   if(c_object == CO_BADGUY) {
     std::vector<bullet_type>::iterator i;
     for(i = bullets.begin(); i != bullets.end(); ++i) {
-        if(& (*i) == pbullet) {
-            bullets.erase(i);
-            return;
-        }
+      if(& (*i) == pbullet) {
+        bullets.erase(i);
+        return;
+      }
     }
   }
 }
@@ -120,105 +120,105 @@ void upgrade_action(upgrade_type *pupgrade)
 {
 
 
-      if (pupgrade->base.height < 32)
-        {
-          /* Rise up! */
+  if (pupgrade->base.height < 32)
+    {
+      /* Rise up! */
 
-          pupgrade->base.height = pupgrade->base.height + 0.7 * frame_ratio;
-          if(pupgrade->base.height > 32)
-            pupgrade->base.height = 32;
-        }
-      else
-        {
-          /* Move around? */
+      pupgrade->base.height = pupgrade->base.height + 0.7 * frame_ratio;
+      if(pupgrade->base.height > 32)
+        pupgrade->base.height = 32;
+    }
+  else
+    {
+      /* Move around? */
 
-          if (pupgrade->kind == UPGRADE_MINTS ||
-              pupgrade->kind == UPGRADE_HERRING)
-            {
-              pupgrade->base.x = pupgrade->base.x + pupgrade->base.xm * frame_ratio;
-              pupgrade->base.y = pupgrade->base.y + pupgrade->base.ym * frame_ratio;
+      if (pupgrade->kind == UPGRADE_MINTS ||
+          pupgrade->kind == UPGRADE_HERRING)
+        {
+          pupgrade->base.x = pupgrade->base.x + pupgrade->base.xm * frame_ratio;
+          pupgrade->base.y = pupgrade->base.y + pupgrade->base.ym * frame_ratio;
 
-              collision_swept_object_map(&pupgrade->old_base,&pupgrade->base);
+          collision_swept_object_map(&pupgrade->old_base,&pupgrade->base);
 
-              /* Off the screen?  Kill it! */
+          /* Off the screen?  Kill it! */
 
-              if (pupgrade->base.x < scroll_x - pupgrade->base.width)
-                upgrades.erase(static_cast<std::vector<upgrade_type>::iterator>(pupgrade));
-              if (pupgrade->base.y > screen->h)
-                upgrades.erase(static_cast<std::vector<upgrade_type>::iterator>(pupgrade));
+          if (pupgrade->base.x < scroll_x - pupgrade->base.width)
+            upgrades.erase(static_cast<std::vector<upgrade_type>::iterator>(pupgrade));
+          if (pupgrade->base.y > screen->h)
+            upgrades.erase(static_cast<std::vector<upgrade_type>::iterator>(pupgrade));
 
-              if (issolid(pupgrade->base.x + 1, pupgrade->base.y + 32.) ||
-                  issolid(pupgrade->base.x + 31., pupgrade->base.y + 32.))
+          if (issolid(pupgrade->base.x + 1, pupgrade->base.y + 32.) ||
+              issolid(pupgrade->base.x + 31., pupgrade->base.y + 32.))
+            {
+              if (pupgrade->base.ym > 0)
                 {
-                  if (pupgrade->base.ym > 0)
+                  if (pupgrade->kind == UPGRADE_MINTS)
                     {
-                      if (pupgrade->kind == UPGRADE_MINTS)
-                        {
-                          pupgrade->base.ym = 0;
-                        }
-                      else if (pupgrade->kind == UPGRADE_HERRING)
-                        {
-                          pupgrade->base.ym = -8;
-                        }
-
-                      pupgrade->base.y = (int)(pupgrade->base.y / 32) * 32;
+                      pupgrade->base.ym = 0;
+                    }
+                  else if (pupgrade->kind == UPGRADE_HERRING)
+                    {
+                      pupgrade->base.ym = -8;
                     }
-                }
-              else
-                pupgrade->base.ym = pupgrade->base.ym + GRAVITY * frame_ratio;
 
-              if (issolid(pupgrade->base.x - 1, (int) pupgrade->base.y))
-                {
-                  if(pupgrade->base.xm < 0)
-                    pupgrade->base.xm = -pupgrade->base.xm;
-                }
-              else if (issolid(pupgrade->base.x + pupgrade->base.width, (int) pupgrade->base.y))
-                {
-                  if(pupgrade->base.xm > 0)
-                    pupgrade->base.xm = -pupgrade->base.xm;
+                  pupgrade->base.y = (int)(pupgrade->base.y / 32) * 32;
                 }
             }
+          else
+            pupgrade->base.ym = pupgrade->base.ym + GRAVITY * frame_ratio;
 
+          if (issolid(pupgrade->base.x - 1, (int) pupgrade->base.y))
+            {
+              if(pupgrade->base.xm < 0)
+                pupgrade->base.xm = -pupgrade->base.xm;
+            }
+          else if (issolid(pupgrade->base.x + pupgrade->base.width, (int) pupgrade->base.y))
+            {
+              if(pupgrade->base.xm > 0)
+                pupgrade->base.xm = -pupgrade->base.xm;
+            }
         }
+
+    }
 }
 
 void upgrade_draw(upgrade_type* pupgrade)
 {
   SDL_Rect dest;
-      if (pupgrade->base.height < 32)
+  if (pupgrade->base.height < 32)
+    {
+      /* Rising up... */
+
+      dest.x = (int)(pupgrade->base.x - scroll_x);
+      dest.y = (int)(pupgrade->base.y + 32 - pupgrade->base.height);
+      dest.w = 32;
+      dest.h = (int)pupgrade->base.height;
+
+      if (pupgrade->kind == UPGRADE_MINTS)
+        texture_draw_part(&img_mints,0,0,dest.x,dest.y,dest.w,dest.h);
+      else if (pupgrade->kind == UPGRADE_COFFEE)
+        texture_draw_part(&img_coffee,0,0,dest.x,dest.y,dest.w,dest.h);
+      else if (pupgrade->kind == UPGRADE_HERRING)
+        texture_draw_part(&img_golden_herring,0,0,dest.x,dest.y,dest.w,dest.h);
+    }
+  else
+    {
+      if (pupgrade->kind == UPGRADE_MINTS)
         {
-          /* Rising up... */
-
-          dest.x = (int)(pupgrade->base.x - scroll_x);
-          dest.y = (int)(pupgrade->base.y + 32 - pupgrade->base.height);
-          dest.w = 32;
-          dest.h = (int)pupgrade->base.height;
-
-          if (pupgrade->kind == UPGRADE_MINTS)
-            texture_draw_part(&img_mints,0,0,dest.x,dest.y,dest.w,dest.h);
-          else if (pupgrade->kind == UPGRADE_COFFEE)
-            texture_draw_part(&img_coffee,0,0,dest.x,dest.y,dest.w,dest.h);
-          else if (pupgrade->kind == UPGRADE_HERRING)
-            texture_draw_part(&img_golden_herring,0,0,dest.x,dest.y,dest.w,dest.h);
+          texture_draw(&img_mints,
+                       pupgrade->base.x - scroll_x, pupgrade->base.y);
         }
-      else
+      else if (pupgrade->kind == UPGRADE_COFFEE)
         {
-          if (pupgrade->kind == UPGRADE_MINTS)
-            {
-              texture_draw(&img_mints,
-                           pupgrade->base.x - scroll_x, pupgrade->base.y);
-            }
-          else if (pupgrade->kind == UPGRADE_COFFEE)
-            {
-              texture_draw(&img_coffee,
-                           pupgrade->base.x - scroll_x, pupgrade->base.y);
-            }
-          else if (pupgrade->kind == UPGRADE_HERRING)
-            {
-              texture_draw(&img_golden_herring,
-                           pupgrade->base.x - scroll_x, pupgrade->base.y);
-            }
+          texture_draw(&img_coffee,
+                       pupgrade->base.x - scroll_x, pupgrade->base.y);
         }
+      else if (pupgrade->kind == UPGRADE_HERRING)
+        {
+          texture_draw(&img_golden_herring,
+                       pupgrade->base.x - scroll_x, pupgrade->base.y);
+        }
+    }
 }
 
 void upgrade_collision(upgrade_type* pupgrade, void* p_c_object, int c_object)
@@ -244,11 +244,11 @@ void upgrade_collision(upgrade_type* pupgrade, void* p_c_object, int c_object)
           pplayer->base.height = 64;
          pplayer->base.y -= 32;
          if(collision_object_map(&pplayer->base))
-         {
-         pplayer->base.height = 32;
-         pplayer->base.y += 32;
-         pplayer->duck = true;
-         }
+            {
+              pplayer->base.height = 32;
+              pplayer->base.y += 32;
+              pplayer->duck = true;
+            }
           timer_start(&super_bkgd_timer, 350);
         }
       else if (pupgrade->kind == UPGRADE_COFFEE)
index 263b188..b90a631 100644 (file)
@@ -40,7 +40,6 @@
 #include "math.h"
 
 void loadshared(void);
-void activate_particle_systems(void);
 
 static texture_type bkg_title;
 static texture_type logo;
@@ -65,10 +64,10 @@ void draw_background()
   texture_draw_bg(&bkg_title);
 }
 
-void draw_demo()
+void draw_demo(Level* plevel)
 {
-  /* DEMO begin */
-  /* update particle systems */
+  /* FIXME:
+  // update particle systems
   std::vector<ParticleSystem*>::iterator p;
   for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
     {
@@ -80,6 +79,7 @@ void draw_demo()
     {
       (*p)->draw(scroll_x, 0, 0);
     }
+  */
 
   // Draw interactive tiles:
   for (int y = 0; y < 15; ++y)
@@ -87,7 +87,7 @@ void draw_demo()
       for (int x = 0; x < 21; ++x)
         {
           drawshape(32*x - fmodf(scroll_x, 32), y * 32,
-                    current_level.ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
+                    plevel->ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
         }
     }
 
@@ -108,9 +108,9 @@ void draw_demo()
     }
   
   // Wrap around at the end of the level back to the beginnig
-  if(current_level.width * 32 - 320 < titletux.base.x)
+  if(plevel->width * 32 - 320 < titletux.base.x)
     {
-      titletux.base.x = titletux.base.x - (current_level.width * 32 - 640);
+      titletux.base.x = titletux.base.x - (plevel->width * 32 - 640);
       scroll_x = titletux.base.x - 320;
     }
 
@@ -142,9 +142,9 @@ int title(void)
 
   st_pause_ticks_init();
 
-  current_level.load((datadir + "/levels/misc/menu.stl").c_str());
+  GameSession session(datadir + "/levels/misc/menu.stl");
   loadshared();
-  activate_particle_systems();
+  //FIXME:activate_particle_systems();
   /* Lower the gravity that tux doesn't jump to hectically through the demo */
   //gravity = 5;
 
@@ -215,8 +215,8 @@ int title(void)
 
       /* Draw the background: */
       draw_background();
-      draw_demo();
-
+      draw_demo(session.get_level());
+      
       if (current_menu == main_menu)
         texture_draw(&logo, 160, 30);
 
index 5a07ed6..f198e81 100644 (file)
@@ -17,6 +17,7 @@
 #include "screen.h"
 #include "defines.h"
 #include "world.h"
+#include "tile.h"
 
 texture_type img_distro[4];
 
@@ -81,11 +82,11 @@ void broken_brick_draw(broken_brick_type* pbroken_brick)
 
 void bouncy_brick_init(bouncy_brick_type* pbouncy_brick, float x, float y)
 {
-  pbouncy_brick->base.x = x;
-  pbouncy_brick->base.y = y;
-  pbouncy_brick->offset = 0;
+  pbouncy_brick->base.x   = x;
+  pbouncy_brick->base.y   = y;
+  pbouncy_brick->offset   = 0;
   pbouncy_brick->offset_m = -BOUNCY_BRICK_SPEED;
-  pbouncy_brick->shape gettileid(x, y);
+  pbouncy_brick->shape    = GameSession::current()->get_level()->gettileid(x, y);
 }
 
 void bouncy_brick_action(bouncy_brick_type* pbouncy_brick)
@@ -119,13 +120,15 @@ void bouncy_brick_draw(bouncy_brick_type* pbouncy_brick)
       dest.w = 32;
       dest.h = 32;
 
+      Level* plevel = GameSession::current()->get_level();
+
       // FIXME: overdrawing hack to clean the tile from the screen to
       // paint it later at on offseted position
-      if(current_level.bkgd_image[0] == '\0')
+      if(plevel->bkgd_image[0] == '\0')
         {
           fillrect(pbouncy_brick->base.x - scroll_x, pbouncy_brick->base.y,
-                   32,32,current_level.bkgd_red,current_level.bkgd_green,
-                   current_level.bkgd_blue,0);
+                   32,32, 
+                   plevel->bkgd_red, plevel->bkgd_green, plevel->bkgd_blue, 0);
         }
       else
         {
@@ -163,5 +166,140 @@ void floating_score_draw(floating_score_type* pfloating_score)
   text_draw(&gold_text, str, (int)pfloating_score->base.x + 16 - strlen(str) * 8, (int)pfloating_score->base.y, 1);
 }
 
+/* Break a brick: */
+void trybreakbrick(float x, float y, bool small)
+{
+  Level* plevel = GameSession::current()->get_level();
+  
+  Tile* tile = gettile(x, y);
+  if (tile->brick)
+    {
+      if (tile->data > 0)
+        {
+          /* Get a distro from it: */
+          add_bouncy_distro(((int)(x + 1) / 32) * 32,
+                            (int)(y / 32) * 32);
+
+          if (!counting_distros)
+            {
+              counting_distros = true;
+              distro_counter = 50;
+            }
+
+          if (distro_counter <= 0)
+            plevel->change(x, y, TM_IA, tile->next_tile);
+
+          play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+          score = score + SCORE_DISTRO;
+          distros++;
+        }
+      else if (!small)
+        {
+          /* Get rid of it: */
+          plevel->change(x, y, TM_IA, tile->next_tile);
+          
+          /* 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;
+        }
+    }
+}
+
+/* Empty a box: */
+void tryemptybox(float x, float y, int col_side)
+{
+  Level* plevel = GameSession::current()->get_level();
+
+  Tile* tile = gettile(x,y);
+  if (!tile->fullbox)
+    return;
+
+  // according to the collision side, set the upgrade direction
+  if(col_side == LEFT)
+    col_side = RIGHT;
+  else
+    col_side = LEFT;
+
+  switch(tile->data)
+    {
+    case 1: //'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 2: // '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 3:// '!':     /* 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: */
+  plevel->change(x, y, TM_IA, tile->next_tile);
+}
+
+/* Try to grab a distro: */
+void trygrabdistro(float x, float y, int bounciness)
+{
+  Level* plevel = GameSession::current()->get_level();
+  Tile* tile = gettile(x, y);
+  if (tile && tile->distro)
+    {
+      plevel->change(x, y, TM_IA, tile->next_tile);
+      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)
+{
+  /* Bad guys: */
+  for (unsigned int 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)
+        {
+          bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_BUMP);
+        }
+    }
+
+
+  /* Upgrades: */
+  for (unsigned int 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);
+        }
+    }
+}
+
 /* EOF */
 
index 243ac8e..ce285d7 100644 (file)
@@ -69,5 +69,19 @@ void floating_score_init(floating_score_type* pfloating_score, float x, float y,
 void floating_score_action(floating_score_type* pfloating_score);
 void floating_score_draw(floating_score_type* pfloating_score);
 
+
+/** Try to grab the coin at the given coordinates */
+void trygrabdistro(float x, float y, int bounciness);
+
+/** Try to break the brick at the given coordinates */
+void trybreakbrick(float x, float y, bool small);
+
+/** Try to get the content out of a bonus box, thus emptying it */
+void tryemptybox(float x, float y, int col_side);
+
+/** Try to bumb a badguy that might we walking above Tux, thus shaking
+    the tile which the badguy is walking on an killing him this way */
+void trybumpbadguy(float x, float y);
+
 #endif /*SUPERTUX_WORLD_H*/