[Scummvm-git-logs] scummvm master -> 63ea83d057b2e95e718e13f88aa0cbb86b5d7470

djsrv dservilla at gmail.com
Tue Jul 14 17:05:35 UTC 2020


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

Summary:
6871ab1ea6 DIRECTOR: LINGO: Add LingoArchive destructor
63ea83d057 DIRECTOR: LINGO: Attempt to repair script type/ID


Commit: 6871ab1ea6117dd6bcea50c53954e21446c66d69
    https://github.com/scummvm/scummvm/commit/6871ab1ea6117dd6bcea50c53954e21446c66d69
Author: djsrv (dservilla at gmail.com)
Date: 2020-07-14T13:04:44-04:00

Commit Message:
DIRECTOR: LINGO: Add LingoArchive destructor

Changed paths:
    engines/director/cast.cpp
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index ea4d289f82..0deda3bcbf 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -97,21 +97,6 @@ Cast::~Cast() {
 
 	delete _loadedStxts;
 	delete _loadedCast;
-
-	for (int i = 0; i <= kMaxScriptType; i++) {
-		for (ScriptContextHash::iterator it = _lingoArchive->scriptContexts[i].begin(); it != _lingoArchive->scriptContexts[i].end(); ++it) {
-			if (!it->_value)
-				continue;
-
-			it->_value->_eventHandlers.clear();
-			it->_value->_functionHandlers.clear();
-			delete it->_value;
-		}
-
-		_lingoArchive->scriptContexts[i].clear();
-	}
-	_lingoArchive->names.clear();
-	_lingoArchive->functionHandlers.clear();
 	delete _lingoArchive;
 }
 
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 4b86e97604..a8201115da 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -198,6 +198,14 @@ Lingo::~Lingo() {
 	cleanupBuiltins();
 }
 
