[Scummvm-cvs-logs] SF.net SVN: scummvm: [28363] scummvm/trunk/engines/gob

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Tue Jul 31 20:16:34 CEST 2007


Revision: 28363
          http://scummvm.svn.sourceforge.net/scummvm/?rev=28363&view=rev
Author:   drmccoy
Date:     2007-07-31 11:16:33 -0700 (Tue, 31 Jul 2007)

Log Message:
-----------
Still partly broken/stubby VMD playing

Modified Paths:
--------------
    scummvm/trunk/engines/gob/coktelvideo.cpp
    scummvm/trunk/engines/gob/coktelvideo.h
    scummvm/trunk/engines/gob/dataio.cpp
    scummvm/trunk/engines/gob/inter_v4.cpp
    scummvm/trunk/engines/gob/videoplayer.cpp

Modified: scummvm/trunk/engines/gob/coktelvideo.cpp
===================================================================
--- scummvm/trunk/engines/gob/coktelvideo.cpp	2007-07-31 18:08:40 UTC (rev 28362)
+++ scummvm/trunk/engines/gob/coktelvideo.cpp	2007-07-31 18:16:33 UTC (rev 28363)
@@ -58,13 +58,16 @@
 	// Rest header
 	_features = _stream->readByte();
 	_framesCount = _stream->readUint16LE();
-	_x = _stream->readUint16LE();
-	_y = _stream->readUint16LE();
-	_width = _stream->readUint16LE();
-	_height = _stream->readUint16LE();
+	_x = _stream->readSint16LE();
+	_y = _stream->readSint16LE();
+	_width = _stream->readSint16LE();
+	_height = _stream->readSint16LE();
 	_flags = _stream->readUint16LE();
 	_firstFramePos = _stream->readUint16LE();
 
+	// IMDs always have video
+	_features |= kFeaturesVideo;
+
 	// Palette
 	_stream->read((byte *) _palette, 768);
 
@@ -77,10 +80,10 @@
 			return false;
 		}
 		if (_stdX != 0) {
-			_stdX = _stream->readUint16LE();
-			_stdY = _stream->readUint16LE();
-			_stdWidth = _stream->readUint16LE();
-			_stdHeight = _stream->readUint16LE();
+			_stdX = _stream->readSint16LE();
+			_stdY = _stream->readSint16LE();
+			_stdWidth = _stream->readSint16LE();
+			_stdHeight = _stream->readSint16LE();
 			_features |= kFeaturesStdCoords;
 		} else
 			_stdX = -1;
