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

waltervn at users.sourceforge.net waltervn at users.sourceforge.net
Mon Aug 17 17:49:22 CEST 2009


Revision: 43482
          http://scummvm.svn.sourceforge.net/scummvm/?rev=43482&view=rev
Author:   waltervn
Date:     2009-08-17 15:49:22 +0000 (Mon, 17 Aug 2009)

Log Message:
-----------
SCI: Add autodetection for DoSound. Cleanup.

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/kernel.cpp
    scummvm/trunk/engines/sci/engine/kernel.h
    scummvm/trunk/engines/sci/engine/ksound.cpp
    scummvm/trunk/engines/sci/engine/savegame.cpp
    scummvm/trunk/engines/sci/engine/state.cpp
    scummvm/trunk/engines/sci/engine/state.h
    scummvm/trunk/engines/sci/resource.cpp
    scummvm/trunk/engines/sci/resource.h
    scummvm/trunk/engines/sci/sci.cpp

Modified: scummvm/trunk/engines/sci/engine/kernel.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.cpp	2009-08-17 13:49:56 UTC (rev 43481)
+++ scummvm/trunk/engines/sci/engine/kernel.cpp	2009-08-17 15:49:22 UTC (rev 43482)
@@ -370,8 +370,8 @@
 Kernel::Kernel(ResourceManager *resmgr) : _resmgr(resmgr) {
 	memset(&_selectorMap, 0, sizeof(_selectorMap));	// FIXME: Remove this once/if we C++ify selector_map_t
 
-	detectSciFeatures(); // must be called before loadSelectorNames()
 	loadSelectorNames();
+	detectSciFeatures();
 	mapSelectors();      // Map a few special selectors for later use
 	loadOpcodes();
 	loadKernelNames();
@@ -382,61 +382,30 @@
 }
 
 void Kernel::detectSciFeatures() {
-	// FIXME Much of this is unreliable
+	SciVersion version = _resmgr->sciVersion();
 
-	Resource *r = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES), 0);
-
-	Common::StringList staticSelectorTable;
-	
-	if (!r) { // No such resource?
-		staticSelectorTable = checkStaticSelectorNames();
-		if (staticSelectorTable.empty())
-			error("Kernel: Could not retrieve selector names");
-	}
-
-	int count = staticSelectorTable.empty() ? READ_LE_UINT16(r->data) + 1 : staticSelectorTable.size(); // Counter is slightly off
 	features = 0;
 
 	// Initialize features based on SCI version
-	switch (_resmgr->sciVersion()) {
-	case SCI_VERSION_0_EARLY:
-		features |= kFeatureOldScriptHeader;
-		/* Fallthrough */
-	case SCI_VERSION_0_LATE:
-		features |= kFeatureOldGfxFunctions;
-		break;
-	default:
-		break;
+
+	// Script header and graphics functions
+	if (version == SCI_VERSION_0_EARLY) {
+		features |= kFeatureOldScriptHeader | kFeatureOldGfxFunctions;
+	} else if (version == SCI_VERSION_0_LATE) {
+		if (findSelector("motionCue") == -1)
+			features |= kFeatureOldGfxFunctions;
 	}
 
-	for (int i = 0; i < count; i++) {
-		Common::String tmp;
-		
-		if (staticSelectorTable.empty()) {
-			int offset = READ_LE_UINT16(r->data + 2 + i * 2);
-			int len = READ_LE_UINT16(r->data + offset);
-			
-			tmp = Common::String((const char *)r->data + offset + 2, len);
-		} else {
-			tmp = staticSelectorTable[i];
-		}
-
-		if (tmp == "motionCue")
-			features &= ~kFeatureOldGfxFunctions;
-
-		if (tmp == "egoMoveSpeed" && _resmgr->sciVersion() < SCI_VERSION_1_1)
+	// Lofs absolute/relative
+	if (version >= SCI_VERSION_1_MIDDLE && version < SCI_VERSION_1_1) {
+		// Assume all games use absolute lofs
+		features |= kFeatureLofsAbsolute;
+	} else if (version == SCI_VERSION_1_EARLY) {
+		// Use heuristic
+		if (findSelector("egoMoveSpeed") != -1)
 			features |= kFeatureLofsAbsolute;
-
-		if (tmp == "setVol")
-			features |= kFeatureSci1Sound;
-
-		if (tmp == "nodePtr")
-			features |= kFeatureSci01Sound;
 	}
 
-	if (features & kFeatureSci1Sound)
-		features &= ~kFeatureSci01Sound;
-
 	printf("Kernel auto-detected features:\n");
 
 	printf("Graphics functions: ");
@@ -445,19 +414,13 @@
 	else
 		printf("new\n");
 
-	printf("lofs parameters: ");
-	if (features & kFeatureLofsAbsolute)
-		printf("absolute\n");
-	else
-		printf("relative\n");
-
-	printf("Sound functions: ");
-	if (features & kFeatureSci1Sound)
-		printf("SCI1\n");
-	else if (features & kFeatureSci01Sound)
-		printf("SCI01\n");
-	else
-		printf("SCI0\n");
+	if (version < SCI_VERSION_1_1) {
+		printf("lofs parameters: ");
+		if (features & kFeatureLofsAbsolute)
+			printf("absolute\n");
+		else
+			printf("relative\n");
+	}
 }
 
 void Kernel::loadSelectorNames() {
@@ -473,7 +436,7 @@
 		
 		for (uint32 i = 0; i < staticSelectorTable.size(); i++) {
 			_selectorNames.push_back(staticSelectorTable[i]);
-			if (features & kFeatureOldScriptHeader)
+			if (_resmgr->sciVersion() == SCI_VERSION_0_EARLY)
 				_selectorNames.push_back(staticSelectorTable[i]);
 		}
 			
@@ -492,7 +455,7 @@
 
 		// Early SCI versions used the LSB in the selector ID as a read/write
 		// toggle. To compensate for that, we add every selector name twice.
-		if (features & kFeatureOldScriptHeader)
+		if (_resmgr->sciVersion() == SCI_VERSION_0_EARLY)
 			_selectorNames.push_back(tmp);
 	}
 }

