[Scummvm-cvs-logs] SF.net SVN: scummvm: [24709] scummvm/trunk/engines/scumm

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Mon Nov 13 20:46:52 CET 2006


Revision: 24709
          http://svn.sourceforge.net/scummvm/?rev=24709&view=rev
Author:   fingolfin
Date:     2006-11-13 11:46:52 -0800 (Mon, 13 Nov 2006)

Log Message:
-----------
Patch from bug #1584888 (SMUSH: Too dependent on accurate timers). Watch out for regressions in SMUSH movie playback / syncing

Modified Paths:
--------------
    scummvm/trunk/engines/scumm/intern.h
    scummvm/trunk/engines/scumm/scumm.cpp
    scummvm/trunk/engines/scumm/smush/smush_mixer.cpp
    scummvm/trunk/engines/scumm/smush/smush_player.cpp
    scummvm/trunk/engines/scumm/smush/smush_player.h

Modified: scummvm/trunk/engines/scumm/intern.h
===================================================================
--- scummvm/trunk/engines/scumm/intern.h	2006-11-13 16:42:34 UTC (rev 24708)
+++ scummvm/trunk/engines/scumm/intern.h	2006-11-13 19:46:52 UTC (rev 24709)
@@ -593,9 +593,6 @@
 	 */
 	bool _smushVideoShouldFinish;
 
-	/** This flag is a hack to allow the pause dialog to pause SMUSH playback, too. */
-	bool _smushPaused;
-
 	bool _smushActive;
 
 	Insane *_insane;

Modified: scummvm/trunk/engines/scumm/scumm.cpp
===================================================================
--- scummvm/trunk/engines/scumm/scumm.cpp	2006-11-13 16:42:34 UTC (rev 24708)
+++ scummvm/trunk/engines/scumm/scumm.cpp	2006-11-13 19:46:52 UTC (rev 24709)
@@ -822,7 +822,6 @@
 
 	_smushFrameRate = 0;
 	_smushVideoShouldFinish = false;
-	_smushPaused = false;
 	_smushActive = false;
 	_insaneRunning = false;
 	_smixer = NULL;
@@ -2157,13 +2156,9 @@
 
 #ifndef DISABLE_SCUMM_7_8
 int ScummEngine_v7::runDialog(Dialog &dialog) {
-	bool oldSmushPaused = _smushPaused;
-	_smushPaused = true;
-
+	_splayer->pause();
 	int result = ScummEngine::runDialog(dialog);
-
-	_smushPaused = oldSmushPaused;
-
+	_splayer->unpause();
 	return result;
 }
 #endif

