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

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Fri Aug 24 22:14:51 CEST 2007


Revision: 28711
          http://scummvm.svn.sourceforge.net/scummvm/?rev=28711&view=rev
Author:   peres001
Date:     2007-08-24 13:14:51 -0700 (Fri, 24 Aug 2007)

Log Message:
-----------
First step in restructuring engine code:
- code has been consolidated in fewer files
- new table-driven parsers/execution
- some functions has been pushed down the engine hierarchy
- Parallaction_br now inherits from Parallaction_ns

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/dialogue.cpp
    scummvm/trunk/engines/parallaction/disk_br.cpp
    scummvm/trunk/engines/parallaction/font.cpp
    scummvm/trunk/engines/parallaction/inventory.cpp
    scummvm/trunk/engines/parallaction/module.mk
    scummvm/trunk/engines/parallaction/parallaction.cpp
    scummvm/trunk/engines/parallaction/parallaction.h
    scummvm/trunk/engines/parallaction/parallaction_br.cpp
    scummvm/trunk/engines/parallaction/parallaction_ns.cpp
    scummvm/trunk/engines/parallaction/parser.cpp
    scummvm/trunk/engines/parallaction/parser.h
    scummvm/trunk/engines/parallaction/staticres.cpp

Added Paths:
-----------
    scummvm/trunk/engines/parallaction/exec_ns.cpp
    scummvm/trunk/engines/parallaction/objects.cpp
    scummvm/trunk/engines/parallaction/objects.h
    scummvm/trunk/engines/parallaction/parser_ns.cpp

Removed Paths:
-------------
    scummvm/trunk/engines/parallaction/animation.cpp
    scummvm/trunk/engines/parallaction/commands.cpp
    scummvm/trunk/engines/parallaction/commands.h
    scummvm/trunk/engines/parallaction/location.cpp
    scummvm/trunk/engines/parallaction/zone.cpp
    scummvm/trunk/engines/parallaction/zone.h

Deleted: scummvm/trunk/engines/parallaction/animation.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/animation.cpp	2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/animation.cpp	2007-08-24 20:14:51 UTC (rev 28711)
@@ -1,769 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "parallaction/parallaction.h"
-
-
-namespace Parallaction {
-
-
-#define INST_ON 						1
-#define INST_OFF						2
-#define INST_X							3
-#define INST_Y							4
-#define INST_Z							5
-#define INST_F							6
-#define INST_LOOP						7
-#define INST_ENDLOOP					8
-#define INST_SHOW						9
-#define INST_INC						10
-#define INST_DEC						11
-#define INST_SET						12
-#define INST_PUT						13
-#define INST_CALL						14
-#define INST_WAIT						15
-#define INST_START						16
-#define INST_SOUND						17
-#define INST_MOVE						18
-#define INST_END						19
-
-
-void	wrapLocalVar(LocalVariable *local);
-
-
-#define NUM_LOCALS	10
-
-uint16	_numLocals = 0;
-char	_localNames[NUM_LOCALS][10];
-
-Animation *Parallaction::findAnimation(const char *name) {
-
-	for (AnimationList::iterator it = _animations.begin(); it != _animations.end(); it++)
-		if (!scumm_stricmp((*it)->_label._text, name)) return *it;
-
-	return NULL;
-}
-
-DECLARE_ANIM_PARSER(invalid) {
-	error("unknown statement '%s' in animation %s", _tokens[0], _locAnimParseCtxt.a->_label._text);
-}
-
-
-DECLARE_ANIM_PARSER(script) {
-	_locAnimParseCtxt.a->_scriptName = strdup(_tokens[1]);
-}
-
-
-DECLARE_ANIM_PARSER(commands) {
-	 parseCommands(*_locAnimParseCtxt.script, _locAnimParseCtxt.a->_commands);
-}
-
-
-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);
-		}
-	}
-
-	_locAnimParseCtxt.a->_oldPos.x = -1000;
-	_locAnimParseCtxt.a->_oldPos.y = -1000;
-
-	_locAnimParseCtxt.a->_flags |= 0x1000000;
-
-	popParserTables();
-}
-
-
-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");
-		}
-	}
-	_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.a->_oldPos.x = -1000;
-	_locAnimParseCtxt.a->_oldPos.y = -1000;
-
-	_locAnimParseCtxt.a->_flags |= 0x1000000;
-
-	popParserTables();
-}
-
-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;
-
-	pushParserTables(_locationAnimParsers, _locationAnimStmt);
-
-	return a;
-}
-
-
-void Parallaction::freeAnimations() {
-	_animations.clear();
-	return;
-}
-
-
-
-void jobDisplayAnimations(void *parm, Job *j) {
-//	printf("jobDisplayAnimations()...\n");
-
-	Graphics::Surface v14;
-
-	uint16 _si = 0;
-
-	for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
-
-		Animation *v18 = *it;
-
-		if ((v18->_flags & kFlagsActive) && ((v18->_flags & kFlagsRemove) == 0))   {
-			v14.w = v18->width();
-			v14.h = v18->height();
-
-			int16 frame = CLIP((int)v18->_frame, 0, v18->getFrameNum()-1);
-
-			v14.pixels = v18->getFrameData(frame);
-
-			if (v18->_flags & kFlagsNoMasked)
-				_si = 3;
-			else
-				_si = _vm->_gfx->queryMask(v18->_top + v18->height());
-
-			debugC(9, kDebugLocation, "jobDisplayAnimations(%s, x:%i, y:%i, z:%i, w:%i, h:%i, f:%i/%i, %p)", v18->_label._text, v18->_left, v18->_top, _si, v14.w, v14.h,
-				frame, v18->getFrameNum(), v14.pixels);
-			_vm->_gfx->blitCnv(&v14, v18->_left, v18->_top, _si, Gfx::kBitBack);
-
-		}
-
-		if (((v18->_flags & kFlagsActive) == 0) && (v18->_flags & kFlagsRemove))   {
-			v18->_flags &= ~kFlagsRemove;
-			v18->_oldPos.x = -1000;
-		}
-
-		if ((v18->_flags & kFlagsActive) && (v18->_flags & kFlagsRemove))	{
-			v18->_flags &= ~kFlagsActive;
-			v18->_flags |= kFlagsRemove;
-		}
-
-	}
-
-//	  printf("done\n");
-
-	return;
-}
-
-
-void jobEraseAnimations(void *arg_0, Job *j) {
-	debugC(3, kDebugJobs, "jobEraseAnimations");
-
-	for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
-
-		Animation *a = *it;
-
-		if (((a->_flags & kFlagsActive) == 0) && ((a->_flags & kFlagsRemove) == 0)) continue;
-
-		Common::Rect r(a->width(), a->height());
-		r.moveTo(a->_oldPos);
-		_vm->_gfx->restoreBackground(r);
-
-		if (arg_0) {
-			a->_oldPos.x = a->_left;
-			a->_oldPos.y = a->_top;
-		}
-
-	}
-
-//	printf("done\n");
-
-	return;
-}
-
-
-void Parallaction::loadProgram(Animation *a, char *filename) {
-//	printf("loadProgram(%s)\n", filename);
-
-	Script *script = _disk->loadScript(filename);
-
-	_numLocals = 0;
-
-	fillBuffers(*script);
-
-	a->_program = new Program;
-
-	Instruction *vCC = new Instruction;
-
-	while (scumm_stricmp(_tokens[0], "endscript")) {
-		parseScriptLine(vCC, a, a->_program->_locals);
-		a->_program->_instructions.push_back(vCC);
-		vCC = new Instruction;
-		fillBuffers(*script);
-	}
-
-	// 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;
-
-	return;
-}
-
-int16 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 addLocal(const char *name, LocalVariable *locals, int16 value = 0, int16 min = -10000, int16 max = 10000) {
-	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;
-	} else {
-		_instParseCtxt.inst->_opBase._a = findAnimation(_tokens[1]);
-	}
-}
-
-
-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);
-	}
-
-	_instParseCtxt.inst->_opB = getLValue(_instParseCtxt.inst, _tokens[2], _instParseCtxt.locals, _instParseCtxt.a);
-
-	if (!scumm_stricmp(_tokens[3], "mod")) {
-		_instParseCtxt.inst->_flags |= kInstMod;
-	}
-}
-
-
-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);
-	}
-
-	_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);
-}
-
-
-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);
-}
-
-
-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]);
-	}
-
-	_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;
-	}
-}
-
-
-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;
-}
-
-
-DECLARE_INSTRUCTION_PARSER(sound) {
-	_instParseCtxt.inst->_opBase._z = findZone(_tokens[1]);
-}
-
-
-DECLARE_INSTRUCTION_PARSER(null) {
-
-}
-
-
-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);
-	}
-
-	_instParseCtxt.inst->_opA._local = &_instParseCtxt.locals[index];
-	_instParseCtxt.inst->_opB._value = _instParseCtxt.locals[index]._value;
-
-	_instParseCtxt.inst->_flags = kInstUsesLiteral | kInstUsesLocal;
-	_instParseCtxt.inst->_index = INST_SET;
-}
-
-
-
-
-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]);
-	}
-
-	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;
-}
-
-LValue Parallaction::getLValue(Instruction *inst, char *str, LocalVariable *locals, Animation *a) {
-
-	LValue v;
-
-	v._pvalue = 0;	// should stop compiler from complaining
-
-	if (isdigit(str[0]) || str[0] == '-') {
-		inst->_flags |= kInstUsesLiteral;
-		v._value = atoi(str);
-		return v;
-	}
-
-	int index = findLocal(str, locals);
-	if (index != -1) {
-		v._local = &locals[index];
-		return v;
-	}
-
-	if (str[1] == '.') {
-		a = findAnimation(&str[2]);
-	}
-
-	if (str[0] == 'X') {
-		v._pvalue = &a->_left;
-	} else
-	if (str[0] == 'Y') {
-		v._pvalue = &a->_top;
-	} else
-	if (str[0] == 'Z') {
-		v._pvalue = &a->_z;
-	} else
-	if (str[0] == 'F') {
-		v._pvalue = &a->_frame;
-	}
-
-	return v;
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(on) {
-	(*_instRunCtxt.inst)->_opBase._a->_flags |= kFlagsActive;
-	(*_instRunCtxt.inst)->_opBase._a->_flags &= ~kFlagsRemove;
-}
-
-
-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);
-
-	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);
-	}
-}
-
-DECLARE_INSTRUCTION_OPCODE(null) {
-
-}
-
-DECLARE_INSTRUCTION_OPCODE(invalid) {
-	error("Can't execute invalid opcode %i", (*_instRunCtxt.inst)->_index);
-}
-
-DECLARE_INSTRUCTION_OPCODE(call) {
-	callFunction((*_instRunCtxt.inst)->_opBase._index, 0);
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(wait) {
-	if (_engineFlags & kEngineWalking)
-		_instRunCtxt.suspend = true;
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(start) {
-//				v1C = (*_instRunCtxt.inst)->_opBase;
-	(*_instRunCtxt.inst)->_opBase._a->_flags |= (kFlagsActing | kFlagsActive);
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(sound) {
-	_activeZone = (*_instRunCtxt.inst)->_opBase._z;
-}
-
-
-DECLARE_INSTRUCTION_OPCODE(move) {
-	WalkNodeList *v4 = _char._builder.buildPath(*(*_instRunCtxt.inst)->_opA._pvalue, *(*_instRunCtxt.inst)->_opB._pvalue);
-	addJob(&jobWalk, v4, kPriority19 );
-	_engineFlags |= kEngineWalking;
-}
-
-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();
-
-	_instRunCtxt.suspend = true;
-}
-
-
-
-void jobRunScripts(void *parm, Job *j) {
-	debugC(3, kDebugJobs, "jobRunScripts");
-
-	static uint16 modCounter = 0;
-
-	for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
-
-		Animation *a = *it;
-
-		if (a->_flags & kFlagsCharacter) a->_z = a->_top + a->height();
-
-		if ((a->_flags & kFlagsActing) == 0) continue;
-		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]);
-
-			_vm->_instRunCtxt.inst = inst;
-			_vm->_instRunCtxt.a = a;
-			_vm->_instRunCtxt.modCounter = modCounter;
-			_vm->_instRunCtxt.suspend = false;
-
-			(_vm->*(_vm->_instructionOpcodes)[(*inst)->_index])();
-
-			inst = _vm->_instRunCtxt.inst;		// handles endloop correctly
-
-			if (_vm->_instRunCtxt.suspend)
-				goto label1;
-
-			inst++;
-		}
-
-		a->_program->_ip = ++inst;
-
-label1:
-		if (a->_flags & kFlagsCharacter)
-			a->_z = a->_top + a->height();
-	}
-
-	_vm->sortAnimations();
-	modCounter++;
-
-	return;
-}
-
-void wrapLocalVar(LocalVariable *local) {
-//	  printf("wrapLocalVar(v: %i, min: %i, max: %i)\n", local->_value, local->_min, local->_max);
-
-	if (local->_value >= local->_max)
-		local->_value = local->_min;
-	if (local->_value < local->_min)
-		local->_value = local->_max - 1;
-
-	return;
-}
-
-int compareAnimationZ(const AnimationPointer &a1, const AnimationPointer &a2) {
-	if (a1->_z == a2->_z) return 0;
-	return (a1->_z < a2->_z ? -1 : 1);
-}
-
-
-void Parallaction::sortAnimations() {
-	_char._ani._z = _char._ani.height() + _char._ani._top;
-	_animations.sort(compareAnimationZ);
-	return;
-}
-
-Animation::Animation() {
-	_cnv = NULL;
-	_program = NULL;
-	_scriptName = 0;
-	_frame = 0;
-	_z = 0;
-}
-
-Animation::~Animation() {
-	if (_program)
-		delete _program;
-
-	if (_scriptName)
-		free(_scriptName);
-
-	if (_cnv)
-		delete _cnv;
-}
-
-uint16 Animation::width() const {
-	if (!_cnv) return 0;
-	return _cnv->_width;
-}
-
-uint16 Animation::height() const {
-	if (!_cnv) return 0;
-	return _cnv->_height;
-}
-
-uint16 Animation::getFrameNum() const {
-	if (!_cnv) return 0;
-	return _cnv->_count;
-}
-
-byte* Animation::getFrameData(uint32 index) const {
-	if (!_cnv) return NULL;
-	return _cnv->getFramePtr(index);
-}
-
-
-Program::Program() {
-	_loopCounter = 0;
-	_locals = new LocalVariable[10];
-}
-
-Program::~Program() {
-	delete[] _locals;
-}
-
-
-} // namespace Parallaction

