[Scummvm-cvs-logs] SF.net SVN: scummvm: [28601] scummvm/trunk/engines/parallaction

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Tue Aug 14 01:44:13 CEST 2007


Revision: 28601
          http://scummvm.svn.sourceforge.net/scummvm/?rev=28601&view=rev
Author:   peres001
Date:     2007-08-13 16:44:13 -0700 (Mon, 13 Aug 2007)

Log Message:
-----------
Changed instruction parsing to array of function pointers.

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/animation.cpp
    scummvm/trunk/engines/parallaction/parallaction.h

Modified: scummvm/trunk/engines/parallaction/animation.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/animation.cpp	2007-08-13 23:17:17 UTC (rev 28600)
+++ scummvm/trunk/engines/parallaction/animation.cpp	2007-08-13 23:44:13 UTC (rev 28601)
@@ -278,155 +278,190 @@
 }
 
 
+DECLARE_INSTRUCTION_PARSER(animation) {
+	if (!scumm_stricmp(_tokens[1], _instParseCtxt.a->_label._text)) {
+		_instParseCtxt.inst->_opBase._a = _instParseCtxt.a;
+	} else {
+		_instParseCtxt.inst->_opBase._a = findAnimation(_tokens[1]);
+	}
+}
 
-void Parallaction::parseScriptLine(Instruction *inst, Animation *a, LocalVariable *locals) {
-//	printf("parseScriptLine()\n");
 
-	if (_tokens[0][1] == '.') {
-		_tokens[0][1] = '\0';
-		a = findAnimation(&_tokens[0][2]);
+DECLARE_INSTRUCTION_PARSER(loop) {
+	_instParseCtxt.inst->_opBase._loopCounter = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
+}
+
+
+DECLARE_INSTRUCTION_PARSER(x) {
+	_instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_left;
+	_instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
+}
+
+
+DECLARE_INSTRUCTION_PARSER(y) {
+	_instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_top;
+	_instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
+}
+
+
+DECLARE_INSTRUCTION_PARSER(z) {
+	_instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_z;
+	_instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
+}
+
+
+DECLARE_INSTRUCTION_PARSER(f) {
+	_instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_frame;
+	_instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
+}
+
+
+DECLARE_INSTRUCTION_PARSER(inc) {
+	if (!scumm_stricmp(_tokens[1], "X")) {
+		_instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_left;
+	} else
+	if (!scumm_stricmp(_tokens[1], "Y")) {
+		_instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_top;
+	} else
+	if (!scumm_stricmp(_tokens[1], "Z")) {
+		_instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_z;
+	} else
+	if (!scumm_stricmp(_tokens[1], "F")) {
+		_instParseCtxt.inst->_opA._pvalue = &_instParseCtxt.a->_frame;
+	} else {
+		_instParseCtxt.inst->_flags |= kInstUsesLocal;
+		_instParseCtxt.inst->_opA = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
 	}
 
-	if (_tokens[1][1] == '.') {
-		_tokens[1][1] = '\0';
-		a = findAnimation(&_tokens[1][2]);
+	_instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a);
+
+	if (!scumm_stricmp(_tokens[3], "mod")) {
+		_instParseCtxt.inst->_flags |= kInstMod;
 	}
+}
 
-	int16 _si = _instructionNames->lookup(_tokens[0]);
-	inst->_index = _si;
 
-	switch (inst->_index) {
-	case INST_ON:	// on
-	case INST_OFF:	// off
-	case INST_START:	// start
-		if (!scumm_stricmp(_tokens[1], a->_label._text)) {
-			inst->_opBase._a = a;
-		} else {
-			inst->_opBase._a = findAnimation(_tokens[1]);
-		}
-		break;
+DECLARE_INSTRUCTION_PARSER(set) {
+	// WORKAROUND: At least one script (balzo.script) in Amiga versions didn't declare
+	//	local variables before using them, thus leading to crashes. The line launching the
+	// 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);
+	}
 
-	case INST_LOOP: // loop
-		inst->_opBase._loopCounter = getLValue(inst, _tokens[1], locals, a);
-		break;
+	_instParseCtxt.inst->_opA = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
+	_instParseCtxt.inst->_flags |= kInstUsesLocal;
+	_instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a);
+}
 
-	case INST_X:	// x
-		inst->_opA._pvalue = &a->_left;
-		inst->_opB = getLValue(inst, _tokens[1], locals, a);
-		break;
 
-	case INST_Y:	// y
-		inst->_opA._pvalue = &a->_top;
-		inst->_opB = getLValue(inst, _tokens[1], locals, a);
-		break;
+DECLARE_INSTRUCTION_PARSER(move) {
+	_instParseCtxt.inst->_opA = getLValue(_instParseCtxt.inst, _tokens[1], _instParseCtxt.locals, _instParseCtxt.a);
+	_instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a);
+}
 
-	case INST_Z:	// z
-		inst->_opA._pvalue = &a->_z;
-		inst->_opB = getLValue(inst, _tokens[1], locals, a);
-		break;
 
-	case INST_F:	// f
-		inst->_opA._pvalue = &a->_frame;
-		inst->_opB = getLValue(inst, _tokens[1], locals, a);
-		break;
+DECLARE_INSTRUCTION_PARSER(put) {
+	if (!scumm_stricmp(_tokens[1], _instParseCtxt.a->_label._text)) {
+		_instParseCtxt.inst->_opBase._a = _instParseCtxt.a;
+	} else {
+		_instParseCtxt.inst->_opBase._a = findAnimation(_tokens[1]);
+	}
 
-	case INST_INC:	// inc
-	case INST_DEC:	// dec
-		if (!scumm_stricmp(_tokens[1], "X")) {
-			inst->_opA._pvalue = &a->_left;
-		} else
-		if (!scumm_stricmp(_tokens[1], "Y")) {
-			inst->_opA._pvalue = &a->_top;
-		} else
-		if (!scumm_stricmp(_tokens[1], "Z")) {
-			inst->_opA._pvalue = &a->_z;
-		} else
-		if (!scumm_stricmp(_tokens[1], "F")) {
-			inst->_opA._pvalue = &a->_frame;
-		} else {
-			inst->_flags |= kInstUsesLocal;
-			inst->_opA = getLValue(inst, _tokens[1], locals, a);
-		}
+	_instParseCtxt.inst->_opA = getLValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a);
+	_instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[3], _instParseCtxt.locals, _instParseCtxt.a);
+	if (!scumm_stricmp(_tokens[4], "masked")) {
+		_instParseCtxt.inst->_flags |= kInstMaskedPut;
+	}
+}
 
-		inst->_opB = getLValue(inst, _tokens[2], locals, a);
 
-		if (!scumm_stricmp(_tokens[3], "mod")) {
-			inst->_flags |= kInstMod;
-		}
-		break;
+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;
+}
 
-	case INST_SET:	// set
-		// WORKAROUND: At least one script (balzo.script) in Amiga versions didn't declare
-		//	local variables before using them, thus leading to crashes. The line launching the
-		// 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], locals) == -1) {
-			addLocal(_tokens[1], locals);
-		}
 
-		inst->_opA = getLValue(inst, _tokens[1], locals, a);
-		inst->_flags |= kInstUsesLocal;
-		inst->_opB = getLValue(inst, _tokens[2], locals, a);
-		break;
+DECLARE_INSTRUCTION_PARSER(sound) {
+	_instParseCtxt.inst->_opBase._z = findZone(_tokens[1]);
+}
 
-	case INST_MOVE: // move
-		inst->_opA = getLValue(inst, _tokens[1], locals, a);
-		inst->_opB = getLValue(inst, _tokens[2], locals, a);
-		break;
 
-	case INST_PUT:	// put
-		if (!scumm_stricmp(_tokens[1], a->_label._text)) {
-			inst->_opBase._a = a;
-		} else {
-			inst->_opBase._a = findAnimation(_tokens[1]);
-		}
+DECLARE_INSTRUCTION_PARSER(null) {
 
-		inst->_opA = getLValue(inst, _tokens[2], locals, a);
-		inst->_opB = getLValue(inst, _tokens[3], locals, a);
-		if (!scumm_stricmp(_tokens[4], "masked")) {
-			inst->_flags |= kInstMaskedPut;
-		}
-		break;
+}
 
