ManaPlus
simpleanimation.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2018 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
24 
26 
27 #include "render/graphics.h"
28 
29 #include "resources/imageset.h"
30 
32 
33 #include "resources/dye/dye.h"
34 
36 
37 #include "utils/checkutils.h"
38 #include "utils/delete2.h"
39 
40 #include "debug.h"
41 
43  mAnimation(animation),
44  mAnimationTime(0),
45  mAnimationPhase(0),
46  mCurrentFrame(mAnimation != nullptr ? &mAnimation->mFrames[0] : nullptr),
47  mInitialized(true),
49 {
50 }
51 
52 SimpleAnimation::SimpleAnimation(XmlNodeConstPtr animationNode,
53  const std::string& dyePalettes) :
54  mAnimation(new Animation("simple animation")),
55  mAnimationTime(0),
56  mAnimationPhase(0),
58  mInitialized(false),
60 {
61  initializeAnimation(animationNode, dyePalettes);
62  if (mAnimation != nullptr)
64  else
65  mCurrentFrame = nullptr;
66 }
67 
69 {
71  if (mImageSet != nullptr)
72  {
73  mImageSet->decRef();
74  mImageSet = nullptr;
75  }
76 }
77 
78 void SimpleAnimation::draw(Graphics *const graphics,
79  const int posX, const int posY) const
80 {
81  FUNC_BLOCK("SimpleAnimation::draw", 1)
82  if ((mCurrentFrame == nullptr) || (mCurrentFrame->image == nullptr))
83  return;
84 
85  graphics->drawImage(mCurrentFrame->image,
86  posX + mCurrentFrame->offsetX,
87  posY + mCurrentFrame->offsetY);
88 }
89 
91 {
92  mAnimationTime = 0;
93  mAnimationPhase = 0;
94 }
95 
97 {
98  if (mAnimation == nullptr)
99  return;
100 
101  if (frame < 0)
102  frame = 0;
103  const unsigned int len = CAST_U32(mAnimation->getLength());
104  if (CAST_U32(frame) >= len)
105  frame = len - 1;
106  mAnimationPhase = frame;
107  mCurrentFrame = &mAnimation->mFrames[frame];
108 }
109 
110 bool SimpleAnimation::update(const int timePassed)
111 {
112  if ((mCurrentFrame == nullptr) || (mAnimation == nullptr) || !mInitialized)
113  return false;
114 
115  bool updated(false);
116  mAnimationTime += timePassed;
117 
119  {
120  updated = true;
122  mAnimationPhase++;
123 
125  mAnimationPhase = 0;
126 
128  }
129  return updated;
130 }
131 
133 {
134  if (mAnimation == nullptr)
135  return 0;
136 
137  return CAST_S32(mAnimation->getLength());
138 }
139 
141 {
142  if (mCurrentFrame != nullptr)
143  return mCurrentFrame->image;
144  return nullptr;
145 }
146 
147 void SimpleAnimation::initializeAnimation(XmlNodeConstPtr animationNode,
148  const std::string &dyePalettes)
149 {
150  mInitialized = false;
151 
152  if (animationNode == nullptr)
153  return;
154 
155  std::string imagePath = XML::getProperty(
156  animationNode, "imageset", "");
157 
158  // Instanciate the dye coloration.
159  if (!imagePath.empty() && !dyePalettes.empty())
160  Dye::instantiate(imagePath, dyePalettes);
161 
162  const ImageSet *const imageset = Loader::getImageSet(
163  XML::getProperty(animationNode, "imageset", ""),
164  XML::getProperty(animationNode, "width", 0),
165  XML::getProperty(animationNode, "height", 0));
166 
167  if (imageset == nullptr)
168  return;
169 
170  const int x1 = imageset->getWidth() / 2 - mapTileSize / 2;
171  const int y1 = imageset->getHeight() - mapTileSize;
172 
173  // Get animation frames
174  for_each_xml_child_node (frameNode, animationNode)
175  {
176  const int delay = XML::getIntProperty(
177  frameNode, "delay", 0, 0, 100000);
178  const int offsetX = XML::getProperty(frameNode, "offsetX", 0) - x1;
179  const int offsetY = XML::getProperty(frameNode, "offsetY", 0) - y1;
180  const int rand = XML::getIntProperty(frameNode, "rand", 100, 0, 100);
181 
182  if (xmlNameEqual(frameNode, "frame"))
183  {
184  const int index = XML::getProperty(frameNode, "index", -1);
185 
186  if (index < 0)
187  {
188  reportAlways("No valid value for 'index'")
189  continue;
190  }
191 
192  Image *const img = imageset->get(index);
193 
194  if (img == nullptr)
195  {
196  reportAlways("No image at index %d", index)
197  continue;
198  }
199 
200  if (mAnimation != nullptr)
201  mAnimation->addFrame(img, delay, offsetX, offsetY, rand);
202  }
203  else if (xmlNameEqual(frameNode, "sequence"))
204  {
205  int start = XML::getProperty(frameNode, "start", -1);
206  const int end = XML::getProperty(frameNode, "end", -1);
207 
208  if (start < 0 || end < 0)
209  {
210  reportAlways("No valid value for 'start' or 'end'")
211  continue;
212  }
213 
214  while (end >= start)
215  {
216  Image *const img = imageset->get(start);
217 
218  if (img == nullptr)
219  {
220  reportAlways("No image at index %d", start)
221  continue;
222  }
223 
224  if (mAnimation != nullptr)
225  mAnimation->addFrame(img, delay, offsetX, offsetY, rand);
226  start++;
227  }
228  }
229  else if (xmlNameEqual(frameNode, "end"))
230  {
231  if (mAnimation != nullptr)
232  mAnimation->addTerminator(rand);
233  }
234  }
235 
236  mInitialized = true;
237 }
#define CAST_U32
Definition: cast.h:30
static void instantiate(std::string &target, const std::string &palettes)
Definition: dye.cpp:96
Image * get(const size_type i) const
Definition: imageset.cpp:66
int offsetX
Definition: frame.h:43
virtual void decRef()
Definition: resource.cpp:49
ImageSet * mImageSet
ImageSet * getImageSet(const std::string &imagePath, const int w, const int h)
int getProperty(const xmlNodePtr node, const char *const name, int def)
Definition: libxml.cpp:173
const Frame * mCurrentFrame
#define delete2(var)
Definition: delete2.h:24
#define new
Definition: debug_new.h:147
void addTerminator(const int rand)
Definition: animation.cpp:55
int getIntProperty(const xmlNodePtr node, const char *const name, int def, const int min, const int max)
Definition: libxml.cpp:189
#define CAST_S32
Definition: cast.h:29
SimpleAnimation(Animation *const animation)
bool update(const int timePassed)
int delay
Definition: frame.h:42
void draw(Graphics *const graphics, const int posX, const int posY) const
size_t getLength() const
Definition: animation.h:69
#define nullptr
Definition: localconsts.h:44
int getWidth() const
Definition: imageset.h:59
#define FUNC_BLOCK(name, id)
Definition: perfomance.h:80
int offsetY
Definition: frame.h:44
void initializeAnimation(const xmlNodePtr animationNode, const std::string &dyePalettes)
Frames mFrames
Definition: animation.h:98
int getLength() const
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
#define for_each_xml_child_node(var, parent)
Definition: libxml.h:160
Image * getCurrentImage() const
Definition: image.h:61
void setFrame(int frame)
void addFrame(Image *const image, const int delay, const int offsetX, const int offsetY, const int rand)
Definition: animation.cpp:45
static const int mapTileSize
Definition: map.h:26
#define CAST_SIZE
Definition: cast.h:33
Image * image
Definition: frame.h:41
#define reportAlways(...)
Definition: checkutils.h:252
int getHeight() const
Definition: imageset.h:65
Animation * mAnimation