[Scummvm-cvs-logs] scummvm master -> 8af6a0ddd2a06e9c3605fa0a6d4f39318738eedc

sev- sev at scummvm.org
Tue Jul 19 13:22:21 CEST 2016


This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
1a880c748c SCUMM: Maniac V0: Clear the text area of the screen on fade out
44000ba826 SCUMM: Maniac V0: Implement original walkbox queue, Cleanup actor walk code
67071b42bc SCUMM: Maniac V0: Implement 'simulator' for CPU lag (as the original engine occasionally ran at less than 60Hz). Fix cal
8af6a0ddd2 Merge pull request #785 from segrax/master


Commit: 1a880c748c5cfb5ed64ca220ff332bc353726345
    https://github.com/scummvm/scummvm/commit/1a880c748c5cfb5ed64ca220ff332bc353726345
Author: Robert Crossfield (robcrossfield at gmail.com)
Date: 2016-07-17T16:40:49+10:00

Commit Message:
SCUMM: Maniac V0: Clear the text area of the screen on fade out

Changed paths:
    engines/scumm/gfx.cpp
    engines/scumm/gfx.h



diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 1d1b6b4..5dc96ec 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -3795,6 +3795,11 @@ void ScummEngine::fadeOut(int effect) {
 		_textSurface.fillRect(Common::Rect(0, vs->topline * _textSurfaceMultiplier, _textSurface.pitch, (vs->topline + vs->h) * _textSurfaceMultiplier), 0);
 #endif
 
+	// V0 wipes the text area before fading out
+	if (_game.version == 0) {
+		updateDirtyScreen( kTextVirtScreen );
+	}
+
 	// TheDig can disable fadeIn(), and may call fadeOut() several times
 	// successively. Disabling the _screenEffectFlag check forces the screen
 	// to get cleared. This fixes glitches, at least, in the first cutscenes
diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h
index 42844da..86913f9 100644
--- a/engines/scumm/gfx.h
+++ b/engines/scumm/gfx.h
@@ -58,7 +58,7 @@ struct CameraData {
 /** Virtual screen identifiers */
 enum VirtScreenNumber {
 	kMainVirtScreen = 0,	// The 'stage'
-	kTextVirtScreen = 1,	// In V1-V3 games: the area where text is printed
+	kTextVirtScreen = 1,	// In V0-V3 games: the area where text is printed
 	kVerbVirtScreen = 2,	// The verb area
 	kUnkVirtScreen = 3		// ?? Not sure what this one is good for...
 };


Commit: 44000ba8262a470612f1c83e2879b8b6f3d8a0b2
    https://github.com/scummvm/scummvm/commit/44000ba8262a470612f1c83e2879b8b6f3d8a0b2
Author: Robert Crossfield (robcrossfield at gmail.com)
Date: 2016-07-19T18:54:14+10:00

Commit Message:
SCUMM: Maniac V0: Implement original walkbox queue, Cleanup actor walk code

Changed paths:
    engines/scumm/actor.cpp
    engines/scumm/actor.h
    engines/scumm/boxes.cpp
    engines/scumm/saveload.h
    engines/scumm/scumm.h



diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index cd54c17..6cb5ce5 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -259,6 +259,8 @@ void Actor_v0::initActor(int mode) {
 		_limb_flipped[i] = false;
 	}
 
+	walkBoxQueueReset();
+
 	if (_vm->_game.features & GF_DEMO) {
 		_sound[0] = v0ActorDemoTalk[_number];
 	} else {
@@ -266,6 +268,116 @@ void Actor_v0::initActor(int mode) {
 	}
 }
 
+void Actor_v0::walkBoxQueueReset() {
+	_walkboxHistory.clear();
+	_walkboxQueueIndex = 0;
+
+	for (uint i = 0; i < ARRAYSIZE( _walkboxQueue ); ++i) {
+		_walkboxQueue[i] = kInvalidBox;
+	}
+}
+
+bool Actor_v0::walkBoxQueueAdd(int box) {
+
+	if (_walkboxQueueIndex == ARRAYSIZE( _walkboxQueue ))
+		return false;
+
+	_walkboxQueue[_walkboxQueueIndex++] = box ;
+	_walkboxHistory.push_back( box );
+	return true;
+}
+
+void Actor_v0::walkboxQueueReverse() {
+	int j = ARRAYSIZE( _walkboxQueue ) - 1;
+
+	while (_walkboxQueue[j] == kInvalidBox && j >= 1)
+		--j;
+
+	if (j <= 1)
+		return;
+
+	for (int i = 1; i < j && j >= 1 ; ++i, --j) {
+		
+		byte tmp = _walkboxQueue[i];
+
+		_walkboxQueue[i] = _walkboxQueue[j];
+		_walkboxQueue[j] = tmp;
+	}
+}
+
+bool Actor_v0::walkBoxQueueFind(int box) {
+
+	for (uint i = 0; i < _walkboxHistory.size(); ++i) {
+		if (box == _walkboxHistory[i])
+			return true;
+	}
+
+	return false;
+}
+
+bool Actor_v0::walkBoxQueuePrepare() {
+	walkBoxQueueReset();
+	int BoxFound = _walkbox;
+
+	if (BoxFound == _walkdata.destbox) {
+
+		_newWalkBoxEntered = true;
+		return true;
+	}
+
+	// Build a series of walkboxes from our current position, to the target
+	do {
+		// Add the current box to the queue
+		if (!walkBoxQueueAdd( BoxFound ))
+			return false;
+
+		// Loop until we find a walkbox which hasn't been tested
+		while (_walkboxQueueIndex > 0) {
+
+			// Check if the dest box is a direct neighbour
+			if ((BoxFound = _vm->getNextBox( BoxFound, _walkdata.destbox )) == kInvalidBox) {
+
+				// Its not, start hunting through this boxes immediate connections
+				byte* boxm = _vm->getBoxConnectionBase( _walkboxQueue[_walkboxQueueIndex - 1] );
+
+				// Attempt to find one, which we havn't already used
+				for (; *boxm != kInvalidBox; ++boxm) {
+					if (walkBoxQueueFind( *boxm ) != true)
+						break;
+				}
+
+				BoxFound = *boxm;
+			}
+
+			// Found one?
+			if (BoxFound != kInvalidBox) {
+
+				// Did we find a connection to the final walkbox
+				if (BoxFound == _walkdata.destbox) {
+
+					_newWalkBoxEntered = true;
+
+					walkBoxQueueAdd( BoxFound );
+
+					walkboxQueueReverse();
+					return true;
+				}
+
+				// Nope, check the next box
+				break;
+			}
+
+			// Drop this box, its useless to us
+			_walkboxQueue[--_walkboxQueueIndex] = kInvalidBox;
+
+			BoxFound = _walkboxQueue[_walkboxQueueIndex - 1];
+		} 
+
+	} while (_walkboxQueueIndex > 0);
+
+	return false;
+}
+
 void Actor::setBox(int box) {
 	_walkbox = box;
 	setupActorScale();
@@ -634,17 +746,18 @@ void Actor::startWalkActor(int destX, int destY, int dir) {
 	_walkdata.dest.y = abr.y;
 	_walkdata.destbox = abr.box;
 	_walkdata.destdir = dir;
-	
+	_walkdata.point3.x = 32000;
+	_walkdata.curbox = _walkbox;
+
 	if (_vm->_game.version == 0) {
-		((Actor_v0*)this)->_newWalkBoxEntered = true;
+		((Actor_v0*)this)->walkBoxQueuePrepare();
+
 	} else if (_vm->_game.version <= 2) {
 		_moving = (_moving & ~(MF_LAST_LEG | MF_IN_LEG)) | MF_NEW_LEG;
  	} else {
  		_moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
  	}
 
-	_walkdata.point3.x = 32000;
-	_walkdata.curbox = _walkbox;
 }
 
 void Actor::startWalkAnim(int cmd, int angle) {
@@ -861,13 +974,7 @@ L2C36:;
 			stopActorMoving();
 			return;
 		}
-		// 2C98: Yes, an exact copy of what just occurred.. the original does this, so im doing it...
-		//       Just to keep me sane when going over it :)
-		if (A == 0xFF) {
-			setActorFromTmp();
-			stopActorMoving();
-			return;
-		}
+
 		return;
 	}
 
@@ -1398,13 +1505,13 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
 			showActor();
 	}
 
-	// V0 always sets the actor to face the camera upon entering a room
 	if (_vm->_game.version == 0) {
-		_walkdata.dest = _pos;
 
-		((Actor_v0*)this)->_newWalkBoxEntered = true;
+		((Actor_v0*)this)->_newWalkBoxEntered = false;
 		((Actor_v0*)this)->_CurrentWalkTo = _pos;
+		((Actor_v0*)this)->_NewWalkTo = _pos;
 
+		// V0 always sets the actor to face the camera upon entering a room
 		setDirection(oldDirToNewDir(2));
 	}
 }
