aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichieSams2013-09-08 15:47:06 -0500
committerRichieSams2013-09-09 11:16:44 -0500
commitedd1a117ae821d96498a78a357ab29018f1c019a (patch)
tree2b72f995c29b654f62134fcdb5f59dd56899797e
parent9e563f01134ec9063d743ef487eb25cae581e2d2 (diff)
downloadscummvm-rg350-edd1a117ae821d96498a78a357ab29018f1c019a.tar.gz
scummvm-rg350-edd1a117ae821d96498a78a357ab29018f1c019a.tar.bz2
scummvm-rg350-edd1a117ae821d96498a78a357ab29018f1c019a.zip
ZVISION: Cache animation frames so they can be re-rendered when the background moves
-rw-r--r--engines/zvision/animation_control.cpp128
-rw-r--r--engines/zvision/animation_control.h2
2 files changed, 96 insertions, 34 deletions
diff --git a/engines/zvision/animation_control.cpp b/engines/zvision/animation_control.cpp
index ca3e225a8a..8c8f6eb238 100644
--- a/engines/zvision/animation_control.cpp
+++ b/engines/zvision/animation_control.cpp
@@ -39,7 +39,8 @@ AnimationControl::AnimationControl(ZVision *engine, uint32 controlKey, const Com
_fileType(RLF),
_loopCount(1),
_currentLoop(0),
- _accumulatedTime(0) {
+ _accumulatedTime(0),
+ _cachedFrame(0) {
if (fileName.hasSuffix(".rlf")) {
_fileType = RLF;
_animation.rlf = new RlfAnimation(fileName, false);
@@ -50,6 +51,8 @@ AnimationControl::AnimationControl(ZVision *engine, uint32 controlKey, const Com
} else {
warning("Unrecognized animation file type: %s", fileName.c_str());
}
+
+ _cachedFrame = new Graphics::Surface();
}
AnimationControl::~AnimationControl() {
@@ -58,6 +61,9 @@ AnimationControl::~AnimationControl() {
} else if (_fileType == AVI) {
delete _animation.avi;
}
+
+ _cachedFrame->free();
+ delete _cachedFrame;
}
bool AnimationControl::process(uint32 deltaTimeInMillis) {
@@ -71,47 +77,75 @@ bool AnimationControl::process(uint32 deltaTimeInMillis) {
_accumulatedTime += deltaTimeInMillis;
uint32 frameTime = _animation.rlf->frameTime();
- while (_accumulatedTime >= frameTime) {
- _accumulatedTime -= frameTime;
+ if (_accumulatedTime >= frameTime) {
+ while (_accumulatedTime >= frameTime) {
+ _accumulatedTime -= frameTime;
- // Make sure the frame is inside the working window
- // If it's not, then just return
+ // Make sure the frame is inside the working window
+ // If it's not, then just return
- RenderManager *renderManager = _engine->getRenderManager();
- Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y));
- Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _animation.rlf->width(), workingWindowPoint.y + _animation.rlf->height());
+ RenderManager *renderManager = _engine->getRenderManager();
+ Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y));
+ Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _animation.rlf->width(), workingWindowPoint.y + _animation.rlf->height());
- // If the clip returns false, it means the animation is outside the working window
- if (!renderManager->clipRectToWorkingWindow(subRect)) {
- return false;
- }
+ // If the clip returns false, it means the animation is outside the working window
+ if (!renderManager->clipRectToWorkingWindow(subRect)) {
+ return false;
+ }
- const Graphics::Surface *frame = _animation.rlf->getNextFrame();
+ const Graphics::Surface *frame = _animation.rlf->getNextFrame();
- // Animation frames for PANORAMAs are transposed, so un-transpose them
- RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState();
- if (state == RenderTable::PANORAMA) {
- Graphics::Surface *tranposedFrame = RenderManager::tranposeSurface(frame);
+ // Animation frames for PANORAMAs are transposed, so un-transpose them
+ RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState();
+ if (state == RenderTable::PANORAMA) {
+ Graphics::Surface *tranposedFrame = RenderManager::tranposeSurface(frame);
- renderManager->copyRectToWorkingWindow((uint16 *)tranposedFrame->getBasePtr(tranposedFrame->w - subRect.width(), tranposedFrame->h - subRect.height()), subRect.left, subRect.top, _animation.rlf->width(), subRect.width(), subRect.height());
+ renderManager->copyRectToWorkingWindow((uint16 *)tranposedFrame->getBasePtr(tranposedFrame->w - subRect.width(), tranposedFrame->h - subRect.height()), subRect.left, subRect.top, _animation.rlf->width(), subRect.width(), subRect.height());
- // Cleanup
- tranposedFrame->free();
- delete tranposedFrame;
- } else {
- renderManager->copyRectToWorkingWindow((uint16 *)frame->getBasePtr(frame->w - subRect.width(), frame->h - subRect.height()), subRect.left, subRect.top, _animation.rlf->width(), subRect.width(), subRect.height());
- }
+ // If the background can move, we need to cache the last frame so it can be rendered during background movement
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ _cachedFrame = tranposedFrame;
+ } else {
+ // Cleanup
+ tranposedFrame->free();
+ delete tranposedFrame;
+ }
+ } else {
+ renderManager->copyRectToWorkingWindow((uint16 *)frame->getBasePtr(frame->w - subRect.width(), frame->h - subRect.height()), subRect.left, subRect.top, _animation.rlf->width(), subRect.width(), subRect.height());
+
+ // If the background can move, we need to cache the last frame so it can be rendered during background movement
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ _cachedFrame->copyFrom(*frame);
+ }
+ }
- // Check if we should continue looping
- if (_animation.rlf->endOfAnimation()) {
- _animation.rlf->seekToFrame(-1);
- if (_loopCount > 0) {
- _currentLoop++;
- if (_currentLoop >= _loopCount) {
- finished = true;
+ // Check if we should continue looping
+ if (_animation.rlf->endOfAnimation()) {
+ _animation.rlf->seekToFrame(-1);
+ if (_loopCount > 0) {
+ _currentLoop++;
+ if (_currentLoop >= _loopCount) {
+ finished = true;
+ }
}
}
}
+ } else {
+ // If the background can move, we have to keep rendering animation frames, otherwise the animation flickers during background movement
+ RenderManager *renderManager = _engine->getRenderManager();
+ RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState();
+
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y));
+ Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _cachedFrame->w, workingWindowPoint.y + _cachedFrame->h);
+
+ // If the clip returns false, it means the animation is outside the working window
+ if (!renderManager->clipRectToWorkingWindow(subRect)) {
+ return false;
+ }
+
+ renderManager->copyRectToWorkingWindow((uint16 *)_cachedFrame->getBasePtr(_cachedFrame->w - subRect.width(), _cachedFrame->h - subRect.height()), subRect.left, subRect.top, _cachedFrame->w, subRect.width(), subRect.height());
+ }
}
} else if (_fileType == AVI) {
if (!_animation.avi->isPlaying()) {
@@ -141,11 +175,37 @@ bool AnimationControl::process(uint32 deltaTimeInMillis) {
renderManager->copyRectToWorkingWindow((uint16 *)tranposedFrame->getBasePtr(tranposedFrame->w - subRect.width(), tranposedFrame->h - subRect.height()), subRect.left, subRect.top, frame->w, subRect.width(), subRect.height());
- // Cleanup
- tranposedFrame->free();
- delete tranposedFrame;
+ // If the background can move, we need to cache the last frame so it can be rendered during background movement
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ _cachedFrame = tranposedFrame;
+ } else {
+ // Cleanup
+ tranposedFrame->free();
+ delete tranposedFrame;
+ }
} else {
renderManager->copyRectToWorkingWindow((uint16 *)frame->getBasePtr(frame->w - subRect.width(), frame->h - subRect.height()), subRect.left, subRect.top, frame->w, subRect.width(), subRect.height());
+
+ // If the background can move, we need to cache the last frame so it can be rendered during background movement
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ _cachedFrame->copyFrom(*frame);
+ }
+ }
+ } else {
+ // If the background can move, we have to keep rendering animation frames, otherwise the animation flickers during background movement
+ RenderManager *renderManager = _engine->getRenderManager();
+ RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState();
+
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y));
+ Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _cachedFrame->w, workingWindowPoint.y + _cachedFrame->h);
+
+ // If the clip returns false, it means the animation is outside the working window
+ if (!renderManager->clipRectToWorkingWindow(subRect)) {
+ return false;
+ }
+
+ renderManager->copyRectToWorkingWindow((uint16 *)_cachedFrame->getBasePtr(_cachedFrame->w - subRect.width(), _cachedFrame->h - subRect.height()), subRect.left, subRect.top, _cachedFrame->w, subRect.width(), subRect.height());
}
}
}
diff --git a/engines/zvision/animation_control.h b/engines/zvision/animation_control.h
index 036ce4b66b..6b104d4c06 100644
--- a/engines/zvision/animation_control.h
+++ b/engines/zvision/animation_control.h
@@ -64,6 +64,8 @@ private:
uint _accumulatedTime;
uint _currentLoop;
+ Graphics::Surface *_cachedFrame;
+
public:
bool process(uint32 deltaTimeInMillis);