aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Kasak2009-07-04 23:05:13 +0000
committerDenis Kasak2009-07-04 23:05:13 +0000
commit960740fe83ee1d1e4cea33f732df4b698d22c479 (patch)
treedd26035f17d3c3e7c3baeb8628f1f29c33302237
parentfdf9eb84d6f9c59527a06a2571ee80b467dffdd3 (diff)
downloadscummvm-rg350-960740fe83ee1d1e4cea33f732df4b698d22c479.tar.gz
scummvm-rg350-960740fe83ee1d1e4cea33f732df4b698d22c479.tar.bz2
scummvm-rg350-960740fe83ee1d1e4cea33f732df4b698d22c479.zip
Rewrote Sprite::draw() to draw overflowing sprites correctly. Stopped playing animations as soon as they're loaded from Game::loadAnimation().
svn-id: r42111
-rw-r--r--engines/draci/game.cpp5
-rw-r--r--engines/draci/sprite.cpp61
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);
}
}