[Scummvm-cvs-logs] SF.net SVN: scummvm: [22088] scummvm/trunk/engines/simon

kirben at users.sourceforge.net kirben at users.sourceforge.net
Sat Apr 22 19:13:00 CEST 2006


Revision: 22088
Author:   kirben
Date:     2006-04-22 19:11:49 -0700 (Sat, 22 Apr 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=22088&view=rev

Log Message:
-----------
Fix audio and video sync. in videos of FF

Modified Paths:
--------------
    scummvm/trunk/engines/simon/animation.cpp
    scummvm/trunk/engines/simon/animation.h
Modified: scummvm/trunk/engines/simon/animation.cpp
===================================================================
--- scummvm/trunk/engines/simon/animation.cpp	2006-04-23 00:08:18 UTC (rev 22087)
+++ scummvm/trunk/engines/simon/animation.cpp	2006-04-23 02:11:49 UTC (rev 22088)
@@ -71,7 +71,7 @@
 	}
 	_width = _fd.readUint16BE();
 	_height = _fd.readUint16BE();
-	debug(5, "frames_count %d width %d height %d ticks %d", _framesCount, _width, _height, _frameTicks);
+	debug(0, "frames_count %d width %d height %d ticks %d", _framesCount, _width, _height, _frameTicks);
 	_frameSize = _width * _height;
 	_frameBuffer1 = (uint8 *)malloc(_frameSize);
 	_frameBuffer2 = (uint8 *)malloc(_frameSize);
@@ -85,20 +85,20 @@
 void MoviePlayer::play() {
 	uint32 tag;
 
-	// Load OmniTV video
-	if (_vm->getBitFlag(40)) {
-		_vm->_variableArray[254] = 6747;
-		return;
-	}
-
 	if (_fd.isOpen() == false) {
-		debug(0, "MoviePlayer::play: No file loaded");
-		return;
+		// Load OmniTV video
+		if (_vm->getBitFlag(40)) {
+			_vm->_variableArray[254] = 6747;
+			return;
+		} else {
+			debug(0, "MoviePlayer::play: No file loaded");
+			return;
+		}
 	}
 
 	_mixer->stopAll();
 
-	_currentFrame = 0;
+	_frameNum = 0;
 
 	_leftButtonDown = false;
 	_rightButtonDown = false;
@@ -110,18 +110,48 @@
 	byte *buffer = (byte *)malloc(size);
 	_fd.read(buffer, size);
 
-	// TODO: Audio and video sync.
+	_ticks = g_system->getMillis();
+
 	Common::MemoryReadStream stream(buffer, size);
-	AudioStream *sndStream = makeWAVStream(stream);
-	_mixer->playInputStream(Audio::Mixer::kSFXSoundType, NULL, sndStream);
+	_bgSoundStream = makeWAVStream(stream);
+	_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_bgSound, _bgSoundStream);
 
 	// Resolution is smaller in Amiga verison so always clear screen
-	if (_width != 640 && _height != 480)
+	if (_width == 384 && _height == 280)
 		g_system->clearScreen();
 
-	while (_currentFrame < _framesCount) {
-		handleNextFrame();
-		++_currentFrame;
+	while (_frameNum < _framesCount) {
+		decodeFrame();
+		processFrame();
+		g_system->updateScreen();
+		_frameNum++;
+
+		OSystem::Event event;
+		while (g_system->pollEvent(event)) {
+			switch (event.type) {
+			case OSystem::EVENT_LBUTTONDOWN:
+				_leftButtonDown = true;
+				break;
+			case OSystem::EVENT_RBUTTONDOWN:
+				_rightButtonDown = true;
+				break;
+			case OSystem::EVENT_LBUTTONUP:
+				_leftButtonDown = false;
+				break;
+			case OSystem::EVENT_RBUTTONUP:
+				_rightButtonDown = false;
+				break;
+			case OSystem::EVENT_QUIT:
+				g_system->quit();
+				break;
+			default:
+				break;
+			}
+		}
+
+		if (_leftButtonDown && _rightButtonDown && !_vm->getBitFlag(40)) {
+			_frameNum = _framesCount;
+		}
 	}
 
 	close();
@@ -141,7 +171,29 @@
 	free(_frameBuffer2);
 }
 
