From cd69472be91fc33637db8063bf0e025fa4dba5e4 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sun, 21 Nov 2010 00:47:56 +0000 Subject: SCI: Adapted kArray/kString to use the new heuristic for late SCI2.1/SCI3 games, and updated their subops accordingly svn-id: r54399 --- engines/sci/engine/klists.cpp | 47 +++++++++++++++++++++++++++--------------- engines/sci/engine/kstring.cpp | 28 +++++++++++++++++-------- 2 files changed, 49 insertions(+), 26 deletions(-) (limited to 'engines/sci/engine') diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp index a0c9891731..5fb2d587ba 100644 --- a/engines/sci/engine/klists.cpp +++ b/engines/sci/engine/klists.cpp @@ -23,6 +23,7 @@ * */ +#include "sci/engine/features.h" #include "sci/engine/state.h" #include "sci/engine/selector.h" #include "sci/engine/kernel.h" @@ -618,6 +619,8 @@ reg_t kMoveToEnd(EngineState *s, int argc, reg_t *argv) { } reg_t kArray(EngineState *s, int argc, reg_t *argv) { + uint16 op = argv[0].toUint16(); + // Use kString when accessing strings // This is possible, as strings inherit from arrays // and in this case (type 3) arrays are of type char *. @@ -626,17 +629,24 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) { // TODO: we need to either merge SCI2 strings and // arrays together, and in the future merge them with // the SCI1 strings and arrays in the segment manager - if (argv[0].toUint16() == 0) { + if (op == 0) { // New, check if the target type is 3 (string) if (argv[2].toUint16() == 3) return kString(s, argc, argv); } else { if (s->_segMan->getSegmentType(argv[1].segment) == SEG_TYPE_STRING || - s->_segMan->getSegmentType(argv[1].segment) == SEG_TYPE_SYS_STRINGS) + s->_segMan->getSegmentType(argv[1].segment) == SEG_TYPE_SYS_STRINGS || + s->_segMan->getSegmentType(argv[1].segment) == SEG_TYPE_SCRIPT) { return kString(s, argc, argv); + } + } + + if (g_sci->_features->detectSci2StringFunctionType() == kSci2StringFunctionNew) { + if (op >= 6) // Cpy, Cmp have been removed + op += 2; } - switch (argv[0].toUint16()) { + switch (op) { case 0: { // New reg_t arrayHandle; SciArray *array = s->_segMan->allocateArray(&arrayHandle); @@ -693,16 +703,6 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) { warning("kArray(Cpy): Request to copy from or to a null pointer"); return NULL_REG; } - -#if 0 - if (s->_segMan->getSegmentObj(argv[1].segment)->getType() != SEG_TYPE_ARRAY || - s->_segMan->getSegmentObj(argv[3].segment)->getType() != SEG_TYPE_ARRAY) { - // Happens in the RAMA demo - warning("kArray(Cpy): Request to copy a segment which isn't an array, ignoring"); - return NULL_REG; - } -#endif - SciArray *array1 = s->_segMan->lookupArray(argv[1]); SciArray *array2 = s->_segMan->lookupArray(argv[3]); uint32 index1 = argv[2].toUint16(); @@ -730,9 +730,16 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) { case 8: { // Dup if (argv[1].isNull()) { warning("kArray(Dup): Request to duplicate a null pointer"); +#if 0 + // Allocate an array anyway + reg_t arrayHandle; + SciArray *dupArray = s->_segMan->allocateArray(&arrayHandle); + dupArray->setType(3); + dupArray->setSize(0); + return arrayHandle; +#endif return NULL_REG; } - SegmentType sourceType = s->_segMan->getSegmentObj(argv[1].segment)->getType(); if (sourceType == SEG_TYPE_SCRIPT) { // A technique used in later SCI2.1 and SCI3 games: the contents of a script @@ -746,8 +753,7 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) { return stringHandle; } else if (sourceType != SEG_TYPE_ARRAY && sourceType != SEG_TYPE_SCRIPT) { - warning("kArray(Dup): Request to duplicate a segment which isn't an array or a script, ignoring"); - return NULL_REG; + error("kArray(Dup): Request to duplicate a segment which isn't an array or a script"); } reg_t arrayHandle; @@ -770,8 +776,15 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) { return argv[1]; return readSelector(s->_segMan, argv[1], SELECTOR(data)); + // New subops in SCI2.1 late / SCI3 + case 10: // unknown + warning("kArray, subop %d", op); + return NULL_REG; + case 11: // unknown + warning("kArray, subop %d", op); + return NULL_REG; default: - error("Unknown kArray subop %d", argv[0].toUint16()); + error("Unknown kArray subop %d", op); } return NULL_REG; diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index a8924bd2b1..2575dd10e7 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -26,6 +26,7 @@ /* String and parser handling */ #include "sci/resource.h" +#include "sci/engine/features.h" #include "sci/engine/state.h" #include "sci/engine/message.h" #include "sci/engine/selector.h" @@ -616,16 +617,14 @@ reg_t kText(EngineState *s, int argc, reg_t *argv) { } reg_t kString(EngineState *s, int argc, reg_t *argv) { + uint16 op = argv[0].toUint16(); - // TODO: Find out how exactly subfunctions work in SCI3 - if (getSciVersion() == SCI_VERSION_3 && - argv[0].toUint16() == 8) - argv[0].offset = 10; - if (getSciVersion() == SCI_VERSION_3 && - argv[0].toUint16() == 11) - argv[0].offset = 13; + if (g_sci->_features->detectSci2StringFunctionType() == kSci2StringFunctionNew) { + if (op >= 7) // Cpy, Cmp have been removed + op += 2; + } - switch (argv[0].toUint16()) { + switch (op) { case 0: { // New reg_t stringHandle; SciString *string = s->_segMan->allocateString(&stringHandle); @@ -789,7 +788,18 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) { Common::String string = s->_segMan->getString(argv[1]); return make_reg(0, (uint16)atoi(string.c_str())); } - case 14: { // lower (SCI3) + // New subops in SCI2.1 late / SCI3 + case 14: // unknown + warning("kString, subop %d", op); + return NULL_REG; + case 15: { // upper + Common::String string = s->_segMan->getString(argv[1]); + + string.toUppercase(); + s->_segMan->strcpy(argv[1], string.c_str()); + return NULL_REG; + } + case 16: { // lower Common::String string = s->_segMan->getString(argv[1]); string.toLowercase(); -- cgit v1.2.3