summaryrefslogtreecommitdiff
path: root/src/compoundsprite.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/compoundsprite.cpp')
-rw-r--r--src/compoundsprite.cpp221
1 files changed, 202 insertions, 19 deletions
diff --git a/src/compoundsprite.cpp b/src/compoundsprite.cpp
index a9a521ef..53fdd7c2 100644
--- a/src/compoundsprite.cpp
+++ b/src/compoundsprite.cpp
@@ -20,9 +20,24 @@
#include "compoundsprite.h"
+#include "game.h"
+#include "graphics.h"
+#include "openglgraphics.h"
+#include "map.h"
+
+#include "resources/image.h"
+
#include "utils/dtor.h"
-CompoundSprite::CompoundSprite()
+#include <SDL.h>
+
+#define BUFFER_WIDTH 100
+#define BUFFER_HEIGHT 100
+
+CompoundSprite::CompoundSprite():
+ mImage(NULL),
+ mAlphaImage(NULL),
+ mNeedsRedraw(false)
{
mAlpha = 1.0f;
}
@@ -36,44 +51,73 @@ CompoundSprite::~CompoundSprite()
clear();
}
-void CompoundSprite::reset()
+bool CompoundSprite::reset()
{
+ bool ret = false;
+
SpriteIterator it, it_end;
for (it = begin(), it_end = end(); it != it_end; it++)
if (*it)
- (*it)->reset();
+ ret |= (*it)->reset();
+
+ mNeedsRedraw |= ret;
+ return ret;
}
-void CompoundSprite::play(SpriteAction action)
+bool CompoundSprite::play(SpriteAction action)
{
+ bool ret = false;
+
SpriteIterator it, it_end;
for (it = begin(), it_end = end(); it != it_end; it++)
if (*it)
- (*it)->play(action);
+ ret |= (*it)->play(action);
+
+ mNeedsRedraw |= ret;
+ return ret;
}
-void CompoundSprite::update(int time)
+bool CompoundSprite::update(int time)
{
+ bool ret = false;
+
SpriteIterator it, it_end;
for (it = begin(), it_end = end(); it != it_end; it++)
if (*it)
- (*it)->update(time);
+ ret |= (*it)->update(time);
+
+ mNeedsRedraw |= ret;
+ return ret;
}
bool CompoundSprite::draw(Graphics* graphics, int posX, int posY) const
{
- SpriteConstIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; it++)
+ if (mNeedsRedraw)
+ redraw();
+
+ if (mAlpha == 1.0f && mImage)
+ return graphics->drawImage(mImage, posX + mOffsetX, posY + mOffsetY);
+ else if (mAlpha && mAlphaImage)
{
- if (*it)
+ if (mAlphaImage->getAlpha() != mAlpha)
+ mAlphaImage->setAlpha(mAlpha);
+
+ return graphics->drawImage(mAlphaImage,
+ posX + mOffsetX, posY + mOffsetY);
+ }
+ else
+ {
+ SpriteConstIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
{
- if ((*it)->getAlpha() != mAlpha)
- (*it)->setAlpha(mAlpha);
- (*it)->draw(graphics, posX, posY);
+ if (*it)
+ {
+ (*it)->draw(graphics, posX, posY);
+ }
}
}
- return true;
+ return false;
}
int CompoundSprite::getWidth() const
@@ -106,16 +150,155 @@ int CompoundSprite::getHeight() const
return 0;
}
-Image* CompoundSprite::getImage() const
+const Image* CompoundSprite::getImage() const
{
- // TODO http://bugs.manasource.org/view.php?id=24
- return NULL;
+ return mImage;
}
-void CompoundSprite::setDirection(SpriteDirection direction)
+bool CompoundSprite::setDirection(SpriteDirection direction)
{
+ bool ret = false;
+
SpriteIterator it, it_end;
for (it = begin(), it_end = end(); it != it_end; it++)
if (*it)
- (*it)->setDirection(direction);
+ ret |= (*it)->setDirection(direction);
+
+ mNeedsRedraw |= ret;
+ return ret;
+}
+
+int CompoundSprite::getNumberOfLayers() const
+{
+ if (mImage || mAlphaImage)
+ {
+ return 1;
+ }
+ else
+ {
+ return size();
+ }
+}
+
+void CompoundSprite::addSprite(Sprite* sprite)
+{
+ push_back(sprite);
+ mNeedsRedraw = true;
+}
+
+void CompoundSprite::setSprite(int layer, Sprite* sprite)
+{
+ // Skip if it won't change anything
+ if (at(layer) == sprite)
+ return;
+
+ if (at(layer))
+ delete at(layer);
+ at(layer) = sprite;
+ mNeedsRedraw = true;
+}
+
+void CompoundSprite::removeSprite(int layer)
+{
+ // Skip if it won't change anything
+ if (at(layer) == NULL)
+ return;
+
+ delete at(layer);
+ at(layer) = NULL;
+ mNeedsRedraw = true;
+}
+
+void CompoundSprite::clear()
+{
+ // Skip if it won't change anything
+ if (empty())
+ return;
+
+ std::vector<Sprite*>::clear();
+ mNeedsRedraw = true;
+}
+
+void CompoundSprite::ensureSize(size_t layerCount)
+{
+ // Skip if it won't change anything
+ if (size() >= layerCount)
+ return;
+
+ resize(layerCount, NULL);
+ mNeedsRedraw = true;
+}
+
+void CompoundSprite::redraw() const
+{
+ // TODO OpenGL support
+ if (Image::getLoadAsOpenGL())
+ {
+ mNeedsRedraw = false;
+ return;
+ }
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ int rmask = 0xff000000;
+ int gmask = 0x00ff0000;
+ int bmask = 0x0000ff00;
+ int amask = 0x000000ff;
+#else
+ int rmask = 0x000000ff;
+ int gmask = 0x0000ff00;
+ int bmask = 0x00ff0000;
+ int amask = 0xff000000;
+#endif
+
+ SDL_Surface *surface = SDL_CreateRGBSurface(SDL_HWSURFACE,
+ BUFFER_WIDTH, BUFFER_HEIGHT,
+ 32, rmask, gmask, bmask, amask);
+
+ if (!surface)
+ return;
+
+ Graphics *graphics = new Graphics();
+ graphics->setBlitMode(Graphics::BLIT_GFX);
+ graphics->setTarget(surface);
+ graphics->_beginDraw();
+
+ int tileX = 32 / 2;
+ int tileY = 32;
+
+ Game *game = Game::instance();
+ if (game)
+ {
+ Map *map = game->getCurrentMap();
+ tileX = map->getTileWidth() / 2;
+ tileY = map->getTileWidth();
+ }
+
+ int posX = BUFFER_WIDTH / 2 - tileX;
+ int posY = BUFFER_HEIGHT - tileY;
+
+ mOffsetX = tileX - BUFFER_WIDTH / 2;
+ mOffsetY = tileY - BUFFER_HEIGHT;
+
+ SpriteConstIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ {
+ if (*it)
+ {
+ (*it)->draw(graphics, posX, posY);
+ }
+ }
+
+ delete graphics;
+
+ SDL_Surface *surfaceA = SDL_CreateRGBSurface(SDL_HWSURFACE,
+ BUFFER_WIDTH, BUFFER_HEIGHT,
+ 32, rmask, gmask, bmask, amask);
+
+ SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE);
+ SDL_BlitSurface(surface, NULL, surfaceA, NULL);
+
+ mImage = Image::load(surface);
+ mAlphaImage = Image::load(surfaceA);
+
+ mNeedsRedraw = false;
}