diff options
author | Alyssa Milburn | 2011-11-26 23:43:54 +0100 |
---|---|---|
committer | Alyssa Milburn | 2011-11-26 23:45:40 +0100 |
commit | dc02f6712796d63a34bbbd4bfbab309a11bdb879 (patch) | |
tree | b69a6c0307989743bbb1c31207425eb9e8b84de6 | |
parent | a6af439effc1bc5381a86f41b8d4c66f9e19d567 (diff) | |
download | scummvm-rg350-dc02f6712796d63a34bbbd4bfbab309a11bdb879.tar.gz scummvm-rg350-dc02f6712796d63a34bbbd4bfbab309a11bdb879.tar.bz2 scummvm-rg350-dc02f6712796d63a34bbbd4bfbab309a11bdb879.zip |
MOHAWK: Add some basic LB list support.
-rw-r--r-- | engines/mohawk/livingbooks_code.cpp | 102 | ||||
-rw-r--r-- | engines/mohawk/livingbooks_code.h | 21 |
2 files changed, 112 insertions, 11 deletions
diff --git a/engines/mohawk/livingbooks_code.cpp b/engines/mohawk/livingbooks_code.cpp index 28cf47783e..59b0510123 100644 --- a/engines/mohawk/livingbooks_code.cpp +++ b/engines/mohawk/livingbooks_code.cpp @@ -480,26 +480,66 @@ void LBCode::parseMain() { if (_currToken == kTokenAssign) error("attempted assignment to self"); break; - } else if (_currToken == kTokenAssign) { + } + bool indexing = false; + LBValue index; + if (_currToken == kTokenListStart) { + debugN("["); + nextToken(); + parseStatement(); + if (_currToken != kTokenListEnd) + error("expected list end"); + debugN("]"); + nextToken(); + if (!_stack.size()) + error("index failed"); + indexing = true; + index = _stack.pop(); + } + if (_currToken == kTokenAssign) { debugN(" = "); nextToken(); parseStatement(); if (!_stack.size()) error("assignment failed"); - LBValue *val = &_vm->_variables[varname]; - *val = _stack.pop(); + LBValue *val; + if (indexing) + val = getIndexedVar(varname, index); + else + val = &_vm->_variables[varname]; + if (val) + *val = _stack.pop(); + else + *val = LBValue(); _stack.push(*val); } else { - _stack.push(_vm->_variables[varname]); + if (indexing) { + LBValue *val = getIndexedVar(varname, index); + if (val) + _stack.push(*val); + else + _stack.push(LBValue()); + } else + _stack.push(_vm->_variables[varname]); } // FIXME: pre/postincrement for non-integers if (_currToken == kTokenPlusPlus) { debugN("++"); - _vm->_variables[varname].integer++; + if (indexing) { + LBValue *val = getIndexedVar(varname, index); + if (val) + val->integer++; + } else + _vm->_variables[varname].integer++; nextToken(); } else if (_currToken == kTokenMinusMinus) { debugN("--"); - _vm->_variables[varname].integer--; + if (indexing) { + LBValue *val = getIndexedVar(varname, index); + if (val) + val->integer--; + } else + _vm->_variables[varname].integer--; nextToken(); } } @@ -611,6 +651,17 @@ void LBCode::parseMain() { } } +LBValue *LBCode::getIndexedVar(Common::String varname, const LBValue &index) { + LBValue &var = _vm->_variables[varname]; + if (var.type != kLBValueList) + error("variable '%s' was indexed, but isn't a list", varname.c_str()); + if (index.type != kLBValueInteger) + error("index wasn't an integer"); + if (index.integer < 1 || index.integer > (int)var.list->array.size()) + return NULL; + return &var.list->array[index.integer - 1]; +} + LBItem *LBCode::resolveItem(const LBValue &value) { if (value.type == kLBValueItemPtr) return value.item; @@ -731,7 +782,7 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = { { "getPage", 0 }, { "getWorldRect", 0 }, { "isWorldWrap", 0 }, - { "newList", 0 }, + { "newList", &LBCode::cmdNewList }, { "deleteList", 0 }, { "add", 0 }, { 0, 0 }, @@ -741,9 +792,9 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = { { 0, 0 }, { "getIndex", 0 }, { "setAt", 0 }, - { "listLen", 0 }, - { "deleteAt", 0 }, - { "clearList", 0 }, + { "listLen", &LBCode::cmdListLen }, + { "deleteAt", &LBCode::cmdDeleteAt }, + { "clearList", &LBCode::cmdUnimplemented }, { "setWorld", 0 }, { "setProperty", 0 }, { "getProperty", 0 }, @@ -961,6 +1012,37 @@ void LBCode::cmdSetDragParams(const Common::Array<LBValue> ¶ms) { warning("ignoring setDragParams"); } +void LBCode::cmdNewList(const Common::Array<LBValue> ¶ms) { + if (params.size() != 0) + error("incorrect number of parameters (%d) to newList", params.size()); + + _stack.push(Common::SharedPtr<LBList>(new LBList)); +} + +void LBCode::cmdListLen(const Common::Array<LBValue> ¶ms) { + if (params.size() != 1) + error("incorrect number of parameters (%d) to listLen", params.size()); + + if (params[0].type != kLBValueList || !params[0].list) + error("invalid lbx object passed to lbxFunc"); + + _stack.push(params[0].list->array.size()); +} + +void LBCode::cmdDeleteAt(const Common::Array<LBValue> ¶ms) { + if (params.size() != 2) + error("incorrect number of parameters (%d) to deleteAt", params.size()); + + if (params[0].type != kLBValueList || !params[0].list) + error("invalid lbx object passed to deleteAt"); + + if (params[1].type != kLBValueInteger) + error("invalid index passed to deleteAt"); + if (params[1].integer < 1 || params[1].integer > (int)params[0].list->array.size()) + return; + params[0].list->array.remove_at(params[1].integer - 1); +} + void LBCode::cmdSetPlayParams(const Common::Array<LBValue> ¶ms) { if (params.size() > 8) error("too many parameters (%d) to setPlayParams", params.size()); diff --git a/engines/mohawk/livingbooks_code.h b/engines/mohawk/livingbooks_code.h index 84ea66a4c7..552a5f4cc0 100644 --- a/engines/mohawk/livingbooks_code.h +++ b/engines/mohawk/livingbooks_code.h @@ -23,6 +23,7 @@ #ifndef MOHAWK_LIVINGBOOKS_CODE_H #define MOHAWK_LIVINGBOOKS_CODE_H +#include "common/ptr.h" #include "common/rect.h" #include "common/stack.h" #include "common/substream.h" @@ -31,6 +32,7 @@ namespace Mohawk { class MohawkEngine_LivingBooks; class LBItem; +struct LBList; enum LBValueType { kLBValueString, @@ -38,7 +40,8 @@ enum LBValueType { kLBValueReal, kLBValuePoint, kLBValueRect, - kLBValueItemPtr + kLBValueItemPtr, + kLBValueList }; struct LBValue { @@ -66,6 +69,10 @@ struct LBValue { type = kLBValueItemPtr; item = itm; } + LBValue(Common::SharedPtr<LBList> l) { + type = kLBValueList; + list = l; + } LBValue(const LBValue &val) { type = val.type; switch (type) { @@ -87,6 +94,9 @@ struct LBValue { case kLBValueItemPtr: item = val.item; break; + case kLBValueList: + list = val.list; + break; } } @@ -97,6 +107,7 @@ struct LBValue { Common::Point point; Common::Rect rect; LBItem *item; + Common::SharedPtr<LBList> list; bool operator==(const LBValue &x) const; bool operator!=(const LBValue &x) const; @@ -111,6 +122,10 @@ struct LBValue { Common::Rect toRect() const; }; +struct LBList { + Common::Array<LBValue> array; +}; + enum { kLBCodeLiteralInteger = 0x1 }; @@ -207,6 +222,7 @@ protected: void parseArithmetic2(); void parseMain(); + LBValue *getIndexedVar(Common::String varname, const LBValue &index); LBItem *resolveItem(const LBValue &value); Common::Array<LBValue> readParams(); Common::Rect getRectFromParams(const Common::Array<LBValue> ¶ms); @@ -233,6 +249,9 @@ public: void cmdBottom(const Common::Array<LBValue> ¶ms); void cmdRight(const Common::Array<LBValue> ¶ms); void cmdSetDragParams(const Common::Array<LBValue> ¶ms); + void cmdNewList(const Common::Array<LBValue> ¶ms); + void cmdListLen(const Common::Array<LBValue> ¶ms); + void cmdDeleteAt(const Common::Array<LBValue> ¶ms); void cmdSetPlayParams(const Common::Array<LBValue> ¶ms); void cmdSetKeyEvent(const Common::Array<LBValue> ¶ms); void cmdSetHitTest(const Common::Array<LBValue> ¶ms); |