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

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Tue Feb 24 12:20:45 CET 2009


Revision: 38838
          http://scummvm.svn.sourceforge.net/scummvm/?rev=38838&view=rev
Author:   peres001
Date:     2009-02-24 11:20:45 +0000 (Tue, 24 Feb 2009)

Log Message:
-----------
Implemented follower support, except that:
* follower is forgotten when location changes (see freeLocation)
* the final walking frame is screwed

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/exec_br.cpp
    scummvm/trunk/engines/parallaction/objects.h
    scummvm/trunk/engines/parallaction/parallaction.cpp
    scummvm/trunk/engines/parallaction/parallaction.h
    scummvm/trunk/engines/parallaction/parallaction_br.cpp
    scummvm/trunk/engines/parallaction/parser_br.cpp
    scummvm/trunk/engines/parallaction/walk.cpp
    scummvm/trunk/engines/parallaction/walk.h

Modified: scummvm/trunk/engines/parallaction/exec_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/exec_br.cpp	2009-02-24 09:18:20 UTC (rev 38837)
+++ scummvm/trunk/engines/parallaction/exec_br.cpp	2009-02-24 11:20:45 UTC (rev 38838)
@@ -116,6 +116,11 @@
 DECLARE_COMMAND_OPCODE(location) {
 	warning("Parallaction_br::cmdOp_location command not yet implemented");
 
+	_vm->_location._startPosition = _ctxt.cmd->u._startPos;
+	_vm->_location._startFrame = 0; // TODO: verify this against the disassembly!f
+	_vm->_location._followerStartPosition = _ctxt.cmd->u._startPos2;
+	_vm->_location._followerStartFrame = 0;
+
 	// TODO: handle startPos and startPos2
 	_vm->scheduleLocationSwitch(_ctxt.cmd->u._string);
 }

Modified: scummvm/trunk/engines/parallaction/objects.h
===================================================================
--- scummvm/trunk/engines/parallaction/objects.h	2009-02-24 09:18:20 UTC (rev 38837)
+++ scummvm/trunk/engines/parallaction/objects.h	2009-02-24 11:20:45 UTC (rev 38838)
@@ -229,6 +229,9 @@
 	GfxObj	*gfxobj;
 	Common::Point	_startPos;
 	uint16	_startFrame;