Deleted: scummvm/trunk/engines/parallaction/commands.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/commands.cpp	2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/commands.cpp	2007-08-24 20:14:51 UTC (rev 28711)
@@ -1,421 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "parallaction/parallaction.h"
-
-
-namespace Parallaction {
-
-#define CMD_SET 			1
-#define CMD_CLEAR			2
-#define CMD_START			3
-#define CMD_SPEAK			4
-#define CMD_GET 			5
-#define CMD_LOCATION		6
-#define CMD_OPEN			7
-#define CMD_CLOSE			8
-#define CMD_ON				9
-#define CMD_OFF 			10
-#define CMD_CALL			11
-#define CMD_TOGGLE			12
-#define CMD_DROP			13
-#define CMD_QUIT			14
-#define CMD_MOVE			15
-#define CMD_STOP			16
-
-DECLARE_COMMAND_PARSER(flags) {
-	createCommand(_lookup);
-
-	if (_globalTable->lookup(_tokens[1]) == Table::notFound) {
-		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--;
-	}
-
-	parseCommandFlags();
-	addCommand();
-}
-
-
-DECLARE_COMMAND_PARSER(animation) {
-	createCommand(_lookup);
-
-	_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++;
-	}
-
-	parseCommandFlags();
-	addCommand();
-}
-
-
-DECLARE_COMMAND_PARSER(zone) {
-	createCommand(_lookup);
-
-	_cmdParseCtxt.cmd->u._zone = findZone(_tokens[_cmdParseCtxt.nextToken]);
-	_cmdParseCtxt.nextToken++;
-
-	parseCommandFlags();
-	addCommand();
-}
-
-
-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) {
-	createCommand(_lookup);
-
-	_cmdParseCtxt.cmd->u._object = _objectsNames->lookup(_tokens[_cmdParseCtxt.nextToken]);
-	_cmdParseCtxt.nextToken++;
-
-	parseCommandFlags();
-	addCommand();
-}
-
-
-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(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) {
-	error("Can't parse unknown command '%s'", _tokens[0]);
-}
-
-DECLARE_COMMAND_PARSER(endcommands) {
-	popParserTables();
-}
-
-void Parallaction::parseCommandFlags() {
-
-	int _si = _cmdParseCtxt.nextToken;
-	Command *cmd = _cmdParseCtxt.cmd;
-
-	if (!scumm_stricmp(_tokens[_si], "flags")) {
-		_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);
-			}
-
-			_si++;
-
-		} while (!scumm_stricmp(_tokens[_si++], "|"));
-
-	}
-
-	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++;
-
-		} while (!scumm_stricmp(_tokens[_si++], "|"));
-
-	}
-
-	_si = _cmdParseCtxt.nextToken;
-
-}
-
-void Parallaction::addCommand() {
-
-	// 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
-
-}
-
-void Parallaction::createCommand(uint id) {
-
-	_cmdParseCtxt.nextToken = 1;
-	_cmdParseCtxt.cmd = new Command;
-	_cmdParseCtxt.cmd->_id = id;
-
-}
-
-void Parallaction::parseCommands(Script &script, CommandList& list) {
-
-	_cmdParseCtxt.list = &list;
-	_cmdParseCtxt.end = false;
-
-	pushParserTables(_commandParsers, _commandsNames);
-
-}
-
-DECLARE_COMMAND_OPCODE(invalid) {
-	error("Can't execute invalid command '%i'", _cmdRunCtxt.cmd->_id);
-}
-
-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;
-	}
-}
-
-
-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;
-	}
-}
-
-
-DECLARE_COMMAND_OPCODE(start) {
-	_cmdRunCtxt.cmd->u._animation->_flags |= kFlagsActing;
-}
-
-
-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 );
-		}
-	}
-}
-
-
-DECLARE_COMMAND_OPCODE(off) {
-	_cmdRunCtxt.cmd->u._zone->_flags |= kFlagsRemove;
-}
-
-
-DECLARE_COMMAND_OPCODE(call) {
-	callFunction(_cmdRunCtxt.cmd->u._callable, _cmdRunCtxt.z);
-}
-
-
-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;
-	}
-}
-
-
-DECLARE_COMMAND_OPCODE(drop){
-	dropItem( _cmdRunCtxt.cmd->u._object );
-}
-
-
-DECLARE_COMMAND_OPCODE(quit) {
-	_engineFlags |= kEngineQuit;
-}
-
-
-DECLARE_COMMAND_OPCODE(move) {
-	if ((_char._ani._flags & kFlagsRemove) || (_char._ani._flags & kFlagsActive) == 0) {
-		return;
-	}
-
-	WalkNodeList *vC = _char._builder.buildPath(_cmdRunCtxt.cmd->u._move._x, _cmdRunCtxt.cmd->u._move._y);
-
-	addJob(&jobWalk, vC, kPriority19 );
-	_engineFlags |= kEngineWalking;
-}
-
-
-DECLARE_COMMAND_OPCODE(stop) {
-	_cmdRunCtxt.cmd->u._animation->_flags &= ~kFlagsActing;
-}
-
-
-
-
-void Parallaction::runCommands(CommandList& list, Zone *z) {
-	debugC(1, kDebugLocation, "runCommands");
-
-	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])();
-	}
-
-	debugC(1, kDebugLocation, "runCommands completed");
-
-	return;
-
-}
-
-Command::Command() {
-	_id = 0;
-	_flagsOn = 0;
-	_flagsOff = 0;
-}
-
-Command::~Command() {
-
-}
-
-} // namespace Parallaction
-
-
-

Deleted: scummvm/trunk/engines/parallaction/commands.h
===================================================================
--- scummvm/trunk/engines/parallaction/commands.h	2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/commands.h	2007-08-24 20:14:51 UTC (rev 28711)
@@ -1,92 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef PARALLACTION_COMMANDS_H
-#define PARALLACTION_COMMANDS_H
-
-
-#include "common/stdafx.h"
-#include "common/scummsys.h"
-
-#include "parallaction/defs.h"
-
-namespace Parallaction {
-
-enum CommandFlags {
-	kFlagsVisited		= 1,
-	kFlagsExit			= 0x10000000,
-	kFlagsEnter 		= 0x20000000,
-	kFlagsGlobal		= 0x40000000
-};
-
-struct Zone;
-struct Animation;
-
-
-// TODO: turn this into a struct
-struct CommandData {
-	uint32			_flags;
-	Animation * 	_animation;
-	Zone*			_zone;
-	char*			_string;
-	uint16			_callable;
-	uint16			_object;
-	struct {
-		int16		 _x;
-		int16		_y;
-	} _move;
-
-	CommandData() {
-		_flags = 0;
-		_animation = 0;
-		_zone = 0;
-		_string = 0;
-		_callable = 0;
-		_object = 0;
-		_move._x = 0;
-		_move._y = 0;
-	}
-
-	~CommandData() {
-		if (_string)
-			free(_string);
-	}
-};
-
-struct Command {
-	uint16			_id;
-	CommandData 	u;
-	uint32			_flagsOn;
-	uint32			_flagsOff;
-
-	Command();
-	~Command();
-};
-
-typedef ManagedList<Command*> CommandList;
-
-} // namespace Parallaction
-
-#endif

Modified: scummvm/trunk/engines/parallaction/dialogue.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/dialogue.cpp	2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/dialogue.cpp	2007-08-24 20:14:51 UTC (rev 28711)
@@ -56,132 +56,6 @@
 
 
 
