[Scummvm-cvs-logs] SF.net SVN: scummvm:[50882] scummvm/trunk/engines/m4

dreammaster at users.sourceforge.net dreammaster at users.sourceforge.net
Wed Jul 14 13:55:15 CEST 2010


Revision: 50882
          http://scummvm.svn.sourceforge.net/scummvm/?rev=50882&view=rev
Author:   dreammaster
Date:     2010-07-14 11:55:15 +0000 (Wed, 14 Jul 2010)

Log Message:
-----------
Preliminary implementation of lots of code related to player movement

Modified Paths:
--------------
    scummvm/trunk/engines/m4/mads_player.cpp
    scummvm/trunk/engines/m4/mads_player.h
    scummvm/trunk/engines/m4/mads_scene.cpp
    scummvm/trunk/engines/m4/mads_scene.h
    scummvm/trunk/engines/m4/rails.h

Modified: scummvm/trunk/engines/m4/mads_player.cpp
===================================================================
--- scummvm/trunk/engines/m4/mads_player.cpp	2010-07-14 11:53:12 UTC (rev 50881)
+++ scummvm/trunk/engines/m4/mads_player.cpp	2010-07-14 11:55:15 UTC (rev 50882)
@@ -35,20 +35,27 @@
 
 MadsPlayer::MadsPlayer() {
 	_playerPos = Common::Point(160, 78);
-	_direction = 0;
-	_newDirection = 0;
+	_ticksAmount = 3;
 	_forceRefresh = true;
 	_stepEnabled = true;
-	_ticksAmount = 3;
-	_priorTimer = 0;
 	_visible = true;
-	_priorVisible = false;
-	_visible3 = false;
 	_yScale = 0;
 	_moving = false;
+
 	_spriteListStart = 0;
+	//TODO:unknown vars
+	_special = 0;
+	_next = 0;
+	_unk4 = false;
+
+	_spritesChanged = true;
+	
+	_direction = 0;
+	_newDirection = 0;
+	_priorTimer = 0;
+	_priorVisible = false;
+	_visible3 = false;
 	_spriteListIdx = 0;
-	_spritesChanged = true;
 	_currentScale = 0;
 	strcpy(_spritesPrefix, "");
 	for (int idx = 0; idx < 8; ++idx)
@@ -59,6 +66,8 @@
 	_frameCount = 0;
 	_frameListIndex = 0;
 	_actionIndex = 0;
+	_routeCount = 0;
+
 	resetActionList();
 }
 
@@ -168,7 +177,7 @@
 				_madsVm->scene()->_spriteSlots[slotIndex] = slot;
 			}
 
-			// TODO: Meaning of word_844c0 block
+			// TODO: Meaning of _v844c0 block
 
 		}
 	}
@@ -325,6 +334,34 @@
 	}
 }
 
