[Scummvm-git-logs] scummvm master -> 189acb438d376b915636a6d4a78846edb4abd6c4

moralrecordings code at moral.net.au
Sun Feb 9 04:14:30 UTC 2020


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:
189acb438d DIRECTOR: LINGO: Add split contexts for main and shared archives


Commit: 189acb438d376b915636a6d4a78846edb4abd6c4
    https://github.com/scummvm/scummvm/commit/189acb438d376b915636a6d4a78846edb4abd6c4
Author: Scott Percival (code at moral.net.au)
Date: 2020-02-09T12:14:14+08:00

Commit Message:
DIRECTOR: LINGO: Add split contexts for main and shared archives

Changed paths:
    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.cpp
    engines/director/lingo/lingo.h
    engines/director/resource.cpp


diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 2d420f0..3a77271 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -336,7 +336,7 @@ void LC::cb_list() {
 
 void LC::cb_call() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->_namelist[nameId];
+	Common::String name = g_lingo->getName(nameId);
 
 	Datum nargs = g_lingo->pop();
 	if ((nargs.type == ARGC) || (nargs.type == ARGCNORET)) {
@@ -351,7 +351,7 @@ void LC::cb_call() {
 
 void LC::cb_globalpush() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->_namelist[nameId];
+	Common::String name = g_lingo->getName(nameId);
 	Datum result;
 	result.type = VOID;
 
@@ -374,7 +374,7 @@ void LC::cb_globalpush() {
 
 void LC::cb_globalassign() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->_namelist[nameId];
+	Common::String name = g_lingo->getName(nameId);
 
 	Symbol *s = g_lingo->lookupVar(name.c_str(), false);
 	if (!s) {
@@ -397,7 +397,7 @@ void LC::cb_globalassign() {
 
 void LC::cb_objectpush() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->_namelist[nameId];
+	Common::String name = g_lingo->getName(nameId);
 	warning("STUB: cb_objectpush(%s)", name.c_str());
 	Datum result;
 	result.type = VOID;
@@ -407,7 +407,7 @@ void LC::cb_objectpush() {
 
 void LC::cb_varpush() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->_namelist[nameId];
+	Common::String name = g_lingo->getName(nameId);
 	Datum result;
 	result.type = VOID;
 
@@ -430,7 +430,7 @@ void LC::cb_varpush() {
 
 void LC::cb_varassign() {
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->_namelist[nameId];
+	Common::String name = g_lingo->getName(nameId);
 
 	Symbol *s = g_lingo->lookupVar(name.c_str(), false);
 	if (!s) {
@@ -519,7 +519,7 @@ void LC::cb_v4theentitynamepush() {
 	}
 
 	int nameId = g_lingo->readInt();
-	Common::String name = g_lingo->_namelist[nameId];
+	Common::String name = g_lingo->getName(nameId);
 
 	Datum id;
 	id.u.s = NULL;
@@ -618,7 +618,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 	_currentScriptContext = new ScriptContext;
 	_currentScriptType = type;
 	_currentEntityId = id;
-	_scriptContexts[type][id] = _currentScriptContext;
+	_archives[_archiveIndex].scriptContexts[type][id] = _currentScriptContext;
 
 	if (stream.size() < 0x5c) {
 		warning("Lscr header too small");
@@ -667,8 +667,8 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 	stream.seek(globalsOffset);
 	for (uint16 i = 0; i < globalsCount; i++) {
 		uint16 index = stream.readUint16();
-		if (index < _namelist.size()) {
-			const char *name = _namelist[index].c_str();
+		if (index < _archives[_archiveIndex].names.size()) {
+			const char *name = _archives[_archiveIndex].names[index].c_str();
 			debugC(5, kDebugLoading, "%d: %s", i, name);
 			g_lingo->lookupVar(name, true, true);
 		} else {
@@ -866,8 +866,8 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 				uint16 index = (uint16)READ_BE_UINT16(&codeStore[namePointer]);
 				namePointer += 2;
 				Common::String name;
-				if (index < _namelist.size()) {
-					name = _namelist[index];
+				if (index < _archives[_archiveIndex].names.size()) {
+					name = _archives[_archiveIndex].names[index];
 					argMap[j] = index;
 				} else {
 					name = Common::String::format("arg_%d", j);
@@ -892,8 +892,8 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 				uint16 index = (uint16)READ_BE_UINT16(&codeStore[namePointer]);
 				namePointer += 2;
 				Common::String name;
-				if (index < _namelist.size()) {
-					name = _namelist[index];
+				if (index < _archives[_archiveIndex].names.size()) {
+					name = _archives[_archiveIndex].names[index];
 					varMap[j] = index;
 				} else {
 					name = Common::String::format("var_%d", j);
@@ -1081,9 +1081,9 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 
 		// Attach to handlers
 		Symbol *sym = NULL;
-		if (nameIndex < _namelist.size()) {
-			debugC(5, kDebugLoading, "Function %d binding: %s()", i, _namelist[nameIndex].c_str());
-			sym = g_lingo->define(_namelist[nameIndex], argCount, _currentScript);
+		if (nameIndex < _archives[_archiveIndex].names.size()) {
+			debugC(5, kDebugLoading, "Function %d binding: %s()", i, _archives[_archiveIndex].names[nameIndex].c_str());
+			sym = g_lingo->define(_archives[_archiveIndex].names[nameIndex], argCount, _currentScript);
 		} else {
 			warning("Function has unknown name id %d, skipping define", nameIndex);
 			sym = new Symbol;
@@ -1095,6 +1095,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 		sym->argNames = argNames;
 		sym->varNames = varNames;
 		sym->ctx = _currentScriptContext;
+		sym->archiveIndex = _archiveIndex;
 		_currentScriptContext->functions.push_back(sym);
 
 	}
@@ -1135,7 +1136,7 @@ void Lingo::addNamesV4(Common::SeekableSubReadStreamEndian &stream) {
 
 	stream.seek(offset);
 
-	_namelist.clear();
+	_archives[_archiveIndex].names.clear();
 
 	Common::Array<Common::String> names;
 	for (uint32 i = 0; i < count; i++) {
@@ -1144,7 +1145,7 @@ void Lingo::addNamesV4(Common::SeekableSubReadStreamEndian &stream) {
 		for (uint8 j = 0; j < size; j++) {
 			name += stream.readByte();
 		}
-		_namelist.push_back(name);
+		_archives[_archiveIndex].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 055a152..29170c9 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -270,7 +270,7 @@ void LC::c_symbolpush() {
 void LC::c_namepush() {
 	Datum d;
 	int i = g_lingo->readInt();
-	g_lingo->push(Datum(new Common::String(g_lingo->_namelist[i])));
+	g_lingo->push(Datum(new Common::String(g_lingo->getName(i))));
 }
 
 void LC::c_argcpush() {
@@ -1310,6 +1310,7 @@ void LC::call(Symbol *sym, int nargs) {
 	fp->retpc = g_lingo->_pc;
 	fp->retscript = g_lingo->_currentScript;
 	fp->retctx = g_lingo->_currentScriptContext;
+	fp->retarchive = g_lingo->_archiveIndex;
 	fp->localvars = g_lingo->_localvars;
 
 	// Create new set of local variables
@@ -1356,6 +1357,9 @@ void LC::call(Symbol *sym, int nargs) {
 	if (sym->ctx) {
 		g_lingo->_currentScriptContext = sym->ctx;
 	}
+	if (sym->archiveIndex) {
+		g_lingo->_archiveIndex = sym->archiveIndex;
+	}
 
 	g_lingo->execute(0);
 
@@ -1376,6 +1380,7 @@ void LC::c_procret() {
 
 	g_lingo->_currentScript = fp->retscript;
 	g_lingo->_currentScriptContext = fp->retctx;
+	g_lingo->_archiveIndex = fp->retarchive;
 	g_lingo->_pc = fp->retpc;
 
 	g_lingo->cleanLocalVars();
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index ee8b582..e497a24 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -275,6 +275,7 @@ Symbol *Lingo::define(Common::String &name, int nargs, ScriptData *code) {
 	sym->argNames = NULL;
 	sym->varNames = NULL;
 	sym->ctx = NULL;
+	sym->archiveIndex = -1;
 
 	if (debugChannelSet(1, kDebugLingoCompile)) {
 		uint pc = 0;
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index 9184f8f..79aa68b 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -200,8 +200,8 @@ void Lingo::runMovieScript(LEvent event) {
 	if (_dontPassEvent)
 		return;
 
-	for (ScriptContextHash::iterator it = _scriptContexts[kMovieScript].begin();
-			it != _scriptContexts[kMovieScript].end(); ++it) {
+	for (ScriptContextHash::iterator it = _archives[_archiveIndex].scriptContexts[kMovieScript].begin();
+			it != _archives[_archiveIndex].scriptContexts[kMovieScript].end(); ++it) {
 		processEvent(event, kMovieScript, it->_key);
 		// TODO: How do know which script handles the message?
 	}
@@ -319,7 +319,7 @@ void Lingo::processEvent(LEvent event, ScriptType st, int entityId) {
 	if (_handlers.contains(ENTITY_INDEX(event, entityId))) {
 		debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d), _eventHandler", _eventHandlerTypes[event], scriptType2str(st), entityId);
 		executeHandler(_eventHandlerTypes[event]); // D4+ Events
-	} else if (_vm->getVersion() < 4 && event == kEventNone && _scriptContexts[st].contains(entityId)) {
+	} else if (_vm->getVersion() < 4 && event == kEventNone && getScriptContext(st, entityId)) {
 		debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d), script", _eventHandlerTypes[event], scriptType2str(st), entityId);
 
 		executeScript(st, entityId, 0); // D3 list of scripts.
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index c2ad108..c58a7ab 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -75,6 +75,8 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
 
 	_dontPassEvent = false;
 
+	_archiveIndex = 0;
+
 	initEventHandlerTypes();
 
 	initBuiltIns();
@@ -89,13 +91,23 @@ Lingo::~Lingo() {
 }
 
 ScriptContext *Lingo::getScriptContext(ScriptType type, uint16 id) {
-	if (type >= (int)_scriptContexts->size()) {
+	if (type >= (int)_archives[_archiveIndex].scriptContexts->size()) {
 		return NULL;
 	}
-	if (!_scriptContexts[type].contains(id)) {
+	if (!_archives[_archiveIndex].scriptContexts[type].contains(id)) {
 		return NULL;
 	}
-	return _scriptContexts[type][id];
+	return _archives[_archiveIndex].scriptContexts[type][id];
+}
+
+Common::String Lingo::getName(uint16 id) {
+	Common::String result;
+	if (id >= _archives[_archiveIndex].names.size()) {
+		warning("Name id %d not in list", id);
+		return result;
+	}
+	result = _archives[_archiveIndex].names[id];
+	return result;
 }
 
 const char *Lingo::findNextDefinition(const char *s) {
@@ -149,7 +161,7 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
 	_currentScriptContext = new ScriptContext;
 	_currentScriptType = type;
 	_currentEntityId = id;
-	_scriptContexts[type][id] = _currentScriptContext;
+	_archives[_archiveIndex].scriptContexts[type][id] = _currentScriptContext;
 
 	// FIXME: unpack into seperate functions
 	_currentScriptFunction = 0;
@@ -272,14 +284,14 @@ void Lingo::restartLingo() {
 	warning("STUB: restartLingo()");
 
 	for (int i = 0; i <= kMaxScriptType; i++) {
-		for (ScriptContextHash::iterator it = _scriptContexts[i].begin(); it != _scriptContexts[i].end(); ++it) {
+		for (ScriptContextHash::iterator it = _archives[_archiveIndex].scriptContexts[i].begin(); it != _archives[_archiveIndex].scriptContexts[i].end(); ++it) {
 			for (size_t j = 0; j < it->_value->functions.size(); j++) {
 				delete it->_value->functions[j];
 			}
 			delete it->_value;
 		}
 
-		_scriptContexts[i].clear();
+		_archives[_archiveIndex].scriptContexts[i].clear();
 	}
 
 	// TODO
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index ab6e681..4e37db9 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -88,6 +88,7 @@ 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 */
 
 	Symbol();
 };
@@ -140,9 +141,17 @@ struct CFrame {	/* proc/func call stack frame */
 	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 */
 	SymbolHash *localvars;
 };
 
+
+struct LingoArchive {
+	ScriptContextHash scriptContexts[kMaxScriptType + 1];
+	Common::Array<Common::String> names;
+};
+
+
 class Lingo {
 
 public:
@@ -182,9 +191,10 @@ private:
 	void runMovieScript(LEvent event);
 	void processSpriteEvent(LEvent event);
 	void processEvent(LEvent event, ScriptType st, int entityId);
-	ScriptContext *getScriptContext(ScriptType type, uint16 id);
 
 public:
+	ScriptContext *getScriptContext(ScriptType type, uint16 id);
+	Common::String getName(uint16 id);
 	ScriptType event2script(LEvent ev);
 	Symbol *getHandler(Common::String &name);
 
@@ -304,7 +314,6 @@ public:
 	int _objectEntityId;
 
 	Common::Array<int> _labelstack;
-	Common::Array<Common::String> _namelist;
 
 	SymbolHash _builtins;
 	Common::HashMap<Common::String, bool> _twoWordBuiltins;
@@ -341,8 +350,6 @@ public:
 	Common::HashMap<Common::String, uint32, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _eventHandlerTypeIds;
 	Common::HashMap<Common::String, Audio::AudioStream *> _audioAliases;
 
-	ScriptContextHash _scriptContexts[kMaxScriptType + 1];
-
 	SymbolHash _globalvars;
 	SymbolHash *_localvars;
 
@@ -351,6 +358,9 @@ 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/resource.cpp b/engines/director/resource.cpp
index 0014f2e..4894cc3 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -305,6 +305,7 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
 	debug(0, "@@@@ Loading Shared cast '%s'", filename.c_str());
 	debug(0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
 
+	_lingo->_archiveIndex = 1;
 	_sharedScore = new Score(this);
 	_sharedScore->setArchive(sharedCast);
 
@@ -409,6 +410,7 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
 	}
 
 	_sharedScore->loadSpriteImages(true);
+	_lingo->_archiveIndex = 0;
 }
 
 } // End of namespace Director




More information about the Scummvm-git-logs mailing list