diff options
| -rw-r--r-- | engines/scumm/actor.cpp | 440 | ||||
| -rw-r--r-- | engines/scumm/actor.h | 40 | ||||
| -rw-r--r-- | engines/scumm/script.cpp | 2 | ||||
| -rw-r--r-- | engines/scumm/script_v0.cpp | 12 | ||||
| -rw-r--r-- | engines/scumm/verbs.cpp | 1 | 
5 files changed, 473 insertions, 22 deletions
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 116a953b0b..1ea1f6eb54 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 46dc7d0295..b2245da3d2 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 2fe5333bfc..efd5e7bd2c 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 af39fdaad8..6cbfbf45b3 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 fdb98a8019..c1bafe1e0f 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);  }  | 
