diff options
-rw-r--r-- | engines/draci/game.cpp | 5 | ||||
-rw-r--r-- | engines/draci/sprite.cpp | 61 |
2 files changed, 37 insertions, 29 deletions
diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp index be29cf9fda..b24d62d36d 100644 --- a/engines/draci/game.cpp +++ b/engines/draci/game.cpp @@ -138,6 +138,9 @@ void Game::init() { _vm->_script->run(getObject(0)->_program, getObject(0)->_init); + // HACK: this is only for testing + _vm->_anims->play(getObject(0)->_seqTab[9]); + changeRoom(0); } @@ -186,7 +189,7 @@ int Game::loadAnimation(uint animNum) { animationReader.readByte(); // Cyclic field, not used animationReader.readByte(); // Relative field, not used - _vm->_anims->addAnimation(animNum, 254, true); + _vm->_anims->addAnimation(animNum, 254, false); for (uint i = 0; i < numFrames; ++i) { uint spriteNum = animationReader.readUint16LE() - 1; diff --git a/engines/draci/sprite.cpp b/engines/draci/sprite.cpp index 39a33438ae..bd442e5ee8 100644 --- a/engines/draci/sprite.cpp +++ b/engines/draci/sprite.cpp @@ -115,50 +115,55 @@ void Sprite::setMirrorOff() { /** * @brief Draws the sprite to a Draci::Surface - * @param surface Pointer to a Draci::Surface + * @param surface Pointer to a Draci::Surface * * Draws the sprite to a Draci::Surface and marks its rectangle on the surface as dirty. + * It is safe to call it for sprites that would overflow the surface. */ void Sprite::draw(Surface *surface, bool markDirty) const { - byte *dst = (byte *)surface->getBasePtr(_x, _y); - byte *src = _data; - - // Determine how many pixels to draw horizontally (to prevent overflow) - int xSpaceLeft = surface->w - _x - 1; - int xPixelsToDraw = (_width < xSpaceLeft) ? _width : xSpaceLeft; - // Determine how many pixels to draw vertically - int ySpaceLeft = surface->h - _y - 1; - int yPixelsToDraw = (_height < ySpaceLeft) ? _height : ySpaceLeft; + Common::Rect sourceRect(0, 0, _width, _height); + Common::Rect destRect(_x, _y, _x + _width, _y + _height); + Common::Rect surfaceRect(0, 0, surface->w, surface->h); + Common::Rect clippedDestRect(destRect); - // Blit the sprite to the surface - for (int i = 0; i < yPixelsToDraw; ++i) { + clippedDestRect.clip(surfaceRect); - // Draw the sprite mirrored if the _mirror flag is set - if (_mirror) { - for (int j = xPixelsToDraw - 1; j >= 0; --j, ++src) { + int adjustLeft = clippedDestRect.left - destRect.left; + int adjustRight = clippedDestRect.right - destRect.right; + int adjustTop = clippedDestRect.top - destRect.top; + int adjustBottom = clippedDestRect.bottom - destRect.bottom; - // Don't blit if the pixel is transparent on the target surface - if (*src != surface->getTransparentColour()) - dst[j] = *src; - } - } else { - for (int j = 0; j < xPixelsToDraw; ++j, ++src) { + sourceRect.left += adjustLeft; + sourceRect.right += adjustRight; + sourceRect.top += adjustTop; + sourceRect.bottom += adjustBottom; + + byte *dst = (byte *)surface->getBasePtr(clippedDestRect.left, clippedDestRect.top); + byte *src = _data; - // Don't blit if the pixel is transparent on the target surface - if (*src != surface->getTransparentColour()) - dst[j] = *src; - } + // Blit the sprite to the surface + for (int i = sourceRect.top; i < sourceRect.bottom; ++i) { + for (int j = sourceRect.left; j < sourceRect.right; ++j) { + + // Don't blit if the pixel is transparent on the target surface + if (src[i * _width + j] != surface->getTransparentColour()) { + + // Draw the sprite mirrored if the _mirror flag is set + if (_mirror) { + dst[sourceRect.right - j - 1] = src[i * _width + j]; + } else { + dst[j] = src[i * _width + j]; + } + } } - src += _width - xPixelsToDraw; dst += surface->pitch; } // Mark the sprite's rectangle dirty if (markDirty) { - Common::Rect r(_x, _y, _x + _width, _y + _height); - surface->markDirtyRect(r); + surface->markDirtyRect(destRect); } } |