[Scummvm-git-logs] scummvm master -> ef42fd3476eb5da3a832d09b35e1cf539f8c2b95

bgK bastien.bouclet at gmail.com
Fri Jul 14 20:01:20 CEST 2017


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

Summary:
ef42fd3476 MOHAWK: Riven: Implement transition offsets


Commit: ef42fd3476eb5da3a832d09b35e1cf539f8c2b95
    https://github.com/scummvm/scummvm/commit/ef42fd3476eb5da3a832d09b35e1cf539f8c2b95
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-14T19:45:23+02:00

Commit Message:
MOHAWK: Riven: Implement transition offsets

The games tries to match objects between the old and new card by
offsetting the transition of the new card.

Fixes #9947.

Changed paths:
    engines/mohawk/riven_card.cpp
    engines/mohawk/riven_card.h
    engines/mohawk/riven_graphics.cpp
    engines/mohawk/riven_graphics.h


diff --git a/engines/mohawk/riven_card.cpp b/engines/mohawk/riven_card.cpp
index ed3f739..f387bc4 100644
--- a/engines/mohawk/riven_card.cpp
+++ b/engines/mohawk/riven_card.cpp
@@ -626,7 +626,7 @@ void RivenHotspot::loadFromStream(Common::ReadStream *stream) {
 	_u0 = stream->readUint16BE();
 	_mouseCursor = stream->readUint16BE();
 	_index = stream->readUint16BE();
-	_u1 = stream->readSint16BE();
+	_transitionOffset = stream->readSint16BE();
 	_flags |= stream->readUint16BE();
 
 	// Read in the scripts now
@@ -693,6 +693,10 @@ int16 RivenHotspot::getNameId() const {
 	return _nameResource;
 }
 
+int16 RivenHotspot::getTransitionOffset() const {
+	return _transitionOffset;
+}
+
 void RivenHotspot::dump() const {
 	debug("index: %d", _index);
 	debug("blstId: %d", _blstID);
@@ -700,8 +704,8 @@ void RivenHotspot::dump() const {
 	debug("rect: (%d, %d, %d, %d)", _rect.left, _rect.top, _rect.right, _rect.bottom);
 	debug("flags: %d", _flags);
 	debug("mouseCursor: %d", _mouseCursor);
+	debug("transitionOffset: %d", _transitionOffset);
 	debug("u0: %d", _u0);
-	debug("u1: %d", _u1);
 	debugN("\n");
 
 	for (uint i = 0; i < _scripts.size(); i++) {
diff --git a/engines/mohawk/riven_card.h b/engines/mohawk/riven_card.h
index 0d752ed..24f2c13 100644
--- a/engines/mohawk/riven_card.h
+++ b/engines/mohawk/riven_card.h
@@ -244,6 +244,13 @@ public:
 	/** Get the hotspot's enable list id */
 	uint16 getBlstId() const;
 
+	/**
+	 * Get the offset used to control overlap during transitions
+	 *
+	 * -1 means no overlap.
+	 */
+	int16 getTransitionOffset() const;
+
 	/** Write all of the hotspot's data to standard output */
 	void dump() const;
 
@@ -263,7 +270,7 @@ private:
 	uint16 _u0;
 	uint16 _mouseCursor;
 	uint16 _index;
-	int16 _u1;
+	int16 _transitionOffset;
 	uint16 _flags;
 	RivenScriptList _scripts;
 };
diff --git a/engines/mohawk/riven_graphics.cpp b/engines/mohawk/riven_graphics.cpp
index 4dfbcab..6324af5 100644
--- a/engines/mohawk/riven_graphics.cpp
+++ b/engines/mohawk/riven_graphics.cpp
@@ -51,7 +51,7 @@ public:
 
 	bool isTimeBased() const { return _timeBased; }
 
-	virtual void drawFrame(uint32 elapsed) = 0;
+	virtual bool drawFrame(uint32 elapsed) = 0;
 
 protected:
 	Common::Rect makeDirectionalInitalArea() const {
@@ -101,7 +101,7 @@ public:
 		_lastCopyArea = makeDirectionalInitalArea();
 	}
 
-	virtual void drawFrame(uint32 elapsed) override {
+	virtual bool drawFrame(uint32 elapsed) override {
 		Common::Rect copyArea;
 		switch (_type) {
 			case kRivenTransitionWipeLeft:
@@ -136,12 +136,14 @@ public:
 
 		if (copyArea.isEmpty()) {
 			// Nothing to draw
-			return;
+			return false;
 		}
 
 		_effectScreen->copyRectToSurface(*_mainScreen, copyArea.left, copyArea.top, copyArea);
 		_system->copyRectToScreen(_effectScreen->getBasePtr(copyArea.left, copyArea.top), _effectScreen->pitch,
 		                          copyArea.left, copyArea.top, copyArea.width(), copyArea.height());
+
+		return false;
 	}
 
 private:
@@ -151,14 +153,16 @@ private:
 class TransitionEffectPan : public TransitionEffect {
 public:
 	TransitionEffectPan(OSystem *system, Graphics::Surface *mainScreen, Graphics::Surface *effectScreen,
-	                    RivenTransition type, uint duration, const Common::Rect &rect) :
+	                    RivenTransition type, uint duration, const Common::Rect &rect, int16 offset) :
 			TransitionEffect(system, mainScreen, effectScreen, type, duration, rect) {
 
 		_timeBased = true;
+		_offset = offset;
 		_initialArea = makeDirectionalInitalArea();
+		 complete = false;
 	}
 
-	virtual void drawFrame(uint32 elapsed) override {
+	virtual bool drawFrame(uint32 elapsed) override {
 		Common::Rect newArea;
 		switch (_type) {
 			case kRivenTransitionPanLeft:
@@ -191,7 +195,7 @@ public:
 
 		if (newArea.isEmpty()) {
 			// Nothing to draw
-			return;
+			return false;
 		}
 
 		Common::Rect oldArea = Common::Rect(
@@ -203,21 +207,45 @@ public:
 
 		int oldX = newArea.left != _rect.left ? _rect.left + newArea.width() : _rect.left;
 		int oldY = newArea.top != _rect.top ? _rect.top + newArea.height() : _rect.top;
-		_system->copyRectToScreen(_effectScreen->getBasePtr(oldX, oldY), _effectScreen->pitch,
-		                          oldArea.left, oldArea.top, oldArea.width(), oldArea.height());
 
 		int newX = newArea.right != _rect.right ? _rect.left + oldArea.width() : _rect.left;
 		int newY = newArea.bottom != _rect.bottom ? _rect.top + oldArea.height() : _rect.top;
+
+		if (_offset != -1) {
+			if (_type == kRivenTransitionPanDown && oldArea.height() - _offset > 0) {
+				newY -= _offset;
+			} else if (_type == kRivenTransitionPanUp && newArea.height() + _offset < _rect.height()) {
+				newY += _offset;
+			} else if (_type == kRivenTransitionPanRight && oldArea.width() - _offset > 0) {
+				newX -= _offset;
+			} else if (_type == kRivenTransitionPanLeft && newArea.width() + _offset < _rect.width()) {
+				newX += _offset;
+			} else {
+				newX = 0;
+				newY = 0;
+				newArea = _rect;
+				oldArea = Common::Rect();
+			}
+		}
+
+		_system->copyRectToScreen(_effectScreen->getBasePtr(oldX, oldY), _effectScreen->pitch,
+		                          oldArea.left, oldArea.top, oldArea.width(), oldArea.height());
+
 		_system->copyRectToScreen(_mainScreen->getBasePtr(newX, newY), _mainScreen->pitch,
 		                          newArea.left, newArea.top, newArea.width(), newArea.height());
 
 		if (newArea == _rect) {
 			_effectScreen->copyRectToSurface(*_mainScreen, _rect.left, _rect.top, _rect);
+			return true; // The transition is complete
+		} else {
+			return false;
 		}
 	}
 
 private:
 	Common::Rect _initialArea;
+	int16 _offset;
+	bool complete;
 };
 
 class TransitionEffectBlend : public TransitionEffect {
@@ -229,13 +257,14 @@ public:
 		_timeBased = false;
 	}
 
-	virtual void drawFrame(uint32 elapsed) override {
+	virtual bool drawFrame(uint32 elapsed) override {
 		assert(_effectScreen->format == _mainScreen->format);
 		assert(_effectScreen->format == _system->getScreenFormat());
 
 		if (elapsed == _duration) {
 			_effectScreen->copyRectToSurface(*_mainScreen, 0, 0, Common::Rect(_mainScreen->w, _mainScreen->h));
 			_system->copyRectToScreen(_effectScreen->getBasePtr(0, 0), _effectScreen->pitch, 0, 0, _effectScreen->w, _effectScreen->h);
+			return true; // The transition is complete
 		} else {
 			Graphics::Surface *screen = _system->lockScreen();
 
@@ -262,6 +291,7 @@ public:
 			}
 
 			_system->unlockScreen();
+			return false;
 		}
 	}
 };
@@ -291,6 +321,7 @@ RivenGraphics::RivenGraphics(MohawkEngine_Riven* vm) : GraphicsManager(), _vm(vm
 	_creditsPos = 0;
 
 	_transitionMode = kRivenTransitionModeFastest;
+	_transitionOffset = -1;
 	_fliesEffect = nullptr;
 }
 
@@ -463,6 +494,13 @@ void RivenGraphics::setTransitionMode(RivenTransitionMode mode) {
 void RivenGraphics::scheduleTransition(RivenTransition id, const Common::Rect &rect) {
 	_scheduledTransition = id;
 	_transitionRect = rect;
+
+	RivenHotspot *hotspot = _vm->getCard()->getCurHotspot();
+	if (hotspot) {
+		_transitionOffset = hotspot->getTransitionOffset();
+	} else {
+		_transitionOffset = -1;
+	}
 }
 
 void RivenGraphics::runScheduledTransition() {
@@ -488,7 +526,7 @@ void RivenGraphics::runScheduledTransition() {
 		case kRivenTransitionPanUp:
 		case kRivenTransitionPanDown: {
 			effect = new TransitionEffectPan(_vm->_system, _mainScreen, _effectScreen,
-			                                 _scheduledTransition, _transitionDuration, _transitionRect);
+			                                 _scheduledTransition, _transitionDuration, _transitionRect, _transitionOffset);
 			break;
 		}
 		case kRivenTransitionBlend:
@@ -503,14 +541,17 @@ void RivenGraphics::runScheduledTransition() {
 	if (effect->isTimeBased()) {
 		uint32 startTime = _vm->_system->getMillis();
 		uint32 timeElapsed = 0;
-		while (timeElapsed < _transitionDuration && !_vm->shouldQuit()) {
-			effect->drawFrame(timeElapsed);
+		bool transitionComplete = false;
+		while (timeElapsed < _transitionDuration && !transitionComplete && !_vm->shouldQuit()) {
+			transitionComplete = effect->drawFrame(timeElapsed);
 
 			_vm->doFrame();
 			timeElapsed = _vm->_system->getMillis() - startTime;
 		}
 
-		effect->drawFrame(_transitionDuration);
+		if (!transitionComplete) {
+			effect->drawFrame(_transitionDuration);
+		}
 	} else {
 		for (uint frame = 1; frame <= _transitionFrames && !_vm->shouldQuit(); frame++) {
 			effect->drawFrame(frame);
@@ -521,6 +562,7 @@ void RivenGraphics::runScheduledTransition() {
 	delete effect;
 
 	_scheduledTransition = kRivenTransitionNone; // Clear scheduled transition
+	_transitionOffset = -1;
 }
 
 void RivenGraphics::clearMainScreen() {
diff --git a/engines/mohawk/riven_graphics.h b/engines/mohawk/riven_graphics.h
index bdc1a2a..62c48d1 100644
--- a/engines/mohawk/riven_graphics.h
+++ b/engines/mohawk/riven_graphics.h
@@ -131,6 +131,7 @@ private:
 	RivenTransitionMode _transitionMode;
 	uint _transitionFrames;
 	uint _transitionDuration;
+	int16 _transitionOffset;
 
 	// Screen Related
 	Graphics::Surface *_mainScreen;





More information about the Scummvm-git-logs mailing list