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

djsrv dservilla at gmail.com
Thu Jul 2 02:07:43 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:
38d17341e2 DIRECTOR: LINGO: Move lingo archive to Cast
fd119949ec DIRECTOR: LINGO: Add temp fix for D4 factories


Commit: 38d17341e29bf0757438b74bdbf54012205eb10e
    https://github.com/scummvm/scummvm/commit/38d17341e29bf0757438b74bdbf54012205eb10e
Author: djsrv (dservilla at gmail.com)
Date: 2020-07-01T22:07:13-04:00

Commit Message:
DIRECTOR: LINGO: Move lingo archive to Cast

Changed paths:
    engines/director/cast.cpp
    engines/director/cast.h
    engines/director/director.cpp
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo-codegen.cpp
    engines/director/lingo/lingo-events.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h
    engines/director/lingo/xlibs/fileio.cpp
    engines/director/movie.cpp
    engines/director/movie.h
    engines/director/resource.cpp
    engines/director/score.cpp
    engines/director/sprite.cpp
    engines/director/types.h


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 3101a76593..83f62fb07e 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -64,7 +64,7 @@ Cast::Cast(DirectorEngine *vm, Movie *movie) {
 	_lingo = _vm->getLingo();
 	_movie = movie;
 
-	_lingoArchive = _movie ? kArchMain : kArchShared;
+	_lingoArchive = new LingoArchive;
 
 	_movieScriptCount = 0;
 	_castArrayStart = _castArrayEnd = 0;
@@ -94,6 +94,19 @@ 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) {
+			it->_value->_eventHandlers.clear();
+			it->_value->_functionHandlers.clear();
+			delete it->_value;
+		}
+
+		_lingoArchive->scriptContexts[i].clear();
+	}
+	_lingoArchive->names.clear();
+	_lingoArchive->functionHandlers.clear();
+	delete _lingoArchive;
 }
 
 CastMember *Cast::getCastMember(int castId) {
@@ -836,7 +849,7 @@ void Cast::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 				if (ConfMan.getBool("dump_scripts"))
 					dumpScript(ci->script.c_str(), scriptType, id);
 
-				_lingo->addCode(ci->script.c_str(), _lingoArchive, scriptType, id, ci->name.c_str());
+				_lingoArchive->addCode(ci->script.c_str(), scriptType, id, ci->name.c_str());
 			}
 		}
 
