redo unit invalidation, this is still a tad bumpy,

...but ilor needs this commit to work on the editor
This commit is contained in:
Jérémy Rosen 2008-06-14 08:45:32 +00:00
parent 06ab5ae194
commit 7259fc8a7f
11 changed files with 142 additions and 116 deletions

View file

@ -208,7 +208,6 @@ int animated<T,T_void_value>::get_animation_time_potential() const
return tick_to_time(current_ticks);
}
template<typename T, typename T_void_value>
int animated<T,T_void_value>::get_animation_time() const
{

View file

@ -1046,16 +1046,18 @@ void display::highlight_hex(gamemap::location hex)
invalidate(mouseoverHex_);
}
void display::invalidate_locations_in_rect(SDL_Rect r)
bool display::invalidate_locations_in_rect(SDL_Rect r)
{
bool result = false;
gamemap::location topleft, bottomright;
get_rect_hex_bounds(r, topleft, bottomright);
for (int x = topleft.x; x <= bottomright.x; ++x) {
for (int y = topleft.y; y <= bottomright.y; ++y) {
gamemap::location loc(x, y);
invalidate(loc);
result |= invalidate(loc);
}
}
return result;
}
void display::set_diagnostic(const std::string& msg)
@ -2020,17 +2022,32 @@ void display::refresh_report(reports::TYPE report_num, reports::report report,
reportSurfaces_[report_num].assign(NULL);
}
}
bool display::invalidate_rectangle(const gamemap::location& first_corner, const gamemap::location& second_corner) {
// unused variable - const SDL_Rect& rect = map_area();
bool result = false;
for (int x = minimum<int>(first_corner.x,second_corner.x); x <= maximum<int>(first_corner.x,second_corner.x);x++) {
for (int y = minimum<int>(first_corner.y,second_corner.y); y <= maximum<int>(first_corner.y,second_corner.y);y++) {
result |= invalidate(gamemap::location(x,y));
}
}
return result;
}
void display::invalidate_rectangle(const gamemap::location& first_corner, const gamemap::location& second_corner) {
bool display::invalidate_zone(const int x1,const int y1, const int x2, const int y2) {
const SDL_Rect& rect = map_area();
return invalidate_rectangle(pixel_position_to_hex(x1 - rect.x+xpos_, y1 - rect.y+ypos_),pixel_position_to_hex(x2 - rect.x+xpos_, y2 - rect.y+ypos_));
}
bool display::rectangle_need_update(const gamemap::location& first_corner, const gamemap::location& second_corner) const {
// unused variable - const SDL_Rect& rect = map_area();
for (int x = minimum<int>(first_corner.x,second_corner.x); x <= maximum<int>(first_corner.x,second_corner.x);x++) {
for (int y = minimum<int>(first_corner.y,second_corner.y); y <= maximum<int>(first_corner.y,second_corner.y);y++) {
invalidate(gamemap::location(x,y));
if(invalidated_.find(gamemap::location(x,y)) != invalidated_.end()) return true;
}
}
return false;
}
void display::invalidate_zone(const int x1,const int y1, const int x2, const int y2) {
bool display::zone_need_update(const int x1,const int y1, const int x2, const int y2) const {
const SDL_Rect& rect = map_area();
invalidate_rectangle(pixel_position_to_hex(x1 - rect.x, y1 - rect.y),pixel_position_to_hex(x2 - rect.x, y2 - rect.y));
return rectangle_need_update(pixel_position_to_hex(x1 - rect.x+xpos_, y1 - rect.y+ypos_),pixel_position_to_hex(x2 - rect.x+xpos_, y2 - rect.y+ypos_));
}

View file

@ -187,9 +187,11 @@ public:
bool brightened = false);
// Will be overridden in the display subclass
virtual void invalidate(const gamemap::location& loc) {invalidated_.insert(loc);};
virtual void invalidate_rectangle(const gamemap::location& first_corner, const gamemap::location& second_corner) ;
virtual void invalidate_zone(const int x1,const int y1, const int x2, const int y2);
virtual bool invalidate(const gamemap::location& loc) {return invalidated_.insert(loc).second;};
virtual bool invalidate_rectangle(const gamemap::location& first_corner, const gamemap::location& second_corner) ;
virtual bool invalidate_zone(const int x1,const int y1, const int x2, const int y2);
virtual bool rectangle_need_update(const gamemap::location& first_corner, const gamemap::location& second_corner) const;
virtual bool zone_need_update(const int x1,const int y1, const int x2, const int y2) const;
virtual void draw_minimap_units() {};
const gamemap& get_map()const { return map_;}
@ -547,7 +549,7 @@ protected:
//! redraw all panels associated with the map display
void draw_all_panels();
void invalidate_locations_in_rect(SDL_Rect r);
bool invalidate_locations_in_rect(SDL_Rect r);
//! Strict weak ordering to sort a STL-set of hexes
//! for drawing using the z-order.

View file

@ -991,83 +991,56 @@ const SDL_Rect& game_display::calculate_energy_bar(surface surf)
return calculate_energy_bar(surf);
}
void game_display::invalidate(const gamemap::location& loc)
bool game_display::invalidate(const gamemap::location& loc)
{
if(!invalidateAll_) {
if (invalidated_.insert(loc).second) {
// Units can overlap adjacent tiles.
unit_map::iterator u = units_.find(loc);
if (u != units_.end()) {
std::set<gamemap::location> overlaps = u->second.overlaps(u->first);
for (std::set<gamemap::location>::iterator i = overlaps.begin(); i != overlaps.end(); i++) {
invalidate(*i);
}
}
if (temp_unit_ && temp_unit_loc_ == loc ) {
std::set<gamemap::location> overlaps = temp_unit_->overlaps(temp_unit_loc_);
for (std::set<gamemap::location>::iterator i = overlaps.begin(); i != overlaps.end(); i++) {
invalidate(*i);
}
}
// If neighbour has a unit which overlaps us, invalidate him
gamemap::location adjacent[6];
get_adjacent_tiles(loc, adjacent);
for (unsigned int i = 0; i < 6; i++) {
u = units_.find(adjacent[i]);
if (u != units_.end()) {
std::set<gamemap::location> overlaps = u->second.overlaps(u->first);
if (overlaps.find(loc) != overlaps.end()) {
invalidate(u->first);
}
}
if (temp_unit_ && temp_unit_loc_ == adjacent[i] ) {
std::set<gamemap::location> overlaps = temp_unit_->overlaps(temp_unit_loc_);
if (overlaps.find(loc) != overlaps.end()) {
invalidate(temp_unit_loc_);
}
}
}
}
bool tmp = invalidated_.insert(loc).second;
return tmp;
}
return false;
}
void game_display::invalidate_animations()
{
new_animation_frame();
if (preferences::animate_map()) {
unit_map::iterator unit;
for(unit=units_.begin() ; unit != units_.end() ; unit++) {
unit->second.refresh(*this, unit->first);
if (unit->second.get_animation() && unit->second.get_animation()->need_update())
invalidate(unit->first);
}
if (temp_unit_ ) {
temp_unit_->refresh(*this, temp_unit_loc_);
if (temp_unit_->get_animation() && temp_unit_->get_animation()->need_update())
invalidate(temp_unit_loc_);
}
gamemap::location topleft;
gamemap::location bottomright;
get_visible_hex_bounds(topleft, bottomright);
if (!preferences::animate_map()) {return;}
gamemap::location topleft;
gamemap::location bottomright;
get_visible_hex_bounds(topleft, bottomright);
for(int x = topleft.x; x <= bottomright.x; ++x) {
for(int y = topleft.y; y <= bottomright.y; ++y) {
const gamemap::location loc(x,y);
if (!shrouded(loc)) {
if (builder_.update_animation(loc)) {
invalidate(loc);
} else if (map_.is_village(loc)) {
const int owner = player_teams::village_owner(loc);
if (owner >= 0 && flags_[owner].need_update() && (!fogged(loc) || !teams_[currentTeam_].is_enemy(owner+1)))
for(int x = topleft.x; x <= bottomright.x; ++x) {
for(int y = topleft.y; y <= bottomright.y; ++y) {
const gamemap::location loc(x,y);
if (!shrouded(loc)) {
if (builder_.update_animation(loc)) {
invalidate(loc);
} else if (map_.is_village(loc)) {
const int owner = player_teams::village_owner(loc);
if (owner >= 0 && flags_[owner].need_update() && (!fogged(loc) || !teams_[currentTeam_].is_enemy(owner+1)))
invalidate(loc);
}
}
}
}
}
unit_map::iterator unit;
for(unit=units_.begin() ; unit != units_.end() ; unit++)
unit->second.refresh(*this, unit->first);
if (temp_unit_ )
temp_unit_->refresh(*this, temp_unit_loc_);
bool new_inval = true;
while(new_inval) {
new_inval = false;
for(unit=units_.begin() ; unit != units_.end() ; unit++) {
new_inval |= unit->second.invalidate(unit->first);
}
if (temp_unit_ ) {
//new_inval |=invalidate(temp_unit_loc_);
new_inval |=temp_unit_->invalidate(temp_unit_loc_);
}
}
new_animation_frame();
}
void game_display::debug_highlight(const gamemap::location& loc, fixed_t amount)

View file

@ -107,7 +107,7 @@ public:
void draw_movement_info(const gamemap::location& loc);
//! Function to invalidate a specific tile for redrawing.
void invalidate(const gamemap::location& loc);
bool invalidate(const gamemap::location& loc);
const gamestatus &get_game_status() { return status_; }
void draw_report(reports::TYPE report_num);

View file

@ -1878,10 +1878,9 @@ void unit::clear_haloes()
unit_anim_halo_ = halo::NO_HALO;
}
}
std::set<gamemap::location> unit::overlaps(const gamemap::location &loc) const
bool unit::invalidate(const gamemap::location &loc)
{
std::set<gamemap::location> over;
bool result = false;
// Very early calls, anim not initialized yet
if(get_animation()) {
@ -1911,19 +1910,9 @@ std::set<gamemap::location> unit::overlaps(const gamemap::location &loc) const
}
params.image_mod = image_mods();
frame_parameters adjusted_params= anim_->get_current_params(params);
// Invalidate adjacent neighbours if we don't stay in our hex
if(adjusted_params.offset != 0) {
gamemap::location::DIRECTION dir = (adjusted_params.offset > 0) ? facing_ : loc.get_opposite_dir(facing_);
gamemap::location adj_loc = loc.get_direction(dir);
over.insert(adj_loc);
gamemap::location arr[6];
get_adjacent_tiles(adj_loc, arr);
for (unsigned int i = 0; i < 6; i++) {
over.insert(arr[i]);
}
}
get_animation()->invalidate(params);
get_animation()->update_last_draw_time();
frame_parameters adjusted_params= get_animation()->get_current_params(params);
result |= get_animation()->invalidate(params);
}
@ -1932,11 +1921,11 @@ std::set<gamemap::location> unit::overlaps(const gamemap::location &loc) const
gamemap::location arr[6];
get_adjacent_tiles(loc, arr);
for (unsigned int i = 0; i < 6; i++) {
over.insert(arr[i]);
result |= game_display::get_singleton()->invalidate(arr[i]);
}
}
return result;
return over;
}
int unit::upkeep() const

