- memleak fix and menu fix from MatzeB
authorIngo Ruhnke <grumbel@gmx.de>
Sun, 25 Apr 2004 21:55:39 +0000 (21:55 +0000)
committerIngo Ruhnke <grumbel@gmx.de>
Sun, 25 Apr 2004 21:55:39 +0000 (21:55 +0000)
- little bullet tweaking from myself
- added story

SVN-Revision: 719

23 files changed:
data/extro.txt [new file with mode: 0644]
data/intro.txt [new file with mode: 0644]
data/supertux.strf
src/button.cpp
src/configfile.cpp
src/defines.h
src/high_scores.cpp
src/level.cpp
src/lispreader.cpp
src/menu.cpp
src/menu.h
src/setup.cpp
src/special.cpp
src/special.h
src/sprite_manager.cpp
src/text.cpp
src/texture.cpp
src/texture.h
src/tile.cpp
src/tile.h
src/title.cpp
src/worldmap.cpp
src/worldmap.h

diff --git a/data/extro.txt b/data/extro.txt
new file mode 100644 (file)
index 0000000..00d10b3
--- /dev/null
@@ -0,0 +1,33 @@
+- Entering Nolok's Throne Room! -
+
+       Tux ran into Nolok's throne room,
+       frantically searching for his beloved.
+       Alas, he found neither Penny nor Nolok
+       there, but instead, another note.
+
+       "Well done, Tux, well done. If you are
+       reading this, you have removed my
+       control over this icy fortress. But as
+       you can see, your beloved Penny is not
+       here. What you did not realize is that
+       this is just one of my many fortresses,
+       spread far across the lands!
+
+       "Tux, your ambition is most honorable,
+       but futile nonetheless. With every
+       fortress you conquer of mine, I will
+       escape to another, and take Penny with
+       me. Do not be silly... it is best that
+       you give up now."
+
+       Tux was sadly leaving the room, when he
+       felt something beneath his foot... an
+       envelope, addressed to him! Inside was
+       a roughly sketched map with fortresses
+       drawn in various lands. On the corner
+       of the map was Penny's signature, a
+       drawing of the ice flower.
+
+       Tux ran out of the fortress, map in
+       hand. No, he decided, he would not give
+       up. Penny was counting on him.
diff --git a/data/intro.txt b/data/intro.txt
new file mode 100644 (file)
index 0000000..24b6103
--- /dev/null
@@ -0,0 +1,22 @@
+- Gwen gets captured! -
+
+       Tux and Gwen were out having a nice
+       picnic on the ice fields of Antarctica.
+       Suddenly, a creature jumped from
+       behind an ice bush, there was a flash,
+       and Tux fell asleep!
+
+       When Tux wakes up, he finds that Gwen
+       is missing. Where she lay before now
+       lies a letter. "Tux, my arch enemy!"
+       says the letter. "I have captured
+       your beautiful Gwen and have taken her
+       to my fortress. The path to my fortress
+       is littered with my minions. Give up on
+       the thought of trying to reclaim her,
+       you haven't a chance! -Nolok"
+
+       Tux looks and see Nolok's fortress in
+       the distance. Determined to save his
+       beloved Gwen, he begins his journey.
+
index ca35d3a..5ea1c35 100644 (file)
@@ -1,3 +1,4 @@
+;; -*- mode: scheme; -*-
 (supertux-resources
  ;; Small Tux Walk
  (sprite (name "smalltux-walk-left")
          (images "shared/tux-duck-left.png"))
  (sprite (name "largetux-duck-right")
          (x-hotspot 6)
-         (y-hotspot 6)
+         (y-hotspot 2)
          (images "shared/tux-duck-right.png"))
 
 
                  "shared/iceflower-3.png"
                  "shared/iceflower-2.png"
                  "shared/iceflower-1.png"))
+
+ (sprite (name "bullet")
+         (x-hotspot 12)
+         (x-hotspot 12)
+         (fps 20)
+         (images "shared/bullet-1.png"
+                 "shared/bullet-2.png"
+                 "shared/bullet-3.png"
+                 "shared/bullet-4.png"))
  )
 
 ;; EOF ;;