-Dialogue *Parallaction::parseDialogue(Script &script) {
-//	printf("parseDialogue()\n");
-	uint16 numQuestions = 0;
-
-	Dialogue *dialogue = new Dialogue;
-
-	Table forwards(20);
-
-	fillBuffers(script, true);
-
-	while (scumm_stricmp(_tokens[0], "enddialogue")) {
-		if (scumm_stricmp(_tokens[0], "Question")) continue;
-
-		Question *question = new Question;
-		dialogue->_questions[numQuestions] = question;
-
-		forwards.addData(_tokens[1]);
-
-		question->_text = parseDialogueString(script);
-
-		fillBuffers(script, true);
-		question->_mood = atoi(_tokens[0]);
-
-		uint16 numAnswers = 0;
-
-		fillBuffers(script, true);
-		while (scumm_stricmp(_tokens[0], "endquestion")) {	// parse answers
-
-			Answer *answer = new Answer;
-			question->_answers[numAnswers] = answer;
-
-			if (_tokens[1][0]) {
-
-				Table* flagNames;
-				uint16 token;
-
-				if (!scumm_stricmp(_tokens[1], "global")) {
-					token = 2;
-					flagNames = _globalTable;
-					answer->_yesFlags |= kFlagsGlobal;
-				} else {
-					token = 1;
-					flagNames = _localFlagNames;
-				}
-
-				do {
-
-					if (!scumm_strnicmp(_tokens[token], "no", 2)) {
-						byte _al = flagNames->lookup(_tokens[token]+2);
-						answer->_noFlags |= 1 << (_al - 1);
-					} else {
-						byte _al = flagNames->lookup(_tokens[token]);
-						answer->_yesFlags |= 1 << (_al - 1);
-					}
-
-					token++;
-
-				} while (!scumm_stricmp(_tokens[token++], "|"));
-
-			}
-
-			answer->_text = parseDialogueString(script);
-
-			fillBuffers(script, true);
-			answer->_mood = atoi(_tokens[0]);
-			answer->_following._name = parseDialogueString(script);
-
-			fillBuffers(script, true);
-			if (!scumm_stricmp(_tokens[0], "commands")) {
-				parseCommands(script, answer->_commands);
-				fillBuffers(script, true);
-			}
-
-			numAnswers++;
-		}
-
-		fillBuffers(script, true);
-		numQuestions++;
-
-	}
-
-	// link questions
-	byte v50[20];
-	memset(v50, 0, 20);
-
-	for (uint16 i = 0; i < numQuestions; i++) {
-		Question *question = dialogue->_questions[i];
-
-		for (uint16 j = 0; j < NUM_ANSWERS; j++) {
-			Answer *answer = question->_answers[j];
-			if (answer == 0) continue;
-
-			int16 index = forwards.lookup(answer->_following._name);
-			free(answer->_following._name);
-
-			if (index == Table::notFound)
-				answer->_following._question = 0;
-			else
-				answer->_following._question = dialogue->_questions[index - 1];
-
-
-		}
-	}
-
-	return dialogue;
-}
-
-
-char *Parallaction::parseDialogueString(Script &script) {
-
-	char vC8[200];
-	char *vD0 = NULL;
-	do {
-
-		vD0 = script.readLine(vC8, 200);
-		if (vD0 == 0) return NULL;
-
-		vD0 = Common::ltrim(vD0);
-
-	} while (strlen(vD0) == 0);
-
-	vD0[strlen(vD0)-1] = '\0';	// deletes the trailing '0xA'
-								// this is critical for Gfx::displayWrappedString to work properly
-	return strdup(vD0);
-}
-
 class DialogueManager {
 
 	Parallaction	*_vm;
@@ -502,34 +376,5 @@
 	return;
 }
 
-Answer::Answer() {
-	_text = NULL;
-	_mood = 0;
-	_following._question =  NULL;
-	_noFlags = 0;
-	_yesFlags = 0;
-}
 
-Answer::~Answer() {
-	if (_text)
-		free(_text);
-}
-
-Question::Question() {
-	_text = NULL;
-	_mood = 0;
-
-	for (uint32 i = 0; i < NUM_ANSWERS; i++)
-		_answers[i] = NULL;
-
-}
-
-Question::~Question() {
-
-	for (uint32 i = 0; i < NUM_ANSWERS; i++)
-		if (_answers[i]) delete _answers[i];
-
-	free(_text);
-}
-
 } // namespace Parallaction

Modified: scummvm/trunk/engines/parallaction/disk_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/disk_br.cpp	2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/disk_br.cpp	2007-08-24 20:14:51 UTC (rev 28711)
@@ -102,7 +102,15 @@
 
 Script* DosDisk_br::loadScript(const char* name) {
 	debugC(5, kDebugDisk, "DosDisk_br::loadScript");
-	return 0;
+
+	Common::File *stream = new Common::File;
+
+	char path[PATH_LEN];
+	sprintf(path, "%s/scripts/%s.scr", _partPath, name);
+	if (!stream->open(path))
+		errorFileNotFound(path);
+
+	return new Script(stream, true);
 }
 
 //	there are no Head resources in Big Red Adventure
@@ -275,7 +283,7 @@
 
 	stream.close();
 