Modified: scummvm/trunk/engines/sci/engine/kernel.h
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.h	2009-08-17 13:49:56 UTC (rev 43481)
+++ scummvm/trunk/engines/sci/engine/kernel.h	2009-08-17 15:49:22 UTC (rev 43482)
@@ -60,9 +60,7 @@
 enum AutoDetectedFeatures {
 	kFeatureOldScriptHeader = 1 << 0,
 	kFeatureOldGfxFunctions = 1 << 1,
-	kFeatureLofsAbsolute    = 1 << 2,
-	kFeatureSci01Sound      = 1 << 3,
-	kFeatureSci1Sound       = 1 << 4
+	kFeatureLofsAbsolute    = 1 << 2
 };
 
 class Kernel {
@@ -119,16 +117,6 @@
 	 */
 	bool hasLofsAbsolute() const { return (features & kFeatureLofsAbsolute); }
 
-	/**
-	 * Determines if the game is using SCI01 sound functions
-	 */
-	bool usesSci01SoundFunctions() const { return (features & kFeatureSci01Sound); }
-
-	/**
-	 * Determines if the game is using SCI1 sound functions
-	 */
-	bool usesSci1SoundFunctions() const { return (features & kFeatureSci1Sound); }
-
 	// Script dissection/dumping functions
 	void dissectScript(int scriptNumber, Vocabulary *vocab);
 	void dumpScriptObject(char *data, int seeker, int objsize);

Modified: scummvm/trunk/engines/sci/engine/ksound.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/ksound.cpp	2009-08-17 13:49:56 UTC (rev 43481)
+++ scummvm/trunk/engines/sci/engine/ksound.cpp	2009-08-17 15:49:22 UTC (rev 43482)
@@ -204,7 +204,7 @@
 }
 
 
