aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction/parser_ns.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/parallaction/parser_ns.cpp')
-rw-r--r--engines/parallaction/parser_ns.cpp221
1 files changed, 87 insertions, 134 deletions
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;