aboutsummaryrefslogtreecommitdiff
path: root/engines/draci
diff options
context:
space:
mode:
authorDenis Kasak2009-07-06 17:25:34 +0000
committerDenis Kasak2009-07-06 17:25:34 +0000
commitf4ba64d2e4783b300242fd43ab6813d6c8ca8cdb (patch)
tree53245beaa69f91c5439cebdac4726ae36c6dfac3 /engines/draci
parent8e341ee968017be7d5bf7690473c80500c6b75d9 (diff)
downloadscummvm-rg350-f4ba64d2e4783b300242fd43ab6813d6c8ca8cdb.tar.gz
scummvm-rg350-f4ba64d2e4783b300242fd43ab6813d6c8ca8cdb.tar.bz2
scummvm-rg350-f4ba64d2e4783b300242fd43ab6813d6c8ca8cdb.zip
Implemented GPL operators.
svn-id: r42183
Diffstat (limited to 'engines/draci')
-rw-r--r--engines/draci/script.cpp128
-rw-r--r--engines/draci/script.h23
2 files changed, 123 insertions, 28 deletions
diff --git a/engines/draci/script.cpp b/engines/draci/script.cpp
index 00d68676e4..1e51402d65 100644
--- a/engines/draci/script.cpp
+++ b/engines/draci/script.cpp
@@ -96,25 +96,27 @@ void Script::setupCommandList() {
{ 27, 1, "FeedPassword", 3, { 1, 1, 1 }, NULL }
};
+ /** Operators used by the mathematical evaluator */
+ static const GPL2Operator gplOperators[] = {
+ {"&", &Script::operAnd },
+ {"|", &Script::operOr },
+ {"^", &Script::operXor },
+ {"==", &Script::operEqual },
+ {"!=", &Script::operNotEqual },
+ {"<", &Script::operLess },
+ {">", &Script::operGreater },
+ {"<=", &Script::operLessOrEqual },
+ {">=", &Script::operGreaterOrEqual },
+ {"*", &Script::operMul },
+ {"/", &Script::operDiv },
+ {"%", &Script::operMod },
+ {"+", &Script::operAdd },
+ {"-", &Script::operSub }
+ };
+
_commandList = gplCommands;
+ _operatorList = gplOperators;
}
-/** Operators used by the mathematical evaluator */
-Common::String operators[] = {
- "oper_and",
- "oper_or",
- "oper_xor",
- "oper_equals",
- "oper_not_equal",
- "oper_less_than",
- "oper_greater_than",
- "oper_less_or_equal",
- "oper_greater_or_equal",
- "oper_multiply",
- "oper_divide",
- "oper_remainder",
- "oper_plus",
- "oper_minus"
-};
/** Functions used by the mathematical evaluator */
Common::String functions[] = {
@@ -146,6 +148,66 @@ enum mathExpressionObject {
kMathVariable
};
+/* GPL operators */
+
+int Script::operAnd(int op1, int op2) {
+ return op1 & op2;
+}
+
+int Script::operOr(int op1, int op2) {
+ return op1 | op2;
+}
+
+int Script::operXor(int op1, int op2) {
+ return op1 ^ op2;
+}
+
+int Script::operEqual(int op1, int op2) {
+ return op1 == op2;
+}
+
+int Script::operNotEqual(int op1, int op2) {
+ return op1 != op2;
+}
+
+int Script::operLess(int op1, int op2) {
+ return op1 < op2;
+}
+
+int Script::operGreater(int op1, int op2) {
+ return op1 > op2;
+}
+
+int Script::operGreaterOrEqual(int op1, int op2) {
+ return op1 >= op2;
+}
+
+int Script::operLessOrEqual(int op1, int op2) {
+ return op1 <= op2;
+}
+
+int Script::operMul(int op1, int op2) {
+ return op1 * op2;
+}
+
+int Script::operAdd(int op1, int op2) {
+ return op1 + op2;
+}
+
+int Script::operSub(int op1, int op2) {
+ return op1 - op2;
+}
+
+int Script::operDiv(int op1, int op2) {
+ return op1 / op2;
+}
+
+int Script::operMod(int op1, int op2) {
+ return op1 % op2;
+}
+
+/* GPL commands */
+
void Script::load(Common::Queue<int> &params) {
int objID = params.pop() - 1;
int animID = params.pop() - 1;
@@ -161,13 +223,16 @@ void Script::load(Common::Queue<int> &params) {
*/
int Script::handleMathExpression(Common::MemoryReadStream &reader) {
- Common::Stack<uint16> stk;
+ Common::Stack<int> stk;
mathExpressionObject obj;
+ GPL2Operator oper;
// Read in initial math object
obj = (mathExpressionObject)reader.readUint16LE();
- uint16 value;
+ int value;
+ int op1, op2, res;
+
while (1) {
if (obj == kMathEnd) {
// Check whether the expression was evaluated correctly
@@ -184,25 +249,31 @@ int Script::handleMathExpression(Common::MemoryReadStream &reader) {
case kMathNumber:
value = reader.readUint16LE();
stk.push(value);
- debugC(3, kDraciBytecodeDebugLevel, "\t\t-number %hu", value);
+ debugC(3, kDraciBytecodeDebugLevel, "\t\tnumber: %d", value);
break;
case kMathOperator:
value = reader.readUint16LE();
- stk.pop();
- stk.pop();
+ op1 = stk.pop();
+ op2 = stk.pop();
- // FIXME: Pushing dummy value for now, but should push return value
- stk.push(0);
+ // Fetch operator
+ oper = _operatorList[value-1];
- debugC(3, kDraciBytecodeDebugLevel, "\t\t-operator %s",
- operators[value-1].c_str());
+ // Calculate result
+ res = (this->*(oper._handler))(op1, op2);
+
+ // Push result
+ stk.push(res);
+
+ debugC(3, kDraciBytecodeDebugLevel, "\t\t%d %s %d (res: %d)",
+ op1, oper._name.c_str(), op2, res);
break;
case kMathVariable:
value = reader.readUint16LE();
stk.push(value);
- debugC(3, kDraciBytecodeDebugLevel, "\t\t-variable %hu", value);
+ debugC(3, kDraciBytecodeDebugLevel, "\t\tvariable: %d", value);
break;
case kMathFunctionCall:
@@ -213,7 +284,7 @@ int Script::handleMathExpression(Common::MemoryReadStream &reader) {
// FIXME: Pushing dummy value for now, but should push return value
stk.push(0);
- debugC(3, kDraciBytecodeDebugLevel, "\t\t-functioncall %s",
+ debugC(3, kDraciBytecodeDebugLevel, "\t\tfunction: %s",
functions[value-1].c_str());
break;
}
@@ -303,6 +374,7 @@ int Script::run(GPL2Program program, uint16 offset) {
const GPL2Command *cmd;
do {
+
// read in command pair
uint16 cmdpair = reader.readUint16BE();
diff --git a/engines/draci/script.h b/engines/draci/script.h
index 5d8340858c..3908b1b660 100644
--- a/engines/draci/script.h
+++ b/engines/draci/script.h
@@ -43,6 +43,7 @@ enum {
};
typedef void (Script::* GPLHandler)(Common::Queue<int> &);
+typedef int (Script::* GPLOperatorHandler)(int, int);
/**
* Represents a single command in the GPL scripting language bytecode.
@@ -59,6 +60,11 @@ struct GPL2Command {
GPLHandler _handler;
};
+struct GPL2Operator {
+ Common::String _name;
+ GPLOperatorHandler _handler;
+};
+
/**
* A convenience data type that holds both the actual bytecode and the
* length of the bytecode. Passed to Script::run().
@@ -82,8 +88,25 @@ private:
/** List of all GPL commands. Initialised in the constructor. */
const GPL2Command *_commandList;
+ const GPL2Operator *_operatorList;
void load(Common::Queue<int> &params);
+ void start(Common::Queue<int> &params);
+
+ int operAnd(int op1, int op2);
+ int operOr(int op1, int op2);
+ int operXor(int op1, int op2);
+ int operSub(int op1, int op2);
+ int operAdd(int op1, int op2);
+ int operDiv(int op1, int op2);
+ int operMul(int op1, int op2);
+ int operEqual(int op1, int op2);
+ int operNotEqual(int op1, int op2);
+ int operGreater(int op1, int op2);
+ int operLess(int op1, int op2);
+ int operGreaterOrEqual(int op1, int op2);
+ int operLessOrEqual(int op1, int op2);
+ int operMod(int op1, int op2);
void setupCommandList();
const GPL2Command *findCommand(byte num, byte subnum);