From a9d9e48c72e70fd41ae9759e3894752eb9708596 Mon Sep 17 00:00:00 2001 From: gfgtdf Date: Sat, 5 Oct 2019 16:16:37 +0200 Subject: [PATCH] fix float_label too fast in some cases now its lifetime is no longer measured in frames in particular its lifetime is now indepndent of the current frames per second --- src/display.hpp | 4 +-- src/floating_label.cpp | 64 ++++++++++++++++++++++++++++----------- src/floating_label.hpp | 16 +++++----- src/game_display.cpp | 4 +-- src/playmp_controller.cpp | 2 +- 5 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/display.hpp b/src/display.hpp index 5093b1bc9e72..15b3a2efca9d 100644 --- a/src/display.hpp +++ b/src/display.hpp @@ -587,7 +587,7 @@ class display : public video2::draw_layering /** Holds options for calls to function 'announce' (@ref announce). */ struct announce_options { - /** Lifetime measured in frames. */ + /** Lifetime measured in milliseconds. */ int lifetime; /** @@ -598,7 +598,7 @@ class display : public video2::draw_layering bool discard_previous; announce_options() - : lifetime(100) + : lifetime(1600) , discard_previous(false) { } diff --git a/src/floating_label.cpp b/src/floating_label.cpp index eb595f70dc08..d8e93fce0383 100644 --- a/src/floating_label.cpp +++ b/src/floating_label.cpp @@ -46,7 +46,10 @@ floating_label::floating_label(const std::string& text, const surface& surf) #else : surf_(surf) , buf_(nullptr) + , buf_pos_() #endif + , fadeout_(true) + , time_start_(0) , text_(text) , font_size_(SIZE_NORMAL) , color_(NORMAL_COLOR) @@ -60,7 +63,6 @@ floating_label::floating_label(const std::string& text, const surface& surf) , width_(-1) , height_(-1) , clip_rect_(CVideo::get_singleton().screen_area()) - , alpha_change_(0) , visible_(true) , align_(CENTER_ALIGN) , border_(0) @@ -154,7 +156,7 @@ surface floating_label::create_surface() return surf_; } -void floating_label::draw(surface screen) +void floating_label::draw(int time, surface screen) { if(!visible_) { buf_ = nullptr; @@ -177,10 +179,40 @@ void floating_label::draw(surface screen) } } - SDL_Rect rect = sdl::create_rect(xpos(surf_->w), ypos_, surf_->w, surf_->h); + SDL_Point pos = get_loc(time); + buf_pos_ = sdl::create_rect(pos.x, pos.y, surf_->w, surf_->h); const clip_rect_setter clip_setter(screen, &clip_rect_); - sdl_copy_portion(screen,&rect,buf_,nullptr); - sdl_blit(surf_,nullptr,screen,&rect); + //important: make a copy of buf_pos_ because sdl_blit modifies dst_rect. + SDL_Rect rect = buf_pos_; + sdl_copy_portion(screen, &rect, buf_, nullptr); + sdl_blit(get_surface(time), nullptr, screen, &rect); +} + +void floating_label::set_lifetime(int lifetime) +{ + lifetime_ = lifetime; + time_start_ = SDL_GetTicks(); +} + + +SDL_Point floating_label::get_loc(int time) +{ + int time_alive = get_time_alive(time); + return { + static_cast(time_alive * xmove_ + xpos(surf_->w)), + static_cast(time_alive * ymove_ + ypos_) + }; +} + +surface floating_label::get_surface(int time) +{ + int time_alive = get_time_alive(time); + int alpha_add = -255 * time_alive / lifetime_; + if(fadeout_ && surf_ != nullptr) { + // fade out moving floating labels + return adjust_surface_alpha_add(surf_, alpha_add); + } + return surf_; } void floating_label::undraw(surface screen) @@ -188,18 +220,10 @@ void floating_label::undraw(surface screen) if(screen == nullptr || buf_ == nullptr) { return; } - SDL_Rect rect = sdl::create_rect(xpos(surf_->w), ypos_, surf_->w, surf_->h); - const clip_rect_setter clip_setter(screen, &clip_rect_); - sdl_blit(buf_,nullptr,screen,&rect); - move(xmove_,ymove_); - if(lifetime_ > 0) { - --lifetime_; - if(alpha_change_ != 0 && (xmove_ != 0.0 || ymove_ != 0.0) && surf_ != nullptr) { - // fade out moving floating labels - surf_ = adjust_surface_alpha_add(surf_,alpha_change_); - } - } + const clip_rect_setter clip_setter(screen, &clip_rect_); + SDL_Rect rect = buf_pos_; + sdl_blit(buf_, nullptr, screen, &rect); } int add_floating_label(const floating_label& flabel) @@ -265,11 +289,13 @@ SDL_Rect get_floating_label_rect(int handle) floating_label_context::floating_label_context() { + //TODO: 'pause' floating labels in other contexrs label_contexts.emplace(); } floating_label_context::~floating_label_context() { + //TODO: 'pause' floating labels in other contexrs const std::set& context = label_contexts.top(); while(!context.empty()) { @@ -286,6 +312,7 @@ void draw_floating_labels(surface screen) if(label_contexts.empty()) { return; } + int time = SDL_GetTicks(); const std::set& context = label_contexts.top(); @@ -293,7 +320,7 @@ void draw_floating_labels(surface screen) // are displayed over earlier added labels. for(label_map::iterator i = labels.begin(); i != labels.end(); ++i) { if(context.count(i->first) > 0) { - i->second.draw(screen); + i->second.draw(time, screen); } } } @@ -303,6 +330,7 @@ void undraw_floating_labels(surface screen) if(label_contexts.empty()) { return; } + int time = SDL_GetTicks(); std::set& context = label_contexts.top(); @@ -316,7 +344,7 @@ void undraw_floating_labels(surface screen) //remove expired labels for(label_map::iterator j = labels.begin(); j != labels.end(); ) { - if(context.count(j->first) > 0 && j->second.expired()) { + if(context.count(j->first) > 0 && j->second.expired(time)) { context.erase(j->first); labels.erase(j++); } else { diff --git a/src/floating_label.hpp b/src/floating_label.hpp index 100bd034aaa1..bb26a731a4c2 100644 --- a/src/floating_label.hpp +++ b/src/floating_label.hpp @@ -50,10 +50,7 @@ class floating_label ymove_ = ymove; } // set the number of frames to display the text for, or -1 to display until removed - void set_lifetime(int lifetime) { - lifetime_ = lifetime; - alpha_change_ = -255 / lifetime_; - } + void set_lifetime(int lifetime); void set_color(const color_t& color) {color_ = color;} void set_bg_color(const color_t& bg_color) { bgcolor_ = bg_color; @@ -69,12 +66,12 @@ class floating_label void use_markup(bool b) {use_markup_ = b;} void move(double xmove, double ymove); - void draw(surface screen); + void draw(int time, surface screen); void undraw(surface screen); surface create_surface(); - bool expired() const { return lifetime_ == 0; } + bool expired(int time) const { return get_time_alive(time) > lifetime_; } void show(const bool value) { visible_ = value; } @@ -82,8 +79,14 @@ class floating_label private: + int get_time_alive(int current_time) const { return current_time - time_start_; } int xpos(std::size_t width) const; + SDL_Point get_loc(int time); + surface get_surface(int time); surface surf_, buf_; + SDL_Rect buf_pos_; + bool fadeout_; + int time_start_; std::string text_; int font_size_; color_t color_, bgcolor_; @@ -92,7 +95,6 @@ class floating_label int lifetime_; int width_, height_; SDL_Rect clip_rect_; - int alpha_change_; bool visible_; font::ALIGN align_; int border_; diff --git a/src/game_display.cpp b/src/game_display.cpp index 8912b6290f49..4476ed5ce3f5 100644 --- a/src/game_display.cpp +++ b/src/game_display.cpp @@ -616,8 +616,8 @@ void game_display::float_label(const map_location& loc, const std::string& text, flabel.set_font_size(font::SIZE_XLARGE); flabel.set_color(color); flabel.set_position(get_location_x(loc)+zoom_/2, get_location_y(loc)); - flabel.set_move(0, -2 * turbo_speed()); - flabel.set_lifetime(60/turbo_speed()); + flabel.set_move(0, -0.1 * turbo_speed()); + flabel.set_lifetime(1000/turbo_speed()); flabel.set_scroll_mode(font::ANCHOR_LABEL_MAP); font::add_floating_label(flabel); diff --git a/src/playmp_controller.cpp b/src/playmp_controller.cpp index 8ac464ed91ae..23db955a386a 100644 --- a/src/playmp_controller.cpp +++ b/src/playmp_controller.cpp @@ -154,7 +154,7 @@ void playmp_controller::play_human_turn() flabel.set_color(color); SDL_Rect rect = gui_->map_area(); flabel.set_position(rect.w/2, rect.h/2); - flabel.set_lifetime(150); + flabel.set_lifetime(2500); flabel.set_clip_rect(rect); font::add_floating_label(flabel);