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
This commit is contained in:
gfgtdf 2019-10-05 16:16:37 +02:00
parent 2c1d9f757e
commit a9d9e48c72
5 changed files with 60 additions and 30 deletions

View file

@ -587,7 +587,7 @@ public:
/** 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 @@ public:
bool discard_previous;
announce_options()
: lifetime(100)
: lifetime(1600)
, discard_previous(false)
{
}

View file

@ -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<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)
@ -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<int>& 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<int>& 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<int>& 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 {

View file

@ -50,10 +50,7 @@ public:
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 @@ public:
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 @@ public:
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 @@ private:
int lifetime_;
int width_, height_;
SDL_Rect clip_rect_;
int alpha_change_;
bool visible_;
font::ALIGN align_;
int border_;

View file

@ -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);

View file

@ -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);