diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/parallaction/exec_ns.cpp | 109 | ||||
-rw-r--r-- | engines/parallaction/objects.cpp | 101 | ||||
-rw-r--r-- | engines/parallaction/objects.h | 64 | ||||
-rw-r--r-- | engines/parallaction/parallaction.h | 18 | ||||
-rw-r--r-- | engines/parallaction/parser_ns.cpp | 221 | ||||
-rw-r--r-- | engines/parallaction/staticres.cpp | 3 |
6 files changed, 286 insertions, 230 deletions
diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index b3f90cc09b..1df78da9c4 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -62,22 +62,22 @@ typedef OpcodeImpl<Parallaction_ns> OpcodeV1; DECLARE_INSTRUCTION_OPCODE(on) { - (*_instRunCtxt.inst)->_opBase._a->_flags |= kFlagsActive; - (*_instRunCtxt.inst)->_opBase._a->_flags &= ~kFlagsRemove; + Instruction *inst = *_instRunCtxt.inst; + + inst->_a->_flags |= kFlagsActive; + inst->_a->_flags &= ~kFlagsRemove; } DECLARE_INSTRUCTION_OPCODE(off) { - (*_instRunCtxt.inst)->_opBase._a->_flags |= kFlagsRemove; + (*_instRunCtxt.inst)->_a->_flags |= kFlagsRemove; } DECLARE_INSTRUCTION_OPCODE(loop) { - if ((*_instRunCtxt.inst)->_flags & kInstUsesLiteral) { - _instRunCtxt.a->_program->_loopCounter = (*_instRunCtxt.inst)->_opBase._loopCounter._value; - } else { - _instRunCtxt.a->_program->_loopCounter = *(*_instRunCtxt.inst)->_opBase._loopCounter._pvalue; - } + Instruction *inst = *_instRunCtxt.inst; + + _instRunCtxt.a->_program->_loopCounter = inst->_opB.getRValue(); _instRunCtxt.a->_program->_loopStart = _instRunCtxt.inst; } @@ -89,64 +89,59 @@ DECLARE_INSTRUCTION_OPCODE(endloop) { } DECLARE_INSTRUCTION_OPCODE(inc) { - int16 _si = 0; - int16 _ax = 0, _bx = 0; - if ((*_instRunCtxt.inst)->_flags & kInstUsesLiteral) { - _si = (*_instRunCtxt.inst)->_opB._value; - } else { - _si = *(*_instRunCtxt.inst)->_opB._pvalue; - } - if ((*_instRunCtxt.inst)->_flags & kInstMod) { // mod - _bx = (_si > 0 ? _si : -_si); + Instruction *inst = *_instRunCtxt.inst; + int16 _si = inst->_opB.getRValue(); + + if (inst->_flags & kInstMod) { // mod + int16 _bx = (_si > 0 ? _si : -_si); if (_instRunCtxt.modCounter % _bx != 0) return; _si = (_si > 0 ? 1 : -1); } - if ((*_instRunCtxt.inst)->_flags & kInstUsesLocal) { // local - if ((*_instRunCtxt.inst)->_index == INST_INC) _ax = _si; - else _ax = -_si; - (*_instRunCtxt.inst)->_opA._local->_value += _ax; - wrapLocalVar((*_instRunCtxt.inst)->_opA._local); - return; + int16* lvalue = inst->_opA.getLValue(); + + if (inst->_index == INST_INC) { + *lvalue += _si; + } else { + *lvalue -= _si; + } + + if (inst->_opA._flags & kParaLocal) { + wrapLocalVar(inst->_opA._local); } - // built-in variable (x, y, z, f) - if ((*_instRunCtxt.inst)->_index == INST_INC) _ax = _si; - else _ax = -_si; - *(*_instRunCtxt.inst)->_opA._pvalue += _ax; } DECLARE_INSTRUCTION_OPCODE(set) { - int16 _si; - if ((*_instRunCtxt.inst)->_flags & kInstUsesLiteral) { - _si = (*_instRunCtxt.inst)->_opB._value; - } else { - _si = *(*_instRunCtxt.inst)->_opB._pvalue; - } + Instruction *inst = *_instRunCtxt.inst; + + int16 _si = inst->_opB.getRValue(); + int16 *lvalue = inst->_opA.getLValue(); + + *lvalue = _si; - if ((*_instRunCtxt.inst)->_flags & kInstUsesLocal) { - (*_instRunCtxt.inst)->_opA._local->_value = _si; - } else { - *(*_instRunCtxt.inst)->_opA._pvalue = _si; - } } DECLARE_INSTRUCTION_OPCODE(put) { + Instruction *inst = *_instRunCtxt.inst; Graphics::Surface v18; - v18.w = (*_instRunCtxt.inst)->_opBase._a->width(); - v18.h = (*_instRunCtxt.inst)->_opBase._a->height(); - v18.pixels = (*_instRunCtxt.inst)->_opBase._a->getFrameData((*_instRunCtxt.inst)->_opBase._a->_frame); - - if ((*_instRunCtxt.inst)->_flags & kInstMaskedPut) { - uint16 _si = _gfx->queryMask((*_instRunCtxt.inst)->_opB._value); - _gfx->blitCnv(&v18, (*_instRunCtxt.inst)->_opA._value, (*_instRunCtxt.inst)->_opB._value, _si, Gfx::kBitBack); - _gfx->blitCnv(&v18, (*_instRunCtxt.inst)->_opA._value, (*_instRunCtxt.inst)->_opB._value, _si, Gfx::kBit2); + v18.w = inst->_a->width(); + v18.h = inst->_a->height(); + v18.pixels = inst->_a->getFrameData(inst->_a->_frame); + + int16 x = inst->_opA.getRValue(); + int16 y = inst->_opB.getRValue(); + + if (inst->_flags & kInstMaskedPut) { + uint16 z = _gfx->queryMask(y); + _gfx->blitCnv(&v18, x, y, z, Gfx::kBitBack); + _gfx->blitCnv(&v18, x, y, z, Gfx::kBit2); } else { - _gfx->flatBlitCnv(&v18, (*_instRunCtxt.inst)->_opA._value, (*_instRunCtxt.inst)->_opB._value, Gfx::kBitBack); - _gfx->flatBlitCnv(&v18, (*_instRunCtxt.inst)->_opA._value, (*_instRunCtxt.inst)->_opB._value, Gfx::kBit2); + _gfx->flatBlitCnv(&v18, x, y, Gfx::kBitBack); + _gfx->flatBlitCnv(&v18, x, y, Gfx::kBit2); } } @@ -159,7 +154,7 @@ DECLARE_INSTRUCTION_OPCODE(invalid) { } DECLARE_INSTRUCTION_OPCODE(call) { - callFunction((*_instRunCtxt.inst)->_opBase._index, 0); + callFunction((*_instRunCtxt.inst)->_immediate, 0); } @@ -170,17 +165,22 @@ DECLARE_INSTRUCTION_OPCODE(wait) { DECLARE_INSTRUCTION_OPCODE(start) { - (*_instRunCtxt.inst)->_opBase._a->_flags |= (kFlagsActing | kFlagsActive); + (*_instRunCtxt.inst)->_a->_flags |= (kFlagsActing | kFlagsActive); } DECLARE_INSTRUCTION_OPCODE(sound) { - _activeZone = (*_instRunCtxt.inst)->_opBase._z; + _activeZone = (*_instRunCtxt.inst)->_z; } DECLARE_INSTRUCTION_OPCODE(move) { - WalkNodeList *v4 = _char._builder.buildPath(*(*_instRunCtxt.inst)->_opA._pvalue, *(*_instRunCtxt.inst)->_opB._pvalue); + Instruction *inst = (*_instRunCtxt.inst); + + int16 x = inst->_opA.getRValue(); + int16 y = inst->_opB.getRValue(); + + WalkNodeList *v4 = _char._builder.buildPath(x, y); addJob(&jobWalk, v4, kPriority19 ); _engineFlags |= kEngineWalking; } @@ -374,11 +374,8 @@ void jobDisplayAnimations(void *parm, Job *j) { v18->_flags &= ~kFlagsActive; v18->_flags |= kFlagsRemove; } - } -// printf("done\n"); - return; } @@ -425,7 +422,7 @@ void jobRunScripts(void *parm, Job *j) { InstructionList::iterator inst = a->_program->_ip; while (((*inst)->_index != INST_SHOW) && (a->_flags & kFlagsActing)) { - debugC(9, kDebugJobs, "Animation: %s, instruction: %s", a->_label._text, (*inst)->_index == INST_END ? "end" : _vm->_instructionNamesRes[(*inst)->_index - 1]); + debugC(9, kDebugJobs, "Animation: %s, instruction: %s", a->_label._text, _vm->_instructionNamesRes[(*inst)->_index - 1]); _vm->_instRunCtxt.inst = inst; _vm->_instRunCtxt.a = a; diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp index d4eba330bb..add2f87b5e 100644 --- a/engines/parallaction/objects.cpp +++ b/engines/parallaction/objects.cpp @@ -81,15 +81,41 @@ byte* Animation::getFrameData(uint32 index) const { } +#define NUM_LOCALS 10 +char _localNames[NUM_LOCALS][10]; + Program::Program() { _loopCounter = 0; - _locals = new LocalVariable[10]; + _locals = new LocalVariable[NUM_LOCALS]; + _numLocals = 0; } Program::~Program() { delete[] _locals; } +int16 Program::findLocal(const char* name) { + for (uint16 _si = 0; _si < NUM_LOCALS; _si++) { + if (!scumm_stricmp(name, _localNames[_si])) + return _si; + } + + return -1; +} + +int16 Program::addLocal(const char *name, int16 value, int16 min, int16 max) { + assert(_numLocals < NUM_LOCALS); + + strcpy(_localNames[_numLocals], name); + _locals[_numLocals]._value = value; + + _locals[_numLocals]._min = min; + _locals[_numLocals]._max = max; + + return _numLocals++; +} + + Zone::Zone() { _left = _top = _right = _bottom = 0; @@ -208,8 +234,81 @@ Question::~Question() { free(_text); } +Instruction::Instruction() { + memset(this, 0, sizeof(Instruction)); +} + +Instruction::~Instruction() { + if (_text) + free(_text); + if (_text2) + free(_text2); +} + +int16 ScriptVar::getRValue() { + + if (_flags & kParaImmediate) { + return _value; + } + + if (_flags & kParaLocal) { + return _local->_value; + } + + if (_flags & kParaField) { + return *_pvalue; + } + + if (_flags & kParaRandom) { + return (rand() * _value) / 32767; + } + + error("Parameter is not an r-value"); + + return 0; +} + +int16* ScriptVar::getLValue() { + if (_flags & kParaLocal) { + return &_local->_value; + } + + if (_flags & kParaField) { + return _pvalue; + } + + error("Parameter is not an l-value"); + +} +void ScriptVar::setLocal(LocalVariable *local) { + _local = local; + _flags |= kParaLocal; +} + +void ScriptVar::setField(int16 *field) { + _pvalue = field; + _flags |= kParaField; +} + +void ScriptVar::setImmediate(int16 value) { + _value = value; + _flags |= kParaImmediate; +} + +void ScriptVar::setRandom(int16 seed) { + _value = seed; + _flags |= kParaRandom; +} + + +ScriptVar::ScriptVar() { + _flags = 0; + _local = 0; + _value = 0; + _pvalue = 0; +} } // namespace Parallaction diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h index 3f8635eb0d..3699e98f01 100644 --- a/engines/parallaction/objects.h +++ b/engines/parallaction/objects.h @@ -299,29 +299,36 @@ struct LocalVariable { } }; -union ScriptVar { +enum ParaFlags { + kParaImmediate = 1, // instruction is using an immediate parameter + kParaLocal = 2, // instruction is using a local variable + kParaField = 0x10, // instruction is using an animation's field + kParaRandom = 0x100 +}; + + +struct ScriptVar { + uint32 _flags; + int16 _value; int16* _pvalue; LocalVariable* _local; - ScriptVar() { - _local = NULL; - } + ScriptVar(); + + int16 getRValue(); + int16* getLValue(); + + void setLocal(LocalVariable *local); + void setField(int16 *field); + void setImmediate(int16 value); + void setRandom(int16 seed); }; enum InstructionFlags { - kInstUsesLiteral = 1, - kInstUsesLocal = 2, kInstMod = 4, kInstMaskedPut = 8, - - kInstUsesField = 0x10, // this value wasn't originally in NS, but it has been added for completeness - - // BRA specific - kInstUnk20 = 0x20, - kInstUsesLLocal = 0x40, - kInstUsesLField = 0x80, - kInstRandom = 0x100 + kInstUnk20 = 0x20 }; typedef ManagedList<Instruction*> InstructionList; @@ -329,12 +336,11 @@ typedef ManagedList<Instruction*> InstructionList; struct Instruction { uint32 _index; uint32 _flags; - struct { - Animation *_a; - Zone *_z; - uint32 _index; - ScriptVar _loopCounter; - } _opBase; + + // common + Animation *_a; + Zone *_z; + int16 _immediate; ScriptVar _opA; ScriptVar _opB; @@ -346,28 +352,28 @@ struct Instruction { int _y; InstructionList::iterator _endif; - Instruction() { - memset(this, 0, sizeof(Instruction)); - } + Instruction(); + ~Instruction(); - ~Instruction() { - if (_text) - free(_text); - if (_text2) - free(_text2); - } }; + struct Program { LocalVariable *_locals; + uint16 _loopCounter; + uint16 _numLocals; + InstructionList::iterator _ip; InstructionList::iterator _loopStart; InstructionList _instructions; Program(); ~Program(); + + int16 findLocal(const char* name); + int16 addLocal(const char *name, int16 value = 0, int16 min = -10000, int16 max = 10000); }; diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index eac10e9b55..791724a08d 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -726,9 +726,11 @@ protected: Table *_instructionNames; struct { + bool end; Animation *a; Instruction *inst; LocalVariable *locals; + Program *program; // BRA specific Instruction *openIf; @@ -748,13 +750,12 @@ protected: DECLARE_UNQUALIFIED_INSTRUCTION_PARSER(call); DECLARE_UNQUALIFIED_INSTRUCTION_PARSER(sound); DECLARE_UNQUALIFIED_INSTRUCTION_PARSER(null); + DECLARE_UNQUALIFIED_INSTRUCTION_PARSER(endscript); - void parseScriptLine(Instruction *inst, Animation *a, LocalVariable *locals); + void parseInstruction(Animation *a, LocalVariable *locals); void loadProgram(Animation *a, const char *filename); - ScriptVar parseLValue(Instruction *inst, const char *str, LocalVariable *locals, Animation *a); - virtual ScriptVar parseRValue(Instruction *inst, const char *str, LocalVariable *locals, Animation *a); - int16 findLocal(const char* name, LocalVariable *locals); - int16 addLocal(const char *name, LocalVariable *locals, int16 value = 0, int16 min = -10000, int16 max = 10000); + void parseLValue(ScriptVar &var, const char *str); + virtual void parseRValue(ScriptVar &var, const char *str); void wrapLocalVar(LocalVariable *local); DECLARE_UNQUALIFIED_COMMAND_OPCODE(invalid); @@ -868,7 +869,7 @@ private: void _c_password(void*); const Callable *_callables; -/* +#ifdef BRA_TEST DECLARE_UNQUALIFIED_LOCATION_PARSER(location); DECLARE_UNQUALIFIED_LOCATION_PARSER(zone); DECLARE_UNQUALIFIED_LOCATION_PARSER(animation); @@ -911,8 +912,7 @@ private: DECLARE_UNQUALIFIED_INSTRUCTION_PARSER(if_op); DECLARE_UNQUALIFIED_INSTRUCTION_PARSER(endif); - virtual ScriptVar parseRValue(Instruction *inst, const char *str, LocalVariable *locals, Animation *a); - + virtual void parseRValue(ScriptVar &var, const char *str); DECLARE_UNQUALIFIED_COMMAND_OPCODE(location); DECLARE_UNQUALIFIED_COMMAND_OPCODE(open); @@ -974,7 +974,7 @@ private: DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(endif); DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(stop); DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(endscript); -*/ +#endif }; // FIXME: remove global diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp index 093e95e5f4..5ee0b6b413 100644 --- a/engines/parallaction/parser_ns.cpp +++ b/engines/parallaction/parser_ns.cpp @@ -75,10 +75,6 @@ namespace Parallaction { #define DECLARE_LOCATION_PARSER(sig) void Parallaction_ns::locParse_##sig() -#define NUM_LOCALS 10 - -uint16 _numLocals = 0; -char _localNames[NUM_LOCALS][10]; DECLARE_ANIM_PARSER(invalid) { @@ -186,31 +182,47 @@ Animation *Parallaction_ns::parseAnimation(Script& script, AnimationList &list, return a; } +void Parallaction_ns::parseInstruction(Animation *a, LocalVariable *locals) { + + Instruction *inst = new Instruction; + + if (_tokens[0][1] == '.') { + _tokens[0][1] = '\0'; + _instParseCtxt.a = findAnimation(&_tokens[0][2]); + } else + if (_tokens[1][1] == '.') { + _tokens[1][1] = '\0'; + _instParseCtxt.a = findAnimation(&_tokens[1][2]); + } else + _instParseCtxt.a = a; + + inst->_index = _instructionNames->lookup(_tokens[0]); + _instParseCtxt.inst = inst; + _instParseCtxt.locals = locals; + + (*(_instructionParsers[inst->_index]))(); + + a->_program->_instructions.push_back(inst); + + return; +} + void Parallaction_ns::loadProgram(Animation *a, const char *filename) { // printf("loadProgram(%s)\n", filename); Script *script = _disk->loadScript(filename); - _numLocals = 0; - - fillBuffers(*script); - a->_program = new Program; - Instruction *vCC = new Instruction; - _instParseCtxt.openIf = NULL; + _instParseCtxt.end = false; + _instParseCtxt.program = a->_program; - while (scumm_stricmp(_tokens[0], "endscript")) { - parseScriptLine(vCC, a, a->_program->_locals); - a->_program->_instructions.push_back(vCC); - vCC = new Instruction; + do { fillBuffers(*script); - } + parseInstruction(a, a->_program->_locals); + } while (!_instParseCtxt.end); - // TODO: use List<>::end() to detect the end of the program - vCC->_index = INST_END; - a->_program->_instructions.push_back(vCC); a->_program->_ip = a->_program->_instructions.begin(); delete script; @@ -218,69 +230,47 @@ void Parallaction_ns::loadProgram(Animation *a, const char *filename) { return; } -int16 Parallaction_ns::findLocal(const char* name, LocalVariable *locals) { - for (uint16 _si = 0; _si < NUM_LOCALS; _si++) { - if (!scumm_stricmp(name, _localNames[_si])) - return _si; - } - - return -1; -} - -int16 Parallaction_ns::addLocal(const char *name, LocalVariable *locals, int16 value, int16 min, int16 max) { - assert(_numLocals < NUM_LOCALS); - - strcpy(_localNames[_numLocals], name); - locals[_numLocals]._value = value; - - locals[_numLocals]._min = min; - locals[_numLocals]._max = max; - - return _numLocals++; -} - - DECLARE_INSTRUCTION_PARSER(animation) { if (!scumm_stricmp(_tokens[1], _instParseCtxt.a->_label._text)) { - _instParseCtxt.inst->_opBase._a = _instParseCtxt.a; + _instParseCtxt.inst->_a = _instParseCtxt.a; } else { - _instParseCtxt.inst->_opBase._a = findAnimation(_tokens[1]); + _instParseCtxt.inst->_a = findAnimation(_tokens[1]); } } DECLARE_INSTRUCTION_PARSER(loop) { - _instParseCtxt.inst->_opBase._loopCounter = parseRValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a); + parseRValue(_instParseCtxt.inst->_opB, _tokens[1]); } DECLARE_INSTRUCTION_PARSER(x) { - _instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_left; - _instParseCtxt.inst->_opB = parseRValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a); + parseLValue(_instParseCtxt.inst->_opA, "X"); + parseRValue(_instParseCtxt.inst->_opB, _tokens[1]); } DECLARE_INSTRUCTION_PARSER(y) { - _instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_top; - _instParseCtxt.inst->_opB = parseRValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a); + parseLValue(_instParseCtxt.inst->_opA, "Y"); + parseRValue(_instParseCtxt.inst->_opB, _tokens[1]); } DECLARE_INSTRUCTION_PARSER(z) { - _instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_z; - _instParseCtxt.inst->_opB = parseRValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a); + parseLValue(_instParseCtxt.inst->_opA, "Z"); + parseRValue(_instParseCtxt.inst->_opB, _tokens[1]); } DECLARE_INSTRUCTION_PARSER(f) { - _instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_frame; - _instParseCtxt.inst->_opB = parseRValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a); + parseLValue(_instParseCtxt.inst->_opA, "F"); + parseRValue(_instParseCtxt.inst->_opB, _tokens[1]); } DECLARE_INSTRUCTION_PARSER(inc) { - _instParseCtxt.inst->_opA = parseLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a); - _instParseCtxt.inst->_opB = parseRValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a); + parseLValue(_instParseCtxt.inst->_opA, _tokens[1]); + parseRValue(_instParseCtxt.inst->_opB, _tokens[2]); if (!scumm_stricmp(_tokens[3], "mod")) { _instParseCtxt.inst->_flags |= kInstMod; @@ -294,30 +284,30 @@ DECLARE_INSTRUCTION_PARSER(set) { // script was commented out on Dos version. This workaround enables the engine // to dynamically add a local variable when it is encountered the first time in // the script, so should fix any other occurrence as well. - if (findLocal(_tokens[1], _instParseCtxt.locals) == -1) { - addLocal(_tokens[1], _instParseCtxt.locals); + if (_instParseCtxt.program->findLocal(_tokens[1]) == -1) { + _instParseCtxt.program->addLocal(_tokens[1]); } - _instParseCtxt.inst->_opA = parseLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a); - _instParseCtxt.inst->_opB = parseRValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a); + parseLValue(_instParseCtxt.inst->_opA, _tokens[1]); + parseRValue(_instParseCtxt.inst->_opB, _tokens[2]); } DECLARE_INSTRUCTION_PARSER(move) { - _instParseCtxt.inst->_opA = parseRValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a); - _instParseCtxt.inst->_opB = parseRValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a); + parseRValue(_instParseCtxt.inst->_opA, _tokens[1]); + parseRValue(_instParseCtxt.inst->_opB, _tokens[2]); } DECLARE_INSTRUCTION_PARSER(put) { if (!scumm_stricmp(_tokens[1], _instParseCtxt.a->_label._text)) { - _instParseCtxt.inst->_opBase._a = _instParseCtxt.a; + _instParseCtxt.inst->_a = _instParseCtxt.a; } else { - _instParseCtxt.inst->_opBase._a = findAnimation(_tokens[1]); + _instParseCtxt.inst->_a = findAnimation(_tokens[1]); } - _instParseCtxt.inst->_opA = parseRValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a); - _instParseCtxt.inst->_opB = parseRValue(_instParseCtxt.inst, _tokens[3], _instParseCtxt.locals, _instParseCtxt.a); + parseRValue(_instParseCtxt.inst->_opA, _tokens[2]); + parseRValue(_instParseCtxt.inst->_opB, _tokens[3]); if (!scumm_stricmp(_tokens[4], "masked")) { _instParseCtxt.inst->_flags |= kInstMaskedPut; } @@ -328,12 +318,12 @@ DECLARE_INSTRUCTION_PARSER(call) { int index = _callableNames->lookup(_tokens[1]); if (index == Table::notFound) error("unknown callable '%s'", _tokens[1]); - _instParseCtxt.inst->_opBase._index = index - 1; + _instParseCtxt.inst->_immediate = index - 1; } DECLARE_INSTRUCTION_PARSER(sound) { - _instParseCtxt.inst->_opBase._z = findZone(_tokens[1]); + _instParseCtxt.inst->_z = findZone(_tokens[1]); } @@ -347,124 +337,86 @@ DECLARE_INSTRUCTION_PARSER(defLocal) { int16 index; if (_tokens[3][0] != '\0') { - index = addLocal(_tokens[0], _instParseCtxt.locals, val, atoi(_tokens[3]), atoi(_tokens[4])); + index = _instParseCtxt.program->addLocal(_tokens[0], val, atoi(_tokens[3]), atoi(_tokens[4])); } else { - index = addLocal(_tokens[0], _instParseCtxt.locals, val); + index = _instParseCtxt.program->addLocal(_tokens[0], val); } - _instParseCtxt.inst->_opA._local = &_instParseCtxt.locals[index]; - _instParseCtxt.inst->_opB._value = _instParseCtxt.locals[index]._value; + _instParseCtxt.inst->_opA.setLocal(&_instParseCtxt.locals[index]); + _instParseCtxt.inst->_opB.setImmediate(_instParseCtxt.locals[index]._value); - _instParseCtxt.inst->_flags = kInstUsesLiteral | kInstUsesLocal; _instParseCtxt.inst->_index = INST_SET; } - - - -void Parallaction_ns::parseScriptLine(Instruction *inst, Animation *a, LocalVariable *locals) { -// printf("parseScriptLine()\n"); - - if (_tokens[0][1] == '.') { - _tokens[0][1] = '\0'; - a = findAnimation(&_tokens[0][2]); - } - - if (_tokens[1][1] == '.') { - _tokens[1][1] = '\0'; - a = findAnimation(&_tokens[1][2]); - } - - int16 _si = _instructionNames->lookup(_tokens[0]); - inst->_index = _si; - - _instParseCtxt.a = a; - _instParseCtxt.inst = inst; - _instParseCtxt.locals = locals; - - (*(_instructionParsers[inst->_index]))(); - - return; +DECLARE_INSTRUCTION_PARSER(endscript) { + _instParseCtxt.end = true; } -ScriptVar Parallaction_ns::parseRValue(Instruction *inst, const char *str, LocalVariable *locals, Animation *a) { - ScriptVar v; - v._pvalue = 0; // should stop compiler from complaining +void Parallaction_ns::parseRValue(ScriptVar &v, const char *str) { if (isdigit(str[0]) || str[0] == '-') { - inst->_flags |= kInstUsesLiteral; - v._value = atoi(str); - return v; + v.setImmediate(atoi(str)); + return; } - int index = findLocal(str, locals); + int index = _instParseCtxt.program->findLocal(str); if (index != -1) { - v._local = &locals[index]; - inst->_flags |= kInstUsesLocal; - return v; + v.setLocal(&_instParseCtxt.locals[index]); + return; } + Animation *a; if (str[1] == '.') { a = findAnimation(&str[2]); + } else { + a = _instParseCtxt.a; } if (str[0] == 'X') { - v._pvalue = &a->_left; - inst->_flags |= kInstUsesField; + v.setField(&a->_left); } else if (str[0] == 'Y') { - v._pvalue = &a->_top; - inst->_flags |= kInstUsesField; + v.setField(&a->_top); } else if (str[0] == 'Z') { - v._pvalue = &a->_z; - inst->_flags |= kInstUsesField; + v.setField(&a->_z); } else if (str[0] == 'F') { - v._pvalue = &a->_frame; - inst->_flags |= kInstUsesField; + v.setField(&a->_frame); } - return v; } -ScriptVar Parallaction_ns::parseLValue(Instruction *inst, const char *str, LocalVariable *locals, Animation *a) { - - ScriptVar v; +void Parallaction_ns::parseLValue(ScriptVar &v, const char *str) { - v._pvalue = 0; // should stop compiler from complaining - - int index = findLocal(str, locals); + int index = _instParseCtxt.program->findLocal(str); if (index != -1) { - v._local = &locals[index]; - inst->_flags |= kInstUsesLocal; - return v; + v.setLocal(&_instParseCtxt.locals[index]); + return; } + Animation *a; if (str[1] == '.') { a = findAnimation(&str[2]); + } else { + a = _instParseCtxt.a; } if (str[0] == 'X') { - v._pvalue = &a->_left; - inst->_flags |= kInstUsesField; + v.setField(&a->_left); } else if (str[0] == 'Y') { - v._pvalue = &a->_top; - inst->_flags |= kInstUsesField; + v.setField(&a->_top); } else if (str[0] == 'Z') { - v._pvalue = &a->_z; - inst->_flags |= kInstUsesField; + v.setField(&a->_z); } else if (str[0] == 'F') { - v._pvalue = &a->_frame; - inst->_flags |= kInstUsesField; + v.setField(&a->_frame); } - return v; } @@ -1013,7 +965,8 @@ void Parallaction_ns::initParsers() { INSTRUCTION_PARSER(null), // wait INSTRUCTION_PARSER(animation), // start INSTRUCTION_PARSER(sound), - INSTRUCTION_PARSER(move) + INSTRUCTION_PARSER(move), + INSTRUCTION_PARSER(endscript) }; uint i; diff --git a/engines/parallaction/staticres.cpp b/engines/parallaction/staticres.cpp index bd583155db..048aed4089 100644 --- a/engines/parallaction/staticres.cpp +++ b/engines/parallaction/staticres.cpp @@ -301,7 +301,8 @@ const char *_instructionNamesRes_ns[] = { "wait", "start", "sound", - "move" + "move", + "endscript" }; const char *_callableNamesRes_ns[] = { |