[Scummvm-cvs-logs] SF.net SVN: scummvm:[55624] scummvm/trunk/engines/toon

sylvaintv at users.sourceforge.net sylvaintv at users.sourceforge.net
Sat Jan 29 21:12:28 CET 2011


Revision: 55624
          http://scummvm.svn.sourceforge.net/scummvm/?rev=55624&view=rev
Author:   sylvaintv
Date:     2011-01-29 20:12:27 +0000 (Sat, 29 Jan 2011)

Log Message:
-----------
TOON: Pathfinding & walking improvements

Use direct line path if possible
Smooth facing direction to avoid flickering (entering zanidu shuttle for example)
Fix possible lockups

Modified Paths:
--------------
    scummvm/trunk/engines/toon/character.cpp
    scummvm/trunk/engines/toon/character.h
    scummvm/trunk/engines/toon/drew.cpp
    scummvm/trunk/engines/toon/drew.h
    scummvm/trunk/engines/toon/path.cpp
    scummvm/trunk/engines/toon/path.h
    scummvm/trunk/engines/toon/toon.cpp

Modified: scummvm/trunk/engines/toon/character.cpp
===================================================================
--- scummvm/trunk/engines/toon/character.cpp	2011-01-29 19:03:50 UTC (rev 55623)
+++ scummvm/trunk/engines/toon/character.cpp	2011-01-29 20:12:27 UTC (rev 55624)
@@ -175,6 +175,8 @@
 
 		int32 localFinalX = _finalX;
 		int32 localFinalY = _finalY;