-void MoviePlayer::handleNextFrame() {
+void MoviePlayer::decodeZlib(uint8 *data, int size, int totalSize) {
+#ifdef USE_ZLIB
+	uint8 *temp = (uint8 *)malloc(size);
+	if (temp) {
+		memcpy(temp, data, size);
+    	z_stream d_stream;
+    	d_stream.zalloc = (alloc_func)0;
+    	d_stream.zfree = (free_func)0;
+    	d_stream.opaque = (voidpf)0;
+    	d_stream.next_in = temp;
+    	d_stream.avail_in = size;
+    	d_stream.total_in = size;
+    	d_stream.next_out = data;
+    	d_stream.avail_out = totalSize;
+    	inflateInit(&d_stream);
+        inflate(&d_stream, Z_FINISH);
+    	inflateEnd(&d_stream);
+		free(temp);
+	}
+#endif
+}
+
+void MoviePlayer::decodeFrame() {
 	uint32 tag = _fd.readUint32BE();
 	if (tag == MKID_BE('CMAP')) {
 		uint8 rgb[768];
@@ -162,23 +214,17 @@
 	if (tag == MKID_BE('FRAM')) {
 		uint8 type = _fd.readByte();
 		uint32 size = _fd.readUint32BE();
-		debug(5, "frame %d type %d size %d", _currentFrame, type, size);
+		debug(0, "frame %d type %d size %d", _frameNum, type, size);
 		_fd.read(_frameBuffer2, size);
 		switch (type) {
 		case 2:
 		case 3:
 			decodeZlib(_frameBuffer2, size, _frameSize);
 			break;
-		case 4:
-		case 5:
-			decode0(_frameBuffer2, size);
-			break;
-		case 6:
-		case 7:
-			decode2(_frameBuffer2, size, _frameSize);
-			break;
+		default:
+			error("decodeFrame: Unknown compression type %d", type);
 		}
-		if (type == 2 || type == 4 || type == 6) {
+		if (type == 2) {
 			memcpy(_frameBuffer1, _frameBuffer2, _frameSize);
 		} else {
 			for (int j = 0; j < _height; ++j) {
@@ -189,91 +235,39 @@
 			}
 		}
 	}
+}
 
+void MoviePlayer::processFrame() {
 	if (_width == 640 && _height == 480)
 		g_system->copyRectToScreen(_frameBuffer1, _width, 0, 0, _width, _height);
 	else
 		g_system->copyRectToScreen(_frameBuffer1, _width, 128, 100, _width, _height);
-	g_system->updateScreen();
-	delay(_frameTicks);
-}
 
-void MoviePlayer::decodeZlib(uint8 *data, int size, int totalSize) {
-#ifdef USE_ZLIB
-	uint8 *temp = (uint8 *)malloc(size);
-	if (temp) {
-		memcpy(temp, data, size);
-    	z_stream d_stream;
-    	d_stream.zalloc = (alloc_func)0;
-    	d_stream.zfree = (free_func)0;
-    	d_stream.opaque = (voidpf)0;
-    	d_stream.next_in = temp;
-    	d_stream.avail_in = size;
-    	d_stream.total_in = size;
-    	d_stream.next_out = data;
-    	d_stream.avail_out = totalSize;
-    	inflateInit(&d_stream);
-        inflate(&d_stream, Z_FINISH);
-    	inflateEnd(&d_stream);
-		free(temp);
-	}
-#endif
-}
+	// TODO Remove set frame rate, were video files use different rate.
+	if ((_bgSoundStream == NULL) || ((_mixer->getSoundElapsedTime(_bgSound) * 10) / 1000 < _frameNum + 1) ||
+		_frameSkipped > 10) {
+		if (_frameSkipped > 10) {
+			warning("force frame %i redraw", _frameNum);
+			_frameSkipped = 0;
+		}
 
-void MoviePlayer::decode0(uint8 *data, int size) {
-	error("decode0");
-}
-
-void MoviePlayer::decode2(uint8 *data, int size, int totalSize) {
-	error("decode2");
-}
-
-void MoviePlayer::delay(uint amount) {
-	OSystem::Event event;
-
-	uint32 start = g_system->getMillis();
-	uint32 cur = start;
-	uint this_delay;
-
-	do {
-		while (g_system->pollEvent(event)) {
-			switch (event.type) {
-			case OSystem::EVENT_LBUTTONDOWN:
-				_leftButtonDown = true;
-				break;
-			case OSystem::EVENT_RBUTTONDOWN:
-				_rightButtonDown = true;
-				break;
-			case OSystem::EVENT_LBUTTONUP:
-				_leftButtonDown = false;
-				break;
-			case OSystem::EVENT_RBUTTONUP:
-				_rightButtonDown = false;
-				break;
-			case OSystem::EVENT_QUIT:
-				g_system->quit();
-				break;
-			default:
-				break;
+		if (_bgSoundStream && _mixer->isSoundHandleActive(_bgSound)) {
+			while (_mixer->isSoundHandleActive(_bgSound) && (_mixer->getSoundElapsedTime(_bgSound) * 10) / 1000 < _frameNum) {
+				g_system->delayMillis(10);
 			}
+			// In case the background sound ends prematurely, update
+			// _ticks so that we can still fall back on the no-sound
+			// sync case for the subsequent frames.
+			_ticks = g_system->getMillis();
+		} else {
+			_ticks += _frameTicks;
+			while (g_system->getMillis() < _ticks)
+				g_system->delayMillis(10);
 		}
-
-		if (_leftButtonDown && _rightButtonDown && !_vm->getBitFlag(40)) {
-			_currentFrame = _framesCount;
-			amount = 0;
-		}
-
-		if (amount == 0)
-			break;
-
-		{
-			this_delay = 20 * 1;
-			if (this_delay > amount)
-				this_delay = amount;
-			g_system->delayMillis(this_delay);
-		}
-		cur = g_system->getMillis();
-	} while (cur < start + amount);
+	} else {
+		warning("dropped frame %i", _frameNum);
+		_frameSkipped++;
+	}
 }
 
 } // End of namespace Simon

Modified: scummvm/trunk/engines/simon/animation.h
===================================================================
--- scummvm/trunk/engines/simon/animation.h	2006-04-23 00:08:18 UTC (rev 22087)
+++ scummvm/trunk/engines/simon/animation.h	2006-04-23 02:11:49 UTC (rev 22088)
@@ -37,6 +37,9 @@
 
 	Audio::Mixer *_mixer;
 
+	Audio::SoundHandle _bgSound;
+	AudioStream *_bgSoundStream;
+
 	bool _playing;
 	bool _leftButtonDown;
 	bool _rightButtonDown;
@@ -47,8 +50,10 @@
 	uint16 _height;
 	uint32 _frameSize;
 	uint16 _framesCount;
-	uint16 _currentFrame;
+	uint16 _frameNum;
 	uint32 _frameTicks;
+	uint _frameSkipped;
+	uint32 _ticks;
 	
 public:
 	MoviePlayer(SimonEngine *vm, Audio::Mixer *mixer);
@@ -59,11 +64,9 @@
 private:
 	void close();
 
-	void delay(uint amount);
-	void handleNextFrame();
+	void decodeFrame();
+	void processFrame();
 	void decodeZlib(uint8 *data, int size, int totalSize);
-	void decode0(uint8 *data, int size);
-	void decode2(uint8 *data, int size, int totalSize);
 };
 
 } // End of namespace Simon


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