00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "global.hpp"
00020
00021 #include <climits>
00022
00023 #include "SDL.h"
00024 #include "animated.hpp"
00025 #include "util.hpp"
00026 #include "serialization/string_utils.hpp"
00027
00028 namespace {
00029 int current_ticks = 0;
00030 }
00031
00032 void new_animation_frame()
00033 {
00034 current_ticks = SDL_GetTicks();
00035 }
00036
00037 int get_current_animation_tick()
00038 {
00039 return current_ticks;
00040 }
00041
00042 template<typename T, typename T_void_value>
00043 const T animated<T,T_void_value>::void_value_ = T_void_value()();
00044
00045 template<typename T, typename T_void_value>
00046 animated<T,T_void_value>::animated(int start_time) :
00047 starting_frame_time_(start_time),
00048 does_not_change_(true),
00049 started_(false),
00050 need_first_update_(false),
00051 start_tick_(0),
00052 cycles_(false),
00053 acceleration_(1),
00054 last_update_tick_(0),
00055 current_frame_key_(0)
00056 {
00057 }
00058
00059 template<typename T, typename T_void_value>
00060 animated<T,T_void_value>::animated(const std::vector<std::pair<int,T> > &cfg, int start_time, bool force_change ):
00061 starting_frame_time_(start_time),
00062 does_not_change_(true),
00063 started_(false),
00064 need_first_update_(false),
00065 start_tick_(0),
00066 cycles_(false),
00067 acceleration_(1),
00068 last_update_tick_(0),
00069 current_frame_key_(0)
00070 {
00071
00072 typename std::vector< std::pair<int,T> >::const_iterator itor = cfg.begin();
00073 for(; itor != cfg.end(); ++itor) {
00074
00075 add_frame(itor->first,itor->second,force_change);
00076 }
00077 }
00078
00079
00080
00081 template<typename T, typename T_void_value>
00082 void animated<T,T_void_value>::add_frame(int duration, const T& value,bool force_change)
00083 {
00084 if(frames_.empty() ) {
00085 does_not_change_=!force_change;
00086 frames_.push_back( frame(duration,value,starting_frame_time_));
00087 } else {
00088 does_not_change_=false;
00089 frames_.push_back( frame(duration,value,frames_.back().start_time_+frames_.back().duration_));
00090 }
00091 }
00092
00093 template<typename T, typename T_void_value>
00094 void animated<T,T_void_value>::start_animation(int start_time, bool cycles)
00095 {
00096 started_ = true;
00097 last_update_tick_ = current_ticks;
00098 acceleration_ = 1.0;
00099 start_tick_ = last_update_tick_ +
00100 static_cast<int>(( starting_frame_time_ - start_time)/acceleration_);
00101
00102 cycles_ = cycles;
00103 if(acceleration_ <=0) acceleration_ = 1;
00104 current_frame_key_= 0;
00105 need_first_update_ = !frames_.empty();
00106 }
00107
00108
00109 template<typename T, typename T_void_value>
00110 void animated<T,T_void_value>::update_last_draw_time(double acceleration)
00111 {
00112 if (acceleration > 0 && acceleration_ != acceleration) {
00113 int tmp = tick_to_time(last_update_tick_);
00114 acceleration_ = acceleration;
00115 start_tick_ = last_update_tick_ +
00116 static_cast<int>(( starting_frame_time_ - tmp)/acceleration_);
00117 }
00118 if(!started_ && start_tick_ != 0) {
00119
00120 start_tick_ +=current_ticks -last_update_tick_;
00121 }
00122 last_update_tick_ = current_ticks;
00123 if (need_first_update_) {
00124 need_first_update_ = false;
00125 return;
00126 }
00127 if(does_not_change_)
00128 return;
00129
00130
00131 if(!started_) {
00132 return;
00133 }
00134
00135 if(frames_.empty()) {
00136 does_not_change_ = true;
00137 return;
00138 }
00139 if(cycles_) {
00140 while(get_animation_time() > get_end_time()){
00141 start_tick_ += static_cast<int>(get_animation_duration()/acceleration_);
00142 current_frame_key_ = 0;
00143 }
00144 }
00145 if(get_current_frame_end_time() < get_animation_time() &&
00146 get_current_frame_end_time() < get_end_time()) {
00147 current_frame_key_++;
00148 }
00149 }
00150
00151 template<typename T, typename T_void_value>
00152 bool animated<T,T_void_value>::need_update() const
00153 {
00154 if(need_first_update_) {
00155 return true;
00156 }
00157 if(does_not_change_) {
00158 return false;
00159 }
00160 if(frames_.empty()) {
00161 return false;
00162 }
00163 if(!started_ && start_tick_ == 0) {
00164 return false;
00165 }
00166 if(current_ticks >
00167 static_cast<int>(get_current_frame_end_time() /
00168 acceleration_+start_tick_)){
00169
00170 return true;
00171 }
00172 return false;
00173 }
00174
00175 template<typename T, typename T_void_value>
00176 bool animated<T,T_void_value>::animation_finished_potential() const
00177 {
00178 if(frames_.empty())
00179 return true;
00180 if(!started_ && start_tick_ == 0)
00181 return true;
00182 if(cycles_ )
00183 return true;
00184 if(tick_to_time(current_ticks) > get_end_time())
00185 return true;
00186
00187 return false;
00188 }
00189 template<typename T, typename T_void_value>
00190 bool animated<T,T_void_value>::animation_finished() const
00191 {
00192 if(frames_.empty())
00193 return true;
00194 if(!started_ && start_tick_ == 0)
00195 return true;
00196 if(cycles_)
00197 return true;
00198 if(get_animation_time() > get_end_time())
00199 return true;
00200
00201 return false;
00202 }
00203
00204 template<typename T, typename T_void_value>
00205 int animated<T,T_void_value>::get_animation_time_potential() const
00206 {
00207 if(!started_ && start_tick_ == 0 ) return starting_frame_time_;
00208
00209 return tick_to_time(current_ticks);
00210 }
00211
00212 template<typename T, typename T_void_value>
00213 int animated<T,T_void_value>::get_animation_time() const
00214 {
00215 if(!started_ && start_tick_ == 0 ) return starting_frame_time_;
00216
00217 return tick_to_time(last_update_tick_);
00218 }
00219
00220 template<typename T, typename T_void_value>
00221 int animated<T,T_void_value>::get_animation_duration() const
00222 {
00223 return get_end_time() - get_begin_time();
00224 }
00225
00226 template<typename T, typename T_void_value>
00227 const T& animated<T,T_void_value>::get_current_frame() const
00228 {
00229 if(frames_.empty() )
00230 return void_value_;
00231 return frames_[current_frame_key_].value_;
00232 }
00233
00234 template<typename T, typename T_void_value>
00235 int animated<T,T_void_value>::get_current_frame_begin_time() const
00236 {
00237 if(frames_.empty() )
00238 return starting_frame_time_;
00239 return frames_[current_frame_key_].start_time_;
00240 }
00241
00242 template<typename T, typename T_void_value>
00243 int animated<T,T_void_value>::get_current_frame_end_time() const
00244 {
00245 if(frames_.empty() )
00246 return starting_frame_time_;
00247 return get_current_frame_begin_time() +get_current_frame_duration();
00248 }
00249
00250 template<typename T, typename T_void_value>
00251 int animated<T,T_void_value>::get_current_frame_duration() const
00252 {
00253 if(frames_.empty() )
00254 return 0;
00255 return frames_[current_frame_key_].duration_;
00256 }
00257
00258 template<typename T, typename T_void_value>
00259 int animated<T,T_void_value>::get_current_frame_time() const
00260 {
00261 if(frames_.empty() )
00262 return 0;
00263
00264 return maximum<int>(0,get_animation_time() - get_current_frame_begin_time());
00265 }
00266
00267 template<typename T, typename T_void_value>
00268 const T& animated<T,T_void_value>::get_first_frame() const
00269 {
00270 if(frames_.empty() )
00271 return void_value_;
00272 return frames_[0].value_;
00273 }
00274
00275 template<typename T, typename T_void_value>
00276 const T& animated<T,T_void_value>::get_last_frame() const
00277 {
00278 if(frames_.empty() )
00279 return void_value_;
00280 return frames_.back().value_;
00281 }
00282
00283 template<typename T, typename T_void_value>
00284 int animated<T,T_void_value>::get_frames_count() const
00285 {
00286 return frames_.size();
00287 }
00288
00289 template<typename T, typename T_void_value>
00290 int animated<T,T_void_value>::get_begin_time() const
00291 {
00292 return starting_frame_time_;
00293 }
00294
00295 template<typename T, typename T_void_value>
00296 int animated<T,T_void_value>::time_to_tick(int animation_time) const
00297 {
00298 if(!started_ && start_tick_ == 0) return 0;
00299 return start_tick_ + static_cast<int>((animation_time-starting_frame_time_)/acceleration_);
00300 }
00301 template<typename T, typename T_void_value>
00302 int animated<T,T_void_value>::tick_to_time(int animation_tick) const
00303 {
00304 if(!started_ && start_tick_ == 0) return 0;
00305 return static_cast<int>(
00306 (static_cast<double>(animation_tick - start_tick_) *
00307 acceleration_) + starting_frame_time_);
00308 }
00309 template<typename T, typename T_void_value>
00310 int animated<T,T_void_value>::get_end_time() const
00311 {
00312 if(frames_.empty())
00313 return starting_frame_time_;
00314 return frames_.back().start_time_ + frames_.back().duration_;
00315 }
00316 template<typename T, typename T_void_value>
00317 void animated<T,T_void_value>::remove_frames_until(int new_starting_time)
00318 {
00319 while (starting_frame_time_ < new_starting_time && !frames_.empty() ) {
00320 starting_frame_time_ += frames_[0].duration_;
00321 frames_.erase(frames_.begin());
00322 }
00323
00324 }
00325 template<typename T, typename T_void_value>
00326 void animated<T,T_void_value>::remove_frames_after(int new_ending_time)
00327 {
00328 int last_start_time = starting_frame_time_;
00329 typename std::vector<frame>::iterator current_frame = frames_.begin();
00330 while (last_start_time < new_ending_time && current_frame != frames_.end()) {
00331 last_start_time += current_frame->duration_;
00332 current_frame++;
00333 }
00334 frames_.erase(current_frame,frames_.end());
00335
00336 }
00337
00338
00339 template<typename T, typename T_void_value>
00340 void animated<T,T_void_value>::set_begin_time(int new_begin_time)
00341 {
00342 const int variation = new_begin_time - starting_frame_time_;
00343 starting_frame_time_ += variation;
00344 for(typename std::vector<frame>::iterator itor = frames_.begin(); itor != frames_.end() ; itor++) {
00345 itor->start_time_ += variation;
00346 }
00347 }
00348