[Scummvm-cvs-logs] SF.net SVN: scummvm:[54398] scummvm/trunk/engines/sci/engine

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Sun Nov 21 01:44:05 CET 2010


Revision: 54398
          http://scummvm.svn.sourceforge.net/scummvm/?rev=54398&view=rev
Author:   thebluegr
Date:     2010-11-21 00:44:04 +0000 (Sun, 21 Nov 2010)

Log Message:
-----------
SCI: Added a heuristic to detect the modified late SCI2.1/SCI3 kString/kArray kernel functions

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/features.cpp
    scummvm/trunk/engines/sci/engine/features.h

Modified: scummvm/trunk/engines/sci/engine/features.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/features.cpp	2010-11-21 00:02:25 UTC (rev 54397)
+++ scummvm/trunk/engines/sci/engine/features.cpp	2010-11-21 00:44:04 UTC (rev 54398)
@@ -40,16 +40,16 @@
 	_gfxFunctionsType = SCI_VERSION_NONE;
 	_messageFunctionType = SCI_VERSION_NONE;
 	_moveCountType = kMoveCountUninitialized;
-
 #ifdef ENABLE_SCI32
 	_sci21KernelType = SCI_VERSION_NONE;
+	_sci2StringFunctionType = kSci2StringFunctionUninitialized;
 #endif
 	_usesCdTrack = Common::File::exists("cdaudio.map");
 }
 
 reg_t GameFeatures::getDetectionAddr(const Common::String &objName, Selector slc, int methodNum) {
 	// Get address of target object
-	reg_t objAddr = _segMan->findObjectByName(objName);
+	reg_t objAddr = _segMan->findObjectByName(objName, 0);
 	reg_t addr;
 
 	if (objAddr.isNull()) {
@@ -528,6 +528,65 @@
 	}
 	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.segment)
+		return false;
+
+	uint16 offset = addr.offset;
+	Script *script = _segMan->getScript(addr.segment);
+
+	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() {

Modified: scummvm/trunk/engines/sci/engine/features.h
===================================================================
--- scummvm/trunk/engines/sci/engine/features.h	2010-11-21 00:02:25 UTC (rev 54397)
+++ scummvm/trunk/engines/sci/engine/features.h	2010-11-21 00:44:04 UTC (rev 54398)
@@ -37,6 +37,12 @@
 	kIncrementMoveCount
 };
 
+enum Sci2StringFunctionType {
+	kSci2StringFunctionUninitialized,
+	kSci2StringFunctionOld,
+	kSci2StringFunctionNew
+};
+
 class GameFeatures {
 public:
 	GameFeatures(SegManager *segMan, Kernel *kernel);
@@ -79,6 +85,13 @@
 	 * @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
 
 	/**
@@ -109,11 +122,13 @@
 	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;


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list