Mana
Loading...
Searching...
No Matches
compoundsprite.cpp
Go to the documentation of this file.
1/*
2 * The Mana Client
3 * Copyright (C) 2010-2012 The Mana Developers
4 *
5 * This file is part of The Mana Client.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "compoundsprite.h"
22
23#include "graphics.h"
24#include "map.h"
25
26#include "resources/image.h"
27
28#include "utils/dtor.h"
29
30#include <SDL.h>
31
38
40{
41 bool ret = false;
42
43 for (auto sprite : mSprites)
44 if (sprite)
45 ret |= sprite->reset();
46
48 return ret;
49}
50
51bool CompoundSprite::play(const std::string &action)
52{
53 bool ret = false;
54
55 for (auto sprite : mSprites)
56 if (sprite)
57 ret |= sprite->play(action);
58
60 return ret;
61}
62
64{
65 bool ret = false;
66
67 for (auto sprite : mSprites)
68 if (sprite)
69 ret |= sprite->update(time);
70
72 return ret;
73}
74
75bool CompoundSprite::draw(Graphics *graphics, int posX, int posY) const
76{
77 doRedraw();
78
79 if (mSprites.empty()) // Nothing to draw
80 return false;
81
82 posX += mOffsetX;
83 posY += mOffsetY;
84
85 if (mAlpha == 1.0f && mImage)
86 {
88 }
89
90 if (mAlpha && mAlphaImage)
91 {
94 }
95
96 for (auto sprite : mSprites)
97 {
98 if (sprite)
99 {
100 sprite->setAlpha(mAlpha);
101 sprite->draw(graphics, posX - sprite->getWidth() / 2, posY - sprite->getHeight());
102 }
103 }
104
105 return false;
106}
107
109{
110 bool ret = false;
111
112 for (auto sprite : mSprites)
113 if (sprite)
114 ret |= sprite->setDirection(direction);
115
116 mNeedsRedraw |= ret;
117 return ret;
118}
119
121{
122 if (mImage || mAlphaImage)
123 return 1;
124
125 return size();
126}
127
129{
130 mSprites.push_back(sprite);
131 mNeedsRedraw = true;
132}
133
134void CompoundSprite::set(int layer, Sprite *sprite)
135{
136 // Skip if it won't change anything
137 if (mSprites.at(layer) == sprite)
138 return;
139
140 delete mSprites.at(layer);
141 mSprites[layer] = sprite;
142 mNeedsRedraw = true;
143}
144
146{
147 // Skip if it won't change anything
148 if (mSprites.empty())
149 return;
150
152 mSprites.clear();
153 mNeedsRedraw = true;
154}
155
156void CompoundSprite::ensureSize(size_t layerCount)
157{
158 // Skip if it won't change anything
159 if (mSprites.size() >= layerCount)
160 return;
161
162 mSprites.resize(layerCount);
163}
164
166{
167 int duration = 0;
168 for (auto sprite : mSprites)
169 if (sprite && sprite->getDuration() > duration)
170 duration = sprite->getDuration();
171
172 return duration;
173}
174
175#if 0
176static void updateValues(int &dimension, int &pos, int imgDimUL, int imgDimRD, int imgOffset)
177{
178 // Handle going beyond the left/up
179 int temp = -(pos + imgOffset - imgDimUL); // Negated for easier use
180 if (temp > 0)
181 {
182 pos += temp;
183 dimension += temp;
184 }
185
186 // Handle going beyond the right/down
187 temp = pos + imgOffset + imgDimRD;
188 if (temp > dimension)
189 dimension = temp;
190}
191#endif
192
194{
195#if 1 // TODO_SDL2: Does it make sense to implement CompoundSprite?
196 auto baseSprite = mSprites.empty() ? nullptr : mSprites.at(0);
197 mWidth = baseSprite ? baseSprite->getWidth() : 0;
198 mHeight = baseSprite ? baseSprite->getHeight() : 0;
199 mOffsetX = 0;
200 mOffsetY = 0;
201 mNeedsRedraw = false;
202#else
203
204#ifdef USE_OPENGL
205 // TODO OpenGL support
206 if (Image::getLoadAsOpenGL())
207 {
208 mWidth = mSprites.at(0)->getWidth();
209 mHeight = mSprites.at(0)->getHeight();
210 mOffsetX = 0;
211 mOffsetY = 0;
212 mNeedsRedraw = false;
213 return;
214 }
215#endif
216
218
219 int posX = 0;
220 int posY = 0;
221
222 for (auto sprite : mSprites)
223 {
224 if (!sprite)
225 continue;
226
228 sprite->getWidth() / 2,
229 sprite->getWidth() / 2,
230 sprite->getOffsetX());
231
233 sprite->getHeight(),
234 0,
235 sprite->getOffsetY());
236 }
237
238 if (mWidth == 0 && mHeight == 0)
239 {
240 mNeedsRedraw = false;
241 return;
242 }
243
244 mOffsetX -= posX;
245 mOffsetY -= posY;
246
247#if SDL_BYTEORDER == SDL_BIG_ENDIAN
248 int rmask = 0xff000000;
249 int gmask = 0x00ff0000;
250 int bmask = 0x0000ff00;
251 int amask = 0x000000ff;
252#else
253 int rmask = 0x000000ff;
254 int gmask = 0x0000ff00;
255 int bmask = 0x00ff0000;
256 int amask = 0xff000000;
257#endif
258
260 32, rmask, gmask, bmask, amask);
261
262 if (!surface)
263 return;
264
265 Graphics *graphics = new Graphics();
266 graphics->setBlitMode(Graphics::BLIT_GFX);
267 graphics->setTarget(surface);
269
270 for (auto sprite : mSprites)
271 {
272 if (!sprite)
273 continue;
274
275 sprite->draw(graphics,
276 posX - sprite->getWidth() / 2,
277 posY - sprite->getHeight());
278 }
279
280 // Uncomment to see buffer sizes
281 /*graphics->fillRectangle(gcn::Rectangle(0, 0, 3, 3));
282 graphics->fillRectangle(gcn::Rectangle(mWidth - 3, 0, 3, 3));
283 graphics->fillRectangle(gcn::Rectangle(mWidth - 3, mHeight - 3, 3, 3));
284 graphics->fillRectangle(gcn::Rectangle(0, mHeight - 3, 3, 3));*/
285
286 delete graphics;
287
289 32, rmask, gmask, bmask, amask);
290
292 SDL_BlitSurface(surface, nullptr, surfaceA, nullptr);
293
294 delete mImage;
295 delete mAlphaImage;
296
299
302
303 mNeedsRedraw = false;
304#endif
305}
void add(Sprite *sprite)
void redraw() const
std::vector< Sprite * > mSprites
bool draw(Graphics *graphics, int posX, int posY) const
void doRedraw() const
size_t size() const
int getNumberOfLayers() const
bool play(const std::string &action)
void ensureSize(size_t layerCount)
void set(int layer, Sprite *sprite)
bool setDirection(SpriteDirection direction)
bool update(int time)
int getMaxDuration() const
A central point of control for graphics.
Definition graphics.h:78
bool drawImage(const Image *image, int x, int y)
Blits an image onto the screen.
Definition graphics.cpp:36
void _beginDraw() override
Definition graphics.cpp:242
int getWidth() const
Returns the logical width of the screen.
Definition graphics.h:221
static Resource * load(SDL_RWops *rw)
Loads an image from an SDL_RWops structure.
Definition image.cpp:98
void setAlpha(float alpha)
Sets the alpha value of this image.
Definition image.cpp:176
Animates a sprite by adding playback state.
Definition sprite.h:37
Graphics * graphics
Definition client.cpp:104
void delete_all(Container &c)
Definition dtor.h:46
SpriteDirection
Definition spritedef.h:74