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

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Fri Nov 20 17:39:36 CET 2009


Revision: 46012
          http://scummvm.svn.sourceforge.net/scummvm/?rev=46012&view=rev
Author:   thebluegr
Date:     2009-11-20 16:39:31 +0000 (Fri, 20 Nov 2009)

Log Message:
-----------
- Removed the non-static selectors "overlay" and "setCursor" from the list of static selectors and introduced a new method for discovering the relevant features when selectors are missing - currently used for determining the graphics functions and setCursor types
- Simplified setCursor detection a bit

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

Modified: scummvm/trunk/engines/sci/engine/state.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/state.cpp	2009-11-20 15:31:08 UTC (rev 46011)
+++ scummvm/trunk/engines/sci/engine/state.cpp	2009-11-20 16:39:31 UTC (rev 46012)
@@ -233,6 +233,70 @@
 	return retval;
 }
 
+bool EngineState::callsKernelFunc(reg_t objAddr, int kernelFunc) {
+	Script *script = _segMan->getScript(objAddr.segment);
+	uint16 offset = objAddr.offset;
+
+	do {
+		uint16 kFuncNum;
+		int opsize = script->_buf[offset++];
+		uint opcode = opsize >> 1;
+		int i = 0;
+		byte argc;
+
+		while (g_opcode_formats[opcode][i]) {
+			switch (g_opcode_formats[opcode][i++]) {
+			case Script_Invalid:
+				break;
+			case Script_SByte:
+			case Script_Byte:
+				offset++;
+				break;
+			case Script_Word:
+			case Script_SWord:
+				offset += 2;
+				break;
+			case Script_SVariable:
+			case Script_Variable:
+			case Script_Property:
+			case Script_Global:
+			case Script_Local:
+			case Script_Temp:
+			case Script_Param:
+				if (opsize & 1)
+					kFuncNum = script->_buf[offset++];
+				else {
+					kFuncNum = 0xffff & (script->_buf[offset] | (script->_buf[offset + 1] << 8));
+					offset += 2;
+				}
+
+				if (opcode == op_callk) {
+					argc = script->_buf[offset++];
+
+					if (kFuncNum == kernelFunc)
+						return true;
+				}
+				break;
+
+			case Script_Offset:
+			case Script_SRelative:
+				offset++;
+				if (!opsize & 1)
+					offset++;
+				break;
+			case Script_End:
+				offset = 0;	// exit loop
+				break;
+			default:
+				warning("opcode %02x: Invalid", opcode);
+
+			}
+		}
+	} while (offset > 0);
+
+	return false;	// not found
+}
+
 bool EngineState::autoDetectFeature(FeatureDetection featureDetection, int methodNum) {
 	Common::String objName;
 	Selector slc;
@@ -276,7 +340,7 @@
 		return false;
 	}
 