index ddc6e4d..793f489 100644 (file)
@@ -57,7 +57,8 @@ Button::Button(std::string icon_file, std::string ninfo, SDLKey nshortcut, int x
       dest.y = 0;
       dest.w = icon->w;
       dest.h = icon->h;
-      SDL_SoftStretch(icon->impl->sdl_surface, NULL, icon->impl->sdl_surface, &dest);
+      SDL_SoftStretch(icon->impl->get_sdl_surface(), NULL,
+          icon->impl->get_sdl_surface(), &dest);
     }
   else
     icon = new Surface(filename,USE_ALPHA);
index df637ec..5be9d1a 100644 (file)
@@ -104,6 +104,8 @@ void loadconfig(void)
   reader.read_int ("keyboard-left", &keymap.left);
   reader.read_int ("keyboard-right", &keymap.right);
   reader.read_int ("keyboard-fire", &keymap.fire);
+
+  lisp_free(root_obj);
 }
 
 void saveconfig (void)
index 936216f..9c86b6d 100644 (file)
@@ -69,9 +69,8 @@ enum DyingType {
 
 #define START_LIVES 4
 
-#define MAX_BULLETS 1
+#define MAX_BULLETS 2
 
-#define GRAVITY 1.0
 #define YM_FOR_JUMP 6.0
 #define WALK_ACCELERATION_X 0.03
 #define RUN_ACCELERATION_X 0.04
index dce9593..cb3d410 100644 (file)
@@ -74,9 +74,7 @@ void load_hs(void)
     }
  
   fclose(fi);
-
-printf("name=%s\n", hs_name.c_str());
-printf("score=%i\n\n", hs_score);
+  lisp_free(root_obj);
 }
 
 void save_hs(int score)
index e30caeb..4bdf1b4 100644 (file)
@@ -127,6 +127,7 @@ void st_subset::load(char *subset)
 
         }
 
+      lisp_free(root_obj);
       fclose(fi);
 
       snprintf(str, 1024, "%s.png", filename);
@@ -203,6 +204,7 @@ void st_subset::free()
 Level::Level()
   : img_bkgd(0)
 {
+  init_defaults();
 }
 
 Level::Level(const std::string& subset, int level)
@@ -501,6 +503,7 @@ Level::load(const std::string& filename)
   else
     endpos = 32*(width-15);
 
+  lisp_free(root_obj);
   fclose(fi);
   return 0;
 }
index 30b3802..e7b8bb6 100644 (file)
 static char token_string[MAX_TOKEN_LENGTH + 1] = "";
 static int token_length = 0;
 
-static lisp_object_t end_marker = { LISP_TYPE_EOF , {0,0}  };
-static lisp_object_t error_object = { LISP_TYPE_PARSE_ERROR , {0,0}  };
-static lisp_object_t close_paren_marker = { LISP_TYPE_PARSE_ERROR , {0,0}  };
-static lisp_object_t dot_marker = { LISP_TYPE_PARSE_ERROR , {0,0} };
+static lisp_object_t end_marker = { LISP_TYPE_EOF, {{0, 0}} };
+static lisp_object_t error_object = { LISP_TYPE_PARSE_ERROR , {{0,0}}  };
+static lisp_object_t close_paren_marker = { LISP_TYPE_PARSE_ERROR , {{0,0}}  };
+static lisp_object_t dot_marker = { LISP_TYPE_PARSE_ERROR , {{0,0}} };
 
 static void
 _token_clear (void)
index bc1bf16..bbf1561 100644 (file)
@@ -223,8 +223,6 @@ Menu::Menu()
   
   pos_x        = screen->w/2;
   pos_y        = screen->h/2;
-  has_backitem = false;
-  last_id = 0;
   arrange_left = 0;
   active_item  = 0;
   effect.init(false);
@@ -239,15 +237,6 @@ void Menu::set_pos(int x, int y, float rw, float rh)
 void
 Menu::additem(MenuItemKind kind_, const std::string& text_, int toggle_, Menu* menu_, int id, int* int_p)
 {
-  if(kind_ == MN_BACK)
-    has_backitem = true;
-  
-  if(id == -1 && item.size() == (unsigned)last_id)
-    {
-    id = last_id;
-    last_id++;
-    }
-
   additem(MenuItem::create(kind_, text_.c_str(), toggle_, menu_, id, int_p));
 }
 
