- Various fixes and cleanups.
authorTobias Gläßer <tobi.web@gmx.de>
Wed, 28 Jul 2004 23:06:12 +0000 (23:06 +0000)
committerTobias Gläßer <tobi.web@gmx.de>
Wed, 28 Jul 2004 23:06:12 +0000 (23:06 +0000)
- Added FrameRate class to SuperTux library
- More menu code C++ing.

SVN-Revision: 1662

lib/Makefile.am
lib/gui/menu.cpp
lib/gui/menu.h
lib/special/frame_rate.cpp [new file with mode: 0644]
lib/special/frame_rate.h [new file with mode: 0644]
lib/special/timer.h
src/gameloop.cpp
src/gameloop.h
src/high_scores.cpp
src/leveleditor.cpp

index 429c5ff..7dbb1d1 100644 (file)
@@ -15,6 +15,7 @@ libsupertux_la_SOURCES =app/globals.cpp \
                        special/sprite.cpp \
                        special/sprite_manager.cpp \
                        special/timer.cpp \
+                       special/frame_rate.cpp \
                        utils/configfile.cpp \
                        utils/lispreader.cpp \
                        utils/lispwriter.cpp \
@@ -45,7 +46,8 @@ libsupertuxspecial_HEADERS =special/base.h \
                        special/moving_object.h \
                        special/sprite.h \
                        special/sprite_manager.h \
-                       special/timer.h
+                       special/timer.h \
+                       special/frame_rate.h
 libsupertuxutils_HEADERS =utils/configfile.h \
                        utils/exceptions.h \
                        utils/lispreader.h \
index 7e273d6..e060e39 100644 (file)
@@ -152,15 +152,23 @@ Menu::set_current(Menu* menu)
   current_ = menu;
 }
 
+MenuItem::MenuItem(MenuItemKind _kind, int _id) : kind(_kind) , id(_id)
+{
+  list.second = 0;
+}
+
+MenuItem::MenuItem(MenuItemKind _kind, int _id, const std::string& _text) : kind(_kind) , id(_id) , text(_text)
+{
+  list.second = 0;
+}
+
 /* Return a pointer to a new menu item */
 MenuItem*
