aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Kasak2009-07-22 07:18:00 +0000
committerDenis Kasak2009-07-22 07:18:00 +0000
commitef37d0a9b05607141558ba358a7dfd361aa26d9e (patch)
tree15aa0d212fbed7d171665fed367cf16179ecb772
parent5a77f089e1c6ea851851c55084a12023380656f1 (diff)
downloadscummvm-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.cpp44
-rw-r--r--engines/draci/animation.h2
-rw-r--r--engines/draci/game.cpp26
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);