[Scummvm-cvs-logs] scummvm master -> dcd0f597e6026e248ff6e2db0224f3f60626cdca

Kirben kirben at optusnet.com.au
Sun Dec 7 05:10:33 CET 2014


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

Summary:
2dbd99d572 SCUMM: Maniac V0: Implement the original Walk Code (to fix some anim glitches), fix opcode to use _moving correctly (as 
29d46e8a10 SCUMM: Maniac V0: If boxes are neighbors, walk directly to the new box. Remove extra call to 'animateCostume'. Remove no
814d9b1153 SCUMM: Maniac V0: Correctly handle 'slanted' walk-boxes, Add new variables to save-games, Bump the SaveGame Version numb
4b1b9ec66f SCUMM: Maniac V0: Remove workaround for bug #2971126 (this issue no longer occurs as walking is handled the same as the 
dcd0f597e6 Merge pull request #539 from segrax/master


Commit: 2dbd99d57264bab012cebd064eadfc34050832b1
    https://github.com/scummvm/scummvm/commit/2dbd99d57264bab012cebd064eadfc34050832b1
Author: Robert Crossfield (robcrossfield at gmail.com)
Date: 2014-11-28T22:24:45+11:00

Commit Message:
SCUMM: Maniac V0: Implement the original Walk Code (to fix some anim glitches), fix opcode to use _moving correctly (as V0 is different)

Changed paths:
    engines/scumm/actor.cpp
    engines/scumm/actor.h
    engines/scumm/script.cpp
    engines/scumm/script_v0.cpp
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 116a953..1ea1f6e 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -250,8 +250,11 @@ void Actor::stopActorMoving() {
 		_vm->stopScript(_walkScript);
 
 	_moving = 0;
-	if (_vm->_game.version == 0)
+
+	if (_vm->_game.version == 0) {
+		_moving = 2;
 		setDirection(_facing);
+	}
 }
 
 void Actor::setActorWalkSpeed(uint newSpeedX, uint newSpeedY) {
@@ -447,7 +450,11 @@ void Actor::startWalkActor(int destX, int destY, int dir) {
 	_walkdata.dest.y = abr.y;
 	_walkdata.destbox = abr.box;
 	_walkdata.destdir = dir;
-	_moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
+	if(_vm->_game.version != 0 ) {
+		_moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
+	} else {
+		((Actor_v0*)this)->unk_FDE1 = 1;
+	}
 	_walkdata.point3.x = 32000;
 
 	_walkdata.curbox = _walkbox;
@@ -651,6 +658,403 @@ bool Actor_v0::checkWalkboxesHaveDirectPath(Common::Point &foundPath) {
 	return false;
 }
 
+bool Actor_v0::sub_2F6F() {
+	_walkDirX = 0;
+	_walkDirY = 0;
+	_walkYCountGreaterThanXCount = 0;
+	uint16 A = 0;
+
+	if (_CurrentWalkTo.x >= _tmp_Dest.x ) {
+		A = _CurrentWalkTo.x - _tmp_Dest.x;
+		_walkDirX = 1;
+	} else {
+		A = _tmp_Dest.x - _CurrentWalkTo.x;
+	}
+
+	_walkXCountInc = A;
+
+	if (_CurrentWalkTo.y >= _tmp_Dest.y ) {
+		A = _CurrentWalkTo.y - _tmp_Dest.y;
+		_walkDirY = 1;
+	} else {
+		A = _tmp_Dest.y - _CurrentWalkTo.y;
+	}
+
+	_walkYCountInc = A;
+	if ( !_walkXCountInc && !_walkYCountInc )
+		return true;
+
+	if( _walkXCountInc <= _walkYCountInc ) 
+		_walkYCountGreaterThanXCount = 1;
+
+	// 2FCC
+	A = _walkXCountInc;
+	if( A <= _walkYCountInc )
+		A = _walkYCountInc;
+
+	_walkMaxXYCountInc = A;
+	_walkXCount = _walkXCountInc;
+	_walkYCount = _walkYCountInc;
+	_walkCountModulo = _walkMaxXYCountInc;
+
+	return false;
+}
+
+byte Actor_v0::updateWalkbox() {
+	if( _vm->checkXYInBoxBounds( _walkbox, _pos.x, _pos.y ) )
+		return 0;
+
+	int numBoxes = _vm->getNumBoxes() - 1;
+	for (int i = 0; i <= numBoxes; i++) {
+		if (_vm->checkXYInBoxBounds( i, _pos.x, _pos.y ) == true ) {
+			if (_walkdata.curbox == i ) {
+				setBox(i);
+
+				unk_FDE1 = 1;
+				return i;
+			}
+		}
+	}
+
+	return 0xFF;
+}
+
+void Actor_v0::setTmpFromActor() {
+	_tmp_Pos = _pos;
+	_pos = _tmp_Dest;
+	_tmp_WalkBox = _walkbox;
+	_tmp_CB5F = unk_FDE1;
+}
+
+void Actor_v0::setActorFromTmp() {
+	_pos = _tmp_Pos;
+	_tmp_Dest = _tmp_Pos;
+	_walkbox = _tmp_WalkBox;
+	unk_FDE1 = _tmp_CB5F;
+}
+
+byte Actor_v0::actorWalkX() {
+	byte A = _walkXCount;
+	A += _walkXCountInc;
+	if (A >= _walkCountModulo) {
+		if (!_walkDirX ) {
+			_tmp_Dest.x--;
+		} else {
+			_tmp_Dest.x++;
+		}
+
+		A -= _walkCountModulo;
+	}
+	// 2EAC
+	_walkXCount = A;
+	setTmpFromActor();
+	if( updateWalkbox() == 0xFF ) {
+		// 2EB9
+		setActorFromTmp();
+
+		return 3;
+	} 
+	// 2EBF
+	if( _tmp_Dest.x == _CurrentWalkTo.x )
+		return 1;
+
+	return 0;
+}
+
+byte Actor_v0::actorWalkY() {
+
+	byte A = _walkYCount;
+	A += _walkYCountInc;
+	if (A >= _walkCountModulo) {
+		if (!_walkDirY ) {
+			_tmp_Dest.y--;
+		} else {
+			_tmp_Dest.y++;
+		}
+
+		A -= _walkCountModulo;
+	}
+	// 2EEB
+	_walkYCount = A;
+	setTmpFromActor();
+	if (updateWalkbox() == 0xFF) {
+		// 2EF8
+		setActorFromTmp();
+		return 4;
+	} 
+
+	// 2EFE
+	if (_walkYCountInc != 0) {
+		if (_walkYCountInc == 0xFF ) {
+			setActorFromTmp();
+			return 4;
+		}
+	}
+
+	// 2F0D
+	if (_CurrentWalkTo.y == _tmp_Dest.y)
+		return 1;
+
+	return 0;
+}
+
+byte Actor_v0::walkboxFindTarget() {
+	return 0xff;
+}
+
+void Actor_v0::actorSetWalkTo() {
+	
+	if (unk_FDE1 == 0 )
+		return;
+
+	unk_FDE1 = 0;
+	byte nextBox = _vm->getNextBox(_walkbox, _walkdata.destbox);
+
+	if (nextBox != 0xFF && nextBox != _walkbox ) {
+		Common::Point tmp;
+		_walkdata.curbox = nextBox;
+
+		getClosestPtOnBox(_vm->getBoxCoordinates(nextBox), _pos.x, _pos.y, _NewWalkTo.x, _NewWalkTo.y);
+		//getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, _NewWalkTo.x, _NewWalkTo.y);
+		
+
+	} else {
+		if( _walkdata.dest.x == -1 )
+			_NewWalkTo = _CurrentWalkTo;
+		else
+			_NewWalkTo = _walkdata.dest;
+	}
+}
+
+void Actor_v0::walkActor() {
+	actorSetWalkTo();
+
+	_needRedraw = true;
+	if (_NewWalkTo != _CurrentWalkTo) {
+		
+		// 2A27
+		_CurrentWalkTo = _NewWalkTo;
+
+loc_2A33:;
+		_moving &= 0xF0;
+		_tmp_Dest = _pos;
+
+		byte tmp = sub_2F6F();
+		_moving &= 0xF0;
+		_moving |= tmp;
+
+		if (!_walkYCountGreaterThanXCount) {
+			if (_walkDirX) {
+				_targetFacing = getAngleFromPos(V12_X_MULTIPLIER*1, V12_Y_MULTIPLIER*0, false);
+			} else {
+				_targetFacing = getAngleFromPos(V12_X_MULTIPLIER*-1, V12_Y_MULTIPLIER*0, false);
+			}
+		} else {
+			if (_walkDirY) {
+				_targetFacing = getAngleFromPos(V12_X_MULTIPLIER*0, V12_Y_MULTIPLIER*1, false);
+			} else {
+				_targetFacing = getAngleFromPos(V12_X_MULTIPLIER*0, V12_Y_MULTIPLIER*-1, false);
+			}
+		}
+
+		directionUpdate();
+		
+		if (_moving & 0x80 ) 
+			return;
+
+		animateActor(newDirToOldDir(_facing));
+
+	} else {
+		// 2A0A
+		if ((_moving & 0x7F) != 1) {
+			
+			if (_NewWalkTo == _pos) {
+				return;
+			}
+		}
+	}
+
+
+	// 2A9A
+	if (_moving == 2 )
+		return;
+
+	if ((_moving & 0x0F) == 1 )
+		return stopActorMoving();
+
+	// 2AAD
+	if (_moving & 0x80) {
+		directionUpdate();
+
+		if ((_moving & 0x80) )
+			return;
+
+		// 2AC2
+		animateActor(newDirToOldDir(_facing));
+	}
+
+	// 2ACE
+	if ((_moving & 0x0F) == 3 ) {
+loc_2C36:;
+		// 2C36
+		setTmpFromActor();
+
+		if (!_walkDirX ) {
+			_pos.x--;
+		} else {
+			_pos.x++;
+		}
+
+		// 2C51
+		if (updateWalkbox() != 0xFF) {
+			//2C66
+			setActorFromTmp();
+			goto loc_2A33;
+		}
+
+		// 2C6C
+		setActorFromTmp();
+
+		if (_CurrentWalkTo.y == _tmp_Dest.y) {
+			stopActorMoving();
+			return;
+		}
+
+		if (!_walkDirY) {
+			_tmp_Dest.y--;
+		} else {
+			_tmp_Dest.y++;
+		}
+		setTmpFromActor();
+		//2C8B
+		byte A = updateWalkbox();
+		if (A == 0xFF) {
+			setActorFromTmp();
+			stopActorMoving();
+			return;
+		}
+		// 2C98: Yes, an exact copy of what just occured.. the original does this, so im doing it...
+		//       Just to keep me sane when going over it :)
+		if (A == 0xFF) {
+			setActorFromTmp();
+			stopActorMoving();
+			return;
+		}
+		return;
+	}
+
+	// 2ADA
+	if ((_moving & 0x0F) == 4 ) {
+		// 2CA3
+loc_2CA3:;
+		setTmpFromActor();
+
+		if (!_walkDirY) {
+			_pos.y--;
+		} else {
+			_pos.y++;
+		}
+		if (updateWalkbox() == 0xFF ) {
+			// 2CC7
+			setActorFromTmp();
+			if( _CurrentWalkTo.x == _tmp_Dest.x ) {
+				stopActorMoving();
+				return;
+			}
+			// 2CD5
+			if (!_walkDirX ) {
+				_tmp_Dest.x--;
+			} else {
+				_tmp_Dest.x++;
+			}
+			setTmpFromActor();
+
+			if (updateWalkbox() == 0xFF ) {
+				setActorFromTmp();
+				stopActorMoving();
+			}
+
+			return;
+		} else {
+			setActorFromTmp();
+			goto loc_2A33;
+		}
+	}
+
+	if ((_moving & 0x0F) == 0 ) {
+	 // 2AE8
+		byte A = actorWalkX();
+
+		if( A == 1 ) {
+			A = actorWalkY();
+			if( A  == 1 ) {
+				// 2AF6
+				_moving &= 0xF0;
+				_moving |= A;
+			} else {
+				// 2B04
+				if( A == 4 ) 
+					stopActorMoving();
+			}
+
+			return;
+
+		} else {
+			// 2B0C
+			if (A == 3) {
+				_moving &= 0xF0;
+				_moving |= A;
+
+				if (_walkDirY) {
+					_targetFacing = getAngleFromPos(V12_X_MULTIPLIER*0, V12_Y_MULTIPLIER*1, false);
+				} else {
+					_targetFacing = getAngleFromPos(V12_X_MULTIPLIER*0, V12_Y_MULTIPLIER*-1, false);
+				}
+
+				directionUpdate();
+				animateActor(newDirToOldDir(_facing));
+				goto loc_2C36;
+
+			} else {
+				// 2B39
+				A = actorWalkY();
+				if (A != 4 )
+					return;
+
+				// 2B46
+				_moving &= 0xF0;
+				_moving |= A;
+
+				if (_walkDirX) {
+					_targetFacing = getAngleFromPos(V12_X_MULTIPLIER*1, V12_Y_MULTIPLIER*0, false);
+				} else {
+					_targetFacing = getAngleFromPos(V12_X_MULTIPLIER*-1, V12_Y_MULTIPLIER*0, false);
+				}
+				
+				directionUpdate();
+				animateActor(newDirToOldDir(_facing));
+				goto loc_2CA3;
+			}
+		}
+	}
+}
+
+void Actor_v0::directionUpdate() {
+
+	int nextFacing = updateActorDirection(true);
+	if (_facing != nextFacing) {
+		// 2A89
+		setDirection(nextFacing);
+
+		if (_facing != _targetFacing ) {
+			_moving |= 0x80;
+		} else {
+			_moving &= ~0x80;
+		}
+	} else
+		_moving &= ~0x80;
+}	
+
 void Actor_v2::walkActor() {
 	Common::Point foundPath, tmp;
 	int new_dir, next_box;
@@ -985,18 +1389,16 @@ void Actor_v0::setDirection(int direction) {
 			break;
 
 		case 2:
-			res = 6;	// Face Away
+			res = 6;	// Face Camera
 			break;
 
 		default:
-			res = 7;	// Face Camera
+			res = 7;	// Face Away
 			break;
 	}
 
 	_animFrameRepeat = -1;
 	animateActor(res);
-	if (_moving)
-		animateCostume();
 }
 
 void Actor::faceToObject(int obj) {
@@ -1017,8 +1419,14 @@ void Actor::turnToDirection(int newdir) {
 		return;
 
 	if (_vm->_game.version <= 6) {
-		_moving = MF_TURN;
 		_targetFacing = newdir;
+		
+		if (_vm->_game.version == 0 ) {
+			setDirection( newdir );
+			return;
+		}
+		_moving = MF_TURN;
+		
 	} else {
 		_moving &= ~MF_TURN;
 		if (newdir != _facing) {
@@ -1085,8 +1493,14 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
 	}
 
 	// V0 always sets the actor to face the camera upon entering a room
-	if (_vm->_game.version == 0)
+	if (_vm->_game.version == 0) {
+		_walkdata.dest = _pos;
+
+		((Actor_v0*)this)->unk_FDE1 = 1;
+		((Actor_v0*)this)->_CurrentWalkTo = _pos;
+
 		setDirection(oldDirToNewDir(2));
+	}
 }
 
 static bool inBoxQuickReject(const BoxCoords &box, int x, int y, int threshold) {
@@ -1410,6 +1824,7 @@ void Actor::showActor() {
 		Actor_v0 *a = ((Actor_v0 *)this);
 
 		a->_costCommand = a->_costCommandNew = 0xFF;
+		
 
 		for (int i = 0; i < 8; ++i) {
 			a->_limbFrameRepeat[i] = 0;
@@ -1659,8 +2074,15 @@ void ScummEngine::processActors() {
 		// would hence cause regressions. See also the other big
 		// comment further up in this method for some details.
 		if (a->_costume) {
+
+			if (_game.version == 0)
+				a->animateCostume();
+
 			a->drawActorCostume();
-			a->animateCostume();
+
+			if (_game.version != 0)
+				a->animateCostume();
+				
 		}
 	}
 }
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index 46dc7d0..b2245da 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -354,6 +354,27 @@ public:
 	byte _miscflags;
 	byte _speaking;
 
+	Common::Point _CurrentWalkTo, _NewWalkTo;
+
+	byte _walkDirX;
+	byte _walkDirY;
+
+	byte _walkYCountGreaterThanXCount;
+	byte _walkXCount;
+	byte _walkXCountInc;
+	byte _walkYCount;
+	byte _walkYCountInc;
+	byte _walkCountModulo;
+
+	byte _walkMaxXYCountInc;
+
+	byte unk_FDE1;
+
+	Common::Point _tmp_Pos;
+	Common::Point _tmp_Dest;
+	byte _tmp_WalkBox;
+	byte _tmp_CB5F;
+
 	int8 _animFrameRepeat;
 	int8 _limbFrameRepeatNew[8];
 	int8 _limbFrameRepeat[8];
@@ -363,16 +384,27 @@ public:
 public:
 	Actor_v0(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {}
 
-	virtual void initActor(int mode);
-	virtual void animateActor(int anim);
-	virtual void animateCostume();
+	void initActor(int mode);
+	void animateActor(int anim);
+	void animateCostume();
 
 	void limbFrameCheck(int limb);
 
+	void directionUpdate();
 	void speakCheck();
-	virtual void setDirection(int direction);
+	void setDirection(int direction);
 	void startAnimActor(int f);
 
+	bool sub_2F6F();
+	void walkActor();
+	void actorSetWalkTo();
+	byte actorWalkX();
+	byte actorWalkY();
+	byte updateWalkbox();
+	byte walkboxFindTarget();
+	void setTmpFromActor();
+	void setActorFromTmp();
+
 	// Used by the save/load system:
 	virtual void saveLoadWithSerializer(Serializer *ser);
 
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index 2fe5333..efd5e7b 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -1179,7 +1179,7 @@ bool ScummEngine_v0::checkPendingWalkAction() {
 	Actor_v0 *a = (Actor_v0 *)derefActor(actor, "checkPendingWalkAction");
 
 	// wait until walking or turning action is finished
-	if (a->_moving)
+	if (a->_moving!=2)
 		return true;
 
 	// after walking and turning finally execute the script
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index af39fda..6cbfbf4 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -589,9 +589,9 @@ void ScummEngine_v0::o_loadRoomWithEgo() {
 		return;
 	}
 
-	// The original interpreter sets the actors new room X/Y to the last rooms X/Y
-	// This fixes a problem with MM: script 158 in room 12, the 'Oomph!' script
-	// This scripts runs before the actor position is set to the correct room entry location
+	// The original interpreter seems to set the actors new room X/Y to the last rooms X/Y
+	// This fixes a problem with MM: script 158 in room 12, the 'Oompf!' script
+	// This scripts runs before the actor position is set to the correct location
 	a->putActor(a->getPos().x, a->getPos().y, room);
 	_egoPositioned = false;
 
@@ -714,10 +714,8 @@ void ScummEngine_v0::o_getActorMoving() {
 	getResultPos();
 	int act = getVarOrDirectByte(PARAM_1);
 	Actor *a = derefActor(act, "o_getActorMoving");
-	if (a->_moving)
-		setResult(1);
-	else
-		setResult(2);
+
+	setResult(a->_moving);
 }
 
 void ScummEngine_v0::o_putActorAtObject() {
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index fdb98a8..c1bafe1 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -717,7 +717,6 @@ void ScummEngine_v0::verbExec() {
 	if (a->_miscflags & kActorMiscFlagFreeze)
 		return;
 
-	a->stopActorMoving();
 	a->startWalkActor(VAR(6), VAR(7), -1);
 }
 


Commit: 29d46e8a10b7fae45d833bee0e7d3e4e62d75c5c
    https://github.com/scummvm/scummvm/commit/29d46e8a10b7fae45d833bee0e7d3e4e62d75c5c
Author: Robert Crossfield (robcrossfield at gmail.com)
Date: 2014-11-29T09:07:10+11:00

Commit Message:
SCUMM: Maniac V0: If boxes are neighbors, walk directly to the new box. Remove extra call to 'animateCostume'. Remove now unnecessary V0 walk calc functions

Changed paths:
    engines/scumm/actor.cpp
    engines/scumm/actor.h
    engines/scumm/boxes.cpp
    engines/scumm/script_v0.cpp
    engines/scumm/scumm_v0.h
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 1ea1f6e..636f718 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -33,6 +33,7 @@
 #include "scumm/resource.h"
 #include "scumm/saveload.h"
 #include "scumm/scumm_v7.h"
+#include "scumm/scumm_v0.h"
 #include "scumm/he/sound_he.h"
 #include "scumm/he/sprite_he.h"
 #include "scumm/usage_bits.h"
@@ -453,7 +454,7 @@ void Actor::startWalkActor(int destX, int destY, int dir) {
 	if(_vm->_game.version != 0 ) {
 		_moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
 	} else {
-		((Actor_v0*)this)->unk_FDE1 = 1;
+		((Actor_v0*)this)->_newWalkBoxEntered = 1;
 	}
 	_walkdata.point3.x = 32000;
 
@@ -574,91 +575,7 @@ void Actor::walkActor() {
 	calcMovementFactor(_walkdata.dest);
 }
 
-bool Actor_v2::checkWalkboxesHaveDirectPath(Common::Point &foundPath) {
-	// only MM v0 supports walking in direct line between walkboxes.
-	// MM v1 already does not support it anymore.
-	return false;
-}
-
-bool Actor_v0::intersectLineSegments(const Common::Point &line1Start, const Common::Point &line1End,
-	const Common::Point &line2Start, const Common::Point &line2End, Common::Point &result)
-{
-	const Common::Point v1 = line1End - line1Start; // line1(n1) = line1Start + n1 * v1
-	const Common::Point v2 = line2End - line2Start; // line2(n2) = line2Start + n2 * v2
-
-	double det = v2.x * v1.y - v1.x * v2.y;
-	if (det == 0)
-		return false;
-
-	double n1 = ((double)v2.x * (line2Start.y - line1Start.y) -
-		         (double)v2.y * (line2Start.x - line1Start.x)) / det;
-	double n2 = ((double)v1.x * (line2Start.y - line1Start.y) -
-		         (double)v1.y * (line2Start.x - line1Start.x)) / det;
-
-	// both coefficients have to be in [0, 1], otherwise the intersection is
-	// not inside of at least one of the two line segments
-	if (n1 < 0.0 || n1 > 1.0 || n2 < 0.0 || n2 > 1.0)
-		return false;
-
-	result.x = line1Start.x + (int)(n1 * v1.x);
-	result.y = line1Start.y + (int)(n1 * v1.y);
-	return true;
-}
-
-/*
- * MM v0 allows the actor to walk in a direct line between boxes to the target
- * if actor and target share a horizontal or vertical corridor.
- * If such a corridor is found the actor is not forced to go horizontally or
- * vertically from one box to the next but can also walk diagonally.
- *
- * Note: the original v0 interpreter sets the target destination for diagonal
- * walking only once and then rechecks whenever the actor reaches a new box if the
- * walk destination is still suitable for the current box.
- * ScummVM does not perform such a check, so it is possible to leave the walkboxes
- * in some cases, for example L-shaped rooms like the swimming pool (actor walks over water)
- * or the medical room (actor walks over examination table).
- * To solve this we intersect the new walk destination with the actor's walkbox borders,
- * so a recheck is done when the actor leaves his box. This is done by the
- * intersectLineSegments() routine calls.
- */
-bool Actor_v0::checkWalkboxesHaveDirectPath(Common::Point &foundPath) {
-	BoxCoords boxCoords = _vm->getBoxCoordinates(_walkbox);
-	BoxCoords curBoxCoords = _vm->getBoxCoordinates(_walkdata.curbox);
-
-	// check if next walkbox is left or right to actor's box
-	if (boxCoords.ll.x > curBoxCoords.lr.x || boxCoords.lr.x < curBoxCoords.ll.x) {
-		// determine horizontal corridor gates
-		int gateUpper = MAX(boxCoords.ul.y, curBoxCoords.ul.y);
-		int gateLower = MIN(boxCoords.ll.y, curBoxCoords.ll.y);
-
-		// check if actor and target are in the same horizontal corridor between the boxes
-		if ((_pos.y >= gateUpper && _pos.y <= gateLower) &&
-			(_walkdata.dest.y >= gateUpper && _walkdata.dest.y <= gateLower)) {
-			if (boxCoords.ll.x > curBoxCoords.lr.x) // next box is left
-				return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ll, boxCoords.ul, foundPath);
-			else // next box is right
-				return intersectLineSegments(_pos, _walkdata.dest, boxCoords.lr, boxCoords.ur, foundPath);
-		}
-	// check if next walkbox is above or below actor's box
-	} else if (boxCoords.ul.y > curBoxCoords.ll.y || boxCoords.ll.y < curBoxCoords.ul.y) {
-		// determine vertical corridor gates
-		int gateLeft = MAX(boxCoords.ll.x, curBoxCoords.ll.x);
-		int gateRight = MIN(boxCoords.lr.x, curBoxCoords.lr.x);
-
-		// check if actor and target are in the same vertical corridor between the boxes
-		if ((_pos.x >= gateLeft && _pos.x <= gateRight) &&
-			(_walkdata.dest.x >= gateLeft && _walkdata.dest.x <= gateRight)) {
-			if (boxCoords.ul.y > curBoxCoords.ll.y) // next box is above
-				return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ul, boxCoords.ur, foundPath);
-			else // next box is below
-				return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ll, boxCoords.lr, foundPath);
-		}
-	}
-
-	return false;
-}
-
-bool Actor_v0::sub_2F6F() {
+bool Actor_v0::calcWalkDistances() {
 	_walkDirX = 0;
 	_walkDirY = 0;
 	_walkYCountGreaterThanXCount = 0;
@@ -710,7 +627,7 @@ byte Actor_v0::updateWalkbox() {
 			if (_walkdata.curbox == i ) {
 				setBox(i);
 
-				unk_FDE1 = 1;
+				_newWalkBoxEntered = 1;
 				return i;
 			}
 		}
@@ -723,14 +640,14 @@ void Actor_v0::setTmpFromActor() {
 	_tmp_Pos = _pos;
 	_pos = _tmp_Dest;
 	_tmp_WalkBox = _walkbox;
-	_tmp_CB5F = unk_FDE1;
+	_tmp_NewWalkBoxEntered = _newWalkBoxEntered;
 }
 
 void Actor_v0::setActorFromTmp() {
 	_pos = _tmp_Pos;
 	_tmp_Dest = _tmp_Pos;
 	_walkbox = _tmp_WalkBox;
-	unk_FDE1 = _tmp_CB5F;
+	_newWalkBoxEntered = _tmp_NewWalkBoxEntered;
 }
 
 byte Actor_v0::actorWalkX() {
@@ -748,21 +665,20 @@ byte Actor_v0::actorWalkX() {
 	// 2EAC
 	_walkXCount = A;
 	setTmpFromActor();
-	if( updateWalkbox() == 0xFF ) {
+	if (updateWalkbox() == 0xFF) {
 		// 2EB9
 		setActorFromTmp();
 
 		return 3;
 	} 
 	// 2EBF
-	if( _tmp_Dest.x == _CurrentWalkTo.x )
+	if (_tmp_Dest.x == _CurrentWalkTo.x)
 		return 1;
 
 	return 0;
 }
 
 byte Actor_v0::actorWalkY() {
-
 	byte A = _walkYCount;
 	A += _walkYCountInc;
 	if (A >= _walkCountModulo) {
@@ -782,15 +698,13 @@ byte Actor_v0::actorWalkY() {
 		setActorFromTmp();
 		return 4;
 	} 
-
 	// 2EFE
 	if (_walkYCountInc != 0) {
-		if (_walkYCountInc == 0xFF ) {
+		if (_walkYCountInc == 0xFF) {
 			setActorFromTmp();
 			return 4;
 		}
 	}
-
 	// 2F0D
 	if (_CurrentWalkTo.y == _tmp_Dest.y)
 		return 1;
@@ -798,31 +712,33 @@ byte Actor_v0::actorWalkY() {
 	return 0;
 }
 
-byte Actor_v0::walkboxFindTarget() {
-	return 0xff;
-}
+void Actor_v0::directionUpdate() {
+
+	int nextFacing = updateActorDirection(true);
+	if (_facing != nextFacing) {
+		// 2A89
+		setDirection(nextFacing);
+
+		// Still need to turn?
+		if (_facing != _targetFacing ) {
+			_moving |= 0x80;
+			return;
+		}
+	}
+
+	_moving &= ~0x80;
+}	
 
 void Actor_v0::actorSetWalkTo() {
 	
-	if (unk_FDE1 == 0 )
+	if (_newWalkBoxEntered == 0)
 		return;
 
-	unk_FDE1 = 0;
-	byte nextBox = _vm->getNextBox(_walkbox, _walkdata.destbox);
+	_newWalkBoxEntered = 0;
 
-	if (nextBox != 0xFF && nextBox != _walkbox ) {
-		Common::Point tmp;
+	int nextBox = ((ScummEngine_v0*)_vm)->walkboxFindTarget( this, _walkdata.destbox, _walkdata.dest );
+	if (nextBox != 0xFF) {
 		_walkdata.curbox = nextBox;
-
-		getClosestPtOnBox(_vm->getBoxCoordinates(nextBox), _pos.x, _pos.y, _NewWalkTo.x, _NewWalkTo.y);
-		//getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, _NewWalkTo.x, _NewWalkTo.y);
-		
-
-	} else {
-		if( _walkdata.dest.x == -1 )
-			_NewWalkTo = _CurrentWalkTo;
-		else
-			_NewWalkTo = _walkdata.dest;
 	}
 }
 
@@ -839,7 +755,7 @@ loc_2A33:;
 		_moving &= 0xF0;
 		_tmp_Dest = _pos;
 
-		byte tmp = sub_2F6F();
+		byte tmp = calcWalkDistances();
 		_moving &= 0xF0;
 		_moving |= tmp;
 
@@ -859,7 +775,7 @@ loc_2A33:;
 
 		directionUpdate();
 		
-		if (_moving & 0x80 ) 
+		if (_moving & 0x80) 
 			return;
 
 		animateActor(newDirToOldDir(_facing));
@@ -876,17 +792,17 @@ loc_2A33:;
 
 
 	// 2A9A
-	if (_moving == 2 )
+	if (_moving == 2)
 		return;
 
-	if ((_moving & 0x0F) == 1 )
+	if ((_moving & 0x0F) == 1)
 		return stopActorMoving();
 
 	// 2AAD
 	if (_moving & 0x80) {
 		directionUpdate();
 
-		if ((_moving & 0x80) )
+		if (_moving & 0x80)
 			return;
 
 		// 2AC2
@@ -899,7 +815,7 @@ loc_2C36:;
 		// 2C36
 		setTmpFromActor();
 
-		if (!_walkDirX ) {
+		if (!_walkDirX) {
 			_pos.x--;
 		} else {
 			_pos.x++;
@@ -944,7 +860,7 @@ loc_2C36:;
 	}
 
 	// 2ADA
-	if ((_moving & 0x0F) == 4 ) {
+	if ((_moving & 0x0F) == 4) {
 		// 2CA3
 loc_2CA3:;
 		setTmpFromActor();
@@ -954,22 +870,22 @@ loc_2CA3:;
 		} else {
 			_pos.y++;
 		}
-		if (updateWalkbox() == 0xFF ) {
+		if (updateWalkbox() == 0xFF) {
 			// 2CC7
 			setActorFromTmp();
-			if( _CurrentWalkTo.x == _tmp_Dest.x ) {
+			if( _CurrentWalkTo.x == _tmp_Dest.x) {
 				stopActorMoving();
 				return;
 			}
 			// 2CD5
-			if (!_walkDirX ) {
+			if (!_walkDirX) {
 				_tmp_Dest.x--;
 			} else {
 				_tmp_Dest.x++;
 			}
 			setTmpFromActor();
 
-			if (updateWalkbox() == 0xFF ) {
+			if (updateWalkbox() == 0xFF) {
 				setActorFromTmp();
 				stopActorMoving();
 			}
@@ -981,19 +897,19 @@ loc_2CA3:;
 		}
 	}
 
-	if ((_moving & 0x0F) == 0 ) {
+	if ((_moving & 0x0F) == 0) {
 	 // 2AE8
 		byte A = actorWalkX();
 
-		if( A == 1 ) {
+		if (A == 1) {
 			A = actorWalkY();
-			if( A  == 1 ) {
+			if (A  == 1) {
 				// 2AF6
 				_moving &= 0xF0;
 				_moving |= A;
 			} else {
 				// 2B04
-				if( A == 4 ) 
+				if (A == 4) 
 					stopActorMoving();
 			}
 
@@ -1018,7 +934,7 @@ loc_2CA3:;
 			} else {
 				// 2B39
 				A = actorWalkY();
-				if (A != 4 )
+				if (A != 4)
 					return;
 
 				// 2B46
@@ -1039,22 +955,6 @@ loc_2CA3:;
 	}
 }
 
-void Actor_v0::directionUpdate() {
-
-	int nextFacing = updateActorDirection(true);
-	if (_facing != nextFacing) {
-		// 2A89
-		setDirection(nextFacing);
-
-		if (_facing != _targetFacing ) {
-			_moving |= 0x80;
-		} else {
-			_moving &= ~0x80;
-		}
-	} else
-		_moving &= ~0x80;
-}	
-
 void Actor_v2::walkActor() {
 	Common::Point foundPath, tmp;
 	int new_dir, next_box;
@@ -1101,10 +1001,8 @@ void Actor_v2::walkActor() {
 
 				_walkdata.curbox = next_box;
 
-				if (!checkWalkboxesHaveDirectPath(foundPath)) {
-					getClosestPtOnBox(_vm->getBoxCoordinates(_walkdata.curbox), _pos.x, _pos.y, tmp.x, tmp.y);
-					getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, foundPath.x, foundPath.y);
-				}
+				getClosestPtOnBox(_vm->getBoxCoordinates(_walkdata.curbox), _pos.x, _pos.y, tmp.x, tmp.y);
+				getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, foundPath.x, foundPath.y);
 			}
 			calcMovementFactor(foundPath);
 		}
@@ -1496,7 +1394,7 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
 	if (_vm->_game.version == 0) {
 		_walkdata.dest = _pos;
 
-		((Actor_v0*)this)->unk_FDE1 = 1;
+		((Actor_v0*)this)->_newWalkBoxEntered = 1;
 		((Actor_v0*)this)->_CurrentWalkTo = _pos;
 
 		setDirection(oldDirToNewDir(2));
@@ -2075,14 +1973,15 @@ void ScummEngine::processActors() {
 		// comment further up in this method for some details.
 		if (a->_costume) {
 
-			if (_game.version == 0)
+			// Unfortunately in V0, the 'animateCostume' call happens right after the call to 'walkActor', before drawing the actor... doing it the
+			// other way with V0, causes graphic glitches
+			if (_game.version == 0) {
 				a->animateCostume();
-
-			a->drawActorCostume();
-
-			if (_game.version != 0)
+				a->drawActorCostume();
+			} else {
+				a->drawActorCostume();
 				a->animateCostume();
-				
+			}
 		}
 	}
 }
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index b2245da..c554cad 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -333,7 +333,6 @@ public:
 protected:
 	virtual bool isPlayer();
 	virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
-	virtual bool checkWalkboxesHaveDirectPath(Common::Point &foundPath);
 };
 
 enum ActorV0MiscFlags {
@@ -349,12 +348,15 @@ enum ActorV0MiscFlags {
 
 class Actor_v0 : public Actor_v2 {
 public:
+	Common::Point _CurrentWalkTo, _NewWalkTo;
+
 	byte _costCommandNew;
 	byte _costCommand;
 	byte _miscflags;
 	byte _speaking;
 
-	Common::Point _CurrentWalkTo, _NewWalkTo;
+	byte _walkCountModulo;
+	byte _newWalkBoxEntered;
 
 	byte _walkDirX;
 	byte _walkDirY;
@@ -364,16 +366,13 @@ public:
 	byte _walkXCountInc;
 	byte _walkYCount;
 	byte _walkYCountInc;
-	byte _walkCountModulo;
 
 	byte _walkMaxXYCountInc;
 
-	byte unk_FDE1;
-
 	Common::Point _tmp_Pos;
 	Common::Point _tmp_Dest;
 	byte _tmp_WalkBox;
-	byte _tmp_CB5F;
+	byte _tmp_NewWalkBoxEntered;
 
 	int8 _animFrameRepeat;
 	int8 _limbFrameRepeatNew[8];
@@ -395,23 +394,18 @@ public:
 	void setDirection(int direction);
 	void startAnimActor(int f);
 
-	bool sub_2F6F();
+	bool calcWalkDistances();
 	void walkActor();
 	void actorSetWalkTo();
 	byte actorWalkX();
 	byte actorWalkY();
 	byte updateWalkbox();
-	byte walkboxFindTarget();
+
 	void setTmpFromActor();
 	void setActorFromTmp();
 
 	// Used by the save/load system:
 	virtual void saveLoadWithSerializer(Serializer *ser);
-
-protected:
-	bool intersectLineSegments(const Common::Point &line1Start, const Common::Point &line1End,
-		const Common::Point &line2Start, const Common::Point &line2End, Common::Point &result);
-	virtual bool checkWalkboxesHaveDirectPath(Common::Point &foundPath);
 };
 
 
diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp
index 70c8f2e..087d842 100644
--- a/engines/scumm/boxes.cpp
+++ b/engines/scumm/boxes.cpp
@@ -1158,6 +1158,30 @@ bool ScummEngine::areBoxesNeighbors(int box1nr, int box2nr) {
 	return false;
 }
 
+byte ScummEngine_v0::walkboxFindTarget(Actor *a, int destbox, Common::Point walkdest) {
+	Actor_v0 *Actor = (Actor_v0*)a;
+
+	byte nextBox = getNextBox(a->_walkbox, destbox);
+
+	if (nextBox != 0xFF && nextBox == destbox && areBoxesNeighbors(a->_walkbox, nextBox)) {
+
+		Actor->_NewWalkTo = walkdest;
+		return nextBox;
+	}
+
+	if (nextBox != 0xFF && 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
+			Actor->_NewWalkTo = walkdest;
+	}
+	return nextBox;
+}
+
 bool ScummEngine_v0::areBoxesNeighbors(int box1nr, int box2nr) {
 	int i;
 	const int numOfBoxes = getNumBoxes();
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 6cbfbf4..9029153 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -589,9 +589,9 @@ void ScummEngine_v0::o_loadRoomWithEgo() {
 		return;
 	}
 
-	// The original interpreter seems to set the actors new room X/Y to the last rooms X/Y
-	// This fixes a problem with MM: script 158 in room 12, the 'Oompf!' script
-	// This scripts runs before the actor position is set to the correct location
+	// The original interpreter sets the actors new room X/Y to the last rooms X/Y
+	// This fixes a problem with MM: script 158 in room 12, the 'Oomph!' script
+	// This scripts runs before the actor position is set to the correct room entry location
 	a->putActor(a->getPos().x, a->getPos().y, room);
 	_egoPositioned = false;
 
@@ -707,7 +707,6 @@ void ScummEngine_v0::o_animateActor() {
 	}
 
 	a->animateActor(anim);
-	a->animateCostume();
 }
 
 void ScummEngine_v0::o_getActorMoving() {
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 80d047a..83e0e32 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -67,6 +67,8 @@ public:
 
 	virtual void resetScumm();
 
+	byte walkboxFindTarget(Actor *a, int destbox, Common::Point walkdest);
+
 protected:
 	virtual void resetRoomObject(ObjectData *od, const byte *room, const byte *searchptr = NULL);
 
@@ -116,7 +118,7 @@ protected:
 
 	void resetSentence();
 
-	virtual bool areBoxesNeighbors(int box1nr, int box2nr);
+	bool areBoxesNeighbors(int box1nr, int box2nr);
 
 	bool ifEqualActiveObject2Common(bool checkType);
 
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index c1bafe1..bf0a693 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -708,7 +708,6 @@ void ScummEngine_v0::verbExec() {
 	Actor_v0 *a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "verbExec");
 	int x = _virtualMouse.x / V12_X_MULTIPLIER;
 	int y = _virtualMouse.y / V12_Y_MULTIPLIER;
-	//actorSetPosInBox();
 
 	// 0xB31
 	VAR(6) = x;


Commit: 814d9b1153df417c184be2b1a9072d0c7b37b201
    https://github.com/scummvm/scummvm/commit/814d9b1153df417c184be2b1a9072d0c7b37b201
Author: Robert Crossfield (robcrossfield at gmail.com)
Date: 2014-12-02T16:25:03+11:00

Commit Message:
SCUMM: Maniac V0: Correctly handle 'slanted' walk-boxes, Add new variables to save-games, Bump the SaveGame Version number, remove obsolete V0 code in V2 functions

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



diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 636f718..90ee5bf 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -51,6 +51,12 @@ static const byte v0ActorTalkArray[0x19] = {
 	0xC0, 0xC0, 0x00, 0x06, 0x06
 };
 
+static const byte v0WalkboxSlantedModifier[0x16] = { 
+	0x00,0x01,0x02,0x03,0x03,0x04,0x05,0x06,
+	0x06,0x07,0x08,0x09,0x09,0x0A,0x0B,
+	0x0C,0x0C,0x0D,0x0E,0x0F,0x10,0x10
+};
+
 Actor::Actor(ScummEngine *scumm, int id) :
 	_vm(scumm), _number(id) {
 	assert(_vm != 0);
@@ -183,6 +189,20 @@ void Actor_v0::initActor(int mode) {
 	_costCommand = 0xFF;
 	_miscflags = 0;
 	_speaking = 0;
+	
+	_walkCountModulo = 0;
+	_newWalkBoxEntered = false;
+	_walkDirX = 0;
+	_walkDirY = 0;
+	_walkYCountGreaterThanXCount = 0;
+	_walkXCount = 0;
+	_walkXCountInc = 0;
+	_walkYCount = 0;
+	_walkYCountInc = 0;
+	_walkMaxXYCountInc = 0;
+
+	_tmp_WalkBox = 0;
+	_tmp_NewWalkBoxEntered = 0;
 
 	_animFrameRepeat = 0;
 	for (int i = 0; i < 8; ++i) {
@@ -250,11 +270,11 @@ void Actor::stopActorMoving() {
 	if (_walkScript)
 		_vm->stopScript(_walkScript);
 
-	_moving = 0;
-
 	if (_vm->_game.version == 0) {
 		_moving = 2;
 		setDirection(_facing);
+	} else {
+		_moving = 0;
 	}
 }
 
@@ -343,9 +363,6 @@ int Actor::actorWalkStep() {
 	int distX, distY;
 	int nextFacing;
 
-	if (_vm->_game.version == 0)
-		((Actor_v0 *)this)->_animFrameRepeat = -1;
-
 	_needRedraw = true;
 
 	nextFacing = updateActorDirection(true);
@@ -354,10 +371,6 @@ int Actor::actorWalkStep() {
 			startWalkAnim(1, nextFacing);
 		}
 		_moving |= MF_IN_LEG;
-
-		// V0: Don't move during the turn
-		if (_vm->_game.version == 0)
-			return 0;
 	}
 
 	if (_walkbox != _walkdata.curbox && _vm->checkXYInBoxBounds(_walkdata.curbox, _pos.x, _pos.y)) {
@@ -393,12 +406,113 @@ int Actor::actorWalkStep() {
 		return 0;
 	}
 
-	if (_vm->_game.version == 0)
-		((Actor_v0 *)this)->animateActor(newDirToOldDir(_facing));
-
 	return 1;
 }
 
+bool Actor_v0::calcWalkDistances() {
+	_walkDirX = 0;
+	_walkDirY = 0;
+	_walkYCountGreaterThanXCount = 0;
+	uint16 A = 0;
+
+	if (_CurrentWalkTo.x >= _tmp_Dest.x ) {
+		A = _CurrentWalkTo.x - _tmp_Dest.x;
+		_walkDirX = 1;
+	} else {
+		A = _tmp_Dest.x - _CurrentWalkTo.x;
+	}
+
+	_walkXCountInc = A;
+
+	if (_CurrentWalkTo.y >= _tmp_Dest.y ) {
+		A = _CurrentWalkTo.y - _tmp_Dest.y;
+		_walkDirY = 1;
+	} else {
+		A = _tmp_Dest.y - _CurrentWalkTo.y;
+	}
+
+	_walkYCountInc = A;
+	if ( !_walkXCountInc && !_walkYCountInc )
+		return true;
+
+	if( _walkXCountInc <= _walkYCountInc ) 
+		_walkYCountGreaterThanXCount = 1;
+
+	// 2FCC
+	A = _walkXCountInc;
+	if( A <= _walkYCountInc )
+		A = _walkYCountInc;
+
+	_walkMaxXYCountInc = A;
+	_walkXCount = _walkXCountInc;
+	_walkYCount = _walkYCountInc;
+	_walkCountModulo = _walkMaxXYCountInc;
+
+	return false;
+}
+
+byte Actor_v0::actorWalkX() {
+	byte A = _walkXCount;
+	A += _walkXCountInc;
+	if (A >= _walkCountModulo) {
+		if (!_walkDirX ) {
+			_tmp_Dest.x--;
+		} else {
+			_tmp_Dest.x++;
+		}
+
+		A -= _walkCountModulo;
+	}
+	// 2EAC
+	_walkXCount = A;
+	setTmpFromActor();
+	if (updateWalkbox() == kInvalidBox) {
+		// 2EB9
+		setActorFromTmp();
+
+		return 3;
+	} 
+	// 2EBF
+	if (_tmp_Dest.x == _CurrentWalkTo.x)
+		return 1;
+
+	return 0;
+}
+
+byte Actor_v0::actorWalkY() {
+	byte A = _walkYCount;
+	A += _walkYCountInc;
+	if (A >= _walkCountModulo) {
+		if (!_walkDirY ) {
+			_tmp_Dest.y--;
+		} else {
+			_tmp_Dest.y++;
+		}
+
+		A -= _walkCountModulo;
+	}
+	// 2EEB
+	_walkYCount = A;
+	setTmpFromActor();
+	if (updateWalkbox() == kInvalidBox) {
+		// 2EF8
+		setActorFromTmp();
+		return 4;
+	} 
+	// 2EFE
+	if (_walkYCountInc != 0) {
+		if (_walkYCountInc == 0xFF) {
+			setActorFromTmp();
+			return 4;
+		}
+	}
+	// 2F0D
+	if (_CurrentWalkTo.y == _tmp_Dest.y)
+		return 1;
+	
+	return 0;
+}
+
 void Actor::startWalkActor(int destX, int destY, int dir) {
 	AdjustBoxResult abr;
 
@@ -451,14 +565,14 @@ void Actor::startWalkActor(int destX, int destY, int dir) {
 	_walkdata.dest.y = abr.y;
 	_walkdata.destbox = abr.box;
 	_walkdata.destdir = dir;
-	if(_vm->_game.version != 0 ) {
-		_moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
-	} else {
-		((Actor_v0*)this)->_newWalkBoxEntered = 1;
-	}
 	_walkdata.point3.x = 32000;
-
 	_walkdata.curbox = _walkbox;
+
+	if(_vm->_game.version == 0 ) {
+		((Actor_v0*)this)->_newWalkBoxEntered = true;
+	} else {
+		_moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
+	}
 }
 
 void Actor::startWalkAnim(int cmd, int angle) {
@@ -575,183 +689,14 @@ void Actor::walkActor() {
 	calcMovementFactor(_walkdata.dest);
 }
 
-bool Actor_v0::calcWalkDistances() {
-	_walkDirX = 0;
-	_walkDirY = 0;
-	_walkYCountGreaterThanXCount = 0;
-	uint16 A = 0;
-
-	if (_CurrentWalkTo.x >= _tmp_Dest.x ) {
-		A = _CurrentWalkTo.x - _tmp_Dest.x;
-		_walkDirX = 1;
-	} else {
-		A = _tmp_Dest.x - _CurrentWalkTo.x;
-	}
-
-	_walkXCountInc = A;
-
-	if (_CurrentWalkTo.y >= _tmp_Dest.y ) {
-		A = _CurrentWalkTo.y - _tmp_Dest.y;
-		_walkDirY = 1;
-	} else {
-		A = _tmp_Dest.y - _CurrentWalkTo.y;
-	}
-
-	_walkYCountInc = A;
-	if ( !_walkXCountInc && !_walkYCountInc )
-		return true;
-
-	if( _walkXCountInc <= _walkYCountInc ) 
-		_walkYCountGreaterThanXCount = 1;
-
-	// 2FCC
-	A = _walkXCountInc;
-	if( A <= _walkYCountInc )
-		A = _walkYCountInc;
-
-	_walkMaxXYCountInc = A;
-	_walkXCount = _walkXCountInc;
-	_walkYCount = _walkYCountInc;
-	_walkCountModulo = _walkMaxXYCountInc;
-
-	return false;
-}
-
-byte Actor_v0::updateWalkbox() {
-	if( _vm->checkXYInBoxBounds( _walkbox, _pos.x, _pos.y ) )
-		return 0;
-
-	int numBoxes = _vm->getNumBoxes() - 1;
-	for (int i = 0; i <= numBoxes; i++) {
-		if (_vm->checkXYInBoxBounds( i, _pos.x, _pos.y ) == true ) {
-			if (_walkdata.curbox == i ) {
-				setBox(i);
-
-				_newWalkBoxEntered = 1;
-				return i;
-			}
-		}
-	}
-
-	return 0xFF;
-}
-
-void Actor_v0::setTmpFromActor() {
-	_tmp_Pos = _pos;
-	_pos = _tmp_Dest;
-	_tmp_WalkBox = _walkbox;
-	_tmp_NewWalkBoxEntered = _newWalkBoxEntered;
-}
-
-void Actor_v0::setActorFromTmp() {
-	_pos = _tmp_Pos;
-	_tmp_Dest = _tmp_Pos;
-	_walkbox = _tmp_WalkBox;
-	_newWalkBoxEntered = _tmp_NewWalkBoxEntered;
-}
-
-byte Actor_v0::actorWalkX() {
-	byte A = _walkXCount;
-	A += _walkXCountInc;
-	if (A >= _walkCountModulo) {
-		if (!_walkDirX ) {
-			_tmp_Dest.x--;
-		} else {
-			_tmp_Dest.x++;
-		}
-
-		A -= _walkCountModulo;
-	}
-	// 2EAC
-	_walkXCount = A;
-	setTmpFromActor();
-	if (updateWalkbox() == 0xFF) {
-		// 2EB9
-		setActorFromTmp();
-
-		return 3;
-	} 
-	// 2EBF
-	if (_tmp_Dest.x == _CurrentWalkTo.x)
-		return 1;
-
-	return 0;
-}
-
-byte Actor_v0::actorWalkY() {
-	byte A = _walkYCount;
-	A += _walkYCountInc;
-	if (A >= _walkCountModulo) {
-		if (!_walkDirY ) {
-			_tmp_Dest.y--;
-		} else {
-			_tmp_Dest.y++;
-		}
-
-		A -= _walkCountModulo;
-	}
-	// 2EEB
-	_walkYCount = A;
-	setTmpFromActor();
-	if (updateWalkbox() == 0xFF) {
-		// 2EF8
-		setActorFromTmp();
-		return 4;
-	} 
-	// 2EFE
-	if (_walkYCountInc != 0) {
-		if (_walkYCountInc == 0xFF) {
-			setActorFromTmp();
-			return 4;
-		}
-	}
-	// 2F0D
-	if (_CurrentWalkTo.y == _tmp_Dest.y)
-		return 1;
-
-	return 0;
-}
-
-void Actor_v0::directionUpdate() {
-
-	int nextFacing = updateActorDirection(true);
-	if (_facing != nextFacing) {
-		// 2A89
-		setDirection(nextFacing);
-
-		// Still need to turn?
-		if (_facing != _targetFacing ) {
-			_moving |= 0x80;
-			return;
-		}
-	}
-
-	_moving &= ~0x80;
-}	
-
-void Actor_v0::actorSetWalkTo() {
-	
-	if (_newWalkBoxEntered == 0)
-		return;
-
-	_newWalkBoxEntered = 0;
-
-	int nextBox = ((ScummEngine_v0*)_vm)->walkboxFindTarget( this, _walkdata.destbox, _walkdata.dest );
-	if (nextBox != 0xFF) {
-		_walkdata.curbox = nextBox;
-	}
-}
-
 void Actor_v0::walkActor() {
 	actorSetWalkTo();
 
 	_needRedraw = true;
 	if (_NewWalkTo != _CurrentWalkTo) {
-		
-		// 2A27
 		_CurrentWalkTo = _NewWalkTo;
 
-loc_2A33:;
+L2A33:;
 		_moving &= 0xF0;
 		_tmp_Dest = _pos;
 
@@ -784,13 +729,11 @@ loc_2A33:;
 		// 2A0A
 		if ((_moving & 0x7F) != 1) {
 			
-			if (_NewWalkTo == _pos) {
+			if (_NewWalkTo == _pos)
 				return;
-			}
 		}
 	}
 
-
 	// 2A9A
 	if (_moving == 2)
 		return;
@@ -805,14 +748,11 @@ loc_2A33:;
 		if (_moving & 0x80)
 			return;
 
-		// 2AC2
 		animateActor(newDirToOldDir(_facing));
 	}
 
-	// 2ACE
 	if ((_moving & 0x0F) == 3 ) {
-loc_2C36:;
-		// 2C36
+L2C36:;
 		setTmpFromActor();
 
 		if (!_walkDirX) {
@@ -822,13 +762,12 @@ loc_2C36:;
 		}
 
 		// 2C51
-		if (updateWalkbox() != 0xFF) {
-			//2C66
+		if (updateWalkbox() != kInvalidBox) {
+
 			setActorFromTmp();
-			goto loc_2A33;
+			goto L2A33;
 		}
 
-		// 2C6C
 		setActorFromTmp();
 
 		if (_CurrentWalkTo.y == _tmp_Dest.y) {
@@ -841,8 +780,9 @@ loc_2C36:;
 		} else {
 			_tmp_Dest.y++;
 		}
+
 		setTmpFromActor();
-		//2C8B
+
 		byte A = updateWalkbox();
 		if (A == 0xFF) {
 			setActorFromTmp();
@@ -861,8 +801,7 @@ loc_2C36:;
 
 	// 2ADA
 	if ((_moving & 0x0F) == 4) {
-		// 2CA3
-loc_2CA3:;
+L2CA3:;
 		setTmpFromActor();
 
 		if (!_walkDirY) {
@@ -870,14 +809,14 @@ loc_2CA3:;
 		} else {
 			_pos.y++;
 		}
-		if (updateWalkbox() == 0xFF) {
+		if (updateWalkbox() == kInvalidBox) {
 			// 2CC7
 			setActorFromTmp();
 			if( _CurrentWalkTo.x == _tmp_Dest.x) {
 				stopActorMoving();
 				return;
 			}
-			// 2CD5
+
 			if (!_walkDirX) {
 				_tmp_Dest.x--;
 			} else {
@@ -885,7 +824,7 @@ loc_2CA3:;
 			}
 			setTmpFromActor();
 
-			if (updateWalkbox() == 0xFF) {
+			if (updateWalkbox() == kInvalidBox) {
 				setActorFromTmp();
 				stopActorMoving();
 			}
@@ -893,22 +832,20 @@ loc_2CA3:;
 			return;
 		} else {
 			setActorFromTmp();
-			goto loc_2A33;
+			goto L2A33;
 		}
 	}
 
 	if ((_moving & 0x0F) == 0) {
-	 // 2AE8
+		// 2AE8
 		byte A = actorWalkX();
 
 		if (A == 1) {
 			A = actorWalkY();
-			if (A  == 1) {
-				// 2AF6
+			if (A == 1) {
 				_moving &= 0xF0;
 				_moving |= A;
 			} else {
-				// 2B04
 				if (A == 4) 
 					stopActorMoving();
 			}
@@ -929,7 +866,7 @@ loc_2CA3:;
 
 				directionUpdate();
 				animateActor(newDirToOldDir(_facing));
-				goto loc_2C36;
+				goto L2C36;
 
 			} else {
 				// 2B39
@@ -937,7 +874,6 @@ loc_2CA3:;
 				if (A != 4)
 					return;
 
-				// 2B46
 				_moving &= 0xF0;
 				_moving |= A;
 
@@ -949,7 +885,7 @@ loc_2CA3:;
 				
 				directionUpdate();
 				animateActor(newDirToOldDir(_facing));
-				goto loc_2CA3;
+				goto L2CA3;
 			}
 		}
 	}
@@ -1394,7 +1330,7 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
 	if (_vm->_game.version == 0) {
 		_walkdata.dest = _pos;
 
-		((Actor_v0*)this)->_newWalkBoxEntered = 1;
+		((Actor_v0*)this)->_newWalkBoxEntered = true;
 		((Actor_v0*)this)->_CurrentWalkTo = _pos;
 
 		setDirection(oldDirToNewDir(2));
@@ -1512,6 +1448,59 @@ static int checkXYInBoxBounds(int boxnum, int x, int y, int &destX, int &destY)
 	return dist;
 }
 
+AdjustBoxResult Actor_v0::adjustPosInBorderWalkbox(AdjustBoxResult box) {
+	AdjustBoxResult Result = box;
+	BoxCoords BoxCoord = _vm->getBoxCoordinates(box.box);
+
+	byte boxMask = _vm->getMaskFromBox(box.box);
+	if (!(boxMask & 0x80))
+		return Result;
+
+	char A;
+	boxMask &= 0x7C;
+	if (boxMask == 0x0C) 
+		A = 2;
+	else {
+		if (boxMask != 0x08)
+			return Result;
+
+		A = 1;
+	}
+
+	// 1BC6
+	byte Modifier = box.y - BoxCoord.ul.y;
+	assert(Modifier < 0x16);
+
+	if (A == 1) {
+		// 1BCF
+		A = BoxCoord.ur.x - v0WalkboxSlantedModifier[ Modifier ];
+		if (A < box.x)
+			return box;
+
+		if (A < 0xA0 || A == 0xA0)
+			A = 0;
+
+		Result.x = A;
+	} else {
+		// 1BED
+		A = BoxCoord.ul.x + v0WalkboxSlantedModifier[ Modifier ];
+
+		if (A < box.x || A == box.x)
+			Result.x = A;
+	}
+
+	return Result;
+}
+
+AdjustBoxResult Actor_v0::adjustXYToBeInBox(int dstX, int dstY) {
+	AdjustBoxResult Result = Actor_v2::adjustXYToBeInBox(dstX, dstY);
+
+	if( Result.box == kInvalidBox )
+		return Result;
+
+	return adjustPosInBorderWalkbox(Result);
+}
+
 AdjustBoxResult Actor_v2::adjustXYToBeInBox(const int dstX, const int dstY) {
 	AdjustBoxResult abr;
 
@@ -1722,7 +1711,7 @@ void Actor::showActor() {
 		Actor_v0 *a = ((Actor_v0 *)this);
 
 		a->_costCommand = a->_costCommandNew = 0xFF;
-		
+		_walkdata.dest = a->_CurrentWalkTo;
 
 		for (int i = 0; i < 8; ++i) {
 			a->_limbFrameRepeat[i] = 0;
@@ -1955,7 +1944,7 @@ void ScummEngine::processActors() {
 				continue;
 
 			// Sound
-			if (a0->_moving  && _currentRoom != 1 && _currentRoom != 44) {
+			if (a0->_moving != 2 && _currentRoom != 1 && _currentRoom != 44) {
 				if (a0->_cost.soundPos == 0)
 					a0->_cost.soundCounter++;
 
@@ -1973,8 +1962,9 @@ void ScummEngine::processActors() {
 		// comment further up in this method for some details.
 		if (a->_costume) {
 
-			// Unfortunately in V0, the 'animateCostume' call happens right after the call to 'walkActor', before drawing the actor... doing it the
-			// other way with V0, causes graphic glitches
+			// Unfortunately in V0, the 'animateCostume' call happens right after the call to 'walkActor' (which is before drawing the actor)... 
+			// doing it the other way with V0, causes animation glitches (when beginnning to walk, as the costume hasnt been updated).
+			// Updating the costume directly after 'walkActor' and again, after drawing... causes frame skipping
 			if (_game.version == 0) {
 				a->animateCostume();
 				a->drawActorCostume();
@@ -3218,6 +3208,70 @@ void Actor_v0::animateActor(int anim) {
 	}
 }
 
+byte Actor_v0::updateWalkbox() {
+	if( _vm->checkXYInBoxBounds( _walkbox, _pos.x, _pos.y ) )
+		return 0;
+
+	int numBoxes = _vm->getNumBoxes() - 1;
+	for (int i = 0; i <= numBoxes; i++) {
+		if (_vm->checkXYInBoxBounds( i, _pos.x, _pos.y ) == true ) {
+			if (_walkdata.curbox == i) {
+				setBox(i);
+				directionUpdate();
+
+				_newWalkBoxEntered = true;
+				return i;
+			}
+		}
+	}
+
+	return kInvalidBox;
+}
+
+void Actor_v0::directionUpdate() {
+
+	int nextFacing = updateActorDirection(true);
+	if (_facing != nextFacing) {
+		// 2A89
+		setDirection(nextFacing);
+
+		// Still need to turn?
+		if (_facing != _targetFacing) {
+			_moving |= 0x80;
+			return;
+		}
+	}
+
+	_moving &= ~0x80;
+}
+
+void Actor_v0::setTmpFromActor() {
+	_tmp_Pos = _pos;
+	_pos = _tmp_Dest;
+	_tmp_WalkBox = _walkbox;
+	_tmp_NewWalkBoxEntered = _newWalkBoxEntered;
+}
+
+void Actor_v0::setActorFromTmp() {
+	_pos = _tmp_Pos;
+	_tmp_Dest = _tmp_Pos;
+	_walkbox = _tmp_WalkBox;
+	_newWalkBoxEntered = _tmp_NewWalkBoxEntered;
+}
+
+void Actor_v0::actorSetWalkTo() {
+	
+	if (_newWalkBoxEntered == false)
+		return;
+
+	_newWalkBoxEntered = false;
+
+	int nextBox = ((ScummEngine_v0*)_vm)->walkboxFindTarget(this, _walkdata.destbox, _walkdata.dest);
+	if (nextBox != kInvalidBox) {
+		_walkdata.curbox = nextBox;
+	}
+}
+
 void Actor_v0::saveLoadWithSerializer(Serializer *ser) {
 	Actor::saveLoadWithSerializer(ser);
 
@@ -3231,6 +3285,20 @@ void Actor_v0::saveLoadWithSerializer(Serializer *ser) {
 		MKLINE(Actor_v0, _animFrameRepeat, sleByte, VER(89)),
 		MKARRAY(Actor_v0, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)),
 		MKARRAY(Actor_v0, _limbFrameRepeat[0], sleInt8, 8, VER(90)),
+		MKLINE(Actor_v0, _CurrentWalkTo.x, sleInt16, VER(97)),
+		MKLINE(Actor_v0, _CurrentWalkTo.y, sleInt16, VER(97)),
+		MKLINE(Actor_v0, _NewWalkTo.x, sleInt16, VER(97)),
+		MKLINE(Actor_v0, _NewWalkTo.y, sleInt16, VER(97)),
+		MKLINE(Actor_v0, _walkCountModulo, sleInt8, VER(97)),
+		MKLINE(Actor_v0, _newWalkBoxEntered, sleByte, VER(97)),
+		MKLINE(Actor_v0, _walkDirX, sleByte, VER(97)),
+		MKLINE(Actor_v0, _walkDirY, sleByte, VER(97)),
+		MKLINE(Actor_v0, _walkYCountGreaterThanXCount, sleByte, VER(97)),
+		MKLINE(Actor_v0, _walkXCount, sleByte, VER(97)),
+		MKLINE(Actor_v0, _walkXCountInc, sleByte, VER(97)),
+		MKLINE(Actor_v0, _walkYCount, sleByte, VER(97)),
+		MKLINE(Actor_v0, _walkYCountInc, sleByte, VER(97)),
+		MKLINE(Actor_v0, _walkMaxXYCountInc, sleByte, VER(97)),
 		MKEND()
 	};
 
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index c554cad..c1a3f23 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -356,7 +356,7 @@ public:
 	byte _speaking;
 
 	byte _walkCountModulo;
-	byte _newWalkBoxEntered;
+	bool _newWalkBoxEntered;
 
 	byte _walkDirX;
 	byte _walkDirY;
@@ -372,7 +372,7 @@ public:
 	Common::Point _tmp_Pos;
 	Common::Point _tmp_Dest;
 	byte _tmp_WalkBox;
-	byte _tmp_NewWalkBoxEntered;
+	bool _tmp_NewWalkBoxEntered;
 
 	int8 _animFrameRepeat;
 	int8 _limbFrameRepeatNew[8];
@@ -401,6 +401,9 @@ public:
 	byte actorWalkY();
 	byte updateWalkbox();
 
+	AdjustBoxResult adjustXYToBeInBox(int dstX, int dstY);
+	AdjustBoxResult adjustPosInBorderWalkbox(AdjustBoxResult box);
+
 	void setTmpFromActor();
 	void setActorFromTmp();
 
diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h
index 01ed21e..753287e 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 96
+#define CURRENT_VER 97
 
 /**
  * An auxillary macro, used to specify savegame versions. We use this instead
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index efd5e7b..c9b37d4 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -1164,8 +1164,10 @@ void ScummEngine_v0::walkToActorOrObject(int object) {
 	VAR(7) = y;
 
 	// actor must not move if frozen
-	if (a->_miscflags & kActorMiscFlagFreeze)
+	if (a->_miscflags & kActorMiscFlagFreeze) {
 		a->stopActorMoving();
+		a->_newWalkBoxEntered = false;
+	}
 }
 
 bool ScummEngine_v0::checkPendingWalkAction() {
@@ -1179,7 +1181,7 @@ bool ScummEngine_v0::checkPendingWalkAction() {
 	Actor_v0 *a = (Actor_v0 *)derefActor(actor, "checkPendingWalkAction");
 
 	// wait until walking or turning action is finished
-	if (a->_moving!=2)
+	if (a->_moving != 2)
 		return true;
 
 	// after walking and turning finally execute the script


Commit: 4b1b9ec66f5889fd20d88f8f7f565e8448ac8389
    https://github.com/scummvm/scummvm/commit/4b1b9ec66f5889fd20d88f8f7f565e8448ac8389
Author: Robert Crossfield (robcrossfield at gmail.com)
Date: 2014-12-02T16:40:46+11:00

Commit Message:
SCUMM: Maniac V0: Remove workaround for bug #2971126 (this issue no longer occurs as walking is handled the same as the original)

Changed paths:
    engines/scumm/script_v5.cpp



diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 91afa85..4a53ca3 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -2497,10 +2497,6 @@ void ScummEngine_v5::walkActorToActor(int actor, int toActor, int dist) {
 		y = abr.y;
 	}
 	a->startWalkActor(x, y, -1);
-
-	// WORKAROUND: See bug #2971126 for details on why this is here.
-	if (_game.version == 0)
-		o5_breakHere();
 }
 
 void ScummEngine_v5::o5_walkActorToActor() {


Commit: dcd0f597e6026e248ff6e2db0224f3f60626cdca
    https://github.com/scummvm/scummvm/commit/dcd0f597e6026e248ff6e2db0224f3f60626cdca
Author: Kirben (kirben at optusnet.com.au)
Date: 2014-12-07T15:09:36+11:00

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

SCUMM: Maniac V0: Original Walk Code Implementation

Changed paths:
    engines/scumm/actor.cpp
    engines/scumm/actor.h
    engines/scumm/boxes.cpp
    engines/scumm/saveload.h
    engines/scumm/script.cpp
    engines/scumm/script_v0.cpp
    engines/scumm/script_v5.cpp
    engines/scumm/scumm_v0.h
    engines/scumm/verbs.cpp









More information about the Scummvm-git-logs mailing list