-	return 0;
+	return t;
 }
 
 Common::SeekableReadStream* DosDisk_br::loadMusic(const char* name) {

Added: scummvm/trunk/engines/parallaction/exec_ns.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/exec_ns.cpp	                        (rev 0)
+++ scummvm/trunk/engines/parallaction/exec_ns.cpp	2007-08-24 20:14:51 UTC (rev 28711)
@@ -0,0 +1,857 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "parallaction/parallaction.h"
+#include "parallaction/sound.h"
+
+
+namespace Parallaction {
+
+#define INST_ON 						1
+#define INST_OFF						2
+#define INST_X							3
+#define INST_Y							4
+#define INST_Z							5
+#define INST_F							6
+#define INST_LOOP						7
+#define INST_ENDLOOP					8
+#define INST_SHOW						9
+#define INST_INC						10
+#define INST_DEC						11
+#define INST_SET						12
+#define INST_PUT						13
+#define INST_CALL						14
+#define INST_WAIT						15
+#define INST_START						16
+#define INST_SOUND						17
+#define INST_MOVE						18
+#define INST_END						19
+
+
+typedef OpcodeImpl<Parallaction_ns> OpcodeV1;
+#define COMMAND_OPCODE(op) OpcodeV1(this, &Parallaction_ns::cmdOp_##op)
+#define DECLARE_COMMAND_OPCODE(op) void Parallaction_ns::cmdOp_##op()
+
+#define INSTRUCTION_OPCODE(op) OpcodeV1(this, &Parallaction_ns::instOp_##op)
+#define DECLARE_INSTRUCTION_OPCODE(op) void Parallaction_ns::instOp_##op()
+
+
+
+
+DECLARE_INSTRUCTION_OPCODE(on) {
+	(*_instRunCtxt.inst)->_opBase._a->_flags |= kFlagsActive;
+	(*_instRunCtxt.inst)->_opBase._a->_flags &= ~kFlagsRemove;
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(off) {
+	(*_instRunCtxt.inst)->_opBase._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;
+	}
+	_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);
+
+	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);
+	}
+}
+
+DECLARE_INSTRUCTION_OPCODE(null) {
+
+}
+
+DECLARE_INSTRUCTION_OPCODE(invalid) {
+	error("Can't execute invalid opcode %i", (*_instRunCtxt.inst)->_index);
+}
+
+DECLARE_INSTRUCTION_OPCODE(call) {
+	callFunction((*_instRunCtxt.inst)->_opBase._index, 0);
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(wait) {
+	if (_engineFlags & kEngineWalking)
+		_instRunCtxt.suspend = true;
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(start) {
+	(*_instRunCtxt.inst)->_opBase._a->_flags |= (kFlagsActing | kFlagsActive);
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(sound) {
+	_activeZone = (*_instRunCtxt.inst)->_opBase._z;
+}
+
+
+DECLARE_INSTRUCTION_OPCODE(move) {
+	WalkNodeList *v4 = _char._builder.buildPath(*(*_instRunCtxt.inst)->_opA._pvalue, *(*_instRunCtxt.inst)->_opB._pvalue);
+	addJob(&jobWalk, v4, kPriority19 );
+	_engineFlags |= kEngineWalking;
+}
+
+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();
+
+	_instRunCtxt.suspend = true;
+}
+
+
+
+void Parallaction_ns::wrapLocalVar(LocalVariable *local) {
+
+	if (local->_value >= local->_max)
+		local->_value = local->_min;
+	if (local->_value < local->_min)
+		local->_value = local->_max - 1;
+
+	return;
+}
+
+
+DECLARE_COMMAND_OPCODE(invalid) {
+	error("Can't execute invalid command '%i'", _cmdRunCtxt.cmd->_id);
+}
+
+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;
+	}
+}
+
+
+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;
+	}
+}
+
+
+DECLARE_COMMAND_OPCODE(start) {
+	_cmdRunCtxt.cmd->u._animation->_flags |= kFlagsActing;
+}
+
+
+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 );
+		}
+	}
+}
+
+
+DECLARE_COMMAND_OPCODE(off) {
+	_cmdRunCtxt.cmd->u._zone->_flags |= kFlagsRemove;
+}
+
+
+DECLARE_COMMAND_OPCODE(call) {
+	callFunction(_cmdRunCtxt.cmd->u._callable, _cmdRunCtxt.z);
+}
+
+
+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;
+	}
+}
+
+
+DECLARE_COMMAND_OPCODE(drop){
+	dropItem( _cmdRunCtxt.cmd->u._object );
+}
+
+
+DECLARE_COMMAND_OPCODE(quit) {
+	_engineFlags |= kEngineQuit;
+}
+
+
+DECLARE_COMMAND_OPCODE(move) {
+	if ((_char._ani._flags & kFlagsRemove) || (_char._ani._flags & kFlagsActive) == 0) {
+		return;
+	}
+
+	WalkNodeList *vC = _char._builder.buildPath(_cmdRunCtxt.cmd->u._move.x, _cmdRunCtxt.cmd->u._move.y);
+
+	addJob(&jobWalk, vC, kPriority19 );
+	_engineFlags |= kEngineWalking;
+}
+
+
+DECLARE_COMMAND_OPCODE(stop) {
+	_cmdRunCtxt.cmd->u._animation->_flags &= ~kFlagsActing;
+}
+
+
+void jobDisplayAnimations(void *parm, Job *j) {
+
+	Graphics::Surface v14;
+
+	uint16 _si = 0;
+
+	for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
+
+		Animation *v18 = *it;
+
+		if ((v18->_flags & kFlagsActive) && ((v18->_flags & kFlagsRemove) == 0))   {
+			v14.w = v18->width();
+			v14.h = v18->height();
+
+			int16 frame = CLIP((int)v18->_frame, 0, v18->getFrameNum()-1);
+
+			v14.pixels = v18->getFrameData(frame);
+
+			if (v18->_flags & kFlagsNoMasked)
+				_si = 3;
+			else
+				_si = _vm->_gfx->queryMask(v18->_top + v18->height());
+
+			debugC(9, kDebugLocation, "jobDisplayAnimations(%s, x:%i, y:%i, z:%i, w:%i, h:%i, f:%i/%i, %p)", v18->_label._text, v18->_left, v18->_top, _si, v14.w, v14.h,
+				frame, v18->getFrameNum(), v14.pixels);
+			_vm->_gfx->blitCnv(&v14, v18->_left, v18->_top, _si, Gfx::kBitBack);
+
+		}
+
+		if (((v18->_flags & kFlagsActive) == 0) && (v18->_flags & kFlagsRemove))   {
+			v18->_flags &= ~kFlagsRemove;
+			v18->_oldPos.x = -1000;
+		}
+
+		if ((v18->_flags & kFlagsActive) && (v18->_flags & kFlagsRemove))	{
+			v18->_flags &= ~kFlagsActive;
+			v18->_flags |= kFlagsRemove;
+		}
+
+	}
+
+//	  printf("done\n");
+
+	return;
+}
+
+
+void jobEraseAnimations(void *arg_0, Job *j) {
+	debugC(3, kDebugJobs, "jobEraseAnimations");
+
+	for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
+
+		Animation *a = *it;
+
+		if (((a->_flags & kFlagsActive) == 0) && ((a->_flags & kFlagsRemove) == 0)) continue;
+
+		Common::Rect r(a->width(), a->height());
+		r.moveTo(a->_oldPos);
+		_vm->_gfx->restoreBackground(r);
+
+		if (arg_0) {
+			a->_oldPos.x = a->_left;
+			a->_oldPos.y = a->_top;
+		}
+
+	}
+
+	return;
+}
+
+
+void jobRunScripts(void *parm, Job *j) {
+	debugC(3, kDebugJobs, "jobRunScripts");
+
+	static uint16 modCounter = 0;
+
+	for (AnimationList::iterator it = _vm->_animations.begin(); it != _vm->_animations.end(); it++) {
+
+		Animation *a = *it;
+
+		if (a->_flags & kFlagsCharacter)
+			a->_z = a->_top + a->height();
+
+		if ((a->_flags & kFlagsActing) == 0)
+			continue;
+
+		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]);
+
+			_vm->_instRunCtxt.inst = inst;
+			_vm->_instRunCtxt.a = a;
+			_vm->_instRunCtxt.modCounter = modCounter;
+			_vm->_instRunCtxt.suspend = false;
+
+			(*_vm->_instructionOpcodes[(*inst)->_index])();
+
+			inst = _vm->_instRunCtxt.inst;		// handles endloop correctly
+
+			if (_vm->_instRunCtxt.suspend)
+				goto label1;
+
+			inst++;
+		}
+
+		a->_program->_ip = ++inst;
+
+label1:
+		if (a->_flags & kFlagsCharacter)
+			a->_z = a->_top + a->height();
+	}
+
+	_vm->sortAnimations();
+	modCounter++;
+
+	return;
+}
+
+
+void Parallaction::runCommands(CommandList& list, Zone *z) {
+	debugC(1, kDebugLocation, "runCommands");
+
+	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[%i]: %s (on: %x, off: %x)", cmd->_id, _commandsNamesRes[cmd->_id-1], cmd->_flagsOn, cmd->_flagsOff);
+
+		_cmdRunCtxt.z = z;
+		_cmdRunCtxt.cmd = cmd;
+
+		(*_commandOpcodes[cmd->_id])();
+	}
+
+	debugC(1, kDebugLocation, "runCommands completed");
+
+	return;
+
+}
+
+
+
+
+//	displays character head commenting an examined object
+//
+//	works on the frontbuffer
+//
+void Parallaction::displayCharacterComment(ExamineData *data) {
+	if (data->_description == NULL) return;
+
+	// NOTE: saving visible screen before displaying comment allows
+	// to restore the exact situation after the comment is deleted.
+	// This means animations are restored in the exact position as
+	// they were, thus avoiding clipping effect as signalled in
+	// BUG item #1762614.
+	_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
+
+	_gfx->setFont(_dialogueFont);
+	_gfx->flatBlitCnv(_char._talk, 0, 190, 80, Gfx::kBitFront);
+
+	int16 v26, v28;
+	_gfx->getStringExtent(data->_description, 130, &v28, &v26);
+	Common::Rect r(v28, v26);
+	r.moveTo(140, 10);
+	_gfx->drawBalloon(r, 0);
+	_gfx->displayWrappedString(data->_description, 140, 10, 0, 130);
+
+	waitUntilLeftClick();
+
+	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+	_gfx->updateScreen();
+
+	return;
+}
+
+//
+//	ZONE TYPE: EXAMINE
+//
+
+//	display detail view of an item (and eventually comments)
+//
+//	works on the frontbuffer
+//
+
+void Parallaction::displayItemComment(ExamineData *data) {
+
+	if (data->_description == NULL) return;
+
+	_gfx->setHalfbriteMode(true);
+
+	char v68[PATH_LEN];
+	strcpy(v68, data->_filename);
+	data->_cnv = _disk->loadStatic(v68);
+	_gfx->flatBlitCnv(data->_cnv, 140, (_screenHeight - data->_cnv->h)/2, Gfx::kBitFront);
+	delete data->_cnv;
+
+	int16 v6A = 0, v6C = 0;
+
+	_gfx->setFont(_dialogueFont);
+	_gfx->getStringExtent(data->_description, 130, &v6C, &v6A);
+	Common::Rect r(v6C, v6A);
+	r.moveTo(0, 90);
+	_gfx->drawBalloon(r, 0);
+	_gfx->flatBlitCnv(_char._head, 100, 152, Gfx::kBitFront);
+	_gfx->displayWrappedString(data->_description, 0, 90, 0, 130);
+
+	jobEraseAnimations((void*)1, NULL);
+	_gfx->updateScreen();
+
+	waitUntilLeftClick();
+
+	_gfx->setHalfbriteMode(false);
+	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+	_gfx->updateScreen();
+
+	return;
+}
+
+
+
+uint16 Parallaction::runZone(Zone *z) {
+	debugC(3, kDebugLocation, "runZone (%s)", z->_label._text);
+
+	uint16 subtype = z->_type & 0xFFFF;
+
+	debugC(3, kDebugLocation, "type = %x, object = %x", subtype, (z->_type & 0xFFFF0000) >> 16);
+	switch(subtype) {
+
+	case kZoneExamine:
+		if (z->u.examine->_filename) {
+			displayItemComment(z->u.examine);
+		} else {
+			displayCharacterComment(z->u.examine);
+		}
+		break;
+
+	case kZoneGet:
+		if (z->_flags & kFlagsFixed) break;
+		if (pickupItem(z) != 0) {
+			return 1;
+		}
+		z->_flags |= kFlagsRemove;
+		break;
+
+	case kZoneDoor:
+		if (z->_flags & kFlagsLocked) break;
+		z->_flags ^= kFlagsClosed;
+		if (z->u.door->_cnv == NULL) break;
+		addJob(&jobToggleDoor, z, kPriority18 );
+		break;
+
+	case kZoneHear:
+		_soundMan->playSfx(z->u.hear->_name, z->u.hear->_channel, (z->_flags & kFlagsLooping) == kFlagsLooping, 60);
+		break;
+
+	case kZoneSpeak:
+		runDialogue(z->u.speak);
+		break;
+
+	}
+
+	debugC(3, kDebugLocation, "runZone completed");
+
+	return 0;
+}
+
+//
+//	ZONE TYPE: DOOR
+//
+void jobToggleDoor(void *parm, Job *j) {
+
+	static byte count = 0;
+
+	Zone *z = (Zone*)parm;
+
+	if (z->u.door->_cnv) {
+		Common::Rect r(z->_left, z->_top, z->_left+z->u.door->_cnv->_width, z->_top+z->u.door->_cnv->_height);
+
+		uint16 _ax = (z->_flags & kFlagsClosed ? 1 : 0);
+		_vm->_gfx->restoreDoorBackground(r, z->u.door->_cnv->getFramePtr(_ax), z->u.door->_background);
+
+		_ax = (z->_flags & kFlagsClosed ? 0 : 1);
+		_vm->_gfx->flatBlitCnv(z->u.door->_cnv, _ax, z->_left, z->_top, Gfx::kBitBack);
+		_vm->_gfx->flatBlitCnv(z->u.door->_cnv, _ax, z->_left, z->_top, Gfx::kBit2);
+	}
+
+	count++;
+	if (count == 2) {
+		j->_finished = 1;
+		count = 0;
+	}
+
+	return;
+}
+
+
+
+//
+//	ZONE TYPE: GET
+//
+
+int16 Parallaction::pickupItem(Zone *z) {
+	int r = addInventoryItem(z->u.get->_icon);
+	if (r == 0)
+		addJob(&jobRemovePickedItem, z, kPriority17 );
+
+	return r;
+}
+
+void jobRemovePickedItem(void *parm, Job *j) {
+
+	Zone *z = (Zone*)parm;
+
+	static uint16 count = 0;
+
+	if (z->u.get->_cnv) {
+		Common::Rect r(z->_left, z->_top, z->_left + z->u.get->_cnv->w, z->_top + z->u.get->_cnv->h);
+
+		_vm->_gfx->restoreGetBackground(r, z->u.get->_backup);
+	}
+
+	count++;
+	if (count == 2) {
+		count = 0;
+		j->_finished = 1;
+	}
+
+	return;
+}
+
+void jobDisplayDroppedItem(void *parm, Job *j) {
+//	printf("jobDisplayDroppedItem...");
+
+	Zone *z = (Zone*)parm;
+
+	if (z->u.get->_cnv) {
+		if (j->_count == 0) {
+			_vm->_gfx->backupGetBackground(z->u.get, z->_left, z->_top);
+		}
+
+		_vm->_gfx->flatBlitCnv(z->u.get->_cnv, z->_left, z->_top, Gfx::kBitBack);
+		_vm->_gfx->flatBlitCnv(z->u.get->_cnv, z->_left, z->_top, Gfx::kBit2);
+	}
+
+	j->_count++;
+	if (j->_count == 2) {
+		j->_count = 0;
+		j->_finished = 1;
+	}
+
+//	printf("done");
+
+	return;
+}
+
+
+
+
+Zone *Parallaction::hitZone(uint32 type, uint16 x, uint16 y) {
+//	printf("hitZone(%i, %i, %i)", type, x, y);
+
+	uint16 _di = y;
+	uint16 _si = x;
+
+	for (ZoneList::iterator it = _zones.begin(); it != _zones.end(); it++) {
+//		printf("Zone name: %s", z->_name);
+
+		Zone *z = *it;
+
+		if (z->_flags & kFlagsRemove) continue;
+
+		Common::Rect r;
+		z->getRect(r);
+		r.right++;		// adjust border because Common::Rect doesn't include bottom-right edge
+		r.bottom++;
+
+		r.grow(-1);		// allows some tolerance for mouse click
+
+		if (!r.contains(_si, _di)) {
+
+			// out of Zone, so look for special values
+			if ((z->_left == -2) || (z->_left == -3)) {
+
+				// WORKAROUND: this huge condition is needed because we made TypeData a collection of structs
+				// instead of an union. So, merge->_obj1 and get->_icon were just aliases in the original engine,
+				// but we need to check it separately here. The same workaround is applied in freeZones.
+				if ((((z->_type & 0xFFFF) == kZoneMerge) && (((_si == z->u.merge->_obj1) && (_di == z->u.merge->_obj2)) || ((_si == z->u.merge->_obj2) && (_di == z->u.merge->_obj1)))) ||
+					(((z->_type & 0xFFFF) == kZoneGet) && ((_si == z->u.get->_icon) || (_di == z->u.get->_icon)))) {
+
+					// special Zone
+					if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
+						return z;
+					if (z->_type == type)
+						return z;
+					if ((z->_type & 0xFFFF0000) == type)
+						return z;
+
+				}
+			}
+
+			if (z->_left != -1)
+				continue;
+			if (_si < _char._ani._left)
+				continue;
+			if (_si > (_char._ani._left + _char._ani.width()))
+				continue;
+			if (_di < _char._ani._top)
+				continue;
+			if (_di > (_char._ani._top + _char._ani.height()))
+				continue;
+
+		}
+
+		// normal Zone
+		if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
+			return z;
+		if (z->_type == type)
+			return z;
+		if ((z->_type & 0xFFFF0000) == type)
+			return z;
+
+	}
+
+
+	int16 _a, _b, _c, _d, _e, _f;
+	for (AnimationList::iterator it = _animations.begin(); it != _animations.end(); it++) {
+
+		Animation *a = *it;
+
+		_a = (a->_flags & kFlagsActive) ? 1 : 0;															   // _a: active Animation
+		_e = ((_si >= a->_left + a->width()) || (_si <= a->_left)) ? 0 : 1;		// _e: horizontal range
+		_f = ((_di >= a->_top + a->height()) || (_di <= a->_top)) ? 0 : 1;		// _f: vertical range
+
+		_b = ((type != 0) || (a->_type == kZoneYou)) ? 0 : 1; 										 // _b: (no type specified) AND (Animation is not the character)
+		_c = (a->_type & 0xFFFF0000) ? 0 : 1; 															// _c: Animation is not an object
+		_d = ((a->_type & 0xFFFF0000) != type) ? 0 : 1;													// _d: Animation is an object of the same type
+
+		if ((_a != 0 && _e != 0 && _f != 0) && ((_b != 0 && _c != 0) || (a->_type == type) || (_d != 0))) {
+
+			return a;
+
+		}
+
+	}
+
+	return NULL;
+}
+
+
+void Parallaction_ns::initOpcodes() {
+
+	static const OpcodeV1 op1[] = {
+		INSTRUCTION_OPCODE(invalid),
+		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)
+	};
+
+	uint i;
+	for (i = 0; i < ARRAYSIZE(op1); i++)
+		_instructionOpcodes.push_back(&op1[i]);
+
+	static const OpcodeV1 op3[] = {
+		COMMAND_OPCODE(invalid),
+		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)
+	};
+
+	for (i = 0; i < ARRAYSIZE(op3); i++)
+		_commandOpcodes.push_back(&op3[i]);
+
+}
+
+
+
+}	// namespace Parallaction