@@ -92,7 +95,7 @@
 	if (_version >= 4) {
 		framesPosPos = _stream->readUint32LE();
 		if (framesPosPos != 0) {
-			_framesPos = new int32[_framesCount];
+			_framesPos = new uint32[_framesCount];
 			assert(_framesPos);
 			_features |= kFeaturesFramesPos;
 		}
@@ -105,9 +108,9 @@
 
 	// Sound
 	if (_features & kFeaturesSound) {
-		_soundFreq = _stream->readUint16LE();
+		_soundFreq = _stream->readSint16LE();
 		_soundSliceSize = _stream->readUint16LE();
-		_soundSlicesCount = _stream->readUint16LE();
+		_soundSlicesCount = _stream->readSint16LE();
 
 		if (_soundFreq < 0)
 			_soundFreq = -_soundFreq;
@@ -158,10 +161,10 @@
 		_frameCoords = new Coord[_framesCount];
 		assert(_frameCoords);
 		for (int i = 0; i < _framesCount; i++) {
-			_frameCoords[i].left = _stream->readUint16LE();
-			_frameCoords[i].top = _stream->readUint16LE();
-			_frameCoords[i].right = _stream->readUint16LE();
-			_frameCoords[i].bottom = _stream->readUint16LE();
+			_frameCoords[i].left = _stream->readSint16LE();
+			_frameCoords[i].top = _stream->readSint16LE();
+			_frameCoords[i].right = _stream->readSint16LE();
+			_frameCoords[i].bottom = _stream->readSint16LE();
 		}
 	}
 
@@ -186,9 +189,9 @@
 void Imd::setXY(int16 x, int16 y) {
 	// Adjusting the standard coordinates
 	if (_stdX != -1) {
-		if (x != -1)
+		if (x >= 0)
 			_stdX = _stdX - _x + x;
-		if (y != -1)
+		if (y >= 0)
 			_stdY = _stdY - _y + y;
 	}
 	
@@ -196,11 +199,11 @@
 	if (_frameCoords) {
 		for (int i = 0; i < _framesCount; i++) {
 			if (_frameCoords[i].left != -1) {
-				if (x != -1) {
+				if (x >= 0) {
 					_frameCoords[i].left = _frameCoords[i].left - _x + x;
 					_frameCoords[i].right = _frameCoords[i].right - _x + x;
 				}
-				if (y != -1) {
+				if (y >= 0) {
 					_frameCoords[i].top = _frameCoords[i].top - _y + y;
 					_frameCoords[i].bottom = _frameCoords[i].bottom - _y + y;
 				}
@@ -208,9 +211,9 @@
 		}
 	}
 
-	if (x != -1)
+	if (x >= 0)
 		_x = x;
-	if (y != -1)
+	if (y >= 0)
 		_y = y;
 }
 
@@ -259,7 +262,7 @@
 	_mixer = 0;
 }
 
-void Imd::seekFrame(int16 frame, int16 whence, bool restart) {
+void Imd::seekFrame(int32 frame, int16 whence, bool restart) {
 	if (!_stream)
 		// Nothing to do
 		return;
@@ -272,7 +275,7 @@
 	else if (whence != SEEK_SET)
 		return;
 
-	if ((frame >= _framesCount) || (frame == _curFrame))
+	if ((frame < 0) || (frame >= _framesCount) || (frame == _curFrame))
 		// Nothing to do
 		return;
 
@@ -293,7 +296,7 @@
 		error("Frame %d is not directly accessible", frame);
 
 	// Seek
-	_stream->seek(framePos, SEEK_SET);
+	_stream->seek(framePos);
 	_curFrame = frame;
 }
 
@@ -426,7 +429,7 @@
 	_lastFrameTime = 0;
 }
 
-CoktelVideo::State Imd::processFrame(int16 frame) {
+CoktelVideo::State Imd::processFrame(uint16 frame) {
 	State state;
 	uint32 cmd = 0;
 	int16 xBak, yBak, heightBak, widthBak;
@@ -440,7 +443,7 @@
 
 	if (frame != _curFrame) {
 		state.flags |= kStateSeeked;
-		seekFrame(frame, SEEK_SET);
+		seekFrame(frame);
 	}
 
 	state.left = xBak = _x;
@@ -559,7 +562,7 @@
 		// Jump to frame
 		if (cmd == 0xFFFD) {
 
-			frame = _stream->readUint16LE();
+			frame = _stream->readSint16LE();
 			if (_framesPos) {
 				_curFrame = frame;
 				_stream->seek(_framesPos[frame], SEEK_SET);
@@ -612,7 +615,7 @@
 			state.flags |= _frameData[0];
 
 		} else
-			state.flags |= kStateNoData;
+			state.flags |= kStateNoVideoData;
 
 	} while (hasNextCmd);
 
@@ -640,95 +643,6 @@
 	return state;
 }
 
-CoktelVideo::State Imd::peekFrame(int16 frame) {
-	State state;
-	uint32 posBak;
-	uint32 tmp;
-	uint16 cmd;
-	int16 frameBak;
-
-	if (!_stream) {
-		state.flags = kStateBreak;
-		return state;
-	}
-
-	posBak = _stream->pos();
-	frameBak = _curFrame;
-
-	if (_curFrame != frame) {
-		state.flags |= kStateSeeked;
-		seekFrame(frame, SEEK_SET);
-	}
-
-	do {
-		if (frame != 0) {
-			if (_stdX != -1)
-				state.flags |= kStateStdCoords;
-			if (_frameCoords && (_frameCoords[frame].left != -1))
-				state.flags |= kStateFrameCoords;
-		}
-
-		cmd = _stream->readUint16LE();
-
-		if ((cmd & 0xFFF8) == 0xFFF0) {
-			if (cmd == 0xFFF0) {
-				_stream->seek(2, SEEK_CUR);
-				cmd = _stream->readUint16LE();
-			}
-
-			if (cmd == 0xFFF1) {
-				state.flags = kStateBreak;
-				continue;
-			} else if (cmd == 0xFFF2) { // Skip (16 bit)
-				cmd = _stream->readUint16LE();
-				_stream->seek(cmd, SEEK_CUR);
-				state.flags = kStateBreak;
-				continue;
-			} else if (cmd == 0xFFF3) { // Skip (32 bit)
-				tmp = _stream->readUint32LE();
-				_stream->seek(cmd, SEEK_CUR);
-				state.flags = kStateBreak;
-				continue;
-			}
-		}
-
-		// Jump to frame
-		if (cmd == 0xFFFD) {
-			frame = _stream->readUint16LE();
-			if (_framesPos) {
-				_stream->seek(_framesPos[frame], SEEK_SET);
-				state.flags |= kStateJump;
-				continue;
-			}
-			break;
-		}
-
-		// Next sound slice data
-		if (cmd == 0xFF00) {
-			_stream->seek(_soundSliceSize, SEEK_CUR);
-			cmd = _stream->readUint16LE();
-		// Initial sound data (all slices)
-		} else if (cmd == 0xFF01) {
-			_stream->seek(_soundSliceSize * _soundSlicesCount, SEEK_CUR);
-			cmd = _stream->readUint16LE();
-		}
-
-		// Frame video data
-		if (cmd != 0) {
-			_stream->read(_frameData, 5);
-			state.flags |= _frameData[0];
-		} else
-			state.flags |= kStateNoData;
-
-		break;
-
-	} while (true);
-
-	_stream->seek(posBak, SEEK_SET);
-	_curFrame = frameBak;
-	return state;
-}
-
 uint32 Imd::renderFrame() {
 	if (!_frameData || (_width <= 0) || (_height <= 0))
 		return 0;
@@ -763,10 +677,10 @@
 		srcPtr = _vidBuffer;
 		type &= 0x7F;
 		if ((type == 2) && (imdW == sW)) {
-			frameUncompressor(imdVidMem, dataPtr);
+			deLZ77(imdVidMem, dataPtr);
 			return retVal;
 		} else
-			frameUncompressor(srcPtr, dataPtr);
+			deLZ77(srcPtr, dataPtr);
 	}
 
 	uint16 pixCount, pixWritten;
@@ -845,7 +759,7 @@
 	return retVal;
 }
 
-void Imd::frameUncompressor(byte *dest, byte *src) {
+void Imd::deLZ77(byte *dest, byte *src) {
 	int i;
 	byte buf[4370];
 	uint16 chunkLength;
@@ -857,7 +771,7 @@
 	uint8 chunkCount;
 	bool mode;
 
-	frameLength = READ_LE_UINT16(src);
+	frameLength = READ_LE_UINT32(src);
 	src += 4;
 
 	if ((READ_LE_UINT16(src) == 0x1234) && (READ_LE_UINT16(src + 2) == 0x5678)) {
@@ -932,4 +846,345 @@
 	}
 }
 
+Vmd::Vmd() {
+	clear(false);
+}
+
+Vmd::~Vmd() {
+	clear();
+}
+
+bool Vmd::load(Common::SeekableReadStream &stream) {
+	unload();
+
+	_stream = &stream;
+
+	uint16 headerLength = _stream->readUint16LE();
+	uint16 handle = _stream->readUint16LE();
+	_version = _stream->readUint16LE();
+
+	// Version checking
+	if ((headerLength != 814) || (handle != 0) || (_version != 1)) {
+		warning("IMD Version incorrect (%d, %d, %d)", headerLength, handle, _version);
+		unload();
+		return false;
+	}
+
+	_framesCount = _stream->readUint16LE();
+
+	warning("# of frames: %d", _framesCount);
+
+	_x = _stream->readSint16LE();
+	_y = _stream->readSint16LE();
+	_width = _stream->readSint16LE();
+	_height = _stream->readSint16LE();
+	if ((_width != 0) && (_height != 0)) {
+		_hasVideo = true;
+		_features |= kFeaturesVideo;
+
+		warning("%dx%d+%d+%d", _width, _height, _x, _y);
+
+	} else
+		_hasVideo = false;
+
+	_flags = _stream->readUint16LE();
+	_partsPerFrame = _stream->readUint16LE();
+	_firstFramePos = _stream->readUint32LE();
+	uint32 unknown1 = _stream->readUint32LE();
+
+	warning("flags: %d (0x%X), #parts: %d, firstFramePos: %d, U1: %d (0x%X)",
+			_flags, _flags, _partsPerFrame, _firstFramePos, unknown1, unknown1);
+
+	_stream->read((byte *) _palette, 768);
+
+	_frameDataSize = _stream->readUint32LE();
+	_vidBufferSize = _stream->readUint32LE();
+
+	if (_hasVideo) {
+		if (_frameDataSize == 0)
+			_frameDataSize = _width * _height + 500;
+		if (_vidBufferSize)
+			_vidBufferSize = _frameDataSize;
+
+		_frameData = new byte[_frameDataSize];
+		assert(_frameData);
+		memset(_frameData, 0, _frameDataSize);
+		_vidBuffer = new byte[_vidBufferSize];
+		assert(_vidBuffer);
+		memset(_vidBuffer, 0, _vidBufferSize);
+		warning("Sizes: frameData: %d, vidBuffer: %d", _frameDataSize, _vidBufferSize);
+	}
+
+	_soundFreq = _stream->readSint16LE();
+	_soundSliceSize = _stream->readUint16LE();
+	_soundSlicesCount = _stream->readSint16LE();
+	uint16 soundFlags = _stream->readUint16LE();
+	_hasSound = (_soundFreq != 0);
+
+	if (_hasSound) {
+		_features |= kFeaturesSound;
+
+		_soundSliceLength = 1000 / (_soundFreq / _soundSliceSize);
+		_frameLength = _soundSliceLength;
+
+		_soundStage = 1;
+
+		_audioStream = Audio::makeAppendableAudioStream(_soundFreq, 0);
+
+		warning("Sound: Freq: %d, # slices %d, slideSize: %d, flags: %d (0x%X), sliceLen = %d",
+				_soundFreq, _soundSlicesCount, _soundSliceSize, soundFlags, soundFlags, _soundSliceLength);
+
+	} else
+		_frameLength = 1000 / 12; // 12 FPS for a video without sound
+
+	uint32 frameInfoOffset = _stream->readUint32LE();
+
+	warning("frameInfoOffset: %d", frameInfoOffset);
+
+	_stream->seek(frameInfoOffset);
+	_frames = new Frame[_framesCount];
+	for (uint16 i = 0; i < _framesCount; i++) {
+		_frames[i].parts = new Part[_partsPerFrame];
+		_stream->skip(2);
+		_frames[i].offset = _stream->readUint32LE();
+	}
+	for (uint16 i = 0; i < _framesCount; i++) {
+		for (uint16 j = 0; j < _partsPerFrame; j++) {
+			_frames[i].parts[j].type = (PartType) _stream->readByte();
+			uint16 Unknown3 = _stream->readByte();
+			_frames[i].parts[j].size = _stream->readUint32LE();
+			if (_frames[i].parts[j].type == kPartTypeAudio) {
+				_frames[i].parts[j].flags = _stream->readByte();
+				_stream->skip(9);
+				warning("%d.%d (%d): Audio: %d (0x%X), %d (0x%X)",
+						i, j, _frames[i].parts[j].size,
+						Unknown3, Unknown3, _frames[i].parts[j].flags, _frames[i].parts[j].flags);
+
+			} else if (_frames[i].parts[j].type == kPartTypeVideo) {
+				_frames[i].parts[j].left = _stream->readUint16LE();
+				_frames[i].parts[j].top = _stream->readUint16LE();
+				_frames[i].parts[j].right = _stream->readUint16LE();
+				_frames[i].parts[j].bottom = _stream->readUint16LE();
+				uint16 Unknown4 = _stream->readByte();
+				_frames[i].parts[j].flags = _stream->readByte();
+				warning("%d.%d (%d): Video: %d (0x%X), %d+%d+%d+%d, %d (0x%X), %d (0x%X)",
+						i, j, _frames[i].parts[j].size,
+						Unknown3, Unknown3, _frames[i].parts[j].left,
+						_frames[i].parts[j].top, _frames[i].parts[j].right,
+						_frames[i].parts[j].bottom, Unknown4, Unknown4,
+						_frames[i].parts[j].flags, _frames[i].parts[j].flags);
+
+			} else {
+				warning("VMD: Unknown frame part type found (%d.%d: %d, %d)",
+						i, j, _frames[i].parts[j].type, _frames[i].parts[j].size);
+				_stream->skip(10);
+//				unload();
+//				return false;
+			}
+		}
+	}
+
+	return true;
+}
+
+void Vmd::unload() {
+	clear();
+}
+
+void Vmd::setXY(int16 x, int16 y) {
+
+	for (int i = 0; i < _framesCount; i++) {
+		for (int j = 0; j < _partsPerFrame; j++) {
+
+			if (_frames[i].parts[j].type == kPartTypeVideo) {
+				if (x >= 0) {
+					_frames[i].parts[j].left = _frames[i].parts[j].left - _x + x;
+					_frames[i].parts[j].right = _frames[i].parts[j].right - _x + x;
+				}
+				if (y >= 0) {
+					_frames[i].parts[j].top = _frames[i].parts[j].top - _y + y;
+					_frames[i].parts[j].bottom = _frames[i].parts[j].bottom - _y + y;
+				}
+			}
+
+		}
+	}
+
+	if (x >= 0)
+		_x = x;
+	if (y >= 0)
+		_y = y;
+}
+
+void Vmd::seekFrame(int32 frame, int16 whence, bool restart) {
+	if (!_stream)
+		// Nothing to do
+		return;
+
+	// Find the frame to which to seek
+	if (whence == SEEK_CUR)
+		frame += _curFrame;
+	else if (whence == SEEK_END)
+		frame = _framesCount - frame - 1;
+	else if (whence != SEEK_SET)
+		return;
+
+	if ((frame < 0) || (frame >= _framesCount))
+		// Nothing to do
+		return;
+
+	// Seek
+	_stream->seek(_frames[frame].offset);
+	_curFrame = frame;
+}
+
+CoktelVideo::State Vmd::nextFrame() {
+	State state;
+
+	state = processFrame(_curFrame);
+	_curFrame++;
+	return state;
+}
+
+void Vmd::clear(bool del) {
+	Imd::clear(del);
+
+	if (del) {
+		delete[] _frames;
+	}
+
+	_hasVideo = true;
+	_partsPerFrame = 0;
+	_frames = 0;
+}
+
+CoktelVideo::State Vmd::processFrame(uint16 frame) {
+	State state;
+	int16 xBak, yBak, heightBak, widthBak;
+	bool startSound = false;
+
+	seekFrame(frame);
+
+	state.flags |= kStateNoVideoData;
+	state.left = -1;
+
+	for (uint16 i = 0; i < _partsPerFrame; i++) {
+		Part &part = _frames[frame].parts[i];
+
+		if (part.type == kPartTypeAudio) {
+			byte *soundBuf;
+
+			// Next sound slice data
+			if (part.flags == 1) {
+
+				if (_soundEnabled) {
+					soundBuf = new byte[part.size];
+					assert(soundBuf);
+
+					_stream->read(soundBuf, part.size);
+					unsignedToSigned(soundBuf, part.size);
+
+					_audioStream->queueBuffer(soundBuf, part.size);
+				} else
+					_stream->skip(part.size);
+
+			// Initial sound data (all slices)
+			} else if (part.flags == 2) {
+
+				if (_soundEnabled) {
+					uint32 U = _stream->readUint32LE();
+
+					warning("Mask? %d (0x%X)", U, U);
+
+					soundBuf = new byte[part.size - 4];
+					assert(soundBuf);
+
+					_stream->read(soundBuf, part.size - 4);
+					unsignedToSigned(soundBuf, part.size - 4);
+
+					_audioStream->queueBuffer(soundBuf, part.size - 4);
+
+					if (_soundStage == 1) {
+						startSound = true;
+					}
+
+				} else
+					_stream->skip(part.size);
+
+			// Empty sound slice
+			} else if (part.flags == 3) {
+
+				if (_soundEnabled && (part.size > 0)) {
+					soundBuf = new byte[part.size];
+					assert(soundBuf);
+
+					memset(soundBuf, 0, part.size);
+
+					_audioStream->queueBuffer(soundBuf, part.size);
+				} else
+					_stream->skip(part.size);
+			}
+
+		} else if (part.type == kPartTypeVideo) {
+			state.flags &= ~kStateNoVideoData;
+
+			if (state.left == -1) {
+				state.left = _x = part.left;
+				state.top = _y = part.top;
+				state.right = _width = part.right;
+				state.bottom = _height = part.bottom;
+				_width -= _x - 1;
+				_height -= _y - 1;
+			} else {
+				_x = part.left;
+				_y = part.top;
+				_width = part.right - (_x - 1);
+				_height = part.bottom - (_y - 1);
+				state.left = MIN(state.left, part.left);
+				state.top = MIN(state.top, part.top);
+				state.right = MAX(state.right, part.right);
+				state.bottom = MAX(state.bottom, part.bottom);
+			}
+
+			if (part.flags & 2) {
+				uint8 index = _stream->readByte();
+				uint8 count = _stream->readByte();
+
+				_stream->read(_palette + index * 3, count + 1);
+				_stream->skip((255 - count) * 3);
+				
+				state.flags |= kStatePalette;
+			}
+
+			_stream->read(_frameData, part.size);
+			state.flags |= renderFrame();
+		} else {
+			warning("Unknown frame part type %d, size %d (%d of %d)", part.type, part.size, i + 1, _partsPerFrame);
+			_stream->skip(part.size);
+		}
+	}
+
+	if (startSound && _soundEnabled) {
+		_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_audioHandle, _audioStream);
+		_soundStartTime = g_system->getMillis();
+		_skipFrames = 0;
+		_soundStage = 2;
+	}
+
+	_x = xBak;
+	_y = yBak;
+	_width = widthBak;
+	_height = heightBak;
+
+	if ((_curFrame == (_framesCount - 1)) && (_soundStage == 2)) {
+		_audioStream->finish();
+		_mixer->stopHandle(_audioHandle);
+		_audioStream = 0;
+		_soundStage = 0;
+	}
+
+	_lastFrameTime = g_system->getMillis();
+	return state;
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/coktelvideo.h
===================================================================
--- scummvm/trunk/engines/gob/coktelvideo.h	2007-07-31 18:08:40 UTC (rev 28362)
+++ scummvm/trunk/engines/gob/coktelvideo.h	2007-07-31 18:16:33 UTC (rev 28363)
@@ -48,7 +48,9 @@
 		/** Has general standard coordinates. */
 		kFeaturesStdCoords = 0x100,
 		/** Has a frame positions table. */
-		kFeaturesFramesPos = 0x200
+		kFeaturesFramesPos = 0x200,
+		/** Has video. */
+		kFeaturesVideo = 0x400
 	};
 
 	enum StateFlags {
@@ -60,7 +62,7 @@
 		/** Updated according to the specific frame coordinates. */
 		kStateFrameCoords = 0x400,
 		/** Got no frame data. */
-		kStateNoData = 0x800,
+		kStateNoVideoData = 0x800,
 		/** Updated according to the general standard coordinates. */
 		kStateStdCoords = 0x1000,
 		/** Had to explicitely seek to the frame. */
@@ -80,6 +82,8 @@
 		int16 bottom;
 		/** Set accordingly to what was done. */
 		uint32 flags;
+
+		State() : left(0), top(0), right(0), bottom(0), flags(0) { }
 	};
 
 	virtual ~CoktelVideo() { }
@@ -95,9 +99,13 @@
 	/** Returns the height of the video. */
 	virtual int16 getHeight() const = 0;
 	/** Returns the number of frames the loaded video has. */
-	virtual int16 getFramesCount() const = 0;
-	/** Returns the current frame number. */
-	virtual int16 getCurrentFrame() const = 0;
+	virtual uint16 getFramesCount() const = 0;
+	/** Returns the current frame number.
+	 *
+	 *  This is the current frame after the last nextFrame()-call,
+	 *  i.e. it's 0 after loading, 1 after the first nextFrame()-call, etc..
+	 */
+	virtual uint16 getCurrentFrame() const = 0;
 	/** Returns the frame rate. */
 	virtual int16 getFrameRate() const = 0;
 	/** Returns the number of frames the video lags behind the audio. */
@@ -128,12 +136,10 @@
 	 *  @param whence The offset from whence the frame is given.
 	 *  @param restart Restart the video to reach an otherwise inaccessible frame?
 	 */
-	virtual void seekFrame(int16 frame, int16 whence = SEEK_SET, bool restart = false) = 0;
+	virtual void seekFrame(int32 frame, int16 whence = SEEK_SET, bool restart = false) = 0;
 
 	/** Render the next frame. */
 	virtual State nextFrame() = 0;
-	/** Look at what a frame would do/have, without actually rendering the frame. */
-	virtual State peekFrame(int16 frame) = 0;
 	/** Wait for the frame to end. */
 	virtual void waitEndFrame() = 0;
 
@@ -160,8 +166,8 @@
 	int16 getY() const { return _y; }
 	int16 getWidth() const { return _width; }
 	int16 getHeight() const { return _height; }
-	int16 getFramesCount() const { return _framesCount; }
-	int16 getCurrentFrame() const { return _curFrame; }
+	uint16 getFramesCount() const { return _framesCount; }
+	uint16 getCurrentFrame() const { return _curFrame; }
 	int16 getFrameRate() const { if (_hasSound) return 1000 / _soundSliceLength; return 12; }
 	uint32 getSyncLag() const { return _skipFrames; }
 	const byte *getPalette() const { return _palette; }
@@ -176,10 +182,9 @@
 	void enableSound(Audio::Mixer &mixer);
 	void disableSound();
 
-	void seekFrame(int16 frame, int16 whence = SEEK_SET, bool restart = false);
+	void seekFrame(int32 frame, int16 whence = SEEK_SET, bool restart = false);
 
 	State nextFrame();
-	State peekFrame(int16 frame);
 	void waitEndFrame();
 
 	void copyCurrentFrame(byte *dest, uint16 x, uint16 y, uint16 width, int16 transp = -1);
@@ -193,17 +198,17 @@
 	} PACKED_STRUCT;
 
 	Common::SeekableReadStream *_stream;
-	uint8 _version;
+	uint16 _version;
 	uint16 _features;
-	int16 _flags;
+	uint16 _flags;
 	int16 _x, _y, _width, _height;
 	int16 _stdX, _stdY, _stdWidth, _stdHeight;
-	int16 _framesCount, _curFrame;
-	int32 *_framesPos;
-	int32 _firstFramePos;
+	uint16 _framesCount, _curFrame;
+	uint32 *_framesPos;
+	uint32 _firstFramePos;
 	Coord *_frameCoords;
 
-	int32 _frameDataSize, _vidBufferSize;
+	uint32 _frameDataSize, _vidBufferSize;
 	byte *_frameData, *_vidBuffer;
 
 	byte _palette[768];
@@ -238,11 +243,56 @@
 	void deleteVidMem(bool del = true);
 	void clear(bool del = true);
 
-	State processFrame(int16 frame);
+	State processFrame(uint16 frame);
 	uint32 renderFrame();
-	void frameUncompressor(byte *dest, byte *src);
+	void deLZ77(byte *dest, byte *src);
 };
 
+class Vmd : public Imd {
+public:
+	Vmd();
+	~Vmd();
+
+	bool load(Common::SeekableReadStream &stream);
+	void unload();
+
+	void setXY(int16 x, int16 y);
+
+	void seekFrame(int32 frame, int16 whence = SEEK_SET, bool restart = false);
+
+	State nextFrame();
+
+protected:
+	enum PartType {
+		kPartTypeAudio = 1,
+		kPartTypeVideo = 2
+	};
+	struct Part {
+		PartType type;
+		uint32 size;
+		int16 left;
+		int16 top;
+		int16 right;
+		int16 bottom;
+		byte flags;
+	} PACKED_STRUCT;
+	struct Frame {
+		uint32 offset;
+		Part *parts;
+
+		Frame() : parts(0) { }
+		~Frame() { delete[] parts; }
+	} PACKED_STRUCT;
+
+	bool _hasVideo;
+	uint16 _partsPerFrame;
+	Frame *_frames;
+
+	void clear(bool del = true);
+
+	State processFrame(uint16 frame);
+};
+
 } // End of namespace Gob
 
 #endif // GOB_COKTELVIDEO_H

