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

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Sun Jul 13 15:04:36 CEST 2008


Revision: 33033
          http://scummvm.svn.sourceforge.net/scummvm/?rev=33033&view=rev
Author:   peres001
Date:     2008-07-13 06:04:36 -0700 (Sun, 13 Jul 2008)

Log Message:
-----------
More refactoring of walk code.

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

Modified: scummvm/trunk/engines/parallaction/parallaction.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.cpp	2008-07-13 12:26:15 UTC (rev 33032)
+++ scummvm/trunk/engines/parallaction/parallaction.cpp	2008-07-13 13:04:36 UTC (rev 33033)
@@ -503,6 +503,34 @@
 }
 
 
+enum {
+	WALK_LEFT = 0,
+	WALK_RIGHT = 1,
+	WALK_DOWN = 2,
+	WALK_UP = 3
+};
+
+struct WalkFrames {
+	int16 stillFrame[4];
+	int16 firstWalkFrame[4];
+	int16 numWalkFrames[4];
+	int16 frameRepeat[4];
+};
+
+WalkFrames _char20WalkFrames = {
+	{  0,  7, 14, 17 },
+	{  1,  8, 15, 18 },
+	{  6,  6,  2,  2 },
+	{  2,  2,  4,  4 }
+};
+
+WalkFrames _char24WalkFrames = {
+	{  0,  9, 18, 21 },
+	{  1, 10, 19, 22 },
+	{  8,  8,  2,  2 },
+	{  2,  2,  4,  4 }
+};
+
 const char Character::_prefixMini[] = "mini";
 const char Character::_suffixTras[] = "tras";
 const char Character::_empty[] = "\0";
@@ -513,6 +541,9 @@
 	_head = NULL;
 	_objs = NULL;
 
+	_direction = WALK_DOWN;
+	_step = 0;
+
 	_dummy = false;
 
 	_ani->_left = 150;
@@ -633,4 +664,29 @@
 }
 
 
+
+
+
+void Character::updateDirection(const Common::Point& pos, const Common::Point& to) {
+
+	Common::Point dist(to.x - pos.x, to.y - pos.y);
+	WalkFrames *frames = (_ani->getFrameNum() == 20) ? &_char20WalkFrames : &_char24WalkFrames;
+
+	_step++;
+
+	if (dist.x == 0 && dist.y == 0) {
+		_ani->_frame = frames->stillFrame[_direction];
+		return;
+	}
+
+	if (dist.x < 0)
+		dist.x = -dist.x;
+	if (dist.y < 0)
+		dist.y = -dist.y;
+
+	_direction = (dist.x > dist.y) ? ((to.x > pos.x) ? WALK_LEFT : WALK_RIGHT) : ((to.y > pos.y) ? WALK_DOWN : WALK_UP);
+	_ani->_frame = frames->firstWalkFrame[_direction] + (_step / frames->frameRepeat[_direction]) % frames->numWalkFrames[_direction];
+}
+
+
 } // namespace Parallaction

Modified: scummvm/trunk/engines/parallaction/parallaction.h
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.h	2008-07-13 12:26:15 UTC (rev 33032)
+++ scummvm/trunk/engines/parallaction/parallaction.h	2008-07-13 13:04:36 UTC (rev 33033)
@@ -229,12 +229,17 @@
 	static const char _suffixTras[];
 	static const char _empty[];
 
+	int16		_direction, _step;
+
 public:
 	void setName(const char *name);
 	const char *getName() const;
 	const char *getBaseName() const;
 	const char *getFullName() const;
 	bool dummy() const;
+
+	void updateDirection(const Common::Point& pos, const Common::Point& to);
+
 };
 
 
@@ -263,7 +268,7 @@
 
 	void		finalizeWalk(Character &character);
 	int16		selectWalkFrame(Character &character, const Common::Point& pos, const WalkNodePtr to);
-	void		clipMove(Common::Point& pos, const WalkNodePtr to);
+	void		clipMove(Common::Point& pos, const Common::Point& to);
 
 	ZonePtr		findZone(const char *name);
 	ZonePtr		hitZone(uint32 type, uint16 x, uint16 y);
@@ -357,7 +362,7 @@
 
 	void		displayComment(ExamineData *data);
 
-	void		checkDoor(Character &character);
+	void		checkDoor(const Common::Point &foot);
 
 	void		freeCharacter();
 
@@ -384,6 +389,7 @@
 
 	void		beep();
 
+	ZonePtr		_zoneTrap;
 
 public:
 //	const char **_zoneFlagNamesRes;

