1 |
|
|
/* |
2 |
|
|
* The ManaPlus Client |
3 |
|
|
* Copyright (C) 2010 The Mana Developers |
4 |
|
|
* Copyright (C) 2011-2019 The ManaPlus Developers |
5 |
|
|
* Copyright (C) 2019-2021 Andrei Karas |
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 |
|
|
|
23 |
|
|
#include "being/compoundsprite.h" |
24 |
|
|
|
25 |
|
|
#include "configuration.h" |
26 |
|
|
|
27 |
|
|
#include "sdlshared.h" |
28 |
|
|
|
29 |
|
|
#include "being/compounditem.h" |
30 |
|
|
|
31 |
|
|
#include "render/surfacegraphics.h" |
32 |
|
|
|
33 |
|
|
#if defined(USE_OPENGL) || !defined(USE_SDL2) |
34 |
|
|
#include "resources/imagehelper.h" |
35 |
|
|
#endif // USE_OPENGL |
36 |
|
|
#include "resources/image/image.h" |
37 |
|
|
|
38 |
|
|
#include "utils/delete2.h" |
39 |
|
|
#include "utils/dtor.h" |
40 |
|
|
#include "utils/foreach.h" |
41 |
|
|
#include "utils/likely.h" |
42 |
|
|
#include "utils/sdlcheckutils.h" |
43 |
|
|
|
44 |
|
|
#ifndef USE_SDL2 |
45 |
|
|
#include "game.h" |
46 |
|
|
|
47 |
|
|
#include "const/resources/map/map.h" |
48 |
|
|
|
49 |
|
|
#include "resources/map/map.h" |
50 |
|
|
|
51 |
|
|
#include "utils/timer.h" |
52 |
|
|
|
53 |
|
|
PRAGMA48(GCC diagnostic push) |
54 |
|
|
PRAGMA48(GCC diagnostic ignored "-Wshadow") |
55 |
|
|
#ifndef SDL_BIG_ENDIAN |
56 |
|
|
#include <SDL_endian.h> |
57 |
|
|
#endif // SDL_BYTEORDER |
58 |
|
|
PRAGMA48(GCC diagnostic pop) |
59 |
|
|
#endif // USE_SDL2 |
60 |
|
|
|
61 |
|
|
#include "debug.h" |
62 |
|
|
|
63 |
|
|
#ifndef USE_SDL2 |
64 |
|
|
static const int BUFFER_WIDTH = 100; |
65 |
|
|
static const int BUFFER_HEIGHT = 100; |
66 |
|
|
static const unsigned cache_max_size = 10; |
67 |
|
|
static const unsigned cache_clean_part = 3; |
68 |
|
|
#endif // USE_SDL2 |
69 |
|
|
|
70 |
|
|
bool CompoundSprite::mEnableDelay = true; |
71 |
|
|
|
72 |
|
103 |
CompoundSprite::CompoundSprite() : |
73 |
|
|
Sprite(), |
74 |
|
|
mSprites(), |
75 |
|
|
imagesCache(), |
76 |
|
|
mCacheItem(nullptr), |
77 |
|
|
mImage(nullptr), |
78 |
|
|
mAlphaImage(nullptr), |
79 |
|
|
mOffsetX(0), |
80 |
|
|
mOffsetY(0), |
81 |
|
|
mStartTime(0), |
82 |
|
|
mLastTime(0), |
83 |
|
|
#ifndef USE_SDL2 |
84 |
|
|
mNextRedrawTime(0), |
85 |
|
|
#endif // USE_SDL2 |
86 |
|
|
mNeedsRedraw(false), |
87 |
✓✗✓✗
|
309 |
mEnableAlphaFix(config.getBoolValue("enableAlphaFix")), |
88 |
✓✗✓✗
|
309 |
mDisableAdvBeingCaching(config.getBoolValue("disableAdvBeingCaching")), |
89 |
✓✗✓✗
|
927 |
mDisableBeingCaching(config.getBoolValue("disableBeingCaching")) |
90 |
|
|
{ |
91 |
|
103 |
mAlpha = 1.0F; |
92 |
|
103 |
} |
93 |
|
|
|
94 |
|
412 |
CompoundSprite::~CompoundSprite() |
95 |
|
|
{ |
96 |
|
103 |
clear(); |
97 |
|
103 |
mImage = nullptr; |
98 |
|
103 |
mAlphaImage = nullptr; |
99 |
|
103 |
} |
100 |
|
|
|
101 |
|
|
bool CompoundSprite::reset() |
102 |
|
|
{ |
103 |
|
|
bool ret = false; |
104 |
|
|
FOR_EACH (SpriteIterator, it, mSprites) |
105 |
|
|
{ |
106 |
|
|
if (*it != nullptr) |
107 |
|
|
ret |= (*it)->reset(); |
108 |
|
|
} |
109 |
|
|
if (ret) |
110 |
|
|
mLastTime = 0; |
111 |
|
|
mNeedsRedraw |= ret; |
112 |
|
|
return ret; |
113 |
|
|
} |
114 |
|
|
|
115 |
|
|
bool CompoundSprite::play(const std::string &action) |
116 |
|
|
{ |
117 |
|
|
bool ret = false; |
118 |
|
|
bool ret2 = true; |
119 |
|
|
FOR_EACH (SpriteIterator, it, mSprites) |
120 |
|
|
{ |
121 |
|
|
if (*it != nullptr) |
122 |
|
|
{ |
123 |
|
|
const bool tmpVal = (*it)->play(action); |
124 |
|
|
ret |= tmpVal; |
125 |
|
|
ret2 &= tmpVal; |
126 |
|
|
} |
127 |
|
|
} |
128 |
|
|
mNeedsRedraw |= ret; |
129 |
|
|
if (ret2) |
130 |
|
|
mLastTime = 0; |
131 |
|
|
return ret; |
132 |
|
|
} |
133 |
|
|
|
134 |
|
|
bool CompoundSprite::update(const int time) |
135 |
|
|
{ |
136 |
|
|
bool ret = false; |
137 |
|
|
if (A_UNLIKELY(mLastTime == 0)) |
138 |
|
|
mStartTime = time; |
139 |
|
|
mLastTime = time; |
140 |
|
|
FOR_EACH (SpriteIterator, it, mSprites) |
141 |
|
|
{ |
142 |
|
|
if (*it != nullptr) |
143 |
|
|
ret |= (*it)->update(time); |
144 |
|
|
} |
145 |
|
|
mNeedsRedraw |= ret; |
146 |
|
|
return ret; |
147 |
|
|
} |
148 |
|
|
|
149 |
|
|
void CompoundSprite::drawSimple(Graphics *const graphics, |
150 |
|
|
const int posX, |
151 |
|
|
const int posY) const |
152 |
|
|
{ |
153 |
|
|
FUNC_BLOCK("CompoundSprite::draw", 1) |
154 |
|
|
if (mNeedsRedraw) |
155 |
|
|
updateImages(); |
156 |
|
|
|
157 |
|
|
if (mSprites.empty()) // Nothing to draw |
158 |
|
|
return; |
159 |
|
|
|
160 |
|
|
if (mAlpha == 1.0F && (mImage != nullptr)) |
161 |
|
|
{ |
162 |
|
|
graphics->drawImage(mImage, posX + mOffsetX, posY + mOffsetY); |
163 |
|
|
} |
164 |
|
|
else if ((mAlpha != 0.0F) && (mAlphaImage != nullptr)) |
165 |
|
|
{ |
166 |
|
|
mAlphaImage->setAlpha(mAlpha); |
167 |
|
|
graphics->drawImage(mAlphaImage, |
168 |
|
|
posX + mOffsetX, posY + mOffsetY); |
169 |
|
|
} |
170 |
|
|
else |
171 |
|
|
{ |
172 |
|
|
CompoundSprite::drawSprites(graphics, posX, posY); |
173 |
|
|
} |
174 |
|
|
} |
175 |
|
|
|
176 |
|
|
void CompoundSprite::drawSprites(Graphics *const graphics, |
177 |
|
|
const int posX, |
178 |
|
|
const int posY) const |
179 |
|
|
{ |
180 |
|
|
FOR_EACH (SpriteConstIterator, it, mSprites) |
181 |
|
|
{ |
182 |
|
|
if (*it != nullptr) |
183 |
|
|
{ |
184 |
|
|
(*it)->setAlpha(mAlpha); |
185 |
|
|
(*it)->draw(graphics, posX, posY); |
186 |
|
|
} |
187 |
|
|
} |
188 |
|
|
} |
189 |
|
|
|
190 |
|
|
void CompoundSprite::drawSpritesSDL(Graphics *const graphics, |
191 |
|
|
const int posX, |
192 |
|
|
const int posY) const |
193 |
|
|
{ |
194 |
|
|
FOR_EACH (SpriteConstIterator, it, mSprites) |
195 |
|
|
{ |
196 |
|
|
if (*it != nullptr) |
197 |
|
|
(*it)->draw(graphics, posX, posY); |
198 |
|
|
} |
199 |
|
|
} |
200 |
|
|
|
201 |
|
|
int CompoundSprite::getWidth() const |
202 |
|
|
{ |
203 |
|
|
FOR_EACH (SpriteConstIterator, it, mSprites) |
204 |
|
|
{ |
205 |
|
|
const Sprite *const base = *it; |
206 |
|
|
if (base != nullptr) |
207 |
|
|
return base->getWidth(); |
208 |
|
|
} |
209 |
|
|
|
210 |
|
|
return 0; |
211 |
|
|
} |
212 |
|
|
|
213 |
|
|
int CompoundSprite::getHeight() const |
214 |
|
|
{ |
215 |
|
|
FOR_EACH (SpriteConstIterator, it, mSprites) |
216 |
|
|
{ |
217 |
|
|
const Sprite *const base = *it; |
218 |
|
|
if (base != nullptr) |
219 |
|
|
return base->getHeight(); |
220 |
|
|
} |
221 |
|
|
|
222 |
|
|
return 0; |
223 |
|
|
} |
224 |
|
|
|
225 |
|
|
const Image *CompoundSprite::getImage() const |
226 |
|
|
{ |
227 |
|
|
return mImage; |
228 |
|
|
} |
229 |
|
|
|
230 |
|
|
bool CompoundSprite::setSpriteDirection(const SpriteDirection::Type direction) |
231 |
|
|
{ |
232 |
|
|
bool ret = false; |
233 |
|
|
FOR_EACH (SpriteIterator, it, mSprites) |
234 |
|
|
{ |
235 |
|
|
if (*it != nullptr) |
236 |
|
|
ret |= (*it)->setSpriteDirection(direction); |
237 |
|
|
} |
238 |
|
|
if (ret) |
239 |
|
|
mLastTime = 0; |
240 |
|
|
mNeedsRedraw |= ret; |
241 |
|
|
return ret; |
242 |
|
|
} |
243 |
|
|
|
244 |
|
|
int CompoundSprite::getNumberOfLayers() const |
245 |
|
|
{ |
246 |
|
|
if ((mImage != nullptr) || (mAlphaImage != nullptr)) |
247 |
|
|
return 1; |
248 |
|
|
return CAST_S32(mSprites.size()); |
249 |
|
|
} |
250 |
|
|
|
251 |
|
|
unsigned int CompoundSprite::getCurrentFrame() const |
252 |
|
|
{ |
253 |
|
|
FOR_EACH (SpriteConstIterator, it, mSprites) |
254 |
|
|
{ |
255 |
|
|
if (*it != nullptr) |
256 |
|
|
return (*it)->getCurrentFrame(); |
257 |
|
|
} |
258 |
|
|
return 0; |
259 |
|
|
} |
260 |
|
|
|
261 |
|
|
unsigned int CompoundSprite::getFrameCount() const |
262 |
|
|
{ |
263 |
|
|
FOR_EACH (SpriteConstIterator, it, mSprites) |
264 |
|
|
{ |
265 |
|
|
if (*it != nullptr) |
266 |
|
|
return (*it)->getFrameCount(); |
267 |
|
|
} |
268 |
|
|
return 0; |
269 |
|
|
} |
270 |
|
|
|
271 |
|
|
void CompoundSprite::addSprite(Sprite *const sprite) |
272 |
|
|
{ |
273 |
|
|
mSprites.push_back(sprite); |
274 |
|
|
mNeedsRedraw = true; |
275 |
|
|
} |
276 |
|
|
|
277 |
|
|
void CompoundSprite::setSprite(const size_t layer, Sprite *const sprite) |
278 |
|
|
{ |
279 |
|
|
// Skip if it won't change anything |
280 |
|
|
if (mSprites[layer] == sprite) |
281 |
|
|
return; |
282 |
|
|
|
283 |
|
|
delete mSprites[layer]; |
284 |
|
|
mSprites[layer] = sprite; |
285 |
|
|
mNeedsRedraw = true; |
286 |
|
|
} |
287 |
|
|
|
288 |
|
|
void CompoundSprite::removeSprite(const int layer) |
289 |
|
|
{ |
290 |
|
|
// Skip if it won't change anything |
291 |
|
|
if (mSprites[layer] == nullptr) |
292 |
|
|
return; |
293 |
|
|
|
294 |
|
|
delete2(mSprites[layer]) |
295 |
|
|
mNeedsRedraw = true; |
296 |
|
|
} |
297 |
|
|
|
298 |
|
103 |
void CompoundSprite::clear() |
299 |
|
|
{ |
300 |
|
|
// Skip if it won't change anything |
301 |
✗✓ |
206 |
if (!mSprites.empty()) |
302 |
|
|
{ |
303 |
|
|
delete_all(mSprites); |
304 |
|
|
mSprites.clear(); |
305 |
|
|
} |
306 |
|
103 |
mNeedsRedraw = true; |
307 |
|
206 |
delete_all(imagesCache); |
308 |
|
206 |
imagesCache.clear(); |
309 |
✗✓ |
103 |
delete2(mCacheItem) |
310 |
|
103 |
mLastTime = 0; |
311 |
|
103 |
} |
312 |
|
|
|
313 |
|
|
void CompoundSprite::ensureSize(const size_t layerCount) |
314 |
|
|
{ |
315 |
|
|
// Skip if it won't change anything |
316 |
|
|
if (mSprites.size() >= layerCount) |
317 |
|
|
return; |
318 |
|
|
|
319 |
|
|
// resize(layerCount, nullptr); |
320 |
|
|
mSprites.resize(layerCount); |
321 |
|
|
} |
322 |
|
|
|
323 |
|
|
void CompoundSprite::redraw() const |
324 |
|
|
{ |
325 |
|
|
#ifndef USE_SDL2 |
326 |
|
|
|
327 |
|
|
#if SDL_BYTEORDER == SDL_BIG_ENDIAN |
328 |
|
|
const uint32_t rmask = 0xff000000U; |
329 |
|
|
const uint32_t gmask = 0x00ff0000U; |
330 |
|
|
const uint32_t bmask = 0x0000ff00U; |
331 |
|
|
const uint32_t amask = 0x000000ffU; |
332 |
|
|
#else // SDL_BYTEORDER == SDL_BIG_ENDIAN |
333 |
|
|
const uint32_t rmask = 0x000000ffU; |
334 |
|
|
const uint32_t gmask = 0x0000ff00U; |
335 |
|
|
const uint32_t bmask = 0x00ff0000U; |
336 |
|
|
const uint32_t amask = 0xff000000U; |
337 |
|
|
#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN |
338 |
|
|
|
339 |
|
|
SDL_Surface *const surface = MSDL_CreateRGBSurface(SDL_HWSURFACE, |
340 |
|
|
BUFFER_WIDTH, BUFFER_HEIGHT, 32, rmask, gmask, bmask, amask); |
341 |
|
|
|
342 |
|
|
if (surface == nullptr) |
343 |
|
|
return; |
344 |
|
|
|
345 |
|
|
SurfaceGraphics *graphics = new SurfaceGraphics; |
346 |
|
|
graphics->setBlitMode(BlitMode::BLIT_GFX); |
347 |
|
|
graphics->setTarget(surface); |
348 |
|
|
graphics->beginDraw(); |
349 |
|
|
|
350 |
|
|
int tileX = mapTileSize / 2; |
351 |
|
|
int tileY = mapTileSize; |
352 |
|
|
|
353 |
|
|
const Game *const game = Game::instance(); |
354 |
|
|
if (game != nullptr) |
355 |
|
|
{ |
356 |
|
|
const Map *const map = game->getCurrentMap(); |
357 |
|
|
if (map != nullptr) |
358 |
|
|
{ |
359 |
|
|
tileX = map->getTileWidth() / 2; |
360 |
|
|
tileY = map->getTileWidth(); |
361 |
|
|
} |
362 |
|
|
} |
363 |
|
|
|
364 |
|
|
const int posX = BUFFER_WIDTH / 2 - tileX; |
365 |
|
|
const int posY = BUFFER_HEIGHT - tileY; |
366 |
|
|
|
367 |
|
|
mOffsetX = tileX - BUFFER_WIDTH / 2; |
368 |
|
|
mOffsetY = tileY - BUFFER_HEIGHT; |
369 |
|
|
|
370 |
|
|
drawSpritesSDL(graphics, posX, posY); |
371 |
|
|
|
372 |
|
|
delete2(graphics) |
373 |
|
|
|
374 |
|
|
SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE); |
375 |
|
|
|
376 |
|
|
delete mAlphaImage; |
377 |
|
|
|
378 |
|
|
if (ImageHelper::mEnableAlpha) |
379 |
|
|
{ |
380 |
|
|
SDL_Surface *const surfaceA = MSDL_CreateRGBSurface(SDL_HWSURFACE, |
381 |
|
|
BUFFER_WIDTH, BUFFER_HEIGHT, 32, rmask, gmask, bmask, amask); |
382 |
|
|
SDL_BlitSurface(surface, nullptr, surfaceA, nullptr); |
383 |
|
|
mAlphaImage = imageHelper->loadSurface(surfaceA); |
384 |
|
|
MSDL_FreeSurface(surfaceA); |
385 |
|
|
} |
386 |
|
|
else |
387 |
|
|
{ |
388 |
|
|
mAlphaImage = nullptr; |
389 |
|
|
} |
390 |
|
|
|
391 |
|
|
delete mImage; |
392 |
|
|
mImage = imageHelper->loadSurface(surface); |
393 |
|
|
MSDL_FreeSurface(surface); |
394 |
|
|
#endif // USE_SDL2 |
395 |
|
|
} |
396 |
|
|
|
397 |
|
|
void CompoundSprite::setAlpha(float alpha) |
398 |
|
|
{ |
399 |
|
|
if (alpha != mAlpha) |
400 |
|
|
{ |
401 |
|
|
if (mEnableAlphaFix && |
402 |
|
|
#ifdef USE_OPENGL |
403 |
|
|
imageHelper->useOpenGL() == RENDER_SOFTWARE && |
404 |
|
|
#endif // USE_OPENGL |
405 |
|
|
mSprites.size() > 3U) |
406 |
|
|
{ |
407 |
|
|
FOR_EACH (SpriteConstIterator, it, mSprites) |
408 |
|
|
{ |
409 |
|
|
if (*it != nullptr) |
410 |
|
|
(*it)->setAlpha(alpha); |
411 |
|
|
} |
412 |
|
|
} |
413 |
|
|
mAlpha = alpha; |
414 |
|
|
} |
415 |
|
|
} |
416 |
|
|
|
417 |
|
|
void CompoundSprite::updateImages() const |
418 |
|
|
{ |
419 |
|
|
#ifndef USE_SDL2 |
420 |
|
|
#ifdef USE_OPENGL |
421 |
|
|
if (imageHelper->useOpenGL() != RENDER_SOFTWARE) |
422 |
|
|
return; |
423 |
|
|
#endif // USE_OPENGL |
424 |
|
|
|
425 |
|
|
if (mEnableDelay) |
426 |
|
|
{ |
427 |
|
|
if (get_elapsed_time1(mNextRedrawTime) < 10) |
428 |
|
|
return; |
429 |
|
|
mNextRedrawTime = tick_time; |
430 |
|
|
} |
431 |
|
|
mNeedsRedraw = false; |
432 |
|
|
|
433 |
|
|
if (!mDisableBeingCaching) |
434 |
|
|
{ |
435 |
|
|
if (mSprites.size() <= 3U) |
436 |
|
|
return; |
437 |
|
|
|
438 |
|
|
if (!mDisableAdvBeingCaching) |
439 |
|
|
{ |
440 |
|
|
if (updateFromCache()) |
441 |
|
|
return; |
442 |
|
|
|
443 |
|
|
redraw(); |
444 |
|
|
|
445 |
|
|
if (mImage != nullptr) |
446 |
|
|
initCurrentCacheItem(); |
447 |
|
|
} |
448 |
|
|
else |
449 |
|
|
{ |
450 |
|
|
redraw(); |
451 |
|
|
} |
452 |
|
|
} |
453 |
|
|
#endif // USE_SDL2 |
454 |
|
|
} |
455 |
|
|
|
456 |
|
|
bool CompoundSprite::updateFromCache() const |
457 |
|
|
{ |
458 |
|
|
#ifndef USE_SDL2 |
459 |
|
|
// static int hits = 0; |
460 |
|
|
// static int miss = 0; |
461 |
|
|
|
462 |
|
|
if ((mCacheItem != nullptr) && (mCacheItem->image != nullptr)) |
463 |
|
|
{ |
464 |
|
|
imagesCache.push_front(mCacheItem); |
465 |
|
|
mCacheItem = nullptr; |
466 |
|
|
if (imagesCache.size() > cache_max_size) |
467 |
|
|
{ |
468 |
|
|
for (unsigned f = 0; f < cache_clean_part; f ++) |
469 |
|
|
{ |
470 |
|
|
CompoundItem *item = imagesCache.back(); |
471 |
|
|
imagesCache.pop_back(); |
472 |
|
|
delete item; |
473 |
|
|
} |
474 |
|
|
} |
475 |
|
|
} |
476 |
|
|
|
477 |
|
|
// logger->log("cache size: %d, hit %d, miss %d", |
478 |
|
|
// (int)imagesCache.size(), hits, miss); |
479 |
|
|
|
480 |
|
|
const size_t sz = mSprites.size(); |
481 |
|
|
FOR_EACH (ImagesCache::iterator, it, imagesCache) |
482 |
|
|
{ |
483 |
|
|
CompoundItem *const ic = *it; |
484 |
|
|
if ((ic != nullptr) && ic->data.size() == sz) |
485 |
|
|
{ |
486 |
|
|
bool fail(false); |
487 |
|
|
VectorPointers::const_iterator it2 = ic->data.begin(); |
488 |
|
|
const VectorPointers::const_iterator it2_end = ic->data.end(); |
489 |
|
|
|
490 |
|
|
for (SpriteConstIterator it1 = mSprites.begin(), |
491 |
|
|
it1_end = mSprites.end(); |
492 |
|
|
it1 != it1_end && it2 != it2_end; |
493 |
|
|
++ it1, ++ it2) |
494 |
|
|
{ |
495 |
|
|
const void *ptr1 = nullptr; |
496 |
|
|
const void *ptr2 = nullptr; |
497 |
|
|
if (*it1 != nullptr) |
498 |
|
|
ptr1 = (*it1)->getHash(); |
499 |
|
|
if (*it2 != nullptr) |
500 |
|
|
ptr2 = *it2; |
501 |
|
|
if (ptr1 != ptr2) |
502 |
|
|
{ |
503 |
|
|
fail = true; |
504 |
|
|
break; |
505 |
|
|
} |
506 |
|
|
} |
507 |
|
|
if (!fail) |
508 |
|
|
{ |
509 |
|
|
// hits ++; |
510 |
|
|
mImage = (*it)->image; |
511 |
|
|
mAlphaImage = (*it)->alphaImage; |
512 |
|
|
imagesCache.erase(it); |
513 |
|
|
mCacheItem = ic; |
514 |
|
|
return true; |
515 |
|
|
} |
516 |
|
|
} |
517 |
|
|
} |
518 |
|
|
mImage = nullptr; |
519 |
|
|
mAlphaImage = nullptr; |
520 |
|
|
// miss++; |
521 |
|
|
#endif // USE_SDL2 |
522 |
|
|
return false; |
523 |
|
|
} |
524 |
|
|
|
525 |
|
|
void CompoundSprite::initCurrentCacheItem() const |
526 |
|
|
{ |
527 |
|
|
delete mCacheItem; |
528 |
|
|
mCacheItem = new CompoundItem; |
529 |
|
|
mCacheItem->image = mImage; |
530 |
|
|
mCacheItem->alphaImage = mAlphaImage; |
531 |
|
|
// mCacheItem->alpha = mAlpha; |
532 |
|
|
|
533 |
|
|
FOR_EACH (SpriteConstIterator, it, mSprites) |
534 |
|
|
{ |
535 |
|
|
if (*it != nullptr) |
536 |
|
|
mCacheItem->data.push_back((*it)->getHash()); |
537 |
|
|
else |
538 |
|
|
mCacheItem->data.push_back(nullptr); |
539 |
|
|
} |
540 |
|
|
} |
541 |
|
|
|
542 |
|
|
bool CompoundSprite::updateNumber(const unsigned num) |
543 |
|
|
{ |
544 |
|
|
bool res(false); |
545 |
|
|
FOR_EACH (SpriteConstIterator, it, mSprites) |
546 |
|
|
{ |
547 |
|
|
if (*it != nullptr) |
548 |
|
|
{ |
549 |
|
|
if ((*it)->updateNumber(num)) |
550 |
|
|
res = true; |
551 |
|
|
} |
552 |
|
|
} |
553 |
|
|
return res; |
554 |
|
|
} |
555 |
|
|
|
556 |
|
|
CompoundItem::CompoundItem() : |
557 |
|
|
data(), |
558 |
|
|
image(nullptr), |
559 |
|
|
alphaImage(nullptr) |
560 |
|
|
{ |
561 |
|
|
} |
562 |
|
|
|
563 |
|
|
CompoundItem::~CompoundItem() |
564 |
|
|
{ |
565 |
|
|
delete image; |
566 |
|
|
delete alphaImage; |
567 |
|
|
} |