-reg_t kDoSound_SCI0(EngineState *s, int funct_nr, int argc, reg_t *argv) {
+reg_t kDoSoundSci0(EngineState *s, int funct_nr, int argc, reg_t *argv) {
 	reg_t obj = (argc > 1) ? argv[1] : NULL_REG;
 	uint16 command = argv[0].toUint16();
 	SongHandle handle = FROBNICATE_HANDLE(obj);
@@ -383,7 +383,7 @@
 }
 
 
-reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) {
+reg_t kDoSoundSci1Early(EngineState *s, int funct_nr, int argc, reg_t *argv) {
 	uint16 command = argv[0].toUint16();
 	reg_t obj = (argc > 1) ? argv[1] : NULL_REG;
 	SongHandle handle = FROBNICATE_HANDLE(obj);
@@ -673,7 +673,7 @@
 	return s->r_acc;
 }
 
-reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) {
+reg_t kDoSoundSci1Late(EngineState *s, int funct_nr, int argc, reg_t *argv) {
 	uint16 command = argv[0].toUint16();
 	reg_t obj = (argc > 1) ? argv[1] : NULL_REG;
 	SongHandle handle = FROBNICATE_HANDLE(obj);
@@ -988,12 +988,17 @@
  * Used for synthesized music playback
  */
 reg_t kDoSound(EngineState *s, int funct_nr, int argc, reg_t *argv) {
-	if (((SciEngine*)g_engine)->getKernel()->usesSci1SoundFunctions())
-		return kDoSound_SCI1(s, funct_nr, argc, argv);
-	else if (((SciEngine*)g_engine)->getKernel()->usesSci01SoundFunctions())
-		return kDoSound_SCI01(s, funct_nr, argc, argv);
-	else
-		return kDoSound_SCI0(s, funct_nr, argc, argv);
+	switch(s->detectDoSoundType()) {
+	case EngineState::kDoSoundTypeSci0:
+		return kDoSoundSci0(s, funct_nr, argc, argv);
+	case EngineState::kDoSoundTypeSci1Early:
+		return kDoSoundSci1Early(s, funct_nr, argc, argv);
+	case EngineState::kDoSoundTypeSci1Late:
+		return kDoSoundSci1Late(s, funct_nr, argc, argv);
+	default:
+		warning("Unknown DoSound type");
+		return NULL_REG;
+	}
 }
 
 /**

Modified: scummvm/trunk/engines/sci/engine/savegame.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/savegame.cpp	2009-08-17 13:49:56 UTC (rev 43481)
+++ scummvm/trunk/engines/sci/engine/savegame.cpp	2009-08-17 15:49:22 UTC (rev 43482)
@@ -701,8 +701,7 @@
 	Song *seeker;
 	SongIteratorType it_type;
 
-	if (((SciEngine *)g_engine)->getKernel()->usesSci01SoundFunctions()
-		|| ((SciEngine *)g_engine)->getKernel()->usesSci1SoundFunctions())
+	if (s->_version > SCI_VERSION_01)
 		it_type = SCI_SONG_ITERATOR_TYPE_SCI1;
 	else
 		it_type = SCI_SONG_ITERATOR_TYPE_SCI0;

Modified: scummvm/trunk/engines/sci/engine/state.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/state.cpp	2009-08-17 13:49:56 UTC (rev 43481)
+++ scummvm/trunk/engines/sci/engine/state.cpp	2009-08-17 15:49:22 UTC (rev 43482)
@@ -24,6 +24,8 @@
  */
 
 #include "sci/engine/state.h"
+#include "sci/engine/vm.h"
+#include "sci/console.h" // For parse_reg_t
 
 namespace Sci {
 
@@ -116,6 +118,8 @@
 	successor = 0;
 
 	speedThrottler = new SpeedThrottler(version);
+
+	_doSoundType = kDoSoundTypeUnknown;
 }
 
 EngineState::~EngineState() {
@@ -242,4 +246,75 @@
 	return retval;
 }
 
+EngineState::DoSoundType EngineState::detectDoSoundType() {
+	if (_doSoundType == kDoSoundTypeUnknown) {
+		reg_t soundClass;
+		const uint checkBytes = 6; // Number of bytes to check
+
+		if (!parse_reg_t(this, "?Sound", &soundClass)) {
+			reg_t fptr;
+
+			Object *obj = obj_get(this, soundClass);
+			SelectorType sel = lookup_selector(this, soundClass, ((SciEngine*)g_engine)->getKernel()->_selectorMap.play, NULL, &fptr);
+
+			if (obj && (sel == kSelectorMethod)) {
+				Script *script = seg_manager->getScript(fptr.segment);
+
+				if (fptr.offset > checkBytes) {
+					// Go to the last portion of Sound::init, should be right before the play function
+					fptr.offset -= checkBytes;
+					byte *buf = script->buf + fptr.offset;
+
+					// Check the call to DoSound's INIT_HANDLE function.
+					// It's either subfunction 0, 5 or 6, depending on the version of DoSound.
+					uint sum = 0;
+					for (uint i = 0; i < checkBytes; i++)
+						sum += buf[i];
+
+					switch(sum) {
+					case 0x1B2: // SCI0
+					case 0x1AE: // SCI01
+						_doSoundType = kDoSoundTypeSci0;
+						break;
+					case 0x13D:
+						_doSoundType = kDoSoundTypeSci1Early;
+						break;
+					case 0x13E:
+						_doSoundType = kDoSoundTypeSci1Late;
+					}
+				}
+			}
+		}
+
+		if (_doSoundType == kDoSoundTypeUnknown) {
+			warning("DoSound detection failed, taking an educated guess");
+
+			if (_version >= SCI_VERSION_1_MIDDLE)
+				_doSoundType = kDoSoundTypeSci1Late;
+			else if (_version > SCI_VERSION_01)
+				_doSoundType = kDoSoundTypeSci1Early;
+			else
+				_doSoundType = kDoSoundTypeSci0;
+		}
+
+		debugCN(1, kDebugLevelSound, "Detected DoSound type: ");
+
+		switch(_doSoundType) {
+		case kDoSoundTypeSci0:
+			debugC(1, kDebugLevelSound, "SCI0");
+			break;
+		case kDoSoundTypeSci1Early:
+			debugC(1, kDebugLevelSound, "SCI1 Early");
+			break;
+		case kDoSoundTypeSci1Late:
+			debugC(1, kDebugLevelSound, "SCI1 Late");
+			break;
+		default:
+			break;
+		}
+	}
+
+	return _doSoundType;
+}
+
 } // End of namespace Sci

Modified: scummvm/trunk/engines/sci/engine/state.h
===================================================================
--- scummvm/trunk/engines/sci/engine/state.h	2009-08-17 13:49:56 UTC (rev 43481)
+++ scummvm/trunk/engines/sci/engine/state.h	2009-08-17 15:49:22 UTC (rev 43482)
@@ -163,6 +163,14 @@
 public:
 	EngineState(ResourceManager *res, SciVersion version, uint32 flags);
 	virtual ~EngineState();
+
+	enum DoSoundType {
+		kDoSoundTypeUnknown,
+		kDoSoundTypeSci0,
+		kDoSoundTypeSci1Early,
+		kDoSoundTypeSci1Late
+	};
+
 	virtual void saveLoadWithSerializer(Common::Serializer &ser);
 
 	kLanguage getLanguage();
@@ -272,6 +280,12 @@
 	 */
 	Common::String strSplit(const char *str, const char *sep = "\r----------\r");
 
+	/**
+	 * Autodetects the DoSound type
+	 * @return DoSound type
+	 */
+	DoSoundType detectDoSoundType();
+
 	/* Debugger data: */
 	Breakpoint *bp_list;   /**< List of breakpoints */
 	int have_bp;  /**< Bit mask specifying which types of breakpoints are used in bp_list */
@@ -301,6 +315,7 @@
 	EngineState *successor; /**< Successor of this state: Used for restoring */
 
 private:
+	DoSoundType _doSoundType;
 	kLanguage charToLanguage(const char c) const;
 	Common::String getLanguageString(const char *str, kLanguage lang) const;
 };