+		int32 smoothDx = 0;
+		int32 smoothDy = 0;
 
 		for (int32 a = 0; a < _vm->getPathFinding()->getPathNodeCount(); a++) {
 			_currentPathX[a] = _vm->getPathFinding()->getPathNodeX(a);
@@ -192,16 +194,25 @@
 
 		if (_blockingWalk) {
 			while ((_x != newPosX || _y != newPosY) && _currentPathNode < _currentPathNodeCount && !_vm->shouldQuitGame()) {
-				if (_currentPathNode < _currentPathNodeCount - 10) {
-					int32 delta = MIN<int32>(10, _currentPathNodeCount - _currentPathNode);
+				if (_currentPathNode < _currentPathNodeCount - 4) {
+					int32 delta = MIN<int32>(4, _currentPathNodeCount - _currentPathNode);
+
 					int32 dx = _currentPathX[_currentPathNode+delta] - _x;
 					int32 dy = _currentPathY[_currentPathNode+delta] - _y;
-					setFacing(getFacingFromDirection(dx, dy));
+
+					// smooth the facing computation. It prevents some ugly flickering from happening
+					if (!smoothDx && !smoothDy) {
+						smoothDx = dx;
+						smoothDy = dy;
+					} else {
+						smoothDx = (dx + smoothDx * 3) / 4;
+						smoothDy = (dy + smoothDy * 3) / 4;
+					}
+
+					setFacing(getFacingFromDirection(smoothDx, smoothDy));
 					playWalkAnim(0, 0);
 				}
 
-				
-
 				// in 1/1000 pixels
 				_numPixelToWalk += _speed * (_vm->getSystem()->getMillis() - _lastWalkTime) * _scale / 1024;
 				_lastWalkTime =  _vm->getSystem()->getMillis();
@@ -994,6 +1005,12 @@
 	return true;
 }
 
+void Character::plotPath(Graphics::Surface& surface) {
+	for (int i = 0; i < _currentPathNodeCount; i++) {
+		 *(byte*)surface.getBasePtr(_currentPathX[i], _currentPathY[i]) = ( i < _currentPathNode);
+	}
+}
+
 void Character::playAnim(int32 animId, int32 unused, int32 flags) {
 	debugC(3, kDebugCharacter, "playAnim(%d, unused, %d)", animId, flags);
 
@@ -1029,8 +1046,11 @@
 		// make the talker busy
 		_flags |= 1;
 
+		// old special anim was talking anim ? in this case we don't wait for the character to be ready
+		bool wasTalkAnim = _specialAnim && strstr(_specialAnim->_name, "TLK");
+
 		// wait for the character to be ready
-		while (_animScriptId != -1 && _animationInstance && _animationInstance->getFrame() > 0 && (_specialAnim && _animationInstance->getAnimation() != _specialAnim)) {
+		while (_animScriptId != -1 && _animationInstance && _animationInstance->getFrame() > 0 && !wasTalkAnim && (_specialAnim && _animationInstance->getAnimation() != _specialAnim)) {
 			_vm->simpleUpdate(false);
 		}
 	}

Modified: scummvm/trunk/engines/toon/character.h
===================================================================
--- scummvm/trunk/engines/toon/character.h	2011-01-29 19:03:50 UTC (rev 55623)
+++ scummvm/trunk/engines/toon/character.h	2011-01-29 20:12:27 UTC (rev 55624)
@@ -100,6 +100,8 @@
 	virtual void updateTimers(int32 relativeAdd);
 	virtual void setTalking(bool talking) { _isTalking = talking; }
 	virtual bool isTalking() { return _isTalking; }
+	virtual void resetScale() { };
+	virtual void plotPath(Graphics::Surface& surface);
 
 	int32 getFacingFromDirection(int32 dx, int32 dy);
 	static const SpecialCharacterAnimation *getSpecialAnimation(int32 characterId, int32 animationId);

Modified: scummvm/trunk/engines/toon/drew.cpp
===================================================================
--- scummvm/trunk/engines/toon/drew.cpp	2011-01-29 19:03:50 UTC (rev 55623)
+++ scummvm/trunk/engines/toon/drew.cpp	2011-01-29 20:12:27 UTC (rev 55624)
@@ -33,6 +33,7 @@
 	_animationInstance = vm->getAnimationManager()->createNewInstance(kAnimationCharacter);
 	_animationInstance->setUseMask(true);
 	vm->getAnimationManager()->addInstance(_animationInstance);
+	_currentScale = 1024;
 }
 
 CharacterDrew::~CharacterDrew() {
@@ -104,6 +105,15 @@
 void CharacterDrew::update(int32 timeIncrement) {
 	debugC(5, kDebugCharacter, "update(%d)", timeIncrement);
 	Character::update(timeIncrement);
+	if (_currentScale > _scale) {
+		_scale += timeIncrement * 2;
+		if (_scale > _currentScale)
+			_scale = _currentScale;
+	} else if (_currentScale < _scale) {
+		_scale -= timeIncrement * 2;
+		if (_scale < _currentScale) 
+			_scale = _currentScale;
+	}
 	setPosition(_x, _y);
 
 }
@@ -114,5 +124,11 @@
 	static const int32 idle[] = { 6, 9, 10, 11, 12 };
 	return idle[_vm->randRange(0, 4)];
 }
+
+void CharacterDrew::resetScale()
+{
+	_scale = _currentScale;
+	setPosition(_x, _y);
+}
 } // End of namespace Toon
 

Modified: scummvm/trunk/engines/toon/drew.h
===================================================================
--- scummvm/trunk/engines/toon/drew.h	2011-01-29 19:03:50 UTC (rev 55623)
+++ scummvm/trunk/engines/toon/drew.h	2011-01-29 20:12:27 UTC (rev 55624)
@@ -40,9 +40,13 @@
 	bool setupPalette();
 	void playStandingAnim();
 	void setPosition(int32 x, int32 y);
+	void resetScale();
 	void update(int32 timeIncrement);
 	void playWalkAnim(int32 start, int32 end);
 	int32 getRandomIdleAnim();
+protected:
+	int32 _currentScale;
+
 };
 
 } // End of namespace Toon

Modified: scummvm/trunk/engines/toon/path.cpp
===================================================================
--- scummvm/trunk/engines/toon/path.cpp	2011-01-29 19:03:50 UTC (rev 55623)
+++ scummvm/trunk/engines/toon/path.cpp	2011-01-29 20:12:27 UTC (rev 55624)
@@ -209,8 +209,40 @@
 	}
 }
 
