aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarisa-Chan2014-03-02 00:03:25 +0700
committerMarisa-Chan2014-03-02 00:03:25 +0700
commiteb9061e580ce7c055c4f7cafe9bd81823367f39d (patch)
treed893494b6d27ecb8866f9415d7fe2d1b52a787e1
parentd90b325a3b0ec5ab455f8b8ae90bef9a528600df (diff)
downloadscummvm-rg350-eb9061e580ce7c055c4f7cafe9bd81823367f39d.tar.gz
scummvm-rg350-eb9061e580ce7c055c4f7cafe9bd81823367f39d.tar.bz2
scummvm-rg350-eb9061e580ce7c055c4f7cafe9bd81823367f39d.zip
ZVISION: Refactor video-play and correct streamvideo for use subtitles and correct scale.
-rw-r--r--engines/zvision/actions.cpp20
-rw-r--r--engines/zvision/subtitles.h2
-rw-r--r--engines/zvision/video.cpp116
-rw-r--r--engines/zvision/zvision.cpp1
-rw-r--r--engines/zvision/zvision.h3
5 files changed, 51 insertions, 91 deletions
diff --git a/engines/zvision/actions.cpp b/engines/zvision/actions.cpp
index bab1a5e1a1..99fa6a646d 100644
--- a/engines/zvision/actions.cpp
+++ b/engines/zvision/actions.cpp
@@ -577,12 +577,22 @@ bool ActionStreamVideo::execute() {
return true;
}
- Common::Rect destRect;
- if ((_flags & DIFFERENT_DIMENSIONS) == DIFFERENT_DIMENSIONS) {
- destRect = Common::Rect(_x1, _y1, _x2, _y2);
- }
+ Common::Rect destRect = Common::Rect(_x1, _y1, _x2 + 1, _y2 + 1);
+
+ Common::String subname = _fileName;
+ subname.setChar('s', subname.size() - 3);
+ subname.setChar('u', subname.size() - 2);
+ subname.setChar('b', subname.size() - 1);
+
+ Subtitle *sub = NULL;
+
+ if (_engine->getSearchManager()->hasFile(subname))
+ sub = new Subtitle(_engine, subname);
+
+ _engine->playVideo(decoder, destRect, _skippable, sub);
- _engine->playVideo(decoder, destRect, _skippable);
+ if (sub)
+ delete sub;
}
return true;
diff --git a/engines/zvision/subtitles.h b/engines/zvision/subtitles.h
index d14cb6f052..698561b655 100644
--- a/engines/zvision/subtitles.h
+++ b/engines/zvision/subtitles.h
@@ -28,6 +28,8 @@
namespace ZVision {
+class ZVision;
+
class Subtitle {
public:
Subtitle(ZVision *engine, const Common::String &subname);
diff --git a/engines/zvision/video.cpp b/engines/zvision/video.cpp
index 6b7299ea84..0ad9000fcb 100644
--- a/engines/zvision/video.cpp
+++ b/engines/zvision/video.cpp
@@ -26,6 +26,7 @@
#include "zvision/clock.h"
#include "zvision/render_manager.h"
+#include "zvision/subtitles.h"
#include "common/system.h"
@@ -38,90 +39,32 @@
namespace ZVision {
-// Taken/modified from SCI
-void scaleBuffer(const byte *src, byte *dst, uint32 srcWidth, uint32 srcHeight, byte bytesPerPixel, uint scaleAmount) {
- assert(bytesPerPixel == 1 || bytesPerPixel == 2);
-
- const uint32 newWidth = srcWidth * scaleAmount;
- const uint32 pitch = newWidth * bytesPerPixel;
- const byte *srcPtr = src;
-
- if (bytesPerPixel == 1) {
- for (uint32 y = 0; y < srcHeight; ++y) {
- for (uint32 x = 0; x < srcWidth; ++x) {
- const byte color = *srcPtr++;
-
- for (uint i = 0; i < scaleAmount; ++i) {
- dst[i] = color;
- dst[pitch + i] = color;
- }
- dst += scaleAmount;
- }
- dst += pitch;
- }
- } else if (bytesPerPixel == 2) {
- for (uint32 y = 0; y < srcHeight; ++y) {
- for (uint32 x = 0; x < srcWidth; ++x) {
- const byte color = *srcPtr++;
- const byte color2 = *srcPtr++;
-
- for (uint i = 0; i < scaleAmount; ++i) {
- uint index = i * 2;
-
- dst[index] = color;
- dst[index + 1] = color2;
- dst[pitch + index] = color;
- dst[pitch + index + 1] = color2;
- }
- dst += 2 * scaleAmount;
- }
- dst += pitch;
- }
- }
-}
-
-void ZVision::playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &destRect, bool skippable) {
- byte bytesPerPixel = videoDecoder.getPixelFormat().bytesPerPixel;
-
- uint16 origWidth = videoDecoder.getWidth();
- uint16 origHeight = videoDecoder.getHeight();
-
- uint scale = 1;
+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
- if (destRect.isEmpty()) {
- // Most videos are very small. Therefore we do a simple 2x scale
- if (origWidth * 2 <= 640 && origHeight * 2 <= 480) {
- scale = 2;
- }
- } else {
- // Assume bilinear scaling. AKA calculate the scale from just the width.
- // Also assume that the scaling is in integral intervals. AKA no 1.5x scaling
- // TODO: Test ^these^ assumptions
- scale = destRect.width() / origWidth;
+ if (dst.isEmpty())
+ dst = Common::Rect(vid.getWidth(), vid.getHeight());
- // TODO: Test if we need to support downscale.
- }
-
- uint16 pitch = origWidth * bytesPerPixel;
+ Graphics::Surface *scaled = NULL;
- uint16 finalWidth = origWidth * scale;
- uint16 finalHeight = origHeight * scale;
-
- byte *scaledVideoFrameBuffer;
- if (scale != 1) {
- scaledVideoFrameBuffer = new byte[finalWidth * finalHeight * bytesPerPixel];
+ if (vid.getWidth() != dst.width() || vid.getHeight() != dst.height()) {
+ scaled = new Graphics::Surface;
+ scaled->create(dst.width(), dst.height(), vid.getPixelFormat());
}
- uint16 x = ((WINDOW_WIDTH - finalWidth) / 2) + destRect.left;
- uint16 y = ((WINDOW_HEIGHT - finalHeight) / 2) + destRect.top;
+
+ uint16 x = _workingWindow.left + dst.left;
+ uint16 y = _workingWindow.top + dst.top;
+ uint16 finalWidth = dst.width() < _workingWindow.width() ? dst.width() : _workingWindow.width();
+ uint16 finalHeight = dst.height() < _workingWindow.height() ? dst.height() : _workingWindow.height();
_clock.stop();
- videoDecoder.start();
+ vid.start();
// Only continue while the video is still playing
- while (!shouldQuit() && !videoDecoder.endOfVideo() && videoDecoder.isPlaying()) {
+ while (!shouldQuit() && !vid.endOfVideo() && vid.isPlaying()) {
// Check for engine quit and video stop key presses
- while (!videoDecoder.endOfVideo() && videoDecoder.isPlaying() && _eventMan->pollEvent(_event)) {
+ while (_eventMan->pollEvent(_event)) {
switch (_event.type) {
case Common::EVENT_KEYDOWN:
switch (_event.kbd.keycode) {
@@ -131,7 +74,7 @@ void ZVision::playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &d
break;
case Common::KEYCODE_SPACE:
if (skippable) {
- videoDecoder.stop();
+ vid.stop();
}
break;
default:
@@ -142,29 +85,32 @@ void ZVision::playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &d
}
}
- if (videoDecoder.needsUpdate()) {
- const Graphics::Surface *frame = videoDecoder.decodeNextFrame();
+ if (vid.needsUpdate()) {
+ const Graphics::Surface *frame = vid.decodeNextFrame();
+ if (sub)
+ sub->process(vid.getCurFrame());
if (frame) {
- if (scale != 1) {
- scaleBuffer((const byte *)frame->getPixels(), scaledVideoFrameBuffer, origWidth, origHeight, bytesPerPixel, scale);
- _system->copyRectToScreen(scaledVideoFrameBuffer, pitch * 2, x, y, finalWidth, finalHeight);
- } else {
- _system->copyRectToScreen((const byte *)frame->getPixels(), pitch, x, y, finalWidth, finalHeight);
+ if (scaled) {
+ _renderManager->scaleBuffer(frame->getPixels(), scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, scaled->w, scaled->h);
+ frame = scaled;
}
+ _system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, x, y, finalWidth, finalHeight);
+ _renderManager->processSubs(0);
}
}
// Always update the screen so the mouse continues to render
_system->updateScreen();
- _system->delayMillis(videoDecoder.getTimeToNextFrame());
+ _system->delayMillis(vid.getTimeToNextFrame() / 2);
}
_clock.start();
- if (scale != 1) {
- delete[] scaledVideoFrameBuffer;
+ if (scaled) {
+ scaled->free();
+ delete scaled;
}
}
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 4c5164cd6e..b1615aa7b4 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -35,6 +35,7 @@
#include "zvision/menu.h"
#include "zvision/search_manager.h"
#include "zvision/text.h"
+#include "zvision/truetype_font.h"
#include "common/config-manager.h"
#include "common/str.h"
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index bbcaf3c952..982d3fd98b 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -54,6 +54,7 @@ class SaveManager;
class RlfAnimation;
class menuHandler;
class textRenderer;
+class Subtitle;
class ZVision : public Engine {
public:
@@ -161,7 +162,7 @@ public:
* @param destRect Where to put the video. (In working window coords)
* @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);
+ void playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &destRect = Common::Rect(0, 0, 0, 0), bool skippable = true, Subtitle *sub = NULL);
Common::String generateSaveFileName(uint slot);
Common::String generateAutoSaveFileName();