[Scummvm-git-logs] scummvm master -> 44d985d1221bbf4ce207a0744238b11e7838136f

moralrecordings code at moral.net.au
Fri Jan 24 17:39:27 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:
f1e6fe5109 CREDITS: Add myself to Director
44d985d122 DIRECTOR: LINGO: Process variable and argument names


Commit: f1e6fe5109f53a55c23c055beb4829b20dd5b7ae
    https://github.com/scummvm/scummvm/commit/f1e6fe5109f53a55c23c055beb4829b20dd5b7ae
Author: Scott Percival (code at moral.net.au)
Date: 2020-01-25T01:38:39+08:00

Commit Message:
CREDITS: Add myself to Director

Changed paths:
    AUTHORS


diff --git a/AUTHORS b/AUTHORS
index 7baffe0..0972ca5 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -109,6 +109,7 @@ ScummVM Team
     Director:
        Eugene Sandulenko
        Dmitry Iskrich
+       Scott Percival
        Steven Hoefel
        Tobia Tesan
 


Commit: 44d985d1221bbf4ce207a0744238b11e7838136f
    https://github.com/scummvm/scummvm/commit/44d985d1221bbf4ce207a0744238b11e7838136f
Author: Scott Percival (code at moral.net.au)
Date: 2020-01-25T01:38:39+08:00

Commit Message:
DIRECTOR: LINGO: Process variable and argument names

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


diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 0e376c8..8cd0155 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -67,9 +67,11 @@ static LingoV4Bytecode lingoV4[] = {
 	// 0x44, push a constant
 	{ 0x45, LC::c_namepush,		"b" },
 	{ 0x49, LC::cb_globalpush,	"b" },
-	{ 0x4c, LC::cb_varpush,		"b" },
+	{ 0x4b, LC::cb_varpush,		"bpa" },
+	{ 0x4c, LC::cb_varpush,		"bpv" },
 	{ 0x4f, LC::cb_globalassign,"b" },
-	{ 0x52, LC::cb_varassign,	"b" },
+	{ 0x51, LC::cb_varassign,	"bpa" },
+	{ 0x52, LC::cb_varassign,	"bpv" },
 	{ 0x53, LC::c_jump,			"jb" },
 	{ 0x54, LC::c_jump,			"jbn" },
 	{ 0x55, LC::c_jumpifz,		"jb" },
@@ -84,9 +86,11 @@ static LingoV4Bytecode lingoV4[] = {
 	{ 0x83, LC::c_argcpush,		"w" },
 	// 0x84, push a constant
 	{ 0x89, LC::cb_globalpush,	"w" },
-	{ 0x8c, LC::cb_varpush,		"w" },
+	{ 0x8b, LC::cb_varpush,		"wpa" },
+	{ 0x8c, LC::cb_varpush,		"wpv" },
 	{ 0x8f, LC::cb_globalassign,"w" },
-	{ 0x92, LC::cb_varassign,	"w" },
+	{ 0x91, LC::cb_varassign,	"wpa" },
+	{ 0x92, LC::cb_varassign,	"wpv" },
 	{ 0x93, LC::c_jump,			"jw" },
 	{ 0x94, LC::c_jump,			"jwn" },
 	{ 0x95, LC::c_jumpifz,		"jw" },
@@ -599,13 +603,13 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 	debugC(5, kDebugLoading, "Lscr globals list:");
 	stream.seek(globalsOffset);
 	for (uint16 i = 0; i < globalsCount; i++) {
-		uint16 nameIndex = stream.readUint16();
-		if (nameIndex < _namelist.size()) {
-			const char *name = _namelist[nameIndex].c_str();
+		uint16 index = stream.readUint16();
+		if (index < _namelist.size()) {
+			const char *name = _namelist[index].c_str();
 			debugC(5, kDebugLoading, "%d: %s", i, name);
-			Symbol *s = g_lingo->lookupVar(name, true, true);
+			g_lingo->lookupVar(name, true, true);
 		} else {
-			warning("Global %d has unknown name id %d, skipping define", i, nameIndex);
+			warning("Global %d has unknown name id %d, skipping define", i, index);
 		}
 	}
 
@@ -721,17 +725,14 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 			stream.hexdump(0x2a);
 		}
 
-		_currentScriptFunction = i;
-		_currentScript = new ScriptData;
-
 		uint16 nameIndex = stream.readUint16();
 		stream.readUint16();
 		uint32 length = stream.readUint32();
 		uint32 startOffset = stream.readUint32();
 		uint16 argCount = stream.readUint16();
-		/*uint32 argOffset = */stream.readUint32();
-		/*uint16 varCount = */stream.readUint16();
-		/*uint32 varNamesOffset = */stream.readUint32();
+		uint32 argOffset = stream.readUint32();
+		uint16 varCount = stream.readUint16();
+		uint32 varOffset = stream.readUint32();
 		stream.readUint16();
 		stream.readUint16();
 		stream.readUint16();
@@ -750,6 +751,61 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 			continue;
 		}
 
+		// Fetch argument name list
+		Common::Array<Common::String> *argNames = new Common::Array<Common::String>;
+		Common::HashMap<uint16, uint16> argMap;
+		if (argOffset < codeStoreOffset) {
+			warning("Function %d argument names start offset is out of bounds!", i);
+		} else if (argOffset + argCount*2 >= codeStoreOffset + codeStoreSize) {
+			warning("Function %d argument names end offset is out of bounds!", i);
+		} else {
+			debugC(5, kDebugLoading, "Function %d argument list:", i);
+			uint16 namePointer = argOffset - codeStoreOffset;
+			for (int j = 0; j < argCount; j++) {
+				uint16 index = (uint16)READ_BE_UINT16(&codeStore[namePointer]);
+				namePointer += 2;
+				Common::String name;
+				if (index < _namelist.size()) {
+					name = _namelist[index];
+					argMap[j] = index;
+				} else {
+					name = Common::String::format("arg_%d", j);
+					warning("Argument has unknown name id %d, using name %s", j, name.c_str());
+				}
+				debugC(5, kDebugLoading, "%d: %s", j, name.c_str());
+				argNames->push_back(name);
+			}
+		}
+
+		// Fetch variable name list
+		Common::Array<Common::String> *varNames = new Common::Array<Common::String>;
+		Common::HashMap<uint16, uint16> varMap;
+		if (varOffset < codeStoreOffset) {
+			warning("Function %d variable names start offset is out of bounds!", i);
+		} else if (varOffset + varCount*2 >= codeStoreOffset + codeStoreSize) {
+			warning("Function %d variable names end offset is out of bounds!", i);
+		} else {
+			debugC(5, kDebugLoading, "Function %d variable list:", i);
+			uint16 namePointer = varOffset - codeStoreOffset;
+			for (int j = 0; j < varCount; j++) {
+				uint16 index = (uint16)READ_BE_UINT16(&codeStore[namePointer]);
+				namePointer += 2;
+				Common::String name;
+				if (index < _namelist.size()) {
+					name = _namelist[index];
+					varMap[j] = index;
+				} else {
+					name = Common::String::format("var_%d", j);
+					warning("Variable has unknown name id %d, using name %s", j, name.c_str());
+				}
+				debugC(5, kDebugLoading, "%d: %s", j, name.c_str());
+				varNames->push_back(name);
+			}
+		}
+
+		_currentScriptFunction = i;
+		_currentScript = new ScriptData;
+
 		if (debugChannelSet(5, kDebugLoading)) {
 			debugC(5, kDebugLoading, "Function %d code:", i);
 			Common::hexdump(codeStore, length, 16, startOffset);
@@ -839,6 +895,31 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 							// argument is negative
 							arg *= -1;
 							break;
+						case 'p':
+							// argument is some kind of denormalised offset
+							if (arg % 6) {
+								warning("Argument %d was expected to be a multiple of 6", arg);
+							}
+							arg /= 6;
+							break;
+						case 'a':
+							// argument is a function argument ID
+							if (argMap.contains(arg)) {
+								arg = argMap[arg];
+							} else {
+								warning("No argument name found for ID %d", arg);
+								arg = -1;
+							}
+							break;
+						case 'v':
+							// argument is a local variable ID
+							if (varMap.contains(arg)) {
+								arg = varMap[arg];
+							} else {
+								warning("No variable name found for ID %d", arg);
+								arg = -1;
+							}
+							break;
 						case 'j':
 							// argument refers to a code offset; fix alignment in post
 							jumpList.push_back(offsetList.size());
@@ -900,6 +981,7 @@ 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);
 		} else {
 			warning("Function has unknown name id %d, skipping define", nameIndex);
@@ -909,6 +991,8 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 			sym->nargs = argCount;
 			sym->maxArgs = argCount;
 		}