View file

@ -205,7 +205,7 @@ public:
void set_facing(gamemap::location::DIRECTION dir);
gamemap::location::DIRECTION facing() const { return facing_; }
std::set<gamemap::location> overlaps(const gamemap::location &loc) const;
bool invalidate(const gamemap::location &loc);
const t_string& traits_description() const { return traits_description_; }
int cost () const { return unit_value_; }

View file

@ -713,6 +713,15 @@ void unit_animation::start_animation(int start_time,const gamemap::location &src
anim_itor->second.start_animation(start_time,src,dst,cycles);
}
}
void unit_animation::update_parameters(const gamemap::location &src, const gamemap::location &dst)
{
unit_anim_.update_parameters(src, dst);
std::map<std::string,particule>::iterator anim_itor =sub_anims_.begin();
for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) {
anim_itor->second.update_parameters(src,dst);
}
}
void unit_animation::pause_animation()
{
@ -735,35 +744,38 @@ void unit_animation::redraw(const frame_parameters& value)
{
std::map<std::string,particule>::iterator anim_itor =sub_anims_.begin();
//unit_anim_.redraw(value,true);
for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) {
anim_itor->second.redraw( value);
}
}
void unit_animation::invalidate(const frame_parameters& value) const
bool unit_animation::invalidate(const frame_parameters& value) const
{
bool result = false;
std::map<std::string,particule>::const_iterator anim_itor =sub_anims_.begin();
unit_anim_.invalidate(value,true);
result |= unit_anim_.invalidate(value,true);
for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) {
anim_itor->second.invalidate(value);
result |= anim_itor->second.invalidate(value);
}
return result;
}
void unit_animation::particule::redraw(const frame_parameters& value)
void unit_animation::particule::redraw(const frame_parameters& value,const bool primary)
{
const unit_frame& current_frame= get_current_frame();
const frame_parameters default_val = parameters_.parameters(get_animation_time() -get_begin_time());
if(get_current_frame_begin_time() != last_frame_begin_time_ ) {
last_frame_begin_time_ = get_current_frame_begin_time();
current_frame.redraw(get_current_frame_time(),true,src_,dst_,&halo_id_,default_val,value);
current_frame.redraw(get_current_frame_time(),true,src_,dst_,&halo_id_,default_val,value,primary);
} else {
current_frame.redraw(get_current_frame_time(),false,src_,dst_,&halo_id_,default_val,value);
current_frame.redraw(get_current_frame_time(),false,src_,dst_,&halo_id_,default_val,value,primary);
}
}
void unit_animation::particule::invalidate(const frame_parameters& value,const bool primary ) const
bool unit_animation::particule::invalidate(const frame_parameters& value,const bool primary ) const
{
const unit_frame& current_frame= get_current_frame();
const frame_parameters default_val = parameters_.parameters(get_animation_time() -get_begin_time());
current_frame.invalidate(get_current_frame_time(),src_,dst_,default_val,value,primary);
return current_frame.invalidate(need_update(),get_current_frame_time(),src_,dst_,default_val,value,primary);
}
unit_animation::particule::~particule()
@ -787,6 +799,16 @@ void unit_animation::particule::start_animation(int start_time,
}
}
void unit_animation::particule::update_parameters(const gamemap::location &src, const gamemap::location &dst)
{
if(src != gamemap::location::null_location || dst != gamemap::location::null_location) {
src_ = src;
dst_ = dst;
}
}
void unit_animator::add_animation(unit* animated_unit,const std::string& event,
const gamemap::location &src , const int value,bool with_bars,bool cycles,
const std::string text,const Uint32 text_color,
@ -851,6 +873,8 @@ void unit_animator::start_animations()
if(anim->animation) {
anim->my_unit->start_animation(begin_time,anim->src, anim->animation,anim->with_bars, anim->cycles,anim->text,anim->text_color);
anim->animation = NULL;
} else {
anim->my_unit->get_animation()->update_parameters(anim->src,anim->src.get_direction(anim->my_unit->facing()));
}
}

