[Scummvm-git-logs] scummvm master -> d2f5023ee9ec5534a9f7a4754c4f1e805c0fb605

bluegr bluegr at gmail.com
Sat Jun 8 12:58:39 CEST 2019


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
d2f5023ee9 SCI: Do not apply script patches when checking for static selectors


Commit: d2f5023ee9ec5534a9f7a4754c4f1e805c0fb605
    https://github.com/scummvm/scummvm/commit/d2f5023ee9ec5534a9f7a4754c4f1e805c0fb605
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2019-06-08T13:57:34+03:00

Commit Message:
SCI: Do not apply script patches when checking for static selectors

Fixes bug #10969

Changed paths:
    engines/sci/engine/kernel.cpp
    engines/sci/engine/kernel.h
    engines/sci/engine/script.cpp
    engines/sci/engine/script.h
    engines/sci/engine/script_patches.cpp
    engines/sci/engine/seg_manager.cpp
    engines/sci/engine/seg_manager.h
    engines/sci/engine/static_selectors.cpp


diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 17f799a..d75c910 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -112,11 +112,6 @@ int Kernel::findSelector(const char *selectorName) const {
 	return -1;
 }
 
-// used by Script patcher to figure out, if it's okay to initialize signature/patch-table
-bool Kernel::selectorNamesAvailable() {
-	return !_selectorNames.empty();
-}
-
 void Kernel::loadSelectorNames() {
 	Resource *r = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SELECTORS), 0);
 	bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 558224f..a27df1a 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -168,8 +168,6 @@ public:
 	 */
 	int findSelector(const char *selectorName) const;
 
-	bool selectorNamesAvailable();
-
 	// Script dissection/dumping functions
 	void dissectScript(int scriptNumber, Vocabulary *vocab);
 	void dumpScriptObject(const SciSpan<const byte> &script, SciSpan<const byte> object);
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 0dea692..25d1283 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -80,7 +80,7 @@ enum {
 	kSci11ExportTableOffset = 8
 };
 
-void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher) {
+void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher, bool applyScriptPatches) {
 	freeScript();
 
 	Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, script_nr), false);
@@ -147,7 +147,8 @@ void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptP
 	}
 
 	// Check scripts (+ possibly SCI 1.1 heap) for matching signatures and patch those, if found