Modified: scummvm/trunk/engines/scumm/smush/smush_mixer.cpp
===================================================================
--- scummvm/trunk/engines/scumm/smush/smush_mixer.cpp	2006-11-13 16:42:34 UTC (rev 24708)
+++ scummvm/trunk/engines/scumm/smush/smush_mixer.cpp	2006-11-13 19:46:52 UTC (rev 24709)
@@ -45,14 +45,12 @@
 }
 
 SmushMixer::~SmushMixer() {
-	Common::StackLock lock(_mutex);
 	for (int32 i = 0; i < NUM_CHANNELS; i++) {
 		_mixer->stopHandle(_channels[i].handle);
 	}
 }
 
 SmushChannel *SmushMixer::findChannel(int32 track) {
-	Common::StackLock lock(_mutex);
 	debugC(DEBUG_SMUSH, "SmushMixer::findChannel(%d)", track);
 	for (int32 i = 0; i < NUM_CHANNELS; i++) {
 		if (_channels[i].id == track)
@@ -62,7 +60,6 @@
 }
 
 void SmushMixer::addChannel(SmushChannel *c) {
-	Common::StackLock lock(_mutex);
 	int32 track = c->getTrackIdentifier();
 	int i;
 
@@ -91,7 +88,6 @@
 }
 
 bool SmushMixer::handleFrame() {
-	Common::StackLock lock(_mutex);
 	debugC(DEBUG_SMUSH, "SmushMixer::handleFrame()");
 	for (int i = 0; i < NUM_CHANNELS; i++) {
 		if (_channels[i].id != -1) {
@@ -136,7 +132,6 @@
 }
 
 bool SmushMixer::stop() {
-	Common::StackLock lock(_mutex);
 	debugC(DEBUG_SMUSH, "SmushMixer::stop()");
 	for (int i = 0; i < NUM_CHANNELS; i++) {
 		if (_channels[i].id != -1) {
@@ -154,7 +149,6 @@
 }
 
 bool SmushMixer::flush() {
-	Common::StackLock lock(_mutex);
 	debugC(DEBUG_SMUSH, "SmushMixer::flush()");
 	for (int i = 0; i < NUM_CHANNELS; i++) {
 		if (_channels[i].id != -1) {

Modified: scummvm/trunk/engines/scumm/smush/smush_player.cpp
===================================================================
--- scummvm/trunk/engines/scumm/smush/smush_player.cpp	2006-11-13 16:42:34 UTC (rev 24708)
+++ scummvm/trunk/engines/scumm/smush/smush_player.cpp	2006-11-13 19:46:52 UTC (rev 24709)
@@ -27,7 +27,6 @@
 #include "common/config-manager.h"
 #include "common/file.h"
 #include "common/system.h"
-#include "common/timer.h"
 #include "common/util.h"
 
 #include "graphics/cursorman.h"
@@ -220,18 +219,17 @@
 	return sr;
 }
 
-void SmushPlayer::timerCallback(void *refCon) {
-	SmushPlayer *sp = (SmushPlayer *)refCon;
-	sp->parseNextFrame();
+void SmushPlayer::timerCallback() {
+	parseNextFrame();
 #ifdef _WIN32_WCE
-	sp->_inTimer = true;
-	sp->_inTimerCount++;
+	_inTimer = true;
+	_inTimerCount++;
 #endif
 #ifdef __SYMBIAN32__
-	if (sp->_closeOnTextTick) {
-		delete sp->_base;
-		sp->_base = NULL;
-		sp->_closeOnTextTick = false;
+	if (_closeOnTextTick) {
+		delete _base;
+		_base = NULL;
+		_closeOnTextTick = false;
 	}
 #endif
 }
@@ -267,6 +265,9 @@
 	_skipPalette = false;
 	_IACTstream = NULL;
 	_smixer = _vm->_smixer;
+	_paused = false;
+	_pauseStartTime = 0;
+	_pauseTime = 0;
 #ifdef _WIN32_WCE
 	_inTimer = false;
 	_inTimerCount = 0;
@@ -307,8 +308,6 @@
 	_vm->_mixer->stopHandle(_IACTchannel);
 	_vm->_smixer->stop();
 
-	_vm->_timer->installTimerProc(&timerCallback, 1000000 / _speed, this);
-
 	_initDone = true;
 }
 
@@ -322,7 +321,6 @@
 		User::After(15624); 
 	}
 #endif
-	_vm->_timer->removeTimerProc(&timerCallback);
 
 	_vm->_smushVideoShouldFinish = true;
 
@@ -1071,13 +1069,8 @@
 }
 
 void SmushPlayer::parseNextFrame() {
-	Common::StackLock lock(_mutex);
-
 	Chunk *sub;
 
-	if (_vm->_smushPaused)
-		return;
-
 	if (_seekPos >= 0) {
 		if (_smixer)
 			_smixer->stop();
@@ -1230,8 +1223,6 @@
 }
 
 void SmushPlayer::seekSan(const char *file, int32 pos, int32 contFrame) {
-	Common::StackLock lock(_mutex);
-
 	_seekFile = file ? file : "";
 	_seekPos = pos;
 	_seekFrame = contFrame;
@@ -1274,8 +1265,22 @@
 #endif
 }
 
+void SmushPlayer::pause() {
+	if (!_paused) {
+		_paused = true;
+		_pauseStartTime = _vm->_system->getMillis();
+	}
+}
+
+void SmushPlayer::unpause() {
+	if (_paused) {
+		_paused = false;
+		_pauseTime += (_vm->_system->getMillis() - _pauseStartTime);
+		_pauseStartTime = 0;
+	}
+}
+
 void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 startFrame) {
-
 	// Verify the specified file exists
 	ScummFile f;
 	_vm->openFile(f, filename);
@@ -1302,7 +1307,39 @@
 	setupAnim(filename);
 	init(speed);
 
+	uint32 startTime = _vm->_system->getMillis();
+
+	_pauseTime = 0;
+	uint frameNo = 0;
+
+	int skipped = 0;
+
 	for (;;) {
+		uint32 elapsed;
+		bool skipFrame = false;
+
+		if (_vm->_mixer->isSoundHandleActive(_compressedFileSoundHandle)) {
+			// Compressed SMUSH files.
+			elapsed = _vm->_mixer->getSoundElapsedTime(_compressedFileSoundHandle);
+		} else if (_vm->_mixer->isSoundHandleActive(_IACTchannel)) {
+			// Curse of Monkey Island SMUSH files.
+			elapsed = _vm->_mixer->getSoundElapsedTime(_IACTchannel);
+		} else {
+			// For other SMUSH files, we don't necessarily have any
+			// one channel to sync against, so we have to use
+			// elapsed real time.
+			uint32 now = _vm->_system->getMillis() - _pauseTime;
+			elapsed = now - startTime;
+		}
+
+		if (elapsed >= (frameNo * 1000) / _speed) {
+			if (elapsed >= ((frameNo + 1) * 1000) / _speed)
+				skipFrame = true;
+			else
+				skipFrame = false;
+			timerCallback();
+		}
+
 		if (_warpNeeded) {
 			_vm->_system->warpMouse(_warpX, _warpY);
 			_warpNeeded = false;
@@ -1326,25 +1363,36 @@
 
 			_palDirtyMax = -1;
 			_palDirtyMin = 256;
+			skipFrame = false;
 		}
+		if (skipFrame) {
+			if (++skipped > 10) {
+				skipFrame = false;
+				skipped = 0;
+			}
+		} else
+			skipped = 0;
 		if (_updateNeeded) {
-			int w = _width, h = _height;
+			if (!skipFrame) {
+				int w = _width, h = _height;
 
-			// Workaround for bug #1386333: "FT DEMO: assertion triggered 
-			// when playing movie". Some frames there are 384 x 224
-			if (w > _vm->_screenWidth)
-				w = _vm->_screenWidth;
+				// Workaround for bug #1386333: "FT DEMO: assertion triggered 
+				// when playing movie". Some frames there are 384 x 224
+				if (w > _vm->_screenWidth)
+					w = _vm->_screenWidth;
 
-			if (h > _vm->_screenHeight)
-				h = _vm->_screenHeight;
+				if (h > _vm->_screenHeight)
+					h = _vm->_screenHeight;
 
-			_vm->_system->copyRectToScreen(_dst, _width, 0, 0, w, h);
-			_vm->_system->updateScreen();
-			_updateNeeded = false;
+				_vm->_system->copyRectToScreen(_dst, _width, 0, 0, w, h);
+				_vm->_system->updateScreen();
+				_updateNeeded = false;
+			}
 #ifdef _WIN32_WCE
 			_inTimer = false;
 			_inTimerCount = 0;
 #endif
+			frameNo++;
 		}
 		if (_endOfFile)
 			break;

Modified: scummvm/trunk/engines/scumm/smush/smush_player.h
===================================================================
--- scummvm/trunk/engines/scumm/smush/smush_player.h	2006-11-13 16:42:34 UTC (rev 24708)
+++ scummvm/trunk/engines/scumm/smush/smush_player.h	2006-11-13 19:46:52 UTC (rev 24709)
@@ -91,12 +91,14 @@
 #ifdef __SYMBIAN32__
 	bool _closeOnTextTick;
 #endif
-	Common::Mutex _mutex;
 
 public:
 	SmushPlayer(ScummEngine_v7 *scumm);
 	~SmushPlayer();
 
+	void pause();
+	void unpause();
+
 	void play(const char *filename, int32 speed, int32 offset = 0, int32 startFrame = 0);
 	void release();
 	void warpMouse(int x, int y, int buttons);
@@ -106,6 +108,9 @@
 	int _width, _height;
 
 	int _origPitch, _origNumStrips;
+	bool _paused;
+	uint32 _pauseStartTime;
+	uint32 _pauseTime;
 
 	void insanity(bool);
 	void setPalette(const byte *palette);
@@ -139,7 +144,7 @@
 	void handleDeltaPalette(Chunk &);
 	void readPalette(byte *, Chunk &);
 
-	static void timerCallback(void *ptr);
+	void timerCallback();
 };
 
 } // End of namespace Scumm


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list