Property changes on: scummvm/trunk/engines/parallaction/exec_ns.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Modified: scummvm/trunk/engines/parallaction/font.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/font.cpp	2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/font.cpp	2007-08-24 20:14:51 UTC (rev 28711)
@@ -571,7 +571,7 @@
 }
 
 Font *DosDisk_br::createFont(const char *name, Common::ReadStream &stream) {
-	printf("DosDisk_br::createFont(%s)\n", name);
+//	printf("DosDisk_br::createFont(%s)\n", name);
 	return new BraFont(stream);
 }
 

Modified: scummvm/trunk/engines/parallaction/inventory.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/inventory.cpp	2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/inventory.cpp	2007-08-24 20:14:51 UTC (rev 28711)
@@ -157,7 +157,7 @@
 	bool found = false;
 	for (uint16 slot = 0; slot < INVENTORY_MAX_ITEMS - 1; slot++) {
 
-		if (v + INVENTORY_FIRST_ITEM == _inventory[slot]._index) {
+		if (v == _inventory[slot]._index) {
 			found = true;
 		}
 

Deleted: scummvm/trunk/engines/parallaction/location.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/location.cpp	2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/location.cpp	2007-08-24 20:14:51 UTC (rev 28711)
@@ -1,567 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "common/system.h"
-
-#include "parallaction/parallaction.h"
-#include "parallaction/sound.h"
-
-namespace Parallaction {
-
-
-DECLARE_LOCATION_PARSER(invalid) {
-	error("unknown keyword '%s' in location '%s'", _tokens[0], _locParseCtxt.filename);
-}
-
-DECLARE_LOCATION_PARSER(endlocation) {
-	_locParseCtxt.end = true;
-}
-
-
-DECLARE_LOCATION_PARSER(location) {
-	// The parameter for location is 'location.mask'.
-	// If mask is not present, then it is assumed
-	// that path & mask are encoded in the background
-	// bitmap, otherwise a separate .msk file exists.
-
-	char *mask = strchr(_tokens[1], '.');
-	if (mask) {
-		mask[0] = '\0';
-		mask++;
-	}
-
-	strcpy(_location._name, _tokens[1]);
-	switchBackground(_location._name, mask);
-
-	if (_tokens[2][0] != '\0') {
-		_char._ani._left = atoi(_tokens[2]);
-		_char._ani._top = atoi(_tokens[3]);
-	}
-
-	if (_tokens[4][0] != '\0') {
-		_char._ani._frame = atoi(_tokens[4]);
-	}
-}
-
-
-DECLARE_LOCATION_PARSER(disk) {
-	_disk->selectArchive(_tokens[1]);
-}
-
-
-DECLARE_LOCATION_PARSER(nodes) {
-	parseWalkNodes(*_locParseCtxt.script, _location._walkNodes);
-}
-
-
-DECLARE_LOCATION_PARSER(zone) {
-	parseZone(*_locParseCtxt.script, _zones, _tokens[1]);
-}
-
-
-DECLARE_LOCATION_PARSER(animation) {
-	parseAnimation(*_locParseCtxt.script, _animations, _tokens[1]);
-}
-
-
-DECLARE_LOCATION_PARSER(localflags) {
-	int _si = 1;	// _localFlagNames[0] = 'visited'
-	while (_tokens[_si][0] != '\0') {
-		_localFlagNames->addData(_tokens[_si]);
-		_si++;
-	}
-}
-
-
-DECLARE_LOCATION_PARSER(commands) {
-	parseCommands(*_locParseCtxt.script, _location._commands);
-}
-
-
-DECLARE_LOCATION_PARSER(acommands) {
-	parseCommands(*_locParseCtxt.script, _location._aCommands);
-}
-
-
-DECLARE_LOCATION_PARSER(flags) {
-	if ((_localFlags[_currentLocationIndex] & kFlagsVisited) == 0) {
-		// only for 1st visit
-		_localFlags[_currentLocationIndex] = 0;
-		int _si = 1;
-
-		do {
-			byte _al = _localFlagNames->lookup(_tokens[_si]);
-			_localFlags[_currentLocationIndex] |= 1 << (_al - 1);
-
-			_si++;
-			if (scumm_stricmp(_tokens[_si], "|")) break;
-			_si++;
-		} while (true);
-	}
-}
-
-
-DECLARE_LOCATION_PARSER(comment) {
-	_location._comment = parseComment(*_locParseCtxt.script);
-}
-
-
-DECLARE_LOCATION_PARSER(endcomment) {
-	_location._endComment = parseComment(*_locParseCtxt.script);
-}
-
-
-DECLARE_LOCATION_PARSER(sound) {
-	if (getPlatform() == Common::kPlatformAmiga) {
-		strcpy(_locationSound, _tokens[1]);
-		_hasLocationSound = true;
-	}
-}
-
-
-DECLARE_LOCATION_PARSER(music) {
-	if (getPlatform() == Common::kPlatformAmiga)
-		_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);
-
-	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;
-
-	pushParserTables(_locationParsers, _locationStmt);
-
-	do {
-
-		fillBuffers(*script, true);
-
-		parseStatement();
-
-	} while (!_locParseCtxt.end);
-
-	popParserTables();
-
-	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
-	// and if-statement, so the code exactly matches the one
-	// in Big Red Adventure.
-	_currentLocationIndex = -1;
-	uint16 _di = 0;
-	while (_locationNames[_di][0] != '\0') {
-		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], name);
-		_currentLocationIndex = _numLocations;
-
-		_numLocations++;
-		_locationNames[_numLocations][0] = '\0';
-		_localFlags[_numLocations] = 0;
-	} else {
-		_localFlags[_currentLocationIndex] |= kFlagsVisited;	// 'visited'
-	}
-}
-
-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;
-
-	// this loads animation scripts
-	AnimationList::iterator it = _animations.begin();
-	for ( ; it != _animations.end(); it++) {
-		if ((*it)->_scriptName)
-			loadProgram(*it, (*it)->_scriptName);
-	}
-
-	return;
-}
-
-
-void Parallaction::freeLocation() {
-	debugC(7, kDebugLocation, "freeLocation");
-
-	_soundMan->stopSfx(0);
-	_soundMan->stopSfx(1);
-	_soundMan->stopSfx(2);
-	_soundMan->stopSfx(3);
-
-	if (_localFlagNames)
-		delete _localFlagNames;
-
-	// HACK: prevents leakage. A routine like this
-	// should allocate memory at all, though.
-	if ((_engineFlags & kEngineQuit) == 0) {
-		_localFlagNames = new Table(120);
-		_localFlagNames->addData("visited");
-	}
-
-	_location._walkNodes.clear();
-
-	freeZones();
-	freeAnimations();
-
-	if (_location._comment) {
-		free(_location._comment);
-	}
-	_location._comment = NULL;
-
-	_location._commands.clear();
-	_location._aCommands.clear();
-
-	return;
-}
-
-
-
-void Parallaction::parseWalkNodes(Script& script, WalkNodeList &list) {
-
-	fillBuffers(script, true);
-	while (scumm_stricmp(_tokens[0], "ENDNODES")) {
-
-		if (!scumm_stricmp(_tokens[0], "COORD")) {
-
-			WalkNode *v4 = new WalkNode(
-				atoi(_tokens[1]) - _char._ani.width()/2,
-				atoi(_tokens[2]) - _char._ani.height()
-			);
-
-			list.push_front(v4);
-		}
-
-		fillBuffers(script, true);
-	}
-
-	return;
-
-}
-
-void Parallaction::freeBackground() {
-
-	if (!_backgroundInfo)
-		return;
-
-	_backgroundInfo->bg.free();
-	_backgroundInfo->mask.free();
-	_backgroundInfo->path.free();
-
-	_pathBuffer = 0;
-
-}
-
-void Parallaction::setBackground(const char* name, const char* mask, const char* path) {
-
-	_disk->loadScenery(*_backgroundInfo, name, mask, path);
-
-	_gfx->setPalette(_backgroundInfo->palette);
-	_gfx->_palette.clone(_backgroundInfo->palette);
-	_gfx->setBackground(&_backgroundInfo->bg);
-
-	if (_backgroundInfo->mask.data)
-		_gfx->setMask(&_backgroundInfo->mask);
-
-	if (_backgroundInfo->path.data)
-		_pathBuffer = &_backgroundInfo->path;
-
-	return;
-}
-
-void Parallaction::showLocationComment(const char *text, bool end) {
-
-	_gfx->setFont(_dialogueFont);
-
-	int16 w, h;
-	_gfx->getStringExtent(const_cast<char*>(text), 130, &w, &h);
-
-	Common::Rect r(w + (end ? 5 : 10), h + 5);
-	r.moveTo(5, 5);
-
-	_gfx->floodFill(Gfx::kBitFront, r, 0);
-	r.grow(-2);
-	_gfx->floodFill(Gfx::kBitFront, r, 1);
-	_gfx->displayWrappedString(const_cast<char*>(text), 3, 5, 0, 130);
-
-	_gfx->updateScreen();
-
-	return;
-}
-
-void Parallaction::switchBackground(const char* background, const char* mask) {
-//	printf("switchBackground(%s)", name);
-
-	Palette pal;
-
-	uint16 v2 = 0;
-	if (!scumm_stricmp(background, "final")) {
-		_gfx->clearScreen(Gfx::kBitBack);
-		for (uint16 _si = 0; _si <= 32; _si++) {
-			pal.setEntry(_si, v2, v2, v2);
-			v2 += 4;
-		}
-
-		g_system->delayMillis(20);
-		_gfx->setPalette(pal);
-		_gfx->updateScreen();
-	}
-
-	setBackground(background, mask, mask);
-
-	return;
-}
-
-extern Zone     *_hoverZone;
-extern Job     *_jDrawLabel;
-extern Job     *_jEraseLabel;
-
-void Parallaction::showSlide(const char *name) {
-
-	BackgroundInfo info;
-
-	_disk->loadSlide(info, name);
-
-	// TODO: avoid using screen buffers for displaying slides. Using a generic buffer
-	// allows for positioning of graphics as needed by Big Red Adventure.
-	// The main problem lies with menu, which relies on multiple buffers, mainly because
-	// it is crappy code.
-	_gfx->setBackground(&info.bg);
-	_gfx->setPalette(info.palette);
-	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
-
-	info.bg.free();
-	info.mask.free();
-	info.path.free();
-
-	return;
-}
-
-/*
-	changeLocation handles transitions between locations, and is able to display slides
-	between one and the other. The input parameter 'location' exists in some flavours:
-
-    1 - [S].slide.[L]{.[C]}
-	2 - [L]{.[C]}
-
-    where:
-
-	[S] is the slide to be shown
-    [L] is the location to switch to (immediately in case 2, or right after slide [S] in case 1)
-    [C] is the character to be selected, and is optional
-
-    The routine tells one form from the other by searching for the '.slide.'
-
-    NOTE: there exists one script in which [L] is not used in the case 1, but its use
-		  is commented out, and would definitely crash the current implementation.
-*/
-void Parallaction::changeLocation(char *location) {
-	debugC(1, kDebugLocation, "changeLocation(%s)", location);
-
-	_soundMan->playLocationMusic(location);
-
-	// WORKAROUND: this if-statement has been added to avoid crashes caused by
-	// execution of label jobs after a location switch. The other workaround in
-	// Parallaction::runGame should have been rendered useless by this one.
-	if (_jDrawLabel != NULL) {
-		removeJob(_jDrawLabel);
-		removeJob(_jEraseLabel);
-		_jDrawLabel = NULL;
-		_jEraseLabel = NULL;
-	}
-
-
-	_hoverZone = NULL;
-	if (_engineFlags & kEngineBlockInput) {
-		changeCursor( kCursorArrow );
-	}
-
-	_animations.remove(&_char._ani);
-
-	freeLocation();
-	char buf[100];
-	strcpy(buf, location);
-
-	Common::StringList list;
-	char *tok = strtok(location, ".");
-	while (tok) {
-		list.push_back(tok);
-		tok = strtok(NULL, ".");
-	}
-
-	if (list.size() < 1 || list.size() > 4)
-		error("changeLocation: ill-formed location string '%s'", location);
-
-	if (list.size() > 1) {
-		if (list[1] == "slide") {
-			showSlide(list[0].c_str());
-			_gfx->setFont(_menuFont);
-			_gfx->displayCenteredString(14, _slideText[0]); // displays text on screen
-			_gfx->updateScreen();
-			waitUntilLeftClick();
-
-			list.remove_at(0);		// removes slide name
-			list.remove_at(0);		// removes 'slide'
-		}
-
-		// list is now only [L].{[C]} (see above comment)
-		if (list.size() == 2) {
-			changeCharacter(list[1].c_str());
-			strcpy(_characterName, list[1].c_str());
-		}
-	}
-
-	_animations.push_front(&_char._ani);
-
-	strcpy(_saveData1, list[0].c_str());
-	parseLocation(list[0].c_str());
-
-	_char._ani._oldPos.x = -1000;
-	_char._ani._oldPos.y = -1000;
-
-	_char._ani.field_50 = 0;
-	if (_location._startPosition.x != -1000) {
-		_char._ani._left = _location._startPosition.x;
-		_char._ani._top = _location._startPosition.y;
-		_char._ani._frame = _location._startFrame;
-		_location._startPosition.y = -1000;
-		_location._startPosition.x = -1000;
-	}
-
-
-	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
-	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2);
-	_gfx->setBlackPalette();
-	_gfx->updateScreen();
-
-	if (_location._commands.size() > 0) {
-		runCommands(_location._commands);
-		runJobs();
-		_gfx->swapBuffers();
-		runJobs();
-		_gfx->swapBuffers();
-	}
-
-	if (_location._comment) {
-		doLocationEnterTransition();
-	}
-
-	runJobs();
-	_gfx->swapBuffers();
-
-	_gfx->setPalette(_gfx->_palette);
-	if (_location._aCommands.size() > 0) {
-		runCommands(_location._aCommands);
-	}
-
-	if (_hasLocationSound)
-		_soundMan->playSfx(_locationSound, 0, true);
-
-	debugC(1, kDebugLocation, "changeLocation() done");
-
-	return;
-
-}
-
-//	displays transition before a new location
-//
-//	clears screen (in white??)
-//	shows location comment (if any)
-//	waits for mouse click
-//	fades towards game palette
-//
-void Parallaction::doLocationEnterTransition() {
-	debugC(1, kDebugLocation, "doLocationEnterTransition");
-
-    if (_localFlags[_currentLocationIndex] & kFlagsVisited) {
-        debugC(3, kDebugLocation, "skipping location transition");
-        return; // visited
-    }
-
-	Palette pal(_gfx->_palette);
-	pal.makeGrayscale();
-	_gfx->setPalette(pal);
-
-	jobRunScripts(NULL, NULL);
-	jobEraseAnimations(NULL, NULL);
-	jobDisplayAnimations(NULL, NULL);
-
-	_gfx->swapBuffers();
-	_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
-
-	showLocationComment(_location._comment, false);
-	waitUntilLeftClick();
-
-	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront );
-
-	// fades maximum intensity palette towards approximation of main palette
-	for (uint16 _si = 0; _si<6; _si++) {
-		pal.fadeTo(_gfx->_palette, 4);
-		_gfx->setPalette(pal);
-		waitTime( 1 );
-		_gfx->updateScreen();
-	}
-
-	debugC(1, kDebugLocation, "doLocationEnterTransition completed");
-
-	return;
-}
-
-} // namespace Parallaction

