aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction
diff options
context:
space:
mode:
authorNicola Mettifogo2009-03-23 11:38:09 +0000
committerNicola Mettifogo2009-03-23 11:38:09 +0000
commitd18274d0ee2bf8effcb36b726fc833503f7924aa (patch)
tree33eb6cd429e8d86e0f923370661765f30086f55d /engines/parallaction
parentca993d8b00e54c8523b5b9e708c94d3fc871e6db (diff)
downloadscummvm-rg350-d18274d0ee2bf8effcb36b726fc833503f7924aa.tar.gz
scummvm-rg350-d18274d0ee2bf8effcb36b726fc833503f7924aa.tar.bz2
scummvm-rg350-d18274d0ee2bf8effcb36b726fc833503f7924aa.zip
Implemented all variants of IF script instruction. Program class has been changed to store an Array of instruction instead of a List, so that references to instructions are integers.
svn-id: r39631
Diffstat (limited to 'engines/parallaction')
-rw-r--r--engines/parallaction/exec.cpp8
-rw-r--r--engines/parallaction/exec.h4
-rw-r--r--engines/parallaction/exec_br.cpp49
-rw-r--r--engines/parallaction/exec_ns.cpp25
-rw-r--r--engines/parallaction/objects.cpp1
-rw-r--r--engines/parallaction/objects.h16
-rw-r--r--engines/parallaction/parser.h13
-rw-r--r--engines/parallaction/parser_br.cpp30
-rw-r--r--engines/parallaction/parser_ns.cpp6
9 files changed, 87 insertions, 65 deletions
diff --git a/engines/parallaction/exec.cpp b/engines/parallaction/exec.cpp
index 7a4208e3c3..0d5215cd9a 100644
--- a/engines/parallaction/exec.cpp
+++ b/engines/parallaction/exec.cpp
@@ -37,18 +37,18 @@ void ProgramExec::runScript(ProgramPtr script, AnimationPtr a) {
_ctxt._suspend = false;
_ctxt._modCounter = _modCounter;
- InstructionList::iterator inst;
+ InstructionPtr inst;
for ( ; (a->_flags & kFlagsActing) ; ) {
- inst = _ctxt._ip;
+ inst = script->_instructions[_ctxt._ip];
_ctxt._inst = inst;
++_ctxt._ip;
- debugC(9, kDebugExec, "inst [%02i] %s\n", (*inst)->_index, _instructionNames[(*inst)->_index - 1]);
+ debugC(9, kDebugExec, "inst [%02i] %s\n", inst->_index, _instructionNames[inst->_index - 1]);
script->_status = kProgramRunning;
- (*_opcodes[(*inst)->_index])(_ctxt);
+ (*_opcodes[inst->_index])(_ctxt);
if (_ctxt._suspend)
break;
diff --git a/engines/parallaction/exec.h b/engines/parallaction/exec.h
index cc816b9b5a..df642e0fed 100644
--- a/engines/parallaction/exec.h
+++ b/engines/parallaction/exec.h
@@ -64,8 +64,8 @@ typedef Common::Array<const CommandOpcode*> CommandOpcodeSet;
struct ProgramContext {
AnimationPtr _anim;
ProgramPtr _program;
- InstructionList::iterator _inst;
- InstructionList::iterator _ip;
+ InstructionPtr _inst;
+ uint32 _ip;
uint16 _modCounter;
bool _suspend;
};
diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp
index 397ab293fa..836dd14f7d 100644
--- a/engines/parallaction/exec_br.cpp
+++ b/engines/parallaction/exec_br.cpp
@@ -312,7 +312,7 @@ DECLARE_COMMAND_OPCODE(offsave) {
}
DECLARE_INSTRUCTION_OPCODE(invalid) {
- error("Can't execute invalid opcode %i", (*ctxt._inst)->_index);
+ error("Can't execute invalid opcode %i", ctxt._inst->_index);
}
DECLARE_COMMAND_OPCODE(clear) {
@@ -367,24 +367,23 @@ DECLARE_COMMAND_OPCODE(set) {
DECLARE_INSTRUCTION_OPCODE(on) {
- _vm->showZone((*ctxt._inst)->_z, true);
+ _vm->showZone(ctxt._inst->_z, true);
}
DECLARE_INSTRUCTION_OPCODE(off) {
- _vm->showZone((*ctxt._inst)->_z, false);
+ _vm->showZone(ctxt._inst->_z, false);
}
DECLARE_INSTRUCTION_OPCODE(set) {
- InstructionPtr inst = *ctxt._inst;
- inst->_opA.setValue(inst->_opB.getValue());
+ ctxt._inst->_opA.setValue(ctxt._inst->_opB.getValue());
}
DECLARE_INSTRUCTION_OPCODE(inc) {
- InstructionPtr inst = *ctxt._inst;
+ InstructionPtr inst = ctxt._inst;
int16 rvalue = inst->_opB.getValue();
@@ -437,25 +436,25 @@ DECLARE_INSTRUCTION_OPCODE(wait) {
DECLARE_INSTRUCTION_OPCODE(start) {
- (*ctxt._inst)->_z->_flags |= kFlagsActing;
+ ctxt._inst->_z->_flags |= kFlagsActing;
}
DECLARE_INSTRUCTION_OPCODE(process) {
- _vm->_activeZone2 = (*ctxt._inst)->_z;
+ _vm->_activeZone2 = ctxt._inst->_z;
}
DECLARE_INSTRUCTION_OPCODE(move) {
// NOTE: I couldn't find evidence of scripts containing this instruction being used
- InstructionPtr inst =*ctxt._inst;
+ InstructionPtr inst = ctxt._inst;
_vm->scheduleWalk(inst->_opA.getValue(), inst->_opB.getValue(), false);
ctxt._suspend = true;
}
DECLARE_INSTRUCTION_OPCODE(color) {
- InstructionPtr inst = *ctxt._inst;
+ InstructionPtr inst = ctxt._inst;
_vm->_gfx->_palette.setEntry(inst->_opB.getValue(), inst->_colors[0], inst->_colors[1], inst->_colors[2]);
}
@@ -477,33 +476,45 @@ DECLARE_INSTRUCTION_OPCODE(print) {
}
DECLARE_INSTRUCTION_OPCODE(text) {
- InstructionPtr inst = (*ctxt._inst);
+ InstructionPtr inst = ctxt._inst;
_vm->setupSubtitles(inst->_text, inst->_text2, inst->_y);
}
DECLARE_INSTRUCTION_OPCODE(ifeq) {
- warning("Parallaction_br::instOp_ifeq not yet implemented");
+ InstructionPtr inst = ctxt._inst;
+ bool cond = inst->_opA.getValue() == inst->_opB.getValue();
+ if (!cond) {
+ ctxt._ip = inst->_endif;
+ }
}
DECLARE_INSTRUCTION_OPCODE(iflt) {
- warning("Parallaction_br::instOp_iflt not yet implemented");
+ InstructionPtr inst = ctxt._inst;
+ bool cond = inst->_opA.getValue() < inst->_opB.getValue();
+ if (!cond) {
+ ctxt._ip = inst->_endif;
+ }
}
DECLARE_INSTRUCTION_OPCODE(ifgt) {
- warning("Parallaction_br::instOp_ifgt not yet implemented");
+ InstructionPtr inst = ctxt._inst;
+ bool cond = inst->_opA.getValue() > inst->_opB.getValue();
+ if (!cond) {
+ ctxt._ip = inst->_endif;
+ }
}
DECLARE_INSTRUCTION_OPCODE(endif) {
- warning("Parallaction_br::instOp_endif not yet implemented");
+ // nothing to do here
}
DECLARE_INSTRUCTION_OPCODE(stop) {
- ZonePtr z = (*ctxt._inst)->_z;
+ ZonePtr z = ctxt._inst->_z;
if (ACTIONTYPE(z) == kZoneHear) {
warning("Parallaction_br::instOp_stop not yet implemented for HEAR zones");
// TODO: stop music or sound effects generated by a zone.
@@ -513,7 +524,7 @@ DECLARE_INSTRUCTION_OPCODE(stop) {
}
DECLARE_INSTRUCTION_OPCODE(loop) {
- InstructionPtr inst = *ctxt._inst;
+ InstructionPtr inst = ctxt._inst;
ctxt._program->_loopCounter = inst->_opB.getValue();
ctxt._program->_loopStart = ctxt._ip;
@@ -531,7 +542,7 @@ DECLARE_INSTRUCTION_OPCODE(show) {
}
DECLARE_INSTRUCTION_OPCODE(call) {
- _vm->callFunction((*ctxt._inst)->_immediate, 0);
+ _vm->callFunction(ctxt._inst->_immediate, 0);
}
@@ -542,7 +553,7 @@ DECLARE_INSTRUCTION_OPCODE(endscript) {
ctxt._program->_status = kProgramDone;
}
- ctxt._ip = ctxt._program->_instructions.begin();
+ ctxt._ip = 0;
ctxt._suspend = true;
}
diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp
index f50b3999ec..4c17f4910a 100644
--- a/engines/parallaction/exec_ns.cpp
+++ b/engines/parallaction/exec_ns.cpp
@@ -67,7 +67,7 @@ extern const char *_instructionNamesRes_ns[];
DECLARE_INSTRUCTION_OPCODE(on) {
- InstructionPtr inst = *ctxt._inst;
+ InstructionPtr inst = ctxt._inst;
inst->_a->_flags |= kFlagsActive;
inst->_a->_flags &= ~kFlagsRemove;
@@ -75,12 +75,12 @@ DECLARE_INSTRUCTION_OPCODE(on) {
DECLARE_INSTRUCTION_OPCODE(off) {
- (*ctxt._inst)->_a->_flags |= kFlagsRemove;
+ ctxt._inst->_a->_flags |= kFlagsRemove;
}
DECLARE_INSTRUCTION_OPCODE(loop) {
- InstructionPtr inst = *ctxt._inst;
+ InstructionPtr inst = ctxt._inst;
ctxt._program->_loopCounter = inst->_opB.getValue();
ctxt._program->_loopStart = ctxt._ip;
@@ -94,7 +94,7 @@ DECLARE_INSTRUCTION_OPCODE(endloop) {
}
DECLARE_INSTRUCTION_OPCODE(inc) {
- InstructionPtr inst = *ctxt._inst;
+ InstructionPtr inst = ctxt._inst;
int16 _si = inst->_opB.getValue();
if (inst->_flags & kInstMod) { // mod
@@ -118,13 +118,12 @@ DECLARE_INSTRUCTION_OPCODE(inc) {
DECLARE_INSTRUCTION_OPCODE(set) {
- InstructionPtr inst = *ctxt._inst;
- inst->_opA.setValue(inst->_opB.getValue());
+ ctxt._inst->_opA.setValue(ctxt._inst->_opB.getValue());
}
DECLARE_INSTRUCTION_OPCODE(put) {
- InstructionPtr inst = *ctxt._inst;
+ InstructionPtr inst = ctxt._inst;
Common::Rect r;
inst->_a->getFrameRect(r);
@@ -145,11 +144,11 @@ DECLARE_INSTRUCTION_OPCODE(show) {
}
DECLARE_INSTRUCTION_OPCODE(invalid) {
- error("Can't execute invalid opcode %i", (*ctxt._inst)->_index);
+ error("Can't execute invalid opcode %i", ctxt._inst->_index);
}
DECLARE_INSTRUCTION_OPCODE(call) {
- _vm->callFunction((*ctxt._inst)->_immediate, 0);
+ _vm->callFunction(ctxt._inst->_immediate, 0);
}
@@ -162,17 +161,17 @@ DECLARE_INSTRUCTION_OPCODE(wait) {
DECLARE_INSTRUCTION_OPCODE(start) {
- (*ctxt._inst)->_a->_flags |= (kFlagsActing | kFlagsActive);
+ ctxt._inst->_a->_flags |= (kFlagsActing | kFlagsActive);
}
DECLARE_INSTRUCTION_OPCODE(sound) {
- _vm->_activeZone = (*ctxt._inst)->_z;
+ _vm->_activeZone = ctxt._inst->_z;
}
DECLARE_INSTRUCTION_OPCODE(move) {
- InstructionPtr inst = (*ctxt._inst);
+ InstructionPtr inst = ctxt._inst;
int16 x = inst->_opA.getValue();
int16 y = inst->_opB.getValue();
@@ -187,7 +186,7 @@ DECLARE_INSTRUCTION_OPCODE(endscript) {
ctxt._program->_status = kProgramDone;
}
- ctxt._ip = ctxt._program->_instructions.begin();
+ ctxt._ip = 0;
ctxt._suspend = true;
}
diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp
index daffe4393d..4832661d62 100644
--- a/engines/parallaction/objects.cpp
+++ b/engines/parallaction/objects.cpp
@@ -25,7 +25,6 @@
#include "parallaction/parallaction.h"
#include "parallaction/objects.h"
-#include "parallaction/parser.h"
namespace Parallaction {
diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h
index 37ebc54659..89ed1350bd 100644
--- a/engines/parallaction/objects.h
+++ b/engines/parallaction/objects.h
@@ -49,7 +49,7 @@ typedef Common::SharedPtr<Animation> AnimationPtr;
typedef Common::List<AnimationPtr> AnimationList;
typedef Common::SharedPtr<Instruction> InstructionPtr;
-typedef Common::List<InstructionPtr> InstructionList;
+typedef Common::Array<InstructionPtr> InstructionList;
typedef Common::List<Common::Point> PointList;
@@ -468,7 +468,7 @@ struct Instruction {
char *_text;
char *_text2;
int _y;
- InstructionList::iterator _endif;
+ uint32 _endif;
Instruction();
~Instruction();
@@ -483,16 +483,14 @@ enum {
struct Program {
AnimationPtr _anim;
-
LocalVariable *_locals;
- uint16 _loopCounter;
-
- uint16 _numLocals;
+ uint16 _loopCounter;
+ uint16 _numLocals;
- InstructionList::iterator _ip;
- InstructionList::iterator _loopStart;
- InstructionList _instructions;
+ uint32 _ip;
+ uint32 _loopStart;
+ InstructionList _instructions;
uint32 _status;
diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h
index 8385961ce3..0c9d053bf3 100644
--- a/engines/parallaction/parser.h
+++ b/engines/parallaction/parser.h
@@ -328,14 +328,13 @@ protected:
OpcodeSet _instructionParsers;
Table *_instructionNames;
+ uint32 _currentInstruction; // index of the instruction being parsed
+
struct ParserContext {
bool end;
AnimationPtr a;
InstructionPtr inst;
LocalVariable *locals;
-
- // BRA specific
- InstructionPtr openIf;
} ctxt;
DECLARE_UNQUALIFIED_INSTRUCTION_PARSER(defLocal);
@@ -377,7 +376,7 @@ public:
clearSet(_instructionParsers);
}
- void parse(Script *script, ProgramPtr program);
+ virtual void parse(Script *script, ProgramPtr program);
};
@@ -395,6 +394,10 @@ protected:
DECLARE_UNQUALIFIED_INSTRUCTION_PARSER(if_op);
DECLARE_UNQUALIFIED_INSTRUCTION_PARSER(endif);
+ int32 _openIfStatement;
+ void beginIfStatement();
+ void endIfStatement();
+
virtual void parseRValue(ScriptVar &var, const char *str);
public:
@@ -402,7 +405,7 @@ public:
}
virtual void init();
-
+ virtual void parse(Script *script, ProgramPtr program);
};
diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp
index 001906c2e5..5b44b47748 100644
--- a/engines/parallaction/parser_br.cpp
+++ b/engines/parallaction/parser_br.cpp
@@ -1058,9 +1058,7 @@ DECLARE_INSTRUCTION_PARSER(text) {
DECLARE_INSTRUCTION_PARSER(if_op) {
debugC(7, kDebugParser, "INSTRUCTION_PARSER(if_op) ");
-
- if (ctxt.openIf)
- error("cannot nest 'if' blocks");
+ beginIfStatement();
parseLValue(ctxt.inst->_opA, _tokens[1]);
parseRValue(ctxt.inst->_opB, _tokens[3]);
@@ -1075,20 +1073,27 @@ DECLARE_INSTRUCTION_PARSER(if_op) {
ctxt.inst->_index = INST_IFLT;
} else
error("unknown test operator '%s' in if-clause", _tokens[2]);
+}
- ctxt.openIf = ctxt.inst;
+void ProgramParser_br::beginIfStatement() {
+ if (_openIfStatement != -1)
+ error("cannot nest 'if' statements");
+ _openIfStatement = _currentInstruction;
}
+void ProgramParser_br::endIfStatement() {
+ if (_openIfStatement == -1)
+ error("unexpected 'endif' in script");
-DECLARE_INSTRUCTION_PARSER(endif) {
- debugC(7, kDebugParser, "INSTRUCTION_PARSER(endif) ");
+ _program->_instructions[_openIfStatement]->_endif = _currentInstruction;
+ _openIfStatement = -1;
+}
- if (!ctxt.openIf)
- error("unexpected 'endif'");
-// ctxt.openIf->_endif = ctxt.inst;
- ctxt.openIf = InstructionPtr();
+DECLARE_INSTRUCTION_PARSER(endif) {
+ debugC(7, kDebugParser, "INSTRUCTION_PARSER(endif) ");
+ endIfStatement();
ctxt.inst->_index = _parser->_lookup;
}
@@ -1142,6 +1147,11 @@ void ProgramParser_br::parseRValue(ScriptVar &v, const char *str) {
}
+void ProgramParser_br::parse(Script *script, ProgramPtr program) {
+ _openIfStatement = -1;
+ ProgramParser_ns::parse(script, program);
+}
+
void LocationParser_br::init() {
diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp
index e6db9bf17b..909753e981 100644
--- a/engines/parallaction/parser_ns.cpp
+++ b/engines/parallaction/parser_ns.cpp
@@ -327,6 +327,9 @@ void ProgramParser_ns::parseInstruction() {
InstructionPtr inst(new Instruction);
ctxt.inst = inst;
+
+ _currentInstruction = _program->_instructions.size();
+
_parser->parseStatement();
_program->_instructions.push_back(inst);
@@ -337,7 +340,6 @@ void ProgramParser_ns::parse(Script *script, ProgramPtr program) {
_script = script;
_program = program;
- ctxt.openIf = InstructionPtr();
ctxt.end = false;
ctxt.locals = program->_locals;
@@ -348,7 +350,7 @@ void ProgramParser_ns::parse(Script *script, ProgramPtr program) {
} while (!ctxt.end);
_parser->popTables();
- program->_ip = program->_instructions.begin();
+ program->_ip = 0;
}
void Parallaction_ns::loadProgram(AnimationPtr a, const char *filename) {