animated.i

Go to the documentation of this file.
00001 /* $Id: animated.i 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2004 by Philippe Plantier <ayin@anathas.org>
00004    Copyright (C) 2005 - 2012 by Guillaume Melquiond <guillaume.melquiond@gmail.com>
00005    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License version 2
00009    or at your option any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /**
00017  * @file animated.i
00018  * Templates related to animations.
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; //assume acceleration is 1, this will be fixed at first update_last_draw_time
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                 // animation is paused
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     // Always update last_update_tick_, for the animation_time functions to work.
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()){  // cut extra 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() &&  // catch up
00148             get_current_frame_end_time() < get_end_time()) {// don't go after the end
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     //FIXME: get_animation_time() use acceleration but get_current_frame_begin_time() doesn't ?
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         // at this point last_start_time is set to the beginning of the first frame past the end
00354         // or set to frames_.end()
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Tue May 22 2012 01:03:40 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs