diff options
Diffstat (limited to 'engines/scumm')
| -rw-r--r-- | engines/scumm/actor.cpp | 57 | ||||
| -rw-r--r-- | engines/scumm/actor.h | 4 | ||||
| -rw-r--r-- | engines/scumm/boxes.cpp | 10 | ||||
| -rw-r--r-- | engines/scumm/gfx.cpp | 2 | ||||
| -rw-r--r-- | engines/scumm/object.cpp | 2 | ||||
| -rw-r--r-- | engines/scumm/scumm.cpp | 50 | ||||
| -rw-r--r-- | engines/scumm/scumm.h | 11 | ||||
| -rw-r--r-- | engines/scumm/scumm_v0.h | 4 | 
8 files changed, 101 insertions, 39 deletions
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 6cb5ce5708..b3e7926015 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 3bc301fddb..62ba161f4e 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 108f227ec2..b5caec3c4f 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 5dc96eceb9..48818b8abf 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 db836467ef..da94a34baf 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 3b7dea194b..3c617470fe 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 5a653d0970..2906fc71f5 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 4098d639c4..5f40940166 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);  | 