View file

@ -52,11 +52,12 @@ class unit_animation
int get_animation_time() const{ return unit_anim_.get_animation_time() ; };
int get_animation_time_potential() const{ return unit_anim_.get_animation_time_potential() ; };
void start_animation(int start_time,const gamemap::location &src = gamemap::location::null_location, const gamemap::location &dst = gamemap::location::null_location , bool cycles=false, const std::string text="", const Uint32 text_color=0,const bool accelerate = true);
void update_parameters(const gamemap::location &src, const gamemap::location &dst);
void pause_animation();
void restart_animation();
int get_current_frame_begin_time() const{ return unit_anim_.get_current_frame_begin_time() ; };
void redraw(const frame_parameters& value);
void invalidate(const frame_parameters& value ) const;
bool invalidate(const frame_parameters& value ) const;
friend class unit;
protected:
@ -82,9 +83,10 @@ class unit_animation
virtual ~particule();
bool need_update() const;
void override(int start_time,const std::string highlight="", const std::string blend_ratio ="",Uint32 blend_color = 0,const std::string offset="");
void redraw( const frame_parameters& value);
void invalidate(const frame_parameters& value, const bool primary = false) const;
void redraw( const frame_parameters& value,const bool primary=false);
bool invalidate(const frame_parameters& value, const bool primary = false) const;
void start_animation(int start_time,const gamemap::location& src,const gamemap::location& dst, bool cycles=false);
void update_parameters(const gamemap::location& src,const gamemap::location& dst);
const frame_parameters parameters(const frame_parameters & default_val,bool primary) const { return get_current_frame().merge_parameters(get_current_frame_time(),parameters_.parameters(get_animation_time()-get_begin_time()),default_val,primary); };
bool accelerate;
private:

View file

@ -317,7 +317,7 @@ bool frame_builder::need_update() const
return false;
}
void unit_frame::redraw(const int frame_time,bool first_time,const gamemap::location & src,const gamemap::location & dst,int*halo_id,const frame_parameters & animation_val,const frame_parameters & engine_val)const
void unit_frame::redraw(const int frame_time,bool first_time,const gamemap::location & src,const gamemap::location & dst,int*halo_id,const frame_parameters & animation_val,const frame_parameters & engine_val,const bool primary)const
{
const int xsrc = game_display::get_singleton()->get_location_x(src);
const int ysrc = game_display::get_singleton()->get_location_y(src);
@ -325,10 +325,9 @@ void unit_frame::redraw(const int frame_time,bool first_time,const gamemap::loca
const int ydst = game_display::get_singleton()->get_location_y(dst);
const gamemap::location::DIRECTION direction = src.get_relative_dir(dst);
const frame_parameters current_data = merge_parameters(frame_time,animation_val,engine_val);
const frame_parameters current_data = merge_parameters(frame_time,animation_val,engine_val,primary);
double tmp_offset = current_data.offset;
int d2 = game_display::get_singleton()->hex_size() / 2;
if(first_time ) {
// stuff sthat should be done only once per frame
if(!current_data.sound.empty() ) {
@ -353,7 +352,7 @@ void unit_frame::redraw(const int frame_time,bool first_time,const gamemap::loca
if(!image_loc.is_void() && image_loc.get_filename() != "") { // invalid diag image, or not diagonal
image=image::get_image(image_loc,
image::SCALED_TO_ZOOM,
false
primary
);
}
const int x = static_cast<int>(tmp_offset * xdst + (1.0-tmp_offset) * xsrc) + d2;
@ -407,7 +406,7 @@ void unit_frame::redraw(const int frame_time,bool first_time,const gamemap::loca
}
}
}
void unit_frame::invalidate(const int frame_time,const gamemap::location & src,const gamemap::location & dst,const frame_parameters & animation_val,const frame_parameters & engine_val,const bool primary) const
bool unit_frame::invalidate(const bool force,const int frame_time,const gamemap::location & src,const gamemap::location & dst,const frame_parameters & animation_val,const frame_parameters & engine_val,const bool primary) const
{
const int xsrc = game_display::get_singleton()->get_location_x(src);
const int ysrc = game_display::get_singleton()->get_location_y(src);
@ -435,7 +434,7 @@ void unit_frame::invalidate(const int frame_time,const gamemap::location & src,c
*/
image=image::get_image(image_loc,
image::SCALED_TO_ZOOM,
false
primary
);
}
const int x = static_cast<int>(tmp_offset * xdst + (1.0-tmp_offset) * xsrc)+current_data.x;
@ -446,12 +445,33 @@ void unit_frame::invalidate(const int frame_time,const gamemap::location & src,c
image->w == game_display::get_singleton()->hex_size() &&
image->h == game_display::get_singleton()->hex_size()) {
game_display::get_singleton()->invalidate(src);
// if we need to update ourselve because we changed, invalidate our hex
// and return whether or not our hex was invalidated
if(force || need_update()){
bool tmp = game_display::get_singleton()->invalidate(src);
return tmp;
}
// if not, then do nothing, either our hex has been invalidated for other reasons, and we did not do it
// or it wasn't and we don't want to do it
return false;
} else {
game_display::get_singleton()->invalidate_zone(x,y,x+image->w,y+image->h);
// if we need to update ourselve because we changed, invalidate our hexs
// and return whether or not our hexs was invalidated
if(force || need_update()){
bool tmp = game_display::get_singleton()->invalidate_zone(x,y,x+image->w,y+image->h);
return tmp;
}
// if not, check if any of our hexes is already invalidated, if any is, invalidate all of them
if(game_display::get_singleton()->zone_need_update(x,y,x+image->w,y+image->h)) {
bool tmp = game_display::get_singleton()->invalidate_zone(x,y,x+image->w,y+image->h);
return tmp;
}
return false;
}
}
return false;
}

View file

@ -177,14 +177,14 @@ class unit_frame {
public:
// Constructors
unit_frame(const frame_builder builder=frame_builder()):builder_(builder){};
void redraw(const int frame_time,bool first_time,const gamemap::location & src,const gamemap::location & dst,int*halo_id,const frame_parameters & animation_val,const frame_parameters & engine_val)const;
void redraw(const int frame_time,bool first_time,const gamemap::location & src,const gamemap::location & dst,int*halo_id,const frame_parameters & animation_val,const frame_parameters & engine_val,const bool primary)const;
const frame_parameters merge_parameters(int current_time,const frame_parameters & animation_val,const frame_parameters & engine_val=frame_parameters(),bool primary=false) const;
const frame_parameters parameters(int current_time) const {return builder_.parameters(current_time);};
int duration() const { return builder_.duration();};
bool does_not_change() const{ return builder_.does_not_change();};
bool need_update() const{ return builder_.need_update();};
void invalidate(const int frame_time,const gamemap::location & src,const gamemap::location & dst,const frame_parameters & animation_val,const frame_parameters & engine_val,const bool primary) const;
bool invalidate(const bool force,const int frame_time,const gamemap::location & src,const gamemap::location & dst,const frame_parameters & animation_val,const frame_parameters & engine_val,const bool primary) const;
private:
frame_builder builder_;