Modified: scummvm/trunk/engines/sci/resource.cpp
===================================================================
--- scummvm/trunk/engines/sci/resource.cpp	2009-08-17 13:49:56 UTC (rev 43481)
+++ scummvm/trunk/engines/sci/resource.cpp	2009-08-17 15:49:22 UTC (rev 43482)
@@ -1480,7 +1480,7 @@
 		// If this turns out to be unreliable, we could do some pic resource checks instead.
 		return SCI_VERSION_1_EARLY;
 	case kResVersionSci1Middle:
-		return SCI_VERSION_1_LATE;
+		return SCI_VERSION_1_MIDDLE;
 	case kResVersionSci1Late:
 		if (_viewType == kViewVga11) {
 			// SCI1.1 resources, assume SCI1.1

Modified: scummvm/trunk/engines/sci/resource.h
===================================================================
--- scummvm/trunk/engines/sci/resource.h	2009-08-17 13:49:56 UTC (rev 43481)
+++ scummvm/trunk/engines/sci/resource.h	2009-08-17 15:49:22 UTC (rev 43482)
@@ -52,7 +52,8 @@
 	SCI_VERSION_01, // KQ1 and multilingual games (S.old.*)
 	SCI_VERSION_1_EGA, // EGA with parser, QFG2
 	SCI_VERSION_1_EARLY, // KQ5. (EGA/VGA)
-	SCI_VERSION_1_LATE, // ECO1, LSL1, LSL5. (EGA/VGA)
+	SCI_VERSION_1_MIDDLE, // LSL1, JONESCD. (EGA?/VGA)
+	SCI_VERSION_1_LATE, // ECO1, LSL5. (EGA/VGA)
 	SCI_VERSION_1_1, // KQ6, ECO2
 	SCI_VERSION_32 // GK
 };

Modified: scummvm/trunk/engines/sci/sci.cpp
===================================================================
--- scummvm/trunk/engines/sci/sci.cpp	2009-08-17 13:49:56 UTC (rev 43481)
+++ scummvm/trunk/engines/sci/sci.cpp	2009-08-17 15:49:22 UTC (rev 43482)
@@ -44,13 +44,14 @@
 class GfxDriver;
 
 // FIXME: error-prone
-const char *versionNames[9] = {
+const char *versionNames[10] = {
 	"Autodetect",
 	"SCI0 Early",
 	"SCI0 Late",
 	"SCI01",
 	"SCI1 EGA",
 	"SCI1 Early",
+	"SCI1 Middle",
 	"SCI1 Late",
 	"SCI1.1",
 	"SCI32"


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