Modified: scummvm/trunk/engines/parallaction/module.mk
===================================================================
--- scummvm/trunk/engines/parallaction/module.mk	2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/module.mk	2007-08-24 20:14:51 UTC (rev 28711)
@@ -1,29 +1,28 @@
 MODULE := engines/parallaction
 
 MODULE_OBJS := \
-	animation.o \
 	callables_br.o \
 	callables_ns.o \
-	commands.o \
 	debug.o \
 	detection.o \
 	dialogue.o \
 	disk_br.o \
 	disk_ns.o \
+	exec_ns.o \
 	font.o \
 	graphics.o \
 	inventory.o \
-	location.o \
 	menu.o \
-	parser.o \
+	objects.o \
 	parallaction.o \
 	parallaction_br.o \
 	parallaction_ns.o \
+	parser.o \
+	parser_ns.o \
 	saveload.o \
 	sound.o \
 	staticres.o \
-	walk.o \
-	zone.o
+	walk.o
 
 # This module can be built as a plugin
 ifdef BUILD_PLUGINS

Added: scummvm/trunk/engines/parallaction/objects.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/objects.cpp	                        (rev 0)
+++ scummvm/trunk/engines/parallaction/objects.cpp	2007-08-24 20:14:51 UTC (rev 28711)
@@ -0,0 +1,215 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "parallaction/objects.h"
+
+namespace Parallaction {
+
+
+
+Command::Command() {
+	_id = 0;
+	_flagsOn = 0;
+	_flagsOff = 0;
+}
+
+Command::~Command() {
+
+}
+
+
+Animation::Animation() {
+	_cnv = NULL;
+	_program = NULL;
+	_scriptName = 0;
+	_frame = 0;
+	_z = 0;
+}
+
+Animation::~Animation() {
+	if (_program)
+		delete _program;
+
+	if (_scriptName)
+		free(_scriptName);
+
+	if (_cnv)
+		delete _cnv;
+}
+
+uint16 Animation::width() const {
+	if (!_cnv) return 0;
+	return _cnv->_width;
+}
+
+uint16 Animation::height() const {
+	if (!_cnv) return 0;
+	return _cnv->_height;
+}
+
+uint16 Animation::getFrameNum() const {
+	if (!_cnv) return 0;
+	return _cnv->_count;
+}
+
+byte* Animation::getFrameData(uint32 index) const {
+	if (!_cnv) return NULL;
+	return _cnv->getFramePtr(index);
+}
+
+
+Program::Program() {
+	_loopCounter = 0;
+	_locals = new LocalVariable[10];
+}
+
+Program::~Program() {
+	delete[] _locals;
+}
+
+
+Zone::Zone() {
+	_left = _top = _right = _bottom = 0;
+
+	_type = 0;
+	_flags = 0;
+}
+
+Zone::~Zone() {
+//	printf("~Zone(%s)\n", _label._text);
+
+	_label._cnv.free();
+
+	switch (_type & 0xFFFF) {
+	case kZoneExamine:
+		free(u.examine->_filename);
+		free(u.examine->_description);
+		delete u.examine;
+		break;
+
+	case kZoneDoor:
+		free(u.door->_location);
+		free(u.door->_background);
+		if (u.door->_cnv)
+			delete u.door->_cnv;
+		delete u.door;
+		break;
+
+	case kZoneSpeak:
+		delete u.speak->_dialogue;
+		delete u.speak;
+		break;
+
+	case kZoneGet:
+		free(u.get->_backup);
+		if (u.get->_cnv) {
+			u.get->_cnv->free();
+			delete u.get->_cnv;
+		}
+		delete u.get;
+		break;
+
+	case kZoneHear:
+		delete u.hear;
+		break;
+
+	case kZoneMerge:
+		delete u.merge;
+		break;
+
+	default:
+		break;
+	}
+}
+
+void Zone::getRect(Common::Rect& r) const {
+	r.left = _left;
+	r.right = _right;
+	r.top = _top;
+	r.bottom = _bottom;
+}
+
+void Zone::translate(int16 x, int16 y) {
+	_left += x;
+	_right += x;
+	_top += y;
+	_bottom += y;
+}
+
+uint16 Zone::width() const {
+	return _right - _left;
+}
+
+uint16 Zone::height() const {
+	return _bottom - _top;
+}
+
+Label::Label() {
+	_text = NULL;
+}
+
+Label::~Label() {
+	_cnv.free();
+	if (_text)
+		free(_text);
+}
+
+
+Answer::Answer() {
+	_text = NULL;
+	_mood = 0;
+	_following._question =  NULL;
+	_noFlags = 0;
+	_yesFlags = 0;
+}
+
+Answer::~Answer() {
+	if (_text)
+		free(_text);
+}
+
+Question::Question() {
+	_text = NULL;
+	_mood = 0;
+
+	for (uint32 i = 0; i < NUM_ANSWERS; i++)
+		_answers[i] = NULL;
+
+}
+
+Question::~Question() {
+
+	for (uint32 i = 0; i < NUM_ANSWERS; i++)
+		if (_answers[i]) delete _answers[i];
+
+	free(_text);
+}
+
+
+
+
+
+} // namespace Parallaction