+	// BRA specific
+	Common::Point	_startPos2;
+	uint16	_startFrame2;
 
 	DoorData() {
 		_location = NULL;

Modified: scummvm/trunk/engines/parallaction/parallaction.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.cpp	2009-02-24 09:18:20 UTC (rev 38837)
+++ scummvm/trunk/engines/parallaction/parallaction.cpp	2009-02-24 11:20:45 UTC (rev 38838)
@@ -111,6 +111,9 @@
 	_location._startPosition.x = -1000;
 	_location._startPosition.y = -1000;
 	_location._startFrame = 0;
+	_location._followerStartPosition.x = -1000;
+	_location._followerStartPosition.y = -1000;
+	_location._followerStartFrame = 0;
 	_objects = 0;
 
 	_screenSize = _screenWidth * _screenHeight;

Modified: scummvm/trunk/engines/parallaction/parallaction.h
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.h	2009-02-24 09:18:20 UTC (rev 38837)
+++ scummvm/trunk/engines/parallaction/parallaction.h	2009-02-24 11:20:45 UTC (rev 38838)
@@ -153,6 +153,8 @@
 	int			_zeta1;
 	int			_zeta2;
 	CommandList		_escapeCommands;
+	Common::Point	_followerStartPosition;
+	uint16			_followerStartFrame;
 
 protected:
 	void freeAnimations();

Modified: scummvm/trunk/engines/parallaction/parallaction_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction_br.cpp	2009-02-24 09:18:20 UTC (rev 38837)
+++ scummvm/trunk/engines/parallaction/parallaction_br.cpp	2009-02-24 11:20:45 UTC (rev 38838)
@@ -202,6 +202,8 @@
 
 	_gfx->freeLocationObjects();
 
+	// TODO: avoid removing needed animations from 'common.slf'
+	// when cleaning up!!!
 	_location._animations.remove(_char._ani);
 	_location.cleanup(removeAll);
 	_location._animations.push_front(_char._ani);
@@ -261,15 +263,27 @@
 	// load new location
 	parseLocation(location);
 
-	setFollower(_followerName);
-
 	if (_location._startPosition.x != -1000) {
-		_char.setFoot(_location._startPosition);
+		_char._ani->setFoot(_location._startPosition);
 		_char._ani->setF(_location._startFrame);
-		_location._startPosition.y = -1000;
-		_location._startPosition.x = -1000;
 	}
 
+	// re-link the follower animation
+	setFollower(_followerName);
+	if (_follower) {
+		Common::Point p = _location._followerStartPosition;
+		if (p.x == -1000) {
+			_char._ani->getFoot(p);
+		}
+		_follower->setFoot(p);
+		_follower->setF(_location._followerStartFrame);
+	}
+
+	_location._startPosition.x = -1000;
+	_location._startPosition.y = -1000;
+	_location._followerStartPosition.x = -1000;
+	_location._followerStartPosition.y = -1000;
+
 	// kFlagsRemove is cleared because the character is visible by default.
 	// Commands can hide the character, anyway.
 	_char._ani->_flags &= ~kFlagsRemove;

Modified: scummvm/trunk/engines/parallaction/parser_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parser_br.cpp	2009-02-24 09:18:20 UTC (rev 38837)
+++ scummvm/trunk/engines/parallaction/parser_br.cpp	2009-02-24 11:20:45 UTC (rev 38838)
@@ -525,6 +525,8 @@
 	ctxt.cmd->u._string = strdup(_tokens[1]);
 	ctxt.nextToken++;
 
+	ctxt.cmd->u._startPos.x = -1000;
+	ctxt.cmd->u._startPos2.x = -1000;
 	if (_tokens[ctxt.nextToken][0] != '\0') {
 		if (isdigit(_tokens[ctxt.nextToken][0]) || _tokens[ctxt.nextToken][0] == '-') {
 			ctxt.cmd->u._startPos.x = atoi(_tokens[ctxt.nextToken]);

Modified: scummvm/trunk/engines/parallaction/walk.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/walk.cpp	2009-02-24 09:18:20 UTC (rev 38837)
+++ scummvm/trunk/engines/parallaction/walk.cpp	2009-02-24 11:20:45 UTC (rev 38838)
@@ -368,15 +368,18 @@
 
 void PathWalker_BR::setCharacterPath(AnimationPtr a, uint16 x, uint16 y) {
 	_character._a = a;
-	_ch = _character;
-	buildPath(x, y);
+	_character._first = true;
+	_character._fieldC = 1;
+	buildPath(_character, x, y);
 	_character._active = true;
 }
 
 void PathWalker_BR::setFollowerPath(AnimationPtr a, uint16 x, uint16 y) {
 	_follower._a = a;
-	_ch = _follower;
-	buildPath(x, y);
+	_follower._first = true;
+	_follower._fieldC = 1;
+	_follower._walkDelay = 5;
+	buildPath(_follower, x - 50, y);
 	_follower._active = true;
 }
 
@@ -386,17 +389,17 @@
 }
 
 
-void PathWalker_BR::buildPath(uint16 x, uint16 y) {
+void PathWalker_BR::buildPath(State &s, uint16 x, uint16 y) {
 	Common::Point foot;
-	_ch._a->getFoot(foot);
+	s._a->getFoot(foot);
 
 	debugC(1, kDebugWalk, "buildPath: from (%i, %i) to (%i, %i)", foot.x, foot.y, x, y);
-	_ch._walkPath.clear();
+	s._walkPath.clear();
 
 	// look for easy path first
 	Common::Point dest(x, y);
 	if (directPathExists(foot, dest)) {
-		_ch._walkPath.push_back(dest);
+		s._walkPath.push_back(dest);
 		debugC(3, kDebugWalk, "buildPath: direct path found");
 		return;
 	}
@@ -404,13 +407,13 @@
 	// look for short circuit cases
 	ZonePtr z0 = _vm->hitZone(kZonePath, x, y);
 	if (!z0) {
-		_ch._walkPath.push_back(dest);
+		s._walkPath.push_back(dest);
 		debugC(3, kDebugWalk, "buildPath: corner case 0");
 		return;
 	}
 	ZonePtr z1 = _vm->hitZone(kZonePath, foot.x, foot.y);
 	if (!z1 || z1 == z0) {
-		_ch._walkPath.push_back(dest);
+		s._walkPath.push_back(dest);
 		debugC(3, kDebugWalk, "buildPath: corner case 1");
 		return;
 	}
@@ -419,7 +422,7 @@
 	int id = atoi(z0->_name);
 
 	if (z1->u.path->_lists[id].empty()) {
-		_ch._walkPath.clear();
+		s._walkPath.clear();
 		debugC(3, kDebugWalk, "buildPath: no path");
 		return;
 	}
@@ -427,39 +430,34 @@
 	PointList::iterator b = z1->u.path->_lists[id].begin();
 	PointList::iterator e = z1->u.path->_lists[id].end();
 	for ( ; b != e; b++) {
-		_ch._walkPath.push_front(*b);
+		s._walkPath.push_front(*b);
 	}
-	_ch._walkPath.push_back(dest);
+	s._walkPath.push_back(dest);
 	debugC(3, kDebugWalk, "buildPath: complex path");
 }
 
 
-void PathWalker_BR::finalizeWalk() {
+void PathWalker_BR::finalizeWalk(State &s) {
 	_engineFlags &= ~kEngineWalking;
-	_ch._first = true;
-	_ch._fieldC = 1;
 
 	Common::Point foot;
-	_ch._a->getFoot(foot);
+	_character._a->getFoot(foot);
 
 	ZonePtr z = _vm->hitZone(kZoneDoor, foot.x, foot.y);
 	if (z && ((z->_flags & kFlagsClosed) == 0)) {
 		_vm->_location._startPosition = z->u.door->_startPos; // foot pos
 		_vm->_location._startFrame = z->u.door->_startFrame;
 
-#if 0
 		// TODO: implement working follower. Must find out a location in which the code is
 		// used and which is stable enough.
-		_followerFootInit.x = -1;
-		if (_follower && z->u.door->startPos2.x != -1) {
-			_followerFootInit.x = z->u.door->startPos2.x;	// foot pos
-			_followerFootInit.y = z->u.door->startPos2.y;	// foot pos
+		if (_follower._active) {
+			_vm->_location._followerStartPosition = z->u.door->_startPos2;	// foot pos
+			_vm->_location._followerStartFrame = z->u.door->_startFrame2;
+		} else {
+			_vm->_location._followerStartPosition.x = -1000;
+			_vm->_location._followerStartPosition.y = -1000;
+			_vm->_location._followerStartFrame = 0;
 		}
-		_followerFootInit.z = -1;
-		if (_follower && z->u.door->startPos2.z != -1) {
-			_followerFootInit.z = z->u.door->startPos2.z;	// foot pos
-		}
-#endif
 
 		_vm->scheduleLocationSwitch(z->u.door->_location);
 		_vm->_cmdExec->run(z->_commands, z);
@@ -467,8 +465,6 @@
 
 #if 0
 	// TODO: Input::walkTo must be extended to support destination frame in addition to coordinates
-	// TODO: the frame argument must be passed to PathWalker through PathBuilder, so probably
-	// a merge between the two Path managers is the right solution
 	if (_engineFlags & FINAL_WALK_FRAME) {	// this flag is set in readInput()
 		_engineFlags &= ~FINAL_WALK_FRAME;
 		_ch._a->_frame = _moveToF; 	// from readInput()...
@@ -478,7 +474,7 @@
 	_ch._a->setFoot(foot);
 #endif
 
-	_ch._a->setF(_ch._dirFrame);	// temporary solution
+	s._a->setF(s._dirFrame);	// temporary solution
 
 #if 0
 	// TODO: support scrolling ;)
@@ -488,7 +484,7 @@
 	if (foot.y < 80) _gfx->scrollUp(100);
 #endif
 
-	return;
+	s._active = false;
 }
 
 void PathWalker_BR::walk() {
@@ -496,12 +492,12 @@
 		return;
 	}
 
-	bool finalize = doWalk(_character);
+	debugC(3, kDebugWalk, "PathWalker_BR::walk()");
+
+	doWalk(_character);
 	doWalk(_follower);
 
-	if (finalize) {
-		finalizeWalk();
-	}
+	debugC(3, kDebugWalk, "PathWalker_BR::walk() -> done");
 }
 
 void PathWalker_BR::checkTrap(const Common::Point &p) {
@@ -530,12 +526,12 @@
 	_vm->_zoneTrap = z;
 }
 
-bool PathWalker_BR::doWalk(State &s) {
+void PathWalker_BR::doWalk(State &s) {
 	if (!s._active) {
-		return false;
+		return;
 	}
 
-	_ch = s;
+	debugC(3, kDebugWalk, "PathWalker_BR::doWalk(%s)", s._a->_name);
 
 #if 0
 	// TODO: support delays in walking. This requires extending Input::walkIo().
@@ -547,119 +543,122 @@
 			Script *script = findScript(_ch._ani->_scriptName);
 			script->_nextCommand = script->firstCommand;
 		}
-		return false;
+		return;
 	}
 #endif
 
-	if (_ch._fieldC == 0) {
-		_ch._walkPath.erase(_ch._walkPath.begin());
+	if (s._fieldC == 0) {
+		s._walkPath.erase(s._walkPath.begin());
 
-		if (_ch._walkPath.empty()) {
-			debugC(3, kDebugWalk, "PathWalker_BR::walk, case 0");
-			return true;
+		if (s._walkPath.empty()) {
+			finalizeWalk(s);
+			debugC(3, kDebugWalk, "PathWalker_BR::doWalk, case 0");
+			return;
 		} else {
-			debugC(3, kDebugWalk, "PathWalker_BR::walk, moving to next node");
+			debugC(3, kDebugWalk, "PathWalker_BR::doWalk, moving to next node");
 		}
 	}
 
-	_ch._a->getFoot(_ch._startFoot);
+	s._a->getFoot(s._startFoot);
 
-	uint scale = _vm->_location.getScale(_ch._startFoot.y);
+	uint scale = _vm->_location.getScale(s._startFoot.y);
 	int xStep = (scale * 16) / 100 + 1;
 	int yStep = (scale * 10) / 100 + 1;
 
 	debugC(9, kDebugWalk, "calculated step: (%i, %i)", xStep, yStep);
 
-	_ch._fieldC = 0;
-	_ch._step++;
-	_ch._step %= 8;
+	s._fieldC = 0;
+	s._step++;
+	s._step %= 8;
 
 	int maxX = _vm->_gfx->_backgroundInfo->width;
 	int minX = 0;
 	int maxY = _vm->_gfx->_backgroundInfo->height;
 	int minY = 0;
 
-	int walkFrame = _ch._step;
-	_ch._dirFrame = 0;
-	Common::Point newpos(_ch._startFoot), delta;
+	int walkFrame = s._step;
+	s._dirFrame = 0;
+	Common::Point newpos(s._startFoot), delta;
 
-	Common::Point p(*_ch._walkPath.begin());
+	Common::Point p(*s._walkPath.begin());
 
-	if (_ch._startFoot.y < p.y && _ch._startFoot.y < maxY && IS_PATH_CLEAR(_ch._startFoot.x, yStep + _ch._startFoot.y)) {
-		if (yStep + _ch._startFoot.y <= p.y) {
-			_ch._fieldC = 1;
+	if (s._startFoot.y < p.y && s._startFoot.y < maxY && IS_PATH_CLEAR(s._startFoot.x, yStep + s._startFoot.y)) {
+		if (yStep + s._startFoot.y <= p.y) {
+			s._fieldC = 1;
 			delta.y = yStep;
-			newpos.y = yStep + _ch._startFoot.y;
+			newpos.y = yStep + s._startFoot.y;
 		} else {
-			delta.y = p.y - _ch._startFoot.y;
+			delta.y = p.y - s._startFoot.y;
 			newpos.y = p.y;
 		}
-		_ch._dirFrame = 9;
+		s._dirFrame = 9;
 	} else
-	if (_ch._startFoot.y > p.y && _ch._startFoot.y > minY && IS_PATH_CLEAR(_ch._startFoot.x, _ch._startFoot.y - yStep)) {
-		if (_ch._startFoot.y - yStep >= p.y) {
-			_ch._fieldC = 1;
+	if (s._startFoot.y > p.y && s._startFoot.y > minY && IS_PATH_CLEAR(s._startFoot.x, s._startFoot.y - yStep)) {
+		if (s._startFoot.y - yStep >= p.y) {
+			s._fieldC = 1;
 			delta.y = yStep;
-			newpos.y = _ch._startFoot.y - yStep;
+			newpos.y = s._startFoot.y - yStep;
 		} else {
-			delta.y = _ch._startFoot.y - p.y;
+			delta.y = s._startFoot.y - p.y;
 			newpos.y = p.y;
 		}
-		_ch._dirFrame = 0;
+		s._dirFrame = 0;
 	}
 
-	if (_ch._startFoot.x < p.x && _ch._startFoot.x < maxX && IS_PATH_CLEAR(_ch._startFoot.x + xStep, _ch._startFoot.y)) {
-		if (_ch._startFoot.x + xStep <= p.x) {
-			_ch._fieldC = 1;
+	if (s._startFoot.x < p.x && s._startFoot.x < maxX && IS_PATH_CLEAR(s._startFoot.x + xStep, s._startFoot.y)) {
+		if (s._startFoot.x + xStep <= p.x) {
+			s._fieldC = 1;
 			delta.x = xStep;
-			newpos.x = xStep + _ch._startFoot.x;
+			newpos.x = xStep + s._startFoot.x;
 		} else {
-			delta.x = p.x - _ch._startFoot.x;
+			delta.x = p.x - s._startFoot.x;
 			newpos.x = p.x;
 		}
 		if (delta.y < delta.x) {
-			_ch._dirFrame = 18;	// right
+			s._dirFrame = 18;	// right
 		}
 	} else
-	if (_ch._startFoot.x > p.x && _ch._startFoot.x > minX && IS_PATH_CLEAR(_ch._startFoot.x - xStep, _ch._startFoot.y)) {
-		if (_ch._startFoot.x - xStep >= p.x) {
-			_ch._fieldC = 1;
+	if (s._startFoot.x > p.x && s._startFoot.x > minX && IS_PATH_CLEAR(s._startFoot.x - xStep, s._startFoot.y)) {
+		if (s._startFoot.x - xStep >= p.x) {
+			s._fieldC = 1;
 			delta.x = xStep;
-			newpos.x = _ch._startFoot.x - xStep;
+			newpos.x = s._startFoot.x - xStep;
 		} else {
-			delta.x = _ch._startFoot.x - p.x;
+			delta.x = s._startFoot.x - p.x;
 			newpos.x = p.x;
 		}
 		if (delta.y < delta.x) {
-			_ch._dirFrame = 27;	// left
+			s._dirFrame = 27;	// left
 		}
 	}
 
-	debugC(9, kDebugWalk, "foot (%i, %i) dest (%i, %i) deltas = %i/%i ", _ch._startFoot.x, _ch._startFoot.y, p.x, p.y, delta.x, delta.y);
+	debugC(9, kDebugWalk, "foot (%i, %i) dest (%i, %i) deltas = %i/%i ", s._startFoot.x, s._startFoot.y, p.x, p.y, delta.x, delta.y);
 
-	if (_ch._fieldC) {
-		debugC(9, kDebugWalk, "PathWalker_BR::walk, foot moved from (%i, %i) to (%i, %i)", _ch._startFoot.x, _ch._startFoot.y, newpos.x, newpos.y);
-		_ch._a->setF(walkFrame + _ch._dirFrame + 1);
-		_ch._startFoot.x = newpos.x;
-		_ch._startFoot.y = newpos.y;
-		_ch._a->setFoot(_ch._startFoot);
-		_ch._a->setZ(newpos.y);
+	if (s._fieldC) {
+		debugC(9, kDebugWalk, "PathWalker_BR::doWalk, foot moved from (%i, %i) to (%i, %i)", s._startFoot.x, s._startFoot.y, newpos.x, newpos.y);
+		s._a->setF(walkFrame + s._dirFrame + 1);
+		s._startFoot.x = newpos.x;
+		s._startFoot.y = newpos.y;
+		s._a->setFoot(s._startFoot);
+		s._a->setZ(newpos.y);
 	}
 
-	if (_ch._fieldC || !_ch._walkPath.empty()) {
+	if (s._fieldC || !s._walkPath.empty()) {
 		Common::Point p;
-		_ch._a->getFoot(p);
+		s._a->getFoot(p);
 		checkTrap(p);
-		debugC(3, kDebugWalk, "PathWalker_BR::walk, case 1");
-		return false;
+		debugC(3, kDebugWalk, "PathWalker_BR::doWalk, case 1");
+		return;
 	}
 
-	debugC(3, kDebugWalk, "PathWalker_BR::walk, case 2");
-	return true;
+	debugC(3, kDebugWalk, "PathWalker_BR::doWalk, case 2");
+	finalizeWalk(s);
+	return;
 }
 
-PathWalker_BR::PathWalker_BR() : _ch(_character) {
-
+PathWalker_BR::PathWalker_BR() {
+	_character._active = false;
+	_follower._active = false;
 }
 
 

Modified: scummvm/trunk/engines/parallaction/walk.h
===================================================================
--- scummvm/trunk/engines/parallaction/walk.h	2009-02-24 09:18:20 UTC (rev 38837)
+++ scummvm/trunk/engines/parallaction/walk.h	2009-02-24 11:20:45 UTC (rev 38838)
@@ -102,12 +102,10 @@
 	State _character;
 	State _follower;
 
-	State &_ch;
-
-	void finalizeWalk();
+	void finalizeWalk(State &s);
 	bool directPathExists(const Common::Point &from, const Common::Point &to);
-	void buildPath(uint16 x, uint16 y);
-	bool doWalk(State &s);
+	void buildPath(State &s, uint16 x, uint16 y);
+	void doWalk(State &s);
 	void checkTrap(const Common::Point &p);
 
 public:


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




More information about the Scummvm-git-logs mailing list