-	scriptPatcher->processScript(_nr, outBuffer);
+	if (applyScriptPatches)
+		scriptPatcher->processScript(_nr, outBuffer);
 
 	if (getSciVersion() <= SCI_VERSION_1_LATE) {
 		// Some buggy game scripts contain two export tables (e.g. script 912
@@ -1119,7 +1120,7 @@ void Script::initializeObjectsSci0(SegManager *segMan, SegmentId segmentId) {
 	relocateSci0Sci21(segmentId);
 }
 
-void Script::initializeObjectsSci11(SegManager *segMan, SegmentId segmentId) {
+void Script::initializeObjectsSci11(SegManager *segMan, SegmentId segmentId, bool applyScriptPatches) {
 	SciSpan<const byte> seeker = _heap.subspan(4 + _heap.getUint16SEAt(2) * 2);
 	Common::Array<reg_t> mismatchedVarCountObjects;
 
@@ -1129,7 +1130,7 @@ void Script::initializeObjectsSci11(SegManager *segMan, SegmentId segmentId) {
 
 		// Copy base from species class, as we need its selector IDs
 		obj->setSuperClassSelector(
-			segMan->getClassAddress(obj->getSuperClassSelector().getOffset(), SCRIPT_GET_LOCK, 0));
+			segMan->getClassAddress(obj->getSuperClassSelector().getOffset(), SCRIPT_GET_LOCK, 0, applyScriptPatches));
 
 		// -propDict- is used by Obj::isMemberOf to determine if an object
 		// is an instance of a class. For classes, we therefore relocate
@@ -1187,12 +1188,12 @@ void Script::initializeObjectsSci11(SegManager *segMan, SegmentId segmentId) {
 }
 
 #ifdef ENABLE_SCI32
-void Script::initializeObjectsSci3(SegManager *segMan, SegmentId segmentId) {
+void Script::initializeObjectsSci3(SegManager *segMan, SegmentId segmentId, bool applyScriptPatches) {
 	SciSpan<const byte> seeker = getSci3ObjectsPointer();
 
 	while (seeker.getUint16SEAt(0) == SCRIPT_OBJECT_MAGIC_NUMBER) {
 		Object *obj = scriptObjInit(make_reg32(segmentId, seeker - *_buf));
-		obj->setSuperClassSelector(segMan->getClassAddress(obj->getSuperClassSelector().getOffset(), SCRIPT_GET_LOCK, 0));
+		obj->setSuperClassSelector(segMan->getClassAddress(obj->getSuperClassSelector().getOffset(), SCRIPT_GET_LOCK, 0, applyScriptPatches));
 		seeker += seeker.getUint16SEAt(2);
 	}
 
@@ -1200,14 +1201,14 @@ void Script::initializeObjectsSci3(SegManager *segMan, SegmentId segmentId) {
 }
 #endif
 
-void Script::initializeObjects(SegManager *segMan, SegmentId segmentId) {
+void Script::initializeObjects(SegManager *segMan, SegmentId segmentId, bool applyScriptPatches) {
 	if (getSciVersion() <= SCI_VERSION_1_LATE)
 		initializeObjectsSci0(segMan, segmentId);
 	else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE)
-		initializeObjectsSci11(segMan, segmentId);
+		initializeObjectsSci11(segMan, segmentId, applyScriptPatches);
 #ifdef ENABLE_SCI32
 	else if (getSciVersion() == SCI_VERSION_3)
-		initializeObjectsSci3(segMan, segmentId);
+		initializeObjectsSci3(segMan, segmentId, applyScriptPatches);
 #endif
 }
 
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index f4afca7..e1a4b96 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -133,7 +133,7 @@ public:
 	~Script();
 
 	void freeScript(const bool keepLocalsSegment = false);
-	void load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher);
+	void load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher, bool applyScriptPatches = true);
 
 	virtual bool isValidOffset(uint32 offset) const;
 	virtual SegmentRef dereference(reg_t pointer);
@@ -180,10 +180,11 @@ public:
 
 	/**
 	 * Initializes the script's objects (SCI0)
-	 * @param segMan	A reference to the segment manager
-	 * @param segmentId	The script's segment id
+	 * @param segMan	          A reference to the segment manager
+	 * @param segmentId	          The script's segment id
+	 * @param applyScriptPatches  Apply patches for the script, if available
 	 */
-	void initializeObjects(SegManager *segMan, SegmentId segmentId);
+	void initializeObjects(SegManager *segMan, SegmentId segmentId, bool applyScriptPatches);
 
 	// script lock operations
 
@@ -336,10 +337,11 @@ private:
 
 	/**
 	 * Initializes the script's objects (SCI1.1 - SCI2.1)
-	 * @param segMan	A reference to the segment manager
-	 * @param segmentId	The script's segment id
+	 * @param segMan	    A reference to the segment manager
+	 * @param segmentId	    The script's segment id
+	 * @applyScriptPatches  Apply patches for the script, if available
 	 */
-	void initializeObjectsSci11(SegManager *segMan, SegmentId segmentId);
+	void initializeObjectsSci11(SegManager *segMan, SegmentId segmentId, bool applyScriptPatches);
 
 #ifdef ENABLE_SCI32
 	/**
@@ -347,7 +349,7 @@ private:
 	 * @param segMan	A reference to the segment manager
 	 * @param segmentId	The script's segment id
 	 */
-	void initializeObjectsSci3(SegManager *segMan, SegmentId segmentId);
+	void initializeObjectsSci3(SegManager *segMan, SegmentId segmentId, bool applyScriptPatches);
 #endif
 
 	LocalVariables *allocLocalsSegment(SegManager *segMan);
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 806fb36..4412ffb 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -14067,10 +14067,6 @@ void ScriptPatcher::processScript(uint16 scriptNr, SciSpan<byte> scriptData) {
 		_isMacSci11 = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1);
 
 		if (!_runtimeTable) {
-			// Abort, in case selectors are not yet initialized (happens for games w/o selector-dictionary)
-			if (!g_sci->getKernel()->selectorNamesAvailable())
-				return;
-
 			// signature table needs to get initialized (Magic DWORD set, selector table set)
 			initSignature(signatureTable);
 
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 4566633..fd6b86e 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -347,11 +347,11 @@ SegmentId SegManager::getScriptSegment(int script_id) const {
 	return _scriptSegMap.getVal(script_id, 0);
 }
 
-SegmentId SegManager::getScriptSegment(int script_nr, ScriptLoadType load) {
+SegmentId SegManager::getScriptSegment(int script_nr, ScriptLoadType load, bool applyScriptPatches) {
 	SegmentId segment;
 
 	if ((load & SCRIPT_GET_LOAD) == SCRIPT_GET_LOAD)
-		instantiateScript(script_nr);
+		instantiateScript(script_nr, applyScriptPatches);
 
 	segment = getScriptSegment(script_nr);
 
@@ -1003,7 +1003,7 @@ void SegManager::createClassTable() {
 	}
 }
 
-reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, uint16 callerSegment) {
+reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, uint16 callerSegment, bool applyScriptPatches) {
 	if (classnr == 0xffff)
 		return NULL_REG;
 
@@ -1012,7 +1012,7 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, uint16 calle
 	} else {
 		Class *the_class = &_classTable[classnr];
 		if (!the_class->reg.getSegment()) {
-			getScriptSegment(the_class->script, lock);
+			getScriptSegment(the_class->script, lock, applyScriptPatches);
 
 			if (!the_class->reg.getSegment()) {
 				if (lock == SCRIPT_GET_DONT_LOAD)
@@ -1028,7 +1028,7 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, uint16 calle
 	}
 }
 
-int SegManager::instantiateScript(int scriptNum) {
+int SegManager::instantiateScript(int scriptNum, bool applyScriptPatches) {
 	SegmentId segmentId = getScriptSegment(scriptNum);
 	Script *scr = getScriptIfLoaded(segmentId);
 	if (scr) {
@@ -1042,10 +1042,10 @@ int SegManager::instantiateScript(int scriptNum) {
 		scr = allocateScript(scriptNum, &segmentId);
 	}
 
-	scr->load(scriptNum, _resMan, _scriptPatcher);
+	scr->load(scriptNum, _resMan, _scriptPatcher, applyScriptPatches);
 	scr->initializeLocals(this);
 	scr->initializeClasses(this);
-	scr->initializeObjects(this, segmentId);
+	scr->initializeObjects(this, segmentId, applyScriptPatches);
 #ifdef ENABLE_SCI32
 	g_sci->_guestAdditions->instantiateScriptHook(*scr);
 #endif
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index d13edf0..fdef0b6 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -98,10 +98,11 @@ public:
 	 * Determines the segment occupied by a certain script. Optionally
 	 * load it, or load & lock it.
 	 * @param[in] script_nr	Number of the script to look up
-	 * @param[in] load		flag determining whether to load/lock the script
-	 * @return				The script's segment ID, or 0 on failure
+	 * @param[in] load		           Flag determining whether to load/lock the script
+	 * @param[in] applyScriptPatches   Apply patches for the script, if available
+	 * @return				           The script's segment ID, or 0 on failure
 	 */
-	SegmentId getScriptSegment(int script_nr, ScriptLoadType load);
+	SegmentId getScriptSegment(int script_nr, ScriptLoadType load, bool applyScriptPatches = true);
 
 	/**
 	 * Makes sure that a script and its superclasses get loaded to the heap.
@@ -109,10 +110,11 @@ public:
 	 * increased. All scripts containing superclasses of this script are loaded
 	 * recursively as well, unless 'recursive' is set to zero. The
 	 * complementary function is "uninstantiateScript()" below.
-	 * @param[in] script_nr		The script number to load
-	 * @return					The script's segment ID or 0 if out of heap
+	 * @param[in] script_nr		       The script number to load
+	 * @param[in] applyScriptPatches   Apply patches for the script, if available
+	 * @return					       The script's segment ID or 0 if out of heap
 	 */
-	int instantiateScript(int script_nr);
+	int instantiateScript(int script_nr, bool applyScriptPatches = true);
 
 	/**
 	 * Decreases the numer of lockers of a script and unloads it if that number
@@ -128,7 +130,7 @@ private:
 
 public:
 	// TODO: document this
-	reg_t getClassAddress(int classnr, ScriptLoadType lock, uint16 callerSegment);
+	reg_t getClassAddress(int classnr, ScriptLoadType lock, uint16 callerSegment, bool applyScriptPatches = true);
 
 	/**
 	 * Return a pointer to the specified script.
diff --git a/engines/sci/engine/static_selectors.cpp b/engines/sci/engine/static_selectors.cpp
index 08c6f5d..ae6c7af 100644
--- a/engines/sci/engine/static_selectors.cpp
+++ b/engines/sci/engine/static_selectors.cpp
@@ -224,11 +224,14 @@ Common::StringArray Kernel::checkStaticSelectorNames() {
 void Kernel::findSpecificSelectors(Common::StringArray &selectorNames) {
 	// Now, we need to find out selectors which keep changing place...
 	// We do that by dissecting game objects, and looking for selectors at
-	// specified locations.
+	// specified locations. We need to load some game scripts here to
+	// find these selectors, but all of the loaded scripts will be
+	// purged at the end of this function, as the segment manager will be
+	// reset.
 
 	// We need to initialize script 0 here, to make sure that it's always
 	// located at segment 1.
-	_segMan->instantiateScript(0);
+	_segMan->instantiateScript(0, false);
 
 	// The Actor class contains the init, xLast and yLast selectors, which
 	// we reference directly. It's always in script 998, so we need to
@@ -242,7 +245,7 @@ void Kernel::findSpecificSelectors(Common::StringArray &selectorNames) {
 #endif
 
 		if (_resMan->testResource(ResourceId(kResourceTypeScript, actorScript))) {
-			_segMan->instantiateScript(actorScript);
+			_segMan->instantiateScript(actorScript, false);
 
 			const Object *actorClass = _segMan->getObject(_segMan->findObjectByName("Actor"));
 
@@ -284,7 +287,7 @@ void Kernel::findSpecificSelectors(Common::StringArray &selectorNames) {
 		if (!_resMan->testResource(ResourceId(kResourceTypeScript, classReferences[i].script)))
 			continue;
 
-		_segMan->instantiateScript(classReferences[i].script);
+		_segMan->instantiateScript(classReferences[i].script, false);
 
 		const Object *targetClass = _segMan->getObject(_segMan->findObjectByName(classReferences[i].className));
 		int targetSelectorPos = 0;





More information about the Scummvm-git-logs mailing list