aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2014-12-16 00:48:16 +0200
committerFilippos Karapetis2014-12-16 01:58:55 +0200
commit7f61a094781256f7c2734aa08637494c1dfac6bf (patch)
tree2dd89d28d338daeb8bdf06e41bcc9e5768cf9885
parent67bd78a95f6efab6d0da4b3bef1b0cebc79c537c (diff)
downloadscummvm-rg350-7f61a094781256f7c2734aa08637494c1dfac6bf.tar.gz
scummvm-rg350-7f61a094781256f7c2734aa08637494c1dfac6bf.tar.bz2
scummvm-rg350-7f61a094781256f7c2734aa08637494c1dfac6bf.zip
ZVISION: Make the RLF decoder a subclass of the common video decoder
This way, the redundant MetaAnimation class can now be removed
-rw-r--r--engines/zvision/animation/meta_animation.cpp132
-rw-r--r--engines/zvision/animation/meta_animation.h98
-rw-r--r--engines/zvision/module.mk1
-rw-r--r--engines/zvision/scripting/controls/fist_control.cpp14
-rw-r--r--engines/zvision/scripting/controls/fist_control.h8
-rw-r--r--engines/zvision/scripting/controls/hotmov_control.cpp10
-rw-r--r--engines/zvision/scripting/controls/hotmov_control.h8
-rw-r--r--engines/zvision/scripting/controls/input_control.cpp14
-rw-r--r--engines/zvision/scripting/controls/input_control.h7
-rw-r--r--engines/zvision/scripting/controls/lever_control.cpp8
-rw-r--r--engines/zvision/scripting/controls/lever_control.h9
-rw-r--r--engines/zvision/scripting/controls/safe_control.cpp10
-rw-r--r--engines/zvision/scripting/controls/safe_control.h9
-rw-r--r--engines/zvision/scripting/sidefx/animation_node.cpp10
-rw-r--r--engines/zvision/scripting/sidefx/animation_node.h11
-rw-r--r--engines/zvision/video/rlf_decoder.cpp141
-rw-r--r--engines/zvision/video/rlf_decoder.h224
-rw-r--r--engines/zvision/video/video.cpp20
-rw-r--r--engines/zvision/zvision.h1
19 files changed, 222 insertions, 513 deletions
diff --git a/engines/zvision/animation/meta_animation.cpp b/engines/zvision/animation/meta_animation.cpp
deleted file mode 100644
index 85b2e0f6b7..0000000000
--- a/engines/zvision/animation/meta_animation.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-
-#include "zvision/animation/meta_animation.h"
-
-#include "zvision/zvision.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/scripting/script_manager.h"
-#include "zvision/video/rlf_decoder.h"
-#include "zvision/video/zork_avi_decoder.h"
-
-#include "video/video_decoder.h"
-
-#include "graphics/surface.h"
-
-namespace ZVision {
-
-MetaAnimation::MetaAnimation(const Common::String &fileName, ZVision *engine)
- : _fileType(RLF),
- _curFrame(NULL) {
- Common::String tmpFileName = fileName;
- tmpFileName.toLowercase();
- if (tmpFileName.hasSuffix(".rlf")) {
- _fileType = RLF;
- Common::File *_file = engine->getSearchManager()->openFile(tmpFileName);
- _animation.rlf = new RLFDecoder(_file, false);
- _frmDelay = _animation.rlf->frameTime();
- } else if (tmpFileName.hasSuffix(".avi")) {
- _fileType = AVI;
- Common::File *_file = engine->getSearchManager()->openFile(tmpFileName);
- _animation.avi = new ZorkAVIDecoder();
- _animation.avi->loadStream(_file);
- _frmDelay = 1000.0 / _animation.avi->getDuration().framerate();
- } else {
- warning("Unrecognized animation file type: %s", fileName.c_str());
- }
-}
-
-MetaAnimation::~MetaAnimation() {
- if (_fileType == RLF) {
- delete _animation.rlf;
- } else if (_fileType == AVI) {
- delete _animation.avi;
- }
-}
-
-uint MetaAnimation::frameCount() {
- if (_fileType == RLF) {
- return _animation.rlf->frameCount();
- } else
- return _animation.avi->getFrameCount();
-
-}
-
-uint MetaAnimation::width() {
- if (_fileType == RLF) {
- return _animation.rlf->width();
- } else
- return _animation.avi->getWidth();
-}
-uint MetaAnimation::height() {
- if (_fileType == RLF) {
- return _animation.rlf->height();
- } else
- return _animation.avi->getHeight();
-}
-uint32 MetaAnimation::frameTime() {
- return _frmDelay;
-}
-
-void MetaAnimation::seekToFrame(int frameNumber) {
- if (frameNumber >= (int)frameCount())
- frameNumber = frameCount() - 1;
-
- if (_fileType == RLF) {
- _animation.rlf->seekToFrame(frameNumber);
- } else
- _animation.avi->seekToFrame(frameNumber);
-}
-
-const Graphics::Surface *MetaAnimation::decodeNextFrame() {
- if (_fileType == RLF)
- _curFrame = _animation.rlf->decodeNextFrame();
- else
- _curFrame = _animation.avi->decodeNextFrame();
-
- return _curFrame;
-}
-
-const Graphics::Surface *MetaAnimation::getFrameData(uint frameNumber) {
- if (frameNumber >= frameCount())
- frameNumber = frameCount() - 1;
-
- if (_fileType == RLF) {
- _curFrame = _animation.rlf->getFrameData(frameNumber);
- return _curFrame;
- } else {
- _animation.avi->seekToFrame(frameNumber);
- _curFrame = _animation.avi->decodeNextFrame();
- return _curFrame;
- }
-}
-
-bool MetaAnimation::endOfAnimation() {
- if (_fileType == RLF) {
- return _animation.rlf->endOfAnimation();
- } else
- return _animation.avi->endOfVideo();
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/animation/meta_animation.h b/engines/zvision/animation/meta_animation.h
deleted file mode 100644
index 6d2025b2cf..0000000000
--- a/engines/zvision/animation/meta_animation.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ZVISION_METAANIM_NODE_H
-#define ZVISION_METAANIM_NODE_H
-
-#include "zvision/scripting/sidefx.h"
-#include "zvision/zvision.h"
-#include "common/rect.h"
-#include "common/list.h"
-
-namespace Common {
-class String;
-}
-
-namespace Video {
-class VideoDecoder;
-}
-
-namespace Graphics {
-struct Surface;
-}
-
-namespace ZVision {
-
-class ZVision;
-class RLFDecoder;
-
-class MetaAnimation {
-public:
- MetaAnimation(const Common::String &fileName, ZVision *engine);
- ~MetaAnimation();
-
- struct playnode {
- Common::Rect pos;
- int32 slot;
- int32 start;
- int32 stop;
- int32 loop;
- int32 _curFrame;
- int32 _delay;
- Graphics::Surface *_scaled;
- };
-
-private:
- enum FileType {
- RLF = 1,
- AVI = 2
- };
-
-private:
- union {
- RLFDecoder *rlf;
- Video::VideoDecoder *avi;
- } _animation;
-
- FileType _fileType;
- int32 _frmDelay;
-
- const Graphics::Surface *_curFrame;
-
-public:
-
- uint frameCount();
- uint width();
- uint height();
- uint32 frameTime();
-
- void seekToFrame(int frameNumber);
-
- const Graphics::Surface *decodeNextFrame();
- const Graphics::Surface *getFrameData(uint frameNumber);
-
- bool endOfAnimation();
-};
-
-} // End of namespace ZVision
-
-#endif
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
index 5c2fd2045b..6ed3eee718 100644
--- a/engines/zvision/module.mk
+++ b/engines/zvision/module.mk
@@ -1,7 +1,6 @@
MODULE := engines/zvision
MODULE_OBJS := \
- animation/meta_animation.o \
core/console.o \
core/events.o \
core/menu.o \
diff --git a/engines/zvision/scripting/controls/fist_control.cpp b/engines/zvision/scripting/controls/fist_control.cpp
index dd6a7f11a9..c3a69084f2 100644
--- a/engines/zvision/scripting/controls/fist_control.cpp
+++ b/engines/zvision/scripting/controls/fist_control.cpp
@@ -22,20 +22,19 @@
#include "common/scummsys.h"
-#include "zvision/scripting/controls/fist_control.h"
-
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
+#include "zvision/scripting/controls/fist_control.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/cursors/cursor_manager.h"
-#include "zvision/animation/meta_animation.h"
#include "zvision/utility/utility.h"
+#include "zvision/video/rlf_decoder.h"
#include "common/stream.h"
#include "common/file.h"
#include "common/system.h"
-
#include "graphics/surface.h"
+#include "video/video_decoder.h"
namespace ZVision {
@@ -106,7 +105,8 @@ void FistControl::renderFrame(uint frameNumber) {
const Graphics::Surface *frameData;
if (_animation) {
- frameData = _animation->getFrameData(frameNumber);
+ _animation->seekToFrame(frameNumber);
+ frameData = _animation->decodeNextFrame();
if (frameData)
_engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _anmRect);
}
@@ -121,7 +121,7 @@ bool FistControl::process(uint32 deltaTimeInMillis) {
_frameTime -= deltaTimeInMillis;
if (_frameTime <= 0) {
- _frameTime = _animation->frameTime();
+ _frameTime = 1000.0 / _animation->getDuration().framerate();
renderFrame(_frameCur);
@@ -194,7 +194,7 @@ void FistControl::readDescFile(const Common::String &fileName) {
if (param.matchString("animation_id", true)) {
// Not used
} else if (param.matchString("animation", true)) {
- _animation = new MetaAnimation(values, _engine);
+ _animation = _engine->loadAnimation(values);
} else if (param.matchString("anim_rect", true)) {
int left, top, right, bottom;
sscanf(values.c_str(), "%d %d %d %d", &left, &top, &right, &bottom);
diff --git a/engines/zvision/scripting/controls/fist_control.h b/engines/zvision/scripting/controls/fist_control.h
index cb765c429a..0a6b977ead 100644
--- a/engines/zvision/scripting/controls/fist_control.h
+++ b/engines/zvision/scripting/controls/fist_control.h
@@ -28,9 +28,11 @@
#include "common/array.h"
#include "common/rect.h"
-namespace ZVision {
+namespace Video {
+ class VideoDecoder;
+}
-class MetaAnimation;
+namespace ZVision {
class FistControl : public Control {
public:
@@ -58,7 +60,7 @@ private:
Common::Array<entries> _entries;
- MetaAnimation *_animation;
+ Video::VideoDecoder *_animation;
Common::Rect _anmRect;
int32 _soundKey;
int32 _frameCur;
diff --git a/engines/zvision/scripting/controls/hotmov_control.cpp b/engines/zvision/scripting/controls/hotmov_control.cpp
index 68861dc221..dfa0200f47 100644
--- a/engines/zvision/scripting/controls/hotmov_control.cpp
+++ b/engines/zvision/scripting/controls/hotmov_control.cpp
@@ -28,14 +28,13 @@
#include "zvision/scripting/script_manager.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/cursors/cursor_manager.h"
-#include "zvision/animation/meta_animation.h"
#include "zvision/utility/utility.h"
#include "common/stream.h"
#include "common/file.h"
#include "common/system.h"
-
#include "graphics/surface.h"
+#include "video/video_decoder.h"
namespace ZVision {
@@ -79,7 +78,7 @@ HotMovControl::HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadSt
char filename[64];
sscanf(values.c_str(), "%s", filename);
values = Common::String(filename);
- _animation = new MetaAnimation(values, _engine);
+ _animation = _engine->loadAnimation(values);
} else if (param.matchString("venus_id", true)) {
_venusId = atoi(values.c_str());
}
@@ -106,7 +105,8 @@ void HotMovControl::renderFrame(uint frameNumber) {
const Graphics::Surface *frameData;
if (_animation) {
- frameData = _animation->getFrameData(frameNumber);
+ _animation->seekToFrame(frameNumber);
+ frameData = _animation->decodeNextFrame();
if (frameData)
_engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _rectangle);
}
@@ -130,7 +130,7 @@ bool HotMovControl::process(uint32 deltaTimeInMillis) {
else
_engine->getScriptManager()->setStateValue(_key, 2);
- _frameTime = _animation->frameTime();
+ _frameTime = 1000.0 / _animation->getDuration().framerate();
}
}
diff --git a/engines/zvision/scripting/controls/hotmov_control.h b/engines/zvision/scripting/controls/hotmov_control.h
index 86600d65dc..b18d44c7a6 100644
--- a/engines/zvision/scripting/controls/hotmov_control.h
+++ b/engines/zvision/scripting/controls/hotmov_control.h
@@ -28,9 +28,11 @@
#include "common/array.h"
#include "common/rect.h"
-namespace ZVision {
+namespace Video {
+ class VideoDecoder;
+}
-class MetaAnimation;
+namespace ZVision {
class HotMovControl : public Control {
public:
@@ -44,7 +46,7 @@ private:
int32 _lastRenderedFrame;
int32 _cycle;
int32 _cyclesCount;
- MetaAnimation *_animation;
+ Video::VideoDecoder *_animation;
Common::Rect _rectangle;
Common::Array<Common::Rect> _frames;
public:
diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp
index c541693ec3..60dcd37453 100644
--- a/engines/zvision/scripting/controls/input_control.cpp
+++ b/engines/zvision/scripting/controls/input_control.cpp
@@ -34,6 +34,7 @@
#include "common/str.h"
#include "common/stream.h"
#include "common/rect.h"
+#include "video/video_decoder.h"
namespace ZVision {
@@ -96,7 +97,7 @@ InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStre
sscanf(values.c_str(), "%25s %*u", fileName);
- _animation = new MetaAnimation(fileName, _engine);
+ _animation = _engine->loadAnimation(fileName);
_frame = -1;
_frameDelay = 0;
} else if (param.matchString("focus", true)) {
@@ -213,16 +214,17 @@ bool InputControl::process(uint32 deltaTimeInMillis) {
bool needDraw = true;// = _textChanged;
_frameDelay -= deltaTimeInMillis;
if (_frameDelay <= 0) {
- _frame = (_frame + 1) % _animation->frameCount();
- _frameDelay = _animation->frameTime();
+ _frame = (_frame + 1) % _animation->getFrameCount();
+ _frameDelay = 1000.0 / _animation->getDuration().framerate();
needDraw = true;
}
if (needDraw) {
- const Graphics::Surface *srf = _animation->getFrameData(_frame);
+ _animation->seekToFrame(_frame);
+ const Graphics::Surface *srf = _animation->decodeNextFrame();
uint32 xx = _textRectangle.left + _txtWidth;
- if (xx >= _textRectangle.left + (_textRectangle.width() - _animation->width()))
- xx = _textRectangle.left + _textRectangle.width() - _animation->width();
+ if (xx >= _textRectangle.left + (_textRectangle.width() - (int16)_animation->getWidth()))
+ xx = _textRectangle.left + _textRectangle.width() - (int16)_animation->getWidth();
_engine->getRenderManager()->blitSurfaceToBkg(*srf, xx, _textRectangle.top);
}
}
diff --git a/engines/zvision/scripting/controls/input_control.h b/engines/zvision/scripting/controls/input_control.h
index 410caf6d49..99f7f5287d 100644
--- a/engines/zvision/scripting/controls/input_control.h
+++ b/engines/zvision/scripting/controls/input_control.h
@@ -24,12 +24,15 @@
#define ZVISION_INPUT_CONTROL_H
#include "zvision/scripting/control.h"
-#include "zvision/animation/meta_animation.h"
#include "zvision/text/text.h"
#include "zvision/text/string_manager.h"
#include "common/rect.h"
+namespace Video {
+ class VideoDecoder;
+}
+
namespace ZVision {
class InputControl : public Control {
@@ -51,7 +54,7 @@ private:
bool _readOnly;
int16 _txtWidth;
- MetaAnimation *_animation;
+ Video::VideoDecoder *_animation;
int32 _frameDelay;
int16 _frame;
diff --git a/engines/zvision/scripting/controls/lever_control.cpp b/engines/zvision/scripting/controls/lever_control.cpp
index 1e4087963e..9566e4e038 100644
--- a/engines/zvision/scripting/controls/lever_control.cpp
+++ b/engines/zvision/scripting/controls/lever_control.cpp
@@ -28,15 +28,14 @@
#include "zvision/scripting/script_manager.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/cursors/cursor_manager.h"
-#include "zvision/animation/meta_animation.h"
#include "zvision/utility/utility.h"
#include "common/stream.h"
#include "common/file.h"
#include "common/tokenizer.h"
#include "common/system.h"
-
#include "graphics/surface.h"
+#include "video/video_decoder.h"
namespace ZVision {
@@ -106,7 +105,7 @@ void LeverControl::parseLevFile(const Common::String &fileName) {
if (param.matchString("animation_id", true)) {
// Not used
} else if (param.matchString("filename", true)) {
- _animation = new MetaAnimation(values, _engine);
+ _animation = _engine->loadAnimation(values);
} else if (param.matchString("skipcolor", true)) {
// Not used
} else if (param.matchString("anim_coords", true)) {
@@ -374,7 +373,8 @@ void LeverControl::renderFrame(uint frameNumber) {
const Graphics::Surface *frameData;
- frameData = _animation->getFrameData(frameNumber);
+ _animation->seekToFrame(frameNumber);
+ frameData = _animation->decodeNextFrame();
if (frameData)
_engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _animationCoords);
}
diff --git a/engines/zvision/scripting/controls/lever_control.h b/engines/zvision/scripting/controls/lever_control.h
index 37d4d3bd8d..fdf4a649dc 100644
--- a/engines/zvision/scripting/controls/lever_control.h
+++ b/engines/zvision/scripting/controls/lever_control.h
@@ -28,10 +28,11 @@
#include "common/list.h"
#include "common/rect.h"
-namespace ZVision {
+namespace Video {
+ class VideoDecoder;
+}
-class ZorkAVIDecoder;
-class MetaAnimation;
+namespace ZVision {
class LeverControl : public Control {
public:
@@ -59,7 +60,7 @@ private:
};
private:
- MetaAnimation *_animation;
+ Video::VideoDecoder *_animation;
int _cursor;
Common::Rect _animationCoords;
diff --git a/engines/zvision/scripting/controls/safe_control.cpp b/engines/zvision/scripting/controls/safe_control.cpp
index 3ad5d3a8ae..9f4e29acae 100644
--- a/engines/zvision/scripting/controls/safe_control.cpp
+++ b/engines/zvision/scripting/controls/safe_control.cpp
@@ -28,15 +28,14 @@
#include "zvision/scripting/script_manager.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/cursors/cursor_manager.h"
-#include "zvision/animation/meta_animation.h"
#include "zvision/utility/utility.h"
#include "common/stream.h"
#include "common/file.h"
#include "common/tokenizer.h"
#include "common/system.h"
-
#include "graphics/surface.h"
+#include "video/video_decoder.h"
namespace ZVision {
@@ -65,7 +64,7 @@ SafeControl::SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream
while (!stream.eos() && !line.contains('}')) {
if (param.matchString("animation", true)) {
- _animation = new MetaAnimation(values, _engine);
+ _animation = _engine->loadAnimation(values);
} else if (param.matchString("rectangle", true)) {
int x;
int y;
@@ -129,7 +128,8 @@ void SafeControl::renderFrame(uint frameNumber) {
int x = _rectangle.left;
int y = _rectangle.top;
- frameData = _animation->getFrameData(frameNumber);
+ _animation->seekToFrame(frameNumber);
+ frameData = _animation->decodeNextFrame();
if (frameData)
_engine->getRenderManager()->blitSurfaceToBkg(*frameData, x, y);
}
@@ -149,7 +149,7 @@ bool SafeControl::process(uint32 deltaTimeInMillis) {
_curFrame--;
renderFrame(_curFrame);
}
- _frameTime = _animation->frameTime();
+ _frameTime = 1000.0 / _animation->getDuration().framerate();
}
}
return false;
diff --git a/engines/zvision/scripting/controls/safe_control.h b/engines/zvision/scripting/controls/safe_control.h
index e32ca97b70..6e1095e304 100644
--- a/engines/zvision/scripting/controls/safe_control.h
+++ b/engines/zvision/scripting/controls/safe_control.h
@@ -28,10 +28,11 @@
#include "common/list.h"
#include "common/rect.h"
-namespace ZVision {
+namespace Video {
+ class VideoDecoder;
+}
-class ZorkAVIDecoder;
-class MetaAnimation;
+namespace ZVision {
class SafeControl : public Control {
public:
@@ -41,7 +42,7 @@ public:
private:
int16 _statesCount;
int16 _curState;
- MetaAnimation *_animation;
+ Video::VideoDecoder *_animation;
Common::Point _center;
Common::Rect _rectangle;
int16 _innerRaduis;
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index 74e4cadbe9..e15f8ec00f 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -27,9 +27,9 @@
#include "zvision/zvision.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/scripting/script_manager.h"
-#include "zvision/animation/meta_animation.h"
#include "graphics/surface.h"
+#include "video/video_decoder.h"
namespace ZVision {
@@ -39,8 +39,8 @@ AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::S
_mask(mask),
_animation(NULL) {
- _animation = new MetaAnimation(fileName, engine);
- _frmDelay = _animation->frameTime();
+ _animation = engine->loadAnimation(fileName);
+ _frmDelay = 1000.0 / _animation->getDuration().framerate();
if (frate > 0)
_frmDelay = 1000.0 / frate;
@@ -164,8 +164,8 @@ void AnimationNode::addPlayNode(int32 slot, int x, int y, int x2, int y2, int st
nod.start = startFrame;
nod.stop = endFrame;
- if (nod.stop >= (int)_animation->frameCount())
- nod.stop = _animation->frameCount() - 1;
+ if (nod.stop >= (int)_animation->getFrameCount())
+ nod.stop = _animation->getFrameCount() - 1;
nod.slot = slot;
nod._curFrame = -1;
diff --git a/engines/zvision/scripting/sidefx/animation_node.h b/engines/zvision/scripting/sidefx/animation_node.h
index 94428d2542..3adfd91f32 100644
--- a/engines/zvision/scripting/sidefx/animation_node.h
+++ b/engines/zvision/scripting/sidefx/animation_node.h
@@ -27,18 +27,17 @@
#include "common/rect.h"
#include "common/list.h"
-namespace Common {
-class String;
-}
-
namespace Graphics {
struct Surface;
}
+namespace Video {
+ class VideoDecoder;
+}
+
namespace ZVision {
class ZVision;
-class MetaAnimation;
class AnimationNode : public SideFX {
public:
@@ -64,7 +63,7 @@ private:
int32 _mask;
bool _DisposeAfterUse;
- MetaAnimation *_animation;
+ Video::VideoDecoder *_animation;
int32 _frmDelay;
public:
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index a4f16af9b0..bdb5dc18bc 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -34,75 +34,46 @@
namespace ZVision {
-RLFDecoder::RLFDecoder(const Common::String &fileName, bool stream)
- : _stream(stream),
- _readStream(NULL),
- _lastFrameRead(0),
- _frameCount(0),
- _width(0),
- _height(0),
- _frameTime(0),
- _frames(0),
- _nextFrame(0),
- _frameBufferByteSize(0) {
-
- Common::File *_file = new Common::File;
- if (!_file->open(fileName)) {
- warning("RLF animation file %s could not be opened", fileName.c_str());
- return;
- }
-
- _readStream = _file;
-
- if (!readHeader()) {
- warning("%s is not a RLF animation file. Wrong magic number", fileName.c_str());
- return;
- }
+RLFDecoder::~RLFDecoder() {
+ close();
+}
- _currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>());
- _frameBufferByteSize = _width * _height * sizeof(uint16);
+bool RLFDecoder::loadStream(Common::SeekableReadStream *stream) {
+ close();
- if (!stream) {
- _frames = new Frame[_frameCount];
+ addTrack(new RLFVideoTrack(stream));
- // Read in each frame
- for (uint i = 0; i < _frameCount; ++i) {
- _frames[i] = readNextFrame();
- }
- }
+ return true;
}
-RLFDecoder::RLFDecoder(Common::SeekableReadStream *rstream, bool stream)
- : _stream(stream),
- _readStream(rstream),
+RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
+ : _readStream(stream),
_lastFrameRead(0),
_frameCount(0),
_width(0),
_height(0),
_frameTime(0),
_frames(0),
- _nextFrame(0),
+ _curFrame(0),
_frameBufferByteSize(0) {
if (!readHeader()) {
- warning("Stream is not a RLF animation. Wrong magic number");
+ warning("Not a RLF animation file. Wrong magic number");
return;
}
_currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>());
_frameBufferByteSize = _width * _height * sizeof(uint16);
- if (!stream) {
- _frames = new Frame[_frameCount];
+ _frames = new Frame[_frameCount];
- // Read in each frame
- for (uint i = 0; i < _frameCount; ++i) {
- _frames[i] = readNextFrame();
- }
+ // Read in each frame
+ for (uint i = 0; i < _frameCount; ++i) {
+ _frames[i] = readNextFrame();
}
}
-RLFDecoder::~RLFDecoder() {
+RLFDecoder::RLFVideoTrack::~RLFVideoTrack() {
for (uint i = 0; i < _frameCount; ++i) {
delete[] _frames[i].encodedData;
}
@@ -111,7 +82,7 @@ RLFDecoder::~RLFDecoder() {
_currentFrameBuffer.free();
}
-bool RLFDecoder::readHeader() {
+bool RLFDecoder::RLFVideoTrack::readHeader() {
if (_readStream->readUint32BE() != MKTAG('F', 'E', 'L', 'R')) {
return false;
}
@@ -160,8 +131,8 @@ bool RLFDecoder::readHeader() {
return true;
}
-RLFDecoder::Frame RLFDecoder::readNextFrame() {
- RLFDecoder::Frame frame;
+RLFDecoder::RLFVideoTrack::Frame RLFDecoder::RLFVideoTrack::readNextFrame() {
+ RLFDecoder::RLFVideoTrack::Frame frame;
_readStream->readUint32BE(); // Magic number MARF
uint32 size = _readStream->readUint32LE(); // Size
@@ -188,30 +159,30 @@ RLFDecoder::Frame RLFDecoder::readNextFrame() {
return frame;
}
-void RLFDecoder::seekToFrame(int frameNumber) {
- assert(!_stream);
- assert(frameNumber < (int)_frameCount || frameNumber >= -1);
+bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) {
+ uint frame = getFrameAtTime(time);
+ assert(frame < (int)_frameCount);
- if (_nextFrame == frameNumber)
- return;
+ if ((uint)_curFrame == frame)
+ return true;
- if (frameNumber < 0) {
- _nextFrame = 0;
- return;
+ if (frame < 0) {
+ _curFrame = 0;
+ return false;
}
- int closestFrame = _nextFrame;
- int distance = (int)frameNumber - _nextFrame;
+ int closestFrame = _curFrame;
+ int distance = (int)frame - _curFrame;
if (distance < 0) {
for (uint i = 0; i < _completeFrames.size(); ++i) {
- if ((int)_completeFrames[i] > frameNumber)
+ if ((int)_completeFrames[i] > frame)
break;
closestFrame = _completeFrames[i];
}
} else {
for (uint i = 0; i < _completeFrames.size(); ++i) {
- int newDistance = (int)frameNumber - (int)(_completeFrames[i]);
+ int newDistance = (int)frame - (int)(_completeFrames[i]);
if (newDistance < 0)
break;
if (newDistance < distance) {
@@ -221,43 +192,27 @@ void RLFDecoder::seekToFrame(int frameNumber) {
}
}
- for (int i = closestFrame; i < frameNumber; ++i) {
+ for (uint i = closestFrame; i < frame; ++i) {
applyFrameToCurrent(i);
}
- _nextFrame = frameNumber;
-}
-
-const Graphics::Surface *RLFDecoder::getFrameData(uint frameNumber) {
- assert(!_stream);
- assert(frameNumber < _frameCount);
+ _curFrame = frame;
- // Since this method is so expensive, first check to see if we can use
- // decodeNextFrame() it's cheap.
- if ((int)frameNumber == _nextFrame - 1) {
- return &_currentFrameBuffer;
- } else if (_nextFrame == (int)frameNumber) {
- return decodeNextFrame();
- }
-
- seekToFrame(frameNumber);
- return decodeNextFrame();
+ return true;
}
-const Graphics::Surface *RLFDecoder::decodeNextFrame() {
- assert(_nextFrame < (int)_frameCount);
+const Graphics::Surface *RLFDecoder::RLFVideoTrack::decodeNextFrame() {
+ // When an animation ends, rewind
+ if (_curFrame == (int)_frameCount)
+ seek(Audio::Timestamp(0, getFrameRate().toInt()));
+
+ applyFrameToCurrent(_curFrame);
- if (_stream) {
- applyFrameToCurrent(readNextFrame());
- } else {
- applyFrameToCurrent(_nextFrame);
- }
-
- _nextFrame++;
+ _curFrame++;
return &_currentFrameBuffer;
}
-void RLFDecoder::applyFrameToCurrent(uint frameNumber) {
+void RLFDecoder::RLFVideoTrack::applyFrameToCurrent(uint frameNumber) {
if (_frames[frameNumber].type == Masked) {
decodeMaskedRunLengthEncoding(_frames[frameNumber].encodedData, (int8 *)_currentFrameBuffer.getPixels(), _frames[frameNumber].encodedSize, _frameBufferByteSize);
} else if (_frames[frameNumber].type == Simple) {
@@ -265,15 +220,7 @@ void RLFDecoder::applyFrameToCurrent(uint frameNumber) {
}
}
-void RLFDecoder::applyFrameToCurrent(const RLFDecoder::Frame &frame) {
- if (frame.type == Masked) {
- decodeMaskedRunLengthEncoding(frame.encodedData, (int8 *)_currentFrameBuffer.getPixels(), frame.encodedSize, _frameBufferByteSize);
- } else if (frame.type == Simple) {
- decodeSimpleRunLengthEncoding(frame.encodedData, (int8 *)_currentFrameBuffer.getPixels(), frame.encodedSize, _frameBufferByteSize);
- }
-}
-
-void RLFDecoder::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
+void RLFDecoder::RLFVideoTrack::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
uint32 sourceOffset = 0;
uint32 destOffset = 0;
int16 numberOfCopy = 0;
@@ -320,7 +267,7 @@ void RLFDecoder::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32
}
}
-void RLFDecoder::decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
+void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
uint32 sourceOffset = 0;
uint32 destOffset = 0;
int16 numberOfCopy = 0;
diff --git a/engines/zvision/video/rlf_decoder.h b/engines/zvision/video/rlf_decoder.h
index dcfd8606c2..f0f31c2128 100644
--- a/engines/zvision/video/rlf_decoder.h
+++ b/engines/zvision/video/rlf_decoder.h
@@ -24,147 +24,109 @@
#define ZVISION_RLF_DECODER_H
#include "common/file.h"
+#include "video/video_decoder.h"
#include "graphics/surface.h"
-namespace Common {
-class String;
-}
-
namespace ZVision {
-class RLFDecoder {
+class RLFDecoder : public Video::VideoDecoder {
public:
- RLFDecoder(const Common::String &fileName, bool stream = true);
- RLFDecoder(Common::SeekableReadStream *rstream, bool stream);
+ RLFDecoder() {}
~RLFDecoder();
-private:
- enum EncodingType {
- Masked,
- Simple
- };
-
- struct Frame {
- EncodingType type;
- int8 *encodedData;
- uint32 encodedSize;
- };
-
-private:
- Common::SeekableReadStream *_readStream;
- bool _stream;
- uint _lastFrameRead;
-
- uint _frameCount;
- uint _width;
- uint _height;
- uint32 _frameTime; // In milliseconds
- Frame *_frames;
- Common::Array<uint> _completeFrames;
-
- int _nextFrame;
- Graphics::Surface _currentFrameBuffer;
- uint32 _frameBufferByteSize;
-
-public:
- uint frameCount() {
- return _frameCount;
- }
- uint width() {
- return _width;
- }
- uint height() {
- return _height;
- }
- uint32 frameTime() {
- return _frameTime;
- }
-
- /**
- * Seeks to the frameNumber and updates the internal Surface with
- * the new frame data. If frameNumber == -1, it only sets _currentFrame,
- * the internal Surface is unchanged. This function requires _stream = false
- *
- * @param frameNumber The frame number to seek to
- */
- void seekToFrame(int frameNumber);
-
- /**
- * Returns the pixel data of the frame specified. It will try to use
- * decodeNextFrame() if possible. If not, it uses seekToFrame() to
- * update the internal Surface and then returns a pointer to it.
- * This function requires _stream = false
- *
- * @param frameNumber The frame number to get data for
- * @return A pointer to the pixel data. Do NOT delete this.
- */
- const Graphics::Surface *getFrameData(uint frameNumber);
- /**
- * Returns the pixel data of current frame and go to next. It is up to the user to
- * check if the current frame is valid before calling this.
- * IE. Use endOfAnimation()
- *
- * @return A pointer to the pixel data. Do NOT delete this.
- */
- const Graphics::Surface *decodeNextFrame();
- /**
- * @return Is the currentFrame is the last frame in the animation?
- */
- bool endOfAnimation() {
- return _nextFrame == (int)_frameCount;
- }
+ bool loadStream(Common::SeekableReadStream *stream);
private:
- /**
- * Reads in the header of the RLF file
- *
- * @return Will return false if the header magic number is wrong
- */
- bool readHeader();
- /**
- * Reads the next frame from the RLF file, stores the data in
- * a Frame object, then returns the object
- *
- * @return A Frame object representing the frame data
- */
- Frame readNextFrame();
-
- /**
- * Applies the frame corresponding to frameNumber on top of _currentFrameBuffer.
- * This function requires _stream = false so it can look up the Frame object
- * referenced by frameNumber.
- *
- * @param frameNumber The frame number to apply to _currentFrameBuffer
- */
- void applyFrameToCurrent(uint frameNumber);
- /**
- * Applies the data from a Frame object on top of a _currentFrameBuffer.
- *
- * @param frame A Frame object to apply to _currentFrameBuffer
- */
- void applyFrameToCurrent(const RLFDecoder::Frame &frame);
-
- /**
- * Decode frame data that uses masked run length encoding. This is the encoding
- * used by P-frames.
- *
- * @param source The source pixel data
- * @param dest The destination buffer
- * @param sourceSize The size of the source pixel data
- * @param destSize The size of the destination buffer
- */
- void decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const;
- /**
- * Decode frame data that uses simple run length encoding. This is the encoding
- * used by I-frames.
- *
- * @param source The source pixel data
- * @param dest The destination buffer
- * @param sourceSize The size of the source pixel data
- * @param destSize The size of the destination buffer
- */
- void decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const;
+ class RLFVideoTrack : public FixedRateVideoTrack {
+ public:
+ RLFVideoTrack(Common::SeekableReadStream *stream);
+ ~RLFVideoTrack();
+
+ uint16 getWidth() const { return _width; }
+ uint16 getHeight() const { return _height; }
+ Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); /*RGB 565*/ }
+ int getCurFrame() const { return _curFrame; }
+ int getFrameCount() const { return _frameCount; }
+ const Graphics::Surface *decodeNextFrame();
+ bool isSeekable() const { return true; }
+ bool seek(const Audio::Timestamp &time);
+
+ protected:
+ Common::Rational getFrameRate() const { return Common::Rational(60, _frameTime); }
+
+ private:
+ enum EncodingType {
+ Masked,
+ Simple
+ };
+
+ struct Frame {
+ EncodingType type;
+ int8 *encodedData;
+ uint32 encodedSize;
+ };
+
+ /**
+ * Reads in the header of the RLF file
+ *
+ * @return Will return false if the header magic number is wrong
+ */
+ bool readHeader();
+
+ /**
+ * Reads the next frame from the RLF file, stores the data in
+ * a Frame object, then returns the object
+ *
+ * @return A Frame object representing the frame data
+ */
+ Frame readNextFrame();
+
+ /**
+ * Applies the frame corresponding to frameNumber on top of _currentFrameBuffer.
+ * This function requires _stream = false so it can look up the Frame object
+ * referenced by frameNumber.
+ *
+ * @param frameNumber The frame number to apply to _currentFrameBuffer
+ */
+ void applyFrameToCurrent(uint frameNumber);
+
+ /**
+ * Decode frame data that uses masked run length encoding. This is the encoding
+ * used by P-frames.
+ *
+ * @param source The source pixel data
+ * @param dest The destination buffer
+ * @param sourceSize The size of the source pixel data
+ * @param destSize The size of the destination buffer
+ */
+ void decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const;
+ /**
+ * Decode frame data that uses simple run length encoding. This is the encoding
+ * used by I-frames.
+ *
+ * @param source The source pixel data
+ * @param dest The destination buffer
+ * @param sourceSize The size of the source pixel data
+ * @param destSize The size of the destination buffer
+ */
+ void decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const;
+
+ uint _lastFrameRead;
+
+ uint _frameCount;
+ uint _width;
+ uint _height;
+ uint32 _frameTime; // In milliseconds
+ Frame *_frames;
+ Common::Array<uint> _completeFrames;
+
+ int _curFrame;
+ Graphics::Surface _currentFrameBuffer;
+ uint32 _frameBufferByteSize;
+
+ Common::SeekableReadStream *_readStream;
+ }; // RLFVideoTrack
};
} // End of namespace ZVision
diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index db6161bf0c..c8f968d975 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.cpp
@@ -30,9 +30,29 @@
#include "zvision/utility/clock.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/graphics/subtitles.h"
+#include "zvision/video/rlf_decoder.h"
+#include "zvision/video/zork_avi_decoder.h"
namespace ZVision {
+Video::VideoDecoder *ZVision::loadAnimation(const Common::String &fileName) {
+ Common::String tmpFileName = fileName;
+ tmpFileName.toLowercase();
+ Video::VideoDecoder *animation = NULL;
+
+ if (tmpFileName.hasSuffix(".rlf"))
+ animation = new RLFDecoder();
+ else if (tmpFileName.hasSuffix(".avi"))
+ animation = new ZorkAVIDecoder();
+ else
+ error("Unknown suffix for animation %s", fileName.c_str());
+
+ Common::File *_file = getSearchManager()->openFile(tmpFileName);
+ animation->loadStream(_file);
+
+ return animation;
+}
+
void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect, bool skippable, Subtitle *sub) {
Common::Rect dst = destRect;
// If destRect is empty, no specific scaling was requested. However, we may choose to do scaling anyway
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index f8763f94ee..82030e6944 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -173,6 +173,7 @@ public:
* @param skippable If true, the video can be skipped at any time using [Spacebar]
*/
void playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &destRect = Common::Rect(0, 0, 0, 0), bool skippable = true, Subtitle *sub = NULL);
+ Video::VideoDecoder *loadAnimation(const Common::String &fileName);
void rotateTo(int16 to, int16 time);