+		sym->argNames = argNames;
+		sym->varNames = varNames;
 		sym->ctx = _currentScriptContext;
 		_currentScriptContext->functions.push_back(sym);
 
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 7a94b6d..33b3016 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1223,6 +1223,41 @@ void LC::call(Symbol *sym, int nargs) {
 
 	// Create new set of local variables
 	g_lingo->_localvars = new SymbolHash;
+	if (sym->argNames) {
+
+		if ((int)sym->argNames->size() < sym->nargs) {
+			int dropSize = sym->nargs - sym->argNames->size();
+			warning("%d arg names defined for %d args! Dropping the last %d values", sym->argNames->size(), sym->nargs, dropSize);
+			for (int i = 0; i < dropSize; i++) {
+				g_lingo->pop();
+				sym->nargs -= 1;
+			}
+		} else if ((int)sym->argNames->size() > sym->nargs) {
+			warning("%d arg names defined for %d args! Ignoring the last %d names", sym->argNames->size(), sym->nargs, sym->argNames->size() - sym->nargs);
+		}
+		for (int i = sym->nargs - 1; i >= 0; i--) {
+			Common::String name = (*sym->argNames)[i];
+			if (!g_lingo->_localvars->contains(name)) {
+				Datum arg;
+				arg.type = VAR;
+				arg.u.sym = g_lingo->lookupVar(name.c_str(), true, false);
+				Datum value = g_lingo->pop();
+				g_lingo->varAssign(arg, value);
+			} else {
+				warning("Argument %s already defined", name.c_str());
+			}
+		}
+	}
+	if (sym->varNames) {
+		for (Common::Array<Common::String>::iterator it = sym->varNames->begin(); it != sym->varNames->end(); ++it) {
+			Common::String name = *it;
+			if (!g_lingo->_localvars->contains(name)) {
+				g_lingo->lookupVar(name.c_str(), true, false);
+			} else {
+				warning("Variable %s already defined", name.c_str());
+			}
+		}
+	}
 
 	g_lingo->_callstack.push_back(fp);
 
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index cc78fba..ee8b582 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -271,6 +271,9 @@ Symbol *Lingo::define(Common::String &name, int nargs, ScriptData *code) {
 	sym->u.defn = code;
 	sym->nargs = nargs;
 	sym->maxArgs = nargs;
+	// TODO: Assign these properties from here
+	sym->argNames = NULL;
+	sym->varNames = NULL;
 	sym->ctx = NULL;
 
 	if (debugChannelSet(1, kDebugLingoCompile)) {
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 1445e01..337099d 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -85,6 +85,8 @@ struct Symbol {	/* symbol table entry */
 	bool parens;	/* whether parens required or not, for builitins */
 
 	bool global;
+	Common::Array<Common::String> *argNames;
+	Common::Array<Common::String> *varNames;
 	ScriptContext *ctx;		/* optional script context to execute with */
 
 	Symbol();




More information about the Scummvm-git-logs mailing list