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

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Thu Aug 16 19:28:18 CEST 2007


Revision: 28637
          http://scummvm.svn.sourceforge.net/scummvm/?rev=28637&view=rev
Author:   peres001
Date:     2007-08-16 10:28:18 -0700 (Thu, 16 Aug 2007)

Log Message:
-----------
Changed more parsing routines to use tables instead of switch statements.

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/animation.cpp
    scummvm/trunk/engines/parallaction/commands.cpp
    scummvm/trunk/engines/parallaction/commands.h
    scummvm/trunk/engines/parallaction/dialogue.cpp
    scummvm/trunk/engines/parallaction/location.cpp
    scummvm/trunk/engines/parallaction/parallaction.cpp
    scummvm/trunk/engines/parallaction/parallaction.h
    scummvm/trunk/engines/parallaction/parser.cpp
    scummvm/trunk/engines/parallaction/staticres.cpp
    scummvm/trunk/engines/parallaction/zone.cpp
    scummvm/trunk/engines/parallaction/zone.h

Modified: scummvm/trunk/engines/parallaction/animation.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/animation.cpp	2007-08-16 07:47:13 UTC (rev 28636)
+++ scummvm/trunk/engines/parallaction/animation.cpp	2007-08-16 17:28:18 UTC (rev 28637)
@@ -68,80 +68,109 @@
 	return NULL;
 }
 
+DECLARE_ANIM_PARSER(invalid) {
+	error("unknown statement '%s' in animation %s", _tokens[0], _locAnimParseCtxt.a->_label._text);
+}
 
