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