Property changes on: scummvm/trunk/engines/parallaction/objects.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/parallaction/objects.h
===================================================================
--- scummvm/trunk/engines/parallaction/objects.h	                        (rev 0)
+++ scummvm/trunk/engines/parallaction/objects.h	2007-08-24 20:14:51 UTC (rev 28711)
@@ -0,0 +1,405 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef PARALLACTION_ZONE_H
+#define PARALLACTION_ZONE_H
+
+#include "common/list.h"
+
+#include "parallaction/defs.h"
+
+#include "parallaction/graphics.h"
+
+
+namespace Parallaction {
+
+struct Zone;
+struct Animation;
+struct Command;
+struct Question;
+struct Answer;
+struct Instruction;
+struct Program;
+
+enum ZoneTypes {
+	kZoneExamine	   = 1, 				// zone displays comment if activated
+	kZoneDoor		   = 2, 				// zone activated on click (after some walk if needed)
+	kZoneGet		   = 4, 				// for pickable items
+	kZoneMerge		   = 8, 				// tags items which can be merged in inventory
+	kZoneTaste		   = 0x10,				// NEVER USED
+	kZoneHear		   = 0x20,				// NEVER USED: they ran out of time before integrating sfx
+	kZoneFeel		   = 0x40,				// NEVER USED
+	kZoneSpeak		   = 0x80,				// tags NPCs the character can talk with
+	kZoneNone		   = 0x100, 			// used to prevent parsing on peculiar Animations
+	kZoneTrap		   = 0x200, 			// zone activated when character enters
+	kZoneYou		   = 0x400, 			// marks the character
+	kZoneCommand	   = 0x800
+};
+
+
+enum ZoneFlags {
+	kFlagsClosed		= 1,				// Zone: door is closed / switch is off
+	kFlagsActive		= 2,				// Zone/Animation: object is visible
+	kFlagsRemove		= 4,				// Zone/Animation: object is soon to be removed
+	kFlagsActing		= 8,				// Animation: script execution is active
+	kFlagsLocked		= 0x10, 			// Zone: door or switch cannot be toggled
+	kFlagsFixed 		= 0x20, 			// Zone: Zone item cannot be picked up
+	kFlagsNoName		= 0x40, 			// Zone with no name (used to prevent some kEvEnterZone events)
+	kFlagsNoMasked		= 0x80, 			// Animation is to be drawn ignoring z buffer
+	kFlagsLooping		= 0x100,			// Animation: script is to be executed repeatedly
+	kFlagsAdded 		= 0x200,			// NEVER USED in Nippon Safes
+	kFlagsCharacter 	= 0x400,			//
+	kFlagsNoWalk		= 0x800 			// Zone: character doesn't need to walk towards object to interact
+};
+
+
+enum CommandFlags {
+	kFlagsVisited		= 1,
+	kFlagsExit			= 0x10000000,
+	kFlagsEnter 		= 0x20000000,
+	kFlagsGlobal		= 0x40000000,
+
+	// BRA specific
+	kFlagsTestTrue		= 2
+};
+
+struct CommandData {
+	uint32			_flags;
+	Animation * 	_animation;
+	Zone*			_zone;
+	char*			_string;
+	uint16			_callable;
+	uint16			_object;
+	Common::Point	 _move;
+
+	// BRA specific
+	Common::Point	_startPos;
+	Common::Point	_startPos2;
+	uint			_lvalue;
+	int				_rvalue;
+	int				_zeta0;
+	int				_zeta1;
+	int				_zeta2;
+	int				_characterId;
+	char*			_string2;
+	int				_musicCommand;
+	int				_musicParm;
+
+
+	CommandData() {
+		memset(this, 0, sizeof(CommandData));
+	}
+
+	~CommandData() {
+		if (_string)
+			free(_string);
+		if (_string2)
+			free(_string2);
+	}
+};
+
+struct Command {
+	uint16			_id;
+	CommandData 	u;
+	uint32			_flagsOn;
+	uint32			_flagsOff;
+
+	Command();
+	~Command();
+};
+
+typedef ManagedList<Command*> CommandList;
+
+
+#define NUM_QUESTIONS		20
+#define NUM_ANSWERS		 	5
+
+struct Answer {
+	char*		_text;
+	uint16		_mood;
+	union {
+		Question*	_question;
+		char*		_name;
+	} _following;
+	CommandList	_commands;
+	uint32		_noFlags;
+	uint32		_yesFlags;
+
+	Answer();
+	~Answer();
+};
+
+struct Question {
+	char*		_text;
+	uint16		_mood;
+	Answer*		_answers[NUM_ANSWERS];
+
+	Question();
+	~Question();
+};
+
+struct Dialogue {
+	Question	*_questions[NUM_QUESTIONS];
+};
+
+struct GetData {	// size = 24
+	uint32			_icon;
+	Graphics::Surface		*_cnv;
+	byte		   *_backup;
+	uint16			field_14;		// unused
+	uint16			field_16;		// unused
+
+	GetData() {
+		_icon = 0;
+		_backup = NULL;
+		_cnv = NULL;
+	}
+};
+struct SpeakData {	// size = 36
+	char		_name[32];
+	Dialogue	*_dialogue;
+
+	SpeakData() {
+		_name[0] = '\0';
+		_dialogue = NULL;
+	}
+};
+struct ExamineData {	// size = 28
+	Graphics::Surface	*_cnv;
+	uint16		_opBase;		   // unused
+	uint16		field_12;			// unused
+	char*		_description;
+	char*		_filename;
+
+	ExamineData() {
+		_opBase = 0;
+		_description = NULL;
+		_filename = NULL;
+		_cnv = NULL;
+	}
+};
+struct DoorData {	// size = 28
+	char*	_location;
+	Cnv 	*_cnv;
+	byte*	_background;
+	Common::Point	_startPos;
+	uint16	_startFrame;
+
+	DoorData() {
+		_location = NULL;
+		_background = NULL;
+		_startFrame = 0;
+		_cnv = NULL;
+	}
+};
+struct HearData {	// size = 20
+	char		_name[20];
+	int			_channel;
+	int			_freq;
+
+	HearData() {
+		_channel = -1;
+		_freq = -1;
+		_name[0] = '\0';
+	}
+};
+struct MergeData {	// size = 12
+	uint32	_obj1;
+	uint32	_obj2;
+	uint32	_obj3;
+
+	MergeData() {
+		_obj1 = _obj2 = _obj3 = 0;
+	}
+};
+
+struct TypeData {
+	GetData 	*get;
+	SpeakData	*speak;
+	ExamineData *examine;
+	DoorData	*door;
+	HearData	*hear;
+	MergeData	*merge;
+
+	TypeData() {
+		get = NULL;
+		speak = NULL;
+		examine = NULL;
+		door = NULL;
+		hear = NULL;
+		merge = NULL;
+	}
+};
+
+struct Label {
+	char*				_text;
+	Graphics::Surface	_cnv;
+
+	Label();
+	~Label();
+};
+
+struct Zone {
+	int16 			_left;
+	int16			_top;
+	int16			_right;
+	int16			_bottom;
+	uint32			_type;
+	uint32			_flags;
+	Label       	_label;
+	uint16			field_2C;		// unused
+	uint16			field_2E;		// unused
+	TypeData		u;
+	CommandList 	_commands;
+	Common::Point	_moveTo;
+
+	Zone();
+	virtual ~Zone();
+
+	void getRect(Common::Rect& r) const;
+	void translate(int16 x, int16 y);
+	virtual uint16 width() const;
+	virtual uint16 height() const;
+};
+
+typedef Zone* ZonePointer;
+typedef ManagedList<ZonePointer> ZoneList;
+
+struct LocalVariable {
+	int16		_value;
+	int16		_min;
+	int16		_max;
+
+	LocalVariable() {
+		_value = 0;
+		_min = -10000;
+		_max = 10000;
+	}
+};
+
+union ScriptVar {
+	int16			_value;
+	int16*			_pvalue;
+	LocalVariable*	_local;
+
+	ScriptVar() {
+		_local = NULL;
+	}
+};
+
+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
+};
+
+typedef ManagedList<Instruction*> InstructionList;
+
+struct Instruction {
+	uint32	_index;
+	uint32	_flags;
+	struct {
+		Animation	*_a;
+		Zone		*_z;
+		uint32		_index;
+		ScriptVar		_loopCounter;
+	} _opBase;
+	ScriptVar	_opA;
+	ScriptVar	_opB;
+
+	// BRA specific
+	byte		_colors[3];
+	ScriptVar	_opC;
+	char		*_text;
+	char		*_text2;
+	int			_y;
+	InstructionList::iterator	_endif;
+
+	Instruction() {
+		memset(this, 0, sizeof(Instruction));
+	}
+
+	~Instruction() {
+		if (_text)
+			free(_text);
+		if (_text2)
+			free(_text2);
+	}
+};
+
+struct Program {
+	LocalVariable	*_locals;
+	uint16			_loopCounter;
+
+	InstructionList::iterator	_ip;
+	InstructionList::iterator	_loopStart;
+	InstructionList				_instructions;
+
+	Program();
+	~Program();
+};
+
+
+
+struct Animation : public Zone  {
+
+	Common::Point	_oldPos;
+	Program 	*_program;
+	Cnv 		*_cnv;
+	char		*_scriptName;
+	int16		_frame;
+	uint16		field_50;		// unused
+	int16		_z;
+	uint16		field_54;		// unused
+	uint16		field_56;		// unused
+	uint16		field_58;		// unused
+	uint16		field_5A;		// unused
+	uint16		field_5C;		// unused
+	uint16		field_5E;		// unused
+
+	Animation();
+	virtual ~Animation();
+	virtual uint16 width() const;
+	virtual uint16 height() const;
+	uint16 getFrameNum() const;
+	byte* getFrameData(uint32 index) const;
+};
+
+typedef Animation* AnimationPointer;
+typedef ManagedList<AnimationPointer> AnimationList;
+
+
+} // namespace Parallaction
+
+#endif


Property changes on: scummvm/trunk/engines/parallaction/objects.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Modified: scummvm/trunk/engines/parallaction/parallaction.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.cpp	2007-08-24 15:32:05 UTC (rev 28710)
+++ scummvm/trunk/engines/parallaction/parallaction.cpp	2007-08-24 20:14:51 UTC (rev 28711)
@@ -53,7 +53,6 @@
 uint16		_language = 0;
 char		_slideText[2][40];
 uint32		_engineFlags = 0;
-Zone	   *_activeZone = NULL;
 
 uint16		_score = 1;
 
@@ -128,11 +127,9 @@
 	delete _globalTable;
 
 	delete _callableNames;
-	delete _commandsNames;
-	delete _instructionNames;
+
 	delete _zoneTypeNames;
 	delete _zoneFlagNames;
-	delete _locationStmt;
 
 	_animations.remove(&_char._ani);
 
@@ -168,6 +165,7 @@
 
 	_backgroundInfo = 0;
 	_pathBuffer = 0;
+	_activeZone = 0;
 
 	_screenSize = _screenWidth * _screenHeight;
 
@@ -178,8 +176,6 @@
 
 	memset(_locationNames, 0, 120*32);
 
-	initOpcodes();
-
 	initInventory();	// needs to be pushed into subclass
 
 	_animations.push_front(&_char._ani);
@@ -840,7 +836,7 @@
 
 }
 
