From ae4aea451d6e2c44b273c963026c4fd697568f79 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Mon, 9 May 2011 03:55:11 -0600 Subject: Fix sprite buffering size issues Reviewed-by: Yohann Ferreira --- src/animatedsprite.cpp | 10 +++ src/animatedsprite.h | 4 + src/being.cpp | 10 --- src/being.h | 10 --- src/compoundsprite.cpp | 176 +++++++++++++++++++++++++------------------- src/compoundsprite.h | 13 +++- src/resources/spritedef.cpp | 2 - src/sprite.h | 16 +++- 8 files changed, 140 insertions(+), 101 deletions(-) (limited to 'src') diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp index 9f4e46bd..fb612f19 100644 --- a/src/animatedsprite.cpp +++ b/src/animatedsprite.cpp @@ -222,6 +222,16 @@ int AnimatedSprite::getHeight() const return 0; } +int AnimatedSprite::getOffsetX() const +{ + return mFrame ? mFrame->offsetX : 0; +} + +int AnimatedSprite::getOffsetY() const +{ + return mFrame ? mFrame->offsetY : 0; +} + const Image* AnimatedSprite::getImage() const { return mFrame ? mFrame->image : 0; diff --git a/src/animatedsprite.h b/src/animatedsprite.h index bd39c267..1c5d6994 100644 --- a/src/animatedsprite.h +++ b/src/animatedsprite.h @@ -66,6 +66,10 @@ class AnimatedSprite : public Sprite int getHeight() const; + int getOffsetX() const; + + int getOffsetY() const; + const Image* getImage() const; bool setDirection(SpriteDirection direction); diff --git a/src/being.cpp b/src/being.cpp index 548895cc..40479236 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -943,16 +943,6 @@ void Being::drawSpeech(int offsetX, int offsetY) } } -int Being::getWidth() const -{ - return std::max(CompoundSprite::getWidth(), DEFAULT_BEING_WIDTH); -} - -int Being::getHeight() const -{ - return std::max(CompoundSprite::getHeight(), DEFAULT_BEING_HEIGHT); -} - void Being::updateCoords() { if (!mDispName) diff --git a/src/being.h b/src/being.h index d2a2701a..f380e0b8 100644 --- a/src/being.h +++ b/src/being.h @@ -380,16 +380,6 @@ class Being : public ActorSprite, public EventListener setPosition(Vector(x, y, z)); } - /** - * Returns the horizontal size of the current base sprite of the being. - */ - virtual int getWidth() const; - - /** - * Returns the vertical size of the current base sprite of the being. - */ - virtual int getHeight() const; - /** * Returns the being's pixel radius used to detect collisions. */ diff --git a/src/compoundsprite.cpp b/src/compoundsprite.cpp index e88a518a..2f39cae6 100644 --- a/src/compoundsprite.cpp +++ b/src/compoundsprite.cpp @@ -28,12 +28,13 @@ #include -#define BUFFER_WIDTH 100 -#define BUFFER_HEIGHT 100 - CompoundSprite::CompoundSprite(): mImage(NULL), mAlphaImage(NULL), + mWidth(0), + mHeight(0), + mOffsetX(0), + mOffsetY(0), mNeedsRedraw(false) { mAlpha = 1.0f; @@ -95,9 +96,15 @@ bool CompoundSprite::draw(Graphics* graphics, int posX, int posY) const if (mNeedsRedraw) redraw(); + if (empty()) // Nothing to draw + return false; + + posX += mOffsetX; + posY += mOffsetY; + if (mAlpha == 1.0f && mImage) { - return graphics->drawImage(mImage, posX + mOffsetX, posY + mOffsetY); + return graphics->drawImage(mImage, posX, posY); } else if (mAlpha && mAlphaImage) { @@ -105,18 +112,19 @@ bool CompoundSprite::draw(Graphics* graphics, int posX, int posY) const mAlphaImage->setAlpha(mAlpha); return graphics->drawImage(mAlphaImage, - posX + mOffsetX, posY + mOffsetY); + posX, posY); } else { SpriteConstIterator it, it_end; for (it = begin(), it_end = end(); it != it_end; it++) { - if (*it) + Sprite *s = *it; + if (s) { - if ((*it)->getAlpha() != mAlpha) - (*it)->setAlpha(mAlpha); - (*it)->draw(graphics, posX, posY); + if (s->getAlpha() != mAlpha) + s->setAlpha(mAlpha); + s->draw(graphics, posX - s->getWidth() / 2, posY - s->getHeight()); } } } @@ -124,36 +132,6 @@ bool CompoundSprite::draw(Graphics* graphics, int posX, int posY) const return false; } -int CompoundSprite::getWidth() const -{ - Sprite *base = NULL; - - SpriteConstIterator it, it_end; - for (it = begin(), it_end = end(); it != it_end; it++) - if ((base = (*it))) - break; - - if (base) - return base->getWidth(); - - return 0; -} - -int CompoundSprite::getHeight() const -{ - Sprite *base = NULL; - - SpriteConstIterator it, it_end; - for (it = begin(), it_end = end(); it != it_end; it++) - if ((base = (*it))) - break; - - if (base) - return base->getHeight(); - - return 0; -} - const Image* CompoundSprite::getImage() const { return mImage; @@ -175,13 +153,9 @@ bool CompoundSprite::setDirection(SpriteDirection direction) int CompoundSprite::getNumberOfLayers() const { if (mImage || mAlphaImage) - { return 1; - } else - { return size(); - } } size_t CompoundSprite::getCurrentFrame() const @@ -250,7 +224,6 @@ void CompoundSprite::ensureSize(size_t layerCount) return; resize(layerCount, NULL); - mNeedsRedraw = true; } /** @@ -283,20 +256,93 @@ size_t CompoundSprite::getFrameCount(size_t layer) return 0; } -void CompoundSprite::redraw() const +static void updateValues(int &dimension, int &pos, int imgDim, int imgOffset) { - // TODO Detect image size needed to avoid cutting off large sprites, and - // reduce memory for smaller ones - mNeedsRedraw = false; - return; + // Handle going beyond the left/up + if (imgOffset < 0) + { + int temp = -(pos + imgOffset); // Negated for easier use + + if (temp > 0) + { + pos += temp; + dimension += temp; + } + } + + // Handle going beyond the right/down + int temp = pos + imgOffset + imgDim; + if (temp > dimension) + dimension = temp; +} +void CompoundSprite::redraw() const +{ // TODO OpenGL support if (Image::getLoadAsOpenGL()) { + // Temporary fix for position + Map *map = Game::instance() ? Game::instance()->getCurrentMap() : 0; + if (map) + { + mOffsetX = map->getTileWidth() / 2; + mOffsetY = map->getTileHeight(); + } + else // Char selection screen fix + { + mOffsetX = 16; + mOffsetY = 32; + } mNeedsRedraw = false; return; } + Sprite *s = NULL; + SpriteConstIterator it = begin(), it_end = end(); + for (it = begin(), it_end = end(); it != it_end; it++) + if ((s = *it)) + break; + + if (!s) + { + mWidth = mHeight = mOffsetX = mOffsetY = 0; + mNeedsRedraw = false; + return; + } + + mWidth = s->getWidth(); + mHeight = s->getHeight(); + mOffsetX = s->getOffsetX(); + mOffsetY = s->getOffsetY(); + int posX = mWidth / 2; + int posY = mHeight; + + for (it++; it != it_end; ++it) + { + s = *it; + + if (s) + { + updateValues(mWidth, posX, s->getWidth(), s->getOffsetX() - s->getWidth() / 2); + updateValues(mHeight, posY, s->getHeight(), s->getOffsetY()); + } + } + + mOffsetX -= posX; + mOffsetY -= posY; + + Map *map = Game::instance() ? Game::instance()->getCurrentMap() : 0; + if (map) + { + mOffsetX += map->getTileWidth() / 2; + mOffsetY += map->getTileHeight(); + } + else // Char selection screen fix + { + mOffsetX += 16; + mOffsetY += 32; + } + #if SDL_BYTEORDER == SDL_BIG_ENDIAN int rmask = 0xff000000; int gmask = 0x00ff0000; @@ -309,8 +355,7 @@ void CompoundSprite::redraw() const int amask = 0xff000000; #endif - SDL_Surface *surface = SDL_CreateRGBSurface(SDL_HWSURFACE, - BUFFER_WIDTH, BUFFER_HEIGHT, + SDL_Surface *surface = SDL_CreateRGBSurface(SDL_HWSURFACE, mWidth, mHeight, 32, rmask, gmask, bmask, amask); if (!surface) @@ -321,36 +366,17 @@ void CompoundSprite::redraw() const graphics->setTarget(surface); graphics->_beginDraw(); - int tileX = 32 / 2; - int tileY = 32; - - Game *game = Game::instance(); - if (game) + for (it = begin(), it_end = end(); it != it_end; ++it) { - 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; + s = *it; - SpriteConstIterator it, it_end; - for (it = begin(), it_end = end(); it != it_end; it++) - { - if (*it) - { - (*it)->draw(graphics, posX, posY); - } + if (s) + s->draw(graphics, posX - s->getWidth() / 2, posY - s->getHeight()); } delete graphics; - SDL_Surface *surfaceA = SDL_CreateRGBSurface(SDL_HWSURFACE, - BUFFER_WIDTH, BUFFER_HEIGHT, + SDL_Surface *surfaceA = SDL_CreateRGBSurface(SDL_HWSURFACE, mWidth, mHeight, 32, rmask, gmask, bmask, amask); SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE); diff --git a/src/compoundsprite.h b/src/compoundsprite.h index 3b443219..5754c4e1 100644 --- a/src/compoundsprite.h +++ b/src/compoundsprite.h @@ -45,12 +45,20 @@ public: /** * Gets the width in pixels of the first sprite in the list. */ - virtual int getWidth() const; + virtual int getWidth() const + { return mWidth; } /** * Gets the height in pixels of the first sprite in the list. */ - virtual int getHeight() const; + virtual int getHeight() const + { return mHeight; } + + int getOffsetX() const + { return mOffsetX; } + + int getOffsetY() const + { return mOffsetY; } virtual const Image* getImage() const; @@ -97,6 +105,7 @@ private: mutable Image *mImage; mutable Image *mAlphaImage; + mutable int mWidth, mHeight; mutable int mOffsetX, mOffsetY; mutable bool mNeedsRedraw; diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp index 51e7ae8e..22312107 100644 --- a/src/resources/spritedef.cpp +++ b/src/resources/spritedef.cpp @@ -227,8 +227,6 @@ void SpriteDef::loadAnimation(xmlNodePtr animationNode, const int delay = XML::getProperty(frameNode, "delay", 0); int offsetX = XML::getProperty(frameNode, "offsetX", 0); int offsetY = XML::getProperty(frameNode, "offsetY", 0); - offsetY -= imageSet->getHeight() - 32; - offsetX -= imageSet->getWidth() / 2 - 16; if (xmlStrEqual(frameNode->name, BAD_CAST "frame")) { diff --git a/src/sprite.h b/src/sprite.h index 38db8b41..797b1b20 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -60,15 +60,27 @@ class Sprite virtual bool draw(Graphics* graphics, int posX, int posY) const = 0; /** - * Gets the width in pixels of the image of the current frame + * Gets the width in pixels of the image */ virtual int getWidth() const = 0; /** - * Gets the height in pixels of the image of the current frame + * Gets the height in pixels of the image */ virtual int getHeight() const = 0; + /** + * Gets the horizontal offset that the sprite will be drawn at + */ + virtual int getOffsetX() const + { return 0; } + + /** + * Gets the vertical offset that the sprite will be drawn at + */ + virtual int getOffsetY() const + { return 0; } + /** * Returns a reference to the current image being drawn. */ -- cgit v1.2.3-60-g2f50