From d20bf5578f170adf51f0e02f859a2cd7fcccc9a4 Mon Sep 17 00:00:00 2001 From: Pauli Nieminen Date: Sat, 24 May 2008 11:43:43 +0000 Subject: [PATCH] fixed parser bug that prevented loading binary data strings --- changelog | 1 + src/SConscript | 3 + src/animated.i | 4 +- src/menu_events.cpp | 16 +++++ src/serialization/tokenizer.cpp | 17 +++-- src/server/server.cpp | 8 +-- src/time.cpp | 118 ++++++++++++++++++++++++++++++++ src/time.hpp | 59 ++++++++++++++++ 8 files changed, 217 insertions(+), 9 deletions(-) create mode 100644 src/time.cpp create mode 100644 src/time.hpp diff --git a/changelog b/changelog index 05289b9a2e0..f15a9010f96 100644 --- a/changelog +++ b/changelog @@ -69,6 +69,7 @@ Version 1.5.0+svn: * campaignd * made campaign server use gzip compression for networking * miscellaneous and bug fixes: + * fixed parser bug that prevented loading binary data strings * fixed issues with campaign info in non-compressed saved games (bug #11386) * Implemented the option to use the mouse selection clipboard in X11 diff --git a/src/SConscript b/src/SConscript index 85d633cc081..4352e58779b 100644 --- a/src/SConscript +++ b/src/SConscript @@ -182,6 +182,7 @@ wesnoth_sources = Split(""" statistics.cpp team.cpp terrain_filter.cpp + time.cpp titlescreen.cpp unit.cpp unit_abilities.cpp @@ -217,6 +218,7 @@ wesnoth_editor_sources = Split(""" editor/editor_dialogs.cpp editor/editor_undo.cpp animated_editor.cpp + time.cpp """) if have_client_prereqs and have_X: wesnoth_editor = env.Program("wesnoth_editor", wesnoth_editor_sources + [libwesnoth_core, libwesnoth_sdl, libwesnoth] + wesnoth_editor_res) @@ -242,6 +244,7 @@ wesnothd_sources = Split(""" server/proxy.cpp server/server.cpp server/simple_wml.cpp + time.cpp """) if have_server_prereqs: wesnothd = env.Program("wesnothd", wesnothd_sources + [libwesnoth_core, libwesnothd]) diff --git a/src/animated.i b/src/animated.i index 1dc893b5105..b503fa2d566 100644 --- a/src/animated.i +++ b/src/animated.i @@ -22,6 +22,7 @@ #include "SDL.h" #include "animated.hpp" +#include "time.hpp" #include "util.hpp" #include "serialization/string_utils.hpp" @@ -31,7 +32,8 @@ namespace { void new_animation_frame() { - current_ticks = SDL_GetTicks(); + ntime::source::get_source().start_frame(); + current_ticks = ntime::source::get_source().get_time(); } int get_current_animation_tick() diff --git a/src/menu_events.cpp b/src/menu_events.cpp index b6a706ff980..b01eee6fc89 100644 --- a/src/menu_events.cpp +++ b/src/menu_events.cpp @@ -37,6 +37,7 @@ #include "replay.hpp" #include "sound.hpp" #include "team.hpp" +#include "time.hpp" #include "unit_display.hpp" #include "unit_types.hpp" #include "wml_separators.hpp" @@ -1824,6 +1825,7 @@ private: chat_handler::do_speak(textbox_info_.box()->text(),textbox_info_.check() != NULL ? textbox_info_.check()->checked() : false); } + void menu_handler::add_chat_message(const time_t& time, const std::string& speaker, int side, const std::string& message, game_display::MESSAGE_TYPE type) @@ -2315,6 +2317,7 @@ private: using chmap::command_failed; using chmap::command_failed_need_arg; + void do_animode(); void do_refresh(); void do_droid(); void do_theme(); @@ -2384,6 +2387,7 @@ private: _("Clear chat history.")); register_command("sunset", &console_handler::do_sunset, _("Visualize the screen refresh procedure."), "", "D"); + register_command("animode", &console_handler::do_animode, "Change animation time mode"); register_command("fps", &console_handler::do_fps, "Show fps."); register_command("benchmark", &console_handler::do_benchmark); register_command("save", &console_handler::do_save, _("Save game.")); @@ -2795,6 +2799,18 @@ private: void console_handler::do_save() { menu_handler_.save_game(get_data(),gui::NULL_DIALOG); } + void console_handler::do_animode(){ + if (ntime::source::get_source().get_time_mode() == ntime::source::REAL_TIME) + { + ntime::source::get_source().set_time_mode(ntime::source::SMOOTH_TIME); + print(get_cmd(), "Smooth rendering"); + } + else + { + ntime::source::get_source().set_time_mode(ntime::source::REAL_TIME); + print(get_cmd(), "Realtime rendering"); + } + } void console_handler::do_save_quit() { menu_handler_.save_game(get_data(),gui::NULL_DIALOG); throw end_level_exception(QUIT); diff --git a/src/serialization/tokenizer.cpp b/src/serialization/tokenizer.cpp index 97998c3fd7c..8dd91165ebf 100644 --- a/src/serialization/tokenizer.cpp +++ b/src/serialization/tokenizer.cpp @@ -156,10 +156,19 @@ const token& tokenizer::next_token() break; if(current_ == '"' && peek_char() == '"') next_char_fast(); - if (current_ == 254) { - skip_comment(); - --lineno_; - continue; + if (current_ == 254 && + (peek_char() == 'l' || peek_char() == 't')) { + next_char_fast(); + if ((current_ == 'l' && peek_char() == 'i') || (current_ == 't' && peek_char() == 'e')) + { + skip_comment(); + --lineno_; + continue; + } + else + { + token_.value += 254; + } } token_.value += current_; diff --git a/src/server/server.cpp b/src/server/server.cpp index c8f36377f23..39efdf7b008 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -23,6 +23,7 @@ #include "../map.hpp" // gamemap::MAX_PLAYERS #include "../network.hpp" #include "../filesystem.hpp" +#include "../time.hpp" #include "../serialization/parser.hpp" #include "../serialization/preprocessor.hpp" #include "../serialization/string_utils.hpp" @@ -297,7 +298,6 @@ private: simple_wml::document games_and_users_list_; metrics metrics_; - fps_limiter fps_limit_; time_t last_ping_; time_t last_stats_; @@ -414,7 +414,7 @@ void server::load_config() { // remember to make new one as a daemon or it will block old one restart_command = cfg_["restart_command"]; - fps_limit_.set_ms_per_frame(lexical_cast_default(cfg_["ms_per_frame"],20)); + ntime::source::get_source().set_frame_time(lexical_cast_default(cfg_["ms_per_frame"],20)); accepted_versions_.clear(); const std::string& versions = cfg_["versions_accepted"]; @@ -477,7 +477,7 @@ void server::run() { for (int loop = 0;; ++loop) { // Try to run with 50 FPS all the time // Server will respond a bit faster under heavy load - fps_limit_.limit(); + ntime::source::get_source().start_frame(); try { // We are going to waith 10 seconds before shutting down so users can get out of game. if (graceful_restart && games_.size() == 0 && ++graceful_counter > 500 ) @@ -502,7 +502,7 @@ void server::run() { process_command(admin_cmd); } - time_t now = time(NULL); + time_t now = time(NULL); if (last_ping_ + 15 <= now) { // and check if bans have expired ban_manager_.check_ban_times(now); diff --git a/src/time.cpp b/src/time.cpp new file mode 100644 index 00000000000..11794ceb554 --- /dev/null +++ b/src/time.cpp @@ -0,0 +1,118 @@ +/* $Id$ */ +/* + Copyright (C) 2008 by Pauli Nieminen + Part of the Battle for Wesnoth Project http://www.wesnoth.org/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 + or at your option any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. + + See the COPYING file for more details. +*/ + +#include +#include "time.hpp" +#include "global.hpp" +#include "SDL.h" + +namespace ntime { + + source source::time_source_; + + source::source() : frame_time_(20), + current_time_(SDL_GetTicks()), + index_(0), + mode_(REAL_TIME) + { + for (int i = 0; i < frames_to_remember; ++i) + { + time_[i] = 0; + } + } + + int source::next_index() + { + return (index_ + 1) % frames_to_remember; + } + + size_t source::start_frame(const bool limit) + { + size_t previus_time = current_time_; + size_t current_time = SDL_GetTicks(); + size_t frame_used = current_time - previus_time; + if (limit && frame_time_ > frame_used) + { + // use delay to wait so we don't take all cpu + size_t wait_time = frame_time_ - frame_used; + SDL_Delay(wait_time); + current_time += wait_time; + } + + + // Advance index only in begin of frame + index_ = next_index(); + time_[index_] = current_time; + if (mode_ == REAL_TIME) + { + current_time_ = current_time; + } + else + { + // Check if we have allready enought frames + // for smooth time calculation + if (time_[next_index()]) + { + // smooth calcuations uses rounding to + // keep time as near of real time as possible + // @todo There should be error correction + // Maybe should use 3 bits shifted values + + size_t average = ((current_time - time_[next_index()]))/((frames_to_remember - 1)); + + + current_time_ += average; + } + else + { + current_time_ = current_time; + } + } + return frame_used; + } + + void source::set_frame_rate(const size_t fps) + { + frame_time_ = 1000/fps; + } + + void source::set_frame_time(const size_t ms) + { + frame_time_ = ms; + } + + size_t source::get_time() const + { + return current_time_; + } + + void source::set_time_mode(const time_mode& mode) + { + mode_ = mode; + } + + source::time_mode source::get_time_mode() const + { + return mode_; + } + + source& source::get_source() + { + return source::time_source_; + } + + + +} + diff --git a/src/time.hpp b/src/time.hpp new file mode 100644 index 00000000000..c8a98e49731 --- /dev/null +++ b/src/time.hpp @@ -0,0 +1,59 @@ +/* $Id$ */ +/* + Copyright (C) 2008 by Pauli Nieminen + Part of the Battle for Wesnoth Project http://www.wesnoth.org/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 + or at your option any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. + + See the COPYING file for more details. +*/ + +#ifndef TIME_HPP_INCLUDED +#define TIME_HPP_INCLUDED +#include + +namespace ntime { + + const int frames_to_remember = 6; + class source { + public: + enum time_mode { + REAL_TIME, + SMOOTH_TIME + }; + private: + size_t time_[frames_to_remember]; + size_t frame_time_; + size_t current_time_; + int index_; + time_mode mode_; + static source time_source_; + source(); + source(const source&); + void operator=(const source&); + + int next_index(); + public: + /** + * Called in begin of each frame + * @return How many milliseconds this frame took? + */ + size_t start_frame(const bool limit = true); + void set_frame_rate(const size_t fps); + void set_frame_time(const size_t ms); + + size_t get_time() const; + + void set_time_mode(const time_mode& mode); + time_mode get_time_mode() const; + + static source& get_source(); + + }; +} + +#endif