-int Table::lookup(const char* s) {
+uint16 Table::lookup(const char* s) {
 
 	for (uint16 i = 0; i < _used; i++) {
 		if (!scumm_stricmp(_data[i], s)) return i + 1;
@@ -849,14 +845,12 @@
 	return notFound;
 }
 
-void Parallaction::pushParserTables(const Opcode* opcodes, Table *statements) {
-
+void Parallaction::pushParserTables(OpcodeSet *opcodes, Table *statements) {
 	_opcodes.push(_currentOpcodes);
 	_statements.push(_currentStatements);
 
 	_currentOpcodes = opcodes;
 	_currentStatements = statements;
-
 }
 
 void Parallaction::popParserTables() {
@@ -870,161 +864,427 @@
 	assert(_currentOpcodes != 0);
 
 	_lookup = _currentStatements->lookup(_tokens[0]);
-	(this->*(_currentOpcodes[_lookup]))();
+	(*(*_currentOpcodes)[_lookup])();
 }
 
-void Parallaction::initOpcodes() {
 
-	static const Opcode op0[] = {
-		INSTRUCTION_PARSER(defLocal),	// invalid 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 = op0;
 
+Animation *Parallaction::findAnimation(const char *name) {
 
-	static const Opcode op1[] = {
-		INSTRUCTION_OPCODE(invalid),
-		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)
-	};
+	for (AnimationList::iterator it = _animations.begin(); it != _animations.end(); it++)
+		if (!scumm_stricmp((*it)->_label._text, name)) return *it;
 
-	_vm->_instructionOpcodes = op1;
+	return NULL;
+}
 
-	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(endcommands),	// endcommands
-		COMMAND_PARSER(endcommands)		// endzone
-	};
+void Parallaction::freeAnimations() {
+	_animations.clear();
+	return;
+}
 
-	_commandParsers = op2;
+int compareAnimationZ(const AnimationPointer &a1, const AnimationPointer &a2) {
+	if (a1->_z == a2->_z) return 0;
+	return (a1->_z < a2->_z ? -1 : 1);
+}
 
-	static const Opcode op3[] = {
-		COMMAND_OPCODE(invalid),
-		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)
-	};
+void Parallaction::sortAnimations() {
+	_char._ani._z = _char._ani.height() + _char._ani._top;
+	_animations.sort(compareAnimationZ);
+	return;
+}
 
-	_commandOpcodes = op3;
 
+void Parallaction::allocateLocationSlot(const char *name) {
+	// WORKAROUND: the original code erroneously incremented
+	// _currentLocationIndex, thus producing inconsistent
+	// savegames. This workaround modified the following loop
+	// and if-statement, so the code exactly matches the one
+	// in Big Red Adventure.
+	_currentLocationIndex = -1;
+	uint16 _di = 0;
+	while (_locationNames[_di][0] != '\0') {
+		if (!scumm_stricmp(_locationNames[_di], name)) {
+			_currentLocationIndex = _di;
+		}
+		_di++;
+	}
 
-	static const Opcode op4[] = {
-		LOCATION_PARSER(invalid),
-		LOCATION_PARSER(endlocation),
-		LOCATION_PARSER(location),
-		LOCATION_PARSER(disk),
-		LOCATION_PARSER(nodes),
-		LOCATION_PARSER(zone),
-		LOCATION_PARSER(animation),
-		LOCATION_PARSER(localflags),
-		LOCATION_PARSER(commands),
-		LOCATION_PARSER(acommands),
-		LOCATION_PARSER(flags),
-		LOCATION_PARSER(comment),
-		LOCATION_PARSER(endcomment),
-		LOCATION_PARSER(sound),
-		LOCATION_PARSER(music),
-		LOCATION_PARSER(redundant)	// for redundant endanimation
-	};
+	if (_di == 120)
+		error("No more location slots available. Please report this immediately to ScummVM team.");
 
-	_locationParsers = op4;
+	if (_currentLocationIndex  == -1) {
+		strcpy(_locationNames[_numLocations], name);
+		_currentLocationIndex = _numLocations;
 
+		_numLocations++;
+		_locationNames[_numLocations][0] = '\0';
+		_localFlags[_numLocations] = 0;
+	} else {
+		_localFlags[_currentLocationIndex] |= kFlagsVisited;	// 'visited'
+	}
+}
 
-	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)
-	};
+void Parallaction::freeLocation() {
+	debugC(7, kDebugLocation, "freeLocation");
 
-	_locationAnimParsers = op6;
+	_soundMan->stopSfx(0);
+	_soundMan->stopSfx(1);
+	_soundMan->stopSfx(2);
+	_soundMan->stopSfx(3);
 
-	_currentOpcodes = 0;
-	_currentStatements = 0;
+	if (_localFlagNames)
+		delete _localFlagNames;
 
+	// HACK: prevents leakage. A routine like this
+	// should allocate memory at all, though.
+	if ((_engineFlags & kEngineQuit) == 0) {
+		_localFlagNames = new Table(120);
+		_localFlagNames->addData("visited");
+	}
+
+	_location._walkNodes.clear();
+
+	freeZones();
+	freeAnimations();
+
+	if (_location._comment) {
+		free(_location._comment);
+	}
+	_location._comment = NULL;
+
+	_location._commands.clear();
+	_location._aCommands.clear();
+
+	return;
 }
 
+
+
+
+void Parallaction::freeBackground() {
+
+	if (!_backgroundInfo)
+		return;
+
+	_backgroundInfo->bg.free();
+	_backgroundInfo->mask.free();
+	_backgroundInfo->path.free();
+
+	_pathBuffer = 0;
+
+}
+
+void Parallaction::setBackground(const char* name, const char* mask, const char* path) {
+
+	_disk->loadScenery(*_backgroundInfo, name, mask, path);
+
+	_gfx->setPalette(_backgroundInfo->palette);
+	_gfx->_palette.clone(_backgroundInfo->palette);
+	_gfx->setBackground(&_backgroundInfo->bg);
+
+	if (_backgroundInfo->mask.data)
+		_gfx->setMask(&_backgroundInfo->mask);
+
+	if (_backgroundInfo->path.data)
+		_pathBuffer = &_backgroundInfo->path;
+
+	return;
+}
+
+void Parallaction::showLocationComment(const char *text, bool end) {
+
+	_gfx->setFont(_dialogueFont);
+
+	int16 w, h;
+	_gfx->getStringExtent(const_cast<char*>(text), 130, &w, &h);
+
+	Common::Rect r(w + (end ? 5 : 10), h + 5);
+	r.moveTo(5, 5);
+
+	_gfx->floodFill(Gfx::kBitFront, r, 0);
+	r.grow(-2);
+	_gfx->floodFill(Gfx::kBitFront, r, 1);
+	_gfx->displayWrappedString(const_cast<char*>(text), 3, 5, 0, 130);
+
+	_gfx->updateScreen();
+
+	return;
+}
+
+void Parallaction::switchBackground(const char* background, const char* mask) {
+//	printf("switchBackground(%s)", name);
+
+	Palette pal;
+
+	uint16 v2 = 0;
+	if (!scumm_stricmp(background, "final")) {
+		_gfx->clearScreen(Gfx::kBitBack);
+		for (uint16 _si = 0; _si <= 32; _si++) {
+			pal.setEntry(_si, v2, v2, v2);
+			v2 += 4;
+		}
+
+		g_system->delayMillis(20);
+		_gfx->setPalette(pal);
+		_gfx->updateScreen();
+	}
+
+	setBackground(background, mask, mask);
+
+	return;
+}
+
+extern Zone     *_hoverZone;
+extern Job     *_jDrawLabel;
+extern Job     *_jEraseLabel;
+
+void Parallaction::showSlide(const char *name) {
+
+	BackgroundInfo info;
+
+	_disk->loadSlide(info, name);
+
+	// TODO: avoid using screen buffers for displaying slides. Using a generic buffer
+	// allows for positioning of graphics as needed by Big Red Adventure.
+	// The main problem lies with menu, which relies on multiple buffers, mainly because
+	// it is crappy code.
+	_gfx->setBackground(&info.bg);
+	_gfx->setPalette(info.palette);
+	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+
+	info.bg.free();
+	info.mask.free();
+	info.path.free();
+
+	return;
+}
+
+/*
+	changeLocation handles transitions between locations, and is able to display slides
+	between one and the other. The input parameter 'location' exists in some flavours:
+
+    1 - [S].slide.[L]{.[C]}
+	2 - [L]{.[C]}
+
+    where:
+
+	[S] is the slide to be shown
+    [L] is the location to switch to (immediately in case 2, or right after slide [S] in case 1)
+    [C] is the character to be selected, and is optional
+
+    The routine tells one form from the other by searching for the '.slide.'
+
+    NOTE: there exists one script in which [L] is not used in the case 1, but its use
+		  is commented out, and would definitely crash the current implementation.
+*/
+void Parallaction::changeLocation(char *location) {
+	debugC(1, kDebugLocation, "changeLocation(%s)", location);
+
+	_soundMan->playLocationMusic(location);
+
+	// WORKAROUND: this if-statement has been added to avoid crashes caused by
+	// execution of label jobs after a location switch. The other workaround in
+	// Parallaction::runGame should have been rendered useless by this one.
+	if (_jDrawLabel != NULL) {
+		removeJob(_jDrawLabel);
+		removeJob(_jEraseLabel);
+		_jDrawLabel = NULL;
+		_jEraseLabel = NULL;
+	}
+
+
+	_hoverZone = NULL;
+	if (_engineFlags & kEngineBlockInput) {
+		changeCursor( kCursorArrow );
+	}
+
+	_animations.remove(&_char._ani);
+
+	freeLocation();
+	char buf[100];
+	strcpy(buf, location);
+
+	Common::StringList list;
+	char *tok = strtok(location, ".");
+	while (tok) {
+		list.push_back(tok);
+		tok = strtok(NULL, ".");
+	}
+
+	if (list.size() < 1 || list.size() > 4)
+		error("changeLocation: ill-formed location string '%s'", location);
+
+	if (list.size() > 1) {
+		if (list[1] == "slide") {
+			showSlide(list[0].c_str());
+			_gfx->setFont(_menuFont);
+			_gfx->displayCenteredString(14, _slideText[0]); // displays text on screen
+			_gfx->updateScreen();
+			waitUntilLeftClick();
+
+			list.remove_at(0);		// removes slide name
+			list.remove_at(0);		// removes 'slide'
+		}
+
+		// list is now only [L].{[C]} (see above comment)
+		if (list.size() == 2) {
+			changeCharacter(list[1].c_str());
+			strcpy(_characterName, list[1].c_str());
+		}
+	}
+
+	_animations.push_front(&_char._ani);
+
+	strcpy(_saveData1, list[0].c_str());
+	parseLocation(list[0].c_str());
+
+	_char._ani._oldPos.x = -1000;
+	_char._ani._oldPos.y = -1000;
+
+	_char._ani.field_50 = 0;
+	if (_location._startPosition.x != -1000) {
+		_char._ani._left = _location._startPosition.x;
+		_char._ani._top = _location._startPosition.y;
+		_char._ani._frame = _location._startFrame;
+		_location._startPosition.y = -1000;
+		_location._startPosition.x = -1000;
+	}
+
+
+	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2);
+	_gfx->setBlackPalette();

@@ Diff output truncated at 100000 characters. @@

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