@@ -255,9 +244,6 @@ Menu::additem(MenuItemKind kind_, const std::string& text_, int toggle_, Menu* m
 void
 Menu::additem(MenuItem* pmenu_item)
 {
-  if(pmenu_item->kind == MN_BACK)
-    has_backitem = true;
-
   item.push_back(*pmenu_item);
   delete pmenu_item;
 }
index ae56b0b..419a1e8 100644 (file)
@@ -138,8 +138,6 @@ private:
   // position of the menu (ie. center of the menu, not top/left)
   int pos_x;
   int pos_y;
-  bool has_backitem;
-  int last_id;
 
   /** input event for the menu (up, down, left, right, etc.) */
   MenuAction menuaction;
index 0580ac6..60ebc4c 100644 (file)
@@ -55,6 +55,8 @@
 
 #include "player.h"
 
+void display_text_file(char *filename);
+
 #ifdef WIN32
 #define mkdir(dir, mode)    mkdir(dir)
 // on win32 we typically don't want LFS paths
@@ -437,21 +439,21 @@ void st_menu(void)
   
   load_game_menu->additem(MN_LABEL,"Start Game",0,0);
   load_game_menu->additem(MN_HL,"",0,0);
-  load_game_menu->additem(MN_DEACTIVE,"Slot 1",0,0);
-  load_game_menu->additem(MN_DEACTIVE,"Slot 2",0,0);
-  load_game_menu->additem(MN_DEACTIVE,"Slot 3",0,0);
-  load_game_menu->additem(MN_DEACTIVE,"Slot 4",0,0);
-  load_game_menu->additem(MN_DEACTIVE,"Slot 5",0,0);
+  load_game_menu->additem(MN_DEACTIVE,"Slot 1",0,0, 1);
+  load_game_menu->additem(MN_DEACTIVE,"Slot 2",0,0, 2);
+  load_game_menu->additem(MN_DEACTIVE,"Slot 3",0,0, 3);
+  load_game_menu->additem(MN_DEACTIVE,"Slot 4",0,0, 4);
+  load_game_menu->additem(MN_DEACTIVE,"Slot 5",0,0, 5);
   load_game_menu->additem(MN_HL,"",0,0);
   load_game_menu->additem(MN_BACK,"Back",0,0);
 
   save_game_menu->additem(MN_LABEL,"Save Game",0,0);
   save_game_menu->additem(MN_HL,"",0,0);
-  save_game_menu->additem(MN_DEACTIVE,"Slot 1",0,0);
-  save_game_menu->additem(MN_DEACTIVE,"Slot 2",0,0);
-  save_game_menu->additem(MN_DEACTIVE,"Slot 3",0,0);
-  save_game_menu->additem(MN_DEACTIVE,"Slot 4",0,0);
-  save_game_menu->additem(MN_DEACTIVE,"Slot 5",0,0);
+  save_game_menu->additem(MN_DEACTIVE,"Slot 1",0,0, 1);
+  save_game_menu->additem(MN_DEACTIVE,"Slot 2",0,0, 2);
+  save_game_menu->additem(MN_DEACTIVE,"Slot 3",0,0, 3);
+  save_game_menu->additem(MN_DEACTIVE,"Slot 4",0,0, 4);
+  save_game_menu->additem(MN_DEACTIVE,"Slot 5",0,0, 5);
   save_game_menu->additem(MN_HL,"",0,0);
   save_game_menu->additem(MN_BACK,"Back",0,0);
 
@@ -489,14 +491,14 @@ bool process_load_game_menu()
 {
   int slot = load_game_menu->check();
 
-  if(slot != -1 && load_game_menu->get_item(slot).kind == MN_ACTION)
+  if(slot != -1 && load_game_menu->get_item_by_id(slot).kind == MN_ACTION)
     {
       char slotfile[1024];
-      snprintf(slotfile, 1024, "%s/slot%d.stsg", st_save_dir, slot-1);
+      snprintf(slotfile, 1024, "%s/slot%d.stsg", st_save_dir, slot);
 
       if (access(slotfile, F_OK) != 0)
         {
-          draw_intro();
+          display_text_file("intro.txt");
         }
 
       WorldMapNS::WorldMap worldmap;
index ee7dacc..aac3458 100644 (file)
@@ -18,6 +18,7 @@
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include <assert.h>
+#include <iostream>
 #include "SDL.h"
 #include "defines.h"
 #include "special.h"
@@ -30,8 +31,7 @@
 #include "sprite_manager.h"
 #include "resources.h"
 
-Surface* img_bullet;
-
+Sprite* img_bullet;
 Sprite* img_star;
 Sprite* img_growup;
 Sprite* img_iceflower;
@@ -39,6 +39,9 @@ Sprite* img_1up;
 
 #define GROWUP_SPEED 1.0f
 
+#define BULLET_STARTING_YM 0
+#define BULLET_XM 6
+
 void
 Bullet::init(float x, float y, float xm, Direction dir)
 {
@@ -79,6 +82,10 @@ Bullet::remove_me()
 void
 Bullet::action(double frame_ratio)
 {
+  frame_ratio *= 0.5f;
+
+  float old_y = base.y;
+
   base.x = base.x + base.xm * frame_ratio;
   base.y = base.y + base.ym * frame_ratio;
 
@@ -86,11 +93,15 @@ Bullet::action(double frame_ratio)
       
   if (issolid(base.x, base.y + 4) || issolid(base.x, base.y))
     {
-      base.ym = -base.ym;
-      base.y = (int)(base.y / 32) * 32;
+      base.y  = old_y;
+      base.ym = -base.ym;     
+      if (base.ym > 13)
+        base.ym = 13;
+      else if (base.ym < -13)
+        base.ym = -13;
     }
 
-  base.ym = base.ym + GRAVITY;
+  base.ym = base.ym + 0.5 * frame_ratio;
 
   if (base.x < scroll_x ||
       base.x > scroll_x + screen->w ||
@@ -110,8 +121,7 @@ Bullet::draw()
   if (base.x >= scroll_x - base.width &&
       base.x <= scroll_x + screen->w)
     {
-      img_bullet->draw( base.x - scroll_x, base.y, 255,
-                   NO_UPDATE);
+      img_bullet->draw(base.x - scroll_x, base.y);
     }
 }
 
@@ -342,8 +352,7 @@ void load_special_gfx()
   img_star      = sprite_manager->load("star");
   img_1up       = sprite_manager->load("1up");
 
-  img_bullet = new Surface(datadir + "/images/shared/bullet.png",
-                           USE_ALPHA);
+  img_bullet    = sprite_manager->load("bullet");
 }
 
 void free_special_gfx()
index b5b518e..1cdbc4c 100644 (file)
@@ -17,9 +17,6 @@
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-#define BULLET_STARTING_YM 1
-#define BULLET_XM 5
-
 #ifndef SUPERTUX_SPECIAL_H
 #define SUPERTUX_SPECIAL_H
 
index 3a69d6e..ca6da2f 100644 (file)
@@ -29,7 +29,8 @@ SpriteManager::SpriteManager(const std::string& filename)
 void
 SpriteManager::load_resfile(const std::string& filename)
 {
-  lisp_object_t* cur = lisp_read_from_file(filename);
+  lisp_object_t* root_obj = lisp_read_from_file(filename);
+  lisp_object_t* cur = root_obj;
 
   if (strcmp(lisp_symbol(lisp_car(cur)), "supertux-resources") != 0)
     return;
@@ -62,6 +63,8 @@ SpriteManager::load_resfile(const std::string& filename)
 
       cur = lisp_cdr(cur);
     }
+
+  lisp_free(root_obj);
 }
 
 Sprite*
index 7562034..aa5581f 100644 (file)
@@ -55,7 +55,7 @@ Text::Text(const std::string& file, int kind_, int w_, int h_)
   chars = new Surface(file, USE_ALPHA);
 
   // Load shadow font.
-  conv = SDL_DisplayFormatAlpha(chars->impl->sdl_surface);
+  conv = SDL_DisplayFormatAlpha(chars->impl->get_sdl_surface());
   pixels = conv->w * conv->h;
   SDL_LockSurface(conv);
   for(i = 0; i < pixels; ++i)
index 7e3b1de..e372063 100644 (file)
@@ -29,7 +29,7 @@
 Surface::Surfaces Surface::surfaces;
 
 SurfaceData::SurfaceData(SDL_Surface* temp, int use_alpha_)
-  : type(SURFACE), use_alpha(use_alpha_)
+  : type(SURFACE), surface(0), use_alpha(use_alpha_)
 {
   // Copy the given surface and make sure that it is not stored in
   // video memory
@@ -40,24 +40,26 @@ SurfaceData::SurfaceData(SDL_Surface* temp, int use_alpha_)
                                  temp->format->Gmask,
                                  temp->format->Bmask,
                                  temp->format->Amask);
+  if(!surface)
+    st_abort("No memory left.", "");
   SDL_SetAlpha(temp,0,0);
   SDL_BlitSurface(temp, NULL, surface, NULL);
 }
 
 SurfaceData::SurfaceData(const std::string& file_, int use_alpha_)
-  : type(LOAD), file(file_), use_alpha(use_alpha_)
+  : type(LOAD), surface(0), file(file_), use_alpha(use_alpha_)
 {
 }
   
 SurfaceData::SurfaceData(const std::string& file_, int x_, int y_, int w_, int h_, int use_alpha_)
-  : type(LOAD_PART), file(file_), use_alpha(use_alpha_),
+  : type(LOAD_PART), surface(0), file(file_), use_alpha(use_alpha_),
     x(x_), y(y_), w(w_), h(h_)
 {
 }
 
 SurfaceData::~SurfaceData()
 {
-  
+  SDL_FreeSurface(surface);  
 }
 
 SurfaceImpl*
@@ -321,6 +323,22 @@ sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, int use_alpha)
   return sdl_surface;
 }
 
