diff options
author | Denis Kasak | 2009-07-22 07:18:00 +0000 |
---|---|---|
committer | Denis Kasak | 2009-07-22 07:18:00 +0000 |
commit | ef37d0a9b05607141558ba358a7dfd361aa26d9e (patch) | |
tree | 15aa0d212fbed7d171665fed367cf16179ecb772 | |
parent | 5a77f089e1c6ea851851c55084a12023380656f1 (diff) | |
download | scummvm-rg350-ef37d0a9b05607141558ba358a7dfd361aa26d9e.tar.gz scummvm-rg350-ef37d0a9b05607141558ba358a7dfd361aa26d9e.tar.bz2 scummvm-rg350-ef37d0a9b05607141558ba358a7dfd361aa26d9e.zip |
* Stopped AnimationManager::drawScene() from marking its own dirtiness.
* Instead, Animation::nextFrame() marks both the old and the new frame dirty. This makes it possible to only update the real screen when the animation changes and results in a pretty big speedup.
* Added utility method Animation::markDirtyRect() which takes a (Surface *) and marks a dirty rect on it for the current frame.
* Fixed artifacts when moving the dragon.
svn-id: r42652
-rw-r--r-- | engines/draci/animation.cpp | 44 | ||||
-rw-r--r-- | engines/draci/animation.h | 2 | ||||
-rw-r--r-- | engines/draci/game.cpp | 26 |
3 files changed, 43 insertions, 29 deletions
diff --git a/engines/draci/animation.cpp b/engines/draci/animation.cpp index 5b1814f4c4..9cf8f35a8d 100644 --- a/engines/draci/animation.cpp +++ b/engines/draci/animation.cpp @@ -50,11 +50,7 @@ bool Animation::isLooping() { void Animation::setRelative(int relx, int rely) { // Delete the previous frame - Common::Rect frameRect; - - frameRect = getFrame()->getRect(); - frameRect.translate(_relX, _relY); - _vm->_screen->getSurface()->markDirtyRect(frameRect); + markDirtyRect(_vm->_screen->getSurface()); _relX = relx; _relY = rely; @@ -66,6 +62,18 @@ void Animation::setLooping(bool looping) { looping, _id); } +void Animation::markDirtyRect(Surface *surface) { + // Fetch the current frame's rectangle + Drawable *frame = _frames[_currentFrame]; + Common::Rect frameRect = frame->getRect(); + + // Translate rectangle to compensate for relative coordinates + frameRect.translate(_relX, _relY); + + // Mark the rectangle dirty on the surface + surface->markDirtyRect(frameRect); +} + void Animation::nextFrame(bool force) { // If there's only one or no frames, or if the animation is not playing, return @@ -73,13 +81,8 @@ void Animation::nextFrame(bool force) { return; Drawable *frame = _frames[_currentFrame]; - - Common::Rect frameRect; - frameRect = frame->getRect(); + Surface *surface = _vm->_screen->getSurface(); - // Translate rectangle to compensate for relative coordinates - frameRect.translate(_relX, _relY); - if (force || (_tick + frame->getDelay() <= _vm->_system->getMillis())) { // If we are at the last frame and not looping, stop the animation // The animation is also restarted to frame zero @@ -87,9 +90,14 @@ void Animation::nextFrame(bool force) { _currentFrame = 0; setPlaying(false); } else { - _vm->_screen->getSurface()->markDirtyRect(frameRect); + // Mark old frame dirty so it gets deleted + markDirtyRect(surface); + _currentFrame = nextFrameNum(); _tick = _vm->_system->getMillis(); + + // Fetch new frame and mark it dirty + markDirtyRect(surface); } } @@ -131,7 +139,7 @@ void Animation::drawFrame(Surface *surface) { frame->setY(newY); // Draw frame - frame->drawScaled(surface, true); + frame->drawScaled(surface, false); // Revert back to old coordinates frame->setX(x); @@ -215,6 +223,9 @@ Animation *AnimationManager::addAnimation(int id, uint z, bool playing) { void AnimationManager::play(int id) { Animation *anim = getAnimation(id); + // Mark the first frame dirty so it gets displayed + anim->markDirtyRect(_vm->_screen->getSurface()); + if (anim) { anim->setPlaying(true); @@ -226,12 +237,7 @@ void AnimationManager::stop(int id) { Animation *anim = getAnimation(id); // Clean up the last frame that was drawn before stopping - Common::Rect frameRect; - - frameRect = anim->getFrame()->getRect(); - - frameRect.translate(anim->getRelativeX(), anim->getRelativeY()); - _vm->_screen->getSurface()->markDirtyRect(frameRect); + anim->markDirtyRect(_vm->_screen->getSurface()); if (anim) { anim->setPlaying(false); diff --git a/engines/draci/animation.h b/engines/draci/animation.h index fa28a61599..0e29934699 100644 --- a/engines/draci/animation.h +++ b/engines/draci/animation.h @@ -66,6 +66,8 @@ public: int getRelativeX(); int getRelativeY(); + void markDirtyRect(Surface *surface); + private: uint nextFrameNum(); diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp index c01e544986..360375f0b8 100644 --- a/engines/draci/game.cpp +++ b/engines/draci/game.cpp @@ -181,7 +181,22 @@ void Game::loop() { double scaleX = _currentRoom._pers0 + _currentRoom._persStep * y; double scaleY = scaleX; - Drawable *frame; + // Set the Z coordinate for the dragon's animation + anim->setZ(y+1); + + // Fetch current frame + Drawable *frame = anim->getFrame(); + + // Fetch base height of the frame + uint height = frame->getHeight(); + + // We naturally want the dragon to position its feet to the location of the + // click but sprites are drawn from their top-left corner so we subtract + // the current height of the dragon's sprite + // We also need to do this before we change the frames' scaled dimensions + // so setRelative() can correctly delete the old frame + y -= scaleY * height; + anim->setRelative(x, y); // Set the scaled dimensions for all frames for (uint i = 0; i < anim->getFramesNum(); ++i) { @@ -194,15 +209,6 @@ void Game::loop() { frame->setScaled(scaledWidth, scaledHeight); } - // Set the Z coordinate for the dragon's animation - anim->setZ(y+1); - - // We naturally want the dragon to position its feet to the location of the - // click but sprites are drawn from their top-left corner so we subtract - // the current height of the dragon's sprite - y -= frame->getScaledHeight(); - anim->setRelative(x, y); - // Play the animation _vm->_anims->play(animID); |