aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlyssa Milburn2011-04-07 00:33:11 +0200
committerAlyssa Milburn2011-04-07 00:33:11 +0200
commit40dd4f89baed798e431b671954e28755ca1aa73b (patch)
tree5a1dd6f3c3e1355b19f4d8940e4aabd3d89f4364
parentbbe2c437a86c6435012d5699dad8e9b4c88ca60c (diff)
downloadscummvm-rg350-40dd4f89baed798e431b671954e28755ca1aa73b.tar.gz
scummvm-rg350-40dd4f89baed798e431b671954e28755ca1aa73b.tar.bz2
scummvm-rg350-40dd4f89baed798e431b671954e28755ca1aa73b.zip
MOHAWK: Support LB script flow control.
-rw-r--r--engines/mohawk/livingbooks.cpp58
-rw-r--r--engines/mohawk/livingbooks.h7
2 files changed, 50 insertions, 15 deletions
diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp
index 3d22683739..542cc9645d 100644
--- a/engines/mohawk/livingbooks.cpp
+++ b/engines/mohawk/livingbooks.cpp
@@ -1956,17 +1956,19 @@ LBScriptEntry *LBItem::parseScriptEntry(uint16 type, uint16 &size, Common::Seeka
}
}
- if (type == kLBMsgListScript && entry->opcode == 0xfffb) {
- uint16 u1 = stream->readUint16();
- uint16 u2 = stream->readUint16();
- uint16 u3 = stream->readUint16();
- warning("unknown 0xfffb: %04x, %04x, %04x", u1, u2, u3);
+ if (type == kLBMsgListScript && entry->opcode == kLBOpJumpUnlessExpression) {
+ if (size < 6)
+ error("not enough bytes (%d) in kLBOpJumpUnlessExpression, event 0x%04x", size, entry->event);
+ entry->offset = stream->readUint32();
+ entry->target = stream->readUint16();
+ debug(4, "kLBOpJumpUnlessExpression: offset %08x, target %d", entry->offset, entry->target);
size -= 6;
}
- if (type == kLBMsgListScript && entry->opcode == 0xfffd) {
- uint16 u1 = stream->readUint16();
- uint16 u2 = stream->readUint16();
- warning("unknown 0xfffd: %04x, %04x", u1, u2);
+ if (type == kLBMsgListScript && entry->opcode == kLBOpJumpToExpression) {
+ if (size < 4)
+ error("not enough bytes (%d) in kLBOpJumpToExpression, event 0x%04x", size, entry->event);
+ entry->offset = stream->readUint32();
+ debug(4, "kLBOpJumpToExpression: offset %08x", entry->offset);
size -= 4;
}
@@ -2469,9 +2471,9 @@ void LBItem::runScript(uint event, uint16 data, uint16 from) {
}
}
-void LBItem::runScriptEntry(LBScriptEntry *entry) {
+int LBItem::runScriptEntry(LBScriptEntry *entry) {
if (entry->state == 0xffff)
- return;
+ return 0;
uint start = 0;
uint count = entry->argc;
@@ -2479,7 +2481,7 @@ void LBItem::runScriptEntry(LBScriptEntry *entry) {
if (!count)
count = 1;
- switch (entry->param) {
+ if (entry->opcode != kLBOpRunSubentries) switch (entry->param) {
case 0xfffe:
// Run once (disable self after run).
entry->state = 0xffff;
@@ -2496,7 +2498,7 @@ void LBItem::runScriptEntry(LBScriptEntry *entry) {
case 0:
// Disable..
entry->state = 0xffff;
- return;
+ return 0;
case 1:
// Stay at the end.
entry->state = count - 1;
@@ -2666,7 +2668,22 @@ void LBItem::runScriptEntry(LBScriptEntry *entry) {
for (uint i = 0; i < entry->subentries.size(); i++) {
LBScriptEntry *subentry = entry->subentries[i];
- runScriptEntry(subentry);
+ int e = runScriptEntry(subentry);
+
+ switch (subentry->opcode) {
+ case kLBOpJumpUnlessExpression:
+ debug(2, "JumpUnless got %d (to %d, on %d, of %d)", e, subentry->target, i, entry->subentries.size());
+ if (!e)
+ i = subentry->target - 1;
+ break;
+ case kLBOpBreakExpression:
+ debug(2, "BreakExpression");
+ i = entry->subentries.size();
+ case kLBOpJumpToExpression:
+ debug(2, "JumpToExpression got %d (on %d, of %d)", e, i, entry->subentries.size());
+ i = e - 1;
+ break;
+ }
}
break;
@@ -2674,11 +2691,24 @@ void LBItem::runScriptEntry(LBScriptEntry *entry) {
runCommand(entry->command);
break;
+ case kLBOpJumpUnlessExpression:
+ case kLBOpBreakExpression:
+ case kLBOpJumpToExpression:
+ if (!_vm->_code)
+ error("no BCOD?");
+ {
+ LBValue r = _vm->_code->runCode(this, entry->offset);
+ // FIXME
+ return r.integer;
+ }
+
default:
error("Unknown script opcode (type 0x%04x, event 0x%04x, opcode 0x%04x, param 0x%04x, target '%s')",
entry->type, entry->event, entry->opcode, entry->param, target->_desc.c_str());
}
}
+
+ return 0;
}
void LBItem::setNextTime(uint16 min, uint16 max) {
diff --git a/engines/mohawk/livingbooks.h b/engines/mohawk/livingbooks.h
index e55f14bc2c..3eff039385 100644
--- a/engines/mohawk/livingbooks.h
+++ b/engines/mohawk/livingbooks.h
@@ -217,6 +217,9 @@ enum {
kLBOpScriptEnable = 0x1b,
kLBOpUnknown1C = 0x1c,
kLBOpSendExpression = 0x1d,
+ kLBOpJumpUnlessExpression = 0xfffb,
+ kLBOpBreakExpression = 0xfffc,
+ kLBOpJumpToExpression = 0xfffd,
kLBOpRunSubentries = 0xfffe,
kLBOpRunCommand = 0xffff
};
@@ -264,6 +267,8 @@ struct LBScriptEntry {
// kLBOpSendExpression
uint32 offset;
+ // kLBOpJumpUnlessExpression
+ uint16 target;
Common::String command;
Common::Array<Common::String> conditions;
@@ -409,7 +414,7 @@ protected:
Common::Array<LBScriptEntry *> _scriptEntries;
void runScript(uint event, uint16 data = 0, uint16 from = 0);
- void runScriptEntry(LBScriptEntry *entry);
+ int runScriptEntry(LBScriptEntry *entry);
LBValue parseValue(const Common::String &command, uint &pos);
void runCommand(const Common::String &command);