[Scummvm-git-logs] scummvm master -> 884d420a0035dd23edf8396e1bcb5b5e858262cb

djsrv dservilla at gmail.com
Mon Jun 28 17:56:30 UTC 2021


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:
eb6670366e DIRECTOR: LINGO: Allow 'the' to fall back to generic object instructions
d37a680c8b DIRECTOR: LINGO: Fix menuItem property compilation
24974cd87d DIRECTOR: LINGO: Don't throw Lingo error in Datum::asCastId
884d420a00 DIRECTOR: LINGO: Handle the number of cast "nonexistent"


Commit: eb6670366e3e1d47a098da8b4a9fe6ea0286cde0
    https://github.com/scummvm/scummvm/commit/eb6670366e3e1d47a098da8b4a9fe6ea0286cde0
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-28T13:29:40-04:00

Commit Message:
DIRECTOR: LINGO: Allow 'the' to fall back to generic object instructions

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


diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 12ef24c2db..2cee784887 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -587,17 +587,14 @@ bool LingoCompiler::visitPutBeforeNode(PutBeforeNode *node) {
 
 /* SetNode */
 
-bool LingoCompiler::codeTheFieldSet(int entity, Node *id, const Common::String &field) {
-	Common::String fieldId = Common::String::format("%d%s", entity, field.c_str());
-	if (!g_lingo->_theEntityFields.contains(fieldId)) {
-		warning("BUILDBOT: LingoCompiler::codeTheFieldSet: Unhandled the field %s of %s", field.c_str(), g_lingo->entity2str(entity));
-		return false;
+int LingoCompiler::getTheFieldID(int entity, const Common::String &field, bool silent) {
+	Common::String fieldKey = Common::String::format("%d%s", entity, field.c_str());
+	if (!g_lingo->_theEntityFields.contains(fieldKey)) {
+		if (!silent)
+			warning("BUILDBOT: LingoCompiler::getTheFieldId: Unhandled the field %s of %s", field.c_str(), g_lingo->entity2str(entity));
+		return -1;
 	}
-	COMPILE(id);
-	code1(LC::c_theentityassign);
-	codeInt(entity);
-	codeInt(g_lingo->_theEntityFields[fieldId]->field);
-	return true;
+	return g_lingo->_theEntityFields[fieldKey]->field;
 }
 
 bool LingoCompiler::visitSetNode(SetNode *node) {
@@ -617,7 +614,6 @@ bool LingoCompiler::visitSetNode(SetNode *node) {
 	}
 
 	if (node->var->type == kTheOfNode) {
-		COMPILE(node->val);
 		TheOfNode *the = static_cast<TheOfNode *>(node->var);
 		switch (the->obj->type) {
 		case kFuncNode:
@@ -625,10 +621,28 @@ bool LingoCompiler::visitSetNode(SetNode *node) {
 				FuncNode *func = static_cast<FuncNode *>(the->obj);
 				if (func->args->size() == 1) {
 					if (func->name->equalsIgnoreCase("cast")) {
-						return codeTheFieldSet(kTheCast, (*func->args)[0], *the->prop);
+						int fieldId = getTheFieldID(kTheCast, *the->prop, true);
+						if (fieldId >= 0) {
+							COMPILE(node->val);
+							COMPILE((*func->args)[0]);
+							code1(LC::c_theentityassign);
+							codeInt(kTheCast);
+							codeInt(fieldId);
+							return true;
+						}
+						// fall back to generic object
 					}
 					if (func->name->equalsIgnoreCase("field")) {
-						return codeTheFieldSet(kTheField, (*func->args)[0], *the->prop);
+						int fieldId = getTheFieldID(kTheField, *the->prop, true);
+						if (fieldId >= 0) {
+							COMPILE(node->val);
+							COMPILE((*func->args)[0]);
+							code1(LC::c_theentityassign);
+							codeInt(kTheField);
+							codeInt(fieldId);
+							return true;
+						}
+						// fall back to generic object
 					}
 					// window is an object and is handled by that case
 				}
@@ -637,41 +651,65 @@ bool LingoCompiler::visitSetNode(SetNode *node) {
 		case kMenuNode:
 			{
 				MenuNode *menu = static_cast<MenuNode *>(the->obj);
-				return codeTheFieldSet(kTheMenu, menu->arg, *the->prop);
+				int fieldId = getTheFieldID(kTheMenu, *the->prop);
+				if (fieldId < 0)
+					return false;
+				COMPILE(node->val);
+				COMPILE(menu->arg);
+				code1(LC::c_theentityassign);
+				codeInt(kTheMenu);
+				codeInt(fieldId);
+				return true;
 			}
 			break;
 		case kMenuItemNode:
 			{
 				MenuItemNode *menuItem = static_cast<MenuItemNode *>(the->obj);
-				Common::String fieldId = Common::String::format("%d%s", kTheMenuItem, the->prop->c_str());
-				if (!g_lingo->_theEntityFields.contains(fieldId)) {
-					warning("BUILDBOT: LingoCompiler:visitTheNode: Unhandled the field %s of menuItem", the->prop->c_str());
+				int fieldId = getTheFieldID(kTheMenuItem, *the->prop);
+				if (fieldId < 0)
 					return false;
-				}
+				COMPILE(node->val);
 				COMPILE(menuItem->arg1)
 				COMPILE(menuItem->arg2);
 				code1(LC::c_theentityassign);
 				codeInt(kTheMenuItem);
-				codeInt(g_lingo->_theEntityFields[fieldId]->field);
+				codeInt(fieldId);
 				return true;
 			}
 			break;
 		case kSoundNode:
 			{
 				SoundNode *sound = static_cast<SoundNode *>(the->obj);
-				return codeTheFieldSet(kTheSoundEntity, sound->arg, *the->prop);
+				int fieldId = getTheFieldID(kTheSoundEntity, *the->prop);
+				if (fieldId < 0)
+					return false;
+				COMPILE(node->val);
+				COMPILE(sound->arg);
+				code1(LC::c_theentityassign);
+				codeInt(kTheSoundEntity);
+				codeInt(fieldId);
+				return true;
 			}
 			break;
 		case kSpriteNode:
 			{
 				SpriteNode *sprite = static_cast<SpriteNode *>(the->obj);
-				return codeTheFieldSet(kTheSprite, sprite->arg, *the->prop);
+				int fieldId = getTheFieldID(kTheSprite, *the->prop);
+				if (fieldId < 0)
+					return false;
+				COMPILE(node->val);
+				COMPILE(sprite->arg);
+				code1(LC::c_theentityassign);
+				codeInt(kTheSprite);
+				codeInt(fieldId);
+				return true;
 			}
 			break;
 		case kVarNode:
 			{
 				VarNode *var = static_cast<VarNode *>(the->obj);
 				if (the->prop->equalsIgnoreCase("number") && var->name->equalsIgnoreCase("castMembers")) {
+					COMPILE(node->val);
 					code1(LC::c_intpush);
 					codeInt(0); // Put dummy id
 					code1(LC::c_theentityassign);
@@ -1166,19 +1204,6 @@ bool LingoCompiler::visitTheNode(TheNode *node) {
 
 /* TheOfNode */
 
-bool LingoCompiler::codeTheFieldGet(int entity, Node *id, const Common::String &field) {
-	Common::String fieldId = Common::String::format("%d%s", entity, field.c_str());
-	if (!g_lingo->_theEntityFields.contains(fieldId)) {
-		warning("BUILDBOT: LingoCompiler::codeTheFieldGet: Unhandled the field %s of %s", field.c_str(), g_lingo->entity2str(entity));
-		return false;
-	}
-	COMPILE(id);
-	code1(LC::c_theentitypush);
-	codeInt(entity);
-	codeInt(g_lingo->_theEntityFields[fieldId]->field);
-	return true;
-}
-
 bool LingoCompiler::visitTheOfNode(TheOfNode *node) {
 	switch (node->obj->type) {
 	case kFuncNode:
@@ -1186,10 +1211,26 @@ bool LingoCompiler::visitTheOfNode(TheOfNode *node) {
 			FuncNode *func = static_cast<FuncNode *>(node->obj);
 			if (func->args->size() == 1) {
 				if (func->name->equalsIgnoreCase("cast")) {
-					return codeTheFieldGet(kTheCast, (*func->args)[0], *node->prop);
+					int fieldId = getTheFieldID(kTheCast, *node->prop, true);
+					if (fieldId >= 0) {
+						COMPILE((*func->args)[0]);
+						code1(LC::c_theentitypush);
+						codeInt(kTheCast);
+						codeInt(fieldId);
+						return true;
+					}
+					// fall back to generic object
 				}
 				if (func->name->equalsIgnoreCase("field")) {
-					return codeTheFieldGet(kTheField, (*func->args)[0], *node->prop);
+					int fieldId = getTheFieldID(kTheField, *node->prop, true);
+					if (fieldId >= 0) {
+						COMPILE((*func->args)[0]);
+						code1(LC::c_theentitypush);
+						codeInt(kTheField);
+						codeInt(fieldId);
+						return true;
+					}
+					// fall back to generic object
 				}
 				// window is an object and is handled by that case
 			}
@@ -1198,35 +1239,54 @@ bool LingoCompiler::visitTheOfNode(TheOfNode *node) {
 	case kMenuNode:
 		{
 			MenuNode *menu = static_cast<MenuNode *>(node->obj);
-			return codeTheFieldGet(kTheMenu, menu->arg, *node->prop);
+			int fieldId = getTheFieldID(kTheMenu, *node->prop);
+			if (fieldId < 0)
+				return false;
+			COMPILE(menu->arg);
+			code1(LC::c_theentitypush);
+			codeInt(kTheMenu);
+			codeInt(fieldId);
+			return true;
 		}
 		break;
 	case kMenuItemNode:
 		{
 			MenuItemNode *menuItem = static_cast<MenuItemNode *>(node->obj);
-			Common::String fieldId = Common::String::format("%d%s", kTheMenuItem, node->prop->c_str());
-			if (!g_lingo->_theEntityFields.contains(fieldId)) {
-				warning("BUILDBOT: LingoCompiler:visitTheNode: Unhandled the field %s of menuItem", node->prop->c_str());
+			int fieldId = getTheFieldID(kTheMenuItem, *node->prop);
+			if (fieldId < 0)
 				return false;
-			}
 			COMPILE(menuItem->arg1)
 			COMPILE(menuItem->arg2);
 			code1(LC::c_theentitypush);
 			codeInt(kTheMenuItem);
-			codeInt(g_lingo->_theEntityFields[fieldId]->field);
+			codeInt(fieldId);
 			return true;
 		}
 		break;
 	case kSoundNode:
 		{
 			SoundNode *sound = static_cast<SoundNode *>(node->obj);
-			return codeTheFieldGet(kTheSoundEntity, sound->arg, *node->prop);
+			int fieldId = getTheFieldID(kTheSoundEntity, *node->prop);
+			if (fieldId < 0)
+				return false;
+			COMPILE(sound->arg);
+			code1(LC::c_theentitypush);
+			codeInt(kTheSoundEntity);
+			codeInt(fieldId);
+			return true;
 		}
 		break;
 	case kSpriteNode:
 		{
 			SpriteNode *sprite = static_cast<SpriteNode *>(node->obj);
-			return codeTheFieldGet(kTheSprite, sprite->arg, *node->prop);
+			int fieldId = getTheFieldID(kTheSprite, *node->prop);
+			if (fieldId < 0)
+				return false;
+			COMPILE(sprite->arg);
+			code1(LC::c_theentitypush);
+			codeInt(kTheSprite);
+			codeInt(fieldId);
+			return true;
 		}
 		break;
 	case kVarNode:
diff --git a/engines/director/lingo/lingo-codegen.h b/engines/director/lingo/lingo-codegen.h
index 1c3e08db9e..0e205843b6 100644
--- a/engines/director/lingo/lingo-codegen.h
+++ b/engines/director/lingo/lingo-codegen.h
@@ -50,8 +50,7 @@ public:
 	void codeVarSet(const Common::String &name);
 	void codeVarRef(const Common::String &name);
 	void codeVarGet(const Common::String &name);
-	bool codeTheFieldSet(int entity, Node *id, const Common::String &field);
-	bool codeTheFieldGet(int entity, Node *id, const Common::String &field);
+	int getTheFieldID(int entity, const Common::String &field, bool silent = false);
 	void registerFactory(Common::String &s);
 	void registerMethodVar(const Common::String &name, VarType type = kVarGeneric);
 	void updateLoopJumps(uint nextTargetPos, uint exitTargetPos);


Commit: d37a680c8b89a3bb299099013ade842fe2e5961b
    https://github.com/scummvm/scummvm/commit/d37a680c8b89a3bb299099013ade842fe2e5961b
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-28T13:30:25-04:00

Commit Message:
DIRECTOR: LINGO: Fix menuItem property compilation

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 2cee784887..b2a9284e59 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -671,7 +671,7 @@ bool LingoCompiler::visitSetNode(SetNode *node) {
 				COMPILE(node->val);
 				COMPILE(menuItem->arg1)
 				COMPILE(menuItem->arg2);
-				code1(LC::c_theentityassign);
+				code1(LC::c_themenuitementityassign);
 				codeInt(kTheMenuItem);
 				codeInt(fieldId);
 				return true;
@@ -1257,7 +1257,7 @@ bool LingoCompiler::visitTheOfNode(TheOfNode *node) {
 				return false;
 			COMPILE(menuItem->arg1)
 			COMPILE(menuItem->arg2);
-			code1(LC::c_theentitypush);
+			code1(LC::c_themenuentitypush);
 			codeInt(kTheMenuItem);
 			codeInt(fieldId);
 			return true;


Commit: 24974cd87d6e47aaab4b40bcc27b857c7ec58c33
    https://github.com/scummvm/scummvm/commit/24974cd87d6e47aaab4b40bcc27b857c7ec58c33
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-28T13:44:02-04:00

Commit Message:
DIRECTOR: LINGO: Don't throw Lingo error in Datum::asCastId

Non-existent cast members don't always cause Lingo errors. Error
handling should be done by the callers of this function.

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


diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 3aa804b46e..578ee12407 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -890,8 +890,8 @@ int Datum::asCastId() const {
 			if (member)
 				return member->getID();
 
-			g_lingo->lingoError("Datum::asCastId: reference to non-existent cast member: %s", asString().c_str());
-			return 0;
+			warning("Datum::asCastId: reference to non-existent cast member: %s", asString().c_str());
+			return -1;
 		}
 		break;
 	case INT:


Commit: 884d420a0035dd23edf8396e1bcb5b5e858262cb
    https://github.com/scummvm/scummvm/commit/884d420a0035dd23edf8396e1bcb5b5e858262cb
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-28T13:44:29-04:00

Commit Message:
DIRECTOR: LINGO: Handle the number of cast "nonexistent"

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


diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index b65bce59fe..1fd50f177b 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -1494,6 +1494,8 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 	if (!member) {
 		if (field == kTheLoaded) {
 			d = 0;
+		} else if (field == kTheNumber) {
+			d = -1;
 		} else {
 			g_lingo->lingoError("Lingo::getTheCast(): CastMember %s not found", id1.asString().c_str());
 		}




More information about the Scummvm-git-logs mailing list