+bool PathFinding::walkLine(int32 x, int32 y, int32 x2, int32 y2) {
+	uint32 bx = x << 16;
+	int32 dx = x2 - x;
+	uint32 by = y << 16;
+	int32 dy = y2 - y;
+	uint32 adx = abs(dx);
+	uint32 ady = abs(dy);
+	int32 t = 0;
+	if (adx <= ady)
+		t = ady;
+	else
+		t = adx;
+
+	int32 cdx = (dx << 16) / t;
+	int32 cdy = (dy << 16) / t;
+
+	int32 i = t;
+	_gridPathCount = 0;
+	while (i) {
+		_tempPathX[i] = bx >> 16;
+		_tempPathY[i] = by >> 16;
+		_gridPathCount++;
+		bx += cdx;
+		by += cdy;
+		i--;
+	}
+
+	_tempPathX[0] = x2;
+	_tempPathY[0] = y2;
+
+	return true;
+}
+
 bool PathFinding::lineIsWalkable(int32 x, int32 y, int32 x2, int32 y2) {
-
 	uint32 bx = x << 16;
 	int32 dx = x2 - x;
 	uint32 by = y << 16;
@@ -228,7 +260,7 @@
 
 	int32 i = t;
 	while (i) {
-		if(!isWalkable(bx >> 16, by >> 16))
+		if (!isWalkable(bx >> 16, by >> 16))
 			return false;
 		bx += cdx;
 		by += cdy;
@@ -251,8 +283,12 @@
 	}
 
 	// first test direct line
-	//if(lineIsWalkable(x,y,destx,desty))
+	if (lineIsWalkable(x,y,destx,desty)) {
+		walkLine(x,y,destx,desty);
+		return true;
+	}
 
+	// no direct line, we use the standard A* algorithm
 	memset(_gridTemp , 0, _width * _height * sizeof(int32));
 	_heap->clear();
 	int32 curX = x;
@@ -277,7 +313,7 @@
 		for (int32 px = startX; px <= endX; px++) {
 			for (int py = startY; py <= endY; py++) {
 				if (px != curX || py != curY) {
-					wei = abs(px - curX) + abs(py - curY);
+					wei = ((abs(px - curX) + abs(py - curY)));
 
 					int32 curPNode = px + py * _width;
 					if (isWalkable(px, py)) { // walkable ?

Modified: scummvm/trunk/engines/toon/path.h
===================================================================
--- scummvm/trunk/engines/toon/path.h	2011-01-29 19:03:50 UTC (rev 55623)
+++ scummvm/trunk/engines/toon/path.h	2011-01-29 20:12:27 UTC (rev 55624)
@@ -64,6 +64,7 @@
 	bool isWalkable(int32 x, int32 y);
 	bool isLikelyWalkable(int32 x, int32 y);
 	bool lineIsWalkable(int32 x, int32 y, int32 x2, int32 y2);
+	bool walkLine(int32 x, int32 y, int32 x2, int32 y2);
 	void init(Picture *mask);
 
 	void resetBlockingRects();

Modified: scummvm/trunk/engines/toon/toon.cpp
===================================================================
--- scummvm/trunk/engines/toon/toon.cpp	2011-01-29 19:03:50 UTC (rev 55623)
+++ scummvm/trunk/engines/toon/toon.cpp	2011-01-29 20:12:27 UTC (rev 55624)
@@ -386,7 +386,8 @@
 	drawConversationLine();
 	drawConversationIcons();
 	drawSack();
-	//drawPalette();
+	//drawPalette();						// used to debug the current palette
+	//_drew->plotPath(*_mainSurface);		// used to debug path finding
 
 #if 0
 	char test[256];
@@ -1059,6 +1060,7 @@
 	_mouseButton = 0;
 	_lastMouseButton = 0x3;
 
+
 	// load package
 	strcpy(temp, createRoomFilename(Common::String::format("%s.pak", _gameState->_locations[_gameState->_currentScene]._name).c_str()).c_str());
 	resources()->openPackage(temp, true);


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