aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/kernel.h11
-rw-r--r--engines/sci/engine/kernel_tables.h29
-rw-r--r--engines/sci/engine/kmisc.cpp16
-rw-r--r--engines/sci/engine/kvideo.cpp166
-rw-r--r--engines/sci/engine/vm.cpp15
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--;