aboutsummaryrefslogtreecommitdiff
path: root/engines/zvision
diff options
context:
space:
mode:
Diffstat (limited to 'engines/zvision')
-rw-r--r--engines/zvision/console.cpp6
-rw-r--r--engines/zvision/events.cpp5
-rw-r--r--engines/zvision/render_manager.cpp13
-rw-r--r--engines/zvision/render_manager.h24
-rw-r--r--engines/zvision/video.cpp87
-rw-r--r--engines/zvision/zvision.cpp31
-rw-r--r--engines/zvision/zvision.h22
7 files changed, 93 insertions, 95 deletions
diff --git a/engines/zvision/console.cpp b/engines/zvision/console.cpp
index 9c7d79a8f1..6634e0bef4 100644
--- a/engines/zvision/console.cpp
+++ b/engines/zvision/console.cpp
@@ -69,9 +69,9 @@ bool Console::cmdLoadVideo(int argc, const char **argv) {
return true;
}
- Video::VideoDecoder *videoDecoder = new ZorkAVIDecoder();
- if (videoDecoder && videoDecoder->loadFile(argv[1])) {
- _engine->getRenderManager()->startVideo(videoDecoder);
+ ZorkAVIDecoder videoDecoder;
+ if (videoDecoder.loadFile(argv[1])) {
+ _engine->playVideo(videoDecoder);
}
return true;
diff --git a/engines/zvision/events.cpp b/engines/zvision/events.cpp
index e392d3c78a..508d2610aa 100644
--- a/engines/zvision/events.cpp
+++ b/engines/zvision/events.cpp
@@ -61,11 +61,6 @@ void ZVision::processEvents() {
if (_event.kbd.hasFlags(Common::KBD_CTRL))
quitGame();
break;
- case Common::KEYCODE_ESCAPE:
- if (_renderManager->isVideoPlaying())
- _renderManager->cancelVideo();
-
- break;
default:
break;
}
diff --git a/engines/zvision/render_manager.cpp b/engines/zvision/render_manager.cpp
index b6163c83c1..604c310689 100644
--- a/engines/zvision/render_manager.cpp
+++ b/engines/zvision/render_manager.cpp
@@ -38,25 +38,12 @@ RenderManager::RenderManager(OSystem *system, const int width, const int height)
: _system(system),
_width(width),
_height(height),
- _pixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), // RGB555
- _currentVideo(0),
_currentBackground(0),
- _scaledVideoFrameBuffer(0),
_needsScreenUpdate(false),
_renderTable(width, height) {
}
-/**
- * Initialize graphics
- */
-void RenderManager::initialize() {
- initGraphics(_width, _height, true, &_pixelFormat);
-}
-
void RenderManager::updateScreen(bool isConsoleActive) {
- if (_currentVideo != 0)
- continueVideo();
-
if (_needsScreenUpdate || isConsoleActive) {
_system->updateScreen();
_needsScreenUpdate = false;
diff --git a/engines/zvision/render_manager.h b/engines/zvision/render_manager.h
index fc2598ecf9..9554e888d9 100644
--- a/engines/zvision/render_manager.h
+++ b/engines/zvision/render_manager.h
@@ -26,8 +26,6 @@
#include "common/types.h"
#include "common/rect.h"
-#include "graphics/pixelformat.h"
-
#include "zvision/render_table.h"
class OSystem;
@@ -51,7 +49,6 @@ private:
OSystem *_system;
const int _width;
const int _height;
- const Graphics::PixelFormat _pixelFormat;
RenderTable _renderTable;
Common::SeekableReadStream *_currentBackground;
@@ -66,22 +63,6 @@ public:
void updateScreen(bool isConsoleActive);
/**
- * Start a video playing. It will also load the first frame of the video.
- *
- * @param videoDecoder The video to play
- */
- void startVideo(Video::VideoDecoder *videoDecoder);
- /**
- * @return Is a video currently being played
- */
- bool isVideoPlaying() { return _currentVideo == 0; }
- /**
- * Cancels a video prematurely. Any sound remaining in the queue will continue to play.
- * The last frame of the video will remain on the screen until something else overwrites it
- */
- void cancelVideo();
-
- /**
* Blits the image or a portion of the image to the screen. Actual screen updates won't happen until the end of the frame.
* The image will be clipped to fit inside the window.
*
@@ -116,11 +97,6 @@ public:
bool needsScreenUpdate() { return _needsScreenUpdate; };
private:
- /**
- * Checks the time since the last video frame, and blits the next frame to the screen
- */
- void continueVideo();
-
void renderSubRectToScreen(uint16 *buffer, uint32 imageWidth, uint32 imageHeight, uint32 horizontalPitch, uint32 destinationX, uint32 destinationY, Common::Rect subRectangle);
};
diff --git a/engines/zvision/video.cpp b/engines/zvision/video.cpp
index 1ccf736970..8550a6cfca 100644
--- a/engines/zvision/video.cpp
+++ b/engines/zvision/video.cpp
@@ -27,7 +27,9 @@
#include "engines/util.h"
#include "graphics/surface.h"
+#include "zvision/clock.h"
#include "zvision/render_manager.h"
+#include "zvision/zvision.h"
namespace ZVision {
@@ -71,62 +73,77 @@ void scale2x(const byte *src, byte *dst, uint32 srcWidth, uint32 srcHeight, byte
}
}
-void RenderManager::startVideo(Video::VideoDecoder *videoDecoder) {
- if (!videoDecoder)
- return;
-
- _currentVideo = videoDecoder;
-
+void ZVision::playVideo(Video::VideoDecoder &videoDecoder) {
+ // Videos use a different pixel format
Common::List<Graphics::PixelFormat> formats;
- formats.push_back(videoDecoder->getPixelFormat());
+ formats.push_back(videoDecoder.getPixelFormat());
initGraphics(_width, _height, true, formats);
-
- _scaledVideoFrameBuffer = new byte[_currentVideo->getWidth() * _currentVideo->getHeight() * _currentVideo->getPixelFormat().bytesPerPixel * 4];
-
- _currentVideo->start();
- // Load the first frame
- continueVideo();
-}
-
-void RenderManager::continueVideo() {
- byte bytesPerPixel = _currentVideo->getPixelFormat().bytesPerPixel;
- uint16 origWidth = _currentVideo->getWidth();
- uint16 origHeight = _currentVideo->getHeight();
+ byte bytesPerPixel = videoDecoder.getPixelFormat().bytesPerPixel;
+ uint16 origWidth = videoDecoder.getWidth();
+ uint16 origHeight = videoDecoder.getHeight();
uint16 pitch = origWidth * bytesPerPixel;
+
+ // Most videos are very small. Therefore we do a simple 2x scale
bool shouldBeScaled = (origWidth * 2 <= 640 && origHeight * 2 <= 480);
uint16 finalWidth = shouldBeScaled ? origWidth * 2 : origWidth;
uint16 finalHeight = shouldBeScaled ? origHeight * 2 : origHeight;
- uint16 x = (_system->getWidth() - finalWidth) / 2;
- uint16 y = (_system->getHeight() - finalHeight) / 2;
+ byte *scaledVideoFrameBuffer = new byte[origHeight * pitch * 4];
+
+ uint16 x = (_width - finalWidth) / 2;
+ uint16 y = (_height - finalHeight) / 2;
+
+ _clock->stop();
+ videoDecoder.start();
+
+ // Only continue while the video is still playing
+ while (videoDecoder.isPlaying()) {
+ _clock->update();
+ uint32 currentTime = _clock->getLastMeasuredTime();
+
+ // Check for engine quit and video stop key presses
+ while (_eventMan->pollEvent(_event)) {
+ switch (_event.type) {
+ case Common::EVENT_KEYDOWN:
+ switch (_event.kbd.keycode) {
+ case Common::KEYCODE_q:
+ if (_event.kbd.hasFlags(Common::KBD_CTRL))
+ quitGame();
+ break;
+ case Common::KEYCODE_SPACE:
+ videoDecoder.stop();
+ break;
+ }
+ }
+ }
- if (!_currentVideo->endOfVideo()) {
- if (_currentVideo->needsUpdate()) {
- const Graphics::Surface *frame = _currentVideo->decodeNextFrame();
+ if (videoDecoder.needsUpdate()) {
+ const Graphics::Surface *frame = videoDecoder.decodeNextFrame();
if (frame) {
if (shouldBeScaled) {
- scale2x((byte *)frame->pixels, _scaledVideoFrameBuffer, origWidth, origHeight, bytesPerPixel);
- _system->copyRectToScreen(_scaledVideoFrameBuffer, pitch * 2, x, y, finalWidth, finalHeight);
+ scale2x((byte *)frame->pixels, scaledVideoFrameBuffer, origWidth, origHeight, bytesPerPixel);
+ _system->copyRectToScreen(scaledVideoFrameBuffer, pitch * 2, x, y, finalWidth, finalHeight);
} else {
_system->copyRectToScreen((byte *)frame->pixels, pitch, x, y, finalWidth, finalHeight);
}
- _needsScreenUpdate = true;
+ _system->updateScreen();
}
}
- } else {
- cancelVideo();
+
+ // Calculate the frame delay based off a desired frame time
+ int delay = _desiredFrameTime - (currentTime - _system->getMillis());
+ // Ensure non-negative
+ delay = delay < 0 ? 0 : delay;
+ _system->delayMillis(delay);
}
-}
-void RenderManager::cancelVideo() {
+ _clock->stop();
+
+ // Reset the pixel format to the original state
initGraphics(_width, _height, true, &_pixelFormat);
- delete _currentVideo;
- _currentVideo = 0;
- delete[] _scaledVideoFrameBuffer;
- _scaledVideoFrameBuffer = 0;
}
} // End of namespace ZVision
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index ca43549f50..0015c41499 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -31,11 +31,14 @@
#include "common/file.h"
#include "engines/util.h"
+
+#include "audio/mixer.h"
#include "zvision/zvision.h"
#include "zvision/console.h"
#include "zvision/script_manager.h"
#include "zvision/render_manager.h"
+#include "zvision/clock.h"
#include "zvision/zfs_archive.h"
#include "zvision/detection.h"
@@ -47,7 +50,9 @@ ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
: Engine(syst),
_gameDescription(gameDesc),
_width(640),
- _height(480) {
+ _height(480),
+ _pixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), /*RGB 555*/
+ _desiredFrameTime(33) /* ~30 fps */ {
// Put your engine in a sane state, but do nothing big yet;
// in particular, do not load data from files; rather, if you
// need to do such things, do them from run().
@@ -75,14 +80,19 @@ ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
_scriptManager = new ScriptManager(this);
_renderManager = new RenderManager(_system, _width, _height);
+ // Create clock
+ _clock = new Clock(_system);
+
debug("ZVision::ZVision");
}
-
+
ZVision::~ZVision() {
debug("ZVision::~ZVision");
// Dispose of resources
delete _console;
+ delete _clock;
+ delete _renderManager;
delete _scriptManager;
delete _rnd;
@@ -103,7 +113,7 @@ void ZVision::initialize() {
SearchMan.add(name, archive);
}
- _renderManager->initialize();
+ initGraphics(_width, _height, true, &_pixelFormat);
_scriptManager->initialize();
@@ -115,25 +125,20 @@ Common::Error ZVision::run() {
initialize();
// Main loop
- uint32 currentTime = _system->getMillis();
- uint32 lastTime = currentTime;
- const uint desiredFrameTime = 33; // ~30 fps
-
while (!shouldQuit()) {
- processEvents();
+ _clock->update();
+ uint32 currentTime = _clock->getLastMeasuredTime();
- currentTime = _system->getMillis();
- uint32 deltaTime = currentTime - lastTime;
- lastTime = currentTime;
+ processEvents();
- _scriptManager->updateNodes(deltaTime);
+ _scriptManager->updateNodes(_clock->getDeltaTime());
_scriptManager->checkPuzzleCriteria();
// Render a frame
_renderManager->updateScreen(_console->isActive());
// Calculate the frame delay based off a desired frame time
- int delay = desiredFrameTime - (currentTime - _system->getMillis());
+ int delay = _desiredFrameTime - (currentTime - _system->getMillis());
// Ensure non-negative
delay = delay < 0 ? 0 : delay;
_system->delayMillis(delay);
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index 9588623f56..459096a03b 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -29,16 +29,24 @@
#include "engines/engine.h"
+#include "graphics/pixelformat.h"
+
#include "zvision/detection.h"
#include "gui/debugger.h"
-
+
+
+namespace Video {
+class VideoDecoder;
+}
+
namespace ZVision {
struct ZVisionGameDescription;
class Console;
class ScriptManager;
class RenderManager;
+class Clock;
// our engine debug channels
enum {
@@ -58,25 +66,35 @@ private:
const ZVisionGameDescription *_gameDescription;
const int _width;
const int _height;
+ const Graphics::PixelFormat _pixelFormat;
+
+ const uint _desiredFrameTime;
// We need random numbers
Common::RandomSource *_rnd;
+
// Managers
ScriptManager *_scriptManager;
RenderManager *_renderManager;
+ // Clock
+ Clock *_clock;
+
// To prevent allocation every time we process events
Common::Event _event;
public:
uint32 getFeatures() const;
Common::Language getLanguage() const;
- virtual Common::Error run();
+ Common::Error run();
+
ScriptManager *getScriptManager() const;
RenderManager *getRenderManager() const;
Common::RandomSource *getRandomSource() const;
ZVisionGameId getGameId() const;
+ void playVideo(Video::VideoDecoder &videoDecoder);
+
private:
void initialize();