@@ -1549,7 +1656,7 @@ AdjustBoxResult Actor_v0::adjustPosInBorderWalkbox(AdjustBoxResult box) {
 		if (A < box.x)
 			return box;
 
-		if (A < 0xA0 || A == 0xA0)
+		if (A <= 0xA0)
 			A = 0;
 
 		Result.x = A;
@@ -1980,9 +2087,10 @@ void ScummEngine::processActors() {
 		if (_game.version == 0) {
 			// 0x057B
 			Actor_v0 *a0 = (Actor_v0*) a;
-			if (a0->_speaking & 1)
+			if (a0->_speaking & 1) {
 				a0->_speaking ^= 0xFE;
-
+				++_V0Delay._actorRedrawCount;
+			}
 			// 0x22B5
 			if (a0->_miscflags & kActorMiscFlagHide)
 				continue;
@@ -2404,8 +2512,13 @@ void Actor_v0::limbFrameCheck(int limb) {
 void Actor_v0::animateCostume() {
 	speakCheck();
 
-	if (_vm->_costumeLoader->increaseAnims(this))
+	byte count = _vm->_costumeLoader->increaseAnims( this );
+
+	if (count) {
+		_vm->_V0Delay._actorLimbRedrawDrawCount += count;
+
 		_needRedraw = true;
+	}
 }
 
 void Actor_v0::speakCheck() {
@@ -3254,7 +3367,7 @@ void Actor_v0::animateActor(int anim) {
 
 	} else {
 
-		if (anim > 4 && anim <= 7)
+		if (anim >= 4 && anim <= 7)
 			_facing = normalizeAngle(oldDirToNewDir(dir));
 	}
 }
@@ -3311,7 +3424,7 @@ void Actor_v0::setActorFromTmp() {
 }
 
 void Actor_v0::actorSetWalkTo() {
-	
+
 	if (_newWalkBoxEntered == false)
 		return;
 
@@ -3350,10 +3463,33 @@ void Actor_v0::saveLoadWithSerializer(Serializer *ser) {
 		MKLINE(Actor_v0, _walkYCount, sleByte, VER(97)),
 		MKLINE(Actor_v0, _walkYCountInc, sleByte, VER(97)),
 		MKLINE(Actor_v0, _walkMaxXYCountInc, sleByte, VER(97)),
+
+		MKARRAY(Actor_v0, _walkboxQueue[0], sleByte, 16, VER(98)),
+		MKLINE(Actor_v0, _walkboxQueueIndex, sleByte, VER(98)),
 		MKEND()
 	};
 
 	ser->saveLoadEntries(this, actorEntries);
+
+	if (ser->isLoading()) {
+		if (_costCommand != 0xFF ) {
+			
+			if (_walkboxQueueIndex < 1) {
+
+				_costCommand = 0xFF;
+				setDirection( _facing );
+				speakCheck();
+			}
+			else {
+				//_costCommandNew = _costCommand;
+				//_costCommand = 0xFF;
+				//animateActor( _costCommandNew );
+				_facing = 0;
+				directionUpdate();
+				animateActor( newDirToOldDir( _facing ) );
+			}
+		}
+	}
 }
 
 void Actor::saveLoadWithSerializer(Serializer *ser) {
@@ -3496,6 +3632,8 @@ void Actor::saveLoadWithSerializer(Serializer *ser) {
 			_walkdata.point3.x >>= V12_X_SHIFT;
 			_walkdata.point3.y >>= V12_Y_SHIFT;
 		}
+
+		setDirection( _facing );
 	}
 }
 
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index c1a3f23..3bc301f 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -350,6 +350,11 @@ class Actor_v0 : public Actor_v2 {
 public:
 	Common::Point _CurrentWalkTo, _NewWalkTo;
 
+	Common::Array<byte> _walkboxHistory;
+
+	byte _walkboxQueue[0x10];
+	byte _walkboxQueueIndex;
+
 	byte _costCommandNew;
 	byte _costCommand;
 	byte _miscflags;
@@ -380,6 +385,12 @@ public:
 
 	bool _limb_flipped[8];
 
+private:
+
+	bool walkBoxQueueAdd( int box );
+	bool walkBoxQueueFind( int box );
+	void walkboxQueueReverse();
+
 public:
 	Actor_v0(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {}
 
@@ -401,6 +412,9 @@ public:
 	byte actorWalkY();
 	byte updateWalkbox();
 
+	void walkBoxQueueReset();
+	bool walkBoxQueuePrepare();
+
 	AdjustBoxResult adjustXYToBeInBox(int dstX, int dstY);
 	AdjustBoxResult adjustPosInBorderWalkbox(AdjustBoxResult box);
 
diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp
index 087d842..108f227 100644
--- a/engines/scumm/boxes.cpp
+++ b/engines/scumm/boxes.cpp
@@ -692,6 +692,22 @@ byte *ScummEngine::getBoxMatrixBaseAddr() {
 	return ptr;
 }
 
+byte *ScummEngine::getBoxConnectionBase( int box ) {
+	byte *boxm = getBoxMatrixBaseAddr();
+
+	int boxIndex = 0;
+
+	for (; boxIndex != box; ++boxIndex) {
+
+		while ( *boxm != 0xFF) {
+			++boxm;
+		}
+
+		++boxm;
+	}
+
+	return boxm;
+}
 /**
  * Compute if there is a way that connects box 'from' with box 'to'.
  * Returns the number of a box adjacent to 'from' that is the next on the
@@ -719,21 +735,18 @@ int ScummEngine::getNextBox(byte from, byte to) {
 	boxm = getBoxMatrixBaseAddr();
 
 	if (_game.version == 0) {
-		// calculate shortest paths
-		byte *itineraryMatrix = (byte *)malloc(numOfBoxes * numOfBoxes);
-		calcItineraryMatrix(itineraryMatrix, numOfBoxes);
 
-		dest = to;
-		do {
-			dest = itineraryMatrix[numOfBoxes * from + dest];
-		} while (dest != Actor::kInvalidBox && !areBoxesNeighbors(from, dest));
+		boxm = getBoxConnectionBase( from );
+
+		for (; *boxm != 0xFF; ++boxm) {
+			if (*boxm == to)
+				break;
+		}
 
-		if (dest == Actor::kInvalidBox)
-			dest = -1;
+		return *boxm;
 
-		free(itineraryMatrix);
-		return dest;
-	} else if (_game.version <= 2) {
+	}
+	else if (_game.version <= 2) {
 		// The v2 box matrix is a real matrix with numOfBoxes rows and columns.
 		// The first numOfBoxes bytes contain indices to the start of the corresponding
 		// row (although that seems unnecessary to me - the value is easily computable.
@@ -967,6 +980,7 @@ void ScummEngine::calcItineraryMatrix(byte *itineraryMatrix, int num) {
 	// 255 (= infinity) to all other boxes.
 	for (i = 0; i < num; i++) {
 		for (j = 0; j < num; j++) {
+
 			if (i == j) {
 				adjacentMatrix[i * boxSize + j] = 0;
 				itineraryMatrix[i * boxSize + j] = j;
@@ -1160,20 +1174,31 @@ bool ScummEngine::areBoxesNeighbors(int box1nr, int box2nr) {
 
 byte ScummEngine_v0::walkboxFindTarget(Actor *a, int destbox, Common::Point walkdest) {
 	Actor_v0 *Actor = (Actor_v0*)a;
+	byte nextBox = kOldInvalidBox;
 
-	byte nextBox = getNextBox(a->_walkbox, destbox);
+	// Do we have a walkbox queue to process
+	if (Actor->_walkboxQueueIndex > 1) {
+		nextBox = Actor->_walkboxQueue[--Actor->_walkboxQueueIndex];
 
-	if (nextBox != 0xFF && nextBox == destbox && areBoxesNeighbors(a->_walkbox, nextBox)) {
+		if (Actor->_walkboxQueueIndex <= 1) {
+			Actor->walkBoxQueueReset();
+		}
+	}
+
+	// Target box reached?
+	if (nextBox != Actor::kInvalidBox && nextBox == destbox && areBoxesNeighbors(a->_walkbox, nextBox)) {
 
 		Actor->_NewWalkTo = walkdest;
 		return nextBox;
 	}
 
-	if (nextBox != 0xFF && nextBox != a->_walkbox) {
+	// Next box reached
+	if (nextBox != Actor::kInvalidBox && nextBox != a->_walkbox) {
 
 		getClosestPtOnBox(getBoxCoordinates(nextBox), a->getPos().x, a->getPos().y, Actor->_NewWalkTo.x, Actor->_NewWalkTo.y);
 
 	} else {
+
 		if (walkdest.x == -1)
 			Actor->_NewWalkTo = Actor->_CurrentWalkTo;
 		else
diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h
index 753287e..fb2d45d 100644
--- a/engines/scumm/saveload.h
+++ b/engines/scumm/saveload.h
@@ -47,7 +47,7 @@ namespace Scumm {
  * only saves/loads those which are valid for the version of the savegame
  * which is being loaded/saved currently.
  */
-#define CURRENT_VER 97
+#define CURRENT_VER 98
 
 /**
  * An auxillary macro, used to specify savegame versions. We use this instead
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index f9758ae..5a653d0 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -1131,6 +1131,8 @@ public:
 
 	byte getNumBoxes();
 	byte *getBoxMatrixBaseAddr();
+	byte *getBoxConnectionBase( int box );
+
 	int getNextBox(byte from, byte to);
 
 	void setBoxFlags(int box, int val);


Commit: 67071b42bc3ada8a1d1b49243ae4fbff9b7ef27c
    https://github.com/scummvm/scummvm/commit/67071b42bc3ada8a1d1b49243ae4fbff9b7ef27c
Author: Robert Crossfield (robcrossfield at gmail.com)
Date: 2016-07-19T20:39:58+10:00

Commit Message:
SCUMM: Maniac V0: Implement 'simulator' for CPU lag (as the original engine occasionally ran at less than 60Hz). Fix call to 'getClosestPtOnBox', whcih was being passed X * V12_X_MULTIPLIER and Y * V12_Y_MULTIPLIER, but the box coordinates, where not

Changed paths:
    engines/scumm/actor.cpp
    engines/scumm/actor.h
    engines/scumm/boxes.cpp
    engines/scumm/gfx.cpp
    engines/scumm/object.cpp
    engines/scumm/scumm.cpp
    engines/scumm/scumm.h
    engines/scumm/scumm_v0.h



diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 6cb5ce5..b3e7926 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -272,23 +272,23 @@ void Actor_v0::walkBoxQueueReset() {
 	_walkboxHistory.clear();
 	_walkboxQueueIndex = 0;
 
-	for (uint i = 0; i < ARRAYSIZE( _walkboxQueue ); ++i) {
+	for (uint i = 0; i < ARRAYSIZE(_walkboxQueue); ++i) {
 		_walkboxQueue[i] = kInvalidBox;
 	}
 }
 
 bool Actor_v0::walkBoxQueueAdd(int box) {
 
-	if (_walkboxQueueIndex == ARRAYSIZE( _walkboxQueue ))
+	if (_walkboxQueueIndex == ARRAYSIZE(_walkboxQueue))
 		return false;
 
-	_walkboxQueue[_walkboxQueueIndex++] = box ;
-	_walkboxHistory.push_back( box );
+	_walkboxQueue[_walkboxQueueIndex++] = box;
+	_walkboxHistory.push_back(box);
 	return true;
 }
 
 void Actor_v0::walkboxQueueReverse() {
-	int j = ARRAYSIZE( _walkboxQueue ) - 1;
+	int j = ARRAYSIZE(_walkboxQueue) - 1;
 
 	while (_walkboxQueue[j] == kInvalidBox && j >= 1)
 		--j;
@@ -328,21 +328,21 @@ bool Actor_v0::walkBoxQueuePrepare() {
 	// Build a series of walkboxes from our current position, to the target
 	do {
 		// Add the current box to the queue
-		if (!walkBoxQueueAdd( BoxFound ))
+		if (!walkBoxQueueAdd(BoxFound))
 			return false;
 
 		// Loop until we find a walkbox which hasn't been tested
 		while (_walkboxQueueIndex > 0) {
 
 			// Check if the dest box is a direct neighbour
-			if ((BoxFound = _vm->getNextBox( BoxFound, _walkdata.destbox )) == kInvalidBox) {
+			if ((BoxFound = _vm->getNextBox(BoxFound, _walkdata.destbox)) == kInvalidBox) {
 
 				// Its not, start hunting through this boxes immediate connections
-				byte* boxm = _vm->getBoxConnectionBase( _walkboxQueue[_walkboxQueueIndex - 1] );
+				byte* boxm = _vm->getBoxConnectionBase(_walkboxQueue[_walkboxQueueIndex - 1]);
 
 				// Attempt to find one, which we havn't already used
 				for (; *boxm != kInvalidBox; ++boxm) {
-					if (walkBoxQueueFind( *boxm ) != true)
+					if (walkBoxQueueFind(*boxm) != true)
 						break;
 				}
 
@@ -357,7 +357,7 @@ bool Actor_v0::walkBoxQueuePrepare() {
 
 					_newWalkBoxEntered = true;
 
-					walkBoxQueueAdd( BoxFound );
+					walkBoxQueueAdd(BoxFound);
 
 					walkboxQueueReverse();
 					return true;
@@ -750,7 +750,7 @@ void Actor::startWalkActor(int destX, int destY, int dir) {
 	_walkdata.curbox = _walkbox;
 
 	if (_vm->_game.version == 0) {
-		((Actor_v0*)this)->walkBoxQueuePrepare();
+		((Actor_v0 *)this)->walkBoxQueuePrepare();
 
 	} else if (_vm->_game.version <= 2) {
 		_moving = (_moving & ~(MF_LAST_LEG | MF_IN_LEG)) | MF_NEW_LEG;
@@ -1507,9 +1507,9 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
 
 	if (_vm->_game.version == 0) {
 
-		((Actor_v0*)this)->_newWalkBoxEntered = false;
-		((Actor_v0*)this)->_CurrentWalkTo = _pos;
-		((Actor_v0*)this)->_NewWalkTo = _pos;
+		((Actor_v0 *)this)->_newWalkBoxEntered = false;
+		((Actor_v0 *)this)->_CurrentWalkTo = _pos;
+		((Actor_v0 *)this)->_NewWalkTo = _pos;
 
 		// V0 always sets the actor to face the camera upon entering a room
 		setDirection(oldDirToNewDir(2));
@@ -2512,7 +2512,7 @@ void Actor_v0::limbFrameCheck(int limb) {
 void Actor_v0::animateCostume() {
 	speakCheck();
 
-	byte count = _vm->_costumeLoader->increaseAnims( this );
+	byte count = _vm->_costumeLoader->increaseAnims(this);
 
 	if (count) {
 		_vm->_V0Delay._actorLimbRedrawDrawCount += count;
@@ -3430,7 +3430,7 @@ void Actor_v0::actorSetWalkTo() {
 
 	_newWalkBoxEntered = false;
 
-	int nextBox = ((ScummEngine_v0*)_vm)->walkboxFindTarget(this, _walkdata.destbox, _walkdata.dest);
+	int nextBox = ((ScummEngine_v0 *)_vm)->walkboxFindTarget(this, _walkdata.destbox, _walkdata.dest);
 	if (nextBox != kInvalidBox) {
 		_walkdata.curbox = nextBox;
 	}
@@ -3471,22 +3471,27 @@ void Actor_v0::saveLoadWithSerializer(Serializer *ser) {
 
 	ser->saveLoadEntries(this, actorEntries);
 
+	// When loading, we need to ensure the limbs are restarted
 	if (ser->isLoading()) {
-		if (_costCommand != 0xFF ) {
+
+		// valid costume command?
+		if (_costCommand != 0xFF) {
 			
+			// Do we have a walkbox queue?
 			if (_walkboxQueueIndex < 1) {
-
 				_costCommand = 0xFF;
-				setDirection( _facing );
+
+				// Standing Still
+				setDirection(_facing);
 				speakCheck();
-			}
-			else {
-				//_costCommandNew = _costCommand;
-				//_costCommand = 0xFF;
-				//animateActor( _costCommandNew );
+
+			} else {
+				// Force limb direction update
 				_facing = 0;
 				directionUpdate();
-				animateActor( newDirToOldDir( _facing ) );
+
+				// Begin walking
+				animateActor(newDirToOldDir(_facing));
 			}
 		}
 	}
@@ -3633,7 +3638,7 @@ void Actor::saveLoadWithSerializer(Serializer *ser) {
 			_walkdata.point3.y >>= V12_Y_SHIFT;
 		}
 
-		setDirection( _facing );
+		setDirection(_facing);
 	}
 }
 
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index 3bc301f..62ba161 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -387,8 +387,8 @@ public:
 
 private:
 
-	bool walkBoxQueueAdd( int box );
-	bool walkBoxQueueFind( int box );
+	bool walkBoxQueueAdd(int box);
+	bool walkBoxQueueFind(int box);
 	void walkboxQueueReverse();
 
 public:
diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp
index 108f227..b5caec3 100644
--- a/engines/scumm/boxes.cpp
+++ b/engines/scumm/boxes.cpp
@@ -692,14 +692,14 @@ byte *ScummEngine::getBoxMatrixBaseAddr() {
 	return ptr;
 }
 
-byte *ScummEngine::getBoxConnectionBase( int box ) {
+byte *ScummEngine::getBoxConnectionBase(int box) {
 	byte *boxm = getBoxMatrixBaseAddr();
 
 	int boxIndex = 0;
 
 	for (; boxIndex != box; ++boxIndex) {
 
-		while ( *boxm != 0xFF) {
+		while (*boxm != 0xFF) {
 			++boxm;
 		}
 
@@ -736,7 +736,7 @@ int ScummEngine::getNextBox(byte from, byte to) {
 
 	if (_game.version == 0) {
 
-		boxm = getBoxConnectionBase( from );
+		boxm = getBoxConnectionBase(from);
 
 		for (; *boxm != 0xFF; ++boxm) {
 			if (*boxm == to)
@@ -1173,7 +1173,7 @@ bool ScummEngine::areBoxesNeighbors(int box1nr, int box2nr) {
 }
 
 byte ScummEngine_v0::walkboxFindTarget(Actor *a, int destbox, Common::Point walkdest) {
-	Actor_v0 *Actor = (Actor_v0*)a;
+	Actor_v0 *Actor = (Actor_v0 *)a;
 	byte nextBox = kOldInvalidBox;
 
 	// Do we have a walkbox queue to process
@@ -1195,7 +1195,7 @@ byte ScummEngine_v0::walkboxFindTarget(Actor *a, int destbox, Common::Point walk
 	// Next box reached
 	if (nextBox != Actor::kInvalidBox && nextBox != a->_walkbox) {
 
-		getClosestPtOnBox(getBoxCoordinates(nextBox), a->getPos().x, a->getPos().y, Actor->_NewWalkTo.x, Actor->_NewWalkTo.y);
+		getClosestPtOnBox(getBoxCoordinates(nextBox), a->getRealPos().x, a->getRealPos().y, Actor->_NewWalkTo.x, Actor->_NewWalkTo.y);
 
 	} else {
 
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 5dc96ec..48818b8 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -3797,7 +3797,7 @@ void ScummEngine::fadeOut(int effect) {
 
 	// V0 wipes the text area before fading out
 	if (_game.version == 0) {
-		updateDirtyScreen( kTextVirtScreen );
+		updateDirtyScreen(kTextVirtScreen);
 	}
 
 	// TheDig can disable fadeIn(), and may call fadeOut() several times
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index db83646..da94a34 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -1126,6 +1126,7 @@ void ScummEngine_v80he::clearDrawQueues() {
  */
 void ScummEngine::markObjectRectAsDirty(int obj) {
 	int i, strip;
+	++_V0Delay._objectRedrawCount;
 
 	for (i = 1; i < _numLocalObjects; i++) {
 		if (_objs[i].obj_nr == (uint16)obj) {
@@ -1133,6 +1134,7 @@ void ScummEngine::markObjectRectAsDirty(int obj) {
 				const int minStrip = MAX(_screenStartStrip, _objs[i].x_pos / 8);
 				const int maxStrip = MIN(_screenEndStrip+1, _objs[i].x_pos / 8 + _objs[i].width / 8);
 				for (strip = minStrip; strip < maxStrip; strip++) {
+					++_V0Delay._objectStripRedrawCount;
 					setGfxUsageBit(strip, USAGE_BIT_DIRTY);
 				}
 			}
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 3b7dea1..3c61747 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -732,11 +732,40 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
 	VAR_ACTIVE_OBJECT2 = 0xFF;
 	VAR_IS_SOUND_RUNNING = 0xFF;
 	VAR_ACTIVE_VERB = 0xFF;
+	
+	DelayReset();
 
 	if (strcmp(dr.fp.pattern, "maniacdemo.d64") == 0 )
 		_game.features |= GF_DEMO;
 }
 
+void ScummEngine_v0::DelayReset() {
+	_V0Delay._screenScroll = false;
+	_V0Delay._objectRedrawCount = 0;
+	_V0Delay._objectStripRedrawCount = 0;
+	_V0Delay._actorRedrawCount = 0;
+	_V0Delay._actorLimbRedrawDrawCount = 0;
+}
+
+int ScummEngine_v0::DelayCalculateDelta() {
+	float Time = 0;
+	
+	// These values are made up, based on trial/error with visual inspection against WinVice
+	// If anyone feels inclined, the routines in the original engine could be profiled
+	// and these values changed accordindly.
+	Time += _V0Delay._objectRedrawCount * 7;
+	Time += _V0Delay._objectStripRedrawCount * 0.6;
+	Time += _V0Delay._actorRedrawCount * 2.0;
+	Time += _V0Delay._actorLimbRedrawDrawCount * 0.3;
+
+	if (_V0Delay._screenScroll)
+		Time += 3.6f;
+
+	DelayReset();
+
+	return roundf(Time);
+}
+
 ScummEngine_v6::ScummEngine_v6(OSystem *syst, const DetectorResult &dr)
 	: ScummEngine(syst, dr) {
 	_blastObjectQueuePos = 0;
@@ -2079,13 +2108,24 @@ Common::Error ScummEngine::go() {
 		if (delta < 1)	// Ensure we don't get into an endless loop
 			delta = 1;  // by not decreasing sleepers.
 
-		// WORKAROUND: walking speed in the original v0/v1 interpreter
+		// WORKAROUND: Unfortunately the MOS 6502 wasn't always fast enough for MM
+		//  a number of situations can lead to the engine running at less than 60 ticks per second, without this drop
+		//	- A single kid is able to escape via the Dungeon Door (after pushing the brick)
+		//	- During the intro, calls to 'SetState08' are made for the lights on the mansion, with a 'breakHere'
+		//	  in between each, the reduction in ticks then occurs while affected stripes are being redrawn.
+		//	  The music buildup is then out of sync with the text "A Lucasfilm Games Production".
+		//	  Each call to 'breakHere' has been replaced with calls to 'Delay' in the V1/V2 versions of the game
+		if (_game.version == 0) {
+			delta += ((ScummEngine_v0 *)this)->DelayCalculateDelta();
+		}
+		
+		// WORKAROUND: walking speed in the original v1 interpreter
 		// is sometimes slower (e.g. during scrolling) than in ScummVM.
 		// This is important for the door-closing action in the dungeon,
 		// otherwise (delta < 6) a single kid is able to escape.
-		if ((_game.version == 0 && isScriptRunning(132)) ||
-			(_game.version == 1 && isScriptRunning(137)))
-			delta = 6;
+		if (_game.version == 1 && isScriptRunning(137)) {
+				delta = 6;
+		}
 
 		// Wait...
 		waitForTimer(delta * 1000 / 60 - diff);
@@ -2452,6 +2492,8 @@ void ScummEngine_v8::scummLoop_handleSaveLoad() {
 
 void ScummEngine::scummLoop_handleDrawing() {
 	if (camera._cur != camera._last || _bgNeedsRedraw || _fullRedraw) {
+		_V0Delay._screenScroll = true;
+
 		redrawBGAreas();
 	}
 
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 5a653d0..2906fc7 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -298,7 +298,14 @@ struct StringTab : StringSlot {
 	}
 };
 
+struct ScummEngine_v0_Delays {
+	bool _screenScroll;
+	uint _objectRedrawCount;
+	uint _objectStripRedrawCount;
+	uint _actorRedrawCount;
+	uint _actorLimbRedrawDrawCount;
 
+};
 
 enum WhereIsObject {
 	WIO_NOT_FOUND = -1,
@@ -1097,6 +1104,8 @@ public:
 	// Indy4 Amiga specific
 	byte *_verbPalette;
 
+	ScummEngine_v0_Delays _V0Delay;
+
 protected:
 	int _shadowPaletteSize;
 	byte _currentPalette[3 * 256];
@@ -1131,7 +1140,7 @@ public:
 
 	byte getNumBoxes();
 	byte *getBoxMatrixBaseAddr();
-	byte *getBoxConnectionBase( int box );
+	byte *getBoxConnectionBase(int box);
 
 	int getNextBox(byte from, byte to);
 
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 4098d63..5f40940 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -70,6 +70,10 @@ public:
 
 	byte walkboxFindTarget(Actor *a, int destbox, Common::Point walkdest);
 
+	/* Delay calculation */
+	void DelayReset();
+	int DelayCalculateDelta();
+
 protected:
 	virtual void resetRoomObject(ObjectData *od, const byte *room, const byte *searchptr = NULL);
 


Commit: 8af6a0ddd2a06e9c3605fa0a6d4f39318738eedc
    https://github.com/scummvm/scummvm/commit/8af6a0ddd2a06e9c3605fa0a6d4f39318738eedc
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2016-07-19T14:22:17+03:00

Commit Message:
Merge pull request #785 from segrax/master

SCUMM: Maniac V0: Walkbox / Timing improvements

Changed paths:
    engines/scumm/actor.cpp
    engines/scumm/actor.h
    engines/scumm/boxes.cpp
    engines/scumm/gfx.cpp
    engines/scumm/gfx.h
    engines/scumm/object.cpp
    engines/scumm/saveload.h
    engines/scumm/scumm.cpp
    engines/scumm/scumm.h
    engines/scumm/scumm_v0.h









More information about the Scummvm-git-logs mailing list