-MenuItem::create(MenuItemKind kind_, const char *text_, int init_toggle_, Menu* target_menu_, int id, int* int_p_)
+MenuItem::create(MenuItemKind kind_, const std::string& text_, int init_toggle_, Menu* target_menu_, int id_, int* int_p_)
 {
-  MenuItem *pnew_item = new MenuItem;
+  MenuItem *pnew_item = new MenuItem(kind_,id_);
 
-  pnew_item->kind = kind_;
-  pnew_item->text = (char*) malloc(sizeof(char) * (strlen(text_) + 1));
-  strcpy(pnew_item->text, text_);
+  pnew_item->text = text_;
 
   if(kind_ == MN_TOGGLE)
     pnew_item->toggled = init_toggle_;
@@ -168,10 +176,7 @@ MenuItem::create(MenuItemKind kind_, const char *text_, int init_toggle_, Menu*
     pnew_item->toggled = false;
 
   pnew_item->target_menu = target_menu_;
-  pnew_item->input = (char*) malloc(sizeof(char));
-  pnew_item->input[0] = '\0';
 
-  pnew_item->id = id;
   pnew_item->int_p = int_p_;
   
   pnew_item->list.second = 0;
@@ -184,25 +189,15 @@ MenuItem::create(MenuItemKind kind_, const char *text_, int init_toggle_, Menu*
 }
 
 void
-MenuItem::change_text(const  char *text_)
+MenuItem::change_text(const  std::string& text_)
 {
-  if (text_)
-    {
-      free(text);
-      text = (char*) malloc(sizeof(char )*(strlen(text_)+1));
-      strcpy(text, text_);
-    }
+  text = text_;
 }
 
 void
-MenuItem::change_input(const  char *text_)
+MenuItem::change_input(const  std::string& text_)
 {
-  if(text)
-    {
-      free(input);
-      input = (char*) malloc(sizeof(char )*(strlen(text_)+1));
-      strcpy(input, text_);
-    }
+  input = text_;
 }
 
 std::string MenuItem::get_input_with_symbol(bool active_item)
@@ -223,9 +218,9 @@ std::string MenuItem::get_input_with_symbol(bool active_item)
 
   char str[1024];
   if(input_flickering)
-    sprintf(str,"%s ",input);
+    sprintf(str,"%s ",input.c_str());
   else
-    sprintf(str,"%s_",input);
+    sprintf(str,"%s_",input.c_str());
 
   std::string string = str;
 
@@ -298,8 +293,6 @@ Menu::~Menu()
     {
       for(unsigned int i = 0; i < item.size(); ++i)
         {
-          free(item[i].text);
-          free(item[i].input);
           item[i].list.first.clear();
         }
     }
@@ -342,6 +335,13 @@ Menu::additem(MenuItem* pmenu_item)
   delete pmenu_item;
 }
 
+/* Add an item to a menu */
+void
+Menu::additem(const MenuItem& pmenu_item)
+{
+  item.push_back(pmenu_item);
+}
+
 void
 Menu::clear()
 {
@@ -432,13 +432,13 @@ Menu::action()
           if(item[active_item].kind == MN_TEXTFIELD
               || item[active_item].kind == MN_NUMFIELD)
             {
-              if(item[active_item].input != NULL)
+              if(!item[active_item].input.empty())
                 {
-                  int i = strlen(item[active_item].input);
+                  int i = item[active_item].input.size();
 
                   while(delete_character > 0)  /* remove charactes */
                     {
-                      item[active_item].input[i-1] = '\0';
+                      item[active_item].input.resize(i-1);
                       delete_character--;
                     }
                 }
@@ -449,19 +449,7 @@ Menu::action()
           if(item[active_item].kind == MN_TEXTFIELD
               || (item[active_item].kind == MN_NUMFIELD && mn_input_char >= '0' && mn_input_char <= '9'))
             {
-              if(item[active_item].input != NULL)
-                {
-                  int i = strlen(item[active_item].input);
-                  item[active_item].input = (char*) realloc(item[active_item].input,sizeof(char)*(i + 2));
-                  item[active_item].input[i] = mn_input_char;
-                  item[active_item].input[i+1] = '\0';
-                }
-              else
-                {
-                  item[active_item].input = (char*) malloc(2*sizeof(char));
-                  item[active_item].input[0] = mn_input_char;
-                  item[active_item].input[1] = '\0';
-                }
+              item[active_item].input.push_back(mn_input_char);
             }
 
         case MENU_ACTION_NONE:
@@ -688,7 +676,7 @@ int Menu::get_width() const
     int menu_width = 0;
     for(unsigned int i = 0; i < item.size(); ++i)
       {
-        int w = strlen(item[i].text) + (item[i].input ? strlen(item[i].input) + 1 : 0); //+ ((item[i].list.second != item[i].list.first.end()) ? (strlen((*(item[i].list.second)).c_str())) : 0);
+        int w = item[i].text.size() + item[i].input.size() + 1; //+ ((item[i].list.second != item[i].list.first.end()) ? (strlen((*(item[i].list.second)).c_str())) : 0);
         if( w > menu_width )
           {
             menu_width = w;
index f4a3943..171b142 100644 (file)
@@ -64,19 +64,22 @@ namespace SuperTux
   class MenuItem
     {
     public:
+      MenuItem() {};
+      MenuItem(MenuItemKind kind, int id = -1);
+      MenuItem(MenuItemKind kind, int id, const std::string& text);
       MenuItemKind kind;
+      int id;   // item id      
       int toggled;
-      char *text;
-      char *input;
+      std::string text;
+      std::string input;
       int *int_p;   // used for setting keys (can be used for more stuff...)
-      int id;   // item id
       std::pair<std::set<std::string>, std::set<std::string>::iterator> list;
       Menu* target_menu;
 
-      void change_text (const char *text);
-      void change_input(const char *text);
+      void change_text (const std::string& text);
+      void change_input(const std::string& text);
 
-      static MenuItem* create(MenuItemKind kind, const char *text, int init_toggle, Menu* target_menu, int id, int* int_p);
+      static MenuItem* create(MenuItemKind kind, const std::string& text, int init_toggle, Menu* target_menu, int id, int* int_p);
 
       std::string get_input_with_symbol(bool active_item);   // returns the text with an input symbol
     private:
@@ -148,6 +151,7 @@ namespace SuperTux
       Menu();
       ~Menu();
 
+      void additem(const MenuItem& menu_item);      
       void additem(MenuItem* pmenu_item);
       void additem(MenuItemKind kind, const std::string& text, int init_toggle, Menu* target_menu, int id = -1, int *int_p = NULL);
 
diff --git a/lib/special/frame_rate.cpp b/lib/special/frame_rate.cpp
new file mode 100644 (file)
index 0000000..a4b1b77
--- /dev/null
@@ -0,0 +1,61 @@
+// 
+//  SuperTux
+//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+// 
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#include "SDL.h"
+
+#include "../special/frame_rate.h"
+#include "../special/timer.h"
+
+using namespace SuperTux;
+
+FrameRate::FrameRate(double fps)
+{
+  set_fps(fps);
+}
+
+void FrameRate::start()
+{
+  update_time = last_update_time = Ticks::get();  
+}
+
+void FrameRate::set_fps(double fps)
+{
+  frame_ms = static_cast<unsigned int>(1000.f/fps);
+}
+
+double FrameRate::get()
+{
+  return ((double)(update_time-last_update_time))/(double)frame_ms;
+}
+
+void FrameRate::update()
+{
+  /* Set the time of the last update and the time of the current update */
+  last_update_time = update_time;
+  update_time      = Ticks::get();
+
+  /* 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 - (frame_ms+2))
+    {
+      SDL_Delay(frame_ms);
+      update_time = Ticks::get();
+    }
+}
+
diff --git a/lib/special/frame_rate.h b/lib/special/frame_rate.h
new file mode 100644 (file)
index 0000000..c5cd18e
--- /dev/null
@@ -0,0 +1,43 @@
+// 
+//  SuperTux
+//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+// 
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef SUPERTUX_FRAMERATE_H
+#define SUPERTUX_FRAMERATE_H
+
+namespace SuperTux
+  {
+
+  class FrameRate
+    {
+    public:
+      FrameRate() {};
+      FrameRate(double fps);
+      void start();
+      void set_fps(double fps);
+      double get();
+      void update();
+    private:
+      unsigned int last_update_time;
+      unsigned int update_time;
+      unsigned int frame_ms;
+    };
+
+} //namespace SuperTux
+
+#endif /*SUPERTUX_FRAMERATE_H*/
+
index 0c98881..b3f78c2 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef SUPERTUX_TIMER_H
 #define SUPERTUX_TIMER_H
 
+#include <cstdlib>
+
 namespace SuperTux
   {
 
index d19461b..740663e 100644 (file)
@@ -74,6 +74,7 @@ GameSession::GameSession(const std::string& levelname_, int mode, bool flip_leve
 
   fps_timer.init(true);            
   frame_timer.init(true);
+  frame_rate.set_fps(100);
 
   context = new DrawingContext();
 
@@ -190,7 +191,7 @@ GameSession::start_timers()
 {
   time_left.start(level->time_left*1000);
   Ticks::pause_init();
-  update_time = Ticks::get();
+  frame_rate.start();
 }
 
 void
@@ -600,7 +601,7 @@ GameSession::run()
   
   int fps_cnt = 0;
 
-  update_time = last_update_time = Ticks::get();
+  frame_rate.start();
 
   // Eat unneeded events
   SDL_Event event;
@@ -611,7 +612,7 @@ GameSession::run()
   while (exit_status == ES_NONE)
     {
       /* Calculate the movement-factor */
-      double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
+      double frame_ratio = frame_rate.get();
 
       if(!frame_timer.check())
         {
@@ -652,18 +653,7 @@ GameSession::run()
           continue;
         }
 
-      /* Set the time of the last update and the time of the current update */
-      last_update_time = update_time;
-      update_time      = Ticks::get();
-
-      /* 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) 
-        {
-          SDL_Delay(10);
-          update_time = Ticks::get();
-        }
+      frame_rate.update();
 
       /* Handle time: */
       if (!time_left.check() && currentsector->player->dying == DYING_NOT
index d82c8a3..5e71456 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "special/timer.h"
 #include "special/base.h"
+#include "special/frame_rate.h"
 
 using namespace SuperTux;
 
@@ -64,8 +65,7 @@ private:
   int st_gl_mode;
   int levelnb;
   float fps_fps;
-  unsigned int last_update_time;
-  unsigned int update_time;
+  FrameRate frame_rate;
   int pause_menu_frame;
   int debug_fps;
 
index 8794004..1685e4b 100644 (file)
@@ -95,10 +95,7 @@ void save_hs(int score)
 
   Menu::set_current(highscore_menu);
 
-  if(!highscore_menu->item[0].input)
-    highscore_menu->item[0].input = (char*) malloc(strlen(hs_name.c_str()) + 1);
-
-  strcpy(highscore_menu->item[0].input,hs_name.c_str());
+  highscore_menu->item[0].input = hs_name;
 
   /* ask for player's name */
   while(Menu::current())
@@ -124,8 +121,7 @@ void save_hs(int score)
       switch (highscore_menu->check())
         {
         case 0:
-          if(highscore_menu->item[0].input != NULL)
-            hs_name = highscore_menu->item[0].input;
+          hs_name = highscore_menu->item[0].input;
           break;
         }
 
index 2dab421..790aa0f 100644 (file)
@@ -330,7 +330,7 @@ int LevelEditor::run(char* filename)
         default:
           if(i >= 1)
           {
-            if(load_level_subset(subset_load_menu->item[i+1].text))
+            if(load_level_subset(subset_load_menu->item[i+1].text.c_str()))
               return 1;
           }
           break;
@@ -348,7 +348,7 @@ int LevelEditor::run(char* filename)
           {
           case MNID_CREATESUBSET:
             LevelSubset::create(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input);
-            le_level_subset->load(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input);
+            le_level_subset->load(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input.c_str());
             leveleditor_menu->get_item_by_id(MNID_SUBSETSETTINGS).kind = MN_GOTO;
             goto_level(1);
             subset_new_menu->get_item_by_id(MNID_SUBSETNAME).change_input("");
@@ -599,7 +599,7 @@ void LevelEditor::apply_level_settings_menu()
 
   if(le_level->get_sector("main")->background->get_image().compare((*level_settings_menu->get_item_by_id(MNID_BGIMG).list.second)) != 0)
   {
-    le_level->get_sector("main")->background->set_image((*level_settings_menu->get_item_by_id(MNID_BGIMG).list.second), atoi(level_settings_menu->get_item_by_id(MNID_BGSPEED).input));
+    le_level->get_sector("main")->background->set_image((*level_settings_menu->get_item_by_id(MNID_BGIMG).list.second), atoi(level_settings_menu->get_item_by_id(MNID_BGSPEED).input.c_str()));
     i = true;
   }
 
@@ -616,17 +616,17 @@ void LevelEditor::apply_level_settings_menu()
   le_level->get_sector("main")->song_title = (*level_settings_menu->get_item_by_id(MNID_SONG).list.second);
 
   le_level->get_sector("main")->solids->resize(
-      atoi(level_settings_menu->get_item_by_id(MNID_LENGTH).input),
-      atoi(level_settings_menu->get_item_by_id(MNID_HEIGHT).input));
-  le_level->time_left = atoi(level_settings_menu->get_item_by_id(MNID_TIME).input);
-  le_level->get_sector("main")->gravity = atof(level_settings_menu->get_item_by_id(MNID_GRAVITY).input);
+      atoi(level_settings_menu->get_item_by_id(MNID_LENGTH).input.c_str()),
+      atoi(level_settings_menu->get_item_by_id(MNID_HEIGHT).input.c_str()));
+  le_level->time_left = atoi(level_settings_menu->get_item_by_id(MNID_TIME).input.c_str());
+  le_level->get_sector("main")->gravity = atof(level_settings_menu->get_item_by_id(MNID_GRAVITY).input.c_str());
   le_level->get_sector("main")->background->set_gradient(Color(
-      atoi(level_settings_menu->get_item_by_id(MNID_TopRed).input),
-      atoi(level_settings_menu->get_item_by_id(MNID_TopGreen).input),
-      atoi(level_settings_menu->get_item_by_id(MNID_TopBlue).input)), Color(
-      atoi(level_settings_menu->get_item_by_id(MNID_BottomRed).input),
-      atoi(level_settings_menu->get_item_by_id(MNID_BottomGreen).input),
-      atoi(level_settings_menu->get_item_by_id(MNID_BottomBlue).input)));
+      atoi(level_settings_menu->get_item_by_id(MNID_TopRed).input.c_str()),
+      atoi(level_settings_menu->get_item_by_id(MNID_TopGreen).input.c_str()),
+      atoi(level_settings_menu->get_item_by_id(MNID_TopBlue).input.c_str())), Color(
+      atoi(level_settings_menu->get_item_by_id(MNID_BottomRed).input.c_str()),
+      atoi(level_settings_menu->get_item_by_id(MNID_BottomGreen).input.c_str()),
+      atoi(level_settings_menu->get_item_by_id(MNID_BottomBlue).input.c_str())));
 }
 
 void LevelEditor::save_subset_settings_menu()