+//---------------------------------------------------------------------------
+
+SurfaceImpl::SurfaceImpl()
+{
+}
+
+SurfaceImpl::~SurfaceImpl()
+{
+  SDL_FreeSurface(sdl_surface);
+}
+
+SDL_Surface* SurfaceImpl::get_sdl_surface() const
+{
+  return sdl_surface;
+}
+
 #ifndef NOOPENGL
 SurfaceOpenGL::SurfaceOpenGL(SDL_Surface* surf, int use_alpha)
 {
@@ -351,7 +369,6 @@ SurfaceOpenGL::SurfaceOpenGL(const std::string& file, int x, int y, int w, int h
 
 SurfaceOpenGL::~SurfaceOpenGL()
 {
-  SDL_FreeSurface(sdl_surface);
   glDeleteTextures(1, &gl_texture);
 }
 
@@ -367,7 +384,7 @@ SurfaceOpenGL::create_gl(SDL_Surface * surf, GLuint * tex)
   h = power_of_two(surf->h),
 
 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
-    conv = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surf->format->BitsPerPixel,
+  conv = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surf->format->BitsPerPixel,
                                 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
 #else
   conv = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surf->format->BitsPerPixel,
@@ -432,10 +449,8 @@ SurfaceOpenGL::draw(float x, float y, Uint8 alpha, bool update)
   glDisable(GL_TEXTURE_2D);
   glDisable(GL_BLEND);
   
-  /* Avoid compiler warnings */
-  if(update)
-    {}
-
+  (void) update; // avoid compiler warning
+  
   return 0;
 }
 
@@ -463,9 +478,7 @@ SurfaceOpenGL::draw_bg(Uint8 alpha, bool update)
   
   glDisable(GL_TEXTURE_2D);
 
-  /* Avoid compiler warnings */
-  if(update)
-    {}
+  (void) update; // avoid compiler warning
 
   return 0;
 }