-	if (featureDetection != kDetectLofsType) {
+	if (methodNum == -1) {
 		if (lookup_selector(_segMan, objAddr, slc, NULL, &addr) != kSelectorMethod) {
 			warning("autoDetectFeature: target selector is not a method of object %s", objName.c_str());
 			return false;
@@ -460,8 +524,34 @@
 		if (getSciVersion() <= SCI_VERSION_01) {
 			// SCI0/SCI01 games never use cursor views
 			_setCursorType = SCI_VERSION_0_EARLY;
+		} else if (getSciVersion() >= SCI_VERSION_1_1) {
+			// SCI1.1 games always use cursor views
+			_setCursorType = SCI_VERSION_1_1;
 		} else {
-			if (!autoDetectFeature(kDetectSetCursorType)) {
+			bool found = false;
+
+			if (_kernel->_selectorCache.setCursor == -1) {
+				// Find which function of the Game object calls setCursor
+				int foundMethod = -1;
+
+				Object *obj = _segMan->getObject(_segMan->findObjectByName("Game"));
+				for (uint m = 0; m < obj->getMethodCount(); m++) {
+					found = callsKernelFunc(obj->getFunction(m), 40);	// kSetCursor (SCI0-SCI11)
+
+					if (found) {
+						foundMethod = m;
+						break;
+					}
+				}
+
+				if (found)
+					found = autoDetectFeature(kDetectSetCursorType, foundMethod);
+			} else {
+				found = autoDetectFeature(kDetectSetCursorType);
+			}
+
+			if (!found) {
+				// Quite normal in several demos which don't have a cursor
 				warning("SetCursor detection failed, taking an educated guess");
 
 				if (getSciVersion() >= SCI_VERSION_1_1)
@@ -533,7 +623,26 @@
 				_gfxFunctionsType = SCI_VERSION_0_LATE;
 			} else {
 				// No shiftparser selector, check if the game is using an overlay
-				if (_kernel->_selectorCache.overlay == -1) {
+				bool hasOverlaySelector = (_kernel->_selectorCache.overlay != -1);
+				int foundMethod = -1;
+
+				if (!hasOverlaySelector) {
+					// No overlay selector found, check if any method of the Rm object
+					// is calling kDrawPic, as the overlay selector might be missing in demos
+
+					Object *obj = _segMan->getObject(_segMan->findObjectByName("Rm"));
+					bool found = false;
+					for (uint m = 0; m < obj->getMethodCount(); m++) {
+						found = callsKernelFunc(obj->getFunction(m), 8);	// kDrawPic	(SCI0 - SCI11)
+
+						if (found) {
+							foundMethod = m;
+							break;
+						}
+					}
+				}
+
+				if (!hasOverlaySelector && foundMethod == -1) {
 					// No overlay selector found, therefore the game is definitely
 					// using old graphics functions
 					_gfxFunctionsType = SCI_VERSION_0_EARLY;
@@ -543,7 +652,7 @@
 					// overlay. Therefore, check it to see how it calls kDrawPic to
 					// determine the graphics functions type used
 
-					if (!autoDetectFeature(kDetectGfxFunctions)) {
+					if (!autoDetectFeature(kDetectGfxFunctions, foundMethod)) {
 						warning("Graphics functions detection failed, taking an educated guess");
 
 						// Try detecting the graphics function types from the existence of the motionCue

Modified: scummvm/trunk/engines/sci/engine/state.h
===================================================================
--- scummvm/trunk/engines/sci/engine/state.h	2009-11-20 15:31:08 UTC (rev 46011)
+++ scummvm/trunk/engines/sci/engine/state.h	2009-11-20 16:39:31 UTC (rev 46012)
@@ -294,6 +294,7 @@
 
 private:
 	bool autoDetectFeature(FeatureDetection featureDetection, int methodNum = -1);
+	bool callsKernelFunc(reg_t objAddr, int kernelFunc);
 
 	SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType;
 	MoveCountType _moveCountType;

Modified: scummvm/trunk/engines/sci/engine/static_selectors.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/static_selectors.cpp	2009-11-20 15:31:08 UTC (rev 46011)
+++ scummvm/trunk/engines/sci/engine/static_selectors.cpp	2009-11-20 16:39:31 UTC (rev 46012)
@@ -63,23 +63,22 @@
 
 // Taken from Codename: Iceman (Full Game)
 static const SelectorRemap sci0SelectorRemap[] = {
-    {     "moveDone", 170 }, {    "setCursor", 254 }, {      "overlay", 270 },
-	{      "points",  316 }, {        "flags", 368 }, {              0,   0 }
+    {     "moveDone", 170 }, {      "points",  316 }, {        "flags", 368 },
+	{              0,   0 }
 };
 
 // Taken from Leisure Suit Larry 1 VGA (Full Game)
 static const SelectorRemap sci1SelectorRemap[] = {
 	{      "nodePtr",  44 }, {   "cantBeHere",  57 }, {    "topString", 101 },
-	{        "flags", 102 }, {    "setCursor", 183 }, {     "syncTime", 247 },
-	{      "syncCue", 248 }, {              0,   0 }
+	{        "flags", 102 }, {     "syncTime", 247 }, {      "syncCue", 248 },
+	{              0,   0 }
 };
 
 // Taken from KQ6 floppy (Full Game)
 static const SelectorRemap sci11SelectorRemap[] = {
 	{      "nodePtr",  41 }, {   "cantBeHere",  54 }, {     "topString", 98 },
 	{        "flags",  99 }, {       "scaleX", 104 }, {       "scaleY", 105 },
-	{    "setCursor", 197 }, {     "syncTime", 279 }, {      "syncCue", 280 },
-	{              0,   0 }
+	{     "syncTime", 279 }, {      "syncCue", 280 }, {              0,   0 }
 };
 
 Common::StringList Kernel::checkStaticSelectorNames() {


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