+void MadsPlayer::setDest(int destX, int destY, int facing) {
+	resetActionList();
+	setTicksAmount();
+	_moving = true;
+	_destFacing = facing;
+	
+	_madsVm->scene()->getSceneResources().setRouteNode(_madsVm->scene()->getSceneResources()._nodes.size() - 2,
+		_playerPos, _madsVm->scene()->_depthSurface);
+	_madsVm->scene()->getSceneResources().setRouteNode(_madsVm->scene()->getSceneResources()._nodes.size() - 1,
+		Common::Point(destX, destY), _madsVm->scene()->_depthSurface);
+
+	bool v = _madsVm->scene()->getDepthHighBit(Common::Point(destX, destY));
+	setupRoute(v);
+	_next = 0;
+
+	if (_routeCount > 0) {
+		Common::Point srcPos = _playerPos;
+		for (int routeCtr = _routeCount - 1; (routeCtr >= 0) && (_next == 0); --routeCtr) {
+			int idx = _routeIndexes[routeCtr];
+			const Common::Point &pt = _madsVm->scene()->getSceneResources()._nodes[idx].pt;
+
+			_next = scanPath(_madsVm->scene()->_depthSurface, srcPos, pt);
+			srcPos = pt;
+		}
+	}
+}
+
+
 int MadsPlayer::getScale(int yp) {
 	MadsSceneResources &r = _madsVm->scene()->getSceneResources();
 
@@ -411,7 +448,98 @@
 }
 
 void MadsPlayer::move() {
-	// TODO: Handle player movement
+	bool routeFlag = false;
+
+	if (_moving) {
+		int idx = _routeCount; 
+		while (!_v844C0 && (_destPos.x == _playerPos.x) && (_destPos.y == _playerPos.y)) {
+			if (idx != 0) {
+				--idx;
+				SceneNode &node = _madsVm->scene()->getSceneResources()._nodes[_routeIndexes[idx]];
+				_destPos = node.pt;
+				routeFlag = true;
+			} else if (_v844BE == idx) {
+				// End of walking path
+				_routeCount = 0;
+				_moving = false;
+				turnToDestFacing();
+				routeFlag = true;
+				idx = _routeCount;
+			} else {
+				_v844C0 = _v844BE;
+				_v844BC = true;
+				_v844BE = 0;
+				_stepEnabled = true;
+				routeFlag = false;
+			}
+
+			if (!_moving)
+				break;
+		}
+		_routeCount = idx;
+	}
+
+	if (routeFlag && _moving)
+		startMovement();
+
+	if (_newDirection != _direction)
+		dirChanged();
+	else if (!_moving)
+		updateFrame();
+
+	int var1 = _unk1;
+	if (_unk4 && (_hypotenuse > 0)) {
+		int v1 = -(_currentScale - 100) * (_posDiff.x - 1) / _hypotenuse + _currentScale;
+		var1 = MAX(1, 10000 / (v1 * _currentScale * var1));
+	}
+
+	if (!_moving || (_direction != _newDirection))
+		return;
+
+	Common::Point newPos = _playerPos;
+
+	if (_v8452E < var1) {
+		do {
+			if (_v8452C < _posDiff.x)
+				_v8452C += _posDiff.y;
+			if (_v8452C >= _posDiff.x) {
+				if ((_posChange.y <= 0) || (_v844C0 != 0))
+					newPos.y += _yDirection;
+				--_posChange.y;
+				_v8452C -= _posDiff.x;
+			}
+
+			if (_v8452C < _posDiff.x) {
+				if ((_posChange.x <= 0) || (_v844C0 != 0))
+					newPos.x += _xDirection;
+				--_posChange.x;
+			}
+
+			if ((_v844BC == 0) && (_v844C0 == 0) && (_v844BE == 0)) {
+				routeFlag = _madsVm->scene()->getDepthHighBit(newPos);
+
+				if (_special == 0)
+					_special = _madsVm->scene()->getDepthHighBits(newPos);
+			}
+
+			_v8452E += _v84530;
+
+		} while ((_v8452E < var1) && !routeFlag && ((_posChange.x > 0) || (_posChange.y > 0)));
+	}
+
+	if (routeFlag)
+		moveComplete();
+	else {
+		if (!_v844C0) {
+			// If the move is complete, make sure the position is exactly on the given destination
+			if (_posChange.x == 0)
+				newPos.x = _destPos.x;
+			if (_posChange.y == 0)
+				newPos.y = _destPos.y;
+		}
+
+		_playerPos = newPos;
+	}
 }
 
 void MadsPlayer::dirChanged() {
@@ -451,4 +579,175 @@
 	_priorTimer += 1;
 }
 