Modified: scummvm/trunk/engines/gob/dataio.cpp
===================================================================
--- scummvm/trunk/engines/gob/dataio.cpp	2007-07-31 18:08:40 UTC (rev 28362)
+++ scummvm/trunk/engines/gob/dataio.cpp	2007-07-31 18:16:33 UTC (rev 28363)
@@ -103,11 +103,20 @@
 	if (_stream)
 		return _stream->read(dataPtr, dataSize);
 
-	int32 res = _io->readChunk(_handle, (byte *) dataPtr, dataSize);
-	if (res >= 0)
-		return res;
+	if ((_handle < 50) || (_handle >= 128))
+		return _io->file_getHandle(_handle)->read((byte *) dataPtr, dataSize);
 
-	return _io->file_getHandle(_handle)->read((byte *) dataPtr, dataSize);
+	byte *data = (byte *) dataPtr;
+	uint32 haveRead = 0;
+	while (dataSize > 0x3FFF) {
+		_io->readChunk(_handle, (byte *) data, 0x3FFF);
+		dataSize -= 0x3FFF;
+		data += 0x3FFF;
+		haveRead += 0x3FFF;
+	}
+	_io->readChunk(_handle, (byte *) data, dataSize);
+
+	return haveRead + dataSize;
 }
 
 DataIO::DataIO(GobEngine *vm) : _vm(vm) {

Modified: scummvm/trunk/engines/gob/inter_v4.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v4.cpp	2007-07-31 18:08:40 UTC (rev 28362)
+++ scummvm/trunk/engines/gob/inter_v4.cpp	2007-07-31 18:16:33 UTC (rev 28363)
@@ -742,12 +742,12 @@
 		close = true;
 	} else if (lastFrame == -3) {
 		warning("Woodruff Stub: Video/Music command -3: Play background video %s", fileName);
-		return;
+//		return;
 	} else if (lastFrame == -4) {
 		warning("Woodruff Stub: Video/Music command -4: Play background video %s", fileName);
 		return;
 	} else if (lastFrame == -5) {
-		warning("Woodruff Stub: Video/Music command -5");
+		warning("Woodruff Stub: Video/Music command -5: Stop background music");
 		return;
 	} else if (lastFrame == -6) {
 		warning("Woodruff Stub: Video/Music command -6: Load background video %s", fileName);

Modified: scummvm/trunk/engines/gob/videoplayer.cpp
===================================================================
--- scummvm/trunk/engines/gob/videoplayer.cpp	2007-07-31 18:08:40 UTC (rev 28362)
+++ scummvm/trunk/engines/gob/videoplayer.cpp	2007-07-31 18:16:33 UTC (rev 28363)
@@ -119,9 +119,7 @@
 		if (which == kVideoTypeIMD) {
 			_video = new Imd();
 		} else if (which == kVideoTypeVMD) {
-			warning("STUB: %s", fileName);
-			closeVideo();
-			return false;
+			_video = new Vmd();
 		} else {
 			warning("Couldn't open video \"%s\": Invalid video Type", fileName);
 			closeVideo();
@@ -161,6 +159,7 @@
 	if (!_video)
 		return;
 
+	breakKey = 27;
 	if (startFrame < 0)
 		startFrame = _video->getCurrentFrame();
 	if (lastFrame < 0)


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