@@ -599,7 +612,6 @@ SurfaceSDL::draw_part(float sx, float sy, float x, float y, float w, float h, Ui
 
 SurfaceSDL::~SurfaceSDL()
 {
-  SDL_FreeSurface(sdl_surface);
 }
 
 /* EOF */
index a80583d..13703f8 100644 (file)
@@ -90,23 +90,28 @@ public:
     this class */
 class SurfaceImpl
 {
-public:
+protected:
   SDL_Surface* sdl_surface;
+
+public:
   int w;
   int h;
 
 public:
+  SurfaceImpl();
+  virtual ~SurfaceImpl();
+  
   /** Return 0 on success, -2 if surface needs to be reloaded */
   virtual int draw(float x, float y, Uint8 alpha, bool update) = 0;
   virtual int draw_bg(Uint8 alpha, bool update) = 0;
   virtual int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, bool update) = 0;
+
+  SDL_Surface* get_sdl_surface() const; // @evil@ try to avoid this function
 };
 
 class SurfaceSDL : public SurfaceImpl
 {
 public:
-  
-public:
   SurfaceSDL(SDL_Surface* surf, int use_alpha);
   SurfaceSDL(const std::string& file, int use_alpha);  
   SurfaceSDL(const std::string& file, int x, int y, int w, int h, int use_alpha);
index 9d11a8f..2f66221 100644 (file)
 TileManager* TileManager::instance_  = 0;
 std::vector<TileGroup>* TileManager::tilegroups_  = 0;
 
+Tile::Tile()
+{
+}
+
+Tile::~Tile()
+{
+  for(std::vector<Surface*>::iterator i = images.begin(); i != images.end();
+      ++i) {
+    delete *i;
+  }
+  for(std::vector<Surface*>::iterator i = editor_images.begin();
+      i != editor_images.end(); ++i) {
+    delete *i;                                                                
+  }
+}
+
+//---------------------------------------------------------------------------
+
 TileManager::TileManager()
 {
   std::string filename = datadir +  "images/tilesets/supertux.stgt";
@@ -33,6 +51,12 @@ TileManager::TileManager()
 
 void TileManager::load_tileset(std::string filename)
 {
+  // free old tiles
+  for(std::vector<Tile*>::iterator i = tiles.begin(); i != tiles.end(); ++i) {
+    delete *i;
+  }
+  tiles.clear();
   lisp_object_t* root_obj = lisp_read_from_file(filename);
 
   if (!root_obj)
@@ -142,6 +166,8 @@ void TileManager::load_tileset(std::string filename)
     {
       assert(0);
     }
+
+  lisp_free(root_obj);
 }
 
 void
index 3dea6c6..740ce9b 100644 (file)
 /**
 Tile Class
 */
-struct Tile
+class Tile
 {
+public:
+  Tile();
+  ~Tile();
+
   int id;
 
   std::vector<Surface*> images;
index c419594..96dca72 100644 (file)
@@ -79,7 +79,8 @@ void generate_contrib_menu()
     {
       st_subset subset;
       subset.load(level_subsets.item[i]);
-      contrib_menu->additem(MN_GOTO, subset.title.c_str(), i, contrib_subset_menu);
+      contrib_menu->additem(MN_GOTO, subset.title.c_str(), i,
+          contrib_subset_menu, i+1);
       contrib_subsets.push_back(subset);
     }
 
@@ -96,7 +97,7 @@ void check_contrib_menu()
   int index = contrib_menu->check();
   if (index != -1)
     {
-      index -= 2; // FIXME: Hack
+      index -= 1;
       if (index >= 0 && index <= int(contrib_subsets.size()))
         {
           if (current_subset != index)
@@ -117,7 +118,7 @@ void check_contrib_menu()
                 {
                   Level level;
                   level.load(subset.name, i);
-                  contrib_subset_menu->additem(MN_ACTION, level.name, 0, 0);
+                  contrib_subset_menu->additem(MN_ACTION, level.name, 0, 0, i);
                 }
               contrib_subset_menu->additem(MN_HL,"",0,0);      
               contrib_subset_menu->additem(MN_BACK, "Back", 0, 0);
@@ -135,9 +136,8 @@ void check_contrib_subset_menu()
   int index = contrib_subset_menu->check();
   if (index != -1)
     {
-      if (contrib_subset_menu->get_item(index).kind == MN_ACTION)
+      if (contrib_subset_menu->get_item_by_id(index).kind == MN_ACTION)
         {
-          index -= 1; // FIXME: Hack
           std::cout << "Sarting level: " << index << std::endl;
           GameSession session(current_contrib_subset, index, ST_GL_PLAY);
           session.run();
@@ -453,7 +453,9 @@ void display_text_file(char *file)
 
       draw_background();
 
-      white_big_text->drawf("- Credits -", 0, screen->h-scroll, A_HMIDDLE, A_TOP, 2);
+      if (strcmp(file, "CREDITS") == 0)
+        white_big_text->drawf("- SuperTux " VERSION " -", 
+                              0, screen->h-scroll, A_HMIDDLE, A_TOP, 2);
 
       y = 0;
       for(int i = 0; i < length; i++)
index 0a3af9f..dbcc71a 100644 (file)
@@ -83,8 +83,6 @@ string_to_direction(const std::string& directory)
     return NONE;
 }
 
-TileManager* TileManager::instance_  = 0;
-
 TileManager::TileManager()
 {
   std::string stwt_filename = datadir +  "images/worldmap/antarctica.stwt";
@@ -143,6 +141,14 @@ TileManager::TileManager()
     {
       assert(0);
     }
+
+  lisp_free(root_obj);
+}
+
+TileManager::~TileManager()
+{
+  for(std::vector<Tile*>::iterator i = tiles.begin(); i != tiles.end(); ++i)
+    delete *i;
 }
 
 Tile*
@@ -152,6 +158,8 @@ TileManager::get(int i)
   return tiles[i];
 }
 
+//---------------------------------------------------------------------------
+
 Tux::Tux(WorldMap* worldmap_)
   : worldmap(worldmap_)
 {
@@ -164,6 +172,11 @@ Tux::Tux(WorldMap* worldmap_)
   input_direction = NONE;
 }
 
+Tux::~Tux()
+{
+  delete sprite;
+}
+
 void
 Tux::draw(const Point& offset)
 {
@@ -268,8 +281,21 @@ Tux::update(float delta)
     }
 }
 
+//---------------------------------------------------------------------------
+Tile::Tile()
+{
+}
+
+Tile::~Tile()
+{
+  delete sprite;
+}
+
+//---------------------------------------------------------------------------
+
 WorldMap::WorldMap()
 {
+  tile_manager = new TileManager();
   tux = new Tux(this);
 
   width  = 20;
@@ -291,6 +317,11 @@ WorldMap::WorldMap()
 WorldMap::~WorldMap()
 {
   delete tux;
+  delete tile_manager;
+
+  delete level_sprite;
+  delete leveldot_green;
+  delete leveldot_red;
 }
 
 void
@@ -362,38 +393,42 @@ WorldMap::load_map()
           cur = lisp_cdr(cur);
         }
     }
+
+    lisp_free(root_obj);
 }
 
 void WorldMap::get_level_title(Levels::pointer level)
 {
-/** get level's title */
-level->title = "<no title>";
+  /** get level's title */
+  level->title = "<no title>";
 
-FILE * fi;
-lisp_object_t* root_obj = 0;
-fi = fopen((datadir +  "levels/" + level->name).c_str(), "r");
-if (fi == NULL)
+  FILE * fi;
+  lisp_object_t* root_obj = 0;
+  fi = fopen((datadir +  "levels/" + level->name).c_str(), "r");
+  if (fi == NULL)
   {
-  perror((datadir +  "levels/" + level->name).c_str());
-  return;
+    perror((datadir +  "levels/" + level->name).c_str());
+    return;
   }
 
-lisp_stream_t stream;
-lisp_stream_init_file (&stream, fi);
-root_obj = lisp_read (&stream);
+  lisp_stream_t stream;
+  lisp_stream_init_file (&stream, fi);
+  root_obj = lisp_read (&stream);
 
-if (root_obj->type == LISP_TYPE_EOF || root_obj->type == LISP_TYPE_PARSE_ERROR)
+  if (root_obj->type == LISP_TYPE_EOF || root_obj->type == LISP_TYPE_PARSE_ERROR)
   {
-  printf("World: Parse Error in file %s", level->name.c_str());
+    printf("World: Parse Error in file %s", level->name.c_str());
   }
 
-if (strcmp(lisp_symbol(lisp_car(root_obj)), "supertux-level") == 0)
+  if (strcmp(lisp_symbol(lisp_car(root_obj)), "supertux-level") == 0)
   {
-  LispReader reader(lisp_cdr(root_obj));
-  reader.read_string("name",  &level->title);
+    LispReader reader(lisp_cdr(root_obj));
+    reader.read_string("name",  &level->title);
   }
 
-fclose(fi);
+  lisp_free(root_obj);
+
+  fclose(fi);
 }
 
 void
@@ -635,7 +670,7 @@ WorldMap::at(Point p)
          && p.y >= 0
          && p.y < height);
 
-  return TileManager::instance()->get(tilemap[width * p.y + p.x]);
+  return tile_manager->get(tilemap[width * p.y + p.x]);
 }
 
 WorldMap::Level*
