From 2e973e2cf1dc2af448a0c27d067b00addb968538 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tobias=20Gl=C3=A4=C3=9Fer?= Date: Wed, 28 Jul 2004 23:06:12 +0000 Subject: [PATCH] - Various fixes and cleanups. - Added FrameRate class to SuperTux library - More menu code C++ing. SVN-Revision: 1662 --- lib/Makefile.am | 4 ++- lib/gui/menu.cpp | 74 +++++++++++++++++++--------------------------- lib/gui/menu.h | 16 ++++++---- lib/special/frame_rate.cpp | 61 ++++++++++++++++++++++++++++++++++++++ lib/special/frame_rate.h | 43 +++++++++++++++++++++++++++ lib/special/timer.h | 2 ++ src/gameloop.cpp | 20 ++++--------- src/gameloop.h | 4 +-- src/high_scores.cpp | 8 ++--- src/leveleditor.cpp | 26 ++++++++-------- 10 files changed, 172 insertions(+), 86 deletions(-) create mode 100644 lib/special/frame_rate.cpp create mode 100644 lib/special/frame_rate.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 429c5ffb0..7dbb1d199 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -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 \ diff --git a/lib/gui/menu.cpp b/lib/gui/menu.cpp index 7e273d665..e060e39a6 100644 --- a/lib/gui/menu.cpp +++ b/lib/gui/menu.cpp @@ -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; diff --git a/lib/gui/menu.h b/lib/gui/menu.h index f4a394326..171b142bd 100644 --- a/lib/gui/menu.h +++ b/lib/gui/menu.h @@ -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::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 index 000000000..a4b1b7737 --- /dev/null +++ b/lib/special/frame_rate.cpp @@ -0,0 +1,61 @@ +// +// SuperTux +// Copyright (C) 2004 Tobias Glaesser +// +// 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(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 index 000000000..c5cd18edc --- /dev/null +++ b/lib/special/frame_rate.h @@ -0,0 +1,43 @@ +// +// SuperTux +// Copyright (C) 2004 Tobias Glaesser +// +// 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*/ + diff --git a/lib/special/timer.h b/lib/special/timer.h index 0c988818f..b3f78c25c 100644 --- a/lib/special/timer.h +++ b/lib/special/timer.h @@ -21,6 +21,8 @@ #ifndef SUPERTUX_TIMER_H #define SUPERTUX_TIMER_H +#include + namespace SuperTux { diff --git a/src/gameloop.cpp b/src/gameloop.cpp index d19461b59..740663e0a 100644 --- a/src/gameloop.cpp +++ b/src/gameloop.cpp @@ -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 diff --git a/src/gameloop.h b/src/gameloop.h index d82c8a3b7..5e71456bd 100644 --- a/src/gameloop.h +++ b/src/gameloop.h @@ -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; diff --git a/src/high_scores.cpp b/src/high_scores.cpp index 87940041f..1685e4b8b 100644 --- a/src/high_scores.cpp +++ b/src/high_scores.cpp @@ -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; } diff --git a/src/leveleditor.cpp b/src/leveleditor.cpp index 2dab42180..790aa0fa7 100644 --- a/src/leveleditor.cpp +++ b/src/leveleditor.cpp @@ -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() -- 2.11.0