+void MadsPlayer::moveComplete() {
+	reset();
+	//todo: Unknown flag
+}
+
+void MadsPlayer::reset() {
+	_destPos = _playerPos;
+	_destFacing = 5;
+	_newDirection = _direction;
+
+	_moving = false;
+	_v844BC = false;
+	_v844C0 = false;
+	_v844BE = 0;
+	_next = 0;
+	_routeCount = 0;
+}
+
+/**
+ * Scans along an edge connecting two points within the depths/walk surface, and returns the information of the first
+ * pixel high nibble encountered with a non-zero value
+ */
+int MadsPlayer::scanPath(M4Surface *depthSurface, const Common::Point &srcPos, const Common::Point &destPos) {
+	// For compressed depth surfaces, always return 0
+	if (_madsVm->scene()->getSceneResources()._depthStyle != 2)
+		return 0;
+
+	int yDiff = destPos.y - srcPos.y;
+	int yAmount = MADS_SURFACE_WIDTH;
+
+	if (yDiff < 0) {
+		yDiff = -yDiff;
+		yAmount = -yAmount;
+	}
+
+	int xDiff = destPos.x - srcPos.y;
+	int xDirection = 1;
+	int xAmount = 0;
+	if (xDiff < 0) {
+		xDiff = -xDiff;
+		xDirection = -xDirection;
+		xAmount = MIN(yDiff, xDiff);
+	}
+
+	++xDiff;
+	++yDiff;
+
+	const byte *srcP = depthSurface->getBasePtr(srcPos.x, srcPos.y);
+	int index = xAmount;
+
+	// Outer horizontal movement loop
+	for (int yIndex = 0; yIndex < yDiff; ++yIndex) {
+		index += yDiff;
+		int v = (*srcP && 0x7F) >> 4;
+		if (v)
+			return v;
+
+		// Inner loop for handling vertical movement
+		while (index >= xDiff) {
+			index -= xDiff;
+
+			int v = (*srcP && 0x7F) >> 4;
+			if (v)
+				return v;
+
+			srcP += yAmount;
+		}
+
+		srcP += xDirection;
+	}
+	
+	return 0;
+}
+
+/**
+ * Starts a player moving to a given destination
+ */
+void MadsPlayer::startMovement() {
+	int xDiff = _destPos.x - _playerPos.x;
+	int yDiff = _destPos.y - _playerPos.y;
+	int srcScale = getScale(_playerPos.y);
+	int destScale = getScale(_destPos.y);
+
+	// Sets the X direction
+	if (xDiff > 0)
+		_xDirection = 1;
+	else if (xDiff < 0)
+		_xDirection = -1;
+	else
+		_xDirection = 0;
+
+	// Sets the Y direction
+	if (yDiff > 0)
+		_yDirection = 1;
+	else if (yDiff < 0)
+		_yDirection = -1;
+	else
+		_yDirection = 0;
+
+	xDiff = ABS(xDiff);
+	yDiff = ABS(yDiff);
+	int scaleDiff = ABS(srcScale - destScale);
+
+	int xAmt100 = xDiff * 100;
+	int yAmt100 = yDiff * 100;
+	int xAmt33 = xDiff * 33;
+
+	int scaleAmount = (_unk4 ? scaleDiff * 3 : 0) + 100 * yDiff / 100;
+	int scaleAmount100 = scaleAmount * 100;
+
+	// Figure out direction that will need to be moved in
+	int majorDir;
+	if (xDiff == 0)
+		majorDir = 1;
+	else if (yDiff == 0)
+		majorDir = 3;
+	else {
+		if ((scaleAmount >= xDiff) && ((xAmt33 / scaleAmount) >= 141))
+			majorDir = 3;
+		else if (yDiff <= xDiff)
+			majorDir = 2;
+		else if ((scaleAmount100 / xDiff) >= 141)
+			majorDir = 1;
+		else
+			majorDir = 2;
+	}
+
+	switch (majorDir) {
+	case 1:
+		_newDirection = (_yDirection <= 0) ? 8 : 2;
+		break;
+	case 2: {
+		_newDirection = ((_yDirection <= 0) ? 9 : 3) - ((_xDirection <= 0) ? 2 : 0);
+		break;
+	}
+	case 3:
+		_newDirection = (_xDirection <= 0) ? 4 : 6;
+		break;
+	default:
+		break;
+	}
+
+	_hypotenuse = SqrtF16(xAmt100 * xAmt100 + yAmt100 * yAmt100);
+	_posDiff.x = xDiff + 1;
+	_posDiff.y = yDiff + 1;
+	_posChange.x = xDiff;
+	_posChange.y = yDiff;
+
+	scaleAmount = MAX(xDiff, yDiff);
+	_v84530  = (scaleAmount == 0) ? 0 : _hypotenuse / scaleAmount;
+	
+	if (_playerPos.x > _destPos.x)
+		_v8452C = MAX(_posChange.x, _posChange.y);
+	else
+		_v8452C = 0;
+	
+	_hypotenuse /= 100;
+	_v8452E = -_v84530;
+}
+
+void MadsPlayer::turnToDestFacing() {
+	if (_destFacing != 5)
+		_newDirection = _destFacing;
+}
+
+void MadsPlayer::setupRoute(bool bitFlag) {
+	// TODO: Properly Implement route setup
+	_routeIndexes[0] = _madsVm->scene()->getSceneResources()._nodes.size() - 1;
+	_routeCount = 1;
+}
+
 } // End of namespace M4