@@ -797,66 +832,69 @@ WorldMap::loadgame(const std::string& filename)
   std::cout << "loadgame: " << filename << std::endl;
   savegame_file = filename;
 
-  if (access(filename.c_str(), F_OK) == 0)
-    {
-      lisp_object_t* cur = lisp_read_from_file(filename);
+  if (access(filename.c_str(), F_OK) != 0)
+    return;
+  
+  lisp_object_t* savegame = lisp_read_from_file(filename);
+  lisp_object_t* cur = savegame;
 
-      if (strcmp(lisp_symbol(lisp_car(cur)), "supertux-savegame") != 0)
-        return;
+  if (strcmp(lisp_symbol(lisp_car(cur)), "supertux-savegame") != 0)
+    return;
 
-      cur = lisp_cdr(cur);
-      LispReader reader(cur);
-  
-      reader.read_int("lives",  &player_status.lives);
-      reader.read_int("score",  &player_status.score);
-      reader.read_int("distros", &player_status.distros);
+  cur = lisp_cdr(cur);
+  LispReader reader(cur);
 
-      if (player_status.lives < 0)
-        player_status.lives = START_LIVES;
+  reader.read_int("lives",  &player_status.lives);
+  reader.read_int("score",  &player_status.score);
+  reader.read_int("distros", &player_status.distros);
 
-      lisp_object_t* tux_cur = 0;
-      if (reader.read_lisp("tux", &tux_cur))
-        {
-          Point p;
-          std::string back_str = "none";
+  if (player_status.lives < 0)
+    player_status.lives = START_LIVES;
 
-          LispReader tux_reader(tux_cur);
-          tux_reader.read_int("x", &p.x);
-          tux_reader.read_int("y", &p.y);
-          tux_reader.read_string("back", &back_str);
-          
-          tux->back_direction = string_to_direction(back_str);      
-          tux->set_tile_pos(p);
-        }
+  lisp_object_t* tux_cur = 0;
+  if (reader.read_lisp("tux", &tux_cur))
+    {
+      Point p;
+      std::string back_str = "none";
+
+      LispReader tux_reader(tux_cur);
+      tux_reader.read_int("x", &p.x);
+      tux_reader.read_int("y", &p.y);
+      tux_reader.read_string("back", &back_str);
+      
+      tux->back_direction = string_to_direction(back_str);      
+      tux->set_tile_pos(p);
+    }
 
-      lisp_object_t* level_cur = 0;
-      if (reader.read_lisp("levels", &level_cur))
+  lisp_object_t* level_cur = 0;
+  if (reader.read_lisp("levels", &level_cur))
+    {
+      while(level_cur)
         {
-          while(level_cur)
-            {
-              lisp_object_t* sym  = lisp_car(lisp_car(level_cur));
-              lisp_object_t* data = lisp_cdr(lisp_car(level_cur));
+          lisp_object_t* sym  = lisp_car(lisp_car(level_cur));
+          lisp_object_t* data = lisp_cdr(lisp_car(level_cur));
 
-              if (strcmp(lisp_symbol(sym), "level") == 0)
-                {
-                  std::string name;
-                  bool solved = false;
+          if (strcmp(lisp_symbol(sym), "level") == 0)
+            {
+              std::string name;
+              bool solved = false;
 
-                  LispReader level_reader(data);
-                  level_reader.read_string("name",   &name);
-                  level_reader.read_bool("solved", &solved);
+              LispReader level_reader(data);
+              level_reader.read_string("name",   &name);
+              level_reader.read_bool("solved", &solved);
 
-                  for(Levels::iterator i = levels.begin(); i != levels.end(); ++i)
-                    {
-                      if (name == i->name)
-                        i->solved = solved;
-                    }
+              for(Levels::iterator i = levels.begin(); i != levels.end(); ++i)
+                {
+                  if (name == i->name)
+                    i->solved = solved;
                 }
-
-              level_cur = lisp_cdr(level_cur);
             }
+
+          level_cur = lisp_cdr(level_cur);
         }
     }
+  lisp_free(savegame);
 }
 
 } // namespace WorldMapNS
index 9f0e085..f94017f 100644 (file)
@@ -46,8 +46,12 @@ struct Point
   int y;
 };
 
-struct Tile
+class Tile
 {
+public:
+  Tile();
+  ~Tile();
+  
   Surface* sprite;
 
   // Directions in which Tux is allowed to walk from this tile
@@ -65,13 +69,11 @@ class TileManager
 private:
   typedef std::vector<Tile*> Tiles;
   Tiles tiles;
-  static TileManager* instance_ ;
 
- TileManager();
 public:
-  static TileManager* instance() { return instance_ ? instance_ : instance_ = new TileManager(); }
+  TileManager();
+  ~TileManager();
 
-  void load();
   Tile* get(int i);
 };
 
@@ -102,6 +104,7 @@ private:
   void stop();
 public: 
   Tux(WorldMap* worldmap_);
+  ~Tux();
   
   void draw(const Point& offset);
   void update(float delta);
@@ -133,6 +136,8 @@ private:
   int width;
   int height;
 
+  TileManager* tile_manager;
+
 public:
   struct Level
   {