/* $Id: unit_frame.cpp 9735 2006-01-18 18:31:24Z boucman $ */ /* Copyright (C) 2006 by Jeremy Rosen 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. 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 #include progressive_string::progressive_string(const std::string & data,int duration) { const std::vector first_pass = utils::split(data); const int time_chunk = maximum(duration / (first_pass.size()?first_pass.size():1),1); std::vector::const_iterator tmp; for(tmp=first_pass.begin();tmp != first_pass.end() ; tmp++) { std::vector second_pass = utils::split(*tmp,':'); if(second_pass.size() > 1) { data_.push_back(std::pair(second_pass[0],atoi(second_pass[1].c_str()))); } else { data_.push_back(std::pair(second_pass[0],time_chunk)); } } } int progressive_string::duration() const { int total =0; std::vector >::const_iterator cur_halo; for(cur_halo = data_.begin() ; cur_halo != data_.end() ; cur_halo++) { total += cur_halo->second; } return total; } const std::string grr; const std::string& progressive_string::get_current_element( int current_time)const { int time = 0; unsigned int sub_halo = 0; if(data_.empty()) return grr; while(time < current_time&& sub_halo < data_.size()) { time += data_[sub_halo].second; sub_halo++; } if(sub_halo > 0) sub_halo --; if(sub_halo >= data_.size()) sub_halo = data_.size(); return data_[sub_halo].first; } bool progressive_string::does_not_change() const { return data_.size() <= 1; } progressive_double::progressive_double(const std::string &data, int duration) { const std::vector first_split = utils::split(data); const int time_chunk = maximum(duration / (first_split.size()?first_split.size():1),1); std::vector::const_iterator tmp; std::vector > first_pass; for(tmp=first_split.begin();tmp != first_split.end() ; tmp++) { std::vector second_pass = utils::split(*tmp,':'); if(second_pass.size() > 1) { first_pass.push_back(std::pair(second_pass[0],atoi(second_pass[1].c_str()))); } else { first_pass.push_back(std::pair(second_pass[0],time_chunk)); } } std::vector >::const_iterator tmp2; for(tmp2=first_pass.begin();tmp2 != first_pass.end() ; tmp2++) { std::vector range = utils::split(tmp2->first,'~'); data_.push_back(std::pair,int> ( std::pair( atof(range[0].c_str()), atof(range.size()>1?range[1].c_str():range[0].c_str())), tmp2->second)); } } const double progressive_double::get_current_element(int current_time)const { int time = 0; unsigned int sub_halo = 0; if(data_.empty()) return 0; while(time < current_time&& sub_halo < data_.size()) { time += data_[sub_halo].second; sub_halo++; } if(sub_halo > 0) { sub_halo--; time -= data_[sub_halo].second; } if(sub_halo >= data_.size()) { sub_halo = data_.size(); time = current_time; // never more than max allowed } const double first = data_[sub_halo].first.first; const double second = data_[sub_halo].first.second; return ( double(current_time - time)/(double)(data_[sub_halo].second))*(second - first)+ first; } int progressive_double::duration() const { int total =0; std::vector,int> >::const_iterator cur_halo; for(cur_halo = data_.begin() ; cur_halo != data_.end() ; cur_halo++) { total += cur_halo->second; } return total; } bool progressive_double::does_not_change() const { return data_.empty() || ( data_.size() == 1 && data_[0].first.first == data_[0].first.second); } progressive_int::progressive_int(const std::string &data, int duration) { const std::vector first_split = utils::split(data); const int time_chunk = maximum(duration / (first_split.size()?first_split.size():1),1); std::vector::const_iterator tmp; std::vector > first_pass; for(tmp=first_split.begin();tmp != first_split.end() ; tmp++) { std::vector second_pass = utils::split(*tmp,':'); if(second_pass.size() > 1) { first_pass.push_back(std::pair(second_pass[0],atoi(second_pass[1].c_str()))); } else { first_pass.push_back(std::pair(second_pass[0],time_chunk)); } } std::vector >::const_iterator tmp2; for(tmp2=first_pass.begin();tmp2 != first_pass.end() ; tmp2++) { std::vector range = utils::split(tmp2->first,'~'); data_.push_back(std::pair,int> ( std::pair( atoi(range[0].c_str()), atoi(range.size()>1?range[1].c_str():range[0].c_str())), tmp2->second)); } } const int progressive_int::get_current_element(int current_time)const { int time = 0; unsigned int sub_halo = 0; if(data_.empty()) return 0; while(time < current_time&& sub_halo < data_.size()) { time += data_[sub_halo].second; sub_halo++; } if(sub_halo > 0) { sub_halo--; time -= data_[sub_halo].second; } if(sub_halo >= data_.size()) { sub_halo = data_.size(); time = current_time; // never more than max allowed } const int first = data_[sub_halo].first.first; const int second = data_[sub_halo].first.second; return int(( double(current_time - time)/(double)(data_[sub_halo].second))*(second - first)+ first); } int progressive_int::duration() const { int total =0; std::vector,int> >::const_iterator cur_halo; for(cur_halo = data_.begin() ; cur_halo != data_.end() ; cur_halo++) { total += cur_halo->second; } return total; } bool progressive_int::does_not_change() const { return data_.empty() || ( data_.size() == 1 && data_[0].first.first == data_[0].first.second); } unit_frame::unit_frame() : image_(), image_diagonal_(),halo_(), sound_(), halo_x_(), halo_y_(), duration_(0), blend_with_(0),blend_ratio_(), highlight_ratio_("1.0"),offset_("-20") { } unit_frame::unit_frame(const image::locator& image, int duration, const std::string& highlight, const std::string& offset, Uint32 blend_color, const std::string& blend_rate, const std::string& in_halo, const std::string& halox, const std::string& haloy, const image::locator & diag) : image_(image),image_diagonal_(diag), halo_(in_halo,duration), halo_x_(halox,duration), halo_y_(haloy,duration), duration_(duration), blend_with_(blend_color), blend_ratio_(blend_rate,duration), highlight_ratio_(highlight,duration) { // let's decide of duration ourselves if(offset.empty()) offset_=progressive_double("-20",duration); else offset_=progressive_double(offset,duration); duration_ = maximum(duration_, highlight_ratio_.duration()); duration_ = maximum(duration_, blend_ratio_.duration()); duration_ = maximum(duration_, halo_.duration()); duration_ = maximum(duration_, offset_.duration()); } unit_frame::unit_frame(const config& cfg) { image_ = image::locator(cfg["image"]); image_diagonal_ = image::locator(cfg["image_diagonal"]); sound_ = cfg["sound"]; if(!cfg["duration"].empty()) { duration_ = atoi(cfg["duration"].c_str()); } else { duration_ = atoi(cfg["end"].c_str()) - atoi(cfg["begin"].c_str()); } halo_ = progressive_string(cfg["halo"],duration_); halo_x_ = progressive_int(cfg["halo_x"],duration_); halo_y_ = progressive_int(cfg["halo_y"],duration_); std::vector tmp_blend=utils::split(cfg["blend_color"]); if(tmp_blend.size() ==3) blend_with_= display::rgb(atoi(tmp_blend[0].c_str()),atoi(tmp_blend[1].c_str()),atoi(tmp_blend[2].c_str())); blend_ratio_ = progressive_double(cfg["blend_ratio"],duration_); highlight_ratio_ = progressive_double(cfg["alpha"].empty()?"1.0":cfg["alpha"],duration_); offset_ = progressive_double(cfg["offset"].empty()?"-20":cfg["offset"],duration_); } const std::string &unit_frame::halo(int current_time) const { return halo_.get_current_element(current_time); } double unit_frame::blend_ratio(int current_time) const { return blend_ratio_.get_current_element(current_time); } fixed_t unit_frame::highlight_ratio(int current_time) const { return ftofxp(highlight_ratio_.get_current_element(current_time)); } double unit_frame::offset(int current_time) const { return offset_.get_current_element(current_time); } int unit_frame::halo_x(int current_time) const { return halo_x_.get_current_element(current_time); } int unit_frame::halo_y(int current_time) const { return halo_y_.get_current_element(current_time); } bool unit_frame::does_not_change() const { return halo_.does_not_change() && halo_x_.does_not_change() && halo_y_.does_not_change() && blend_ratio_.does_not_change() && highlight_ratio_.does_not_change() && offset_.does_not_change(); }