animated.i

Go to the documentation of this file.
00001 /* $Id: animated.i 26797 2008-05-23 17:37:37Z suokko $ */
00002 /*
00003    Copyright (C) 2004 by Philippe Plantier <ayin@anathas.org>
00004    Copyright (C) 2005 - 2008 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 //! @file animated.i
00017 //! Templates related to animations.
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; //assume acceleration is 1, this will be fixed at first update_last_draw_time
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                 // animation is paused
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     // Always update last_update_tick_, for the animation_time functions to work.
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()){  // cut extra 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() &&  // catch up
00146             get_current_frame_end_time() < get_end_time()) {// don't go after the end
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     //FIXME: get_animation_time() use acceleration but get_current_frame_begin_time() doesn't ?
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 

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs