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

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Tue Aug 14 00:59:13 CEST 2007


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

Log Message:
-----------
Changed Command parsing/execution and Instruction execution from switch statements into arrays of function pointers.

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

Modified: scummvm/trunk/engines/parallaction/animation.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/animation.cpp	2007-08-13 21:15:27 UTC (rev 28598)
+++ scummvm/trunk/engines/parallaction/animation.cpp	2007-08-13 22:59:13 UTC (rev 28599)
@@ -49,7 +49,7 @@
 #define INST_START						16
 #define INST_SOUND						17
 #define INST_MOVE						18
-#define INST_END						1000
+#define INST_END						19
 
 
 void	wrapLocalVar(LocalVariable *local);
@@ -470,153 +470,194 @@
 }
 
 
+DECLARE_INSTRUCTION_OPCODE(on) {
+	(*_instRunCtxt.inst)->_opBase._a->_flags |= kFlagsActive;
+	(*_instRunCtxt.inst)->_opBase._a->_flags &= ~kFlagsRemove;
+}
 
-void jobRunScripts(void *parm, Job *j) {
-	debugC(3, kDebugJobs, "jobRunScripts");
 
-	static uint16 modCounter = 0;
+DECLARE_INSTRUCTION_OPCODE(off) {
+	(*_instRunCtxt.inst)->_opBase._a->_flags |= kFlagsRemove;
+//				v1C = (*_instRunCtxt.inst)->_opBase;
+}
 
+
+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;
+	}
+	_instRunCtxt.a->_program->_loopStart = _instRunCtxt.inst;
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(endloop) {
+	if (--_instRunCtxt.a->_program->_loopCounter > 0) {
+		_instRunCtxt.inst = _instRunCtxt.a->_program->_loopStart;
+	}
+}
+
+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);
+		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;
+	}
+
+	// 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;
+	}
+
+	if ((*_instRunCtxt.inst)->_flags & kInstUsesLocal) {
+		(*_instRunCtxt.inst)->_opA._local->_value = _si;
+	} else {
+		*(*_instRunCtxt.inst)->_opA._pvalue = _si;
+	}
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(put) {
 	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);
 
-	for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
+	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);
+	} 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);
+	}
+}
 
-		Animation *a = *it;
+DECLARE_INSTRUCTION_OPCODE(null) {
 
-		if (a->_flags & kFlagsCharacter) a->_z = a->_top + a->height();
+}
 
-		if ((a->_flags & kFlagsActing) == 0) continue;
-		InstructionList::iterator inst = a->_program->_ip;
+DECLARE_INSTRUCTION_OPCODE(call) {
+	callFunction((*_instRunCtxt.inst)->_opBase._index, 0);
+}
 
-//		printf("Animation: %s, flags: %x\n", a->_name, a->_flags);
 
-		while (((*inst)->_index != INST_SHOW) && (a->_flags & kFlagsActing)) {
+DECLARE_INSTRUCTION_OPCODE(wait) {
+	if (_engineFlags & kEngineWalking)
+		_instRunCtxt.suspend = true;
+}
 
-			debugC(9, kDebugJobs, "Animation: %s, instruction: %s", a->_label._text, (*inst)->_index == INST_END ? "end" : _vm->_instructionNamesRes[(*inst)->_index - 1]);
 
-			switch ((*inst)->_index) {
-			case INST_ENDLOOP:	// endloop
-				if (--a->_program->_loopCounter > 0) {
-					inst = a->_program->_loopStart;
-				}
-				break;
+DECLARE_INSTRUCTION_OPCODE(start) {
+//				v1C = (*_instRunCtxt.inst)->_opBase;
+	(*_instRunCtxt.inst)->_opBase._a->_flags |= (kFlagsActing | kFlagsActive);
+}
 
-			case INST_OFF:	{// off
-				(*inst)->_opBase._a->_flags |= kFlagsRemove;
-//				v1C = (*inst)->_opBase;
-				}
-				break;
 
-			case INST_ON:	// on
-				(*inst)->_opBase._a->_flags |= kFlagsActive;
-				(*inst)->_opBase._a->_flags &= ~kFlagsRemove;
-				break;
+DECLARE_INSTRUCTION_OPCODE(sound) {
+	_activeZone = (*_instRunCtxt.inst)->_opBase._z;
+}
 
-			case INST_START:	// start
-//				v1C = (*inst)->_opBase;
-				(*inst)->_opBase._a->_flags |= (kFlagsActing | kFlagsActive);
-				break;
 
-			case INST_LOOP: // loop
-				if ((*inst)->_flags & kInstUsesLiteral) {
-					a->_program->_loopCounter = (*inst)->_opBase._loopCounter._value;
-				} else {
-					a->_program->_loopCounter = *(*inst)->_opBase._loopCounter._pvalue;
-				}
-				a->_program->_loopStart = inst;
-				break;
+DECLARE_INSTRUCTION_OPCODE(move) {
+	WalkNodeList *v4 = _char._builder.buildPath(*(*_instRunCtxt.inst)->_opA._pvalue, *(*_instRunCtxt.inst)->_opB._pvalue);
+	addJob(&jobWalk, v4, kPriority19 );
+	_engineFlags |= kEngineWalking;
+}
 
-			case INST_INC:	// inc
-			case INST_DEC: {	// dec
-				int16 _si = 0;
-				int16 _ax = 0, _bx = 0;
-				if ((*inst)->_flags & kInstUsesLiteral) {
-					_si = (*inst)->_opB._value;
-				} else {
-					_si = *(*inst)->_opB._pvalue;
-				}
-				if ((*inst)->_flags & kInstMod) {	// mod
-					_bx = (_si > 0 ? _si : -_si);
-					if (modCounter % _bx != 0) break;
+DECLARE_INSTRUCTION_OPCODE(end) {
+	if ((_instRunCtxt.a->_flags & kFlagsLooping) == 0) {
+		_instRunCtxt.a->_flags &= ~kFlagsActing;
+		runCommands(_instRunCtxt.a->_commands, _instRunCtxt.a);
+	}
+	_instRunCtxt.a->_program->_ip = _instRunCtxt.a->_program->_instructions.begin();
 
-					_si = (_si > 0 ?  1 : -1);
-				}
-				if ((*inst)->_flags & kInstUsesLocal) {	// local
-					if ((*inst)->_index == INST_INC) _ax = _si;
-					else _ax = -_si;
+	_instRunCtxt.suspend = true;
+}
 
-					(*inst)->_opA._local->_value += _ax;
-					wrapLocalVar((*inst)->_opA._local);
-					break;
-				}
 
-				// built-in variable (x, y, z, f)
-				if ((*inst)->_index == INST_INC) _ax = _si;
-				else _ax = -_si;
-				*(*inst)->_opA._pvalue += _ax;
-			}
-			break;
 
-			case INST_MOVE: { // move
-				WalkNodeList *v4 = _vm->_char._builder.buildPath(*(*inst)->_opA._pvalue, *(*inst)->_opB._pvalue);
-				_vm->addJob(&jobWalk, v4, kPriority19 );
-				_engineFlags |= kEngineWalking;
-			}
-				break;
+void jobRunScripts(void *parm, Job *j) {
+	debugC(3, kDebugJobs, "jobRunScripts");
 
-			case INST_PUT:	// put
-				v18.w = (*inst)->_opBase._a->width();
-				v18.h = (*inst)->_opBase._a->height();
-				v18.pixels = (*inst)->_opBase._a->getFrameData((*inst)->_opBase._a->_frame);
+	static uint16 modCounter = 0;
 
-				if ((*inst)->_flags & kInstMaskedPut) {
-					uint16 _si = _vm->_gfx->queryMask((*inst)->_opB._value);
-					_vm->_gfx->blitCnv(&v18, (*inst)->_opA._value, (*inst)->_opB._value, _si, Gfx::kBitBack);
-					_vm->_gfx->blitCnv(&v18, (*inst)->_opA._value, (*inst)->_opB._value, _si, Gfx::kBit2);
-				} else {
-					_vm->_gfx->flatBlitCnv(&v18, (*inst)->_opA._value, (*inst)->_opB._value, Gfx::kBitBack);
-					_vm->_gfx->flatBlitCnv(&v18, (*inst)->_opA._value, (*inst)->_opB._value, Gfx::kBit2);
-				}
-				break;
+	static const Parallaction::Opcode opcodes[] = {
+		INSTRUCTION_OPCODE(on),
+		INSTRUCTION_OPCODE(off),
+		INSTRUCTION_OPCODE(set),		// x
+		INSTRUCTION_OPCODE(set),		// y
+		INSTRUCTION_OPCODE(set),		// z
+		INSTRUCTION_OPCODE(set),		// f
+		INSTRUCTION_OPCODE(loop),
+		INSTRUCTION_OPCODE(endloop),
+		INSTRUCTION_OPCODE(null),
+		INSTRUCTION_OPCODE(inc),
+		INSTRUCTION_OPCODE(inc),		// dec
+		INSTRUCTION_OPCODE(set),
+		INSTRUCTION_OPCODE(put),
+		INSTRUCTION_OPCODE(call),
+		INSTRUCTION_OPCODE(wait),
+		INSTRUCTION_OPCODE(start),
+		INSTRUCTION_OPCODE(sound),
+		INSTRUCTION_OPCODE(move),
+		INSTRUCTION_OPCODE(end)
+	};
 
-			case INST_END:	// exit
-				if ((a->_flags & kFlagsLooping) == 0) {
-					a->_flags &= ~kFlagsActing;
-					_vm->runCommands(a->_commands, a);
-				}
-				a->_program->_ip = a->_program->_instructions.begin();
-				goto label1;
+	_vm->_instructionOpcodes = opcodes;
 
+	for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
 
-			case INST_CALL: // call
-				_vm->callFunction((*inst)->_opBase._index, 0);
-				break;
+		Animation *a = *it;
 
-			case INST_WAIT: // wait
-				if (_engineFlags & kEngineWalking) goto label1;
-				break;
+		if (a->_flags & kFlagsCharacter) a->_z = a->_top + a->height();
 
-			case INST_SOUND:	// sound
-				_activeZone = (*inst)->_opBase._z;
-				break;
+		if ((a->_flags & kFlagsActing) == 0) continue;
+		InstructionList::iterator inst = a->_program->_ip;
 
-			default: {			// INST_SET, INST_X, INST_Y, INST_Z, INST_F
-				int16 _si;
-				if ((*inst)->_flags & kInstUsesLiteral) {
-					_si = (*inst)->_opB._value;
-				} else {
-					_si = *(*inst)->_opB._pvalue;
-				}
+		while (((*inst)->_index != INST_SHOW) && (a->_flags & kFlagsActing)) {
 
-				if ((*inst)->_flags & kInstUsesLocal) {
-					(*inst)->_opA._local->_value = _si;
-				} else {
-					*(*inst)->_opA._pvalue = _si;
-				}
-				}
-				break;
+			debugC(9, kDebugJobs, "Animation: %s, instruction: %s", a->_label._text, (*inst)->_index == INST_END ? "end" : _vm->_instructionNamesRes[(*inst)->_index - 1]);
 
-			}
+			_vm->_instRunCtxt.inst = inst;
+			_vm->_instRunCtxt.a = a;
+			_vm->_instRunCtxt.modCounter = modCounter;
+			_vm->_instRunCtxt.suspend = false;
 
+			(_vm->*(_vm->_instructionOpcodes)[(*inst)->_index - 1])();
+
+			inst = _vm->_instRunCtxt.inst;		// handles endloop correctly
+
+			if (_vm->_instRunCtxt.suspend)
+				goto label1;
+
 			inst++;
 		}
 

Modified: scummvm/trunk/engines/parallaction/commands.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/commands.cpp	2007-08-13 21:15:27 UTC (rev 28598)
+++ scummvm/trunk/engines/parallaction/commands.cpp	2007-08-13 22:59:13 UTC (rev 28599)
@@ -47,93 +47,115 @@
 #define CMD_MOVE			15
 #define CMD_STOP			16
 
+DECLARE_COMMAND_PARSER(Flags) {
+	if (_globalTable->lookup(_tokens[1]) == -1) {
+		do {
+			char _al = _localFlagNames->lookup(_tokens[_cmdParseCtxt.nextToken]);
+			_cmdParseCtxt.nextToken++;
+			_cmdParseCtxt.cmd->u._flags |= 1 << (_al - 1);
+		} while (!scumm_stricmp(_tokens[_cmdParseCtxt.nextToken++], "|"));
+		_cmdParseCtxt.nextToken--;
+	} else {
+		_cmdParseCtxt.cmd->u._flags |= kFlagsGlobal;
+		do {
+			char _al = _globalTable->lookup(_tokens[1]);
+			_cmdParseCtxt.nextToken++;
+			_cmdParseCtxt.cmd->u._flags |= 1 << (_al - 1);
+		} while (!scumm_stricmp(_tokens[_cmdParseCtxt.nextToken++], "|"));
+		_cmdParseCtxt.nextToken--;
+	}
+}
 
-void Parallaction::parseCommands(Script &script, CommandList& list) {
-//	printf("parseCommands()");
 
-	fillBuffers(script, true);
+DECLARE_COMMAND_PARSER(Animation) {
+	_cmdParseCtxt.cmd->u._animation = findAnimation(_tokens[_cmdParseCtxt.nextToken]);
+	_cmdParseCtxt.nextToken++;
+	if (_cmdParseCtxt.cmd->u._animation == NULL) {
+		strcpy(_forwardedAnimationNames[_numForwards], _tokens[_cmdParseCtxt.nextToken-1]);
+		_forwardedCommands[_numForwards] = _cmdParseCtxt.cmd;
+		_numForwards++;
+	}
+}
 
-	while (scumm_stricmp(_tokens[0], "ENDCOMMANDS") && scumm_stricmp(_tokens[0], "ENDZONE")) {
-//		printf("token[0] = %s", _tokens[0]);
 
-		Command *cmd = new Command;
+DECLARE_COMMAND_PARSER(Zone) {
+	_cmdParseCtxt.cmd->u._zone = findZone(_tokens[_cmdParseCtxt.nextToken]);
+	_cmdParseCtxt.nextToken++;
+}
 
-		cmd->_id = _commandsNames->lookup(_tokens[0]);
-		uint16 _si = 1;
 
-//		printf("cmd id = %i", cmd->_id);
+DECLARE_COMMAND_PARSER(Location) {
+	_cmdParseCtxt.cmd->u._string = (char*)malloc(strlen(_tokens[_cmdParseCtxt.nextToken])+1);
+	strcpy(_cmdParseCtxt.cmd->u._string, _tokens[_cmdParseCtxt.nextToken]);
+	_cmdParseCtxt.nextToken++;
+}
 
-		switch (cmd->_id) {
-		case CMD_SET:	// set
-		case CMD_CLEAR: // clear
-		case CMD_TOGGLE:	// toggle
-			if (_globalTable->lookup(_tokens[1]) == -1) {
-				do {
-					char _al = _localFlagNames->lookup(_tokens[_si]);
-					_si++;
-					cmd->u._flags |= 1 << (_al - 1);
-				} while (!scumm_stricmp(_tokens[_si++], "|"));
-				_si--;
-			} else {
-				cmd->u._flags |= kFlagsGlobal;
-				do {
-					char _al = _globalTable->lookup(_tokens[1]);
-					_si++;
-					cmd->u._flags |= 1 << (_al - 1);
-				} while (!scumm_stricmp(_tokens[_si++], "|"));
-				_si--;
-			}
-			break;
 
-		case CMD_START: // start
-		case CMD_STOP:	// stop
-			cmd->u._animation = findAnimation(_tokens[_si]);
-			_si++;
-			if (cmd->u._animation == NULL) {
-				strcpy(_forwardedAnimationNames[_numForwards], _tokens[_si-1]);
-				_forwardedCommands[_numForwards] = cmd;
-				_numForwards++;
-			}
-			break;
+DECLARE_COMMAND_PARSER(Drop) {
+	_cmdParseCtxt.cmd->u._object = _objectsNames->lookup(_tokens[_cmdParseCtxt.nextToken]);
+	_cmdParseCtxt.nextToken++;
+}
 
-		case CMD_SPEAK: // speak
-		case CMD_GET:	// get
-		case CMD_OPEN:	// open
-		case CMD_CLOSE: // close
-		case CMD_ON:	// on
-		case CMD_OFF:	// off
-			cmd->u._zone = findZone(_tokens[_si]);
-			_si++;
-			break;
 
-		case CMD_LOCATION:	// location
-			cmd->u._string = (char*)malloc(strlen(_tokens[_si])+1);
-			strcpy(cmd->u._string, _tokens[_si]);
-			_si++;
-			break;
+DECLARE_COMMAND_PARSER(Call) {
+	_cmdParseCtxt.cmd->u._callable = _callableNames->lookup(_tokens[_cmdParseCtxt.nextToken]) - 1;
+	_cmdParseCtxt.nextToken++;
+}
 
-		case CMD_CALL:	// call
-			cmd->u._callable = _callableNames->lookup(_tokens[_si]) - 1;
-			_si++;
-			break;
 
-		case CMD_DROP:	// drop
-			cmd->u._object = _objectsNames->lookup(_tokens[_si]);
-			_si++;
-			break;
+DECLARE_COMMAND_PARSER(Null) {
+}
 
-		case CMD_QUIT:	// quit
-			break;
 
-		case CMD_MOVE:	// move
-			cmd->u._move._x = atoi(_tokens[_si]);
-			_si++;
-			cmd->u._move._y = atoi(_tokens[_si]);
-			_si++;
-			break;
+DECLARE_COMMAND_PARSER(Move) {
+	_cmdParseCtxt.cmd->u._move._x = atoi(_tokens[_cmdParseCtxt.nextToken]);
+	_cmdParseCtxt.nextToken++;
+	_cmdParseCtxt.cmd->u._move._y = atoi(_tokens[_cmdParseCtxt.nextToken]);
+	_cmdParseCtxt.nextToken++;
+}
 
-		}
 
+
+
+void Parallaction::parseCommands(Script &script, CommandList& list) {
+
+	static const Opcode parsers[] = {
+		COMMAND_PARSER(Flags),			// set
+		COMMAND_PARSER(Flags),			// clear
+		COMMAND_PARSER(Animation),		// start
+		COMMAND_PARSER(Zone),			// speak
+		COMMAND_PARSER(Zone),			// get
+		COMMAND_PARSER(Location),		// location
+		COMMAND_PARSER(Zone),			// open
+		COMMAND_PARSER(Zone),			// close
+		COMMAND_PARSER(Zone),			// on
+		COMMAND_PARSER(Zone),			// off
+		COMMAND_PARSER(Call),			// call
+		COMMAND_PARSER(Flags),			// toggle
+		COMMAND_PARSER(Drop),			// drop
+		COMMAND_PARSER(Null),			// quit
+		COMMAND_PARSER(Move),			// move
+		COMMAND_PARSER(Animation)		// stop
+	};
+
+	_commandParsers = parsers;
+
+
+	fillBuffers(script, true);
+
+	while (scumm_stricmp(_tokens[0], "ENDCOMMANDS") && scumm_stricmp(_tokens[0], "ENDZONE")) {
+
+		Command *cmd = new Command;
+
+		cmd->_id = _commandsNames->lookup(_tokens[0]);
+
+		_cmdParseCtxt.nextToken = 1;
+		_cmdParseCtxt.cmd = cmd;
+
+		(this->*_commandParsers[cmd->_id - 1])();
+
+		int _si = _cmdParseCtxt.nextToken;
+
 		if (!scumm_stricmp(_tokens[_si], "flags")) {
 			_si++;
 
@@ -192,144 +214,181 @@
 		fillBuffers(script, true);
 
 	}
+}
 
+
+DECLARE_COMMAND_OPCODE(set) {
+	if (_cmdRunCtxt.cmd->u._flags & kFlagsGlobal) {
+		_cmdRunCtxt.cmd->u._flags &= ~kFlagsGlobal;
+		_commandFlags |= _cmdRunCtxt.cmd->u._flags;
+	} else {
+		_localFlags[_currentLocationIndex] |= _cmdRunCtxt.cmd->u._flags;
+	}
 }
 
 
-void Parallaction::runCommands(CommandList& list, Zone *z) {
-	debugC(1, kDebugLocation, "runCommands");
+DECLARE_COMMAND_OPCODE(clear) {
+	if (_cmdRunCtxt.cmd->u._flags & kFlagsGlobal) {
+		_cmdRunCtxt.cmd->u._flags &= ~kFlagsGlobal;
+		_commandFlags &= ~_cmdRunCtxt.cmd->u._flags;
+	} else {
+		_localFlags[_currentLocationIndex] &= ~_cmdRunCtxt.cmd->u._flags;
+	}
+}
 
-	CommandList::iterator it = list.begin();
-	for ( ; it != list.end(); it++) {
 
-		Command *cmd = *it;
-		CommandData *u = &cmd->u;
-		uint32 v8 = _localFlags[_currentLocationIndex];
+DECLARE_COMMAND_OPCODE(start) {
+	_cmdRunCtxt.cmd->u._zone->_flags |= kFlagsActing;
+}
 
-		if (_engineFlags & kEngineQuit)
-			break;
 
-		if (cmd->_flagsOn & kFlagsGlobal) {
-			v8 = _commandFlags | kFlagsGlobal;
+DECLARE_COMMAND_OPCODE(speak) {
+	_activeZone = _cmdRunCtxt.cmd->u._zone;
+}
+
+
+DECLARE_COMMAND_OPCODE(get) {
+	_cmdRunCtxt.cmd->u._zone->_flags &= ~kFlagsFixed;
+	if (!runZone(_cmdRunCtxt.cmd->u._zone)) {
+		runCommands(_cmdRunCtxt.cmd->u._zone->_commands);
+	}
+}
+
+
+DECLARE_COMMAND_OPCODE(location) {
+	strcpy(_location._name, _cmdRunCtxt.cmd->u._string);
+	_engineFlags |= kEngineChangeLocation;
+}
+
+
+DECLARE_COMMAND_OPCODE(open) {
+	_cmdRunCtxt.cmd->u._zone->_flags &= ~kFlagsClosed;
+	if (_cmdRunCtxt.cmd->u._zone->u.door->_cnv) {
+		addJob(&jobToggleDoor, (void*)_cmdRunCtxt.cmd->u._zone, kPriority18 );
+	}
+}
+
+
+DECLARE_COMMAND_OPCODE(close) {
+	_cmdRunCtxt.cmd->u._zone->_flags |= kFlagsClosed;
+	if (_cmdRunCtxt.cmd->u._zone->u.door->_cnv) {
+		addJob(&jobToggleDoor, (void*)_cmdRunCtxt.cmd->u._zone, kPriority18 );
+	}
+}
+
+
+DECLARE_COMMAND_OPCODE(on) {
+	// WORKAROUND: the original DOS-based engine didn't check u->_zone before dereferencing
+	// the pointer to get structure members, thus leading to crashes in systems with memory
+	// protection.
+	// As a side note, the overwritten address is the 5th entry in the DOS interrupt table
+	// (print screen handler): this suggests that a system would hang when the print screen
+	// key is pressed after playing Nippon Safes, provided that this code path is taken.
+	if (_cmdRunCtxt.cmd->u._zone != NULL) {
+		_cmdRunCtxt.cmd->u._zone->_flags &= ~kFlagsRemove;
+		_cmdRunCtxt.cmd->u._zone->_flags |= kFlagsActive;
+		if ((_cmdRunCtxt.cmd->u._zone->_type & 0xFFFF) == kZoneGet) {
+			addJob(&jobDisplayDroppedItem, _cmdRunCtxt.cmd->u._zone, kPriority17 );
 		}
+	}
+}
 
-		if ((cmd->_flagsOn & v8) != cmd->_flagsOn) continue;
-		if ((cmd->_flagsOff & ~v8) != cmd->_flagsOff) continue;
 
-		debugC(1, kDebugLocation, "runCommands: %s (on: %x, off: %x)", _commandsNamesRes[cmd->_id-1], cmd->_flagsOn, cmd->_flagsOff);
+DECLARE_COMMAND_OPCODE(off) {
+	_cmdRunCtxt.cmd->u._zone->_flags |= kFlagsRemove;
+}
 
-		switch (cmd->_id) {
 
-		case CMD_SET:	// set
-			if (cmd->u._flags & kFlagsGlobal) {
-				cmd->u._flags &= ~kFlagsGlobal;
-				_commandFlags |= cmd->u._flags;
-			} else {
-				_localFlags[_currentLocationIndex] |= cmd->u._flags;
-			}
-			break;
+DECLARE_COMMAND_OPCODE(call) {
+	callFunction(_cmdRunCtxt.cmd->u._callable, _cmdRunCtxt.z);
+}
 
-		case CMD_CLEAR: // clear
-			if (cmd->u._flags & kFlagsGlobal) {
-				cmd->u._flags &= ~kFlagsGlobal;
-				_commandFlags &= ~cmd->u._flags;
-			} else {
-				_localFlags[_currentLocationIndex] &= ~cmd->u._flags;
-			}
-			break;
 
-		case CMD_TOGGLE:	// toggle
-			if (cmd->u._flags & kFlagsGlobal) {
-				cmd->u._flags &= ~kFlagsGlobal;
-				_commandFlags ^= cmd->u._flags;
-			} else {
-				_localFlags[_currentLocationIndex] ^= cmd->u._flags;
-			}
-			break;
+DECLARE_COMMAND_OPCODE(toggle) {
+	if (_cmdRunCtxt.cmd->u._flags & kFlagsGlobal) {
+		_cmdRunCtxt.cmd->u._flags &= ~kFlagsGlobal;
+		_commandFlags ^= _cmdRunCtxt.cmd->u._flags;
+	} else {
+		_localFlags[_currentLocationIndex] ^= _cmdRunCtxt.cmd->u._flags;
+	}
+}
 
-		case CMD_START: // start
-			cmd->u._zone->_flags |= kFlagsActing;
-			break;
 
-		case CMD_STOP:	// stop
-			cmd->u._zone->_flags &= ~kFlagsActing;
-			break;
+DECLARE_COMMAND_OPCODE(drop){
+	dropItem( _cmdRunCtxt.cmd->u._object );
+}
 
-		case CMD_SPEAK: // speak
-			_activeZone = u->_zone;
-			break;
 
-		case CMD_GET:	// get
-			u->_zone->_flags &= ~kFlagsFixed;
-			if (!runZone(u->_zone)) {
-				runCommands(u->_zone->_commands);
-			}
-			break;
+DECLARE_COMMAND_OPCODE(quit) {
+	_engineFlags |= kEngineQuit;
+}
 
-		case CMD_DROP:	// drop
-			dropItem( u->_object );
-			break;
 
-		case CMD_OPEN:	// open
-			u->_zone->_flags &= ~kFlagsClosed;
-			if (u->_zone->u.door->_cnv) {
-				addJob(&jobToggleDoor, (void*)u->_zone, kPriority18 );
-			}
-			break;
+DECLARE_COMMAND_OPCODE(move) {
+	if ((_char._ani._flags & kFlagsRemove) || (_char._ani._flags & kFlagsActive) == 0) {
+		return;
+	}
 
-		case CMD_CLOSE: // close
-			u->_zone->_flags |= kFlagsClosed;
-			if (u->_zone->u.door->_cnv) {
-				addJob(&jobToggleDoor, (void*)u->_zone, kPriority18 );
-			}
-			break;
+	WalkNodeList *vC = _char._builder.buildPath(_cmdRunCtxt.cmd->u._move._x, _cmdRunCtxt.cmd->u._move._y);
 
-		case CMD_ON:	// on
-			// WORKAROUND: the original DOS-based engine didn't check u->_zone before dereferencing
-			// the pointer to get structure members, thus leading to crashes in systems with memory
-			// protection.
-			// As a side note, the overwritten address is the 5th entry in the DOS interrupt table
-			// (print screen handler): this suggests that a system would hang when the print screen
-			// key is pressed after playing Nippon Safes, provided that this code path is taken.
-			if (u->_zone != NULL) {
-				u->_zone->_flags &= ~kFlagsRemove;
-				u->_zone->_flags |= kFlagsActive;
-				if ((u->_zone->_type & 0xFFFF) == kZoneGet) {
-					addJob(&jobDisplayDroppedItem, u->_zone, kPriority17 );
-				}
-			}
-			break;
+	addJob(&jobWalk, vC, kPriority19 );
+	_engineFlags |= kEngineWalking;
+}
 
-		case CMD_OFF:	// off
-			u->_zone->_flags |= kFlagsRemove;
-			break;
 
-		case CMD_LOCATION:	// location
-			strcpy(_location._name, u->_string);
-			_engineFlags |= kEngineChangeLocation;
-			break;
+DECLARE_COMMAND_OPCODE(stop) {
+	_cmdRunCtxt.cmd->u._zone->_flags &= ~kFlagsActing;
+}
 
-		case CMD_CALL:	// call
-			callFunction(u->_callable, z);
-			break;
 
-		case CMD_QUIT:	// quit
-			_engineFlags |= kEngineQuit;
-			break;
 
-		case CMD_MOVE: {	// move
-			if ((_char._ani._flags & kFlagsRemove) || (_char._ani._flags & kFlagsActive) == 0) {
-				continue;
-			}
 
-			WalkNodeList *vC = _char._builder.buildPath(u->_move._x, u->_move._y);
+void Parallaction::runCommands(CommandList& list, Zone *z) {
+	debugC(1, kDebugLocation, "runCommands");
 
-			addJob(&jobWalk, vC, kPriority19 );
-			_engineFlags |= kEngineWalking;
-			}
+	static const Opcode opcodes[] = {
+		COMMAND_OPCODE(set),
+		COMMAND_OPCODE(clear),
+		COMMAND_OPCODE(start),
+		COMMAND_OPCODE(speak),
+		COMMAND_OPCODE(get),
+		COMMAND_OPCODE(location),
+		COMMAND_OPCODE(open),
+		COMMAND_OPCODE(close),
+		COMMAND_OPCODE(on),
+		COMMAND_OPCODE(off),
+		COMMAND_OPCODE(call),
+		COMMAND_OPCODE(toggle),
+		COMMAND_OPCODE(drop),
+		COMMAND_OPCODE(quit),
+		COMMAND_OPCODE(move),
+		COMMAND_OPCODE(stop)
+	};
+
+	_commandOpcodes = opcodes;
+
+	CommandList::iterator it = list.begin();
+	for ( ; it != list.end(); it++) {
+
+		Command *cmd = *it;
+		uint32 v8 = _localFlags[_currentLocationIndex];
+
+		if (_engineFlags & kEngineQuit)
 			break;
 
+		if (cmd->_flagsOn & kFlagsGlobal) {
+			v8 = _commandFlags | kFlagsGlobal;
 		}
+
+		if ((cmd->_flagsOn & v8) != cmd->_flagsOn) continue;
+		if ((cmd->_flagsOff & ~v8) != cmd->_flagsOff) continue;
+
+		debugC(1, kDebugLocation, "runCommands: %s (on: %x, off: %x)", _commandsNamesRes[cmd->_id-1], cmd->_flagsOn, cmd->_flagsOff);
+
+		_cmdRunCtxt.z = z;
+		_cmdRunCtxt.cmd = cmd;
+
+		(this->*_commandOpcodes[cmd->_id - 1])();
 	}
 
 	debugC(1, kDebugLocation, "runCommands completed");

Modified: scummvm/trunk/engines/parallaction/parallaction.h
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.h	2007-08-13 21:15:27 UTC (rev 28598)
+++ scummvm/trunk/engines/parallaction/parallaction.h	2007-08-13 22:59:13 UTC (rev 28599)
@@ -292,6 +292,17 @@
 };
 
 
+#define DECLARE_COMMAND_PARSER(sig) void Parallaction::cmdParse_##sig()
+#define COMMAND_PARSER(sig) &Parallaction::cmdParse_##sig
+
+#define DECLARE_COMMAND_OPCODE(op) void Parallaction::cmdOp_##op()
+#define COMMAND_OPCODE(op) &Parallaction::cmdOp_##op
+
+
+#define DECLARE_INSTRUCTION_OPCODE(op) void Parallaction::instOp_##op()
+#define INSTRUCTION_OPCODE(op) &Parallaction::instOp_##op
+
+
 class Parallaction : public Engine {
 	friend class Debugger;
 
@@ -309,6 +320,71 @@
 
 	void 		waitTime(uint32 t);
 
+	typedef void (Parallaction::*Opcode)();
+	const Opcode	*_commandParsers;
+
+	struct {
+		Command	*cmd;
+		int		nextToken;
+	} _cmdParseCtxt;
+
+	DECLARE_COMMAND_PARSER(Flags);
+	DECLARE_COMMAND_PARSER(Animation);
+	DECLARE_COMMAND_PARSER(Zone);
+	DECLARE_COMMAND_PARSER(Location);
+	DECLARE_COMMAND_PARSER(Drop);
+	DECLARE_COMMAND_PARSER(Call);
+	DECLARE_COMMAND_PARSER(Null);
+	DECLARE_COMMAND_PARSER(Move);
+
+	const Opcode	*_commandOpcodes;
+
+	struct {
+		Command	*cmd;
+		Zone	*z;
+	} _cmdRunCtxt;
+
+	DECLARE_COMMAND_OPCODE(set);
+	DECLARE_COMMAND_OPCODE(clear);
+	DECLARE_COMMAND_OPCODE(start);
+	DECLARE_COMMAND_OPCODE(speak);
+	DECLARE_COMMAND_OPCODE(get);
+	DECLARE_COMMAND_OPCODE(location);
+	DECLARE_COMMAND_OPCODE(open);
+	DECLARE_COMMAND_OPCODE(close);
+	DECLARE_COMMAND_OPCODE(on);
+	DECLARE_COMMAND_OPCODE(off);
+	DECLARE_COMMAND_OPCODE(call);
+	DECLARE_COMMAND_OPCODE(toggle);
+	DECLARE_COMMAND_OPCODE(drop);
+	DECLARE_COMMAND_OPCODE(quit);
+	DECLARE_COMMAND_OPCODE(move);
+	DECLARE_COMMAND_OPCODE(stop);
+
+	const Opcode	*_instructionOpcodes;
+
+	struct {
+		Animation	*a;
+		InstructionList::iterator inst;
+		uint16		modCounter;
+		bool		suspend;
+	} _instRunCtxt;
+
+	DECLARE_INSTRUCTION_OPCODE(on);
+	DECLARE_INSTRUCTION_OPCODE(off);
+	DECLARE_INSTRUCTION_OPCODE(loop);
+	DECLARE_INSTRUCTION_OPCODE(endloop);
+	DECLARE_INSTRUCTION_OPCODE(null);
+	DECLARE_INSTRUCTION_OPCODE(inc);
+	DECLARE_INSTRUCTION_OPCODE(set);
+	DECLARE_INSTRUCTION_OPCODE(put);
+	DECLARE_INSTRUCTION_OPCODE(call);
+	DECLARE_INSTRUCTION_OPCODE(wait);
+	DECLARE_INSTRUCTION_OPCODE(start);
+	DECLARE_INSTRUCTION_OPCODE(sound);
+	DECLARE_INSTRUCTION_OPCODE(move);
+	DECLARE_INSTRUCTION_OPCODE(end);
+
 	void 		parseLocation(const char *filename);
 	virtual bool parseLocationLine(const char *filename, Script *script) = 0;
 	void 		changeCursor(int32 index);
@@ -498,6 +574,7 @@
 
 };
 
+
 class Parallaction_ns : public Parallaction {
 
 public:


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