-	case INST_CALL: {	// call
-		int index = _callableNames->lookup(_tokens[1]);
-		if (index == Table::notFound)
-			error("unknown callable '%s'", _tokens[1]);
-		inst->_opBase._index = index - 1;
+
+DECLARE_INSTRUCTION_PARSER(defLocal) {
+	int16 val = atoi(_tokens[2]);
+	int16 index;
+
+	if (_tokens[3][0] != '\0') {
+		index = addLocal(_tokens[0], _instParseCtxt.locals, val, atoi(_tokens[3]), atoi(_tokens[4]));
+	} else {
+		index = addLocal(_tokens[0], _instParseCtxt.locals, val);
 	}
-	break;
 
-	case INST_SOUND:	// sound
-		inst->_opBase._z = findZone(_tokens[1]);
-		break;
+	_instParseCtxt.inst->_opA._local = &_instParseCtxt.locals[index];
+	_instParseCtxt.inst->_opB._value = _instParseCtxt.locals[index]._value;
 
-	case INST_ENDLOOP:	// endloop
-	case INST_SHOW: // show
-	case INST_WAIT: // wait
-		break;
+	_instParseCtxt.inst->_flags = kInstUsesLiteral | kInstUsesLocal;
+	_instParseCtxt.inst->_index = INST_SET;
+}
 
-	default: {	// local definition
-		int16 val = atoi(_tokens[2]);
-		int16 index;
 
-		if (_tokens[3][0] != '\0') {
-			index = addLocal(_tokens[0], locals, val, atoi(_tokens[3]), atoi(_tokens[4]));
-		} else {
-			index = addLocal(_tokens[0], locals, val);
-		}
 
-		inst->_opA._local = &locals[index];
-		inst->_opB._value = locals[index]._value;
 
-		inst->_flags = kInstUsesLiteral | kInstUsesLocal;
-		inst->_index = INST_SET;
+void Parallaction::parseScriptLine(Instruction *inst, Animation *a, LocalVariable *locals) {
+//	printf("parseScriptLine()\n");
+
+	static const Opcode opcodes[] = {
+		INSTRUCTION_PARSER(defLocal),	// unknown opcode -> local definition
+		INSTRUCTION_PARSER(animation),	// on
+		INSTRUCTION_PARSER(animation),	// off
+		INSTRUCTION_PARSER(x),
+		INSTRUCTION_PARSER(y),
+		INSTRUCTION_PARSER(z),
+		INSTRUCTION_PARSER(f),
+		INSTRUCTION_PARSER(loop),
+		INSTRUCTION_PARSER(null),		// endloop
+		INSTRUCTION_PARSER(null),		// show
+		INSTRUCTION_PARSER(inc),
+		INSTRUCTION_PARSER(inc),		// dec
+		INSTRUCTION_PARSER(set),
+		INSTRUCTION_PARSER(put),
+		INSTRUCTION_PARSER(call),
+		INSTRUCTION_PARSER(null),		// wait
+		INSTRUCTION_PARSER(animation),	// start
+		INSTRUCTION_PARSER(sound),
+		INSTRUCTION_PARSER(move)
+	};
+
+	_instructionParsers = opcodes;
+
+	if (_tokens[0][1] == '.') {
+		_tokens[0][1] = '\0';
+		a = findAnimation(&_tokens[0][2]);
 	}
-	break;
 
+	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;
+
+	(this->*_instructionParsers[inst->_index])();
+
 	return;
 }
 

Modified: scummvm/trunk/engines/parallaction/parallaction.h
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.h	2007-08-13 23:17:17 UTC (rev 28600)
+++ scummvm/trunk/engines/parallaction/parallaction.h	2007-08-13 23:44:13 UTC (rev 28601)
@@ -302,6 +302,8 @@
 #define DECLARE_COMMAND_OPCODE(op) void Parallaction::cmdOp_##op()
 #define COMMAND_OPCODE(op) &Parallaction::cmdOp_##op
 
+#define DECLARE_INSTRUCTION_PARSER(sig) void Parallaction::instParse_##sig()
+#define INSTRUCTION_PARSER(sig) &Parallaction::instParse_##sig
 
 #define DECLARE_INSTRUCTION_OPCODE(op) void Parallaction::instOp_##op()
 #define INSTRUCTION_OPCODE(op) &Parallaction::instOp_##op
@@ -365,6 +367,29 @@
 	DECLARE_COMMAND_OPCODE(move);
 	DECLARE_COMMAND_OPCODE(stop);
 
+	const Opcode	*_instructionParsers;
+
+	struct {
+		Animation	*a;
+		Instruction *inst;
+		LocalVariable *locals;
+	} _instParseCtxt;
+
+	DECLARE_INSTRUCTION_PARSER(animation);
+	DECLARE_INSTRUCTION_PARSER(loop);
+	DECLARE_INSTRUCTION_PARSER(x);
+	DECLARE_INSTRUCTION_PARSER(y);
+	DECLARE_INSTRUCTION_PARSER(z);
+	DECLARE_INSTRUCTION_PARSER(f);
+	DECLARE_INSTRUCTION_PARSER(inc);
+	DECLARE_INSTRUCTION_PARSER(set);
+	DECLARE_INSTRUCTION_PARSER(move);
+	DECLARE_INSTRUCTION_PARSER(put);
+	DECLARE_INSTRUCTION_PARSER(call);
+	DECLARE_INSTRUCTION_PARSER(sound);
+	DECLARE_INSTRUCTION_PARSER(null);
+	DECLARE_INSTRUCTION_PARSER(defLocal);
+
 	const Opcode	*_instructionOpcodes;
 
 	struct {


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list