diff options
author | Colin Snover | 2016-07-02 19:11:46 -0500 |
---|---|---|
committer | Colin Snover | 2016-07-10 09:35:24 -0500 |
commit | 4d91b458e53ebda8726055d338da12c05a7879ea (patch) | |
tree | caaaf88c74cb0009f88b5c5390b7a138892cb376 /engines/sci/engine | |
parent | 28d4f5b0e48780dbbee3343d3d41fdd79340a3f4 (diff) | |
download | scummvm-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.h | 11 | ||||
-rw-r--r-- | engines/sci/engine/kernel_tables.h | 18 | ||||
-rw-r--r-- | engines/sci/engine/kvideo.cpp | 163 | ||||
-rw-r--r-- | engines/sci/engine/state.h | 1 |
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; |