diff options
author | Nicola Mettifogo | 2009-03-23 11:38:09 +0000 |
---|---|---|
committer | Nicola Mettifogo | 2009-03-23 11:38:09 +0000 |
commit | d18274d0ee2bf8effcb36b726fc833503f7924aa (patch) | |
tree | 33eb6cd429e8d86e0f923370661765f30086f55d /engines | |
parent | ca993d8b00e54c8523b5b9e708c94d3fc871e6db (diff) | |
download | scummvm-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')
-rw-r--r-- | engines/parallaction/exec.cpp | 8 | ||||
-rw-r--r-- | engines/parallaction/exec.h | 4 | ||||
-rw-r--r-- | engines/parallaction/exec_br.cpp | 49 | ||||
-rw-r--r-- | engines/parallaction/exec_ns.cpp | 25 | ||||
-rw-r--r-- | engines/parallaction/objects.cpp | 1 | ||||
-rw-r--r-- | engines/parallaction/objects.h | 16 | ||||
-rw-r--r-- | engines/parallaction/parser.h | 13 | ||||
-rw-r--r-- | engines/parallaction/parser_br.cpp | 30 | ||||
-rw-r--r-- | engines/parallaction/parser_ns.cpp | 6 |
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) { |