diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/zvision/console.cpp | 6 | ||||
-rw-r--r-- | engines/zvision/events.cpp | 5 | ||||
-rw-r--r-- | engines/zvision/render_manager.cpp | 13 | ||||
-rw-r--r-- | engines/zvision/render_manager.h | 24 | ||||
-rw-r--r-- | engines/zvision/video.cpp | 87 | ||||
-rw-r--r-- | engines/zvision/zvision.cpp | 31 | ||||
-rw-r--r-- | engines/zvision/zvision.h | 22 |
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(); |