This commit was manufactured by cvs2svn to create branch 'branch_gettext1'.
This commit is contained in:
parent
2965548fb1
commit
636f8b8874
7 changed files with 362 additions and 0 deletions
BIN
images/items/signpost.png
Normal file
BIN
images/items/signpost.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
BIN
images/undead-soulshooter-attack.png
Normal file
BIN
images/undead-soulshooter-attack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
images/undead-soulshooter-defend.png
Normal file
BIN
images/undead-soulshooter-defend.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
images/undead-soulshooter-ranged.png
Normal file
BIN
images/undead-soulshooter-ranged.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
images/undead-soulshooter-ranged2.png
Normal file
BIN
images/undead-soulshooter-ranged2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
images/undead-soulshooter.png
Normal file
BIN
images/undead-soulshooter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
362
src/animated.hpp
Normal file
362
src/animated.hpp
Normal file
|
@ -0,0 +1,362 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2004 by Philippe Plantier <ayin@anathas.org>
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ANIMATED_IMAGE_H_INCLUDED
|
||||
#define ANIMATED_IMAGE_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "SDL.h"
|
||||
#include "config.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
template<typename T>
|
||||
class void_value
|
||||
{
|
||||
public:
|
||||
const T operator()() { return T(); }
|
||||
};
|
||||
|
||||
template<typename T, typename T_void_value=void_value<T> >
|
||||
class animated
|
||||
{
|
||||
public:
|
||||
class string_initializer
|
||||
{
|
||||
public:
|
||||
virtual T operator()(const std::string& s) const { return T(s); }
|
||||
};
|
||||
|
||||
animated();
|
||||
|
||||
//if T can be constructed from a string, you may use this constructor
|
||||
// animated(const std::string& cfg);
|
||||
//if T cannot, you may provide a custom (subclassed) string_initializer
|
||||
//to do the job
|
||||
|
||||
animated(const std::string &cfg, const string_initializer& init=string_initializer());
|
||||
|
||||
// //if T can be constructed from a config&, you may use this constructor
|
||||
//animated(const config& cfg, const std::string& tag);
|
||||
|
||||
// Adds a void frame
|
||||
void add_frame(int start);
|
||||
|
||||
// Adds a frame
|
||||
void add_frame(int start, const T& value);
|
||||
|
||||
//Starts an animation cycle. The first frame of the animation to start
|
||||
//may be set to any value
|
||||
enum { INFINITE_CYCLES = -1 };
|
||||
void start_animation(int start_time=0, int cycles=1, int acceleration=1);
|
||||
|
||||
int get_first_frame_time() const;
|
||||
int get_last_frame_time() const;
|
||||
int get_duration() const;
|
||||
|
||||
//inlined for performance
|
||||
void update_current_frame() { if(does_not_change_) return; update_current_frame_internal(); };
|
||||
bool frame_changed() const;
|
||||
|
||||
//True if the current animation was finished
|
||||
bool animation_finished() const;
|
||||
int get_animation_time() const;
|
||||
int get_frame_time() const;
|
||||
const T& get_current_frame() const;
|
||||
const T& get_base_frame() const;
|
||||
|
||||
private:
|
||||
struct frame
|
||||
{
|
||||
frame(int milliseconds) :
|
||||
milliseconds(milliseconds), has_value(false)
|
||||
{};
|
||||
|
||||
frame(int milliseconds, const T& value) :
|
||||
milliseconds(milliseconds), value(value), has_value(true)
|
||||
{};
|
||||
|
||||
// Represents the timestamp of the frame start
|
||||
int milliseconds;
|
||||
bool has_value;
|
||||
T value;
|
||||
};
|
||||
void update_current_frame_internal();
|
||||
|
||||
static const T void_value_;
|
||||
|
||||
int starting_frame_time_;
|
||||
int ending_frame_time_;
|
||||
|
||||
bool started_;
|
||||
bool no_current_frame_;
|
||||
bool does_not_change_; // optimization for 1-frame permanent animations
|
||||
|
||||
int real_start_ticks_;
|
||||
int start_ticks_;
|
||||
int current_cycle_;
|
||||
int current_time_;
|
||||
int cycles_;
|
||||
int acceleration_;
|
||||
bool frame_changed_;
|
||||
int start_frame_;
|
||||
int duration_;
|
||||
typename std::vector<frame>::size_type current_frame_;
|
||||
|
||||
std::vector<frame> frames_;
|
||||
};
|
||||
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const T animated<T,T_void_value>::void_value_ = T_void_value()();
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
animated<T,T_void_value>::animated() :
|
||||
no_current_frame_(true), started_(false),
|
||||
starting_frame_time_(INT_MAX),
|
||||
ending_frame_time_(INT_MIN),
|
||||
start_ticks_(0),
|
||||
real_start_ticks_(0),
|
||||
does_not_change_(false),
|
||||
acceleration_(1)
|
||||
{}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
animated<T,T_void_value>::animated(const std::string &cfg, const string_initializer& init):
|
||||
no_current_frame_(true), started_(false),
|
||||
starting_frame_time_(INT_MAX),
|
||||
start_ticks_(0),
|
||||
real_start_ticks_(0),
|
||||
does_not_change_(false),
|
||||
acceleration_(1)
|
||||
{
|
||||
std::vector<std::string> items = config::split(cfg);
|
||||
|
||||
int current_time = 0;
|
||||
|
||||
std::vector<std::string>::const_iterator itor = items.begin();
|
||||
for(; itor != items.end(); ++itor) {
|
||||
const std::vector<std::string>& items = config::split(*itor, ':');
|
||||
std::string str;
|
||||
int time;
|
||||
|
||||
if(items.size() > 1) {
|
||||
str = items.front();
|
||||
time = atoi(items.back().c_str());
|
||||
} else {
|
||||
str = *itor;
|
||||
time = 100;
|
||||
}
|
||||
|
||||
frames_.push_back(frame(current_time, init(str)));
|
||||
current_time += time;
|
||||
}
|
||||
|
||||
starting_frame_time_ = 0;
|
||||
ending_frame_time_ = current_time;
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
void animated<T,T_void_value>::add_frame(int start)
|
||||
{
|
||||
frames_.push_back(frame(start));
|
||||
starting_frame_time_ = minimum<int>(starting_frame_time_, start);
|
||||
ending_frame_time_ = maximum<int>(ending_frame_time_, start);
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
void animated<T,T_void_value>::add_frame(int start, const T& value)
|
||||
{
|
||||
frames_.push_back(frame(start, value));
|
||||
starting_frame_time_ = minimum<int>(starting_frame_time_, start);
|
||||
ending_frame_time_ = maximum<int>(ending_frame_time_, start);
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
void animated<T,T_void_value>::start_animation(int start_frame, int cycles, int acceleration)
|
||||
{
|
||||
started_ = true;
|
||||
start_frame_ = start_frame;
|
||||
start_ticks_ = real_start_ticks_ = current_time_ = SDL_GetTicks() * acceleration;
|
||||
cycles_ = cycles;
|
||||
current_cycle_ = 0;
|
||||
acceleration_ = acceleration;
|
||||
// current_frame_ = frames_.begin();
|
||||
current_frame_ = 0;
|
||||
|
||||
if (ending_frame_time_ >= start_frame_) {
|
||||
duration_ = ending_frame_time_ - start_frame_;
|
||||
} else {
|
||||
duration_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
void animated<T,T_void_value>::update_current_frame_internal()
|
||||
{
|
||||
// std::cerr << "--- updating frame ---\n";
|
||||
if(does_not_change_)
|
||||
return;
|
||||
|
||||
frame_changed_ = false;
|
||||
// Always update current_time_, for the animation_time functions to work.
|
||||
current_time_ = SDL_GetTicks() * acceleration_;
|
||||
if(!started_)
|
||||
return;
|
||||
|
||||
if(frames_.empty()) {
|
||||
no_current_frame_ = true;
|
||||
does_not_change_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(frames_.size() == 1 && cycles_ == INFINITE_CYCLES) {
|
||||
does_not_change_ = true;
|
||||
frame_changed_ = false;
|
||||
}
|
||||
|
||||
if (duration_ > 0) {
|
||||
// Ticks is the actual time since animation started.
|
||||
int ticks = current_time_ - start_ticks_;
|
||||
|
||||
// Handles cycle overflow
|
||||
if(ticks > duration_) {
|
||||
int ncycles = ticks/duration_;
|
||||
current_cycle_ = minimum<int>(cycles_, current_cycle_ + ncycles);
|
||||
start_ticks_ += ncycles * duration_;
|
||||
ticks -= ncycles * duration_;
|
||||
// current_frame_ = frames_.begin();
|
||||
current_frame_ = 0;
|
||||
frame_changed_ = true;
|
||||
}
|
||||
// Checks if the animation is finished
|
||||
if(cycles_ != INFINITE_CYCLES && current_cycle_ >= cycles_) {
|
||||
// If the animation is finished, the current frame is the last
|
||||
// one
|
||||
current_frame_ = frames_.size() - 1;
|
||||
frame_changed_ = true;
|
||||
// std::cerr << "Animation finished\n";
|
||||
no_current_frame_ = false;
|
||||
started_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(ticks < (frames_[current_frame_].milliseconds - start_frame_)) {
|
||||
// std::cerr << "Animation not yet started\n";
|
||||
frame_changed_ = true;
|
||||
no_current_frame_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Looks for the current frame
|
||||
typename std::vector<frame>::size_type i = current_frame_ + 1;
|
||||
for(; i != frames_.size(); ++i) {
|
||||
if(ticks < (frames_[i].milliseconds - start_frame_))
|
||||
break;
|
||||
current_frame_ = i;
|
||||
frame_changed_ = true;
|
||||
// std::cerr << "Skipping to next frame\n";
|
||||
}
|
||||
no_current_frame_ = false;
|
||||
|
||||
} else {
|
||||
// If the duration is void, the animation is automatically finished.
|
||||
// current_cycle_ = cycles_;
|
||||
if(cycles_ != -1)
|
||||
started_ = false;
|
||||
|
||||
does_not_change_ = true;
|
||||
frame_changed_ = false;
|
||||
// current_frame_ = frames_.size() - 1;
|
||||
// frame_changed_ = false;
|
||||
// std::cerr << "Returning last frame\n";
|
||||
no_current_frame_ = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
bool animated<T,T_void_value>::frame_changed() const
|
||||
{
|
||||
return frame_changed_;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
bool animated<T,T_void_value>::animation_finished() const
|
||||
{
|
||||
if(!started_)
|
||||
return true;
|
||||
//if(current_cycle_ == cycles_)
|
||||
// return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
int animated<T,T_void_value>::get_animation_time() const
|
||||
{
|
||||
if(does_not_change_)
|
||||
return SDL_GetTicks() * acceleration_ - real_start_ticks_ + start_frame_;
|
||||
|
||||
return current_time_ - real_start_ticks_ + start_frame_;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
int animated<T,T_void_value>::get_frame_time() const
|
||||
{
|
||||
return current_time_ - start_ticks_ + start_frame_;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const T& animated<T,T_void_value>::get_current_frame() const
|
||||
{
|
||||
if(no_current_frame_ == true)
|
||||
return void_value_;
|
||||
if(!frames_[current_frame_].has_value)
|
||||
return void_value_;
|
||||
|
||||
return frames_[current_frame_].value;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const T& animated<T,T_void_value>::get_base_frame() const
|
||||
{
|
||||
if(frames_.empty())
|
||||
return void_value_;
|
||||
|
||||
return frames_[0];
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
int animated<T,T_void_value>::get_first_frame_time() const
|
||||
{
|
||||
if (starting_frame_time_ != INT_MAX && starting_frame_time_ != INT_MIN)
|
||||
return starting_frame_time_;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
int animated<T,T_void_value>::get_last_frame_time() const
|
||||
{
|
||||
if (ending_frame_time_ != INT_MAX && ending_frame_time_ != INT_MIN)
|
||||
return ending_frame_time_;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
Add table
Reference in a new issue