From 6d4a9f54e1f41ebc506cbf177bf2d18ae056a99f Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Wed, 23 Dec 2015 23:05:56 +0100 Subject: WAGE: Implement first round of comparisons --- engines/wage/entities.cpp | 4 ++- engines/wage/entities.h | 3 +- engines/wage/script.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++--- engines/wage/script.h | 25 +++++---------- engines/wage/wage.h | 11 +++++++ 5 files changed, 99 insertions(+), 23 deletions(-) diff --git a/engines/wage/entities.cpp b/engines/wage/entities.cpp index 75b624c4c7..e6ce4e9e5a 100644 --- a/engines/wage/entities.cpp +++ b/engines/wage/entities.cpp @@ -60,6 +60,7 @@ void Designed::setDesignBounds(Common::Rect *bounds) { Scene::Scene(String name, Common::SeekableReadStream *data) { _name = name; + _classType = SCENE; _design = new Design(data); setDesignBounds(readRect(data)); @@ -81,7 +82,7 @@ Scene::Scene(String name, Common::SeekableReadStream *data) { Obj::Obj(String name, Common::SeekableReadStream *data) : _currentOwner(NULL), _currentScene(NULL) { _name = name; - + _classType = OBJ; _design = new Design(data); setDesignBounds(readRect(data)); @@ -125,6 +126,7 @@ Obj::Obj(String name, Common::SeekableReadStream *data) : _currentOwner(NULL), _ Chr::Chr(String name, Common::SeekableReadStream *data) { _name = name; + _classType = CHR; _design = new Design(data); setDesignBounds(readRect(data)); diff --git a/engines/wage/entities.h b/engines/wage/entities.h index edb63ef1e7..eb3609c7ff 100644 --- a/engines/wage/entities.h +++ b/engines/wage/entities.h @@ -108,11 +108,12 @@ public: class Designed { public: - Designed() : _design(NULL), _designBounds(NULL) {} + Designed() : _design(NULL), _designBounds(NULL), _classType(UNKNOWN) {} String _name; Design *_design; Common::Rect *_designBounds; + OperandType _classType; Common::Rect *getDesignBounds() { return _designBounds == NULL ? NULL : new Common::Rect(*_designBounds); diff --git a/engines/wage/script.cpp b/engines/wage/script.cpp index b9e51c082a..8953fe1507 100644 --- a/engines/wage/script.cpp +++ b/engines/wage/script.cpp @@ -507,10 +507,10 @@ enum { }; struct Comparator { - char operation; - OperandTypes o1; - OperandTypes o2; - int compfunc; + char op; + OperandType o1; + OperandType o2; + int cmp; } static comparators[] = { { '=', NUMBER, NUMBER, kCompEqNumNum }, { '=', OBJ, SCENE, kCompEqObjScene }, @@ -644,11 +644,82 @@ bool Script::eval(Operand *lhs, const char *op, Operand *rhs) { } return result; + } else { + for (int cmp = 0; comparators[cmp].op != 0; cmp++) { + if (comparators[cmp].op == op[0] && + comparators[cmp].o1 == lhs->_type && comparators[cmp].o2 == rhs->_type) + return compare(lhs, rhs, comparators[cmp].cmp); + } + +#if 0 + // Now, try partial matches. + for (int cmp = 0; comparators[cmp].op != 0; cmp++) { + if (comparators[cmp].op == op[0]) + if (lhs->_typecomparators[cmp].o1 == lhs->_type) + } + + for (PairEvaluator e : handlers) { + Operand converted; + if (e.lhsType == o1.type && (converted = convertOperand(o2, e.rhsType)) != null) { + e.evaluatePair(o1, converted); + return; + } else if (e.rhsType == o2.type && (converted = convertOperand(o1, e.lhsType)) != null) { + e.evaluatePair(converted, o2); + return; + } + } + + // Now, try double conversion. + for (PairEvaluator e : handlers) { + Operand c1, c2; + if ((c1 = convertOperand(o1, e.lhsType)) != null && + (c2 = convertOperand(o2, e.rhsType)) != null) { + e.evaluatePair(c1, c2); + return; + } + } +#endif } return false; } +Script::Operand *Script::convertOperand(Operand *operand, int type) { + if (operand->_type == type) + return operand; + + if (type == SCENE) { + if (operand->_type == STRING || operand->_type == NUMBER) { + Common::String key(operand->toString()); + key.toLowercase(); + if (_world->_scenes.contains(key)) + return new Operand(_world->_scenes[key], SCENE); + } + } else if (type == OBJ) { + if (operand->_type == STRING || operand->_type == NUMBER) { + Common::String key = operand->toString(); + key.toLowercase(); + if (_world->_objs.contains(key)) + return new Operand(_world->_objs[key], OBJ); + } else if (operand->_type == CLICK_INPUT) { + if (_inputClick->_classType == OBJ) + return new Operand(_inputClick, OBJ); + } + } else if (type == CHR) { + if (operand->_type == STRING || operand->_type == NUMBER) { + Common::String key = operand->toString(); + key.toLowercase(); + if (_world->_chrs.contains(key)) + return new Operand(_world->_chrs[key], CHR); + } else if (operand->_type == CLICK_INPUT) { + if (_inputClick->_classType == CHR) + return new Operand(_inputClick, CHR); + } + } + + return NULL; +} + bool Script::evalClickCondition(Operand *lhs, const char *op, Operand *rhs) { warning("STUB: evalClickCondition"); diff --git a/engines/wage/script.h b/engines/wage/script.h index d1d3d217ad..b9249c33c6 100644 --- a/engines/wage/script.h +++ b/engines/wage/script.h @@ -50,16 +50,6 @@ namespace Wage { -enum OperandTypes { - OBJ = 0, - CHR = 1, - SCENE = 2, - NUMBER = 3, - STRING = 4, - CLICK_INPUT = 5, - TEXT_INPUT = 6 -}; - class Script { public: Script(Common::SeekableReadStream *data) : _data(data) {} @@ -86,35 +76,35 @@ private: String *string; Designed *inputClick; } _value; - OperandTypes _type; + OperandType _type; Common::String _str; - Operand(Obj *value, OperandTypes type) { + Operand(Obj *value, OperandType type) { _value.obj = value; _type = type; } - Operand(Chr *value, OperandTypes type) { + Operand(Chr *value, OperandType type) { _value.chr = value; _type = type; } - Operand(Scene *value, OperandTypes type) { + Operand(Scene *value, OperandType type) { _value.scene = value; _type = type; } - Operand(int value, OperandTypes type) { + Operand(int value, OperandType type) { _value.number = value; _type = type; } - Operand(String *value, OperandTypes type) { + Operand(String *value, OperandType type) { _value.string = value; _type = type; } - Operand(Designed *value, OperandTypes type) { + Operand(Designed *value, OperandType type) { _value.inputClick = value; _type = type; } @@ -158,6 +148,7 @@ private: void skipIf(); bool compare(Operand *o1, Operand *o2, int comparator); bool eval(Operand *lhs, const char *op, Operand *rhs); + Operand *convertOperand(Operand *operand, int type); bool evalClickCondition(Operand *lhs, const char *op, Operand *rhs); void processMove(); void processLet(); diff --git a/engines/wage/wage.h b/engines/wage/wage.h index 2ad28c9527..1e57ef5d5a 100644 --- a/engines/wage/wage.h +++ b/engines/wage/wage.h @@ -68,6 +68,17 @@ class Chr; using Common::String; +enum OperandType { + OBJ = 0, + CHR = 1, + SCENE = 2, + NUMBER = 3, + STRING = 4, + CLICK_INPUT = 5, + TEXT_INPUT = 6, + UNKNOWN = 100 +}; + // our engine debug levels enum { kWageDebugExample = 1 << 0, -- cgit v1.2.3