diff options
| author | Martin Kiewitz | 2015-12-29 01:44:11 +0100 | 
|---|---|---|
| committer | Martin Kiewitz | 2015-12-29 01:44:11 +0100 | 
| commit | 0dd760724e37b70bfaade2c34c12e34fab4d4b71 (patch) | |
| tree | f44a01f75f84d65db8e2b737742085db9f878899 /engines/sci/engine | |
| parent | 00e0d68a9f4b85ac66f757dd8603036b82a566e6 (diff) | |
| download | scummvm-rg350-0dd760724e37b70bfaade2c34c12e34fab4d4b71.tar.gz scummvm-rg350-0dd760724e37b70bfaade2c34c12e34fab4d4b71.tar.bz2 scummvm-rg350-0dd760724e37b70bfaade2c34c12e34fab4d4b71.zip  | |
SCI32: split up SCI2.1 into EARLY/MIDDLE/LATE
- Detection works via signatures (couldn't find a better way)
- new kString subcalls were introduced SCI2.1 LATE
- kString now has signatures and is split via subcall table
- kString fix, so that KQ7 doesn't crash, when starting a chapter
- Sci2StringFunctionType removed, because no longer needed
Diffstat (limited to 'engines/sci/engine')
| -rw-r--r-- | engines/sci/engine/features.cpp | 70 | ||||
| -rw-r--r-- | engines/sci/engine/features.h | 15 | ||||
| -rw-r--r-- | engines/sci/engine/kernel.cpp | 6 | ||||
| -rw-r--r-- | engines/sci/engine/kernel.h | 21 | ||||
| -rw-r--r-- | engines/sci/engine/kernel_tables.h | 111 | ||||
| -rw-r--r-- | engines/sci/engine/kevent.cpp | 4 | ||||
| -rw-r--r-- | engines/sci/engine/kmisc.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/kscripts.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/ksound.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/kstring.cpp | 341 | ||||
| -rw-r--r-- | engines/sci/engine/kvideo.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/message.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/object.cpp | 8 | ||||
| -rw-r--r-- | engines/sci/engine/object.h | 22 | ||||
| -rw-r--r-- | engines/sci/engine/savegame.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/script.cpp | 18 | ||||
| -rw-r--r-- | engines/sci/engine/static_selectors.cpp | 18 | ||||
| -rw-r--r-- | engines/sci/engine/vm_types.cpp | 8 | 
18 files changed, 348 insertions, 306 deletions
diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp index be062dba64..a993506f7a 100644 --- a/engines/sci/engine/features.cpp +++ b/engines/sci/engine/features.cpp @@ -40,7 +40,6 @@ GameFeatures::GameFeatures(SegManager *segMan, Kernel *kernel) : _segMan(segMan)  	_moveCountType = kMoveCountUninitialized;  #ifdef ENABLE_SCI32  	_sci21KernelType = SCI_VERSION_NONE; -	_sci2StringFunctionType = kSci2StringFunctionUninitialized;  #endif  	_usesCdTrack = Common::File::exists("cdaudio.map");  	if (!ConfMan.getBool("use_cdaudio")) @@ -143,8 +142,8 @@ SciVersion GameFeatures::detectDoSoundType() {  			//  SCI0LATE. Although the last SCI0EARLY game (lsl2) uses SCI0LATE resources  			_doSoundType = g_sci->getResMan()->detectEarlySound() ? SCI_VERSION_0_EARLY : SCI_VERSION_0_LATE;  #ifdef ENABLE_SCI32 -		} else if (getSciVersion() >= SCI_VERSION_2_1) { -			_doSoundType = SCI_VERSION_2_1; +		} else if (getSciVersion() >= SCI_VERSION_2_1_EARLY) { +			_doSoundType = SCI_VERSION_2_1_EARLY;  #endif  		} else if (SELECTOR(nodePtr) == -1) {  			// No nodePtr selector, so this game is definitely using newer @@ -271,7 +270,7 @@ SciVersion GameFeatures::detectLofsType() {  			return _lofsType;  		} -		if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) { +		if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE) {  			// SCI1.1 type, i.e. we compensate for the fact that the heap is attached  			// to the end of the script  			_lofsType = SCI_VERSION_1_1; @@ -475,7 +474,7 @@ bool GameFeatures::autoDetectSci21KernelType() {  		}  		warning("autoDetectSci21KernelType(): Sound object not loaded, assuming a SCI2.1 table"); -		_sci21KernelType = SCI_VERSION_2_1; +		_sci21KernelType = SCI_VERSION_2_1_EARLY;  		return true;  	} @@ -514,7 +513,7 @@ bool GameFeatures::autoDetectSci21KernelType() {  				_sci21KernelType = SCI_VERSION_2;  				return true;  			} else if (kFuncNum == 0x75) { -				_sci21KernelType = SCI_VERSION_2_1; +				_sci21KernelType = SCI_VERSION_2_1_EARLY;  				return true;  			}  		} @@ -532,65 +531,6 @@ SciVersion GameFeatures::detectSci21KernelType() {  	}  	return _sci21KernelType;  } - -Sci2StringFunctionType GameFeatures::detectSci2StringFunctionType() { -	if (_sci2StringFunctionType == kSci2StringFunctionUninitialized) { -		if (getSciVersion() <= SCI_VERSION_1_1) { -			error("detectSci21StringFunctionType() called from SCI1.1 or earlier"); -		} else if (getSciVersion() == SCI_VERSION_2) { -			// SCI2 games are always using the old type -			_sci2StringFunctionType = kSci2StringFunctionOld; -		} else if (getSciVersion() == SCI_VERSION_3) { -			// SCI3 games are always using the new type -			_sci2StringFunctionType = kSci2StringFunctionNew; -		} else {	// SCI2.1 -			if (!autoDetectSci21StringFunctionType()) -				_sci2StringFunctionType = kSci2StringFunctionOld; -			else -				_sci2StringFunctionType = kSci2StringFunctionNew; -		} -	} - -	debugC(1, kDebugLevelVM, "Detected SCI2 kString type: %s", (_sci2StringFunctionType == kSci2StringFunctionOld) ? "old" : "new"); - -	return _sci2StringFunctionType; -} - -bool GameFeatures::autoDetectSci21StringFunctionType() { -	// Look up the script address -	reg_t addr = getDetectionAddr("Str", SELECTOR(size)); - -	if (!addr.getSegment()) -		return false; - -	uint16 offset = addr.getOffset(); -	Script *script = _segMan->getScript(addr.getSegment()); - -	while (true) { -		int16 opparams[4]; -		byte extOpcode; -		byte opcode; -		offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams); -		opcode = extOpcode >> 1; - -		// Check for end of script -		if (opcode == op_ret || offset >= script->getBufSize()) -			break; - -		if (opcode == op_callk) { -			uint16 kFuncNum = opparams[0]; - -			// SCI2.1 games which use the new kString functions call kString(8). -			// Earlier ones call the callKernel script function, but not kString -			// directly -			if (_kernel->getKernelName(kFuncNum) == "String") -				return true; -		} -	} - -	return false;	// not found a call to kString -} -  #endif  bool GameFeatures::autoDetectMoveCountType() { diff --git a/engines/sci/engine/features.h b/engines/sci/engine/features.h index a4d715fee0..1c410267e6 100644 --- a/engines/sci/engine/features.h +++ b/engines/sci/engine/features.h @@ -34,12 +34,6 @@ enum MoveCountType {  	kIncrementMoveCount  }; -enum Sci2StringFunctionType { -	kSci2StringFunctionUninitialized, -	kSci2StringFunctionOld, -	kSci2StringFunctionNew -}; -  class GameFeatures {  public:  	GameFeatures(SegManager *segMan, Kernel *kernel); @@ -82,13 +76,6 @@ public:  	 * @return Graphics functions type, SCI_VERSION_2 / SCI_VERSION_2_1  	 */  	SciVersion detectSci21KernelType(); - -	/** -	 * Autodetects the string subfunctions used in SCI2 - SCI3 -	 * @return string subfunctions type, kSci2StringFunctionOld / kSci2StringFunctionNew -	 */ -	Sci2StringFunctionType detectSci2StringFunctionType(); -  #endif  	/** @@ -132,13 +119,11 @@ private:  	bool autoDetectMoveCountType();  #ifdef ENABLE_SCI32  	bool autoDetectSci21KernelType(); -	bool autoDetectSci21StringFunctionType();  #endif  	SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType, _messageFunctionType;  #ifdef ENABLE_SCI32  	SciVersion _sci21KernelType; -	Sci2StringFunctionType _sci2StringFunctionType;  #endif  	MoveCountType _moveCountType; diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index bfb7bfcd08..c0f2c64995 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -118,7 +118,7 @@ void Kernel::loadSelectorNames() {  	// Starting with KQ7, Mac versions have a BE name table. GK1 Mac and earlier (and all  	// other platforms) always use LE. -	bool isBE = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_2_1 +	bool isBE = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_2_1_EARLY  			&& g_sci->getGameId() != GID_GK1);  	if (!r) { // No such resource? @@ -863,7 +863,9 @@ void Kernel::loadKernelNames(GameFeatures *features) {  		_kernelNames = Common::StringArray(sci2_default_knames, kKernelEntriesSci2);  		break; -	case SCI_VERSION_2_1: +	case SCI_VERSION_2_1_EARLY: +	case SCI_VERSION_2_1_MIDDLE: +	case SCI_VERSION_2_1_LATE:  		if (features->detectSci21KernelType() == SCI_VERSION_2) {  			// Some early SCI2.1 games use a modified SCI2 kernel table instead of  			// the SCI2.1 kernel table. We detect which version to use based on diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 57b4d9455b..5d929a36ae 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -414,6 +414,27 @@ 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);  reg_t kString(EngineState *s, int argc, reg_t *argv); + +reg_t kStringNew(EngineState *s, int argc, reg_t *argv); +reg_t kStringSize(EngineState *s, int argc, reg_t *argv); +reg_t kStringAt(EngineState *s, int argc, reg_t *argv); +reg_t kStringPutAt(EngineState *s, int argc, reg_t *argv); +reg_t kStringFree(EngineState *s, int argc, reg_t *argv); +reg_t kStringFill(EngineState *s, int argc, reg_t *argv); +reg_t kStringCopy(EngineState *s, int argc, reg_t *argv); +reg_t kStringCompare(EngineState *s, int argc, reg_t *argv); +reg_t kStringDup(EngineState *s, int argc, reg_t *argv); +reg_t kStringGetData(EngineState *s, int argc, reg_t *argv); +reg_t kStringLen(EngineState *s, int argc, reg_t *argv); +reg_t kStringPrintf(EngineState *s, int argc, reg_t *argv); +reg_t kStringPrintfBuf(EngineState *s, int argc, reg_t *argv); +reg_t kStringAtoi(EngineState *s, int argc, reg_t *argv); +reg_t kStringTrim(EngineState *s, int argc, reg_t *argv); +reg_t kStringUpper(EngineState *s, int argc, reg_t *argv); +reg_t kStringLower(EngineState *s, int argc, reg_t *argv); +reg_t kStringTrn(EngineState *s, int argc, reg_t *argv); +reg_t kStringTrnExclude(EngineState *s, int argc, reg_t *argv); +  reg_t kMulDiv(EngineState *s, int argc, reg_t *argv);  reg_t kCantBeHere32(EngineState *s, int argc, reg_t *argv);  reg_t kRemapColors32(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index 2cbd79366d..49dfa17554 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -34,6 +34,15 @@ namespace Sci {  // . -> any type  // i* -> optional multiple integers  // .* -> any parameters afterwards (or none) +// +// data types: +// i - regular integer +// o - object +// r - reference +// n - node +// 0 - NULL +// . - any +// ! - invalid reference/offset  struct SciKernelMapSubEntry {  	SciVersion fromVersion; @@ -56,7 +65,8 @@ struct SciKernelMapSubEntry {  #define SIG_SCI1           SCI_VERSION_1_EGA_ONLY, SCI_VERSION_1_LATE  #define SIG_SCI11          SCI_VERSION_1_1, SCI_VERSION_1_1  #define SIG_SINCE_SCI11    SCI_VERSION_1_1, SCI_VERSION_NONE -#define SIG_SCI21          SCI_VERSION_2_1, SCI_VERSION_3 +#define SIG_SINCE_SCI21    SCI_VERSION_2_1_EARLY, SCI_VERSION_3 +#define SIG_UNTIL_SCI21MID SCI_VERSION_2_1_EARLY, SCI_VERSION_2_1_MIDDLE  #define SIG_SCI16          SCI_VERSION_NONE, SCI_VERSION_1_1  #define SIG_SCI32          SCI_VERSION_2, SCI_VERSION_NONE @@ -65,7 +75,7 @@ struct SciKernelMapSubEntry {  #define SIG_SOUNDSCI0      SCI_VERSION_0_EARLY, SCI_VERSION_0_LATE  #define SIG_SOUNDSCI1EARLY SCI_VERSION_1_EARLY, SCI_VERSION_1_EARLY  #define SIG_SOUNDSCI1LATE  SCI_VERSION_1_LATE, SCI_VERSION_1_LATE -#define SIG_SOUNDSCI21     SCI_VERSION_2_1, SCI_VERSION_3 +#define SIG_SOUNDSCI21     SCI_VERSION_2_1_EARLY, SCI_VERSION_3  #define SIGFOR_ALL   0x3f  #define SIGFOR_DOS   1 << 0 @@ -190,7 +200,7 @@ static const SciKernelMapSubEntry kGraph_subops[] = {  //    version,         subId, function-mapping,                    signature,              workarounds  static const SciKernelMapSubEntry kPalVary_subops[] = { -	{ SIG_SCI21,           0, MAP_CALL(PalVaryInit),               "ii(i)(i)(i)",          NULL }, +	{ SIG_SINCE_SCI21,     0, MAP_CALL(PalVaryInit),               "ii(i)(i)(i)",          NULL },  	{ SIG_SCIALL,          0, MAP_CALL(PalVaryInit),               "ii(i)(i)",             NULL },  	{ SIG_SCIALL,          1, MAP_CALL(PalVaryReverse),            "(i)(i)(i)",            NULL },  	{ SIG_SCIALL,          2, MAP_CALL(PalVaryGetCurrentStep),     "",                     NULL }, @@ -246,6 +256,7 @@ static const SciKernelMapSubEntry kFileIO_subops[] = {  #ifdef ENABLE_SCI32 +//    version,         subId, function-mapping,                    signature,              workarounds  static const SciKernelMapSubEntry kSave_subops[] = {  	{ SIG_SCI32,           0, MAP_CALL(SaveGame),                  "[r0]i[r0](r0)",        NULL },  	{ SIG_SCI32,           1, MAP_CALL(RestoreGame),               "[r0]i[r0]",            NULL }, @@ -261,31 +272,73 @@ static const SciKernelMapSubEntry kSave_subops[] = {  //    version,         subId, function-mapping,                    signature,              workarounds  static const SciKernelMapSubEntry kList_subops[] = { -	{ SIG_SCI21,           0, MAP_CALL(NewList),                   "",                     NULL }, -	{ SIG_SCI21,           1, MAP_CALL(DisposeList),               "l",                    NULL }, -	{ SIG_SCI21,           2, MAP_CALL(NewNode),                   ".(.)",                 NULL }, -	{ SIG_SCI21,           3, MAP_CALL(FirstNode),                 "[l0]",                 NULL }, -	{ SIG_SCI21,           4, MAP_CALL(LastNode),                  "l",                    NULL }, -	{ SIG_SCI21,           5, MAP_CALL(EmptyList),                 "l",                    NULL }, -	{ SIG_SCI21,           6, MAP_CALL(NextNode),                  "n",                    NULL }, -	{ SIG_SCI21,           7, MAP_CALL(PrevNode),                  "n",                    NULL }, -	{ SIG_SCI21,           8, MAP_CALL(NodeValue),                 "[n0]",                 NULL }, -	{ SIG_SCI21,           9, MAP_CALL(AddAfter),                  "lnn.",                 NULL }, -	{ SIG_SCI21,          10, MAP_CALL(AddToFront),                "ln.",                  NULL }, -	{ SIG_SCI21,          11, MAP_CALL(AddToEnd),                  "ln(.)",                NULL }, -	{ SIG_SCI21,          12, MAP_CALL(AddBefore),                 "ln.",                  NULL }, -	{ SIG_SCI21,          13, MAP_CALL(MoveToFront),               "ln",                   NULL }, -	{ SIG_SCI21,          14, MAP_CALL(MoveToEnd),                 "ln",                   NULL }, -	{ SIG_SCI21,          15, MAP_CALL(FindKey),                   "l.",                   NULL }, -	{ SIG_SCI21,          16, MAP_CALL(DeleteKey),                 "l.",                   NULL }, -	{ SIG_SCI21,          17, MAP_CALL(ListAt),                    "li",                   NULL }, -	{ SIG_SCI21,          18, MAP_CALL(ListIndexOf) ,              "l[io]",                NULL }, -	{ SIG_SCI21,          19, MAP_CALL(ListEachElementDo),         "li(.*)",               NULL }, -	{ SIG_SCI21,          20, MAP_CALL(ListFirstTrue),             "li(.*)",               NULL }, -	{ SIG_SCI21,          21, MAP_CALL(ListAllTrue),               "li(.*)",               NULL }, -	{ SIG_SCI21,          22, MAP_CALL(Sort),                      "ooo",                  NULL }, +	{ SIG_SINCE_SCI21,     0, MAP_CALL(NewList),                   "",                     NULL }, +	{ SIG_SINCE_SCI21,     1, MAP_CALL(DisposeList),               "l",                    NULL }, +	{ SIG_SINCE_SCI21,     2, MAP_CALL(NewNode),                   ".(.)",                 NULL }, +	{ SIG_SINCE_SCI21,     3, MAP_CALL(FirstNode),                 "[l0]",                 NULL }, +	{ SIG_SINCE_SCI21,     4, MAP_CALL(LastNode),                  "l",                    NULL }, +	{ SIG_SINCE_SCI21,     5, MAP_CALL(EmptyList),                 "l",                    NULL }, +	{ SIG_SINCE_SCI21,     6, MAP_CALL(NextNode),                  "n",                    NULL }, +	{ SIG_SINCE_SCI21,     7, MAP_CALL(PrevNode),                  "n",                    NULL }, +	{ SIG_SINCE_SCI21,     8, MAP_CALL(NodeValue),                 "[n0]",                 NULL }, +	{ SIG_SINCE_SCI21,     9, MAP_CALL(AddAfter),                  "lnn.",                 NULL }, +	{ SIG_SINCE_SCI21,    10, MAP_CALL(AddToFront),                "ln.",                  NULL }, +	{ SIG_SINCE_SCI21,    11, MAP_CALL(AddToEnd),                  "ln(.)",                NULL }, +	{ SIG_SINCE_SCI21,    12, MAP_CALL(AddBefore),                 "ln.",                  NULL }, +	{ SIG_SINCE_SCI21,    13, MAP_CALL(MoveToFront),               "ln",                   NULL }, +	{ SIG_SINCE_SCI21,    14, MAP_CALL(MoveToEnd),                 "ln",                   NULL }, +	{ SIG_SINCE_SCI21,    15, MAP_CALL(FindKey),                   "l.",                   NULL }, +	{ SIG_SINCE_SCI21,    16, MAP_CALL(DeleteKey),                 "l.",                   NULL }, +	{ SIG_SINCE_SCI21,    17, MAP_CALL(ListAt),                    "li",                   NULL }, +	{ SIG_SINCE_SCI21,    18, MAP_CALL(ListIndexOf) ,              "l[io]",                NULL }, +	{ SIG_SINCE_SCI21,    19, MAP_CALL(ListEachElementDo),         "li(.*)",               NULL }, +	{ SIG_SINCE_SCI21,    20, MAP_CALL(ListFirstTrue),             "li(.*)",               NULL }, +	{ SIG_SINCE_SCI21,    21, MAP_CALL(ListAllTrue),               "li(.*)",               NULL }, +	{ SIG_SINCE_SCI21,    22, MAP_CALL(Sort),                      "ooo",                  NULL }, +	SCI_SUBOPENTRY_TERMINATOR +}; + +//    version,         subId, function-mapping,                    signature,              workarounds +static const SciKernelMapSubEntry kString_subops[] = { +	{ SIG_SCI32,           0, MAP_CALL(StringNew),                 "i(i)",                 NULL }, +	{ SIG_SCI32,           1, MAP_CALL(StringSize),                "[or]",                 NULL }, +	{ SIG_SCI32,           2, MAP_CALL(StringAt),                  "[or]i",                NULL }, +	{ SIG_SCI32,           3, MAP_CALL(StringPutAt),               "[or]i(i*)",            NULL }, +	// StringFree accepts invalid references +	{ SIG_SCI32,           4, MAP_CALL(StringFree),                "[or0!]",               NULL }, +	{ SIG_SCI32,           5, MAP_CALL(StringFill),                "[or]ii",               NULL }, +	{ SIG_SCI32,           6, MAP_CALL(StringCopy),                "[or]i[or]ii",          NULL }, +	{ SIG_SCI32,           7, MAP_CALL(StringCompare),             "[or][or](i)",          NULL }, + +	// =SCI2.1 Early and SCI2.1 Middle= +	{ SIG_UNTIL_SCI21MID,  8, MAP_CALL(StringDup),                 "[or]",                 NULL }, +	{ SIG_UNTIL_SCI21MID,  9, MAP_CALL(StringGetData),             "[or]",                 NULL }, +	{ SIG_UNTIL_SCI21MID, 10, MAP_CALL(StringLen),                 "[or]",                 NULL }, +	{ SIG_UNTIL_SCI21MID, 11, MAP_CALL(StringPrintf),              "[or](.*)",             NULL }, +	{ SIG_UNTIL_SCI21MID, 12, MAP_CALL(StringPrintfBuf),           "[or](.*)",             NULL }, +	{ SIG_UNTIL_SCI21MID, 13, MAP_CALL(StringAtoi),                "[or]",                 NULL }, +	// exact functionality of Trim is unknown atm +	{ SIG_UNTIL_SCI21MID, 14, MAP_CALL(StringTrim),                "[or]",                 NULL }, +	{ SIG_UNTIL_SCI21MID, 15, MAP_CALL(StringUpper),               "[or]",                 NULL }, +	{ SIG_UNTIL_SCI21MID, 16, MAP_CALL(StringLower),               "[or]",                 NULL }, +	// the following 2 are unknown atm (happen in Phantasmagoria) +	// possibly translate? +	{ SIG_UNTIL_SCI21MID, 17, MAP_CALL(StringTrn),                 "[or]",                 NULL }, +	{ SIG_UNTIL_SCI21MID, 18, MAP_CALL(StringTrnExclude),          "[or]",                 NULL }, + +	// SCI2.1 Late + SCI3 - kStringDup + kStringGetData were removed +	{ SIG_SCI32,           8, MAP_CALL(StringLen),                 "[or]",                 NULL }, +	{ SIG_SCI32,           9, MAP_CALL(StringPrintf),              "[or](.*)",             NULL }, +	{ SIG_SCI32,          10, MAP_CALL(StringPrintfBuf),           "[or](.*)",             NULL }, +	{ SIG_SCI32,          11, MAP_CALL(StringAtoi),                "[or]",                 NULL }, +	{ SIG_SCI32,          12, MAP_CALL(StringTrim),                "[or]",                 NULL }, +	{ SIG_SCI32,          13, MAP_CALL(StringUpper),               "[or]",                 NULL }, +	{ SIG_SCI32,          14, MAP_CALL(StringLower),               "[or]",                 NULL }, +	{ SIG_SCI32,          15, MAP_CALL(StringTrn),                 "[or]",                 NULL }, +	{ SIG_SCI32,          16, MAP_CALL(StringTrnExclude),          "[or]",                 NULL },  	SCI_SUBOPENTRY_TERMINATOR  }; +  #endif  struct SciKernelMapEntry { @@ -429,7 +482,7 @@ static SciKernelMapEntry s_kernelMap[] = {  	{ MAP_CALL(Said),              SIG_EVERYWHERE,           "[r0]",                  NULL,            NULL },  	{ MAP_CALL(SaveGame),          SIG_EVERYWHERE,           "[r0]i[r0](r0)",         NULL,            NULL },  	{ MAP_CALL(ScriptID),          SIG_EVERYWHERE,           "[io](i)",               NULL,            NULL }, -	{ MAP_CALL(SetCursor),         SIG_SCI21, SIGFOR_ALL,    "i(i)([io])(i*)",        NULL,            NULL }, +	{ MAP_CALL(SetCursor),         SIG_SINCE_SCI21, SIGFOR_ALL, "i(i)([io])(i*)",     NULL,            NULL },  	// TODO: SCI2.1 may supply an object optionally (mother goose sci21 right on startup) - find out why  	{ MAP_CALL(SetCursor),         SIG_SCI11, SIGFOR_ALL,    "i(i)(i)(i)(iiiiii)",    NULL,            NULL },  	{ MAP_CALL(SetCursor),         SIG_EVERYWHERE,           "i(i)(i)(i)(i)",         NULL,            kSetCursor_workarounds }, @@ -513,7 +566,7 @@ static SciKernelMapEntry s_kernelMap[] = {  	// our garbage collector (i.e. the SCI0-SCI1.1 semantics).  	{ "Purge", kFlushResources,    SIG_EVERYWHERE,           "i",                     NULL,            NULL },  	{ MAP_CALL(SetShowStyle),      SIG_EVERYWHERE,           "ioiiiii([ri])(i)",      NULL,            NULL }, -	{ MAP_CALL(String),            SIG_EVERYWHERE,           "(.*)",                  NULL,            NULL }, +	{ MAP_CALL(String),            SIG_EVERYWHERE,           "(.*)",                  kString_subops,  NULL },  	{ MAP_CALL(UpdatePlane),       SIG_EVERYWHERE,           "o",                     NULL,            NULL },  	{ MAP_CALL(UpdateScreenItem),  SIG_EVERYWHERE,           "o",                     NULL,            NULL },  	{ MAP_CALL(ObjectIntersect),   SIG_EVERYWHERE,           "oo",                    NULL,            NULL }, @@ -570,7 +623,7 @@ static SciKernelMapEntry s_kernelMap[] = {  	// SCI2.1 Kernel Functions  	{ MAP_CALL(CD),                SIG_EVERYWHERE,           "(.*)",                  NULL,            NULL },  	{ MAP_CALL(IsOnMe),            SIG_EVERYWHERE,           "iioi",                  NULL,            NULL }, -	{ MAP_CALL(List),              SIG_SCI21, SIGFOR_ALL,    "(.*)",                  kList_subops,    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(Robot),             SIG_EVERYWHERE,           "(.*)",                  NULL,            NULL }, diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index 8e16e0a07a..eb052dd24e 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -58,7 +58,7 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {  		// In case we use a simulated event we query the current mouse position  		mousePos = g_sci->_gfxCursor->getPosition();  #ifdef ENABLE_SCI32 -		if (getSciVersion() >= SCI_VERSION_2_1) +		if (getSciVersion() >= SCI_VERSION_2_1_EARLY)  			g_sci->_gfxCoordAdjuster->fromDisplayToScript(mousePos.y, mousePos.x);  #endif  		// Limit the mouse cursor position, if necessary @@ -84,7 +84,7 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {  	// For a real event we use its associated mouse position  	mousePos = curEvent.mousePos;  #ifdef ENABLE_SCI32 -	if (getSciVersion() >= SCI_VERSION_2_1) +	if (getSciVersion() >= SCI_VERSION_2_1_EARLY)  		g_sci->_gfxCoordAdjuster->fromDisplayToScript(mousePos.y, mousePos.x);  #endif  	// Limit the mouse cursor position, if necessary diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 448e641b63..1d9dae69b7 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -487,7 +487,7 @@ 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 -		if (getSciVersion() >= SCI_VERSION_2_1) // Set Mac cursor remap +		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)  			warning("Unknown SCI1 kMacPlatform(0) call"); diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 5c271780dd..303de079aa 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -229,7 +229,7 @@ reg_t kScriptID(EngineState *s, int argc, reg_t *argv) {  	uint16 address = scr->validateExportFunc(index, true);  	// Point to the heap for SCI1.1 - SCI2.1 games -	if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) +	if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE)  		address += scr->getScriptSize();  	// Bugfix for the intro speed in PQ2 version 1.002.011. diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index 6a1708d21a..032191e4c1 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -185,7 +185,7 @@ reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) {  		volume = CLIP<int16>(volume, 0, AUDIO_VOLUME_MAX);  		debugC(kDebugLevelSound, "kDoAudio: set volume to %d", volume);  #ifdef ENABLE_SCI32 -		if (getSciVersion() >= SCI_VERSION_2_1) { +		if (getSciVersion() >= SCI_VERSION_2_1_EARLY) {  			int16 volumePrev = mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 2;  			volumePrev = CLIP<int16>(volumePrev, 0, AUDIO_VOLUME_MAX);  			mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume * 2); diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index eef758a0d9..cd0d6af936 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -674,189 +674,230 @@ reg_t kText(EngineState *s, int argc, reg_t *argv) {  	return s->r_acc;  } -reg_t kString(EngineState *s, int argc, reg_t *argv) { -	uint16 op = argv[0].toUint16(); +// TODO: there is an unused second argument, happens at least in LSL6 right during the intro +reg_t kStringNew(EngineState *s, int argc, reg_t *argv) { +	reg_t stringHandle; +	SciString *string = s->_segMan->allocateString(&stringHandle); +	string->setSize(argv[0].toUint16()); -	if (g_sci->_features->detectSci2StringFunctionType() == kSci2StringFunctionNew) { -		if (op >= 8)	// Dup, GetData have been removed -			op += 2; -	} +	// Make sure the first character is a null character +	if (string->getSize() > 0) +		string->setValue(0, 0); -	switch (op) { -	case 0: { // New -		reg_t stringHandle; -		SciString *string = s->_segMan->allocateString(&stringHandle); -		string->setSize(argv[1].toUint16()); +	return stringHandle; +} -		// Make sure the first character is a null character -		if (string->getSize() > 0) -			string->setValue(0, 0); +reg_t kStringSize(EngineState *s, int argc, reg_t *argv) { +	return make_reg(0, s->_segMan->getString(argv[0]).size()); +} -		return stringHandle; -		} -	case 1: // Size -		return make_reg(0, s->_segMan->getString(argv[1]).size()); -	case 2: { // At (return value at an index) -		// Note that values are put in bytes to avoid sign extension -		if (argv[1].getSegment() == s->_segMan->getStringSegmentId()) { -			SciString *string = s->_segMan->lookupString(argv[1]); -			byte val = string->getRawData()[argv[2].toUint16()]; -			return make_reg(0, val); -		} else { -			Common::String string = s->_segMan->getString(argv[1]); -			byte val = string[argv[2].toUint16()]; -			return make_reg(0, val); -		} +// At (return value at an index) +reg_t kStringAt(EngineState *s, int argc, reg_t *argv) { +	// Note that values are put in bytes to avoid sign extension +	if (argv[0].getSegment() == s->_segMan->getStringSegmentId()) { +		SciString *string = s->_segMan->lookupString(argv[0]); +		byte val = string->getRawData()[argv[1].toUint16()]; +		return make_reg(0, val); +	} else { +		Common::String string = s->_segMan->getString(argv[0]); +		byte val = string[argv[1].toUint16()]; +		return make_reg(0, val);  	} -	case 3: { // Atput (put value at an index) -		SciString *string = s->_segMan->lookupString(argv[1]); +} -		uint32 index = argv[2].toUint16(); -		uint32 count = argc - 3; +// Atput (put value at an index) +reg_t kStringPutAt(EngineState *s, int argc, reg_t *argv) { +	SciString *string = s->_segMan->lookupString(argv[0]); -		if (index + count > 65535) -			break; +	uint32 index = argv[1].toUint16(); +	uint32 count = argc - 2; -		if (string->getSize() < index + count) -			string->setSize(index + count); +	if (index + count > 65535) +		return NULL_REG; -		for (uint16 i = 0; i < count; i++) -			string->setValue(i + index, argv[i + 3].toUint16()); +	if (string->getSize() < index + count) +		string->setSize(index + count); -		return argv[1]; // We also have to return the handle -	} -	case 4: // Free -		// Freeing of strings is handled by the garbage collector -		return s->r_acc; -	case 5: { // Fill -		SciString *string = s->_segMan->lookupString(argv[1]); -		uint16 index = argv[2].toUint16(); +	for (uint16 i = 0; i < count; i++) +		string->setValue(i + index, argv[i + 2].toUint16()); + +	return argv[0]; // We also have to return the handle +} + +reg_t kStringFree(EngineState *s, int argc, reg_t *argv) { +	// Freeing of strings is handled by the garbage collector +	return s->r_acc; +} + +reg_t kStringFill(EngineState *s, int argc, reg_t *argv) { +	SciString *string = s->_segMan->lookupString(argv[0]); +	uint16 index = argv[1].toUint16(); + +	// A count of -1 means fill the rest of the array +	uint16 count = argv[2].toSint16() == -1 ? string->getSize() - index : argv[2].toUint16(); +	uint16 stringSize = string->getSize(); -		// A count of -1 means fill the rest of the array -		uint16 count = argv[3].toSint16() == -1 ? string->getSize() - index : argv[3].toUint16(); -		uint16 stringSize = string->getSize(); +	if (stringSize < index + count) +		string->setSize(index + count); -		if (stringSize < index + count) -			string->setSize(index + count); +	for (uint16 i = 0; i < count; i++) +		string->setValue(i + index, argv[3].toUint16()); -		for (uint16 i = 0; i < count; i++) -			string->setValue(i + index, argv[4].toUint16()); +	return argv[0]; +} + +reg_t kStringCopy(EngineState *s, int argc, reg_t *argv) { +	const char *string2 = 0; +	uint32 string2Size = 0; +	Common::String string; -		return argv[1]; +	if (argv[2].getSegment() == s->_segMan->getStringSegmentId()) { +		SciString *sstr; +		sstr = s->_segMan->lookupString(argv[2]); +		string2 = sstr->getRawData(); +		string2Size = sstr->getSize(); +	} else { +		string = s->_segMan->getString(argv[2]); +		string2 = string.c_str(); +		string2Size = string.size() + 1;  	} -	case 6: { // Cpy -		const char *string2 = 0; -		uint32 string2Size = 0; -		Common::String string; - -		if (argv[3].getSegment() == s->_segMan->getStringSegmentId()) { -			SciString *sstr; -			sstr = s->_segMan->lookupString(argv[3]); -			string2 = sstr->getRawData(); -			string2Size = sstr->getSize(); -		} else { -			string = s->_segMan->getString(argv[3]); -			string2 = string.c_str(); -			string2Size = string.size() + 1; + +	uint32 index1 = argv[1].toUint16(); +	uint32 index2 = argv[3].toUint16(); + +	if (argv[0] == argv[2]) { +		// source and destination string are one and the same +		if (index1 == index2) { +			// even same index? ignore this call +			// Happens in KQ7, when starting a chapter +			return argv[0];  		} +		// TODO: this will crash, when setSize() is triggered later +		// we need to exactly replicate original interpreter behavior +		warning("kString(Copy): source is the same as destination string"); +	} -		uint32 index1 = argv[2].toUint16(); -		uint32 index2 = argv[4].toUint16(); +	// The original engine ignores bad copies too +	if (index2 > string2Size) +		return NULL_REG; -		// The original engine ignores bad copies too -		if (index2 > string2Size) -			break; +	// A count of -1 means fill the rest of the array +	uint32 count = argv[4].toSint16() == -1 ? string2Size - index2 + 1 : argv[4].toUint16(); +//	reg_t strAddress = argv[0]; -		// A count of -1 means fill the rest of the array -		uint32 count = argv[5].toSint16() == -1 ? string2Size - index2 + 1 : argv[5].toUint16(); -		reg_t strAddress = argv[1]; +	SciString *string1 = s->_segMan->lookupString(argv[0]); +	//SciString *string1 = !argv[1].isNull() ? s->_segMan->lookupString(argv[1]) : s->_segMan->allocateString(&strAddress); -		SciString *string1 = s->_segMan->lookupString(argv[1]); -		//SciString *string1 = !argv[1].isNull() ? s->_segMan->lookupString(argv[1]) : s->_segMan->allocateString(&strAddress); +	if (string1->getSize() < index1 + count) +		string1->setSize(index1 + count); -		if (string1->getSize() < index1 + count) -			string1->setSize(index1 + count); +	// Note: We're accessing from c_str() here because the +	// string's size ignores the trailing 0 and therefore +	// triggers an assert when doing string2[i + index2]. +	for (uint16 i = 0; i < count; i++) +		string1->setValue(i + index1, string2[i + index2]); -		// Note: We're accessing from c_str() here because the -		// string's size ignores the trailing 0 and therefore -		// triggers an assert when doing string2[i + index2]. -		for (uint16 i = 0; i < count; i++) -			string1->setValue(i + index1, string2[i + index2]); +	return argv[0]; +} -		return strAddress; -	} -	case 7: { // Cmp -		Common::String string1 = argv[1].isNull() ? "" : s->_segMan->getString(argv[1]); -		Common::String string2 = argv[2].isNull() ? "" : s->_segMan->getString(argv[2]); - -		if (argc == 4) // Strncmp -			return make_reg(0, strncmp(string1.c_str(), string2.c_str(), argv[3].toUint16())); -		else           // Strcmp -			return make_reg(0, strcmp(string1.c_str(), string2.c_str())); -	} -	case 8: { // Dup -		reg_t stringHandle; +reg_t kStringCompare(EngineState *s, int argc, reg_t *argv) { +	Common::String string1 = argv[0].isNull() ? "" : s->_segMan->getString(argv[0]); +	Common::String string2 = argv[1].isNull() ? "" : s->_segMan->getString(argv[1]); -		SciString *dupString = s->_segMan->allocateString(&stringHandle); +	if (argc == 3) // Strncmp +		return make_reg(0, strncmp(string1.c_str(), string2.c_str(), argv[2].toUint16())); +	else           // Strcmp +		return make_reg(0, strcmp(string1.c_str(), string2.c_str())); +} -		if (argv[1].getSegment() == s->_segMan->getStringSegmentId()) { -			*dupString = *s->_segMan->lookupString(argv[1]); -		} else { -			dupString->fromString(s->_segMan->getString(argv[1])); -		} +// was removed for SCI2.1 Late+ +reg_t kStringDup(EngineState *s, int argc, reg_t *argv) { +	reg_t stringHandle; -		return stringHandle; -	} -	case 9: // Getdata -		if (!s->_segMan->isHeapObject(argv[1])) -			return argv[1]; - -		return readSelector(s->_segMan, argv[1], SELECTOR(data)); -	case 10: // Stringlen -		return make_reg(0, s->_segMan->strlen(argv[1])); -	case 11: { // Printf -		reg_t stringHandle; -		s->_segMan->allocateString(&stringHandle); - -		reg_t *adjustedArgs = new reg_t[argc]; -		adjustedArgs[0] = stringHandle; -		memcpy(&adjustedArgs[1], argv + 1, (argc - 1) * sizeof(reg_t)); - -		kFormat(s, argc, adjustedArgs); -		delete[] adjustedArgs; -		return stringHandle; -		} -	case 12: // Printf Buf -		return kFormat(s, argc - 1, argv + 1); -	case 13: { // atoi -		Common::String string = s->_segMan->getString(argv[1]); -		return make_reg(0, (uint16)atoi(string.c_str())); -	} -	// 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]); +	SciString *dupString = s->_segMan->allocateString(&stringHandle); -		string.toUppercase(); -		s->_segMan->strcpy(argv[1], string.c_str()); -		return NULL_REG; +	if (argv[0].getSegment() == s->_segMan->getStringSegmentId()) { +		*dupString = *s->_segMan->lookupString(argv[0]); +	} else { +		dupString->fromString(s->_segMan->getString(argv[0]));  	} -	case 16: { // lower -		Common::String string = s->_segMan->getString(argv[1]); -		string.toLowercase(); -		s->_segMan->strcpy(argv[1], string.c_str()); -		return NULL_REG; -	} -	default: -		error("Unknown kString subop %d", argv[0].toUint16()); -	} +	return stringHandle; +} + +// was removed for SCI2.1 Late+ +reg_t kStringGetData(EngineState *s, int argc, reg_t *argv) { +	if (!s->_segMan->isHeapObject(argv[0])) +		return argv[0]; + +	return readSelector(s->_segMan, argv[0], SELECTOR(data)); +} + +reg_t kStringLen(EngineState *s, int argc, reg_t *argv) { +	return make_reg(0, s->_segMan->strlen(argv[0])); +} + +reg_t kStringPrintf(EngineState *s, int argc, reg_t *argv) { +	reg_t stringHandle; +	s->_segMan->allocateString(&stringHandle); + +	reg_t *adjustedArgs = new reg_t[argc + 1]; +	adjustedArgs[0] = stringHandle; +	memcpy(&adjustedArgs[1], argv, argc * sizeof(reg_t)); + +	kFormat(s, argc + 1, adjustedArgs); +	delete[] adjustedArgs; +	return stringHandle; +} + +reg_t kStringPrintfBuf(EngineState *s, int argc, reg_t *argv) { +	return kFormat(s, argc, argv); +} +reg_t kStringAtoi(EngineState *s, int argc, reg_t *argv) { +	Common::String string = s->_segMan->getString(argv[0]); +	return make_reg(0, (uint16)atoi(string.c_str())); +} + +reg_t kStringTrim(EngineState *s, int argc, reg_t *argv) { +	warning("kStringTrim (argc = %d)", argc); +	return NULL_REG; +} + +reg_t kStringUpper(EngineState *s, int argc, reg_t *argv) { +	Common::String string = s->_segMan->getString(argv[0]); + +	string.toUppercase(); +	s->_segMan->strcpy(argv[0], string.c_str()); +	return NULL_REG; +} + +reg_t kStringLower(EngineState *s, int argc, reg_t *argv) { +	Common::String string = s->_segMan->getString(argv[0]); + +	string.toLowercase(); +	s->_segMan->strcpy(argv[0], string.c_str());  	return NULL_REG;  } +// Possibly kStringTranslate? +reg_t kStringTrn(EngineState *s, int argc, reg_t *argv) { +	warning("kStringTrn (argc = %d)", argc); +	return NULL_REG; +} + +// Possibly kStringTranslateExclude? +reg_t kStringTrnExclude(EngineState *s, int argc, reg_t *argv) { +	warning("kStringTrnExclude (argc = %d)", argc); +	return NULL_REG; +} + +reg_t kString(EngineState *s, int argc, reg_t *argv) { +	if (!s) +		return make_reg(0, getSciVersion()); +	error("not supposed to call this"); +} +  #endif  } // End of namespace Sci diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp index f925111fc9..6920466711 100644 --- a/engines/sci/engine/kvideo.cpp +++ b/engines/sci/engine/kvideo.cpp @@ -181,7 +181,7 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) {  		// for the video, so we'll just play it from there for now.  #ifdef ENABLE_SCI32 -		if (getSciVersion() >= SCI_VERSION_2_1) { +		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) diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp index 640175b20a..5300b72b71 100644 --- a/engines/sci/engine/message.cpp +++ b/engines/sci/engine/message.cpp @@ -182,7 +182,7 @@ bool MessageState::getRecord(CursorStack &stack, bool recurse, MessageRecord &re  #ifdef ENABLE_SCI32  	case 5: // v5 seems to be compatible with v4  		// SCI32 Mac is different than SCI32 DOS/Win here -		if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_2_1) +		if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_2_1_EARLY)  			reader = new MessageReaderV4_MacSCI32(res->data, res->size);  		else  #endif diff --git a/engines/sci/engine/object.cpp b/engines/sci/engine/object.cpp index eeff45163d..0626c084c1 100644 --- a/engines/sci/engine/object.cpp +++ b/engines/sci/engine/object.cpp @@ -45,7 +45,7 @@ static bool relocateBlock(Common::Array<reg_t> &block, int block_location, Segme  		return false;  	}  	block[idx].setSegment(segment); // Perform relocation -	if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) +	if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE)  		block[idx].incOffset(scriptSize);  	return true; @@ -63,7 +63,7 @@ void Object::init(byte *buf, reg_t obj_pos, bool initVariables) {  		for (int i = 0; i < _methodCount * 2 + 2; ++i) {  			_baseMethod.push_back(READ_SCI11ENDIAN_UINT16(data + READ_LE_UINT16(data + kOffsetFunctionArea) + i * 2));  		} -	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) { +	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE) {  		_variables.resize(READ_SCI11ENDIAN_UINT16(data + 2));  		_baseVars = (const uint16 *)(buf + READ_SCI11ENDIAN_UINT16(data + 4));  		_methodCount = READ_SCI11ENDIAN_UINT16(buf + READ_SCI11ENDIAN_UINT16(data + 6)); @@ -75,7 +75,7 @@ void Object::init(byte *buf, reg_t obj_pos, bool initVariables) {  	}  	if (initVariables) { -		if (getSciVersion() <= SCI_VERSION_2_1) { +		if (getSciVersion() <= SCI_VERSION_2_1_LATE) {  			for (uint i = 0; i < _variables.size(); i++)  				_variables[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(data + (i * 2)));  		} else { @@ -92,7 +92,7 @@ int Object::locateVarSelector(SegManager *segMan, Selector slc) const {  	const byte *buf = 0;  	uint varnum = 0; -	if (getSciVersion() <= SCI_VERSION_2_1) { +	if (getSciVersion() <= SCI_VERSION_2_1_LATE) {  		const Object *obj = getClass(segMan);  		varnum = getSciVersion() <= SCI_VERSION_1_LATE ? getVarCount() : obj->getVariable(1).toUint16();  		buf = (const byte *)obj->_baseVars; diff --git a/engines/sci/engine/object.h b/engines/sci/engine/object.h index 00fe7c6875..0ae7ed2cab 100644 --- a/engines/sci/engine/object.h +++ b/engines/sci/engine/object.h @@ -79,42 +79,42 @@ public:  	}  	reg_t getSpeciesSelector() const { -		if (getSciVersion() <= SCI_VERSION_2_1) +		if (getSciVersion() < SCI_VERSION_3)  			return _variables[_offset];  		else	// SCI3  			return _speciesSelectorSci3;  	}  	void setSpeciesSelector(reg_t value) { -		if (getSciVersion() <= SCI_VERSION_2_1) +		if (getSciVersion() < SCI_VERSION_3)  			_variables[_offset] = value;  		else	// SCI3  			_speciesSelectorSci3 = value;  	}  	reg_t getSuperClassSelector() const { -		if (getSciVersion() <= SCI_VERSION_2_1) +		if (getSciVersion() < SCI_VERSION_3)  			return _variables[_offset + 1];  		else	// SCI3  			return _superClassPosSci3;  	}  	void setSuperClassSelector(reg_t value) { -		if (getSciVersion() <= SCI_VERSION_2_1) +		if (getSciVersion() < SCI_VERSION_3)  			_variables[_offset + 1] = value;  		else	// SCI3  			_superClassPosSci3 = value;  	}  	reg_t getInfoSelector() const { -		if (getSciVersion() <= SCI_VERSION_2_1) +		if (getSciVersion() < SCI_VERSION_3)  			return _variables[_offset + 2];  		else	// SCI3  			return _infoSelectorSci3;  	}  	void setInfoSelector(reg_t info) { -		if (getSciVersion() <= SCI_VERSION_2_1) +		if (getSciVersion() < SCI_VERSION_3)  			_variables[_offset + 2] = info;  		else	// SCI3  			_infoSelectorSci3 = info; @@ -123,7 +123,7 @@ public:  	// No setter for the -info- selector  	reg_t getNameSelector() const { -		if (getSciVersion() <= SCI_VERSION_2_1) +		if (getSciVersion() < SCI_VERSION_3)  			return _offset + 3 < (uint16)_variables.size() ? _variables[_offset + 3] : NULL_REG;  		else	// SCI3  			return _variables.size() ? _variables[0] : NULL_REG; @@ -132,7 +132,7 @@ public:  	// No setter for the name selector  	reg_t getPropDictSelector() const { -		if (getSciVersion() <= SCI_VERSION_2_1) +		if (getSciVersion() < SCI_VERSION_3)  			return _variables[2];  		else  			// This should never occur, this is called from a SCI1.1 - SCI2.1 only function @@ -140,7 +140,7 @@ public:  	}  	void setPropDictSelector(reg_t value) { -		if (getSciVersion() <= SCI_VERSION_2_1) +		if (getSciVersion() < SCI_VERSION_3)  			_variables[2] = value;  		else  			// This should never occur, this is called from a SCI1.1 - SCI2.1 only function @@ -148,14 +148,14 @@ public:  	}  	reg_t getClassScriptSelector() const { -		if (getSciVersion() <= SCI_VERSION_2_1) +		if (getSciVersion() < SCI_VERSION_3)  			return _variables[4];  		else	// SCI3  			return make_reg(0, READ_SCI11ENDIAN_UINT16(_baseObj + 6));  	}  	void setClassScriptSelector(reg_t value) { -		if (getSciVersion() <= SCI_VERSION_2_1) +		if (getSciVersion() < SCI_VERSION_3)  			_variables[4] = value;  		else	// SCI3  			// This should never occur, this is called from a SCI1.1 - SCI2.1 only function diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 93b3a997cc..b464d347bd 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -465,7 +465,7 @@ void Script::syncStringHeap(Common::Serializer &s) {  				break;  		} while (1); -	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1){ +	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE){  		// Strings in SCI1.1 come after the object instances  		byte *buf = _heapStart + 4 + READ_SCI11ENDIAN_UINT16(_heapStart + 2) * 2; diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 36e33ccfa6..26a7ff5718 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -84,7 +84,7 @@ void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptP  	if (getSciVersion() == SCI_VERSION_0_EARLY) {  		_bufSize += READ_LE_UINT16(script->data) * 2; -	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) { +	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE) {  		// In SCI1.1 - SCI2.1, the heap was in a separate space from the script. We append  		// it to the end of the script, and adjust addressing accordingly.  		// However, since we address the heap with a 16-bit pointer, the @@ -142,7 +142,7 @@ void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptP  	assert(_bufSize >= script->size);  	memcpy(_buf, script->data, script->size); -	if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) { +	if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE) {  		Resource *heap = resMan->findResource(ResourceId(kResourceTypeHeap, _nr), 0);  		assert(heap != 0); @@ -171,7 +171,7 @@ void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptP  			_localsOffset = localsBlock - _buf + 4;  			_localsCount = (READ_LE_UINT16(_buf + _localsOffset - 2) - 4) >> 1;	// half block size  		} -	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) { +	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE) {  		if (READ_LE_UINT16(_buf + 1 + 5) > 0) {	// does the script have an export table?  			_exportTable = (const uint16 *)(_buf + 1 + 5 + 2);  			_numExports = READ_SCI11ENDIAN_UINT16(_exportTable - 1); @@ -387,7 +387,7 @@ void Script::identifyOffsets() {  			scriptDataLeft -= blockSize;  		} while (1); -	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) { +	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE) {  		// Strings in SCI1.1 up to SCI2 come after the object instances  		scriptDataPtr = _heapStart;  		scriptDataLeft = _heapSize; @@ -668,7 +668,7 @@ static bool relocateBlock(Common::Array<reg_t> &block, int block_location, Segme  		return false;  	}  	block[idx].setSegment(segment); // Perform relocation -	if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) +	if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE)  		block[idx].incOffset(scriptSize);  	return true; @@ -702,7 +702,7 @@ void Script::relocateSci0Sci21(reg_t block) {  	uint16 heapSize = (uint16)_bufSize;  	uint16 heapOffset = 0; -	if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) { +	if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE) {  		heap = _heapStart;  		heapSize = (uint16)_heapSize;  		heapOffset = _scriptSize; @@ -930,7 +930,7 @@ void Script::initializeClasses(SegManager *segMan) {  	if (getSciVersion() <= SCI_VERSION_1_LATE) {  		seeker = findBlockSCI0(SCI_OBJ_CLASS);  		mult = 1; -	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) { +	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE) {  		seeker = _heapStart + 4 + READ_SCI11ENDIAN_UINT16(_heapStart + 2) * 2;  		mult = 2;  	} else if (getSciVersion() == SCI_VERSION_3) { @@ -962,7 +962,7 @@ void Script::initializeClasses(SegManager *segMan) {  			if (isClass)  				species = READ_SCI11ENDIAN_UINT16(seeker + 12);  			classpos += 12; -		} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) { +		} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE) {  			isClass = (READ_SCI11ENDIAN_UINT16(seeker + 14) & kInfoFlagClass);	// -info- selector  			species = READ_SCI11ENDIAN_UINT16(seeker + 10);  		} else if (getSciVersion() == SCI_VERSION_3) { @@ -1104,7 +1104,7 @@ void Script::initializeObjectsSci3(SegManager *segMan, SegmentId segmentId) {  void Script::initializeObjects(SegManager *segMan, SegmentId segmentId) {  	if (getSciVersion() <= SCI_VERSION_1_LATE)  		initializeObjectsSci0(segMan, segmentId); -	else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) +	else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE)  		initializeObjectsSci11(segMan, segmentId);  	else if (getSciVersion() == SCI_VERSION_3)  		initializeObjectsSci3(segMan, segmentId); diff --git a/engines/sci/engine/static_selectors.cpp b/engines/sci/engine/static_selectors.cpp index 188da3d5a2..8aa1697f07 100644 --- a/engines/sci/engine/static_selectors.cpp +++ b/engines/sci/engine/static_selectors.cpp @@ -114,16 +114,16 @@ static const SelectorRemap sciSelectorRemap[] = {  	{        SCI_VERSION_1_1,        SCI_VERSION_1_1, "cantBeHere",   54 },  	// The following are not really needed. They've only been defined to  	// ease game debugging. -	{        SCI_VERSION_1_1,        SCI_VERSION_2_1,    "-objID-", 4096 }, -	{        SCI_VERSION_1_1,        SCI_VERSION_2_1,     "-size-", 4097 }, -	{        SCI_VERSION_1_1,        SCI_VERSION_2_1, "-propDict-", 4098 }, -	{        SCI_VERSION_1_1,        SCI_VERSION_2_1, "-methDict-", 4099 }, -	{        SCI_VERSION_1_1,        SCI_VERSION_2_1, "-classScript-", 4100 }, -	{        SCI_VERSION_1_1,        SCI_VERSION_2_1,   "-script-", 4101 }, -	{        SCI_VERSION_1_1,        SCI_VERSION_2_1,    "-super-", 4102 }, +	{        SCI_VERSION_1_1,        SCI_VERSION_2_1_LATE,    "-objID-", 4096 }, +	{        SCI_VERSION_1_1,        SCI_VERSION_2_1_LATE,     "-size-", 4097 }, +	{        SCI_VERSION_1_1,        SCI_VERSION_2_1_LATE, "-propDict-", 4098 }, +	{        SCI_VERSION_1_1,        SCI_VERSION_2_1_LATE, "-methDict-", 4099 }, +	{        SCI_VERSION_1_1,        SCI_VERSION_2_1_LATE, "-classScript-", 4100 }, +	{        SCI_VERSION_1_1,        SCI_VERSION_2_1_LATE,   "-script-", 4101 }, +	{        SCI_VERSION_1_1,        SCI_VERSION_2_1_LATE,    "-super-", 4102 },  	// -	{        SCI_VERSION_1_1,        SCI_VERSION_2_1,     "-info-", 4103 }, -	{ SCI_VERSION_NONE,             SCI_VERSION_NONE,            0,    0 } +	{        SCI_VERSION_1_1,        SCI_VERSION_2_1_LATE,     "-info-", 4103 }, +	{        SCI_VERSION_NONE,           SCI_VERSION_NONE,            0,    0 }  };  struct ClassReference { diff --git a/engines/sci/engine/vm_types.cpp b/engines/sci/engine/vm_types.cpp index 65a82832cc..cf008c45e1 100644 --- a/engines/sci/engine/vm_types.cpp +++ b/engines/sci/engine/vm_types.cpp @@ -29,7 +29,7 @@  namespace Sci {  SegmentId reg_t::getSegment() const { -	if (getSciVersion() <= SCI_VERSION_2_1) { +	if (getSciVersion() < SCI_VERSION_3) {  		return _segment;  	} else {  		// Return the lower 14 bits of the segment @@ -38,7 +38,7 @@ SegmentId reg_t::getSegment() const {  }  void reg_t::setSegment(SegmentId segment) { -	if (getSciVersion() <= SCI_VERSION_2_1) { +	if (getSciVersion() < SCI_VERSION_3) {  		_segment = segment;  	} else {  		// Set the lower 14 bits of the segment, and preserve the upper 2 ones for the offset @@ -47,7 +47,7 @@ void reg_t::setSegment(SegmentId segment) {  }  uint32 reg_t::getOffset() const { -	if (getSciVersion() <= SCI_VERSION_2_1) { +	if (getSciVersion() < SCI_VERSION_3) {  		return _offset;  	} else {  		// Return the lower 16 bits from the offset, and the 17th and 18th bits from the segment @@ -56,7 +56,7 @@ uint32 reg_t::getOffset() const {  }  void reg_t::setOffset(uint32 offset) { -	if (getSciVersion() <= SCI_VERSION_2_1) { +	if (getSciVersion() < SCI_VERSION_3) {  		_offset = offset;  	} else {  		// Store the lower 16 bits in the offset, and the 17th and 18th bits in the segment  | 
