[Scummvm-cvs-logs] scummvm master -> a0eacd0537a1fc10d2a29a435d59b31412daa0f6

dreammaster dreammaster at scummvm.org
Fri Jan 15 14:20:21 CET 2016


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:
a0eacd0537 MADS: Implement conversation conditionals evaluation


Commit: a0eacd0537a1fc10d2a29a435d59b31412daa0f6
    https://github.com/scummvm/scummvm/commit/a0eacd0537a1fc10d2a29a435d59b31412daa0f6
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2016-01-15T08:19:42-05:00

Commit Message:
MADS: Implement conversation conditionals evaluation

Changed paths:
    engines/mads/conversations.cpp
    engines/mads/conversations.h



diff --git a/engines/mads/conversations.cpp b/engines/mads/conversations.cpp
index 2ae07ba..f065ac2 100644
--- a/engines/mads/conversations.cpp
+++ b/engines/mads/conversations.cpp
@@ -151,6 +151,9 @@ void GameConversations::start() {
 	_runningConv->_cnd._currentNode = -1;
 	_runningConv->_cnd._numImports = 0;
 	_runningConv->_cnd._vars[0].setValue(_nextStartNode->_val);
+
+	// Store a reference to the variables list in the script handler for later reference
+	ScriptEntry::Conditional::_vars = &_runningConv->_cnd._vars;
 }
 
 void GameConversations::setVariable(uint idx, int val) {
@@ -441,7 +444,16 @@ int GameConversations::executeEntry(int index) {
 	bool flag = true;
 	for (uint scriptIdx = 0; scriptIdx < dlg._script.size(); ++scriptIdx) {
 		DialogCommand cmd = dlg._script[scriptIdx]._command;
-		// TODO
+		
+		switch (cmd) {
+		case CMD_1:
+		case CMD_HIDE:
+		case CMD_UNHIDE:
+			break;
+
+		default:
+			error("Unknown script opcode");
+		}
 	}
 
 	if (flag) {
@@ -774,10 +786,14 @@ void ScriptEntry::load(Common::SeekableReadStream &s) {
 	}
 }
 
+/*------------------------------------------------------------------------*/
+
+Common::Array<ConversationVar> *ScriptEntry::Conditional::_vars = nullptr;
+
 void ScriptEntry::Conditional::load(Common::SeekableReadStream &s) {
-	_paramsFlag = s.readUint16LE();
+	_operation = (ConditionalOperation)s.readUint16LE();
 
-	if (_paramsFlag == 0xff) {
+	if (_operation == CNVOP_ABORT) {
 		_param1._isVariable = false;
 		_param1._val = 0;
 		_param2._isVariable = false;
@@ -790,62 +806,53 @@ void ScriptEntry::Conditional::load(Common::SeekableReadStream &s) {
 	}
 }
 
-/*
-do {
-command = convFile->readByte();
-chk = convFile->readUint16BE();
-if (chk != 0xFF00 && chk != 0x0000) {
-warning("Error while reading conversation node entries - bailing out");
-break;
-}
-
-switch (command) {
-case cmdNodeEnd:
-//debug("Node end");
-break;
-case cmdDialogEnd:
-//debug("Dialog end");
-break;
-case cmdHide: {
-byte count = convFile->readByte();
-for (byte k = 0; k < count; k++) {
-//uint16 nodeRef = convFile->readUint16LE();
-//debug("Hide node %d", nodeRef);
-}
-
-}
-break;
-case cmdUnhide: {
-byte count = convFile->readByte();
-for (byte k = 0; k < count; k++) {
-//uint16 nodeRef = convFile->readUint16LE();
-//debug("Unhide node %d", nodeRef);
-}
-
-}
-break;
-case cmdMessage:
-//debug("Message");
-convFile->skip(7);	// TODO
-break;
-case cmdGoto: {
-convFile->skip(3);	// unused?
-//byte nodeRef = convFile->readByte();
-//debug("Goto %d", nodeRef);
-}
-break;
-case cmdAssign: {
-convFile->skip(3);	// unused?
-//uint16 value = convFile->readUint16LE();
-//uint16 variable = convFile->readUint16LE();
-//debug("Variable %d = %d", variable, value);
-}
-break;
-default:
-error("Unknown conversation command %d", command);
-break;
-}
-} while (command != cmdNodeEnd && command != cmdDialogEnd);
-*/
+int ScriptEntry::Conditional::evaluate() const {
+	if (_operation == CNVOP_NONE)
+		return -1;
+
+	int param1 = get(0);
+	if (_operation == CNVOP_VALUE)
+		return param1;
+	int param2 = get(1);
+
+	switch (_operation) {
+	case CNVOP_ADD:
+		return param1 + param2;
+	case CNVOP_SUBTRACT:
+		return param1 - param2;
+	case CNVOP_MULTIPLY:
+		return param1 * param2;
+	case CNVOP_DIVIDE:
+		return param1 / param2;
+	case CNVOP_MODULUS:
+		return param1 % param2;
+	case CNVOP_LTEQ:
+		return (param1 <= param2) ? 1 : 0;
+	case CNVOP_GTEQ:
+		return (param1 < param2) ? 1 : 0;
+	case CNVOP_LT:
+		return (param1 < param2) ? 1 : 0;
+	case CNVOP_GT:
+		return (param1 > param2) ? 1 : 0;
+	case CNVOP_NEQ:
+		return (param1 != param2) ? 1 : 0;
+	case CNVOP_EQ:
+		return (param1 == param2) ? 1 : 0;
+	case CNVOP_AND:
+		return (param1 || param2) ? 1 : 0;
+	case CNVOP_OR:
+		return (param1 && param2) ? 1 : 0;
+	default:
+		error("Unknown conditional operation");
+	}
+}
+
+int ScriptEntry::Conditional::get(int paramNum) const {
+	const CondtionalParamEntry &p = (paramNum == 0) ? _param1 : _param2;
+	return p._isVariable ? *(*_vars)[p._val].getValue() : p._val;
+}
+
+/*------------------------------------------------------------------------*/
+
 
 } // End of namespace MADS
diff --git a/engines/mads/conversations.h b/engines/mads/conversations.h
index 188f074..688fac7 100644
--- a/engines/mads/conversations.h
+++ b/engines/mads/conversations.h
@@ -68,6 +68,62 @@ enum ConvEntryFlag {
 	ENTRYFLAG_8000 = 0x8000
 };
 
+enum ConditionalOperation {
+	CNVOP_NONE = 0xff,
+	CNVOP_VALUE = 0,
+	CNVOP_ADD = 1,
+	CNVOP_SUBTRACT = 2,
+	CNVOP_MULTIPLY = 3,
+	CNVOP_DIVIDE = 4,
+	CNVOP_MODULUS = 5,
+	CNVOP_LTEQ = 6,
+	CNVOP_GTEQ = 7,
+	CNVOP_LT = 8,
+	CNVOP_GT = 9,
+	CNVOP_NEQ = 10,
+	CNVOP_EQ = 11,
+	CNVOP_AND = 12,
+	CNVOP_OR = 13,
+	CNVOP_ABORT = 0xff
+};
+
+
+struct ConversationVar {
+	bool _isPtr;
+	int _val;
+	int *_valPtr;
+
+	/**
+	 * Constructor
+	 */
+	ConversationVar() : _isPtr(false), _val(0), _valPtr(nullptr) {}
+
+	/**
+	 * Sets a numeric value
+	 */
+	void setValue(int val);
+
+	/**
+	 * Sets a pointer value
+	 */
+	void setValue(int *val);
+
+	/**
+	 * Return either the variable's pointer, or a pointer to it's direct value
+	 */
+	int *getValue() { return _isPtr ? _valPtr : &_val; }
+
+	/**
+	 * Returns true if variable is a pointer
+	 */
+	bool isPtr() const { return _isPtr; }
+
+	/**
+	 * Returns true if variable is numeric
+	 */
+	bool isNumeric() const { return !_isPtr; }
+};
+
 struct ScriptEntry {
 	struct Conditional {
 		struct CondtionalParamEntry {
@@ -80,19 +136,30 @@ struct ScriptEntry {
 			CondtionalParamEntry() : _isVariable(false), _val(0) {}
 		};
 
-		uint _paramsFlag;
+		static Common::Array<ConversationVar> *_vars;
+		ConditionalOperation _operation;
 		CondtionalParamEntry _param1;
 		CondtionalParamEntry _param2;
 
 		/**
 		 * Constructor
 		 */
-		Conditional() : _paramsFlag(false) {}
+		Conditional() : _operation(CNVOP_NONE) {}
 
 		/**
 		 * Loads data from a passed stream into the parameters structure
 		 */
 		void load(Common::SeekableReadStream &s);
+
+		/**
+		 * Gets the value
+		 */
+		int get(int paramNum) const;
+
+		/**
+		 * Evaluates the conditional
+		 */
+		int evaluate() const;
 	};
 
 	DialogCommand _command;
@@ -178,42 +245,6 @@ struct ConversationData {
 	void load(const Common::String &filename);
 };
 
-struct ConversationVar {
-	bool _isPtr;
-	int _val;
-	int *_valPtr;
-
-	/**
-	 * Constructor
-	 */
-	ConversationVar() : _isPtr(false), _val(0), _valPtr(nullptr) {}
-
-	/**
-	 * Sets a numeric value
-	 */
-	void setValue(int val);
-
-	/**
-	 * Sets a pointer value
-	 */
-	void setValue(int *val);
-
-	/**
-	 * Return either the variable's pointer, or a pointer to it's direct value
-	 */
-	int *getValue() { return _isPtr ? _valPtr : &_val; }
-
-	/**
-	 * Returns true if variable is a pointer
-	 */
-	bool isPtr() const { return _isPtr; }
-
-	/**
-	 * Returns true if variable is numeric
-	 */
-	bool isNumeric() const { return !_isPtr; }
-};
-
 /**
  * Conditional (i.e. changeable) data for the conversation
  */






More information about the Scummvm-git-logs mailing list