diff options
Diffstat (limited to 'engines/sci/engine')
-rw-r--r-- | engines/sci/engine/kernel.h | 11 | ||||
-rw-r--r-- | engines/sci/engine/kernel_tables.h | 29 | ||||
-rw-r--r-- | engines/sci/engine/kmisc.cpp | 16 | ||||
-rw-r--r-- | engines/sci/engine/kvideo.cpp | 166 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 15 |
5 files changed, 84 insertions, 153 deletions
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index b02a7e545a..5ff4f932be 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -450,17 +450,6 @@ reg_t kPlayVMDShowCursor(EngineState *s, int argc, reg_t *argv); reg_t kPlayVMDSetBlackoutArea(EngineState *s, int argc, reg_t *argv); reg_t kPlayVMDRestrictPalette(EngineState *s, int argc, reg_t *argv); -reg_t kShowMovie32(EngineState *s, int argc, reg_t *argv); -reg_t kShowMovieWin(EngineState *s, int argc, reg_t *argv); -reg_t kShowMovieWinOpen(EngineState *s, int argc, reg_t *argv); -reg_t kShowMovieWinInit(EngineState *s, int argc, reg_t *argv); -reg_t kShowMovieWinPlay(EngineState *s, int argc, reg_t *argv); -reg_t kShowMovieWinClose(EngineState *s, int argc, reg_t *argv); -reg_t kShowMovieWinCue(EngineState *s, int argc, reg_t *argv); -reg_t kShowMovieWinGetDuration(EngineState *s, int argc, reg_t *argv); -reg_t kShowMovieWinPlayUntilEvent(EngineState *s, int argc, reg_t *argv); -reg_t kShowMovieWinInitDouble(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 76c24b09e3..e0e4dcc233 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -423,27 +423,6 @@ static const SciKernelMapSubEntry kList_subops[] = { SCI_SUBOPENTRY_TERMINATOR }; -// version, subId, function-mapping, signature, workarounds -static const SciKernelMapSubEntry kShowMovieWin_subops[] = { - { SIG_SCI2, 0, MAP_CALL(ShowMovieWinOpen), "r", NULL }, - { SIG_SCI2, 1, MAP_CALL(ShowMovieWinInit), "ii(ii)", NULL }, - { SIG_SCI2, 2, MAP_CALL(ShowMovieWinPlay), "i", NULL }, - { SIG_SCI2, 6, MAP_CALL(ShowMovieWinClose), "", NULL }, - { SIG_SINCE_SCI21, 0, MAP_CALL(ShowMovieWinOpen), "ir", NULL }, - { SIG_SINCE_SCI21, 1, MAP_CALL(ShowMovieWinInit), "iii(ii)", NULL }, - { SIG_SINCE_SCI21, 2, MAP_CALL(ShowMovieWinPlay), "i(ii)(i)(i)", NULL }, - { SIG_SINCE_SCI21, 6, MAP_CALL(ShowMovieWinClose), "i", NULL }, - // Since movies are rendered within the graphics engine in ScummVM, - // it is not necessary to copy the palette from SCI to MCI, so this - // can be a no-op - { SIG_SINCE_SCI21, 7, MAP_EMPTY(ShowMovieWinSetPalette), "i", NULL }, - { SIG_SINCE_SCI21, 8, MAP_CALL(ShowMovieWinGetDuration), "i", NULL }, - { SIG_SINCE_SCI21, 11, MAP_CALL(ShowMovieWinCue), "ii", NULL }, - { SIG_SINCE_SCI21, 14, MAP_CALL(ShowMovieWinPlayUntilEvent), "i(i)", NULL }, - { SIG_SINCE_SCI21, 15, MAP_CALL(ShowMovieWinInitDouble), "iii", NULL }, - 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 @@ -709,11 +688,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(SetSynonyms), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(SetVideoMode), SIG_EVERYWHERE, "i", NULL, NULL }, { MAP_CALL(ShakeScreen), SIG_EVERYWHERE, "(i)(i)", NULL, NULL }, - { MAP_CALL(ShowMovie), SIG_SCI16, SIGFOR_ALL, "(.*)", NULL, NULL }, -#ifdef ENABLE_SCI32 - { "ShowMovie", kShowMovie32, SIG_SCI32, SIGFOR_DOS, "ri(i)(i)", NULL, NULL }, - { "ShowMovie", kShowMovieWin, SIG_SCI32, SIGFOR_WIN, "(.*)", kShowMovieWin_subops, NULL }, -#endif + { MAP_CALL(ShowMovie), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_CALL(Show), SIG_EVERYWHERE, "i", NULL, NULL }, { MAP_CALL(SinDiv), SIG_EVERYWHERE, "ii", NULL, NULL }, { MAP_CALL(Sort), SIG_EVERYWHERE, "ooo", NULL, NULL }, @@ -845,7 +820,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(List), SIG_SINCE_SCI21, SIGFOR_ALL, "(.*)", kList_subops, NULL }, { MAP_CALL(MulDiv), SIG_EVERYWHERE, "iii", NULL, NULL }, { MAP_CALL(PlayVMD), SIG_EVERYWHERE, "(.*)", kPlayVMD_subops, NULL }, - { MAP_EMPTY(Robot), SIG_EVERYWHERE, "(.*)", NULL, 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 }, { MAP_CALL(AddPicAt), SIG_EVERYWHERE, "oiii(i)(i)", NULL, NULL }, diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index c99540967c..1924848717 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -20,7 +20,6 @@ * */ -#include "common/config-manager.h" #include "common/system.h" #include "sci/sci.h" @@ -543,7 +542,7 @@ enum kSciPlatforms { enum kPlatformOps { kPlatformUnk0 = 0, kPlatformCDSpeed = 1, - kPlatformColorDepth = 2, + kPlatformUnk2 = 2, kPlatformCDCheck = 3, kPlatformGetPlatform = 4, kPlatformUnk5 = 5, @@ -564,6 +563,11 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv) { return NULL_REG; } + if (g_sci->forceHiresGraphics()) { + // force Windows platform, so that hires-graphics are enabled + isWindows = true; + } + uint16 operation = (argc == 0) ? 0 : argv[0].toUint16(); switch (operation) { @@ -571,9 +575,9 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv) { // TODO: Returns CD Speed? warning("STUB: kPlatform(CDSpeed)"); break; - case kPlatformColorDepth: + case kPlatformUnk2: // Always returns 2 - return make_reg(0, /* 256-color */ 2); + return make_reg(0, 2); case kPlatformCDCheck: // TODO: Some sort of CD check? warning("STUB: kPlatform(CDCheck)"); @@ -587,9 +591,9 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv) { return make_reg(0, (isWindows) ? kSciPlatformWindows : kSciPlatformDOS); case kPlatformUnk5: // This case needs to return the opposite of case 6 to get hires graphics - return make_reg(0, !ConfMan.getBool("enable_high_resolution_graphics")); + return make_reg(0, !isWindows); case kPlatformIsHiRes: - return make_reg(0, ConfMan.getBool("enable_high_resolution_graphics")); + return make_reg(0, isWindows); case kPlatformIsItWindows: return make_reg(0, isWindows); default: diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp index 86d8a4b817..de4d4a282c 100644 --- a/engines/sci/engine/kvideo.cpp +++ b/engines/sci/engine/kvideo.cpp @@ -61,15 +61,33 @@ void playVideo(Video::VideoDecoder *videoDecoder, VideoState videoState) { uint16 screenWidth = g_sci->_gfxScreen->getDisplayWidth(); uint16 screenHeight = g_sci->_gfxScreen->getDisplayHeight(); - if (screenWidth == 640 && width <= 320 && height <= 240) { + videoState.fileName.toLowercase(); + bool isVMD = videoState.fileName.hasSuffix(".vmd"); + + if (screenWidth == 640 && width <= 320 && height <= 240 && ((videoState.flags & kDoubled) || !isVMD)) { width *= 2; height *= 2; pitch *= 2; scaleBuffer = new byte[width * height * bytesPerPixel]; } - uint16 x = (screenWidth - width) / 2; - uint16 y = (screenHeight - height) / 2; + uint16 x, y; + + // Sanity check... + if (videoState.x > 0 && videoState.y > 0 && isVMD) { + x = videoState.x; + y = videoState.y; + + if (x + width > screenWidth || y + height > screenHeight) { + // Happens in the Lighthouse demo + warning("VMD video won't fit on screen, centering it instead"); + x = (screenWidth - width) / 2; + y = (screenHeight - height) / 2; + } + } else { + x = (screenWidth - width) / 2; + y = (screenHeight - height) / 2; + } bool skipVideo = false; EngineState *s = g_sci->getEngineState(); @@ -163,6 +181,16 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) { // TODO: This appears to be some sort of subop. case 0 contains the string // for the video, so we'll just play it from there for now. +#ifdef ENABLE_SCI32 + if (getSciVersion() >= SCI_VERSION_2_1_EARLY) { + // SCI2.1 always has argv[0] as 1, the rest of the arguments seem to + // follow SCI1.1/2. + if (argv[0].toUint16() != 1) + error("SCI2.1 kShowMovie argv[0] not 1"); + argv++; + argc--; + } +#endif switch (argv[0].toUint16()) { case 0: { Common::String filename = s->_segMan->getString(argv[1]); @@ -215,100 +243,50 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) { } #ifdef ENABLE_SCI32 -reg_t kShowMovie32(EngineState *s, int argc, reg_t *argv) { - Common::String fileName = s->_segMan->getString(argv[0]); - const int16 numTicks = argv[1].toSint16(); - const int16 x = argc > 3 ? argv[2].toSint16() : 0; - const int16 y = argc > 3 ? argv[3].toSint16() : 0; - - g_sci->_video32->getSEQPlayer().play(fileName, numTicks, x, y); - - return s->r_acc; -} - -reg_t kShowMovieWin(EngineState *s, int argc, reg_t *argv) { - if (!s) - return make_reg(0, getSciVersion()); - error("not supposed to call this"); -} - -reg_t kShowMovieWinOpen(EngineState *s, int argc, reg_t *argv) { - // SCI2.1 adds a movie ID to the call, but the movie ID is broken, - // so just ignore it - if (getSciVersion() > SCI_VERSION_2) { - ++argv; - --argc; - } - - const Common::String fileName = s->_segMan->getString(argv[0]); - return make_reg(0, g_sci->_video32->getAVIPlayer().open(fileName)); -} - -reg_t kShowMovieWinInit(EngineState *s, int argc, reg_t *argv) { - // SCI2.1 adds a movie ID to the call, but the movie ID is broken, - // so just ignore it - if (getSciVersion() > SCI_VERSION_2) { - ++argv; - --argc; - } - - const int16 x = argv[0].toSint16(); - const int16 y = argv[1].toSint16(); - const int16 width = argc > 3 ? argv[2].toSint16() : 0; - const int16 height = argc > 3 ? argv[3].toSint16() : 0; - return make_reg(0, g_sci->_video32->getAVIPlayer().init1x(x, y, width, height)); -} - -reg_t kShowMovieWinPlay(EngineState *s, int argc, reg_t *argv) { - if (getSciVersion() == SCI_VERSION_2) { - AVIPlayer::EventFlags flags = (AVIPlayer::EventFlags)argv[0].toUint16(); - return make_reg(0, g_sci->_video32->getAVIPlayer().playUntilEvent(flags)); - } else { - // argv[0] is a broken movie ID - const int16 from = argc > 2 ? argv[1].toSint16() : 0; - const int16 to = argc > 2 ? argv[2].toSint16() : 0; - const int16 showStyle = argc > 3 ? argv[3].toSint16() : 0; - const bool cue = argc > 4 ? (bool)argv[4].toSint16() : false; - return make_reg(0, g_sci->_video32->getAVIPlayer().play(from, to, showStyle, cue)); - } -} - -reg_t kShowMovieWinClose(EngineState *s, int argc, reg_t *argv) { - return make_reg(0, g_sci->_video32->getAVIPlayer().close()); -} - -reg_t kShowMovieWinGetDuration(EngineState *s, int argc, reg_t *argv) { - return make_reg(0, g_sci->_video32->getAVIPlayer().getDuration()); -} -reg_t kShowMovieWinCue(EngineState *s, int argc, reg_t *argv) { - // SCI2.1 adds a movie ID to the call, but the movie ID is broken, - // so just ignore it - if (getSciVersion() > SCI_VERSION_2) { - ++argv; - --argc; +reg_t kRobot(EngineState *s, int argc, reg_t *argv) { + int16 subop = argv[0].toUint16(); + + switch (subop) { + case 0: { // init + int id = argv[1].toUint16(); + reg_t obj = argv[2]; + int16 flag = argv[3].toSint16(); + int16 x = argv[4].toUint16(); + int16 y = argv[5].toUint16(); + warning("kRobot(init), id %d, obj %04x:%04x, flag %d, x=%d, y=%d", id, PRINT_REG(obj), flag, x, y); + g_sci->_robotDecoder->load(id); + g_sci->_robotDecoder->start(); + g_sci->_robotDecoder->setPos(x, y); + } + break; + case 1: // LSL6 hires (startup) + // TODO + return NULL_REG; // an integer is expected + case 4: { // start - we don't really have a use for this one + //int id = argv[1].toUint16(); + //warning("kRobot(start), id %d", id); + } + break; + case 7: // unknown, called e.g. by Phantasmagoria + warning("kRobot(%d)", subop); + break; + case 8: // sync + //if (true) { // debug: automatically skip all robot videos + if (g_sci->_robotDecoder->endOfVideo()) { + g_sci->_robotDecoder->close(); + // Signal the engine scripts that the video is done + writeSelector(s->_segMan, argv[1], SELECTOR(signal), SIGNAL_REG); + } else { + writeSelector(s->_segMan, argv[1], SELECTOR(signal), NULL_REG); + } + break; + default: + warning("kRobot(%d)", subop); + break; } - const uint16 frameNo = argv[0].toUint16(); - return make_reg(0, g_sci->_video32->getAVIPlayer().cue(frameNo)); -} - -reg_t kShowMovieWinPlayUntilEvent(EngineState *s, int argc, reg_t *argv) { - const int defaultFlags = - AVIPlayer::kEventFlagEnd | - AVIPlayer::kEventFlagEscapeKey; - - // argv[0] is the movie number, which is not used by this method - const AVIPlayer::EventFlags flags = (AVIPlayer::EventFlags)(argc > 1 ? argv[1].toUint16() : defaultFlags); - - return make_reg(0, g_sci->_video32->getAVIPlayer().playUntilEvent(flags)); -} - -reg_t kShowMovieWinInitDouble(EngineState *s, int argc, reg_t *argv) { - // argv[0] is a broken movie ID - const int16 x = argv[1].toSint16(); - const int16 y = argv[2].toSint16(); - return make_reg(0, g_sci->_video32->getAVIPlayer().init2x(x, y)); + return s->r_acc; } reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) { diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 548fd477bf..3e12084ed6 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -405,21 +405,6 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) { error("[VM] k%s[%x]: no subfunction ID parameter given", kernelCall.name, kernelCallNr); if (argv[0].isPointer()) error("[VM] k%s[%x]: given subfunction ID is actually a pointer", kernelCall.name, kernelCallNr); - -#ifdef ENABLE_SCI32 - // The Windows version of kShowMovie has subops, but the subop number - // is put in the second parameter in SCI2.1+, even though every other - // kcall with subops puts the subop in the first parameter. To allow use - // of the normal subops system, we swap the arguments so the subop - // number is in the usual place. - if (getSciVersion() > SCI_VERSION_2 && - g_sci->getPlatform() == Common::kPlatformWindows && - strcmp(kernelCall.name, "ShowMovie") == 0) { - assert(argc > 1); - SWAP(argv[0], argv[1]); - } -#endif - const uint16 subId = argv[0].toUint16(); // Skip over subfunction-id argc--; |