aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/parallaction/exec_ns.cpp109
-rw-r--r--engines/parallaction/objects.cpp101
-rw-r--r--engines/parallaction/objects.h64
-rw-r--r--engines/parallaction/parallaction.h18
-rw-r--r--engines/parallaction/parser_ns.cpp221
-rw-r--r--engines/parallaction/staticres.cpp3
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[] = {