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

moralrecordings code at moral.net.au
Sat Feb 8 06:53:03 UTC 2020


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

Summary:
42462f1e11 DIRECTOR: LINGO: Add opcode stubs, decouple script context fetching
31c8e09540 DIRECTOR: LINGO: Fix argument order of c_of
f08d512bff DIRECTOR: LINGO: Set range of b_random(i) as [1, i]
ab09750ac9 DIRECTOR: LINGO: Partial implementation of c_of


Commit: 42462f1e11d33346be5b9808dd3b23e3fbf44aa2
    https://github.com/scummvm/scummvm/commit/42462f1e11d33346be5b9808dd3b23e3fbf44aa2
Author: Scott Percival (code at moral.net.au)
Date: 2020-02-08T14:50:05+08:00

Commit Message:
DIRECTOR: LINGO: Add opcode stubs, decouple script context fetching

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


diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 0e1b704..2d420f0 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -66,6 +66,7 @@ static LingoV4Bytecode lingoV4[] = {
 	{ 0x43, LC::c_argcpush,		"b" },
 	// 0x44, push a constant
 	{ 0x45, LC::c_namepush,		"b" },
+	{ 0x46, LC::cb_objectpush,  "b" },
 	{ 0x49, LC::cb_globalpush,	"b" },
 	{ 0x4b, LC::cb_varpush,		"bpa" },
 	{ 0x4c, LC::cb_varpush,		"bpv" },
@@ -77,6 +78,7 @@ static LingoV4Bytecode lingoV4[] = {
 	{ 0x55, LC::c_jumpifz,		"jb" },
 	{ 0x56, LC::cb_localcall,	"b" },
 	{ 0x57, LC::cb_call,		"b" },
+	{ 0x58, LC::cb_methodcall,  "b" },
 	{ 0x59, LC::cb_v4assign,	"b" },
 	{ 0x5c, LC::cb_v4theentitypush, "b" },
 	{ 0x5d, LC::cb_v4theentityassign, "b" },
@@ -85,6 +87,8 @@ static LingoV4Bytecode lingoV4[] = {
 	{ 0x82, LC::c_argcnoretpush,"w" },
 	{ 0x83, LC::c_argcpush,		"w" },
 	// 0x84, push a constant
+	{ 0x85, LC::c_namepush,     "w" },
+	{ 0x86, LC::cb_objectpush,  "w" },
 	{ 0x89, LC::cb_globalpush,	"w" },
 	{ 0x8b, LC::cb_varpush,		"wpa" },
 	{ 0x8c, LC::cb_varpush,		"wpv" },
@@ -94,6 +98,13 @@ static LingoV4Bytecode lingoV4[] = {
 	{ 0x93, LC::c_jump,			"jw" },
 	{ 0x94, LC::c_jump,			"jwn" },
 	{ 0x95, LC::c_jumpifz,		"jw" },
+	{ 0x96, LC::cb_localcall,	"w" },
+	{ 0x97, LC::cb_call,		"w" },
+	{ 0x98, LC::cb_methodcall,  "w" },
+	{ 0x99, LC::cb_v4assign,	"w" },
+	{ 0x9c, LC::cb_v4theentitypush, "w" },
+	{ 0x9d, LC::cb_v4theentityassign, "w" },
+	{ 0xa6, LC::cb_v4theentitynamepush, "w" },
 	{ 0, 0, 0 }
 };
 
@@ -248,6 +259,24 @@ void LC::cb_localcall() {
 }
 
 
+void LC::cb_methodcall() {
+	g_lingo->readInt();
+	Datum obj = g_lingo->pop();
+	obj.toString();
+	warning("STUB: cb_methodcall(%s)", obj.u.s->c_str());
+
+	Datum nargs = g_lingo->pop();
+	if ((nargs.type == ARGC) || (nargs.type == ARGCNORET)) {
+		if (debugChannelSet(3, kDebugLingoExec))
+			g_lingo->printSTUBWithArglist("", nargs.u.i, "methodcall:");
+
+	} else {
+		warning("cb_methodcall: second arg should be of type ARGC or ARGCNORET, not %s", nargs.type2str());
+	}
+
+}
+
+
 void LC::cb_v4assign() {
 	int op = g_lingo->readInt();
 
@@ -366,6 +395,16 @@ void LC::cb_globalassign() {
 }
 
 
+void LC::cb_objectpush() {
+	int nameId = g_lingo->readInt();
+	Common::String name = g_lingo->_namelist[nameId];
+	warning("STUB: cb_objectpush(%s)", name.c_str());
+	Datum result;
+	result.type = VOID;
+	g_lingo->push(result);
+}
+
+
 void LC::cb_varpush() {
 	int nameId = g_lingo->readInt();
 	Common::String name = g_lingo->_namelist[nameId];
@@ -569,11 +608,11 @@ void LC::cb_zeropush() {
 void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType type, uint16 id) {
 	debugC(1, kDebugLingoCompile, "Add V4 bytecode for type %s with id %d", scriptType2str(type), id);
 
-	if (_scriptContexts[type].contains(id)) {
-		for (size_t j = 0; j < _scriptContexts[type][id]->functions.size(); j++) {
-			delete _scriptContexts[type][id]->functions[j];
-		}
-		delete _scriptContexts[type][id];
+	if (getScriptContext(type, id)) {
+		// 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", id, type);
+		return;
 	}
 
 	_currentScriptContext = new ScriptContext;
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 50a6fdf..0735031 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -144,6 +144,8 @@ static struct FuncDescr {
 	{ LC::cb_globalpush,	"cb_globalpush",	"i" },
 	{ LC::cb_list,			"cb_list",			"" },
 	{ LC::cb_localcall,		"cb_localcall",		"i" },
+	{ LC::cb_methodcall,	"cb_methodcall",	"i" },
+	{ LC::cb_objectpush,	"cb_objectpush",	"i" },
 	{ LC::cb_unk,			"cb_unk",			"i" },
 	{ LC::cb_unk1,			"cb_unk1",			"ii" },
 	{ LC::cb_unk2,			"cb_unk2",			"iii" },
diff --git a/engines/director/lingo/lingo-code.h b/engines/director/lingo/lingo-code.h
index 23dff63..6256fa8 100644
--- a/engines/director/lingo/lingo-code.h
+++ b/engines/director/lingo/lingo-code.h
@@ -137,6 +137,8 @@ namespace LC {
 	void cb_globalpush();
 	void cb_list();
 	void cb_localcall();
+	void cb_methodcall();
+	void cb_objectpush();
 	void cb_varassign();
 	void cb_varpush();
 	void cb_v4assign();
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 8f66ff9..13e5c3a 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -88,6 +88,16 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
 Lingo::~Lingo() {
 }
 
+ScriptContext *Lingo::getScriptContext(ScriptType type, uint16 id) {
+	if (type >= (int)_scriptContexts->size()) {
+		return NULL;
+	}
+	if (!_scriptContexts[type].contains(id)) {
+		return NULL;
+	}
+	return _scriptContexts[type][id];
+}
+
 const char *Lingo::findNextDefinition(const char *s) {
 	const char *res = s;
 
@@ -129,11 +139,11 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
 	debugC(1, kDebugLingoCompile, "Add code for type %s(%d) with id %d\n"
 			"***********\n%s\n\n***********", scriptType2str(type), type, id, code);
 
-	if (_scriptContexts[type].contains(id)) {
-		for (size_t j = 0; j < _scriptContexts[type][id]->functions.size(); j++) {
-			delete _scriptContexts[type][id]->functions[j];
-		}
-		delete _scriptContexts[type][id];
+	if (getScriptContext(type, id)) {
+		// 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", id, type);
+		return;
 	}
 
 	_currentScriptContext = new ScriptContext;
@@ -224,18 +234,19 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
 }
 
 void Lingo::executeScript(ScriptType type, uint16 id, uint16 function) {
-	if (!_scriptContexts[type].contains(id)) {
+	ScriptContext *sc = getScriptContext(type, id);
+	if (!sc) {
 		debugC(3, kDebugLingoExec, "Request to execute non-existant script type %d id %d", type, id);
 		return;
 	}
-	if (function >= _scriptContexts[type][id]->functions.size()) {
+	if (function >= sc->functions.size()) {
 		debugC(3, kDebugLingoExec, "Request to execute non-existant function %d in script type %d id %d", function, type, id);
 		return;
 	}
 
 	debugC(1, kDebugLingoExec, "Executing script type: %s, id: %d, function: %d", scriptType2str(type), id, function);
 
-	_currentScriptContext = _scriptContexts[type][id];
+	_currentScriptContext = sc;
 	_currentScript = _currentScriptContext->functions[function]->u.defn;
 	_pc = 0;
 	_returning = false;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 2f9dfd0..ab6e681 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -182,6 +182,7 @@ private:
 	void runMovieScript(LEvent event);
 	void processSpriteEvent(LEvent event);
 	void processEvent(LEvent event, ScriptType st, int entityId);
+	ScriptContext *getScriptContext(ScriptType type, uint16 id);
 
 public:
 	ScriptType event2script(LEvent ev);


Commit: 31c8e0954068aead43eae2bd415a3777e318ee33
    https://github.com/scummvm/scummvm/commit/31c8e0954068aead43eae2bd415a3777e318ee33
Author: Scott Percival (code at moral.net.au)
Date: 2020-02-08T14:50:05+08:00

Commit Message:
DIRECTOR: LINGO: Fix argument order of c_of

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


diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 0735031..888677c 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -665,15 +665,15 @@ void LC::c_within() {
 }
 
 void LC::c_of() {
-	Datum first_char = g_lingo->pop();
-	Datum last_char = g_lingo->pop();
-	Datum first_word = g_lingo->pop();
-	Datum last_word = g_lingo->pop();
-	Datum first_item = g_lingo->pop();
-	Datum last_item = g_lingo->pop();
-	Datum first_line = g_lingo->pop();
-	Datum last_line = g_lingo->pop();
 	Datum target = g_lingo->pop();
+	Datum last_line = g_lingo->pop();
+	Datum first_line = g_lingo->pop();
+	Datum last_item = g_lingo->pop();
+	Datum first_item = g_lingo->pop();
+	Datum last_word = g_lingo->pop();
+	Datum first_word = g_lingo->pop();
+	Datum last_char = g_lingo->pop();
+	Datum first_char = g_lingo->pop();
 
 	warning("STUB: c_of: %d %d %d %d %d %d %d %d %s",
 		first_char.u.i, last_char.u.i, first_word.u.i, last_word.u.i,


Commit: f08d512bff10caf50190b01c09200746280f164a
    https://github.com/scummvm/scummvm/commit/f08d512bff10caf50190b01c09200746280f164a
Author: Scott Percival (code at moral.net.au)
Date: 2020-02-08T14:50:05+08:00

Commit Message:
DIRECTOR: LINGO: Set range of b_random(i) as [1, i]

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


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 7c66d57..7635bf9 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -408,7 +408,7 @@ void LB::b_random(int nargs) {
 
 	max.toInt();
 
-	res.u.i = g_lingo->_vm->_rnd.getRandomNumber(max.u.i);
+	res.u.i = g_lingo->_vm->_rnd.getRandomNumber(max.u.i - 1) + 1;
 	res.type = INT;
 
 	g_lingo->push(res);


Commit: ab09750ac95d7c91574196627aa9dd7b66956548
    https://github.com/scummvm/scummvm/commit/ab09750ac95d7c91574196627aa9dd7b66956548
Author: Scott Percival (code at moral.net.au)
Date: 2020-02-08T14:50:05+08:00

Commit Message:
DIRECTOR: LINGO: Partial implementation of c_of

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


diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 888677c..055a152 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -567,11 +567,11 @@ void LC::c_ampersand() {
 	g_lingo->push(d1);
 }
 
-void LC::c_after() {
+void LC::c_before() {
 	LC::c_ampersand();
 }
 
-void LC::c_before() {
+void LC::c_after() {
 	Datum d2 = g_lingo->pop();
 	Datum d1 = g_lingo->pop();
 
@@ -665,6 +665,7 @@ void LC::c_within() {
 }
 
 void LC::c_of() {
+	// put char 5 of word 1 of line 2 into field "thing"
 	Datum target = g_lingo->pop();
 	Datum last_line = g_lingo->pop();
 	Datum first_line = g_lingo->pop();
@@ -675,13 +676,111 @@ void LC::c_of() {
 	Datum last_char = g_lingo->pop();
 	Datum first_char = g_lingo->pop();
 
-	warning("STUB: c_of: %d %d %d %d %d %d %d %d %s",
-		first_char.u.i, last_char.u.i, first_word.u.i, last_word.u.i,
-		first_item.u.i, last_item.u.i, first_line.u.i, last_line.u.i,
-		target.u.s->c_str());
+	target.toString();
+	Common::String result = *target.u.s;
+
+	if (first_line.u.i > 0) {
+		Common::String newline("\r");
+		int first = first_line.u.i;
+		int last = first;
+		if (last_line.u.i > 0) {
+			if ((first_item.u.i > 0) || (first_word.u.i > 0) || (first_char.u.i > 0)) {
+				warning("c_of: last_line defined but unused");
+			} else if (last_line.u.i < first_line.u.i) {
+				warning("c_of: last_line before first_line, ignoring");
+			} else {
+				last = last_line.u.i;
+			}
+		}
+		uint32 pointer = 0;
+		int curLine = 0;
+		int firstIndex = -1;
+		int lastIndex = -1;
+		while (pointer < result.size()) {
+			curLine += 1;
+			if (curLine == first) {
+				firstIndex = pointer;
+			}
+			pointer = result.find(newline, pointer);
+			if (curLine == last) {
+				lastIndex = pointer;
+				break;
+			}
+		}
+		if (firstIndex < 0) {
+			warning("c_of: first_line out of range");
+			result = "";
+		} else {
+			result = result.substr(firstIndex, lastIndex);
+		}
+	}
 
-	g_lingo->push(target);
+	if (first_item.u.i > 0) {
+		warning("STUB: c_of item indexing");
+	}
 
+	if (first_word.u.i > 0) {
+		int first = first_word.u.i;
+		int last = first;
+		if (last_word.u.i > 0) {
+			if (first_char.u.i > 0) {
+				warning("c_of: last_word defined but unused");
+			} else if (last_word.u.i < first_word.u.i) {
+				warning("c_of: last_word before first_word, ignoring");
+			} else {
+				last = last_word.u.i;
+			}
+		}
+		uint32 pointer = 0;
+		int curWord = 0;
+		int firstIndex = -1;
+		int lastIndex = -1;
+		bool inWord = false;
+		while (pointer < result.size()) {
+			if ((result[pointer] == '\r') || (result[pointer] == '\t') ||
+				(result[pointer] == '\n') || (result[pointer] == ' ')) {
+				if (inWord) {
+					inWord = false;
+					if (last == curWord) {
+						break;
+					}
+				}
+			} else {
+				if (!inWord) {
+					inWord = true;
+					curWord += 1;
+					if (first == curWord) {
+						firstIndex = pointer;
+					}
+				}
+			}
+			pointer += 1;
+		}
+		lastIndex = pointer;
+		if (firstIndex < 0) {
+			warning("c_of: first_word out of range");
+			result = "";
+		} else {
+			result = result.substr(firstIndex, lastIndex - firstIndex);
+		}
+	}
+
+	if (first_char.u.i > 0) {
+		int first = first_char.u.i;
+		int last = first;
+		if (last_char.u.i > 0) {
+			if (last_char.u.i < first_char.u.i) {
+				warning("c_of: last_char before first_char, ignoring");
+			} else {
+				last = last_char.u.i;
+			}
+		}
+		result = result.substr(first - 1, last - first);
+	}
+
+	*target.u.s = result;
+
+	g_lingo->push(target);
 }
 
 void LC::c_charOf() {




More information about the Scummvm-git-logs mailing list