Modified: scummvm/trunk/engines/parallaction/parallaction_ns.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction_ns.cpp	2008-07-13 12:26:15 UTC (rev 33032)
+++ scummvm/trunk/engines/parallaction/parallaction_ns.cpp	2008-07-13 13:04:36 UTC (rev 33033)
@@ -305,6 +305,8 @@
 	_gfx->hideFloatingLabel();
 	_gfx->freeLabels();
 
+	_zoneTrap = nullZonePtr;
+
 	_input->stopHovering();
 	if (_engineFlags & kEngineBlockInput) {
 		setArrowCursor();

Modified: scummvm/trunk/engines/parallaction/walk.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/walk.cpp	2008-07-13 12:26:15 UTC (rev 33032)
+++ scummvm/trunk/engines/parallaction/walk.cpp	2008-07-13 13:04:36 UTC (rev 33033)
@@ -27,15 +27,7 @@
 
 namespace Parallaction {
 
-// should be reset on location switch
-static uint16 _doorData1 = 1000;
-static ZonePtr _zoneTrap;
 
-// should be reset on character switch
-static uint16	walkData1 = 0;
-static uint16	walkData2 = 0;	// next walk frame
-
-
 inline byte PathBuffer::getValue(uint16 x, uint16 y) {
 	byte m = data[(x >> 3) + y * internalWidth];
 	uint n = (_vm->getPlatform() == Common::kPlatformPC) ? (x & 7) : (7 - (x & 7));
@@ -261,99 +253,43 @@
 	return 1;
 }
 
-void Parallaction::clipMove(Common::Point& pos, const WalkNodePtr to) {
+void Parallaction::clipMove(Common::Point& pos, const Common::Point& to) {
 
-	if ((pos.x < to->_x) && (pos.x < _pathBuffer->w) && (_pathBuffer->getValue(pos.x + 2, pos.y) != 0)) {
-		pos.x = (pos.x + 2 < to->_x) ? pos.x + 2 : to->_x;
+	if ((pos.x < to.x) && (pos.x < _pathBuffer->w) && (_pathBuffer->getValue(pos.x + 2, pos.y) != 0)) {
+		pos.x = (pos.x + 2 < to.x) ? pos.x + 2 : to.x;
 	}
 
-	if ((pos.x > to->_x) && (pos.x > 0) && (_pathBuffer->getValue(pos.x - 2, pos.y) != 0)) {
-		pos.x = (pos.x - 2 > to->_x) ? pos.x - 2 : to->_x;
+	if ((pos.x > to.x) && (pos.x > 0) && (_pathBuffer->getValue(pos.x - 2, pos.y) != 0)) {
+		pos.x = (pos.x - 2 > to.x) ? pos.x - 2 : to.x;
 	}
 
-	if ((pos.y < to->_y) && (pos.y < _pathBuffer->h) && (_pathBuffer->getValue(pos.x, pos.y + 2) != 0)) {
-		pos.y = (pos.y + 2 <= to->_y) ? pos.y + 2 : to->_y;
+	if ((pos.y < to.y) && (pos.y < _pathBuffer->h) && (_pathBuffer->getValue(pos.x, pos.y + 2) != 0)) {
+		pos.y = (pos.y + 2 <= to.y) ? pos.y + 2 : to.y;
 	}
 
-	if ((pos.y > to->_y) && (pos.y > 0) && (_pathBuffer->getValue(pos.x, pos.y - 2) != 0)) {
-		pos.y = (pos.y - 2 >= to->_y) ? pos.y - 2 : to->_y;
+	if ((pos.y > to.y) && (pos.y > 0) && (_pathBuffer->getValue(pos.x, pos.y - 2) != 0)) {
+		pos.y = (pos.y - 2 >= to.y) ? pos.y - 2 : to.y;
 	}
 
 	return;
 }
 
-int16 Parallaction::selectWalkFrame(Character &character, const Common::Point& pos, const WalkNodePtr to) {
 
-	Common::Point dist(to->_x - pos.x, to->_y - pos.y);
+void Parallaction::checkDoor(const Common::Point &foot) {
 
-	if (dist.x < 0)
-		dist.x = -dist.x;
-	if (dist.y < 0)
-		dist.y = -dist.y;
-
-	walkData1++;
-
-	// walk frame selection
-	int16 v16;
-	if (character._ani->getFrameNum() == 20) {
-
-		if (dist.x > dist.y) {
-			walkData2 = (to->_x > pos.x) ? 0 : 7;
-			walkData1 %= 12;
-			v16 = walkData1 / 2;
-		} else {
-			walkData2 = (to->_y > pos.y) ? 14 : 17;
-			walkData1 %= 8;
-			v16 = walkData1 / 4;
-		}
-
-	} else {
-
-		if (dist.x > dist.y) {
-			walkData2 = (to->_x > pos.x) ? 0 : 9;
-			walkData1 %= 16;
-			v16 = walkData1 / 2;
-		} else {
-			walkData2 = (to->_y > pos.y) ? 18 : 21;
-			walkData1 %= 8;
-			v16 = walkData1 / 4;
-		}
-
-	}
-
-	return v16;
-}
-
-void Parallaction::checkDoor(Character &character) {
-	if (_currentLocationIndex != _doorData1) {
-		_doorData1 = _currentLocationIndex;
-		_zoneTrap = nullZonePtr;
-	}
-
-	_engineFlags &= ~kEngineWalking;
-
-	Common::Point foot;
-
-	character.getFoot(foot);
 	ZonePtr z = hitZone(kZoneDoor, foot.x, foot.y);
-
 	if (z) {
-
 		if ((z->_flags & kFlagsClosed) == 0) {
 			_location._startPosition = z->u.door->_startPos;
 			_location._startFrame = z->u.door->_startFrame;
-
 			scheduleLocationSwitch(z->u.door->_location);
 			_zoneTrap = nullZonePtr;
-
 		} else {
 			_cmdExec->run(z->_commands, z);
 		}
 	}
 
-	character.getFoot(foot);
 	z = hitZone(kZoneTrap, foot.x, foot.y);
-
 	if (z) {
 		setLocationFlags(kFlagsEnter);
 		_cmdExec->run(z->_commands, z);
@@ -371,11 +307,14 @@
 
 
 void Parallaction::finalizeWalk(Character &character) {
-	checkDoor(character);
+	_engineFlags &= ~kEngineWalking;
+
+	Common::Point foot;
+	character.getFoot(foot);
+	checkDoor(foot);
+
 	delete character._walkPath;
 	character._walkPath = 0;
-
-	character._ani->_frame = walkData2;
 }
 
 void Parallaction_ns::walk(Character &character) {
@@ -386,35 +325,45 @@
 	Common::Point curPos;
 	character.getFoot(curPos);
 
+	// update target, if previous was reached
 	WalkNodeList::iterator it = character._walkPath->begin();
-
 	if (it != character._walkPath->end()) {
 		if ((*it)->_x == curPos.x && (*it)->_y == curPos.y) {
 			debugC(1, kDebugWalk, "walk reached node (%i, %i)", (*it)->_x, (*it)->_y);
 			it = character._walkPath->erase(it);
 		}
 	}
+
+	// advance character towards the target
+	Common::Point targetPos;
 	if (it == character._walkPath->end()) {
 		debugC(1, kDebugWalk, "walk reached last node");
 		finalizeWalk(character);
-		return;
-	}
+		targetPos = curPos;
+	} else {
+		if (*it) {
+			// targetPos is saved to help setting character direction
+			targetPos.x = (*it)->_x;
+			targetPos.y = (*it)->_y;
+		}
 
-	// selectWalkFrame must be performed before position is changed by clipMove
-	int16 walkFrame = selectWalkFrame(character, curPos, *it);
+		Common::Point newPos(curPos);
+		clipMove(newPos, targetPos);
+		character.setFoot(newPos);
 
-	Common::Point newPos(curPos);
-	clipMove(newPos, *it);
-	character.setFoot(newPos);
-
-	if (newPos == curPos) {
-		debugC(1, kDebugWalk, "walk was blocked by an unforeseen obstacle");
-		finalizeWalk(character);
-	} else {
-		character._ani->_frame = walkFrame + walkData2 + 1;
+		if (newPos == curPos) {
+			debugC(1, kDebugWalk, "walk was blocked by an unforeseen obstacle");
+			finalizeWalk(character);
+		}
 	}
 
-	return;
+	// targetPos is used to select the direction (and the walkFrame) of a character,
+	// since it doesn't cause the sudden changes in orientation that newPos would.
+	// Since newPos is 'adjusted' according to walkable areas, an imaginary line drawn
+	// from curPos to newPos is prone to abrutply change in direction, thus making the
+	// code select 'too different' frames when walking diagonally against obstacles,
+	// and yielding an annoying shaking effect in the character.
+	character.updateDirection(curPos, targetPos);
 }
 
 


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