@@ -849,7 +862,7 @@ void Cast::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 
 void Cast::loadLingoNames(Common::SeekableSubReadStreamEndian &stream) {
 	if (_vm->getVersion() >= 4) {
-		_lingo->addNamesV4(stream, _lingoArchive);
+		_lingoArchive->addNamesV4(stream);
 	} else {
 		error("Cast::loadLingoNames: unsuported Director version (%d)", _vm->getVersion());
 	}
@@ -894,7 +907,7 @@ void Cast::loadLingoContext(Common::SeekableSubReadStreamEndian &stream) {
 		for (Common::Array<int16>::iterator iterator = lscr.begin(); iterator != lscr.end(); ++iterator) {
 			if (*iterator >= 0) {
 				Common::SeekableSubReadStreamEndian *r;
-				_lingo->addCodeV4(*(r = _castArchive->getResource(MKTAG('L', 's', 'c', 'r'), *iterator)), _lingoArchive, _macName);
+				_lingoArchive->addCodeV4(*(r = _castArchive->getResource(MKTAG('L', 's', 'c', 'r'), *iterator)), _macName);
 				delete r;
 			}
 		}
@@ -930,7 +943,7 @@ void Cast::loadScriptText(Common::SeekableSubReadStreamEndian &stream) {
 	if (script.contains("\nmenu:") || script.hasPrefix("menu:"))
 		return;
 
-	_lingo->addCode(script.c_str(), _lingoArchive, kMovieScript, _movieScriptCount);
+	_lingoArchive->addCode(script.c_str(), kMovieScript, _movieScriptCount);
 
 	_movieScriptCount++;
 }
@@ -961,7 +974,7 @@ void Cast::loadCastInfo(Common::SeekableSubReadStreamEndian &stream, uint16 id)
 		dumpScript(ci->script.c_str(), kCastScript, id);
 
 	if (!ci->script.empty())
-		_lingo->addCode(ci->script.c_str(), _lingoArchive, kCastScript, id, ci->name.c_str());
+		_lingoArchive->addCode(ci->script.c_str(), kCastScript, id, ci->name.c_str());
 
 	ci->name = getString(castStrings[1]);
 	ci->directory = getString(castStrings[2]);
diff --git a/engines/director/cast.h b/engines/director/cast.h
index b7b2eb594d..f416397ec3 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -38,6 +38,7 @@ struct CastMemberInfo;
 class CastMember;
 class DirectorEngine;
 class Lingo;
+struct LingoArchive;
 struct Resource;
 class Stxt;
 class BitmapCastMember;
@@ -92,7 +93,7 @@ public:
 	uint16 _castArrayEnd;
 
 	uint16 _movieScriptCount;
-	int _lingoArchive;
+	LingoArchive *_lingoArchive;
 
 private:
 	DirectorEngine *_vm;
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index a7835501fb..a2cbfafddd 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -164,9 +164,6 @@ Common::Error DirectorEngine::run() {
 	//_mainArchive = new RIFFArchive();
 	//_mainArchive->openFile("bookshelf_example.mmm");
 
-	_currentMovie = new Movie(this);
-	_currentPath = getPath(getEXEName(), _currentPath);
-
 	if (getPlatform() == Common::kPlatformWindows)
 		_machineType = 256; // IBM PC-type machine
 
@@ -184,8 +181,6 @@ Common::Error DirectorEngine::run() {
 		_sharedCastFile = "Shared.dir";
 	}
 
-	_currentMovie->loadSharedCastsFrom(_currentPath + _sharedCastFile);
-
 	debug(0, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\nObtaining score name\n");
 
 	if (getGameGID() == GID_TESTALL)  {
@@ -306,13 +301,12 @@ Common::Error DirectorEngine::run() {
 			_currentMovie->setArchive(mov);
 			debug(0, "Switching to movie '%s'", _currentMovie->getMacName().c_str());
 
+			_lingo->resetLingo();
 			if (sharedCast && sharedCast->_castArchive
 					&& sharedCast->_castArchive->getFileName().equalsIgnoreCase(_currentPath + _sharedCastFile)) {
-				_lingo->resetLingo(true);
 				_currentMovie->_sharedCast = sharedCast;
 			} else {
 				delete sharedCast;
-				_lingo->resetLingo(false);
 				_currentMovie->loadSharedCastsFrom(_currentPath + _sharedCastFile);
 			}
 
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 428d043deb..7af9ed594f 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1633,8 +1633,9 @@ void LB::b_installMenu(int nargs) {
 		menu->createSubMenuFromString(submenu, submenuText.c_str(), 0);
 	}
 
-	// TODO: Menu callbacks should probably not be in the movie's lingo archive
-	g_lingo->addCode(handlers.c_str(), kArchMain, kMovieScript, 1337);
+	// TODO: Menu callbacks should probably not be defined as a movie script
+	LingoArchive *mainArchive = g_director->getCurrentMovie()->getMainLingoArch();
+	mainArchive->addCode(handlers.c_str(), kMovieScript, 1337);
 }
 
 Common::String Lingo::genMenuHandler(int *commandId, Common::String &command) {
@@ -2191,11 +2192,11 @@ void LB::b_script(int nargs) {
 
 		if (cast->_type == kCastLingoScript) {
 			// script cast can be either a movie script or score script
-			script = g_lingo->getScriptContext(cast->_cast->_lingoArchive, kMovieScript, castId);
+			script = g_director->getCurrentMovie()->getScriptContext(kMovieScript, castId);
 			if (!script)
-				script = g_lingo->getScriptContext(cast->_cast->_lingoArchive, kScoreScript, castId);
+				script = g_director->getCurrentMovie()->getScriptContext(kScoreScript, castId);
 		} else {
-			script = g_lingo->getScriptContext(cast->_cast->_lingoArchive, kCastScript, castId);
+			g_director->getCurrentMovie()->getScriptContext(kCastScript, castId);
 		}
 
 		if (script) {
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 4154701291..182a4b45db 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -498,7 +498,7 @@ void LC::cb_proplist() {
 
 void LC::cb_call() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->getName(nameId);
+	Common::String name = g_lingo->_currentArchive->getName(nameId);
 
 	Datum nargs = g_lingo->pop();
 	if ((nargs.type == ARGC) || (nargs.type == ARGCNORET)) {
@@ -513,7 +513,7 @@ void LC::cb_call() {
 
 void LC::cb_globalpush() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->getName(nameId);
+	Common::String name = g_lingo->_currentArchive->getName(nameId);
 	Datum target(name);
 	target.type = VAR;
 	debugC(3, kDebugLingoExec, "cb_globalpush: pushing %s to stack", name.c_str());
@@ -524,7 +524,7 @@ void LC::cb_globalpush() {
 
 void LC::cb_globalassign() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->getName(nameId);
+	Common::String name = g_lingo->_currentArchive->getName(nameId);
 	Datum target(name);
 	target.type = VAR;
 	debugC(3, kDebugLingoExec, "cb_globalassign: assigning to %s", name.c_str());
@@ -538,7 +538,7 @@ void LC::cb_globalassign() {
 
 void LC::cb_objectfieldassign() {
 	int fieldNameId = g_lingo->readInt();
-	Common::String fieldName = g_lingo->getName(fieldNameId);
+	Common::String fieldName = g_lingo->_currentArchive->getName(fieldNameId);
 	Datum object = g_lingo->pop();
 	Datum value = g_lingo->pop();
 	g_lingo->setObjectProp(object, fieldName, value);
@@ -546,14 +546,14 @@ void LC::cb_objectfieldassign() {
 
 void LC::cb_objectfieldpush() {
 	int fieldNameId = g_lingo->readInt();
-	Common::String fieldName = g_lingo->getName(fieldNameId);
+	Common::String fieldName = g_lingo->_currentArchive->getName(fieldNameId);
 	Datum object = g_lingo->pop();
 	g_lingo->push(g_lingo->getObjectProp(object, fieldName));
 }
 
 void LC::cb_objectpush() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->getName(nameId);
+	Common::String name = g_lingo->_currentArchive->getName(nameId);
 	Datum result(name);
 	result.type = SYMBOL;
 	g_lingo->push(result);
@@ -561,7 +561,7 @@ void LC::cb_objectpush() {
 
 void LC::cb_tellcall() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->getName(nameId);
+	Common::String name = g_lingo->_currentArchive->getName(nameId);
 	warning("STUB: cb_tellcall(%s)", name.c_str());
 
 	Datum nargs = g_lingo->pop();
@@ -578,7 +578,7 @@ void LC::cb_tellcall() {
 
 void LC::cb_theassign() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->getName(nameId);
+	Common::String name = g_lingo->_currentArchive->getName(nameId);
 	Datum value = g_lingo->pop();
 	if (g_lingo->_currentMe.type == OBJECT) {
 		if (g_lingo->_currentMe.u.obj->hasProp(name)) {
@@ -593,14 +593,14 @@ void LC::cb_theassign() {
 
 void LC::cb_theassign2() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->getName(nameId);
+	Common::String name = g_lingo->_currentArchive->getName(nameId);
 	Datum value = g_lingo->pop();
 	warning("STUB: cb_theassign2(%s, %s)", name.c_str(), value.asString().c_str());
 }
 
 void LC::cb_thepush() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->getName(nameId);
+	Common::String name = g_lingo->_currentArchive->getName(nameId);
 	if (g_lingo->_currentMe.type == OBJECT) {
 		if (g_lingo->_currentMe.u.obj->hasProp(name)) {
 			g_lingo->push(g_lingo->_currentMe.u.obj->getProp(name));
@@ -618,7 +618,7 @@ void LC::cb_thepush() {
 void LC::cb_thepush2() {
 	int nameId = g_lingo->readInt();
 	Datum result;
-	Common::String name = g_lingo->getName(nameId);
+	Common::String name = g_lingo->_currentArchive->getName(nameId);
 	if (g_lingo->_theEntities.contains(name)) {
 		TheEntity *entity = g_lingo->_theEntities[name];
 		Datum id;
@@ -635,7 +635,7 @@ void LC::cb_thepush2() {
 
 void LC::cb_varpush() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->getName(nameId);
+	Common::String name = g_lingo->_currentArchive->getName(nameId);
 	Datum target(name);
 	target.type = VAR;
 	debugC(3, kDebugLingoExec, "cb_varpush: pushing %s to stack", name.c_str());
@@ -646,7 +646,7 @@ void LC::cb_varpush() {
 
 void LC::cb_varassign() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->getName(nameId);
+	Common::String name = g_lingo->_currentArchive->getName(nameId);
 	Datum target(name);
 	target.type = VAR;
 	debugC(3, kDebugLingoExec, "cb_varassign: assigning to %s", name.c_str());
@@ -732,7 +732,7 @@ void LC::cb_v4theentitynamepush() {
 	}
 
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->getName(nameId);
+	Common::String name = g_lingo->_currentArchive->getName(nameId);
 
 	Datum id;
 	id.u.s = NULL;
@@ -817,10 +817,10 @@ void LC::cb_zeropush() {
 	g_lingo->push(d);
 }
 
-void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIndex, const Common::String &archName) {
+ScriptContext *Lingo::compileLingoV4(Common::SeekableSubReadStreamEndian &stream, LingoArchive *archive, const Common::String &archName) {
 	if (stream.size() < 0x5c) {
 		warning("Lscr header too small");
-		return;
+		return nullptr;
 	}
 
 	if (debugChannelSet(5, kDebugLoading)) {
@@ -894,15 +894,16 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
 			castName = info->name;
 	}
 
-	_assemblyArchive = archiveIndex;
+	_assemblyArchive = archive;
 
+	ScriptContext *sc = nullptr;
 	Common::String factoryName;
 	if (scriptFlags & kScriptFlagFactoryDef) {
-		if (0 <= factoryNameId && factoryNameId < (int16)_archives[_assemblyArchive].names.size()) {
-			factoryName = _archives[_assemblyArchive].names[factoryNameId];
+		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);
-			return;
+			return nullptr;
 		}
 		debugC(1, kDebugCompile, "Add V4 bytecode for factory '%s' with id %d", factoryName.c_str(), castId);
 
@@ -911,29 +912,28 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
 	} else {
 		debugC(1, kDebugCompile, "Add V4 bytecode for type %s with id %d", scriptType2str(scriptType), castId);
 
-		if (getScriptContext(archiveIndex, 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;
+			return nullptr;
 		}
 
-		_assemblyContext = new ScriptContext(scriptType, !castName.empty() ? castName : Common::String::format("%d", castId));
-		_archives[_assemblyArchive].scriptContexts[scriptType][castId] = _assemblyContext;
+		sc = _assemblyContext = new ScriptContext(!castName.empty() ? castName : Common::String::format("%d", castId), _assemblyArchive, scriptType, castId);
 	}
 
 	// initialise each property
 	if ((uint32)stream.size() < propertiesOffset + propertiesCount * 2) {
 		warning("Lscr properties store missing");
-		return;
+		return nullptr;
 	}
 
 	debugC(5, kDebugLoading, "Lscr property list:");
 	stream.seek(propertiesOffset);
 	for (uint16 i = 0; i < propertiesCount; i++) {
 		int16 index = stream.readSint16();
-		if (0 <= index && index < (int16)_archives[_assemblyArchive].names.size()) {
-			const char *name = _archives[_assemblyArchive].names[index].c_str();
+		if (0 <= index && index < (int16)archive->names.size()) {
+			const char *name = archive->names[index].c_str();
 			debugC(5, kDebugLoading, "%d: %s", i, name);
 			if (scriptFlags & kScriptFlagFactoryDef) {
 				_currentFactory->properties[name] = Datum();
@@ -948,15 +948,15 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
 	// initialise each global variable
 	if ((uint32)stream.size() < globalsOffset + globalsCount * 2) {
 		warning("Lscr globals store missing");
-		return;
+		return nullptr;
 	}
 
 	debugC(5, kDebugLoading, "Lscr globals list:");
 	stream.seek(globalsOffset);
 	for (uint16 i = 0; i < globalsCount; i++) {
 		int16 index = stream.readSint16();
-		if (0 <= index && index < (int16)_archives[_assemblyArchive].names.size()) {
-			const char *name = _archives[_assemblyArchive].names[index].c_str();
+		if (0 <= index && index < (int16)archive->names.size()) {
+			const char *name = archive->names[index].c_str();
 			debugC(5, kDebugLoading, "%d: %s", i, name);
 			if (!_globalvars.contains(name)) {
 				_globalvars[name] = Datum();
@@ -976,7 +976,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
 
 	if ((uint32)stream.size() < constsStoreOffset) {
 		warning("Lscr consts store missing");
-		return;
+		return nullptr;
 	}
 
 	stream.seek(constsStoreOffset);
@@ -1101,7 +1101,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
 	// copy the storage area first.
 	if ((uint32)stream.size() < functionsOffset) {
 		warning("Lscr functions store missing");
-		return;
+		return nullptr;
 	}
 
 	uint32 codeStoreSize = functionsOffset - codeStoreOffset;
@@ -1171,19 +1171,19 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
 				int16 index = READ_BE_INT16(&codeStore[namePointer]);
 				namePointer += 2;
 				Common::String name;
-				if (0 <= index && index < (int16)_archives[_assemblyArchive].names.size()) {
-					name = _archives[_assemblyArchive].names[index];
+				if (0 <= index && index < (int16)archive->names.size()) {
+					name = archive->names[index];
 					argMap[j] = index;
 				} else if (j == 0 && (scriptFlags & kScriptFlagFactoryDef)) {
 					name = "me";
 
 					// find or add "me" in the names list
-					for (index = 0; index < (int16)_archives[_assemblyArchive].names.size(); index++) {
-						if (_archives[_assemblyArchive].names[index].equalsIgnoreCase(name))
+					for (index = 0; index < (int16)archive->names.size(); index++) {
+						if (archive->names[index].equalsIgnoreCase(name))
 							break;
 					}
-					if (index == (int16)_archives[_assemblyArchive].names.size())
-						_archives[_assemblyArchive].names.push_back(name);
+					if (index == (int16)archive->names.size())
+						archive->names.push_back(name);
 
 					argMap[j] = index;
 				} else {
@@ -1209,8 +1209,8 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
 				int16 index = READ_BE_INT16(&codeStore[namePointer]);
 				namePointer += 2;
 				Common::String name;
-				if (0 <= index && index < (int16)_archives[_assemblyArchive].names.size()) {
-					name = _archives[_assemblyArchive].names[index];
+				if (0 <= index && index < (int16)archive->names.size()) {
+					name = archive->names[index];
 					varMap[j] = index;
 				} else {
 					name = Common::String::format("var_%d", j);
@@ -1396,9 +1396,9 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
 
 		// Attach to handlers
 		Symbol sym;
-		if (0 <= nameIndex && nameIndex < (int16)_archives[_assemblyArchive].names.size()) {
-			debugC(5, kDebugLoading, "Function %d binding: %s()", i, _archives[_assemblyArchive].names[nameIndex].c_str());
-			sym = g_lingo->define(_archives[_assemblyArchive].names[nameIndex], argCount, _currentAssembly, argNames, varNames);
+		if (0 <= nameIndex && nameIndex < (int16)archive->names.size()) {
+			debugC(5, kDebugLoading, "Function %d binding: %s()", i, archive->names[nameIndex].c_str());
+			sym = _assemblyContext->define(archive->names[nameIndex], argCount, _currentAssembly, argNames, varNames);
 		} else {
 			warning("Function has unknown name id %d, skipping define", nameIndex);
 			sym.name = new Common::String();
@@ -1411,8 +1411,8 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
 		}
 
 		if (!skipdump && ConfMan.getBool("dump_scripts")) {
-			if (0 <= nameIndex && nameIndex < (int16)_archives[_assemblyArchive].names.size())
-				out.writeString(Common::String::format("function %s, %d args\n", _archives[_assemblyArchive].names[nameIndex].c_str(), argCount));
+			if (0 <= nameIndex && nameIndex < (int16)archive->names.size())
+				out.writeString(Common::String::format("function %s, %d args\n", archive->names[nameIndex].c_str(), argCount));
 			else
 				out.writeString(Common::String::format("<noname>, %d args\n", argCount));
 
@@ -1435,11 +1435,19 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
 	}
 
 	free(codeStore);
+	_assemblyContext = nullptr;
 	_currentFactory = nullptr;
+
+	return sc;
 }
 
+void LingoArchive::addCodeV4(Common::SeekableSubReadStreamEndian &stream, const Common::String &archName) {
+	ScriptContext *ctx = g_lingo->compileLingoV4(stream, this, archName);
+	if (ctx)
+		scriptContexts[ctx->_type][ctx->_id] = ctx;
+}
 
-void Lingo::addNamesV4(Common::SeekableSubReadStreamEndian &stream, int archiveIndex) {
+void LingoArchive::addNamesV4(Common::SeekableSubReadStreamEndian &stream) {
 	debugC(1, kDebugCompile, "Add V4 script name index");
 
 	if (stream.size() < 0x14) {
@@ -1471,16 +1479,15 @@ void Lingo::addNamesV4(Common::SeekableSubReadStreamEndian &stream, int archiveI
 
 	stream.seek(offset);
 
-	_archives[archiveIndex].names.clear();
+	names.clear();
 
-	Common::Array<Common::String> names;
 	for (uint32 i = 0; i < count; i++) {
 		uint8 size = stream.readByte();
 		Common::String name;
 		for (uint8 j = 0; j < size; j++) {
 			name += stream.readByte();
 		}
-		_archives[archiveIndex].names.push_back(name);
+		names.push_back(name);
 		debugC(5, kDebugLoading, "%d: \"%s\"", i, name.c_str());
 	}
 
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index d5be25d086..5f6dc5a644 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -215,7 +215,7 @@ void Lingo::pushContext(const Symbol funcSym, bool preserveVarFrame) {
 	fp->retpc = g_lingo->_pc;
 	fp->retscript = g_lingo->_currentScript;
 	fp->retctx = g_lingo->_currentScriptContext;
-	fp->retarchive = g_lingo->_archiveIndex;
+	fp->retarchive = g_lingo->_currentArchive;
 	fp->localvars = g_lingo->_localvars;
 	fp->retMe = g_lingo->_currentMe;
 	fp->sp = funcSym;
@@ -225,11 +225,10 @@ void Lingo::pushContext(const Symbol funcSym, bool preserveVarFrame) {
 		g_lingo->_currentScriptContext = funcSym.ctx;
 		g_lingo->_currentMe = funcSym.ctx->_target; // reference-counted datum
 	}
-	g_lingo->_archiveIndex = funcSym.archiveIndex;
+	g_lingo->_currentArchive = funcSym.archive;
 
-	// Functions with an archiveIndex of -1 are anonymous.
-	// Execute them within the current var frame.
-	if (!preserveVarFrame && funcSym.archiveIndex >= 0)
+	// Execute anonymous functions within the current var frame.
+	if (!preserveVarFrame && !funcSym.anonymous)
 		g_lingo->_localvars = new DatumHash;
 
 	g_lingo->_callstack.push_back(fp);
@@ -244,19 +243,19 @@ void Lingo::popContext() {
 	CFrame *fp = g_lingo->_callstack.back();
 	g_lingo->_callstack.pop_back();
 
-	// Destroy anonymous context
-	if (g_lingo->_archiveIndex < 0) {
+	// Destroy anonymous function context
+	if (fp->sp.anonymous) {
 		delete g_lingo->_currentScriptContext;
 	}
 
 	g_lingo->_currentScript = fp->retscript;
 	g_lingo->_currentScriptContext = fp->retctx;
-	g_lingo->_archiveIndex = fp->retarchive;
+	g_lingo->_currentArchive = fp->retarchive;
 	g_lingo->_pc = fp->retpc;
 	g_lingo->_currentMe = fp->retMe;
 
 	// Restore local variables
-	if (fp->sp.archiveIndex >= 0) {
+	if (!fp->sp.anonymous) {
 		g_lingo->cleanLocalVars();
 		g_lingo->_localvars = fp->localvars;
 	}
@@ -351,7 +350,7 @@ void LC::c_symbolpush() {
 void LC::c_namepush() {
 	Datum d;
 	int i = g_lingo->readInt();
-	g_lingo->push(Datum(Common::String(g_lingo->getName(i))));
+	g_lingo->push(Datum(Common::String(g_lingo->_currentArchive->getName(i))));
 }
 
 void LC::c_argcpush() {
@@ -1456,7 +1455,7 @@ void LC::call(const Symbol &funcSym, int nargs) {
 	g_lingo->pushContext(funcSym, true);
 
 	DatumHash *localvars = g_lingo->_localvars;
-	if (funcSym.archiveIndex >= 0) {
+	if (!funcSym.anonymous) {
 		// Create new set of local variables
 		// g_lingo->_localvars is not set until later so any lazy arguments
 		// can be evaluated within the current variable frame
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 19f10d0924..a1186bcee9 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -62,7 +62,7 @@ void Lingo::cleanLocalVars() {
 	g_lingo->_localvars = nullptr;
 }
 
-Symbol Lingo::define(Common::String &name, int nargs, ScriptData *code, Common::Array<Common::String> *argNames, Common::Array<Common::String> *varNames, Object *factory) {
+Symbol ScriptContext::define(Common::String &name, int nargs, ScriptData *code, Common::Array<Common::String> *argNames, Common::Array<Common::String> *varNames) {
 	Symbol sym;
 	sym.name = new Common::String(name);
 	sym.type = HANDLER;
@@ -71,36 +71,26 @@ Symbol Lingo::define(Common::String &name, int nargs, ScriptData *code, Common::
 	sym.maxArgs = nargs;
 	sym.argNames = argNames;
 	sym.varNames = varNames;
-	sym.ctx = _assemblyContext;
-	sym.archiveIndex = _assemblyArchive;
+	sym.ctx = this;
+	sym.archive = _archive;
 
 	if (debugChannelSet(1, kDebugCompile)) {
 		uint pc = 0;
 		while (pc < sym.u.defn->size()) {
 			uint spc = pc;
-			Common::String instr = g_lingo->decodeInstruction(_assemblyArchive, sym.u.defn, pc, &pc);
+			Common::String instr = g_lingo->decodeInstruction(_archive, sym.u.defn, pc, &pc);
 			debugC(1, kDebugCompile, "[%5d] %s", spc, instr.c_str());
 		}
 		debugC(1, kDebugCompile, "<end define code>");
 	}
 
-	if (factory) {
-		if (factory->ctx->_functionHandlers.contains(name)) {
-			warning("Redefining method '%s' on factory '%s'", name.c_str(), factory->name->c_str());
-		}
-		factory->ctx->_functionHandlers[name] = sym;
-	} else if (_assemblyArchive >= 0) {
-		Symbol existing = getHandler(name);
-		if (existing.type != VOID)
-			warning("Redefining handler '%s'", name.c_str());
-
-		if (!_eventHandlerTypeIds.contains(name)) {
-			if (_assemblyContext->_type == kMovieScript && !_archives[_assemblyArchive].functionHandlers.contains(name))
-				_archives[_assemblyArchive].functionHandlers[name] = sym;
-			_assemblyContext->_functionHandlers[name] = sym;
-		} else {
-			_assemblyContext->_eventHandlers[_eventHandlerTypeIds[name]] = sym;
+	if (!g_lingo->_eventHandlerTypeIds.contains(name)) {
+		_functionHandlers[name] = sym;
+		if (_type == kMovieScript && _archive && !_archive->functionHandlers.contains(name)) {
+			_archive->functionHandlers[name] = sym;
 		}
+	} else {
+		_eventHandlers[g_lingo->_eventHandlerTypeIds[name]] = sym;
 	}
 
 	return sym;
@@ -123,7 +113,9 @@ Symbol Lingo::codeDefine(Common::String &name, int start, int nargs, Object *fac
 		if (it->_value == kVarLocal)
 			varNames->push_back(Common::String(it->_key));
 	}
-	Symbol sym = define(name, nargs, code, argNames, varNames, factory);
+
+	ScriptContext *ctx = factory ? factory->ctx : _assemblyContext;
+	Symbol sym = ctx->define(name, nargs, code, argNames, varNames);
 
 	if (debugChannelSet(1, kDebugCompile)) {
 		debug("Function vars");
@@ -292,7 +284,7 @@ void Lingo::varCreate(const Common::String &name, bool global, DatumHash *localv
 }
 
 void Lingo::codeFactory(Common::String &name) {
-	ScriptContext *ctx = new ScriptContext(kNoneScript, name);
+	ScriptContext *ctx = new ScriptContext(name);
 	Object *obj = new Object(name, kFactoryObj, ctx);
 
 	_currentFactory = obj;
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index dc8b7c2464..9055127243 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -23,6 +23,7 @@
 #include "director/director.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-code.h"
+#include "director/cast.h"
 #include "director/movie.h"
 #include "director/frame.h"
 #include "director/score.h"
@@ -103,8 +104,9 @@ int Lingo::getEventCount() {
 
 void Lingo::setPrimaryEventHandler(LEvent event, const Common::String &code) {
 	debugC(3, kDebugLingoExec, "setting primary event handler (%s)", _eventHandlerTypes[event]);
-	_archives[kArchMain].primaryEventHandlers[event] = code;
-	addCode(code.c_str(), kArchMain, kGlobalScript, event);
+	LingoArchive *mainArchive = g_director->getCurrentMovie()->getMainLingoArch();
+	mainArchive->primaryEventHandlers[event] = code;
+	mainArchive->addCode(code.c_str(), kGlobalScript, event);
 }
 
 void Lingo::queueSpriteEvent(LEvent event, int eventId, int spriteId) {
@@ -118,7 +120,8 @@ void Lingo::queueSpriteEvent(LEvent event, int eventId, int spriteId) {
 	 * When more than one movie script [...]
 	 * [D4 docs] */
 
-	Score *score = _vm->getCurrentMovie()->getScore();
+	Movie *movie = _vm->getCurrentMovie();
+	Score *score = movie->getScore();
 	Frame *currentFrame = score->_frames[score->getCurrentFrame()];
 	assert(currentFrame != nullptr);
 	Sprite *sprite = score->getSpriteById(spriteId);
@@ -130,25 +133,20 @@ void Lingo::queueSpriteEvent(LEvent event, int eventId, int spriteId) {
 			// If sprite is immediate, its script is run on mouseDown, otherwise on mouseUp
 			if ((event == kEventMouseDown && sprite->_immediate)
 					|| (event == kEventMouseUp && !sprite->_immediate)) {
-				_eventQueue.push(LingoEvent(kEventNone, eventId, kArchMain, kScoreScript, sprite->_scriptId, false, spriteId));
+				_eventQueue.push(LingoEvent(kEventNone, eventId, kScoreScript, sprite->_scriptId, false, spriteId));
 			}
 		} else {
-			ScriptContext *script = getScriptContext(kArchMain, kScoreScript, sprite->_scriptId);
+			ScriptContext *script = movie->getScriptContext(kScoreScript, sprite->_scriptId);
 			if (script && script->_eventHandlers.contains(event)) {
-				_eventQueue.push(LingoEvent(event, eventId, kArchMain, kScoreScript, sprite->_scriptId, false, spriteId));
+				_eventQueue.push(LingoEvent(event, eventId, kScoreScript, sprite->_scriptId, false, spriteId));
 			}
 		}
 	}
 
 	// Cast script
-	int archiveIndex = kArchMain;
-	ScriptContext *script = getScriptContext(archiveIndex, kCastScript, sprite->_castId);
-	if (!script) {
-		archiveIndex = kArchShared;
-		script = getScriptContext(archiveIndex, kCastScript, sprite->_castId);
-	}
+	ScriptContext *script = movie->getScriptContext(kCastScript, sprite->_castId);
 	if (script && script->_eventHandlers.contains(event)) {
-		_eventQueue.push(LingoEvent(event, eventId, archiveIndex, kCastScript, sprite->_castId, false, spriteId));
+		_eventQueue.push(LingoEvent(event, eventId, kCastScript, sprite->_castId, false, spriteId));
 	}
 }
 
@@ -160,7 +158,8 @@ void Lingo::queueFrameEvent(LEvent event, int eventId) {
 	 * [p.81 of D4 docs]
 	 */
 
-	Score *score = _vm->getCurrentMovie()->getScore();
+	Movie *movie = _vm->getCurrentMovie();
+	Score *score = movie->getScore();
 
 	// if (event == kEventPrepareFrame || event == kEventIdle) {
 	// 	entity = score->getCurrentFrame();
@@ -171,11 +170,11 @@ void Lingo::queueFrameEvent(LEvent event, int eventId) {
 
 	if (scriptId) {
 		if (event == kEventEnterFrame && _vm->getVersion() <= 3) {
-			_eventQueue.push(LingoEvent(kEventNone, eventId, kArchMain, kScoreScript, scriptId, false));
+			_eventQueue.push(LingoEvent(kEventNone, eventId, kScoreScript, scriptId, false));
 		} else {
-			ScriptContext *script = getScriptContext(kArchMain, kScoreScript, scriptId);
+			ScriptContext *script = movie->getScriptContext(kScoreScript, scriptId);
 			if (script && script->_eventHandlers.contains(event)) {
-				_eventQueue.push(LingoEvent(event, eventId, kArchMain, kScoreScript, scriptId, false));
+				_eventQueue.push(LingoEvent(event, eventId, kScoreScript, scriptId, false));
 			}
 		}
 	}
@@ -188,18 +187,23 @@ void Lingo::queueMovieEvent(LEvent event, int eventId) {
 	 */
 
 	// FIXME: shared cast movie scripts could come before main movie ones
-	for (ScriptContextHash::iterator it = _archives[kArchMain].scriptContexts[kMovieScript].begin();
-			it != _archives[kArchMain].scriptContexts[kMovieScript].end(); ++it) {
+	Movie *movie = g_director->getCurrentMovie();
+	LingoArchive *mainArchive = movie->getMainLingoArch();
+	for (ScriptContextHash::iterator it = mainArchive->scriptContexts[kMovieScript].begin();
+			it != mainArchive->scriptContexts[kMovieScript].end(); ++it) {
 		if (it->_value->_eventHandlers.contains(event)) {
-			_eventQueue.push(LingoEvent(event, eventId, kArchMain, kMovieScript, it->_key, false));
+			_eventQueue.push(LingoEvent(event, eventId, kMovieScript, it->_key, false));
 			return;
 		}
 	}
-	for (ScriptContextHash::iterator it = _archives[kArchShared].scriptContexts[kMovieScript].begin();
-			it != _archives[kArchShared].scriptContexts[kMovieScript].end(); ++it) {
-		if (it->_value->_eventHandlers.contains(event)) {
-			_eventQueue.push(LingoEvent(event, eventId, kArchShared, kMovieScript, it->_key, false));
-			return;
+	LingoArchive *sharedArchive = movie->getSharedLingoArch();
+	if (sharedArchive) {
+		for (ScriptContextHash::iterator it = sharedArchive->scriptContexts[kMovieScript].begin();
+				it != sharedArchive->scriptContexts[kMovieScript].end(); ++it) {
+			if (it->_value->_eventHandlers.contains(event)) {
+				_eventQueue.push(LingoEvent(event, eventId, kMovieScript, it->_key, false));
+				return;
+			}
 		}
 	}
 }
@@ -228,8 +232,8 @@ void Lingo::registerEvent(LEvent event, int spriteId) {
 	case kEventKeyUp:
 	case kEventKeyDown:
 	case kEventTimeout:
-		if (getScriptContext(kArchMain, kGlobalScript, event)) {
-			_eventQueue.push(LingoEvent(kEventNone, eventId, kArchMain, kGlobalScript, event, true));
+		if (g_director->getCurrentMovie()->getScriptContext(kGlobalScript, event)) {
+			_eventQueue.push(LingoEvent(kEventNone, eventId, kGlobalScript, event, true));
 		}
 		break;
 	default:
@@ -320,25 +324,25 @@ void Lingo::processEvents() {
 			continue;
 
 		_passEvent = el.passByDefault;
-		processEvent(el.event, el.archiveIndex, el.scriptType, el.scriptId, el.channelId);
+		processEvent(el.event, el.scriptType, el.scriptId, el.channelId);
 		lastEventId = el.eventId;
 	}
 }
 
-void Lingo::processEvent(LEvent event, int archiveIndex, ScriptType st, int scriptId, int channelId) {
+void Lingo::processEvent(LEvent event, ScriptType st, int scriptId, int channelId) {
 	_currentChannelId = channelId;
 
 	if (!_eventHandlerTypes.contains(event))
 		error("processEvent: Unknown event %d", event);
 
-	ScriptContext *script = getScriptContext(archiveIndex, st, scriptId);
+	ScriptContext *script = g_director->getCurrentMovie()->getScriptContext(st, scriptId);
 
 	if (script && script->_eventHandlers.contains(event)) {
-		debugC(1, kDebugEvents, "Lingo::processEvent(%s, %d, %s, %d): executing event handler", _eventHandlerTypes[event], archiveIndex, scriptType2str(st), scriptId);
+		debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d): executing event handler", _eventHandlerTypes[event], scriptType2str(st), scriptId);
 		LC::call(script->_eventHandlers[event], 0);
 		execute(_pc);
 	} else {
-		debugC(9, kDebugEvents, "Lingo::processEvent(%s, %d, %s, %d): no handler", _eventHandlerTypes[event], archiveIndex, scriptType2str(st), scriptId);
+		debugC(9, kDebugEvents, "Lingo::processEvent(%s, %s, %d): no handler", _eventHandlerTypes[event], scriptType2str(st), scriptId);
 	}
 }
 
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 7c036d223c..7c5f40e346 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -342,6 +342,8 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		return d;
 	}
 
+	LingoArchive *mainArchive = _vm->getCurrentMovie()->getMainLingoArch();
+
 	switch (entity) {
 	case kTheCast:
 		d = getTheCast(id, field);
@@ -380,15 +382,15 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheKeyDownScript:
 		d.type = STRING;
-		if (_archives[kArchMain].primaryEventHandlers.contains(kEventKeyDown))
-			d.u.s = new Common::String(_archives[kArchMain].primaryEventHandlers[kEventKeyDown]);
+		if (mainArchive->primaryEventHandlers.contains(kEventKeyDown))
+			d.u.s = new Common::String(mainArchive->primaryEventHandlers[kEventKeyDown]);
 		else
 			d.u.s = new Common::String();
 		break;
 	case kTheKeyUpScript:
 		d.type = STRING;
-		if (_archives[kArchMain].primaryEventHandlers.contains(kEventKeyUp))
-			d.u.s = new Common::String(_archives[kArchMain].primaryEventHandlers[kEventKeyUp]);
+		if (mainArchive->primaryEventHandlers.contains(kEventKeyUp))
+			d.u.s = new Common::String(mainArchive->primaryEventHandlers[kEventKeyUp]);
 		else
 			d.u.s = new Common::String();
 		break;
@@ -482,8 +484,8 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheMouseDownScript:
 		d.type = STRING;
-		if (_archives[kArchMain].primaryEventHandlers.contains(kEventMouseDown))
-			d.u.s = new Common::String(_archives[kArchMain].primaryEventHandlers[kEventMouseDown]);
+		if (mainArchive->primaryEventHandlers.contains(kEventMouseDown))
+			d.u.s = new Common::String(mainArchive->primaryEventHandlers[kEventMouseDown]);
 		else
 			d.u.s = new Common::String();
 		break;
@@ -501,8 +503,8 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheMouseUpScript:
 		d.type = STRING;
-		if (_archives[kArchMain].primaryEventHandlers.contains(kEventMouseUp))
-			d.u.s = new Common::String(_archives[kArchMain].primaryEventHandlers[kEventMouseUp]);
+		if (mainArchive->primaryEventHandlers.contains(kEventMouseUp))
+			d.u.s = new Common::String(mainArchive->primaryEventHandlers[kEventMouseUp]);
 		else
 			d.u.s = new Common::String();
 		break;
@@ -573,8 +575,8 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheTimeoutScript:
 		d.type = STRING;
-		if (_archives[kArchMain].primaryEventHandlers.contains(kEventTimeout))
-			d.u.s = new Common::String(_archives[kArchMain].primaryEventHandlers[kEventTimeout]);
+		if (mainArchive->primaryEventHandlers.contains(kEventTimeout))
+			d.u.s = new Common::String(mainArchive->primaryEventHandlers[kEventTimeout]);
 		else
 			d.u.s = new Common::String();
 		break;
@@ -1119,9 +1121,7 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
 			warning("Lingo::setTheCast(): The cast %d not found. type: %d", id, castType);
 			return;
 		}
-		// FIXME: What if the cast member is in a different archive than the current one?
-		addCode(d.u.s->c_str(), _archiveIndex, kCastScript, id);
-
+		member->_cast->_lingoArchive->addCode(d.u.s->c_str(), kCastScript, id);
 		castInfo->script = d.asString();
 		break;
 	case kTheText:
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 0cb8a8870f..91ca1a03e5 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -55,7 +55,8 @@ Symbol::Symbol() {
 	argNames = nullptr;
 	varNames = nullptr;
 	ctx = nullptr;
-	archiveIndex = kArchMain;
+	archive = nullptr;
+	anonymous = false;
 }
 
 Symbol::Symbol(const Symbol &s) {
@@ -71,7 +72,8 @@ Symbol::Symbol(const Symbol &s) {
 	argNames = s.argNames;
 	varNames = s.varNames;
 	ctx = s.ctx;
-	archiveIndex = s.archiveIndex;
+	archive = s.archive;
+	anonymous = s.anonymous;
 }
 
 Symbol& Symbol::operator=(const Symbol &s) {
@@ -89,7 +91,8 @@ Symbol& Symbol::operator=(const Symbol &s) {
 		argNames = s.argNames;
 		varNames = s.varNames;
 		ctx = s.ctx;
-		archiveIndex = s.archiveIndex;
+		archive = s.archive;
+		anonymous = s.anonymous;
 	}
 	return *this;
 }
@@ -133,10 +136,11 @@ PCell::PCell(const Datum &prop, const Datum &val) {
 Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
 	g_lingo = this;
 
+	_currentArchive = nullptr;
 	_currentScript = 0;
 	_currentScriptContext = nullptr;
 
-	_assemblyArchive = 0;
+	_assemblyArchive = nullptr;
 	_currentAssembly = nullptr;
 	_assemblyContext = nullptr;
 
@@ -162,8 +166,6 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
 
 	_localvars = NULL;
 
-	_archiveIndex = kArchMain;
-
 	// events
 	_nextEventId = 0;
 	_passEvent = false;
@@ -182,52 +184,41 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
 }
 
 Lingo::~Lingo() {
-	resetLingo(false);
+	resetLingo();
 	cleanupBuiltins();
 }
 
-ScriptContext *Lingo::getScriptContext(int archiveIndex, ScriptType type, uint16 id) {
-	if (archiveIndex < 0)
-		return NULL;
-
-	if (!_archives[archiveIndex].scriptContexts[type].contains(id)) {
-		return NULL;
+ScriptContext *LingoArchive::getScriptContext(ScriptType type, uint16 id) {
+	if (!scriptContexts[type].contains(id)) {
+		return nullptr;
 	}
-
-	return _archives[archiveIndex].scriptContexts[type][id];
+	return scriptContexts[type][id];
 }
 
-Common::String Lingo::getName(uint16 id) {
+Common::String LingoArchive::getName(uint16 id) {
 	Common::String result;
-	if (id >= _archives[_archiveIndex].names.size()) {
+	if (id >= names.size()) {
 		warning("Name id %d not in list", id);
 		return result;
 	}
-	result = _archives[_archiveIndex].names[id];
+	result = names[id];
 	return result;
 }
 
 Symbol Lingo::getHandler(const Common::String &name) {
-	Symbol result;
 	if (!_eventHandlerTypeIds.contains(name)) {
 		// local functions
 		if (_currentScriptContext && _currentScriptContext->_functionHandlers.contains(name))
 			return _currentScriptContext->_functionHandlers[name];
 
-		// local scripts
-		if (_archives[kArchMain].functionHandlers.contains(name))
-			return _archives[kArchMain].functionHandlers[name];
-
-		// shared scripts
-		if (_archives[kArchShared].functionHandlers.contains(name))
-			return _archives[kArchShared].functionHandlers[name];
+		Symbol sym = g_director->getCurrentMovie()->getHandler(name);
+		if (sym.type != VOID)
+			return sym;
 
 		if (_builtins.contains(name))
 			return _builtins[name];
-
-		return result;
 	}
-	return result;
+	return Symbol();
 }
 
 const char *Lingo::findNextDefinition(const char *s) {
@@ -267,16 +258,11 @@ const char *Lingo::findNextDefinition(const char *s) {
 	return NULL;
 }
 
-void Lingo::addCode(const char *code, int archiveIndex, ScriptType type, uint16 id, const char *scriptName) {
-	if (_archiveIndex < 0) {
-		warning("Lingo::addCode(): Invalid archiveIndex");
-		return;
-	}
-
+void LingoArchive::addCode(const char *code, ScriptType type, uint16 id, const char *scriptName) {
 	debugC(1, kDebugCompile, "Add code for type %s(%d) with id %d\n"
 			"***********\n%s\n\n***********", scriptType2str(type), type, id, code);
 
-	if (getScriptContext(archiveIndex, type, id)) {
+	if (getScriptContext(type, id)) {
 		// We can't undefine context data because it could be used in e.g. symbols.
 		// Although it has a legit case when kTheScriptText re sets code.
 		// Warn on double definitions.
@@ -289,20 +275,20 @@ void Lingo::addCode(const char *code, int archiveIndex, ScriptType type, uint16
 	else
 		contextName = Common::String::format("%d", id);
 
-	ScriptContext *sc = compileLingo(code, archiveIndex, type, id, contextName);
-	_archives[_assemblyArchive].scriptContexts[type][id] = sc;
+	ScriptContext *sc = g_lingo->compileLingo(code, this, type, id, contextName);
+	scriptContexts[type][id] = sc;
 }
 
 ScriptContext *Lingo::compileAnonymous(const char *code) {
 	debugC(1, kDebugCompile, "Compiling anonymous lingo\n"
 			"***********\n%s\n\n***********", code);
 
-	return compileLingo(code, kArchNone, kNoneScript, 0, "[anonymous]");
+	return compileLingo(code, nullptr, kNoneScript, 0, "[anonymous]", true);
 }
 
-ScriptContext *Lingo::compileLingo(const char *code, int archiveIndex, ScriptType type, uint16 id, const Common::String &scriptName) {
-	_assemblyArchive = archiveIndex;
-	ScriptContext *sc = _assemblyContext = new ScriptContext(type, scriptName);
+ScriptContext *Lingo::compileLingo(const char *code, LingoArchive *archive, ScriptType type, uint16 id, const Common::String &scriptName, bool anonymous) {
+	_assemblyArchive = archive;
+	ScriptContext *sc = _assemblyContext = new ScriptContext(scriptName, archive, type, id);
 	_currentAssembly = new ScriptData;
 
 	_methodVars = new VarTypeHash;
@@ -393,7 +379,8 @@ ScriptContext *Lingo::compileLingo(const char *code, int archiveIndex, ScriptTyp
 	Common::String typeStr = Common::String(scriptType2str(type));
 	currentFunc.name = new Common::String("[" + typeStr + " " + _assemblyContext->_name + "]");
 	currentFunc.ctx = _assemblyContext;
-	currentFunc.archiveIndex = _assemblyArchive;
+	currentFunc.archive = archive;
+	currentFunc.anonymous = anonymous;
 	// arg names should be empty, but just in case
 	Common::Array<Common::String> *argNames = new Common::Array<Common::String>;
 	for (uint i = 0; i < _argstack.size(); i++) {
@@ -423,9 +410,10 @@ ScriptContext *Lingo::compileLingo(const char *code, int archiveIndex, ScriptTyp
 
 	currentFunc.argNames = argNames;
 	currentFunc.varNames = varNames;
+	_currentAssembly = nullptr;
 	_assemblyContext->_eventHandlers[kEventNone] = currentFunc;
 	_assemblyContext = nullptr;
-	_currentAssembly = nullptr;
+	_assemblyArchive = nullptr;
 	return sc;
 }
 
@@ -460,7 +448,7 @@ void Lingo::printCallStack(uint pc) {
 	}
 }
 
-Common::String Lingo::decodeInstruction(int archiveIndex, ScriptData *sd, uint pc, uint *newPc) {
+Common::String Lingo::decodeInstruction(LingoArchive *archive, ScriptData *sd, uint pc, uint *newPc) {
 	Symbol sym;
 	Common::String res;
 
@@ -527,7 +515,7 @@ Common::String Lingo::decodeInstruction(int archiveIndex, ScriptData *sd, uint p
 					i = (*sd)[pc++];
 					int v = READ_UINT32(&i);
 
-					res += Common::String::format(" \"%s\"", _archives[archiveIndex].names[v].c_str());
+					res += Common::String::format(" \"%s\"", archive->names[v].c_str());
 					break;
 				}
 			default:
@@ -551,7 +539,7 @@ void Lingo::execute(uint pc) {
 	int counter = 0;
 
 	for (_pc = pc; !_abort && (*_currentScript)[_pc] != STOP;) {
-		Common::String instr = decodeInstruction(_archiveIndex, _currentScript, _pc);
+		Common::String instr = decodeInstruction(_currentArchive, _currentScript, _pc);
 		uint current = _pc;
 
 		if (debugChannelSet(5, kDebugLingoExec))
@@ -593,7 +581,13 @@ void Lingo::execute(uint pc) {
 }
 
 void Lingo::executeScript(ScriptType type, uint16 id) {
-	ScriptContext *sc = getScriptContext(_archiveIndex, type, id);
+	Movie *movie = _vm->getCurrentMovie();
+	if (!movie) {
+		warning("Request to execute script with no movie");
+		return;
+	}
+
+	ScriptContext *sc = movie->getScriptContext(type, id);
 
 	if (!sc) {
 		debugC(3, kDebugLingoExec, "Request to execute non-existant script type %d id %d", type, id);
@@ -614,28 +608,9 @@ void Lingo::executeHandler(const Common::String &name) {
 	execute(_pc);
 }
 
-void Lingo::resetLingo(bool keepSharedCast) {
+void Lingo::resetLingo() {
 	debugC(3, kDebugLingoExec, "Resetting Lingo!");
 
-	for (int a = 0; a < 2; a++) {
-		if (a == 1 && keepSharedCast)
-			continue;
-
-		LingoArchive *arch = &_archives[a];
-		for (int i = 0; i <= kMaxScriptType; i++) {
-			for (ScriptContextHash::iterator it = arch->scriptContexts[i].begin(); it != arch->scriptContexts[i].end(); ++it) {
-				it->_value->_eventHandlers.clear();
-				it->_value->_functionHandlers.clear();
-				delete it->_value;
-			}
-
-			arch->scriptContexts[i].clear();
-		}
-
-		arch->names.clear();
-		arch->functionHandlers.clear();
-	}
-
 	g_director->_wm->removeMenu();
 
 	// TODO
@@ -1085,6 +1060,8 @@ void Lingo::runTests() {
 	SearchMan.listMatchingMembers(fsList, "*.lingo");
 	Common::StringArray fileList;
 
+	LingoArchive *mainArchive = g_director->getCurrentMovie()->getMainLingoArch();
+
 	// Repurpose commandline option --start-movie to run a specific lingo script.
 	if (ConfMan.hasKey("start_movie")) {
 		fileList.push_back(ConfMan.get("start_movie"));
@@ -1109,7 +1086,7 @@ void Lingo::runTests() {
 			debug(">> Compiling file %s of size %d, id: %d", fileList[i].c_str(), size, counter);
 
 			_hadError = false;
-			addCode(script, kArchMain, kMovieScript, counter);
+			mainArchive->addCode(script, kMovieScript, counter);
 
 			if (!debugChannelSet(-1, kDebugCompileOnly)) {
 				if (!_hadError)
@@ -1133,9 +1110,9 @@ void Lingo::executeImmediateScripts(Frame *frame) {
 			// From D5 only explicit event handlers are processed
 			// Before that you could specify commands which will be executed on mouse up
 			if (_vm->getVersion() < 5)
-				g_lingo->processEvent(kEventNone, kArchMain, kScoreScript, frame->_sprites[i]->_scriptId, i);
+				g_lingo->processEvent(kEventNone, kScoreScript, frame->_sprites[i]->_scriptId, i);
 			else
-				g_lingo->processEvent(kEventMouseUp, kArchMain, kScoreScript, frame->_sprites[i]->_scriptId, i);
+				g_lingo->processEvent(kEventMouseUp, kScoreScript, frame->_sprites[i]->_scriptId, i);
 		}
 	}
 }
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 321d74619c..3b1da06c76 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -26,6 +26,8 @@
 #include "common/hash-ptr.h"
 #include "common/hash-str.h"
 
+#include "director/types.h"
+
 namespace Audio {
 class AudioStream;
 }
@@ -37,6 +39,7 @@ namespace Director {
 
 struct TheEntity;
 struct TheEntityField;
+struct LingoArchive;
 struct LingoV4Bytecode;
 struct LingoV4TheEntity;
 struct Object;
@@ -93,7 +96,8 @@ struct Symbol {	/* symbol table entry */
 	Common::Array<Common::String> *argNames;
 	Common::Array<Common::String> *varNames;
 	ScriptContext *ctx;		/* optional script context to execute with */
-	int archiveIndex; 		/* optional archive to execute with */
+	LingoArchive *archive; 	/* optional archive to execute with */
+	bool anonymous;
 
 	Symbol();
 	Symbol(const Symbol &s);
@@ -168,8 +172,10 @@ typedef Common::HashMap<Common::String, TheEntityField *, Common::IgnoreCase_Has
 
 class ScriptContext {
 public:
-	ScriptType _type;
 	Common::String _name;
+	LingoArchive *_archive;
+	ScriptType _type;
+	uint16 _id;
 	Common::Array<Common::String> _functionNames; // used by cb_localcall
 	SymbolHash _functionHandlers;
 	Common::HashMap<uint32, Symbol> _eventHandlers;
@@ -177,7 +183,8 @@ public:
 	Common::Array<Common::String> _propNames;
 	Datum _target;
 
-	ScriptContext(ScriptType type, Common::String name) : _type(type), _name(name) {}
+	ScriptContext(Common::String name, LingoArchive *archive = nullptr, ScriptType type = kNoneScript, uint16 id = 0)
+		: _name(name), _archive(archive), _type(type), _id(id) {}
 	ScriptContext(const ScriptContext &sc) {
 		_type = sc._type;
 		_name = sc._name;
@@ -195,6 +202,7 @@ public:
 	}
 
 	Datum getParentScript();
+	Symbol define(Common::String &name, int nargs, ScriptData *code, Common::Array<Common::String> *argNames, Common::Array<Common::String> *varNames);
 
 private:
 	Datum _parentScript;
@@ -274,9 +282,9 @@ struct Object {
 struct CFrame {	/* proc/func call stack frame */
 	Symbol	sp;	/* symbol table entry */
 	int		retpc;	/* where to resume after return */
-	ScriptData	*retscript;	 /* which script to resume after return */
-	ScriptContext	*retctx;   /* which script context to use after return */
-	int 	retarchive;	/* which archive to use after return */
+	ScriptData *retscript;		/* which script to resume after return */
+	ScriptContext *retctx;		/* which script context to use after return */
+	LingoArchive *retarchive;	/* which archive to use after return */
 	DatumHash *localvars;
 	Datum retMe; /* which me obj to use after return */
 };
@@ -284,16 +292,14 @@ struct CFrame {	/* proc/func call stack frame */
 struct LingoEvent {
 	LEvent event;
 	int eventId;
-	int archiveIndex;
 	ScriptType scriptType;
 	int scriptId;
 	bool passByDefault;
 	int channelId;
 
-	LingoEvent (LEvent e, int ei, int ai, ScriptType st, int si, bool pass, int ci = -1) {
+	LingoEvent (LEvent e, int ei, ScriptType st, int si, bool pass, int ci = -1) {
 		event = e;
 		eventId = ei;
-		archiveIndex = ai;
 		scriptType = st;
 		scriptId = si;
 		passByDefault = pass;
@@ -307,6 +313,13 @@ struct LingoArchive {
 	Common::Array<Common::String> names;
 	Common::HashMap<uint32, Common::String> primaryEventHandlers;
 	SymbolHash functionHandlers;
+
+	ScriptContext *getScriptContext(ScriptType type, uint16 id);
+	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 addNamesV4(Common::SeekableSubReadStreamEndian &stream);
 };
 
 struct RepeatBlock {
@@ -320,17 +333,16 @@ public:
 	Lingo(DirectorEngine *vm);
 	~Lingo();
 
-	void resetLingo(bool keepSharedCast);
+	void resetLingo();
 
-	void addCode(const char *code, int archiveIndex, ScriptType type, uint16 id, const char *scriptName = nullptr);
 	ScriptContext *compileAnonymous(const char *code);
-	void addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIndex, const Common::String &archName);
-	void addNamesV4(Common::SeekableSubReadStreamEndian &stream, int archiveIndex);
+	ScriptContext *compileLingo(const char *code, LingoArchive *archive, ScriptType type, uint16 id, const Common::String &scriptName, bool anonyomous = false);
+	ScriptContext *compileLingoV4(Common::SeekableSubReadStreamEndian &stream, LingoArchive *archive, const Common::String &archName);
 	void executeHandler(const Common::String &name);
 	void executeScript(ScriptType type, uint16 id);
 	void printStack(const char *s, uint pc);
 	void printCallStack(uint pc);
-	Common::String decodeInstruction(int archiveIndex, ScriptData *sd, uint pc, uint *newPC = NULL);
+	Common::String decodeInstruction(LingoArchive *archive, ScriptData *sd, uint pc, uint *newPC = NULL);
 
 	void initBuiltIns();
 	void cleanupBuiltins();
@@ -351,7 +363,6 @@ public:
 
 	// lingo.cpp
 private:
-	ScriptContext *compileLingo(const char *code, int archiveIndex, ScriptType type, uint16 id, const Common::String &scriptName);
 	const char *findNextDefinition(const char *s);
 
 	// lingo-events.cpp
@@ -361,14 +372,12 @@ private:
 	void queueSpriteEvent(LEvent event, int eventId, int spriteId);
 	void queueFrameEvent(LEvent event, int eventId);
 	void queueMovieEvent(LEvent event, int eventId);
-	void processEvent(LEvent event, int archiveIndex, ScriptType st, int entityId, int channelId = -1);
+	void processEvent(LEvent event, ScriptType st, int entityId, int channelId = -1);
 
 	int _nextEventId;
 	Common::Queue<LingoEvent> _eventQueue;
 
 public:
-	ScriptContext *getScriptContext(int archiveIndex, ScriptType type, uint16 id);
-	Common::String getName(uint16 id);
 	ScriptType event2script(LEvent ev);
 	Symbol getHandler(const Common::String &name);
 
@@ -473,11 +482,10 @@ public:
 	int codeInt(int val);
 	void codeLabel(int label);
 	int codeString(const char *s);
-	Symbol define(Common::String &s, int nargs, ScriptData *code, Common::Array<Common::String> *argNames = nullptr, Common::Array<Common::String> *varNames = nullptr, Object *obj = nullptr);
 	void processIf(int toplabel, int endlabel);
 	void varCreate(const Common::String &name, bool global, DatumHash *localvars = nullptr);
 
-	int _assemblyArchive;
+	LingoArchive *_assemblyArchive;
 	ScriptContext *_assemblyContext;
 	ScriptData *_currentAssembly;
 	LexerDefineState _indef;
@@ -500,6 +508,7 @@ public:
 
 public:
 	int _currentChannelId;
+	LingoArchive *_currentArchive;
 	ScriptContext *_currentScriptContext;
 	ScriptData *_currentScript;
 	Datum _currentMe;
@@ -552,9 +561,6 @@ public:
 	Common::HashMap<int, LingoV4Bytecode *> _lingoV4;
 	Common::HashMap<int, LingoV4TheEntity *> _lingoV4TheEntity;
 
-	LingoArchive _archives[2];
-	int _archiveIndex;
-
 	uint _pc;
 
 	StackData _stack;
diff --git a/engines/director/lingo/xlibs/fileio.cpp b/engines/director/lingo/xlibs/fileio.cpp
index 8adb3a1762..bcd0eee72c 100644
--- a/engines/director/lingo/xlibs/fileio.cpp
+++ b/engines/director/lingo/xlibs/fileio.cpp
@@ -61,7 +61,7 @@ static struct MethodProto {
 void FileIO::initialize(int type) {
 	if (type & kXObj) {
 		if (!g_lingo->_globalvars.contains(xlibName)) {
-			ScriptContext *ctx = new ScriptContext(kNoneScript, Common::String(xlibName));
+			ScriptContext *ctx = new ScriptContext(Common::String(xlibName));
 			FileObject *xobj = new FileObject(kXObj, ctx);
 			xobj->initMethods();
 			g_lingo->_globalvars[xlibName] = xobj->ctx->_target;
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index 9c7e29cfd8..145cd93b49 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -189,7 +189,7 @@ void Movie::loadFileInfo(Common::SeekableSubReadStreamEndian &stream) {
 		_cast->dumpScript(_script.c_str(), kMovieScript, _cast->_movieScriptCount);
 
 	if (!_script.empty())
-		_lingo->addCode(_script.c_str(), _cast->_lingoArchive, kMovieScript, _cast->_movieScriptCount);
+		_cast->_lingoArchive->addCode(_script.c_str(), kMovieScript, _cast->_movieScriptCount);
 
 	_cast->_movieScriptCount++;
 	_changedBy = fileInfoStrings[1];
@@ -245,4 +245,31 @@ const Stxt *Movie::getStxt(int castId) {
 	return result;
 }
 
+LingoArchive *Movie::getMainLingoArch() {
+	return _cast->_lingoArchive;
+}
+
+LingoArchive *Movie::getSharedLingoArch() {
+	return _sharedCast ? _sharedCast->_lingoArchive : nullptr;
+}
+
+ScriptContext *Movie::getScriptContext(ScriptType type, uint16 id) {
+	ScriptContext *result = _cast->_lingoArchive->getScriptContext(type, id);
+	if (result == nullptr && _sharedCast) {
+		result = _sharedCast->_lingoArchive->getScriptContext(type, id);
+	}
+	return result;
+}
+
+Symbol Movie::getHandler(const Common::String &name) {
+	if (!g_lingo->_eventHandlerTypeIds.contains(name)) {
+		if (_cast->_lingoArchive->functionHandlers.contains(name))
+			return _cast->_lingoArchive->functionHandlers[name];
+
+		if (_sharedCast && _sharedCast->_lingoArchive->functionHandlers.contains(name))
+			return _sharedCast->_lingoArchive->functionHandlers[name];
+	}
+	return Symbol();
+}
+
 } // End of namespace Director
diff --git a/engines/director/movie.h b/engines/director/movie.h
index 3bd11705d5..37b8bcaddf 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -36,6 +36,9 @@ struct CastMemberInfo;
 class CastMember;
 class DirectorEngine;
 class Lingo;
+struct LingoArchive;
+struct ScriptContext;
+struct Symbol;
 
 class Movie {
 public:
@@ -59,6 +62,11 @@ public:
 	CastMember *getCastMember(int castId);
 	const Stxt *getStxt(int castId);
 
+	LingoArchive *getMainLingoArch();
+	LingoArchive *getSharedLingoArch();
+	ScriptContext *getScriptContext(ScriptType type, uint16 id);
+	Symbol getHandler(const Common::String &name);
+
 private:
 	void loadFileInfo(Common::SeekableSubReadStreamEndian &stream);
 
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 9b13aeb4c9..a7d13ceae9 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -29,6 +29,7 @@
 #include "director/castmember.h"
 #include "director/movie.h"
 #include "director/lingo/lingo.h"
+#include "director/util.h"
 
 namespace Director {
 
@@ -51,6 +52,10 @@ void DirectorEngine::loadInitialMovie(const Common::String movie) {
 		loadEXE(movie);
 	else
 		loadMac(movie);
+	
+	_currentMovie = new Movie(this);
+	_currentPath = getPath(getEXEName(), _currentPath);
+	_currentMovie->loadSharedCastsFrom(_currentPath + _sharedCastFile);
 }
 
 Archive *DirectorEngine::openMainArchive(const Common::String movie) {
@@ -74,9 +79,13 @@ void DirectorEngine::loadEXE(const Common::String movie) {
 	if (iniStream) {
 		char *script = (char *)calloc(iniStream->size() + 1, 1);
 		iniStream->read(script, iniStream->size());
-		_lingo->addCode(script, kArchMain, kMovieScript, 0);
+
+		_currentMovie = new Movie(this);
+		_currentMovie->getMainLingoArch()->addCode(script, kMovieScript, 0);
 		_lingo->processEvent(kEventStartUp);
-		_lingo->resetLingo(true);
+		delete _currentMovie;
+		_currentMovie = nullptr;
+
 		free(script);
 	} else {
 		warning("No LINGO.INI");
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 3ce9567f13..74f9a6f174 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -904,7 +904,7 @@ void Score::loadActions(Common::SeekableSubReadStreamEndian &stream) {
 			// continue;
 		}
 		if (!j->_value.empty()) {
-			_lingo->addCode(j->_value.c_str(), _movie->getCast()->_lingoArchive, kScoreScript, j->_key);
+			_movie->getMainLingoArch()->addCode(j->_value.c_str(), kScoreScript, j->_key);
 
 			processImmediateFrameScript(j->_value, j->_key);
 		}
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index f99826b201..691199bdcf 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -82,8 +82,7 @@ bool Sprite::isActive() {
 	if (_moveable || _puppet || _scriptId)
 		return true;
 
-	if (g_lingo->getScriptContext(kArchMain, kCastScript, _castId)
-			|| g_lingo->getScriptContext(kArchShared, kCastScript, _castId))
+	if (g_director->getCurrentMovie()->getScriptContext(kCastScript, _castId))
 		return true;
 
 	return false;
diff --git a/engines/director/types.h b/engines/director/types.h
index fb4454acd0..fd2bbfbb3a 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -261,12 +261,6 @@ enum {
 	kCursorMouseUp
 };
 
-enum ArchiveType {
-	kArchNone = -1,
-	kArchMain = 0,
-	kArchShared = 1
-};
-
 struct Datum;
 struct PCell;
 typedef Common::Array<Datum> DatumArray;


Commit: fd119949ec323e943c81ed8b30cfcb5262a34907
    https://github.com/scummvm/scummvm/commit/fd119949ec323e943c81ed8b30cfcb5262a34907
Author: djsrv (dservilla at gmail.com)
Date: 2020-07-01T22:07:13-04:00

Commit Message:
DIRECTOR: LINGO: Add temp fix for D4 factories

Changed paths:
    engines/director/lingo/lingo-codegen.cpp


diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index a1186bcee9..f3435d55d3 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -284,7 +284,9 @@ void Lingo::varCreate(const Common::String &name, bool global, DatumHash *localv
 }
 
 void Lingo::codeFactory(Common::String &name) {
-	ScriptContext *ctx = new ScriptContext(name);
+	// FIXME: The factory's context should not be tied to the LingoArchive
+	// but bytecode needs it to resolve names
+	ScriptContext *ctx = new ScriptContext(name, _assemblyArchive);
 	Object *obj = new Object(name, kFactoryObj, ctx);
 
 	_currentFactory = obj;




More information about the Scummvm-git-logs mailing list