+LingoArchive::~LingoArchive() {
+	for (int i = 0; i <= kMaxScriptType; i++) {
+		for (ScriptContextHash::iterator it = scriptContexts[i].begin(); it != scriptContexts[i].end(); ++it) {
+			delete it->_value;
+		}
+	}
+}
+
 ScriptContext *LingoArchive::getScriptContext(ScriptType type, uint16 id) {
 	if (!scriptContexts[type].contains(id)) {
 		return nullptr;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 09d20ed86f..643045f901 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -201,6 +201,8 @@ struct LingoEvent {
 
 
 struct LingoArchive {
+	~LingoArchive();
+
 	ScriptContextHash scriptContexts[kMaxScriptType + 1];
 	Common::Array<Common::String> names;
 	Common::HashMap<uint32, Common::String> primaryEventHandlers;


Commit: 63ea83d057b2e95e718e13f88aa0cbb86b5d7470
    https://github.com/scummvm/scummvm/commit/63ea83d057b2e95e718e13f88aa0cbb86b5d7470
Author: djsrv (dservilla at gmail.com)
Date: 2020-07-14T13:04:44-04:00

Commit Message:
DIRECTOR: LINGO: Attempt to repair script type/ID

Changed paths:
    engines/director/cast.cpp
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 0deda3bcbf..ffeca72a29 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -915,13 +915,40 @@ void Cast::loadLingoContext(Common::SeekableSubReadStreamEndian &stream) {
 			stream.readUint16();
 		}
 
-		for (Common::Array<int16>::iterator iterator = lscr.begin(); iterator != lscr.end(); ++iterator) {
-			if (*iterator >= 0) {
+		for (uint16 i = 0; i < lscr.size(); i++) {
+			if (lscr[i] >= 0) {
 				Common::SeekableSubReadStreamEndian *r;
-				_lingoArchive->addCodeV4(*(r = _castArchive->getResource(MKTAG('L', 's', 'c', 'r'), *iterator)), _macName);
+				_lingoArchive->addCodeV4(*(r = _castArchive->getResource(MKTAG('L', 's', 'c', 'r'), lscr[i])), i, _macName);
 				delete r;
 			}
 		}
+
+		// repair script type + cast ID
+		for (Common::HashMap<int, CastMember *>::iterator it = _loadedCast->begin(); it != _loadedCast->end(); ++it) {
+			if (it->_value->_type == kCastLingoScript) {
+				ScriptCastMember *member = static_cast<ScriptCastMember *>(it->_value);
+				if (!_lingoArchive->lctxContexts.contains(member->_id - 1)) {
+					warning("%s %d has invalid script ID %d", scriptType2str(member->_scriptType), it->_key, member->_id);
+					continue;
+				}
+
+				ScriptContext *script = _lingoArchive->lctxContexts[member->_id - 1];
+				debugC(1, kDebugCompile, "Repairing script %d: %s %d -> %s %d", member->_id, scriptType2str(script->_scriptType), script->_id, scriptType2str(member->_scriptType), it->_key);
+				script->_scriptType = member->_scriptType;
+				script->_id = it->_key;
+			}
+		}
+		
+		// actually define scripts
+		for (ScriptContextHash::iterator it = _lingoArchive->lctxContexts.begin(); it != _lingoArchive->lctxContexts.end(); ++it) {
+			ScriptContext *script = it->_value;
+			if (!script->isFactory()) {
+				if (_lingoArchive->getScriptContext(script->_scriptType, script->_id)) {
+					error("Script already defined for type %s, id %d", scriptType2str(script->_scriptType), script->_id);
+				}
+				_lingoArchive->scriptContexts[script->_scriptType][script->_id] = script;
+			}
+		}
 	} else {
 		error("Cast::loadLingoContext: unsuported Director version (%d)", _vm->getVersion());
 	}
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 908c2cdef7..d5ce2f6efe 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -849,7 +849,7 @@ ScriptContext *Lingo::compileLingoV4(Common::SeekableSubReadStreamEndian &stream
 	/* uint32 length = */ stream.readUint32();
 	/* uint32 length2 = */ stream.readUint32();
 	uint16 codeStoreOffset = stream.readUint16();
-	/* uint16 lctxIndex = */ stream.readUint16();
+	uint16 lctxIndex = stream.readUint16();
 	// unk2
 	for (uint32 i = 0; i < 0x10; i++) {
 		stream.readByte();
@@ -897,6 +897,8 @@ ScriptContext *Lingo::compileLingoV4(Common::SeekableSubReadStreamEndian &stream
 		CastMemberInfo *info = g_director->getCurrentMovie()->getCastMemberInfo(castId);
 		if (info)
 			castName = info->name;
+	} else {
+		warning("Script %d has invalid cast member %d", lctxIndex, castId);
 	}
 
 	_assemblyArchive = archive;
@@ -907,25 +909,19 @@ ScriptContext *Lingo::compileLingoV4(Common::SeekableSubReadStreamEndian &stream
 		if (0 <= factoryNameId && factoryNameId < (int16)archive->names.size()) {
 			factoryName = archive->names[factoryNameId];
 		} else {
-			warning("Factory %d has unknown name id %d, skipping define", castId, factoryNameId);
+			warning("Factory %d has unknown name id %d, skipping define", lctxIndex, factoryNameId);
 			return nullptr;
 		}
-		debugC(1, kDebugCompile, "Add V4 bytecode for factory '%s' with id %d", factoryName.c_str(), castId);
+		debugC(1, kDebugCompile, "Add V4 script %d: factory '%s'", lctxIndex, factoryName.c_str());
 
-		_assemblyContext = new ScriptContext(factoryName, _assemblyArchive, scriptType, castId);
+		sc = new ScriptContext(factoryName, _assemblyArchive, scriptType, castId);
 		codeFactory(factoryName);
 	} else {
-		debugC(1, kDebugCompile, "Add V4 bytecode for type %s with id %d", scriptType2str(scriptType), castId);
-
-		if (archive->getScriptContext(scriptType, castId)) {
-			// We can't undefine context data because it could be used in e.g. symbols.
-			// Abort on double definitions.
-			error("Script already defined for type %d, id %d", scriptType, castId);
-			return nullptr;
-		}
+		debugC(1, kDebugCompile, "Add V4 script %d: maybe %s %d", lctxIndex, scriptType2str(scriptType), castId);
 
-		sc = _assemblyContext = new ScriptContext(!castName.empty() ? castName : Common::String::format("%d", castId), _assemblyArchive, scriptType, castId);
+		sc = new ScriptContext(!castName.empty() ? castName : Common::String::format("%d", castId), _assemblyArchive, scriptType, castId);
 	}
+	_assemblyContext = sc;
 
 	// initialise each property
 	if ((uint32)stream.size() < propertiesOffset + propertiesCount * 2) {
@@ -1450,10 +1446,10 @@ ScriptContext *Lingo::compileLingoV4(Common::SeekableSubReadStreamEndian &stream
 	return sc;
 }
 
-void LingoArchive::addCodeV4(Common::SeekableSubReadStreamEndian &stream, const Common::String &archName) {
+void LingoArchive::addCodeV4(Common::SeekableSubReadStreamEndian &stream, uint16 lctxIndex, const Common::String &archName) {
 	ScriptContext *ctx = g_lingo->compileLingoV4(stream, this, archName);
 	if (ctx) {
-		scriptContexts[ctx->_scriptType][ctx->_id] = ctx;
+		lctxContexts[lctxIndex] = ctx;
 		*ctx->_refCount += 1;
 	}
 }
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 643045f901..3801ad9f97 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -203,6 +203,7 @@ struct LingoEvent {
 struct LingoArchive {
 	~LingoArchive();
 
+	ScriptContextHash lctxContexts;
 	ScriptContextHash scriptContexts[kMaxScriptType + 1];
 	Common::Array<Common::String> names;
 	Common::HashMap<uint32, Common::String> primaryEventHandlers;
@@ -212,7 +213,7 @@ struct LingoArchive {
 	Common::String getName(uint16 id);
 
 	void addCode(const char *code, ScriptType type, uint16 id, const char *scriptName = nullptr);
-	void addCodeV4(Common::SeekableSubReadStreamEndian &stream, const Common::String &archName);
+	void addCodeV4(Common::SeekableSubReadStreamEndian &stream, uint16 lctxIndex, const Common::String &archName);
 	void addNamesV4(Common::SeekableSubReadStreamEndian &stream);
 };
 




More information about the Scummvm-git-logs mailing list