Modified: scummvm/trunk/engines/m4/mads_player.h
===================================================================
--- scummvm/trunk/engines/m4/mads_player.h	2010-07-14 11:53:12 UTC (rev 50881)
+++ scummvm/trunk/engines/m4/mads_player.h	2010-07-14 11:55:15 UTC (rev 50882)
@@ -31,6 +31,7 @@
 namespace M4 {
 
 #define PLAYER_SEQ_INDEX -2
+#define MAX_ROUTE_NODES 22
 
 class MadsPlayer {
 private:
@@ -42,12 +43,18 @@
 	void idle();
 	void move();
 	void dirChanged();
+	void reset();
+	int scanPath(M4Surface *depthSurface, const Common::Point &srcPos, const Common::Point &destPos);
+	void startMovement();
 public:
 	char _spritesPrefix[16];
 	int _spriteSetCount;
 	bool _spriteSetsPresent[8];
 	Common::Point _playerPos;
 	Common::Point _destPos;
+	Common::Point _posChange;
+	Common::Point _posDiff;
+	int _hypotenuse;
 	uint32 _priorTimer;
 	uint _ticksAmount;
 	int16 _direction, _newDirection;
@@ -70,6 +77,21 @@
 	int _actionList2[12];
 	int _unk2;
 	int _unk3;
+	int _xDirection, _yDirection;
+	int _destFacing;
+	int _special;
+	int _next;
+	int _routeCount;
+	int _routeOffset;
+	int _tempRoute[MAX_ROUTE_NODES];
+	int _routeIndexes[MAX_ROUTE_NODES];
+	bool _unk4;
+	bool _v844BC;
+	int _v844BE;
+	bool _v844C0;
+	int _v8452E;
+	int _v8452C;
+	int _v84530;
 
 	static const int _directionListIndexes[32];
 public:
@@ -81,6 +103,10 @@
 	void setupFrame();
 	void step();
 	void nextFrame();
+	void setDest(int destX, int destY, int facing);
+	void turnToDestFacing();
+	void setupRoute(bool bitFlag);
+	void moveComplete();
 };
 
 } // End of namespace M4

Modified: scummvm/trunk/engines/m4/mads_scene.cpp
===================================================================
--- scummvm/trunk/engines/m4/mads_scene.cpp	2010-07-14 11:53:12 UTC (rev 50881)
+++ scummvm/trunk/engines/m4/mads_scene.cpp	2010-07-14 11:55:15 UTC (rev 50882)
@@ -48,6 +48,17 @@
 
 //--------------------------------------------------------------------------
 
+void SceneNode::load(Common::SeekableReadStream *stream) {
+	// Get the next data block
+	uint8 obj[0x30];
+	stream->read(obj, 0x30);
+
+	pt.x = READ_LE_UINT16(&obj[0]);
+	pt.y = READ_LE_UINT16(&obj[2]);
+}
+
+//--------------------------------------------------------------------------
+
 MadsScene::MadsScene(MadsEngine *vm): _sceneResources(), Scene(vm, &_sceneResources), MadsView(this) {
 	_vm = vm;
 	_activeAnimation = NULL;
@@ -265,6 +276,10 @@
 		statusText[0] = toupper(statusText[0]);	// capitalize first letter
 		setStatusText(statusText);
 	}
