aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
authorColin Snover2016-07-02 19:11:46 -0500
committerColin Snover2016-07-10 09:35:24 -0500
commit4d91b458e53ebda8726055d338da12c05a7879ea (patch)
treecaaaf88c74cb0009f88b5c5390b7a138892cb376 /engines/sci/engine
parent28d4f5b0e48780dbbee3343d3d41fdd79340a3f4 (diff)
downloadscummvm-rg350-4d91b458e53ebda8726055d338da12c05a7879ea.tar.gz
scummvm-rg350-4d91b458e53ebda8726055d338da12c05a7879ea.tar.bz2
scummvm-rg350-4d91b458e53ebda8726055d338da12c05a7879ea.zip
SCI32: Implement kPlayVMD
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/kernel.h11
-rw-r--r--engines/sci/engine/kernel_tables.h18
-rw-r--r--engines/sci/engine/kvideo.cpp163
-rw-r--r--engines/sci/engine/state.h1
4 files changed, 96 insertions, 97 deletions
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index d95e228045..d49f0649c1 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -441,6 +441,17 @@ reg_t kDoAudioFade(EngineState *s, int argc, reg_t *argv);
reg_t kDoAudioHasSignal(EngineState *s, int argc, reg_t *argv);
reg_t kDoAudioSetLoop(EngineState *s, int argc, reg_t *argv);
+reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv);
+reg_t kPlayVMDOpen(EngineState *s, int argc, reg_t *argv);
+reg_t kPlayVMDInit(EngineState *s, int argc, reg_t *argv);
+reg_t kPlayVMDClose(EngineState *s, int argc, reg_t *argv);
+reg_t kPlayVMDPlayUntilEvent(EngineState *s, int argc, reg_t *argv);
+reg_t kPlayVMDShowCursor(EngineState *s, int argc, reg_t *argv);
+reg_t kPlayVMDStartBlob(EngineState *s, int argc, reg_t *argv);
+reg_t kPlayVMDStopBlobs(EngineState *s, int argc, reg_t *argv);
+reg_t kPlayVMDBlack(EngineState *s, int argc, reg_t *argv);
+reg_t kPlayVMDRestrictPalette(EngineState *s, int argc, reg_t *argv);
+
reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv);
reg_t kArray(EngineState *s, int argc, reg_t *argv);
reg_t kListAt(EngineState *s, int argc, reg_t *argv);
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index dacaafe757..6e5add15e2 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -412,6 +412,22 @@ static const SciKernelMapSubEntry kList_subops[] = {
SCI_SUBOPENTRY_TERMINATOR
};
+// There are a lot of subops to PlayVMD, but only a few of them are ever
+// actually used by games
+// version, subId, function-mapping, signature, workarounds
+static const SciKernelMapSubEntry kPlayVMD_subops[] = {
+ { SIG_SINCE_SCI21, 0, MAP_CALL(PlayVMDOpen), "r(i)(i)", NULL },
+ { SIG_SINCE_SCI21, 1, MAP_CALL(PlayVMDInit), "ii(i)(i)(ii)", NULL },
+ { SIG_SINCE_SCI21, 6, MAP_CALL(PlayVMDClose), "", NULL },
+ { SIG_SINCE_SCI21, 14, MAP_CALL(PlayVMDPlayUntilEvent), "i(i)(i)", NULL },
+ { SIG_SINCE_SCI21, 16, MAP_CALL(PlayVMDShowCursor), "i", NULL },
+ { SIG_SINCE_SCI21, 17, MAP_DUMMY(PlayVMDStartBlob), "", NULL },
+ { SIG_SINCE_SCI21, 18, MAP_DUMMY(PlayVMDStopBlobs), "", NULL },
+ { SIG_SINCE_SCI21, 21, MAP_CALL(PlayVMDBlack), "iiii", NULL },
+ { SIG_SINCE_SCI21, 23, MAP_CALL(PlayVMDRestrictPalette), "ii", NULL },
+ SCI_SUBOPENTRY_TERMINATOR
+};
+
// version, subId, function-mapping, signature, workarounds
static const SciKernelMapSubEntry kRemapColors_subops[] = {
{ SIG_SCI32, 0, MAP_CALL(RemapColorsOff), "(i)", NULL },
@@ -792,7 +808,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(IsOnMe), SIG_EVERYWHERE, "iioi", NULL, NULL },
{ MAP_CALL(List), SIG_SINCE_SCI21, SIGFOR_ALL, "(.*)", kList_subops, NULL },
{ MAP_CALL(MulDiv), SIG_EVERYWHERE, "iii", NULL, NULL },
- { MAP_CALL(PlayVMD), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+ { MAP_CALL(PlayVMD), SIG_EVERYWHERE, "(.*)", kPlayVMD_subops, NULL },
{ MAP_CALL(Robot), SIG_EVERYWHERE, "(.*)", NULL, NULL },
{ MAP_CALL(Save), SIG_EVERYWHERE, "i(.*)", kSave_subops, NULL },
{ MAP_CALL(Text), SIG_SINCE_SCI21MID, SIGFOR_ALL, "i(.*)", kText_subops, NULL },
diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp
index 8db0c542eb..aa37da6ea0 100644
--- a/engines/sci/engine/kvideo.cpp
+++ b/engines/sci/engine/kvideo.cpp
@@ -40,7 +40,8 @@
#include "video/qt_decoder.h"
#include "sci/video/seq_decoder.h"
#ifdef ENABLE_SCI32
-#include "video/coktel_decoder.h"
+#include "sci/graphics/frameout.h"
+#include "sci/graphics/video32.h"
#include "sci/video/robot_decoder.h"
#endif
@@ -289,113 +290,83 @@ reg_t kRobot(EngineState *s, int argc, reg_t *argv) {
}
reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) {
- uint16 operation = argv[0].toUint16();
- Video::VideoDecoder *videoDecoder = 0;
- bool reshowCursor = g_sci->_gfxCursor->isVisible();
- Common::String warningMsg;
-
- switch (operation) {
- case 0: // init
- s->_videoState.reset();
- s->_videoState.fileName = s->_segMan->derefString(argv[1]);
+ if (!s)
+ return make_reg(0, getSciVersion());
+ error("not supposed to call this");
+}
- if (argc > 2 && argv[2] != NULL_REG)
- warning("kPlayVMD: third parameter isn't 0 (it's %04x:%04x - %s)", PRINT_REG(argv[2]), s->_segMan->getObjectName(argv[2]));
- break;
- case 1:
- {
- // Set VMD parameters. Called with a maximum of 6 parameters:
- //
- // x, y, flags, gammaBoost, gammaFirst, gammaLast
- //
- // gammaBoost boosts palette colors in the range gammaFirst to
- // gammaLast, but only if bit 4 in flags is set. Percent value such that
- // 0% = no amplification These three parameters are optional if bit 4 is
- // clear. Also note that the x, y parameters play subtle games if used
- // with subfx 21. The subtleness has to do with creation of temporary
- // planes and positioning relative to such planes.
-
- uint16 flags = argv[3].getOffset();
- Common::String flagspec;
-
- if (argc > 3) {
- if (flags & kDoubled)
- flagspec += "doubled ";
- if (flags & kDropFrames)
- flagspec += "dropframes ";
- if (flags & kBlackLines)
- flagspec += "blacklines ";
- if (flags & kUnkBit3)
- flagspec += "bit3 ";
- if (flags & kGammaBoost)
- flagspec += "gammaboost ";
- if (flags & kHoldBlackFrame)
- flagspec += "holdblack ";
- if (flags & kHoldLastFrame)
- flagspec += "holdlast ";
- if (flags & kUnkBit7)
- flagspec += "bit7 ";
- if (flags & kStretch)
- flagspec += "stretch";
-
- warning("VMDFlags: %s", flagspec.c_str());
-
- s->_videoState.flags = flags;
- }
+reg_t kPlayVMDOpen(EngineState *s, int argc, reg_t *argv) {
+ const Common::String fileName = s->_segMan->getString(argv[0]);
+ // argv[1] is an optional cache size argument which we do not use
+ // const uint16 cacheSize = argc > 1 ? CLIP<int16>(argv[1].toSint16(), 16, 1024) : 0;
+ const VMDPlayer::OpenFlags flags = argc > 2 ? (VMDPlayer::OpenFlags)argv[2].toUint16() : VMDPlayer::kOpenFlagNone;
- warning("x, y: %d, %d", argv[1].getOffset(), argv[2].getOffset());
- s->_videoState.x = argv[1].getOffset();
- s->_videoState.y = argv[2].getOffset();
+ return make_reg(0, g_sci->_video32->getVMDPlayer().open(fileName, flags));
+}
- if (argc > 4 && flags & 16)
- warning("gammaBoost: %d%% between palette entries %d and %d", argv[4].getOffset(), argv[5].getOffset(), argv[6].getOffset());
- break;
+reg_t kPlayVMDInit(EngineState *s, int argc, reg_t *argv) {
+ const int16 x = argv[0].toSint16();
+ const int16 y = argv[1].toSint16();
+ const VMDPlayer::PlayFlags flags = argc > 2 ? (VMDPlayer::PlayFlags)argv[2].toUint16() : VMDPlayer::kPlayFlagNone;
+ int16 boostPercent;
+ int16 boostStartColor;
+ int16 boostEndColor;
+ if (argc > 5 && (flags & VMDPlayer::kPlayFlagBoost)) {
+ boostPercent = argv[3].toSint16();
+ boostStartColor = argv[4].toSint16();
+ boostEndColor = argv[5].toSint16();
+ } else {
+ boostPercent = 0;
+ boostStartColor = -1;
+ boostEndColor = -1;
}
- case 6: // Play
- videoDecoder = new Video::AdvancedVMDDecoder();
- if (s->_videoState.fileName.empty()) {
- // Happens in Lighthouse
- warning("kPlayVMD: Empty filename passed");
- return s->r_acc;
- }
+ g_sci->_video32->getVMDPlayer().init(x, y, flags, boostPercent, boostStartColor, boostEndColor);
- if (!videoDecoder->loadFile(s->_videoState.fileName)) {
- warning("Could not open VMD %s", s->_videoState.fileName.c_str());
- break;
- }
+ return make_reg(0, 0);
+}
- if (reshowCursor)
- g_sci->_gfxCursor->kernelHide();
+reg_t kPlayVMDClose(EngineState *s, int argc, reg_t *argv) {
+ return make_reg(0, g_sci->_video32->getVMDPlayer().close());
+}
- playVideo(videoDecoder, s->_videoState);
+reg_t kPlayVMDPlayUntilEvent(EngineState *s, int argc, reg_t *argv) {
+ const VMDPlayer::EventFlags flags = (VMDPlayer::EventFlags)argv[0].toUint16();
+ const int16 lastFrameNo = argc > 1 ? argv[1].toSint16() : -1;
+ const int16 yieldInterval = argc > 2 ? argv[2].toSint16() : -1;
+ return make_reg(0, g_sci->_video32->getVMDPlayer().kernelPlayUntilEvent(flags, lastFrameNo, yieldInterval));
+}
- if (reshowCursor)
- g_sci->_gfxCursor->kernelShow();
- break;
- case 23: // set video palette range
- s->_vmdPalStart = argv[1].toUint16();
- s->_vmdPalEnd = argv[2].toUint16();
- break;
- case 14:
- // Takes an additional integer parameter (e.g. 3)
- case 16:
- // Takes an additional parameter, usually 0
- case 21:
- // Looks to be setting the video size and position. Called with 4 extra integer
- // parameters (e.g. 86, 41, 235, 106)
- default:
- warningMsg = Common::String::format("PlayVMD - unsupported subop %d. Params: %d (", operation, argc);
+reg_t kPlayVMDShowCursor(EngineState *s, int argc, reg_t *argv) {
+ g_sci->_video32->getVMDPlayer().setShowCursor((bool)argv[0].toUint16());
+ return s->r_acc;
+}
- for (int i = 0; i < argc; i++) {
- warningMsg += Common::String::format("%04x:%04x", PRINT_REG(argv[i]));
- warningMsg += (i == argc - 1 ? ")" : ", ");
- }
+reg_t kPlayVMDStartBlob(EngineState *s, int argc, reg_t *argv) {
+ debug("kPlayVMDStartBlob");
+ return s->r_acc;
+}
- warning("%s", warningMsg.c_str());
- break;
- }
+reg_t kPlayVMDStopBlobs(EngineState *s, int argc, reg_t *argv) {
+ debug("kPlayVMDStopBlobs");
+ return s->r_acc;
+}
+
+reg_t kPlayVMDBlack(EngineState *s, int argc, reg_t *argv) {
+ const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
+ const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+
+ Common::Rect blackoutArea;
+ blackoutArea.left = MAX((int16)0, argv[0].toSint16());
+ blackoutArea.top = MAX((int16)0, argv[1].toSint16());
+ blackoutArea.right = MIN(scriptWidth, (int16)(argv[2].toSint16() + 1));
+ blackoutArea.bottom = MIN(scriptHeight, (int16)(argv[3].toSint16() + 1));
+ g_sci->_video32->getVMDPlayer().setBlackoutArea(blackoutArea);
+ return s->r_acc;
+}
+reg_t kPlayVMDRestrictPalette(EngineState *s, int argc, reg_t *argv) {
+ g_sci->_video32->getVMDPlayer().restrictPalette(argv[0].toUint16(), argv[1].toUint16());
return s->r_acc;
}
diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h
index baca4a503b..dd8d76f002 100644
--- a/engines/sci/engine/state.h
+++ b/engines/sci/engine/state.h
@@ -201,6 +201,7 @@ public:
uint16 _memorySegmentSize;
byte _memorySegment[kMemorySegmentMax];
+ // TODO: Excise video code from the state manager
VideoState _videoState;
uint16 _vmdPalStart, _vmdPalEnd;
bool _syncedAudioOptions;