-Animation *Parallaction::parseAnimation(Script& script, AnimationList &list, char *name) {
-//	printf("parseAnimation(%s)\n", name);
 
-	Animation *vD0 = new Animation;
+DECLARE_ANIM_PARSER(script) {
+	_locAnimParseCtxt.a->_scriptName = strdup(_tokens[1]);
+}
 
-	vD0->_label._text = (char*)malloc(strlen(name)+1);
-	strcpy(vD0->_label._text, name);
 
-	list.push_front(vD0);
+DECLARE_ANIM_PARSER(commands) {
+	 parseCommands(*_locAnimParseCtxt.script, _locAnimParseCtxt.a->_commands);
+}
 
-	fillBuffers(script, true);
-	while (scumm_stricmp(_tokens[0], "endanimation")) {
-//		printf("token[0] = %s\n", _tokens[0]);
 
-		if (!scumm_stricmp(_tokens[0], "script")) {
-			loadProgram(vD0, _tokens[1]);
+DECLARE_ANIM_PARSER(type) {
+	if (_tokens[2][0] != '\0') {
+		_locAnimParseCtxt.a->_type = ((4 + _objectsNames->lookup(_tokens[2])) << 16) & 0xFFFF0000;
+	}
+	int16 _si = _zoneTypeNames->lookup(_tokens[1]);
+	if (_si != Table::notFound) {
+		_locAnimParseCtxt.a->_type |= 1 << (_si-1);
+		if (((_locAnimParseCtxt.a->_type & 0xFFFF) != kZoneNone) && ((_locAnimParseCtxt.a->_type & 0xFFFF) != kZoneCommand)) {
+			parseZoneTypeBlock(*_locAnimParseCtxt.script, _locAnimParseCtxt.a);
 		}
-		if (!scumm_stricmp(_tokens[0], "commands")) {
-			 parseCommands(script, vD0->_commands);
-		}
-		if (!scumm_stricmp(_tokens[0], "type")) {
-			if (_tokens[2][0] != '\0') {
-				vD0->_type = ((4 + _objectsNames->lookup(_tokens[2])) << 16) & 0xFFFF0000;
-			}
-			int16 _si = _zoneTypeNames->lookup(_tokens[1]);
-			if (_si != Table::notFound) {
-				vD0->_type |= 1 << (_si-1);
-				if (((vD0->_type & 0xFFFF) != kZoneNone) && ((vD0->_type & 0xFFFF) != kZoneCommand)) {
-					parseZoneTypeBlock(script, vD0);
-				}
-			}
-		}
-		if (!scumm_stricmp(_tokens[0], "label")) {
-			renderLabel(&vD0->_label._cnv, _tokens[1]);
-		}
-		if (!scumm_stricmp(_tokens[0], "flags")) {
-			uint16 _si = 1;
+	}
 
-			do {
-				byte _al = _zoneFlagNames->lookup(_tokens[_si]);
-				_si++;
-				vD0->_flags |= 1 << (_al - 1);
-			} while (!scumm_stricmp(_tokens[_si++], "|"));
+	_locAnimParseCtxt.end = true;
+}
+
+
+DECLARE_ANIM_PARSER(label) {
+	renderLabel(&_locAnimParseCtxt.a->_label._cnv, _tokens[1]);
+}
+
+
+DECLARE_ANIM_PARSER(flags) {
+	uint16 _si = 1;
+
+	do {
+		byte _al = _zoneFlagNames->lookup(_tokens[_si]);
+		_si++;
+		_locAnimParseCtxt.a->_flags |= 1 << (_al - 1);
+	} while (!scumm_stricmp(_tokens[_si++], "|"));
+}
+
+
+DECLARE_ANIM_PARSER(file) {
+	char vC8[200];
+	strcpy(vC8, _tokens[1]);
+	if (_engineFlags & kEngineTransformedDonna) {
+		if (!scumm_stricmp(_tokens[1], "donnap") || !scumm_stricmp(_tokens[1], "donnapa")) {
+			strcat(vC8, "tras");
 		}
-		if (!scumm_stricmp(_tokens[0], "file")) {
-			char vC8[200];
-			strcpy(vC8, _tokens[1]);
-			if (_engineFlags & kEngineTransformedDonna) {
-				if (!scumm_stricmp(_tokens[1], "donnap") || !scumm_stricmp(_tokens[1], "donnapa")) {
-					strcat(vC8, "tras");
-				}
-			}
-			vD0->_cnv = _disk->loadFrames(vC8);
-		}
-		if (!scumm_stricmp(_tokens[0], "position")) {
-			vD0->_left = atoi(_tokens[1]);
-			vD0->_top = atoi(_tokens[2]);
-			vD0->_z = atoi(_tokens[3]);
-		}
-		if (!scumm_stricmp(_tokens[0], "moveto")) {
-			vD0->_moveTo.x = atoi(_tokens[1]);
-			vD0->_moveTo.y = atoi(_tokens[2]);
-		}
+	}
+	_locAnimParseCtxt.a->_cnv = _disk->loadFrames(vC8);
+}
 
+
+DECLARE_ANIM_PARSER(position) {
+	_locAnimParseCtxt.a->_left = atoi(_tokens[1]);
+	_locAnimParseCtxt.a->_top = atoi(_tokens[2]);
+	_locAnimParseCtxt.a->_z = atoi(_tokens[3]);
+}
+
+
+DECLARE_ANIM_PARSER(moveto) {
+	_locAnimParseCtxt.a->_moveTo.x = atoi(_tokens[1]);
+	_locAnimParseCtxt.a->_moveTo.y = atoi(_tokens[2]);
+}
+
+
+DECLARE_ANIM_PARSER(endanimation) {
+	_locAnimParseCtxt.end = true;
+}
+
+Animation *Parallaction::parseAnimation(Script& script, AnimationList &list, char *name) {
+//	printf("parseAnimation(%s)\n", name);
+
+	Animation *a = new Animation;
+
+	a->_label._text = strdup(name);
+
+	list.push_front(a);
+
+	_locAnimParseCtxt.a = a;
+	_locAnimParseCtxt.end = false;
+	_locAnimParseCtxt.script = &script;
+
+	do {
 		fillBuffers(script, true);
-	}
 
-	vD0->_oldPos.x = -1000;
-	vD0->_oldPos.y = -1000;
+		int index = _locationAnimStmt->lookup(_tokens[0]);
+		(this->*_locationAnimParsers[index])();
 
-	vD0->_flags |= 0x1000000;
+	} while (!_locAnimParseCtxt.end);
 
-	return vD0;
+	a->_oldPos.x = -1000;
+	a->_oldPos.y = -1000;
+
+	a->_flags |= 0x1000000;
+
+	return a;
 }
 
 
@@ -690,6 +719,7 @@
 Animation::Animation() {
 	_cnv = NULL;
 	_program = NULL;
+	_scriptName = 0;
 	_frame = 0;
 	_z = 0;
 }
@@ -698,6 +728,9 @@
 	if (_program)
 		delete _program;
 
+	if (_scriptName)
+		free(_scriptName);
+
 	if (_cnv)
 		delete _cnv;
 }

Modified: scummvm/trunk/engines/parallaction/commands.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/commands.cpp	2007-08-16 07:47:13 UTC (rev 28636)
+++ scummvm/trunk/engines/parallaction/commands.cpp	2007-08-16 17:28:18 UTC (rev 28637)
@@ -47,7 +47,9 @@
 #define CMD_MOVE			15
 #define CMD_STOP			16
 
-DECLARE_COMMAND_PARSER(Flags) {
+DECLARE_COMMAND_PARSER(flags) {
+	createCommand(_lookup);
+
 	if (_globalTable->lookup(_tokens[1]) == Table::notFound) {
 		do {
 			char _al = _localFlagNames->lookup(_tokens[_cmdParseCtxt.nextToken]);
@@ -64,10 +66,15 @@
 		} while (!scumm_stricmp(_tokens[_cmdParseCtxt.nextToken++], "|"));
 		_cmdParseCtxt.nextToken--;
 	}
+
+	parseCommandFlags();
+	addCommand();
 }
 
 
-DECLARE_COMMAND_PARSER(Animation) {
+DECLARE_COMMAND_PARSER(animation) {
+	createCommand(_lookup);
+
 	_cmdParseCtxt.cmd->u._animation = findAnimation(_tokens[_cmdParseCtxt.nextToken]);
 	_cmdParseCtxt.nextToken++;
 	if (_cmdParseCtxt.cmd->u._animation == NULL) {
@@ -75,124 +82,170 @@
 		_forwardedCommands[_numForwards] = _cmdParseCtxt.cmd;
 		_numForwards++;
 	}
+
+	parseCommandFlags();
+	addCommand();
 }
 
 
-DECLARE_COMMAND_PARSER(Zone) {
+DECLARE_COMMAND_PARSER(zone) {
+	createCommand(_lookup);
+
 	_cmdParseCtxt.cmd->u._zone = findZone(_tokens[_cmdParseCtxt.nextToken]);
 	_cmdParseCtxt.nextToken++;
+
+	parseCommandFlags();
+	addCommand();
 }
 
 
-DECLARE_COMMAND_PARSER(Location) {
+DECLARE_COMMAND_PARSER(location) {
+	createCommand(_lookup);
+
 	_cmdParseCtxt.cmd->u._string = (char*)malloc(strlen(_tokens[_cmdParseCtxt.nextToken])+1);
 	strcpy(_cmdParseCtxt.cmd->u._string, _tokens[_cmdParseCtxt.nextToken]);
 	_cmdParseCtxt.nextToken++;
+
+	parseCommandFlags();
+	addCommand();
 }
 
 
-DECLARE_COMMAND_PARSER(Drop) {
+DECLARE_COMMAND_PARSER(drop) {
+	createCommand(_lookup);
+
 	_cmdParseCtxt.cmd->u._object = _objectsNames->lookup(_tokens[_cmdParseCtxt.nextToken]);
 	_cmdParseCtxt.nextToken++;
+
+	parseCommandFlags();
+	addCommand();
 }
 
 
-DECLARE_COMMAND_PARSER(Call) {
+DECLARE_COMMAND_PARSER(call) {
+	createCommand(_lookup);
+
 	_cmdParseCtxt.cmd->u._callable = _callableNames->lookup(_tokens[_cmdParseCtxt.nextToken]) - 1;
 	_cmdParseCtxt.nextToken++;
+
+	parseCommandFlags();
+	addCommand();
 }
 
 
-DECLARE_COMMAND_PARSER(Null) {
+DECLARE_COMMAND_PARSER(null) {
 }
 
 
-DECLARE_COMMAND_PARSER(Move) {
+DECLARE_COMMAND_PARSER(move) {
+	createCommand(_lookup);
+
 	_cmdParseCtxt.cmd->u._move._x = atoi(_tokens[_cmdParseCtxt.nextToken]);
 	_cmdParseCtxt.nextToken++;
 	_cmdParseCtxt.cmd->u._move._y = atoi(_tokens[_cmdParseCtxt.nextToken]);
 	_cmdParseCtxt.nextToken++;
+
+	parseCommandFlags();
+	addCommand();
 }
 
-DECLARE_COMMAND_PARSER(Invalid) {
+DECLARE_COMMAND_PARSER(invalid) {
 	error("Can't parse unknown command '%s'", _tokens[0]);
 }
 
-void Parallaction::parseCommands(Script &script, CommandList& list) {
+DECLARE_COMMAND_PARSER(endcommands) {
+	_cmdParseCtxt.end = true;
+}
 
-	fillBuffers(script, true);
+void Parallaction::parseCommandFlags() {
 
-	while (scumm_stricmp(_tokens[0], "ENDCOMMANDS") && scumm_stricmp(_tokens[0], "ENDZONE")) {
+	int _si = _cmdParseCtxt.nextToken;
+	Command *cmd = _cmdParseCtxt.cmd;
 
-		Command *cmd = new Command;
+	if (!scumm_stricmp(_tokens[_si], "flags")) {
+		_si++;
 
-		cmd->_id = _commandsNames->lookup(_tokens[0]);
+		do {
+			if (!scumm_stricmp(_tokens[_si], "exit") || !scumm_stricmp(_tokens[_si], "exittrap")) {
+				cmd->_flagsOn |= kFlagsExit;
+			} else
+			if (!scumm_stricmp(_tokens[_si], "enter") || !scumm_stricmp(_tokens[_si], "entertrap")) {
+				cmd->_flagsOn |= kFlagsEnter;
+			} else
+			if (!scumm_strnicmp(_tokens[_si], "no", 2)) {
+				byte _al = _localFlagNames->lookup(&_tokens[_si][2]);
+				cmd->_flagsOff |= 1 << (_al - 1);
+			} else {
+				byte _al = _localFlagNames->lookup(_tokens[_si]);
+				cmd->_flagsOn |= 1 << (_al - 1);
+			}
 
-		_cmdParseCtxt.nextToken = 1;
-		_cmdParseCtxt.cmd = cmd;
+			_si++;
 
-		(this->*_commandParsers[cmd->_id])();
+		} while (!scumm_stricmp(_tokens[_si++], "|"));
 
-		int _si = _cmdParseCtxt.nextToken;
+	}
 
-		if (!scumm_stricmp(_tokens[_si], "flags")) {
+	if (!scumm_stricmp(_tokens[_si], "gflags")) {
+		_si++;
+		cmd->_flagsOn |= kFlagsGlobal;
+
+		do {
+			if (!scumm_stricmp(_tokens[_si], "exit")) {
+				cmd->_flagsOn |= kFlagsExit;
+			} else
+			if (!scumm_stricmp(_tokens[_si], "enter")) {
+				cmd->_flagsOn |= kFlagsEnter;
+			} else
+			if (!scumm_strnicmp(_tokens[_si], "no", 2)) {
+				byte _al = _globalTable->lookup(&_tokens[_si][2]);
+				cmd->_flagsOff |= 1 << (_al - 1);
+			} else {
+				byte _al = _globalTable->lookup(_tokens[_si]);
+				cmd->_flagsOn |= 1 << (_al - 1);
+			}
+
 			_si++;
 
-			do {
-				if (!scumm_stricmp(_tokens[_si], "exit") || !scumm_stricmp(_tokens[_si], "exittrap")) {
-					cmd->_flagsOn |= kFlagsExit;
-				} else
-				if (!scumm_stricmp(_tokens[_si], "enter") || !scumm_stricmp(_tokens[_si], "entertrap")) {
-					cmd->_flagsOn |= kFlagsEnter;
-				} else
-				if (!scumm_strnicmp(_tokens[_si], "no", 2)) {
-					byte _al = _localFlagNames->lookup(&_tokens[_si][2]);
-					cmd->_flagsOff |= 1 << (_al - 1);
-				} else {
-					byte _al = _localFlagNames->lookup(_tokens[_si]);
-					cmd->_flagsOn |= 1 << (_al - 1);
-				}
+		} while (!scumm_stricmp(_tokens[_si++], "|"));
 
-				_si++;
+	}
 
-			} while (!scumm_stricmp(_tokens[_si++], "|"));
+	_si = _cmdParseCtxt.nextToken;
 
-		}
+}
 
-		if (!scumm_stricmp(_tokens[_si], "gflags")) {
-			_si++;
-			cmd->_flagsOn |= kFlagsGlobal;
+void Parallaction::addCommand() {
 
-			do {
-				if (!scumm_stricmp(_tokens[_si], "exit")) {
-					cmd->_flagsOn |= kFlagsExit;
-				} else
-				if (!scumm_stricmp(_tokens[_si], "enter")) {
-					cmd->_flagsOn |= kFlagsEnter;
-				} else
-				if (!scumm_strnicmp(_tokens[_si], "no", 2)) {
-					byte _al = _globalTable->lookup(&_tokens[_si][2]);
-					cmd->_flagsOff |= 1 << (_al - 1);
-				} else {
-					byte _al = _globalTable->lookup(_tokens[_si]);
-					cmd->_flagsOn |= 1 << (_al - 1);
-				}
+	// FIXME: implement a proper parseCommands for BRA
+	if (getGameType() == GType_BRA)
+		delete _cmdParseCtxt.cmd;
+	else
+		_cmdParseCtxt.list->push_front(_cmdParseCtxt.cmd);	// NOTE: command lists are written backwards in scripts
 
-				_si++;
+}
 
-			} while (!scumm_stricmp(_tokens[_si++], "|"));
+void Parallaction::createCommand(uint id) {
 
-		}
+	_cmdParseCtxt.nextToken = 1;
+	_cmdParseCtxt.cmd = new Command;
+	_cmdParseCtxt.cmd->_id = id;
 
-		// FIXME: implement a proper parseCommands for BRA
-		if (getGameType() == GType_BRA)
-			delete cmd;
-		else
-			list.push_front(cmd);	// NOTE: command lists are written backwards in scripts
+}
 
+void Parallaction::parseCommands(Script &script, CommandList& list) {
+
+	_cmdParseCtxt.list = &list;
+	_cmdParseCtxt.end = false;
+
+	do {
 		fillBuffers(script, true);
 
-	}
+		_lookup = _commandsNames->lookup(_tokens[0]);
+		(this->*_commandParsers[_lookup])();
+
+	} while (!_cmdParseCtxt.end);
+
 }
 
 DECLARE_COMMAND_OPCODE(invalid) {
@@ -220,7 +273,7 @@
 
 
 DECLARE_COMMAND_OPCODE(start) {
-	_cmdRunCtxt.cmd->u._zone->_flags |= kFlagsActing;
+	_cmdRunCtxt.cmd->u._animation->_flags |= kFlagsActing;
 }
 
 
@@ -319,7 +372,7 @@
 
 
 DECLARE_COMMAND_OPCODE(stop) {
-	_cmdRunCtxt.cmd->u._zone->_flags &= ~kFlagsActing;
+	_cmdRunCtxt.cmd->u._animation->_flags &= ~kFlagsActing;
 }
 
 
@@ -366,8 +419,6 @@
 
 Command::~Command() {
 
-	if (_id == CMD_LOCATION) free(u._string);
-
 }
 
 } // namespace Parallaction

Modified: scummvm/trunk/engines/parallaction/commands.h
===================================================================
--- scummvm/trunk/engines/parallaction/commands.h	2007-08-16 07:47:13 UTC (rev 28636)
+++ scummvm/trunk/engines/parallaction/commands.h	2007-08-16 17:28:18 UTC (rev 28637)
@@ -46,7 +46,7 @@
 
 
 // TODO: turn this into a struct
-union CommandData {
+struct CommandData {
 	uint32			_flags;
 	Animation * 	_animation;
 	Zone*			_zone;
@@ -60,9 +60,18 @@
 
 	CommandData() {
 		_flags = 0;
+		_animation = 0;
+		_zone = 0;
+		_string = 0;
+		_callable = 0;
+		_object = 0;
+		_move._x = 0;
+		_move._y = 0;
 	}
 
 	~CommandData() {
+		if (_string)
+			free(_string);
 	}
 };
 

Modified: scummvm/trunk/engines/parallaction/dialogue.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/dialogue.cpp	2007-08-16 07:47:13 UTC (rev 28636)
+++ scummvm/trunk/engines/parallaction/dialogue.cpp	2007-08-16 17:28:18 UTC (rev 28637)
@@ -179,11 +179,7 @@
 
 	vD0[strlen(vD0)-1] = '\0';	// deletes the trailing '0xA'
 								// this is critical for Gfx::displayWrappedString to work properly
-
-	char *vCC = (char*)malloc(strlen(vD0)+1);
-	strcpy(vCC, vD0);
-
-	return vCC;
+	return strdup(vD0);
 }
 
 class DialogueManager {

Modified: scummvm/trunk/engines/parallaction/location.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/location.cpp	2007-08-16 07:47:13 UTC (rev 28636)
+++ scummvm/trunk/engines/parallaction/location.cpp	2007-08-16 17:28:18 UTC (rev 28637)
@@ -148,17 +148,46 @@
 		_soundMan->setMusicFile(_tokens[1]);
 }
 
+DECLARE_LOCATION_PARSER(redundant) {
+	warning("redundant '%s' line found in script '%s'", _tokens[0], _locParseCtxt.filename);
+}
 
 
-
 void Parallaction::parseLocation(const char *filename) {
     debugC(1, kDebugLocation, "parseLocation('%s')", filename);
 
-	_gfx->setFont(_labelFont);
+	allocateLocationSlot(filename);
 
 	Script *script = _disk->loadLocation(filename);
+
+	// TODO: the following two lines are specific to Nippon Safes
+	// and should be moved into something like 'initializeParsing()'
+	_gfx->setFont(_labelFont);
 	_hasLocationSound = false;
 
+	_locParseCtxt.end = false;;
+	_locParseCtxt.script = script;
+	_locParseCtxt.filename = filename;
+
+
+	do {
+
+		fillBuffers(*script, true);
+
+		int index = _locationStmt->lookup(_tokens[0]);
+		(this->*_locationParsers[index])();
+
+	} while (!_locParseCtxt.end);
+
+
+	delete script;
+
+	finalizeLocationParsing();
+
+	return;
+}
+
+void Parallaction::allocateLocationSlot(const char *name) {
 	// WORKAROUND: the original code erroneously incremented
 	// _currentLocationIndex, thus producing inconsistent
 	// savegames. This workaround modified the following loop
@@ -167,14 +196,17 @@
 	_currentLocationIndex = -1;
 	uint16 _di = 0;
 	while (_locationNames[_di][0] != '\0') {
-		if (!scumm_stricmp(_locationNames[_di], filename)) {
+		if (!scumm_stricmp(_locationNames[_di], name)) {
 			_currentLocationIndex = _di;
 		}
 		_di++;
 	}
 
+	if (_di == 120)
+		error("No more location slots available. Please report this immediately to ScummVM team.");
+
 	if (_currentLocationIndex  == -1) {
-		strcpy(_locationNames[_numLocations], filename);
+		strcpy(_locationNames[_numLocations], name);
 		_currentLocationIndex = _numLocations;
 
 		_numLocations++;
@@ -183,41 +215,24 @@
 	} else {
 		_localFlags[_currentLocationIndex] |= kFlagsVisited;	// 'visited'
 	}
-
-	_locParseCtxt.end = false;;
-	_locParseCtxt.script = script;
-	_locParseCtxt.filename = filename;
-
-	fillBuffers(*script, true);
-
-	int index;
-	while (true) {
-
-		index = _locationStmt->lookup(_tokens[0]);
-
-		(this->*_locationParsers[index])();
-
-		if (_locParseCtxt.end)
-			break;
-
-		fillBuffers(*script, true);
-	}
-
-	resolveLocationForwards();
-
-	delete script;
-
-	return;
 }
 
-void Parallaction::resolveLocationForwards() {
+void Parallaction::finalizeLocationParsing() {
 
+	// this resolves any forward references in the script
 	for (uint16 _si = 0; _forwardedCommands[_si]; _si++) {
 		_forwardedCommands[_si]->u._animation = findAnimation(_forwardedAnimationNames[_si]);
 		_forwardedCommands[_si] = NULL;
 	}
+	_numForwards = 0;
 
-	_numForwards = 0;
+	// this loads animation scripts
+	AnimationList::iterator it = _animations.begin();
+	for ( ; it != _animations.end(); it++) {
+		if ((*it)->_scriptName)
+			loadProgram(*it, (*it)->_scriptName);
+	}
+
 	return;
 }
 

Modified: scummvm/trunk/engines/parallaction/parallaction.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.cpp	2007-08-16 07:47:13 UTC (rev 28636)
+++ scummvm/trunk/engines/parallaction/parallaction.cpp	2007-08-16 17:28:18 UTC (rev 28637)
@@ -902,23 +902,25 @@
 	_vm->_instructionOpcodes = op1;
 
 	static const Opcode op2[] = {
-		COMMAND_PARSER(Invalid),
-		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
+		COMMAND_PARSER(invalid),
+		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
+		COMMAND_PARSER(endcommands),	// endcommands
+		COMMAND_PARSER(endcommands)		// endzone
 	};
 
 	_commandParsers = op2;
@@ -961,12 +963,41 @@
 		LOCATION_PARSER(comment),
 		LOCATION_PARSER(endcomment),
 		LOCATION_PARSER(sound),
-		LOCATION_PARSER(music)
+		LOCATION_PARSER(music),
+		LOCATION_PARSER(redundant)	// for redundant endanimation
 	};
 
 	_locationParsers = op4;
 
 
+	static const Opcode op5[] = {
+		ZONE_PARSER(invalid),
+		ZONE_PARSER(limits),
+		ZONE_PARSER(moveto),
+		ZONE_PARSER(type),
+		ZONE_PARSER(commands),
+		ZONE_PARSER(label),
+		ZONE_PARSER(flags),
+		ZONE_PARSER(endzone)
+	};
+
+	_locationZoneParsers = op5;
+
+	static const Opcode op6[] = {
+		ANIM_PARSER(invalid),
+		ANIM_PARSER(script),
+		ANIM_PARSER(commands),
+		ANIM_PARSER(type),
+		ANIM_PARSER(label),
+		ANIM_PARSER(flags),
+		ANIM_PARSER(file),
+		ANIM_PARSER(position),
+		ANIM_PARSER(moveto),
+		ANIM_PARSER(endanimation)
+	};
+
+	_locationAnimParsers = op6;
+
 }
 
 } // namespace Parallaction

Modified: scummvm/trunk/engines/parallaction/parallaction.h
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.h	2007-08-16 07:47:13 UTC (rev 28636)
+++ scummvm/trunk/engines/parallaction/parallaction.h	2007-08-16 17:28:18 UTC (rev 28637)
@@ -296,6 +296,14 @@
 };
 
 
+#define DECLARE_ZONE_PARSER(sig) void Parallaction::locZoneParse_##sig()
+#define DECLARE_UNQUALIFIED_ZONE_PARSER(sig) void locZoneParse_##sig()
+#define ZONE_PARSER(sig) &Parallaction::locZoneParse_##sig
+
+#define DECLARE_ANIM_PARSER(sig) void Parallaction::locAnimParse_##sig()
+#define DECLARE_UNQUALIFIED_ANIM_PARSER(sig) void locAnimParse_##sig()
+#define ANIM_PARSER(sig) &Parallaction::locAnimParse_##sig
+
 #define DECLARE_COMMAND_PARSER(sig) void Parallaction::cmdParse_##sig()
 #define DECLARE_UNQUALIFIED_COMMAND_PARSER(sig) void cmdParse_##sig()
 #define COMMAND_PARSER(sig) &Parallaction::cmdParse_##sig
@@ -338,20 +346,25 @@
 	typedef void (Parallaction::*Opcode)();
 	const Opcode	*_commandParsers;
 
+	uint	_lookup;
+
 	struct {
 		Command	*cmd;
 		int		nextToken;
+		CommandList *list;
+		bool	end;
 	} _cmdParseCtxt;
 
-	DECLARE_UNQUALIFIED_COMMAND_PARSER(Invalid);
-	DECLARE_UNQUALIFIED_COMMAND_PARSER(Flags);
-	DECLARE_UNQUALIFIED_COMMAND_PARSER(Animation);
-	DECLARE_UNQUALIFIED_COMMAND_PARSER(Zone);
-	DECLARE_UNQUALIFIED_COMMAND_PARSER(Location);
-	DECLARE_UNQUALIFIED_COMMAND_PARSER(Drop);
-	DECLARE_UNQUALIFIED_COMMAND_PARSER(Call);
-	DECLARE_UNQUALIFIED_COMMAND_PARSER(Null);
-	DECLARE_UNQUALIFIED_COMMAND_PARSER(Move);
+	DECLARE_UNQUALIFIED_COMMAND_PARSER(invalid);
+	DECLARE_UNQUALIFIED_COMMAND_PARSER(flags);
+	DECLARE_UNQUALIFIED_COMMAND_PARSER(animation);
+	DECLARE_UNQUALIFIED_COMMAND_PARSER(zone);
+	DECLARE_UNQUALIFIED_COMMAND_PARSER(location);
+	DECLARE_UNQUALIFIED_COMMAND_PARSER(drop);
+	DECLARE_UNQUALIFIED_COMMAND_PARSER(call);
+	DECLARE_UNQUALIFIED_COMMAND_PARSER(null);
+	DECLARE_UNQUALIFIED_COMMAND_PARSER(move);
+	DECLARE_UNQUALIFIED_COMMAND_PARSER(endcommands);
 
 	const Opcode	*_commandOpcodes;
 
@@ -434,6 +447,7 @@
 		const char	*filename;
 		bool	end;
 		Script	*script;
+		Zone *z;
 	} _locParseCtxt;
 
 	DECLARE_UNQUALIFIED_LOCATION_PARSER(invalid);
@@ -451,7 +465,44 @@
 	DECLARE_UNQUALIFIED_LOCATION_PARSER(endcomment);
 	DECLARE_UNQUALIFIED_LOCATION_PARSER(sound);
 	DECLARE_UNQUALIFIED_LOCATION_PARSER(music);
+	DECLARE_UNQUALIFIED_LOCATION_PARSER(redundant);
 
+	const Opcode  *_locationZoneParsers;
+
+	struct {
+		bool	end;
+		Script	*script;
+		Zone *z;
+	} _locZoneParseCtxt;
+
+	DECLARE_UNQUALIFIED_ZONE_PARSER(invalid);
+	DECLARE_UNQUALIFIED_ZONE_PARSER(limits);
+	DECLARE_UNQUALIFIED_ZONE_PARSER(moveto);
+	DECLARE_UNQUALIFIED_ZONE_PARSER(type);
+	DECLARE_UNQUALIFIED_ZONE_PARSER(commands);
+	DECLARE_UNQUALIFIED_ZONE_PARSER(label);
+	DECLARE_UNQUALIFIED_ZONE_PARSER(flags);
+	DECLARE_UNQUALIFIED_ZONE_PARSER(endzone);
+
+	const Opcode  *_locationAnimParsers;
+
+	struct {
+		bool	end;
+		Script	*script;
+		Animation *a;
+	} _locAnimParseCtxt;
+
+	DECLARE_UNQUALIFIED_ANIM_PARSER(invalid);
+	DECLARE_UNQUALIFIED_ANIM_PARSER(script);
+	DECLARE_UNQUALIFIED_ANIM_PARSER(commands);
+	DECLARE_UNQUALIFIED_ANIM_PARSER(type);
+	DECLARE_UNQUALIFIED_ANIM_PARSER(label);
+	DECLARE_UNQUALIFIED_ANIM_PARSER(flags);
+	DECLARE_UNQUALIFIED_ANIM_PARSER(file);
+	DECLARE_UNQUALIFIED_ANIM_PARSER(position);
+	DECLARE_UNQUALIFIED_ANIM_PARSER(moveto);
+	DECLARE_UNQUALIFIED_ANIM_PARSER(endanimation);
+
 	void 		changeCursor(int32 index);
 	void		showCursor(bool visible);
 	void 		changeCharacter(const char *name);
@@ -496,10 +547,10 @@
 	Table		*_instructionNames;
 	Table		*_localFlagNames;
 	Table		*_locationStmt;
+	Table		*_locationZoneStmt;
+	Table		*_locationAnimStmt;
 
 
-
-
 public:
 	int getGameType() const;
 	uint32 getFeatures() const;
@@ -597,7 +648,8 @@
 
 	void		doLocationEnterTransition();
 	void		changeLocation(char *location);
-	void 		resolveLocationForwards();
+	void		allocateLocationSlot(const char *name);
+	void 		finalizeLocationParsing();
 	void 		switchBackground(const char* background, const char* mask);
 	void 		freeLocation();
 	void 		showLocationComment(const char *text, bool end);
@@ -616,6 +668,9 @@
 	LValue		getLValue(Instruction *inst, char *str, LocalVariable *locals, Animation *a);
 
 	void		parseCommands(Script &script, CommandList&);
+	void		parseCommandFlags();
+	void		createCommand(uint id);
+	void		addCommand();
 
 	void 		freeCharacter();
 

Modified: scummvm/trunk/engines/parallaction/parser.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parser.cpp	2007-08-16 07:47:13 UTC (rev 28636)
+++ scummvm/trunk/engines/parallaction/parser.cpp	2007-08-16 17:28:18 UTC (rev 28637)
@@ -103,8 +103,7 @@
 		strcat(_tmp_comment, " ");
 	} while (true);
 
-	v194 = (char*)malloc(strlen(_tmp_comment)+1);
-	strcpy(v194, _tmp_comment);
+	v194 = strdup(_tmp_comment);
 	_tmp_comment[0] = '\0';
 
 	return v194;

Modified: scummvm/trunk/engines/parallaction/staticres.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/staticres.cpp	2007-08-16 07:47:13 UTC (rev 28636)
+++ scummvm/trunk/engines/parallaction/staticres.cpp	2007-08-16 17:28:18 UTC (rev 28637)
@@ -278,7 +278,9 @@
 	"drop",
 	"quit",
 	"move",
-	"stop"
+	"stop",
+	"endcommands",
+	"endzone"
 };
 
 const char *_instructionNamesRes_ns[] = {
@@ -344,9 +346,32 @@
 	"comment",
 	"endcomment",
 	"sound",
-	"music"
+	"music",
+	"endanimation"
 };
 
+const char *_locationZoneStmtRes_ns[] = {
+	"limits",
+	"moveto",
+	"type",
+	"commands",
+	"label",
+	"flags",
+	"endzone"
+};
+
+const char *_locationAnimStmtRes_ns[] = {
+	"script",
+	"commands",
+	"type",
+	"label",
+	"flags",
+	"file",
+	"position",
+	"moveto",
+	"endanimation"
+};
+
 const char *_zoneTypeNamesRes_br[] = {
 	"examine",
 	"door",
@@ -582,6 +607,8 @@
 	_zoneTypeNames = new Table(ARRAYSIZE(_zoneTypeNamesRes_ns), _zoneTypeNamesRes_ns);
 	_commandsNames = new Table(ARRAYSIZE(_commandsNamesRes_ns), _commandsNamesRes_ns);
 	_locationStmt = new Table(ARRAYSIZE(_locationStmtRes_ns), _locationStmtRes_ns);
+	_locationZoneStmt = new Table(ARRAYSIZE(_locationZoneStmtRes_ns), _locationZoneStmtRes_ns);
+	_locationAnimStmt = new Table(ARRAYSIZE(_locationAnimStmtRes_ns), _locationAnimStmtRes_ns);
 
 	_localFlagNames = new Table(120);
 	_localFlagNames->addData("visited");

Modified: scummvm/trunk/engines/parallaction/zone.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/zone.cpp	2007-08-16 07:47:13 UTC (rev 28636)
+++ scummvm/trunk/engines/parallaction/zone.cpp	2007-08-16 17:28:18 UTC (rev 28637)
@@ -36,17 +36,72 @@
 
 Zone *Parallaction::findZone(const char *name) {
 
-	for (ZoneList::iterator it = _zones.begin(); it != _zones.end(); it++)
+	for (ZoneList::iterator it = _zones.begin(); it != _zones.end(); it++) {
 		if (!scumm_stricmp((*it)->_label._text, name)) return *it;
+	}
 
 	return findAnimation(name);
 }
 
+DECLARE_ZONE_PARSER(invalid) {
+	error("unknown statement '%s' in zone %s", _tokens[0], _locZoneParseCtxt.z->_label._text);
+}
 
+DECLARE_ZONE_PARSER(endzone) {
+	_locZoneParseCtxt.end = true;
+}
 
+DECLARE_ZONE_PARSER(limits) {
+	_locZoneParseCtxt.z->_left = atoi(_tokens[1]);
+	_locZoneParseCtxt.z->_top = atoi(_tokens[2]);
+	_locZoneParseCtxt.z->_right = atoi(_tokens[3]);
+	_locZoneParseCtxt.z->_bottom = atoi(_tokens[4]);
+}
 
+
+DECLARE_ZONE_PARSER(moveto) {
+	_locZoneParseCtxt.z->_moveTo.x = atoi(_tokens[1]);
+	_locZoneParseCtxt.z->_moveTo.y = atoi(_tokens[2]);
+}
+
+
+DECLARE_ZONE_PARSER(type) {
+	if (_tokens[2][0] != '\0') {
+		_locZoneParseCtxt.z->_type = (4 + _objectsNames->lookup(_tokens[2])) << 16;
+	}
+	int16 _si = _zoneTypeNames->lookup(_tokens[1]);
+	if (_si != Table::notFound) {
+		_locZoneParseCtxt.z->_type |= 1 << (_si - 1);
+		parseZoneTypeBlock(*_locZoneParseCtxt.script, _locZoneParseCtxt.z);
+	}
+
+	_locZoneParseCtxt.end = true;
+}
+
+
+DECLARE_ZONE_PARSER(commands) {
+	 parseCommands(*_locZoneParseCtxt.script, _locZoneParseCtxt.z->_commands);
+}
+
+
+DECLARE_ZONE_PARSER(label) {
+//			printf("label: %s", _tokens[1]);
+	renderLabel(&_locZoneParseCtxt.z->_label._cnv, _tokens[1]);
+}
+
+
+DECLARE_ZONE_PARSER(flags) {
+	uint16 _si = 1;
+
+	do {
+		char _al = _zoneFlagNames->lookup(_tokens[_si]);
+		_si++;
+		_locZoneParseCtxt.z->_flags |= 1 << (_al - 1);
+	} while (!scumm_stricmp(_tokens[_si++], "|"));
+}
+
 void Parallaction::parseZone(Script &script, ZoneList &list, char *name) {
-//	printf("parseZone(%s)", name);
+	printf("parseZone(%s)\n", name);
 
 	if (findZone(name)) {
 		while (scumm_stricmp(_tokens[0], "endzone")) {
@@ -57,55 +112,22 @@
 
 	Zone *z = new Zone;
 
-	z->_label._text = (char*)malloc(strlen(name)+1);
-	strcpy(z->_label._text, name);
+	z->_label._text = strdup(name);
 
+	_locZoneParseCtxt.z = z;
+	_locZoneParseCtxt.end = false;
+	_locZoneParseCtxt.script = &script;
+
 	list.push_front(z);
 
-	fillBuffers(script, true);
-	while (scumm_stricmp(_tokens[0], "endzone")) {
-//		printf("token[0] = %s", _tokens[0]);
+	do {
 
-		if (!scumm_stricmp(_tokens[0], "limits")) {
-			z->_left = atoi(_tokens[1]);
-			z->_top = atoi(_tokens[2]);
-			z->_right = atoi(_tokens[3]);
-			z->_bottom = atoi(_tokens[4]);
-		}
-		if (!scumm_stricmp(_tokens[0], "moveto")) {
-			z->_moveTo.x = atoi(_tokens[1]);
-			z->_moveTo.y = atoi(_tokens[2]);
-		}
-		if (!scumm_stricmp(_tokens[0], "type")) {
-			if (_tokens[2][0] != '\0') {
-				z->_type = (4 + _objectsNames->lookup(_tokens[2])) << 16;
-			}
-			int16 _si = _zoneTypeNames->lookup(_tokens[1]);
-			if (_si != Table::notFound) {
-				z->_type |= 1 << (_si - 1);
-				parseZoneTypeBlock(script, z);
-				continue;
-			}
-		}
-		if (!scumm_stricmp(_tokens[0], "commands")) {
-			 parseCommands(script, z->_commands);
-		}
-		if (!scumm_stricmp(_tokens[0], "label")) {
-//			printf("label: %s", _tokens[1]);
-			renderLabel(&z->_label._cnv, _tokens[1]);
-		}
-		if (!scumm_stricmp(_tokens[0], "flags")) {
-			uint16 _si = 1;
+		fillBuffers(script, true);
 
-			do {
-				char _al = _zoneFlagNames->lookup(_tokens[_si]);
-				_si++;
-				z->_flags |= 1 << (_al - 1);
-			} while (!scumm_stricmp(_tokens[_si++], "|"));
-		}
+		int index = _locationZoneStmt->lookup(_tokens[0]);
+		(this->*_locationZoneParsers[index])();
 
-		fillBuffers(script, true);
-	}
+	} while (!_locZoneParseCtxt.end);
 
 	return;
 }
@@ -191,8 +213,7 @@
 		switch (z->_type & 0xFFFF) {
 		case kZoneExamine: // examine Zone init
 			if (!scumm_stricmp(_tokens[0], "file")) {
-				u->examine->_filename = (char*)malloc(strlen(_tokens[1])+1);
-				strcpy(u->examine->_filename, _tokens[1]);
+				u->examine->_filename = strdup(_tokens[1]);
 			}
 			if (!scumm_stricmp(_tokens[0], "desc")) {
 				u->examine->_description = parseComment(script);
@@ -207,8 +228,7 @@
 			}
 
 			if (!scumm_stricmp(_tokens[0], "location")) {
-				u->door->_location = (char*)malloc(strlen(_tokens[1])+1);
-				strcpy(u->door->_location, _tokens[1]);
+				u->door->_location = strdup(_tokens[1]);
 			}
 
 			if (!scumm_stricmp(_tokens[0], "file")) {

Modified: scummvm/trunk/engines/parallaction/zone.h
===================================================================
--- scummvm/trunk/engines/parallaction/zone.h	2007-08-16 07:47:13 UTC (rev 28636)
+++ scummvm/trunk/engines/parallaction/zone.h	2007-08-16 17:28:18 UTC (rev 28637)
@@ -297,6 +297,7 @@
 	Common::Point	_oldPos;
 	Program 	*_program;
 	Cnv 		*_cnv;
+	char		*_scriptName;
 	int16		_frame;
 	uint16		field_50;		// unused
 	int16		_z;


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