+
+	// **DEBUG** - being used for movement testing
+	_madsVm->_player.moveComplete();
+	_madsVm->_player.setDest(x, y, 2);
 }
 
 void MadsScene::rightClick(int x, int y) {
@@ -503,6 +518,22 @@
 	_activeAnimation = anim;
 }
 
+bool MadsScene::getDepthHighBit(const Common::Point &pt) {
+	const byte *p = _depthSurface->getBasePtr(pt.x, pt.y);
+	if (_sceneResources._depthStyle == 2) 
+		return ((*p << 4) & 0x80) != 0;
+
+	return (*p & 0x80) != 0;
+}
+
+bool MadsScene::getDepthHighBits(const Common::Point &pt) {
+	if (_sceneResources._depthStyle == 2)
+		return 0;
+
+	const byte *p = _depthSurface->getBasePtr(pt.x, pt.y);
+	return (*p & 0x70) >> 4;
+}
+
 /*--------------------------------------------------------------------------*/
 
 MadsAction::MadsAction() {
@@ -733,9 +764,9 @@
 
 	// Load in any scene objects
 	for (int i = 0; i < objectCount; ++i) {
-		MadsObject rec;
+		SceneNode rec;
 		rec.load(stream);
-		_objects.push_back(rec);
+		_nodes.push_back(rec);
 	}
 	for (int i = 0; i < 20 - objectCount; ++i)
 		stream->skip(48);
@@ -810,6 +841,9 @@
 		delete depthSurface;
 }
 
+void MadsSceneResources::setRouteNode(int nodeIndex, const Common::Point &pt, M4Surface *depthSurface) {
+	// TODO
+}
 
 /*--------------------------------------------------------------------------*/
 

Modified: scummvm/trunk/engines/m4/mads_scene.h
===================================================================
--- scummvm/trunk/engines/m4/mads_scene.h	2010-07-14 11:53:12 UTC (rev 50881)
+++ scummvm/trunk/engines/m4/mads_scene.h	2010-07-14 11:55:15 UTC (rev 50882)
@@ -37,6 +37,13 @@
 
 #define DEPTH_BANDS_SIZE 15
 
+class SceneNode {
+public:
+	Common::Point pt;
+
+	void load(Common::SeekableReadStream *stream);
+};
+
 class MadsSceneResources: public SceneResources {
 public:
 	int _sceneId;
@@ -44,7 +51,7 @@
 	int _depthStyle;
 	int _width;
 	int _height;
-	Common::Array<MadsObject> _objects;
+	Common::Array<SceneNode> _nodes;
 	Common::Array<Common::String> _setNames;
 	int _yBandsStart, _yBandsEnd;
 	int _maxScale, _minScale;
@@ -55,6 +62,7 @@
 	void load(int sceneId, const char *resName, int v0, M4Surface *depthSurface, M4Surface *surface);
 	int bandsRange() const { return _yBandsEnd - _yBandsStart; }
 	int scaleRange() const { return _maxScale - _minScale; }
+	void setRouteNode(int nodeIndex, const Common::Point &pt, M4Surface *depthSurface);
 };
 
 enum MadsActionMode {ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, ACTMODE_TALK = 6};
@@ -138,6 +146,8 @@
 	MadsSceneResources &getSceneResources() { return _sceneResources; }
 	MadsAction &getAction() { return _action; }
 	void setStatusText(const char *text) {}//***DEPRECATED***
+	bool getDepthHighBit(const Common::Point &pt);
+	bool getDepthHighBits(const Common::Point &pt);
 };
 
 #define CHEAT_SEQUENCE_MAX 8

Modified: scummvm/trunk/engines/m4/rails.h
===================================================================
--- scummvm/trunk/engines/m4/rails.h	2010-07-14 11:53:12 UTC (rev 50881)
+++ scummvm/trunk/engines/m4/rails.h	2010-07-14 11:55:15 UTC (rev 50882)
@@ -93,6 +93,8 @@
 	bool isLineWalkable(int x0, int y0, int x1, int y1);
 };
 
+long SqrtF16(long n);
+
 } // End of namespace M4
 
 #endif


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