diff options
Diffstat (limited to 'engines/sci/engine/kmisc.cpp')
-rw-r--r-- | engines/sci/engine/kmisc.cpp | 147 |
1 files changed, 108 insertions, 39 deletions
diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index f4bb4ff85b..9aa03a4760 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -20,6 +20,7 @@ * */ +#include "common/config-manager.h" #include "common/system.h" #include "sci/sci.h" @@ -29,6 +30,9 @@ #include "sci/engine/kernel.h" #include "sci/engine/gc.h" #include "sci/graphics/cursor.h" +#ifdef ENABLE_SCI32 +#include "sci/graphics/cursor32.h" +#endif #include "sci/graphics/maciconbar.h" #include "sci/console.h" @@ -243,10 +247,18 @@ reg_t kGetTime(EngineState *s, int argc, reg_t *argv) { debugC(kDebugLevelTime, "GetTime(24h) returns %d", retval); break; case KGETTIME_DATE : - // Year since 1980 (0 = 1980, 1 = 1981, etc.) - retval = loc_time.tm_mday | ((loc_time.tm_mon + 1) << 5) | (((loc_time.tm_year - 80) & 0x7f) << 9); + { + // SCI0 late: Year since 1920 (0 = 1920, 1 = 1921, etc) + // SCI01 and newer: Year since 1980 (0 = 1980, 1 = 1981, etc) + // Atari ST SCI0 late versions use the newer base year. + int baseYear = 80; + if (getSciVersion() == SCI_VERSION_0_LATE && g_sci->getPlatform() == Common::kPlatformDOS) { + baseYear = 20; + } + retval = loc_time.tm_mday | ((loc_time.tm_mon + 1) << 5) | (((loc_time.tm_year - baseYear) & 0x7f) << 9); debugC(kDebugLevelTime, "GetTime(date) returns %d", retval); break; + } default: error("Attempt to use unknown GetTime mode %d", mode); break; @@ -401,6 +413,15 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) { } else if (setting == "startroom") { // Debug setting in LSL7, specifies the room to start from. s->_segMan->strcpy(data, ""); + } else if (setting == "game") { + // Hoyle 5 startup, specifies the number of the game to start. + s->_segMan->strcpy(data, ""); + } else if (setting == "laptop") { + // Hoyle 5 startup. + s->_segMan->strcpy(data, ""); + } else if (setting == "jumpto") { + // Hoyle 5 startup. + s->_segMan->strcpy(data, ""); } else { error("GetConfig: Unknown configuration setting %s", setting.c_str()); } @@ -438,6 +459,14 @@ reg_t kGetWindowsOption(EngineState *s, int argc, reg_t *argv) { } } +extern Common::String format(const Common::String &source, int argc, const reg_t *argv); + +reg_t kPrintDebug(EngineState *s, int argc, reg_t *argv) { + const Common::String debugString = s->_segMan->getString(argv[0]); + debugC(kDebugLevelGame, "%s", format(debugString, argc - 1, argv + 1).c_str()); + return s->r_acc; +} + #endif // kIconBar is really a subop of kMacPlatform for SCI1.1 Mac @@ -493,9 +522,12 @@ reg_t kMacPlatform(EngineState *s, int argc, reg_t *argv) { // In SCI1, its usage is still unknown // In SCI1.1, it's NOP // In SCI32, it's used for remapping cursor ID's +#ifdef ENABLE_SCI32 if (getSciVersion() >= SCI_VERSION_2_1_EARLY) // Set Mac cursor remap - g_sci->_gfxCursor->setMacCursorRemapList(argc - 1, argv + 1); - else if (getSciVersion() != SCI_VERSION_1_1) + g_sci->_gfxCursor32->setMacCursorRemapList(argc - 1, argv + 1); + else +#endif + if (getSciVersion() != SCI_VERSION_1_1) warning("Unknown SCI1 kMacPlatform(0) call"); break; case 4: // Handle icon bar code @@ -518,31 +550,28 @@ reg_t kMacPlatform(EngineState *s, int argc, reg_t *argv) { } enum kSciPlatforms { + kSciPlatformMacintosh = 0, kSciPlatformDOS = 1, kSciPlatformWindows = 2 }; -enum kPlatformOps { - kPlatformUnk0 = 0, - kPlatformCDSpeed = 1, - kPlatformUnk2 = 2, - kPlatformCDCheck = 3, - kPlatformGetPlatform = 4, - kPlatformUnk5 = 5, - kPlatformIsHiRes = 6, - kPlatformIsItWindows = 7 -}; - reg_t kPlatform(EngineState *s, int argc, reg_t *argv) { + enum Operation { + kPlatformUnknown = 0, + kPlatformGetPlatform = 4, + kPlatformUnknown5 = 5, + kPlatformIsHiRes = 6, + kPlatformWin311OrHigher = 7 + }; + bool isWindows = g_sci->getPlatform() == Common::kPlatformWindows; - if (argc == 0 && getSciVersion() < SCI_VERSION_2) { + if (argc == 0) { // This is called in KQ5CD with no parameters, where it seems to do some // graphics driver check. This kernel function didn't have subfunctions // then. If 0 is returned, the game functions normally, otherwise all // the animations show up like a slideshow (e.g. in the intro). So we - // return 0. However, the behavior changed for kPlatform with no - // parameters in SCI32. + // return 0. return NULL_REG; } @@ -554,30 +583,23 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv) { uint16 operation = (argc == 0) ? 0 : argv[0].toUint16(); switch (operation) { - case kPlatformCDSpeed: - // TODO: Returns CD Speed? - warning("STUB: kPlatform(CDSpeed)"); - break; - case kPlatformUnk2: - // Always returns 2 - return make_reg(0, 2); - case kPlatformCDCheck: - // TODO: Some sort of CD check? - warning("STUB: kPlatform(CDCheck)"); - break; - case kPlatformUnk0: + case kPlatformUnknown: // For Mac versions, kPlatform(0) with other args has more functionality if (g_sci->getPlatform() == Common::kPlatformMacintosh && argc > 1) return kMacPlatform(s, argc - 1, argv + 1); // Otherwise, fall through case kPlatformGetPlatform: - return make_reg(0, (isWindows) ? kSciPlatformWindows : kSciPlatformDOS); - case kPlatformUnk5: + if (isWindows) + return make_reg(0, kSciPlatformWindows); + else if (g_sci->getPlatform() == Common::kPlatformMacintosh) + return make_reg(0, kSciPlatformMacintosh); + else + return make_reg(0, kSciPlatformDOS); + case kPlatformUnknown5: // This case needs to return the opposite of case 6 to get hires graphics return make_reg(0, !isWindows); case kPlatformIsHiRes: - return make_reg(0, isWindows); - case kPlatformIsItWindows: + case kPlatformWin311OrHigher: return make_reg(0, isWindows); default: error("Unsupported kPlatform operation %d", operation); @@ -586,6 +608,43 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv) { return NULL_REG; } +#ifdef ENABLE_SCI32 +reg_t kPlatform32(EngineState *s, int argc, reg_t *argv) { + enum Operation { + kGetPlatform = 0, + kGetCDSpeed = 1, + kGetColorDepth = 2, + kGetCDDrive = 3 + }; + + const Operation operation = argc > 0 ? (Operation)argv[0].toSint16() : kGetPlatform; + + switch (operation) { + case kGetPlatform: + switch (g_sci->getPlatform()) { + case Common::kPlatformDOS: + return make_reg(0, kSciPlatformDOS); + case Common::kPlatformWindows: + return make_reg(0, kSciPlatformWindows); + case Common::kPlatformMacintosh: + // For Mac versions, kPlatform(0) with other args has more functionality + if (argc > 1) + return kMacPlatform(s, argc - 1, argv + 1); + else + return make_reg(0, kSciPlatformMacintosh); + default: + error("Unknown platform %d", g_sci->getPlatform()); + } + case kGetColorDepth: + return make_reg(0, /* 256 color */ 2); + case kGetCDSpeed: + case kGetCDDrive: + default: + return make_reg(0, 0); + } +} +#endif + reg_t kEmpty(EngineState *s, int argc, reg_t *argv) { // Placeholder for empty kernel functions which are still called from the // engine scripts (like the empty kSetSynonyms function in SCI1.1). This @@ -597,18 +656,28 @@ reg_t kEmpty(EngineState *s, int argc, reg_t *argv) { reg_t kStub(EngineState *s, int argc, reg_t *argv) { Kernel *kernel = g_sci->getKernel(); int kernelCallNr = -1; + int kernelSubCallNr = -1; Common::List<ExecStack>::const_iterator callIterator = s->_executionStack.end(); if (callIterator != s->_executionStack.begin()) { callIterator--; ExecStack lastCall = *callIterator; - kernelCallNr = lastCall.debugSelector; + kernelCallNr = lastCall.debugKernelFunction; + kernelSubCallNr = lastCall.debugKernelSubFunction; + } + + Common::String warningMsg; + if (kernelSubCallNr == -1) { + warningMsg = "Dummy function k" + kernel->getKernelName(kernelCallNr) + + Common::String::format("[%x]", kernelCallNr); + } else { + warningMsg = "Dummy function k" + kernel->getKernelName(kernelCallNr, kernelSubCallNr) + + Common::String::format("[%x:%x]", kernelCallNr, kernelSubCallNr); + } - Common::String warningMsg = "Dummy function k" + kernel->getKernelName(kernelCallNr) + - Common::String::format("[%x]", kernelCallNr) + - " invoked. Params: " + - Common::String::format("%d", argc) + " ("; + warningMsg += " invoked. Params: " + + Common::String::format("%d", argc) + " ("; for (int i = 0; i < argc; i++) { warningMsg += Common::String::format("%04x:%04x", PRINT_REG(argv[i])); |