[Scummvm-cvs-logs] SF.net SVN: scummvm:[48233] scummvm/trunk/graphics/video/coktelvideo

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Thu Mar 11 07:14:53 CET 2010


Revision: 48233
          http://scummvm.svn.sourceforge.net/scummvm/?rev=48233&view=rev
Author:   drmccoy
Date:     2010-03-11 06:14:52 +0000 (Thu, 11 Mar 2010)

Log Message:
-----------
Adding support for the very primitive and simply early IMD format used in Fascination

Modified Paths:
--------------
    scummvm/trunk/graphics/video/coktelvideo/coktelvideo.cpp
    scummvm/trunk/graphics/video/coktelvideo/coktelvideo.h

Modified: scummvm/trunk/graphics/video/coktelvideo/coktelvideo.cpp
===================================================================
--- scummvm/trunk/graphics/video/coktelvideo/coktelvideo.cpp	2010-03-10 21:44:58 UTC (rev 48232)
+++ scummvm/trunk/graphics/video/coktelvideo/coktelvideo.cpp	2010-03-11 06:14:52 UTC (rev 48233)
@@ -38,79 +38,407 @@
 
 namespace Graphics {
 
-Imd::Imd() {
-	clear(false);
+PreImd::PreImd() {
+	zeroData();
+
+	_forcedWidth  = 0;
+	_forcedHeight = 0;
 }
 
-Imd::~Imd() {
-	clear();
+PreImd::PreImd(int16 width, int16 height) {
+	zeroData();
+
+	_forcedWidth  = width;
+	_forcedHeight = height;
 }
 
-uint32 Imd::getFeatures() const {
+PreImd::~PreImd() {
+	deleteData();
+	zeroData();
+}
+
+uint32 PreImd::getFeatures() const {
 	return _features;
 }
 
-uint16 Imd::getFlags() const {
+uint16 PreImd::getFlags() const {
 	return _flags;
 }
 
-int16 Imd::getX() const {
+int16 PreImd::getX() const {
 	return _x;
 }
 
-int16 Imd::getY() const {
+int16 PreImd::getY() const {
 	return _y;
 }
 
-int16 Imd::getWidth() const {
+int16 PreImd::getWidth() const {
 	return _width;
 }
 
-int16 Imd::getHeight() const {
+int16 PreImd::getHeight() const {
 	return _height;
 }
 
-uint16 Imd::getFramesCount() const {
+uint16 PreImd::getFramesCount() const {
 	return _framesCount;
 }
 
-uint16 Imd::getCurrentFrame() const {
+uint16 PreImd::getCurrentFrame() const {
 	return _curFrame;
 }
 
-int16 Imd::getFrameRate() const {
-	if (!_hasSound)
-		return _frameRate;
+void PreImd::setFrameRate(int16 frameRate) {
+	if (frameRate == 0)
+		frameRate = 1;
 
-	return 1000 / (_soundSliceLength >> 16);
+	_frameRate   = frameRate;
+	_frameLength = 1000 / _frameRate;
 }
 
-uint32 Imd::getSyncLag() const {
-	return _skipFrames;
+int16 PreImd::getFrameRate() const {
+	return 0;
 }
 
-const byte *Imd::getPalette() const {
+uint32 PreImd::getSyncLag() const {
+	return 0;
+}
+
+const byte *PreImd::getPalette() const {
 	return _palette;
 }
 
-bool Imd::getFrameCoords(int16 frame,
+bool PreImd::getFrameCoords(int16 frame,
 		int16 &x, int16 &y, int16 &width, int16 &height) {
 
 	return false;
 }
 
-bool Imd::hasExtraData() const {
+bool PreImd::hasExtraData() const {
 	return false;
 }
 
-bool Imd::hasExtraData(const char *fileName) const {
+bool PreImd::hasExtraData(const char *fileName) const {
 	return false;
 }
 
-Common::MemoryReadStream *Imd::getExtraData(const char *fileName) {
+Common::MemoryReadStream *PreImd::getExtraData(const char *fileName) {
 	return 0;
 }
 
+bool PreImd::load(Common::SeekableReadStream &stream) {
+	warning("loading preIMD");
+
+	assert((_forcedWidth > 0) && (_forcedHeight > 0));
+
+	unload();
+
+	_stream = &stream;
+
+	_stream->seek(0);
+
+	_framesCount = _stream->readUint16LE();
+
+	_width  = _forcedWidth;
+	_height = _forcedHeight;
+
+	_vidBufferSize = _width * _height;
+	_vidBuffer = new byte[_vidBufferSize];
+	memset(_vidBuffer, 0, _vidBufferSize);
+
+	return true;
+}
+
+void PreImd::unload() {
+	clear();
+}
+
+void PreImd::setXY(int16 x, int16 y) {
+	_x = x;
+	_y = y;
+}
+
+void PreImd::setVideoMemory(byte *vidMem, uint16 width, uint16 height) {
+	deleteVidMem();
+
+	_hasOwnVidMem = false;
+	_vidMem       = vidMem;
+	_vidMemWidth  = width;
+	_vidMemHeight = height;
+}
+
+void PreImd::setVideoMemory() {
+	deleteVidMem();
+
+	if ((_width > 0) && (_height > 0)) {
+		setXY(0, 0);
+		_hasOwnVidMem = true;
+		_vidMem       = new byte[_width * _height];
+		_vidMemWidth  = _width;
+		_vidMemHeight = _height;
+
+		memset(_vidMem, 0, _width * _height);
+	}
+}
+
+void PreImd::setDoubleMode(bool doubleMode) {
+}
+
+void PreImd::enableSound(Audio::Mixer &mixer) {
+}
+
+void PreImd::disableSound() {
+}
+
+bool PreImd::isSoundPlaying() const {
+	return false;
+}
+
+void PreImd::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) || (frame == _curFrame))
+		// Nothing to do
+		return;
+
+	// Run through the frames
+	_curFrame = 0;
+	_stream->seek(2);
+	while (_curFrame != frame) {
+		uint16 frameSize = _stream->readUint16LE();
+
+		_stream->skip(frameSize + 2);
+
+		_curFrame++;
+	}
+}
+
+CoktelVideo::State PreImd::nextFrame() {
+	return processFrame(_curFrame);
+}
+
+uint32 PreImd::getFrameWaitTime() {
+	return _frameLength;
+}
+
+void PreImd::waitEndFrame() {
+	uint32 waitTime = getFrameWaitTime();
+	if (waitTime > 0)
+		g_system->delayMillis(waitTime);
+}
+
+void PreImd::copyCurrentFrame(byte *dest,
+		uint16 left, uint16 top, uint16 width, uint16 height,
+		uint16 x, uint16 y, uint16 pitch, int16 transp) {
+}
+
+void PreImd::zeroVidMem() {
+	_hasOwnVidMem = false;
+	_vidMem       = 0;
+	_vidMemWidth  = 0;
+	_vidMemHeight = 0;
+}
+
+void PreImd::deleteVidMem() {
+	if (_hasOwnVidMem)
+		delete[] _vidMem;
+
+	zeroVidMem();
+}
+
+void PreImd::zeroData() {
+	_stream = 0;
+
+	_features = 0;
+	_flags    = 0;
+
+	_x      = 0;
+	_y      = 0;
+	_width  = 0;
+	_height = 0;
+
+	_framesCount = 0;
+	_curFrame    = 0;
+	_frameRate   = 12;
+	_frameLength = 1000 / _frameRate;
+
+	memset(_palette, 0, 768);
+
+	zeroVidMem();
+
+	_vidBufferSize = 0;
+	_vidBuffer     = 0;
+}
+
+void PreImd::deleteData() {
+	deleteVidMem();
+
+	delete[] _vidBuffer;
+}
+
+void PreImd::clear() {
+	deleteData();
+	zeroData();
+}
+
+CoktelVideo::State PreImd::processFrame(uint16 frame) {
+	assert((_width > 0) && (_height > 0));
+
+	State state;
+
+	if (!_stream || (frame >= _framesCount)) {
+		state.flags = kStateBreak;
+		return state;
+	}
+
+	if (frame != _curFrame) {
+		state.flags |= kStateSeeked;
+		seekFrame(frame);
+	}
+
+	if (!_vidMem)
+		setVideoMemory();
+
+	uint16 frameSize = _stream->readUint16LE();
+
+	uint32 nextFramePos = _stream->pos() + frameSize + 2;
+
+	byte cmd;
+
+	cmd = _stream->readByte();
+	frameSize--;
+
+	bool hasPalette = false;
+	if (cmd == 0) {
+		// Palette. Ignored by Fascination, though
+
+		hasPalette = true;
+
+		_stream->read(_palette, 768);
+
+		frameSize -= 769;
+
+		cmd = _stream->readByte();
+	}
+
+	if (cmd != 2) {
+		// Partial frame data
+
+		uint32 fSize = frameSize;
+		uint32 vidSize = _vidBufferSize;
+		byte *vidBuffer = _vidBuffer;
+
+		while ((fSize > 0) && (vidSize > 0)) {
+			uint32 n = _stream->readByte();
+			fSize--;
+
+			if ((n & 0x80) != 0) {
+				// Data
+
+				n = MIN<uint32>((n & 0x7F) + 1, MIN(fSize, vidSize));
+
+				_stream->read(vidBuffer, n);
+
+				vidBuffer += n;
+				vidSize -= n;
+				fSize -= n;
+
+			} else {
+				// Skip
+
+				n = MIN<uint32>(n + 1, vidSize);
+
+				vidBuffer += n;
+				vidSize -= n;
+			}
+		}
+
+	} else {
+		// Full direct frame
+
+		uint32 vidSize = MIN<uint32>(_vidBufferSize, frameSize);
+
+		_stream->read(_vidBuffer, vidSize);
+	}
+
+	renderFrame();
+
+	_stream->seek(nextFramePos);
+
+	_curFrame++;
+
+	// Complete frame needs to be updated
+	state.left   = _x;
+	state.top    = _y;
+	state.right  = _x + _width  - 1;
+	state.bottom = _y + _height - 1;
+
+	return state;
+}
+
+void PreImd::renderFrame() {
+	assert(_vidMem);
+
+	uint16 w = MIN<uint16>(_vidMemWidth , _width);
+	uint16 h = MIN<uint16>(_vidMemHeight, _height);
+
+	const byte *src = _vidBuffer;
+	byte *dst = _vidMem + (_y * _vidMemWidth) + _x;
+
+	uint32 frameDataSize = _vidBufferSize;
+
+	while (h-- > 0) {
+		uint32 n = MIN<uint32>(w, frameDataSize);
+
+		memcpy(dst, src, n);
+
+		src += _width;
+		dst += _vidMemWidth;
+
+		frameDataSize -= n;
+	}
+}
+
+
+Imd::Imd() {
+	zeroData();
+}
+
+Imd::~Imd() {
+	deleteData();
+	zeroData();
+}
+
+void Imd::setFrameRate(int16 frameRate) {
+	if (frameRate == 0)
+		frameRate = 1;
+
+	_frameRate   = frameRate;
+	_frameLength = 1000 / _frameRate;
+}
+
+int16 Imd::getFrameRate() const {
+	if (!_hasSound)
+		return _frameRate;
+
+	return 1000 / (_soundSliceLength >> 16);
+}
+
+uint32 Imd::getSyncLag() const {
+	return _skipFrames;
+}
+
 bool Imd::loadCoordinates() {
 	// Standard coordinates
 	if (_version >= 3) {
@@ -306,14 +634,6 @@
 	clear();
 }
 
-void Imd::setFrameRate(int16 frameRate) {
-	if (frameRate == 0)
-		frameRate = 1;
-
-	_frameRate   = frameRate;
-	_frameLength = 1000 / _frameRate;
-}
-
 void Imd::setXY(int16 x, int16 y) {
 	// Adjusting the standard coordinates
 	if (_stdX != -1) {
@@ -345,32 +665,6 @@
 		_y = y;
 }
 
-void Imd::setVideoMemory(byte *vidMem, uint16 width, uint16 height) {
-	deleteVidMem();
-
-	_hasOwnVidMem = false;
-	_vidMem       = vidMem;
-	_vidMemWidth  = width;
-	_vidMemHeight = height;
-}
-
-void Imd::setVideoMemory() {
-	deleteVidMem();
-
-	if ((_width > 0) && (_height > 0)) {
-		setXY(0, 0);
-		_hasOwnVidMem = true;
-		_vidMem       = new byte[_width * _height];
-		_vidMemWidth  = _width;
-		_vidMemHeight = _height;
-
-		memset(_vidMem, 0, _width * _height);
-	}
-}
-
-void Imd::setDoubleMode(bool doubleMode) {
-}
-
 void Imd::enableSound(Audio::Mixer &mixer) {
 	// Sanity check
 	if (mixer.getOutputRate() == 0)
@@ -478,12 +772,6 @@
 	return 0;
 }
 
-void Imd::waitEndFrame() {
-	uint32 waitTime = getFrameWaitTime();
-	if (waitTime > 0)
-		g_system->delayMillis(waitTime);
-}
-
 void Imd::copyCurrentFrame(byte *dest,
 		uint16 left, uint16 top, uint16 width, uint16 height,
 		uint16 x, uint16 y, uint16 pitch, int16 transp) {
@@ -535,51 +823,24 @@
 
 }
 
-void Imd::deleteVidMem(bool del) {
-	if (del) {
-		if (_hasOwnVidMem)
-			delete[] _vidMem;
-	}
+void Imd::zeroData() {
+	PreImd::zeroData();
 
-	_hasOwnVidMem = false;
-	_vidMem       = 0;
-	_vidMemWidth  = 0;
-	_vidMemHeight = 0;
-}
-
-void Imd::clear(bool del) {
-	if (del) {
-		delete[] _framesPos;
-		delete[] _frameCoords;
-		delete[] _frameData;
-		delete[] _vidBuffer;
-
-		disableSound();
-	}
-
-	_stream = 0;
-
 	_version  = 0;
-	_features = 0;
-	_flags    = 0;
 
-	_x    = _y    = _width    = _height    = 0;
-	_stdX = _stdY = _stdWidth = _stdHeight = 0;
+	_stdX      = 0;
+	_stdY      = 0;
+	_stdWidth  = 0;
+	_stdHeight = 0;
 
-	_framesCount = _curFrame = 0;
-
 	_framesPos     = 0;
 	_firstFramePos = 0;
 	_frameCoords   = 0;
 
-	_frameDataSize = _vidBufferSize = 0;
-	_frameData     = _vidBuffer     = 0;
+	_frameDataSize = 0;
+	_frameData     = 0;
 	_frameDataLen  = 0;
 
-	memset(_palette, 0, 768);
-
-	deleteVidMem(del);
-
 	_hasSound     = false;
 	_soundEnabled = false;
 	_soundStage   = 0;
@@ -592,11 +853,24 @@
 	_soundSliceLength = 0;
 	_audioStream      = 0;
 
-	_frameRate     = 12;
-	_frameLength   = 0;
 	_lastFrameTime = 0;
 }
 
+void Imd::deleteData() {
+	PreImd::deleteData();
+
+	delete[] _framesPos;
+	delete[] _frameCoords;
+	delete[] _frameData;
+
+	disableSound();
+}
+
+void Imd::clear() {
+	deleteData();
+	zeroData();
+}
+
 void Imd::nextSoundSlice(bool hasNextCmd) {
 	if (hasNextCmd || !_soundEnabled) {
 		_stream->seek(_soundSliceSize, SEEK_CUR);
@@ -1133,11 +1407,12 @@
 };
 
 Vmd::Vmd(Graphics::PaletteLUT *palLUT) : _palLUT(palLUT) {
-	clear(false);
+	zeroData();
 }
 
 Vmd::~Vmd() {
-	clear();
+	deleteData();
+	zeroData();
 }
 
 bool Vmd::assessVideoProperties() {
@@ -1578,17 +1853,9 @@
 	return state;
 }
 
-void Vmd::clear(bool del) {
-	Imd::clear(del);
+void Vmd::zeroData() {
+	Imd::zeroData();
 
-	if (del) {
-#ifdef USE_INDEO3
-		delete _codecIndeo3;
-#endif
-		delete[] _frames;
-		delete[] _vidMemBuffer;
-	}
-
 	_hasVideo   = true;
 	_videoCodec = 0;
 
@@ -1617,6 +1884,21 @@
 	_vidMemBuffer   = 0;
 }
 
+void Vmd::deleteData() {
+	Imd::deleteData();
+
+#ifdef USE_INDEO3
+		delete _codecIndeo3;
+#endif
+		delete[] _frames;
+		delete[] _vidMemBuffer;
+}
+
+void Vmd::clear() {
+	deleteData();
+	zeroData();
+}
+
 CoktelVideo::State Vmd::processFrame(uint16 frame) {
 	State state;
 	bool startSound = false;

Modified: scummvm/trunk/graphics/video/coktelvideo/coktelvideo.h
===================================================================
--- scummvm/trunk/graphics/video/coktelvideo/coktelvideo.h	2010-03-10 21:44:58 UTC (rev 48232)
+++ scummvm/trunk/graphics/video/coktelvideo/coktelvideo.h	2010-03-11 06:14:52 UTC (rev 48233)
@@ -125,6 +125,7 @@
 	virtual int16 getWidth() const = 0;
 	/** Returns the height of the video. */
 	virtual int16 getHeight() const = 0;
+
 	/** Returns the number of frames the loaded video has. */
 	virtual uint16 getFramesCount() const = 0;
 	/** Returns the current frame number.
@@ -209,26 +210,30 @@
 			uint16 x, uint16 y, uint16 pitch, int16 transp = -1) = 0;
 };
 
-/** Coktel Vision's IMD files.
+/** Coktel Vision's first simple IMD format, used by Fascination.
  */
-class Imd : public CoktelVideo {
+class PreImd : public CoktelVideo {
 public:
-	Imd();
-	~Imd();
+	PreImd();
+	PreImd(int16 width, int16 height);
+	~PreImd();
 
 	uint32 getFeatures() const;
 	uint16 getFlags()    const;
 
-	int16  getX()      const;
-	int16  getY()      const;
-	int16  getWidth()  const;
-	int16  getHeight() const;
+	int16 getX()      const;
+	int16 getY()      const;
+	int16 getWidth()  const;
+	int16 getHeight() const;
 
 	uint16 getFramesCount()  const;
 	uint16 getCurrentFrame() const;
-	int16  getFrameRate()    const;
-	uint32 getSyncLag()      const;
 
+	void setFrameRate(int16 frameRate);
+	int16 getFrameRate() const;
+
+	uint32 getSyncLag() const;
+
 	const byte *getPalette() const;
 
 	bool getFrameCoords(int16 frame,
@@ -238,8 +243,6 @@
 	bool hasExtraData(const char *fileName) const;
 	Common::MemoryReadStream *getExtraData(const char *fileName);
 
-	void setFrameRate(int16 frameRate);
-
 	bool load(Common::SeekableReadStream &stream);
 	void unload();
 
@@ -265,6 +268,80 @@
 			uint16 x, uint16 y, uint16 pitch, int16 transp = -1);
 
 protected:
+	Common::SeekableReadStream *_stream;
+
+	// Properties
+	uint32 _features;
+	uint16 _flags;
+
+	int16 _forcedWidth;
+	int16 _forcedHeight;
+
+	// Current coordinates
+	int16 _x;
+	int16 _y;
+	int16 _width;
+	int16 _height;
+
+	uint16 _framesCount;
+	uint16 _curFrame;
+	int16  _frameRate;
+	uint32 _frameLength;
+
+	byte _palette[768];
+
+	// Video memory
+	bool  _hasOwnVidMem;
+	byte  *_vidMem;
+	uint16 _vidMemWidth;
+	uint16 _vidMemHeight;
+
+	byte  *_vidBuffer;
+	uint32 _vidBufferSize;
+
+	void clear();
+	void zeroData();
+	void deleteData();
+
+	void zeroVidMem();
+	void deleteVidMem();
+
+	State processFrame(uint16 frame);
+	void renderFrame();
+};
+
+/** Coktel Vision's IMD files.
+ */
+class Imd : public PreImd {
+public:
+	Imd();
+	~Imd();
+
+	void setFrameRate(int16 frameRate);
+	int16 getFrameRate() const;
+
+	uint32 getSyncLag()      const;
+
+	bool load(Common::SeekableReadStream &stream);
+	void unload();
+
+	void setXY(int16 x, int16 y);
+
+	void enableSound(Audio::Mixer &mixer);
+	void disableSound();
+
+	bool isSoundPlaying() const;
+
+	void seekFrame(int32 frame, int16 whence = SEEK_SET, bool restart = false);
+
+	State nextFrame();
+	uint32 getFrameWaitTime();
+
+	void copyCurrentFrame(byte *dest,
+			uint16 left, uint16 top, uint16 width, uint16 height,
+			uint16 x, uint16 y, uint16 pitch, int16 transp = -1);
+
+protected:
 	enum Command {
 		kCommandNextSound   = 0xFF00,
 		kCommandStartSound  = 0xFF01,
@@ -288,28 +365,15 @@
 		int16 bottom;
 	} PACKED_STRUCT;
 
-	Common::SeekableReadStream *_stream;
-
 	// Properties
 	uint16 _version;
-	uint32 _features;
-	uint16 _flags;
 
-	// Current coordinates
-	int16 _x;
-	int16 _y;
-	int16 _width;
-	int16 _height;
-
 	// Standard coordinates gives by the header
 	int16 _stdX;
 	int16 _stdY;
 	int16 _stdWidth;
 	int16 _stdHeight;
 
-	uint16 _framesCount;
-	uint16 _curFrame;
-
 	uint32 *_framesPos;
 	uint32  _firstFramePos;
 	Coord *_frameCoords;
@@ -319,18 +383,6 @@
 	uint32 _frameDataSize;
 	uint32 _frameDataLen;
 
-	// Buffer for uncompressed raw frame data
-	byte  *_vidBuffer;
-	uint32 _vidBufferSize;
-
-	byte _palette[768];
-
-	// Video memory
-	bool  _hasOwnVidMem;
-	byte  *_vidMem;
-	uint16 _vidMemWidth;
-	uint16 _vidMemHeight;
-
 	// Sound properties
 	uint16 _soundFlags;
 	int16  _soundFreq;
@@ -347,18 +399,16 @@
 	Audio::QueuingAudioStream *_audioStream;
 	Audio::SoundHandle _audioHandle;
 
-	// Current video state
-	int16  _frameRate;
-	uint32 _frameLength;
 	uint32 _lastFrameTime;
 
 	Audio::Mixer *_mixer;
 
+	void clear();
+	void zeroData();
+	void deleteData();
+
 	void unsignedToSigned(byte *buffer, int length);
 
-	void deleteVidMem(bool del = true);
-	void clear(bool del = true);
-
 	bool loadCoordinates();
 	bool loadFrameTableOffsets(uint32 &framesPosPos, uint32 &framesCoordsPos);
 	bool assessVideoProperties();
@@ -500,7 +550,9 @@
 	Indeo3 *_codecIndeo3;
 #endif
 
-	void clear(bool del = true);
+	void clear();
+	void zeroData();
+	void deleteData();
 
 	bool getPartCoords(int16 frame, PartType type,
 			int16 &x, int16 &y, int16 &width, int16 &height);


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