Skip to content

Commit

Permalink
fix float_label too fast in some cases
Browse files Browse the repository at this point in the history
now its lifetime is no longer measured in frames
in particular its lifetime is now indepndent of the
current frames per second
  • Loading branch information
gfgtdf committed Mar 19, 2020
1 parent 2c1d9f7 commit a9d9e48
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 30 deletions.
4 changes: 2 additions & 2 deletions src/display.hpp
Expand Up @@ -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;

/**
Expand All @@ -598,7 +598,7 @@ class display : public video2::draw_layering
bool discard_previous;

announce_options()
: lifetime(100)
: lifetime(1600)
, discard_previous(false)
{
}
Expand Down
64 changes: 46 additions & 18 deletions src/floating_label.cpp
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -177,29 +179,51 @@ 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<int>(time_alive * xmove_ + xpos(surf_->w)),
static_cast<int>(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)
{
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)
Expand Down Expand Up @@ -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<int>& context = label_contexts.top();

while(!context.empty()) {
Expand All @@ -286,14 +312,15 @@ void draw_floating_labels(surface screen)
if(label_contexts.empty()) {
return;
}
int time = SDL_GetTicks();

const std::set<int>& context = label_contexts.top();

// draw the labels in the order they were added, so later added labels (likely to be tooltips)
// 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);
}
}
}
Expand All @@ -303,6 +330,7 @@ void undraw_floating_labels(surface screen)
if(label_contexts.empty()) {
return;
}
int time = SDL_GetTicks();

std::set<int>& context = label_contexts.top();

Expand All @@ -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 {
Expand Down
16 changes: 9 additions & 7 deletions src/floating_label.hpp
Expand Up @@ -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;
Expand All @@ -69,21 +66,27 @@ 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; }

LABEL_SCROLL_MODE scroll() const { return scroll_; }

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_;
Expand All @@ -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_;
Expand Down
4 changes: 2 additions & 2 deletions src/game_display.cpp
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/playmp_controller.cpp
Expand Up @@ -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);
Expand Down

0 comments on commit a9d9e48

Please sign in to comment.