[Scummvm-cvs-logs] SF.net SVN: scummvm:[40759] scummvm/trunk

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Thu May 21 15:02:56 CEST 2009


Revision: 40759
          http://scummvm.svn.sourceforge.net/scummvm/?rev=40759&view=rev
Author:   thebluegr
Date:     2009-05-21 13:02:56 +0000 (Thu, 21 May 2009)

Log Message:
-----------
Renamed the DXA, SMK and FLIC video decoders to reflect the fact that they're decoders, not players

Modified Paths:
--------------
    scummvm/trunk/dists/msvc7/scummvm.vcproj
    scummvm/trunk/dists/msvc71/scummvm.vcproj
    scummvm/trunk/dists/msvc8/scummvm.vcproj
    scummvm/trunk/dists/msvc9/scummvm.vcproj
    scummvm/trunk/engines/agos/animation.h
    scummvm/trunk/engines/saga/introproc_saga2.cpp
    scummvm/trunk/engines/scumm/he/animation_he.h
    scummvm/trunk/engines/sword1/animation.h
    scummvm/trunk/engines/sword2/animation.h
    scummvm/trunk/engines/tucker/tucker.h
    scummvm/trunk/graphics/module.mk

Added Paths:
-----------
    scummvm/trunk/graphics/video/dxa_decoder.cpp
    scummvm/trunk/graphics/video/dxa_decoder.h
    scummvm/trunk/graphics/video/flic_decoder.cpp
    scummvm/trunk/graphics/video/flic_decoder.h
    scummvm/trunk/graphics/video/smk_decoder.cpp
    scummvm/trunk/graphics/video/smk_decoder.h

Removed Paths:
-------------
    scummvm/trunk/graphics/video/dxa_player.cpp
    scummvm/trunk/graphics/video/dxa_player.h
    scummvm/trunk/graphics/video/flic_player.cpp
    scummvm/trunk/graphics/video/flic_player.h
    scummvm/trunk/graphics/video/smk_player.cpp
    scummvm/trunk/graphics/video/smk_player.h

Modified: scummvm/trunk/dists/msvc7/scummvm.vcproj
===================================================================
--- scummvm/trunk/dists/msvc7/scummvm.vcproj	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/dists/msvc7/scummvm.vcproj	2009-05-21 13:02:56 UTC (rev 40759)
@@ -1214,16 +1214,16 @@
 			<Filter
 				Name="video">
 				<File
-					RelativePath="..\..\graphics\video\dxa_player.cpp">
+					RelativePath="..\..\graphics\video\dxa_decoder.cpp">
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\dxa_player.h">
+					RelativePath="..\..\graphics\video\dxa_decoder.h">
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\flic_player.cpp">
+					RelativePath="..\..\graphics\video\flic_decoder.cpp">
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\flic_player.h">
+					RelativePath="..\..\graphics\video\flic_decoder.h">
 				</File>
 				<File
 					RelativePath="..\..\graphics\video\mpeg_player.cpp">
@@ -1232,10 +1232,10 @@
 					RelativePath="..\..\graphics\video\mpeg_player.h">
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\smk_player.cpp">
+					RelativePath="..\..\graphics\video\smk_decoder.cpp">
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\smk_player.h">
+					RelativePath="..\..\graphics\video\smk_decoder.h">
 				</File>
 				<File
 					RelativePath="..\..\graphics\video\video_player.cpp">

Modified: scummvm/trunk/dists/msvc71/scummvm.vcproj
===================================================================
--- scummvm/trunk/dists/msvc71/scummvm.vcproj	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/dists/msvc71/scummvm.vcproj	2009-05-21 13:02:56 UTC (rev 40759)
@@ -1228,16 +1228,16 @@
 			<Filter
 				Name="video">
 				<File
-					RelativePath="..\..\graphics\video\dxa_player.cpp">
+					RelativePath="..\..\graphics\video\dxa_decoder.cpp">
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\dxa_player.h">
+					RelativePath="..\..\graphics\video\dxa_decoder.h">
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\flic_player.cpp">
+					RelativePath="..\..\graphics\video\flic_decoder.cpp">
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\flic_player.h">
+					RelativePath="..\..\graphics\video\flic_decoder.h">
 				</File>
 				<File
 					RelativePath="..\..\graphics\video\mpeg_player.cpp">
@@ -1246,10 +1246,10 @@
 					RelativePath="..\..\graphics\video\mpeg_player.h">
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\smk_player.cpp">
+					RelativePath="..\..\graphics\video\smk_decoder.cpp">
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\smk_player.h">
+					RelativePath="..\..\graphics\video\smk_decoder.h">
 				</File>
 				<File
 					RelativePath="..\..\graphics\video\video_player.cpp">

Modified: scummvm/trunk/dists/msvc8/scummvm.vcproj
===================================================================
--- scummvm/trunk/dists/msvc8/scummvm.vcproj	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/dists/msvc8/scummvm.vcproj	2009-05-21 13:02:56 UTC (rev 40759)
@@ -1648,19 +1648,19 @@
 				Name="video"
 				>
 				<File
-					RelativePath="..\..\graphics\video\dxa_player.cpp"
+					RelativePath="..\..\graphics\video\dxa_decoder.cpp"
 					>
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\dxa_player.h"
+					RelativePath="..\..\graphics\video\dxa_decoder.h"
 					>
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\flic_player.cpp"
+					RelativePath="..\..\graphics\video\flic_decoder.cpp"
 					>
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\flic_player.h"
+					RelativePath="..\..\graphics\video\flic_decoder.h"
 					>
 				</File>
 				<File
@@ -1672,11 +1672,11 @@
 					>
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\smk_player.cpp"
+					RelativePath="..\..\graphics\video\smk_decoder.cpp"
 					>
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\smk_player.h"
+					RelativePath="..\..\graphics\video\smk_decoder.h"
 					>
 				</File>
 				<File

Modified: scummvm/trunk/dists/msvc9/scummvm.vcproj
===================================================================
--- scummvm/trunk/dists/msvc9/scummvm.vcproj	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/dists/msvc9/scummvm.vcproj	2009-05-21 13:02:56 UTC (rev 40759)
@@ -1653,19 +1653,19 @@
 				Name="video"
 				>
 				<File
-					RelativePath="..\..\graphics\video\dxa_player.cpp"
+					RelativePath="..\..\graphics\video\dxa_decoder.cpp"
 					>
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\dxa_player.h"
+					RelativePath="..\..\graphics\video\dxa_decoder.h"
 					>
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\flic_player.cpp"
+					RelativePath="..\..\graphics\video\flic_decoder.cpp"
 					>
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\flic_player.h"
+					RelativePath="..\..\graphics\video\flic_decoder.h"
 					>
 				</File>
 				<File
@@ -1677,11 +1677,11 @@
 					>
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\smk_player.cpp"
+					RelativePath="..\..\graphics\video\smk_decoder.cpp"
 					>
 				</File>
 				<File
-					RelativePath="..\..\graphics\video\smk_player.h"
+					RelativePath="..\..\graphics\video\smk_decoder.h"
 					>
 				</File>
 				<File

Modified: scummvm/trunk/engines/agos/animation.h
===================================================================
--- scummvm/trunk/engines/agos/animation.h	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/engines/agos/animation.h	2009-05-21 13:02:56 UTC (rev 40759)
@@ -29,8 +29,8 @@
 #include "common/file.h"
 #include "common/stream.h"
 
-#include "graphics/video/dxa_player.h"
-#include "graphics/video/smk_player.h"
+#include "graphics/video/dxa_decoder.h"
+#include "graphics/video/smk_decoder.h"
 #include "sound/mixer.h"
 
 namespace AGOS {

Modified: scummvm/trunk/engines/saga/introproc_saga2.cpp
===================================================================
--- scummvm/trunk/engines/saga/introproc_saga2.cpp	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/engines/saga/introproc_saga2.cpp	2009-05-21 13:02:56 UTC (rev 40759)
@@ -33,7 +33,7 @@
 
 #include "sound/mixer.h"
 #include "graphics/surface.h"
-#include "graphics/video/smk_player.h"
+#include "graphics/video/smk_decoder.h"
 
 #include "common/events.h"
 #include "common/system.h"

Modified: scummvm/trunk/engines/scumm/he/animation_he.h
===================================================================
--- scummvm/trunk/engines/scumm/he/animation_he.h	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/engines/scumm/he/animation_he.h	2009-05-21 13:02:56 UTC (rev 40759)
@@ -28,7 +28,7 @@
 
 #include "common/file.h"
 
-#include "graphics/video/smk_player.h"
+#include "graphics/video/smk_decoder.h"
 
 #include "sound/mixer.h"
 

Modified: scummvm/trunk/engines/sword1/animation.h
===================================================================
--- scummvm/trunk/engines/sword1/animation.h	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/engines/sword1/animation.h	2009-05-21 13:02:56 UTC (rev 40759)
@@ -26,8 +26,8 @@
 #ifndef SWORD1_ANIMATION_H
 #define SWORD1_ANIMATION_H
 
-#include "graphics/video/dxa_player.h"
-#include "graphics/video/smk_player.h"
+#include "graphics/video/dxa_decoder.h"
+#include "graphics/video/smk_decoder.h"
 #include "graphics/video/video_player.h"
 
 #include "sword1/screen.h"

Modified: scummvm/trunk/engines/sword2/animation.h
===================================================================
--- scummvm/trunk/engines/sword2/animation.h	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/engines/sword2/animation.h	2009-05-21 13:02:56 UTC (rev 40759)
@@ -28,8 +28,8 @@
 #ifndef SWORD2_ANIMATION_H
 #define SWORD2_ANIMATION_H
 
-#include "graphics/video/dxa_player.h"
-#include "graphics/video/smk_player.h"
+#include "graphics/video/dxa_decoder.h"
+#include "graphics/video/smk_decoder.h"
 #include "graphics/video/video_player.h"
 #include "sound/mixer.h"
 

Modified: scummvm/trunk/engines/tucker/tucker.h
===================================================================
--- scummvm/trunk/engines/tucker/tucker.h	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/engines/tucker/tucker.h	2009-05-21 13:02:56 UTC (rev 40759)
@@ -32,7 +32,7 @@
 #include "common/events.h"
 #include "common/stream.h"
 
-#include "graphics/video/flic_player.h"
+#include "graphics/video/flic_decoder.h"
 
 #include "sound/mixer.h"
 

Modified: scummvm/trunk/graphics/module.mk
===================================================================
--- scummvm/trunk/graphics/module.mk	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/graphics/module.mk	2009-05-21 13:02:56 UTC (rev 40759)
@@ -18,10 +18,10 @@
 	thumbnail.o \
 	VectorRenderer.o \
 	VectorRendererSpec.o \
-	video/dxa_player.o \
-	video/flic_player.o \
+	video/dxa_decoder.o \
+	video/flic_decoder.o \
 	video/mpeg_player.o \
-	video/smk_player.o \
+	video/smk_decoder.o \
 	video/video_player.o \
 	video/coktelvideo/indeo3.o \
 	video/coktelvideo/coktelvideo.o

Copied: scummvm/trunk/graphics/video/dxa_decoder.cpp (from rev 40752, scummvm/trunk/graphics/video/dxa_player.cpp)
===================================================================
--- scummvm/trunk/graphics/video/dxa_decoder.cpp	                        (rev 0)
+++ scummvm/trunk/graphics/video/dxa_decoder.cpp	2009-05-21 13:02:56 UTC (rev 40759)
@@ -0,0 +1,563 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/debug.h"
+#include "common/endian.h"
+#include "common/archive.h"
+#include "common/system.h"
+#include "common/util.h"
+
+#include "graphics/video/dxa_decoder.h"
+
+#ifdef USE_ZLIB
+  #include "common/zlib.h"
+#endif
+
+namespace Graphics {
+
+DXADecoder::DXADecoder() {
+	_fileStream = 0;
+
+	_frameBuffer1 = 0;
+	_frameBuffer2 = 0;
+	_scaledBuffer = 0;
+	_videoFrameBuffer = 0;
+
+	_inBuffer = 0;
+	_inBufferSize = 0;
+
+	_decompBuffer = 0;
+	_decompBufferSize = 0;
+
+	_videoInfo.width = 0;
+	_videoInfo.height = 0;
+
+	_frameSize = 0;
+	_videoInfo.frameCount = 0;
+	_videoInfo.currentFrame = 0;
+	_videoInfo.frameRate = 0;
+	_videoInfo.frameDelay = 0;
+
+	_scaleMode = S_NONE;
+}
+
+DXADecoder::~DXADecoder() {
+	closeFile();
+}
+
+bool DXADecoder::loadFile(const char *fileName) {
+	uint32 tag;
+	int32 frameRate;
+
+	closeFile();
+
+	_fileStream = SearchMan.createReadStreamForMember(fileName);
+	if (!_fileStream)
+		return false;
+
+	tag = _fileStream->readUint32BE();
+	assert(tag == MKID_BE('DEXA'));
+
+	uint8 flags = _fileStream->readByte();
+	_videoInfo.frameCount = _fileStream->readUint16BE();
+	frameRate = _fileStream->readSint32BE();
+
+	if (frameRate > 0) {
+		_videoInfo.frameRate = 1000 / frameRate;
+		_videoInfo.frameDelay = frameRate * 100;
+	} else if (frameRate < 0) {
+		_videoInfo.frameRate = 100000 / (-frameRate);
+		_videoInfo.frameDelay = -frameRate;
+	} else {
+		_videoInfo.frameRate = 10;
+		_videoInfo.frameDelay = 10000;
+	}
+
+	_videoInfo.width = _fileStream->readUint16BE();
+	_videoInfo.height = _fileStream->readUint16BE();
+
+	if (flags & 0x80) {
+		_scaleMode = S_INTERLACED;
+		_curHeight = _videoInfo.height / 2;
+	} else if (flags & 0x40) {
+		_scaleMode = S_DOUBLE;
+		_curHeight = _videoInfo.height / 2;
+	} else {
+		_scaleMode = S_NONE;
+		_curHeight = _videoInfo.height;
+	}
+
+	debug(2, "flags 0x0%x framesCount %d width %d height %d rate %d ticks %d", flags, getFrameCount(), getWidth(), getHeight(), getFrameRate(), getFrameDelay());
+
+	_frameSize = _videoInfo.width * _videoInfo.height;
+	_decompBufferSize = _frameSize;
+	_frameBuffer1 = (uint8 *)malloc(_frameSize);
+	memset(_frameBuffer1, 0, _frameSize);
+	_frameBuffer2 = (uint8 *)malloc(_frameSize);
+	memset(_frameBuffer2, 0, _frameSize);
+	if (!_frameBuffer1 || !_frameBuffer2)
+		error("DXADecoder: Error allocating frame buffers (size %u)", _frameSize);
+
+	_scaledBuffer = 0;
+	if (_scaleMode != S_NONE) {
+		_scaledBuffer = (uint8 *)malloc(_frameSize);
+		memset(_scaledBuffer, 0, _frameSize);
+		if (!_scaledBuffer)
+			error("Error allocating scale buffer (size %u)", _frameSize);
+	}
+
+#ifdef DXA_EXPERIMENT_MAXD
+	// Check for an extended header
+	if (flags & 1) {
+		uint32 size;
+
+		do {
+			tag = _fileStream->readUint32BE();
+			if (tag != 0) {
+				size = _fileStream->readUint32BE();
+			}
+			switch (tag) {
+				case 0: // No more tags
+					break;
+				case MKID_BE('MAXD'):
+					assert(size == 4);
+					_decompBufferSize = _fileStream->readUint32BE();
+					break;
+				default: // Unknown tag - skip it.
+					while (size > 0) {
+						byte dummy = _fileStream->readByte();
+						size--;
+					}
+					break;
+			}
+		} while (tag != 0);
+	}
+#endif
+	
+	// Read the sound header
+	_soundTag = _fileStream->readUint32BE();
+
+	_videoInfo.currentFrame = 0;
+
+	_videoInfo.firstframeOffset = _fileStream->pos();
+
+	return true;
+}
+
+void DXADecoder::closeFile() {
+	if (!_fileStream)
+		return;
+
+	delete _fileStream;
+	_fileStream = 0;
+
+	free(_frameBuffer1);
+	free(_frameBuffer2);
+	free(_scaledBuffer);
+	free(_inBuffer);
+	free(_decompBuffer);
+
+	_inBuffer = 0;
+	_decompBuffer = 0;
+}
+
+void DXADecoder::decodeZlib(byte *data, int size, int totalSize) {
+#ifdef USE_ZLIB
+	unsigned long dstLen = totalSize;
+	Common::uncompress(data, &dstLen, _inBuffer, size);
+#endif
+}
+
+#define BLOCKW 4
+#define BLOCKH 4
+
+void DXADecoder::decode12(int size) {
+#ifdef USE_ZLIB
+	if (_decompBuffer == NULL) {
+		_decompBuffer = (byte *)malloc(_decompBufferSize);
+		memset(_decompBuffer, 0, _decompBufferSize);
+		if (_decompBuffer == NULL)
+			error("Error allocating decomp buffer (size %u)", _decompBufferSize);
+	}
+	/* decompress the input data */
+	decodeZlib(_decompBuffer, size, _decompBufferSize);
+
+	byte *dat = _decompBuffer;
+
+	memcpy(_frameBuffer2, _frameBuffer1, _frameSize);
+
+	for (uint32 by = 0; by < _videoInfo.height; by += BLOCKH) {
+		for (uint32 bx = 0; bx < _videoInfo.width; bx += BLOCKW) {
+			byte type = *dat++;
+			byte *b2 = _frameBuffer1 + bx + by * _videoInfo.width;
+
+			switch (type) {
+			case 0:
+				break;
+			case 10:
+			case 11:
+			case 12:
+			case 13:
+			case 14:
+			case 15:
+			case 1:	{
+				unsigned short diffMap;
+				if (type >= 10 && type <= 15) {
+					static const struct { uint8 sh1, sh2; } shiftTbl[6] = {
+						{0, 0},	{8, 0},	{8, 8},	{8, 4},	{4, 0},	{4, 4}
+					};
+					diffMap = ((*dat & 0xF0) << shiftTbl[type-10].sh1) |
+						  ((*dat & 0x0F) << shiftTbl[type-10].sh2);
+					dat++;
+				} else {
+					diffMap = *(unsigned short*)dat;
+					dat += 2;
+				}
+
+				for (int yc = 0; yc < BLOCKH; yc++) {
+					for (int xc = 0; xc < BLOCKW; xc++) {
+						if (diffMap & 0x8000) {
+							b2[xc] = *dat++;
+						}
+						diffMap <<= 1;
+					}
+					b2 += _videoInfo.width;
+				}
+				break;
+			}
+			case 2:	{
+				byte color = *dat++;
+
+				for (int yc = 0; yc < BLOCKH; yc++) {
+					for (int xc = 0; xc < BLOCKW; xc++) {
+						b2[xc] = color;
+					}
+					b2 += _videoInfo.width;
+				}
+				break;
+			}
+			case 3:	{
+				for (int yc = 0; yc < BLOCKH; yc++) {
+					for (int xc = 0; xc < BLOCKW; xc++) {
+						b2[xc] = *dat++;
+					}
+					b2 += _videoInfo.width;
+				}
+				break;
+			}
+			case 4:	{
+				byte mbyte = *dat++;
+				int mx = (mbyte >> 4) & 0x07;
+				if (mbyte & 0x80)
+					mx = -mx;
+				int my = mbyte & 0x07;
+				if (mbyte & 0x08)
+					my = -my;
+				byte *b1 = _frameBuffer2 + (bx+mx) + (by+my) * _videoInfo.width;
+				for (int yc = 0; yc < BLOCKH; yc++) {
+					memcpy(b2, b1, BLOCKW);
+					b1 += _videoInfo.width;
+					b2 += _videoInfo.width;
+				}
+				break;
+			}
+			case 5:
+				break;
+			default:
+				error("decode12: Unknown type %d", type);
+			}
+		}
+	}
+#endif
+}
+
+void DXADecoder::decode13(int size) {
+#ifdef USE_ZLIB
+	uint8 *codeBuf, *dataBuf, *motBuf, *maskBuf;
+
+	if (_decompBuffer == NULL) {
+		_decompBuffer = (byte *)malloc(_decompBufferSize);
+		memset(_decompBuffer, 0, _decompBufferSize);
+		if (_decompBuffer == NULL)
+			error("Error allocating decomp buffer (size %u)", _decompBufferSize);
+	}
+
+	/* decompress the input data */
+	decodeZlib(_decompBuffer, size, _decompBufferSize);
+
+	memcpy(_frameBuffer2, _frameBuffer1, _frameSize);
+
+	int codeSize = _videoInfo.width * _curHeight / 16;
+	int dataSize, motSize, maskSize;
+
+	dataSize = READ_BE_UINT32(&_decompBuffer[0]);
+	motSize  = READ_BE_UINT32(&_decompBuffer[4]);
+	maskSize = READ_BE_UINT32(&_decompBuffer[8]);
+
+	codeBuf = &_decompBuffer[12];
+	dataBuf = &codeBuf[codeSize];
+	motBuf = &dataBuf[dataSize];
+	maskBuf = &motBuf[motSize];
+
+	for (uint32 by = 0; by < _curHeight; by += BLOCKH) {
+		for (uint32 bx = 0; bx < _videoInfo.width; bx += BLOCKW) {
+			uint8 type = *codeBuf++;
+			uint8 *b2 = (uint8*)_frameBuffer1 + bx + by * _videoInfo.width;
+
+			switch (type) {
+			case 0:
+				break;
+
+			case 1: {
+				uint16 diffMap = READ_BE_UINT16(maskBuf);
+				maskBuf += 2;
+
+				for (int yc = 0; yc < BLOCKH; yc++) {
+					for (int xc = 0; xc < BLOCKW; xc++) {
+						if (diffMap & 0x8000) {
+							b2[xc] = *dataBuf++;
+						}
+						diffMap <<= 1;
+					}
+					b2 += _videoInfo.width;
+				}
+				break;
+			}
+			case 2: {
+				uint8 color = *dataBuf++;
+
+				for (int yc = 0; yc < BLOCKH; yc++) {
+					for (int xc = 0; xc < BLOCKW; xc++) {
+						b2[xc] = color;
+					}
+					b2 += _videoInfo.width;
+				}
+				break;
+			}
+			case 3: {
+				for (int yc = 0; yc < BLOCKH; yc++) {
+					for (int xc = 0; xc < BLOCKW; xc++) {
+						b2[xc] = *dataBuf++;
+					}
+					b2 += _videoInfo.width;
+				}
+				break;
+			}
+			case 4: {
+				uint8 mbyte = *motBuf++;
+
+				int mx = (mbyte >> 4) & 0x07;
+				if (mbyte & 0x80)
+					mx = -mx;
+				int my = mbyte & 0x07;
+				if (mbyte & 0x08)
+					my = -my;
+
+				uint8 *b1 = (uint8*)_frameBuffer2 + (bx+mx) + (by+my) * _videoInfo.width;
+				for (int yc = 0; yc < BLOCKH; yc++) {
+					memcpy(b2, b1, BLOCKW);
+					b1 += _videoInfo.width;
+					b2 += _videoInfo.width;
+				}
+				break;
+			}
+			case 8: {
+				static const int subX[4] = {0, 2, 0, 2};
+				static const int subY[4] = {0, 0, 2, 2};
+
+				uint8 subMask = *maskBuf++;
+
+				for (int subBlock = 0; subBlock < 4; subBlock++) {
+					int sx = bx + subX[subBlock], sy = by + subY[subBlock];
+					b2 = (uint8*)_frameBuffer1 + sx + sy * _videoInfo.width;
+					switch (subMask & 0xC0) {
+					// 00: skip
+					case 0x00:
+						break;
+					// 01: solid color
+					case 0x40: {
+						uint8 subColor = *dataBuf++;
+						for (int yc = 0; yc < BLOCKH / 2; yc++) {
+							for (int xc = 0; xc < BLOCKW / 2; xc++) {
+								b2[xc] = subColor;
+							}
+							b2 += _videoInfo.width;
+						}
+						break;
+					}
+					// 02: motion vector
+					case 0x80: {
+						uint8 mbyte = *motBuf++;
+
+						int mx = (mbyte >> 4) & 0x07;
+						if (mbyte & 0x80)
+							mx = -mx;
+
+						int my = mbyte & 0x07;
+						if (mbyte & 0x08)
+							my = -my;
+
+						uint8 *b1 = (uint8*)_frameBuffer2 + (sx+mx) + (sy+my) * _videoInfo.width;
+						for (int yc = 0; yc < BLOCKH / 2; yc++) {
+							memcpy(b2, b1, BLOCKW / 2);
+							b1 += _videoInfo.width;
+							b2 += _videoInfo.width;
+						}
+						break;
+					}
+					// 03: raw
+					case 0xC0:
+						for (int yc = 0; yc < BLOCKH / 2; yc++) {
+							for (int xc = 0; xc < BLOCKW / 2; xc++) {
+								b2[xc] = *dataBuf++;
+							}
+							b2 += _videoInfo.width;
+						}
+						break;
+					}
+					subMask <<= 2;
+				}
+				break;
+			}
+			case 32:
+			case 33:
+			case 34: {
+				int count = type - 30;
+				uint8 pixels[4];
+
+				memcpy(pixels, dataBuf, count);
+				dataBuf += count;
+
+				if (count == 2) {
+					uint16 code = READ_BE_UINT16(maskBuf);
+					maskBuf += 2;
+					for (int yc = 0; yc < BLOCKH; yc++) {
+						for (int xc = 0; xc < BLOCKW; xc++) {
+							b2[xc] = pixels[code & 1];
+							code >>= 1;
+						}
+						b2 += _videoInfo.width;
+					}
+				} else {
+					uint32 code = READ_BE_UINT32(maskBuf);
+					maskBuf += 4;
+					for (int yc = 0; yc < BLOCKH; yc++) {
+						for (int xc = 0; xc < BLOCKW; xc++) {
+							b2[xc] = pixels[code & 3];
+							code >>= 2;
+						}
+						b2 += _videoInfo.width;
+					}
+				}
+				break;
+			}
+			default:
+				error("decode13: Unknown type %d", type);
+			}
+		}
+	}
+#endif
+}
+
+bool DXADecoder::decodeNextFrame() {
+	uint32 tag;
+
+	if (_videoInfo.currentFrame == 0)
+		_videoInfo.startTime = g_system->getMillis();
+
+	tag = _fileStream->readUint32BE();
+	if (tag == MKID_BE('CMAP')) {
+		byte rgb[768];
+
+		_fileStream->read(rgb, ARRAYSIZE(rgb));
+		setPalette(rgb);
+	}
+
+	tag = _fileStream->readUint32BE();
+	if (tag == MKID_BE('FRAM')) {
+		byte type = _fileStream->readByte();
+		uint32 size = _fileStream->readUint32BE();
+		if ((_inBuffer == NULL) || (_inBufferSize < size)) {
+			free(_inBuffer);
+			_inBuffer = (byte *)malloc(size);
+			memset(_inBuffer, 0, size);
+			if (_inBuffer == NULL)
+				error("Error allocating input buffer (size %u)", size);
+			_inBufferSize = size;
+		}
+
+		_fileStream->read(_inBuffer, size);
+
+		switch (type) {
+		case 2:
+			decodeZlib(_frameBuffer1, size, _frameSize);
+			break;
+		case 3:
+			decodeZlib(_frameBuffer2, size, _frameSize);
+			break;
+		case 12:
+			decode12(size);
+			break;
+		case 13:
+			decode13(size);
+			break;
+		default:
+			error("decodeFrame: Unknown compression type %d", type);
+		}
+
+		if (type == 3) {
+			for (uint32 j = 0; j < _curHeight; ++j) {
+				for (uint32 i = 0; i < _videoInfo.width; ++i) {
+					const int offs = j * _videoInfo.width + i;
+					_frameBuffer1[offs] ^= _frameBuffer2[offs];
+				}
+			}
+		}
+	}
+
+	switch (_scaleMode) {
+	case S_INTERLACED:
+		for (int cy = 0; cy < _curHeight; cy++) {
+			memcpy(&_scaledBuffer[2 * cy * _videoInfo.width], &_frameBuffer1[cy * _videoInfo.width], _videoInfo.width);
+			memset(&_scaledBuffer[((2 * cy) + 1) * _videoInfo.width], 0, _videoInfo.width);
+		}
+		_videoFrameBuffer = _scaledBuffer;
+		break;
+	case S_DOUBLE:
+		for (int cy = 0; cy < _curHeight; cy++) {
+			memcpy(&_scaledBuffer[2 * cy * _videoInfo.width], &_frameBuffer1[cy * _videoInfo.width], _videoInfo.width);
+			memcpy(&_scaledBuffer[((2 * cy) + 1) * _videoInfo.width], &_frameBuffer1[cy * _videoInfo.width], _videoInfo.width);
+		}
+		_videoFrameBuffer = _scaledBuffer;
+		break;
+	case S_NONE:
+		_videoFrameBuffer = _frameBuffer1;
+		break;
+	}
+
+	return ++_videoInfo.currentFrame < _videoInfo.frameCount;
+}
+
+} // End of namespace Graphics


Property changes on: scummvm/trunk/graphics/video/dxa_decoder.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Copied: scummvm/trunk/graphics/video/dxa_decoder.h (from rev 40752, scummvm/trunk/graphics/video/dxa_player.h)
===================================================================
--- scummvm/trunk/graphics/video/dxa_decoder.h	                        (rev 0)
+++ scummvm/trunk/graphics/video/dxa_decoder.h	2009-05-21 13:02:56 UTC (rev 40759)
@@ -0,0 +1,89 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/**
+ * Video decoder used in engines:
+ *  - agos
+ *  - sword1
+ *  - sword2
+ */
+
+#ifndef GRAPHICS_VIDEO_DXA_PLAYER_H
+#define GRAPHICS_VIDEO_DXA_PLAYER_H
+
+#include "graphics/video/video_player.h"
+
+namespace Graphics {
+
+class DXADecoder : public VideoDecoder {
+public:
+	DXADecoder();
+	virtual ~DXADecoder();
+
+	/**
+	 * Load a DXA encoded video file
+	 * @param filename	the filename to load
+	 */
+	bool loadFile(const char *fileName);
+
+	/**
+	 * Close a DXA encoded video file
+	 */
+	void closeFile();
+
+	bool decodeNextFrame();
+
+	/**
+	 * Get the sound chunk tag of the loaded DXA file
+	 */
+	uint32 getSoundTag() { return _soundTag; }
+
+private:
+	void decodeZlib(byte *data, int size, int totalSize);
+	void decode12(int size);
+	void decode13(int size);
+
+	enum ScaleMode {
+		S_NONE,
+		S_INTERLACED,
+		S_DOUBLE
+	};
+
+	byte *_frameBuffer1;
+	byte *_frameBuffer2;
+	byte *_scaledBuffer;
+	byte *_inBuffer;
+	uint32 _inBufferSize;
+	byte *_decompBuffer;
+	uint32 _decompBufferSize;
+	uint16 _curHeight;
+	uint32 _frameSize;
+	ScaleMode _scaleMode;
+	uint32 _soundTag;
+};
+
+} // End of namespace Graphics
+
+#endif


Property changes on: scummvm/trunk/graphics/video/dxa_decoder.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Deleted: scummvm/trunk/graphics/video/dxa_player.cpp
===================================================================
--- scummvm/trunk/graphics/video/dxa_player.cpp	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/graphics/video/dxa_player.cpp	2009-05-21 13:02:56 UTC (rev 40759)
@@ -1,563 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/debug.h"
-#include "common/endian.h"
-#include "common/archive.h"
-#include "common/system.h"
-#include "common/util.h"
-
-#include "graphics/video/dxa_player.h"
-
-#ifdef USE_ZLIB
-  #include "common/zlib.h"
-#endif
-
-namespace Graphics {
-
-DXADecoder::DXADecoder() {
-	_fileStream = 0;
-
-	_frameBuffer1 = 0;
-	_frameBuffer2 = 0;
-	_scaledBuffer = 0;
-	_videoFrameBuffer = 0;
-
-	_inBuffer = 0;
-	_inBufferSize = 0;
-
-	_decompBuffer = 0;
-	_decompBufferSize = 0;
-
-	_videoInfo.width = 0;
-	_videoInfo.height = 0;
-
-	_frameSize = 0;
-	_videoInfo.frameCount = 0;
-	_videoInfo.currentFrame = 0;
-	_videoInfo.frameRate = 0;
-	_videoInfo.frameDelay = 0;
-
-	_scaleMode = S_NONE;
-}
-
-DXADecoder::~DXADecoder() {
-	closeFile();
-}
-
-bool DXADecoder::loadFile(const char *fileName) {
-	uint32 tag;
-	int32 frameRate;
-
-	closeFile();
-
-	_fileStream = SearchMan.createReadStreamForMember(fileName);
-	if (!_fileStream)
-		return false;
-
-	tag = _fileStream->readUint32BE();
-	assert(tag == MKID_BE('DEXA'));
-
-	uint8 flags = _fileStream->readByte();
-	_videoInfo.frameCount = _fileStream->readUint16BE();
-	frameRate = _fileStream->readSint32BE();
-
-	if (frameRate > 0) {
-		_videoInfo.frameRate = 1000 / frameRate;
-		_videoInfo.frameDelay = frameRate * 100;
-	} else if (frameRate < 0) {
-		_videoInfo.frameRate = 100000 / (-frameRate);
-		_videoInfo.frameDelay = -frameRate;
-	} else {
-		_videoInfo.frameRate = 10;
-		_videoInfo.frameDelay = 10000;
-	}
-
-	_videoInfo.width = _fileStream->readUint16BE();
-	_videoInfo.height = _fileStream->readUint16BE();
-
-	if (flags & 0x80) {
-		_scaleMode = S_INTERLACED;
-		_curHeight = _videoInfo.height / 2;
-	} else if (flags & 0x40) {
-		_scaleMode = S_DOUBLE;
-		_curHeight = _videoInfo.height / 2;
-	} else {
-		_scaleMode = S_NONE;
-		_curHeight = _videoInfo.height;
-	}
-
-	debug(2, "flags 0x0%x framesCount %d width %d height %d rate %d ticks %d", flags, getFrameCount(), getWidth(), getHeight(), getFrameRate(), getFrameDelay());
-
-	_frameSize = _videoInfo.width * _videoInfo.height;
-	_decompBufferSize = _frameSize;
-	_frameBuffer1 = (uint8 *)malloc(_frameSize);
-	memset(_frameBuffer1, 0, _frameSize);
-	_frameBuffer2 = (uint8 *)malloc(_frameSize);
-	memset(_frameBuffer2, 0, _frameSize);
-	if (!_frameBuffer1 || !_frameBuffer2)
-		error("DXADecoder: Error allocating frame buffers (size %u)", _frameSize);
-
-	_scaledBuffer = 0;
-	if (_scaleMode != S_NONE) {
-		_scaledBuffer = (uint8 *)malloc(_frameSize);
-		memset(_scaledBuffer, 0, _frameSize);
-		if (!_scaledBuffer)
-			error("Error allocating scale buffer (size %u)", _frameSize);
-	}
-
-#ifdef DXA_EXPERIMENT_MAXD
-	// Check for an extended header
-	if (flags & 1) {
-		uint32 size;
-
-		do {
-			tag = _fileStream->readUint32BE();
-			if (tag != 0) {
-				size = _fileStream->readUint32BE();
-			}
-			switch (tag) {
-				case 0: // No more tags
-					break;
-				case MKID_BE('MAXD'):
-					assert(size == 4);
-					_decompBufferSize = _fileStream->readUint32BE();
-					break;
-				default: // Unknown tag - skip it.
-					while (size > 0) {
-						byte dummy = _fileStream->readByte();
-						size--;
-					}
-					break;
-			}
-		} while (tag != 0);
-	}
-#endif
-	
-	// Read the sound header
-	_soundTag = _fileStream->readUint32BE();
-
-	_videoInfo.currentFrame = 0;
-
-	_videoInfo.firstframeOffset = _fileStream->pos();
-
-	return true;
-}
-
-void DXADecoder::closeFile() {
-	if (!_fileStream)
-		return;
-
-	delete _fileStream;
-	_fileStream = 0;
-
-	free(_frameBuffer1);
-	free(_frameBuffer2);
-	free(_scaledBuffer);
-	free(_inBuffer);
-	free(_decompBuffer);
-
-	_inBuffer = 0;
-	_decompBuffer = 0;
-}
-
-void DXADecoder::decodeZlib(byte *data, int size, int totalSize) {
-#ifdef USE_ZLIB
-	unsigned long dstLen = totalSize;
-	Common::uncompress(data, &dstLen, _inBuffer, size);
-#endif
-}
-
-#define BLOCKW 4
-#define BLOCKH 4
-
-void DXADecoder::decode12(int size) {
-#ifdef USE_ZLIB
-	if (_decompBuffer == NULL) {
-		_decompBuffer = (byte *)malloc(_decompBufferSize);
-		memset(_decompBuffer, 0, _decompBufferSize);
-		if (_decompBuffer == NULL)
-			error("Error allocating decomp buffer (size %u)", _decompBufferSize);
-	}
-	/* decompress the input data */
-	decodeZlib(_decompBuffer, size, _decompBufferSize);
-
-	byte *dat = _decompBuffer;
-
-	memcpy(_frameBuffer2, _frameBuffer1, _frameSize);
-
-	for (uint32 by = 0; by < _videoInfo.height; by += BLOCKH) {
-		for (uint32 bx = 0; bx < _videoInfo.width; bx += BLOCKW) {
-			byte type = *dat++;
-			byte *b2 = _frameBuffer1 + bx + by * _videoInfo.width;
-
-			switch (type) {
-			case 0:
-				break;
-			case 10:
-			case 11:
-			case 12:
-			case 13:
-			case 14:
-			case 15:
-			case 1:	{
-				unsigned short diffMap;
-				if (type >= 10 && type <= 15) {
-					static const struct { uint8 sh1, sh2; } shiftTbl[6] = {
-						{0, 0},	{8, 0},	{8, 8},	{8, 4},	{4, 0},	{4, 4}
-					};
-					diffMap = ((*dat & 0xF0) << shiftTbl[type-10].sh1) |
-						  ((*dat & 0x0F) << shiftTbl[type-10].sh2);
-					dat++;
-				} else {
-					diffMap = *(unsigned short*)dat;
-					dat += 2;
-				}
-
-				for (int yc = 0; yc < BLOCKH; yc++) {
-					for (int xc = 0; xc < BLOCKW; xc++) {
-						if (diffMap & 0x8000) {
-							b2[xc] = *dat++;
-						}
-						diffMap <<= 1;
-					}
-					b2 += _videoInfo.width;
-				}
-				break;
-			}
-			case 2:	{
-				byte color = *dat++;
-
-				for (int yc = 0; yc < BLOCKH; yc++) {
-					for (int xc = 0; xc < BLOCKW; xc++) {
-						b2[xc] = color;
-					}
-					b2 += _videoInfo.width;
-				}
-				break;
-			}
-			case 3:	{
-				for (int yc = 0; yc < BLOCKH; yc++) {
-					for (int xc = 0; xc < BLOCKW; xc++) {
-						b2[xc] = *dat++;
-					}
-					b2 += _videoInfo.width;
-				}
-				break;
-			}
-			case 4:	{
-				byte mbyte = *dat++;
-				int mx = (mbyte >> 4) & 0x07;
-				if (mbyte & 0x80)
-					mx = -mx;
-				int my = mbyte & 0x07;
-				if (mbyte & 0x08)
-					my = -my;
-				byte *b1 = _frameBuffer2 + (bx+mx) + (by+my) * _videoInfo.width;
-				for (int yc = 0; yc < BLOCKH; yc++) {
-					memcpy(b2, b1, BLOCKW);
-					b1 += _videoInfo.width;
-					b2 += _videoInfo.width;
-				}
-				break;
-			}
-			case 5:
-				break;
-			default:
-				error("decode12: Unknown type %d", type);
-			}
-		}
-	}
-#endif
-}
-
-void DXADecoder::decode13(int size) {
-#ifdef USE_ZLIB
-	uint8 *codeBuf, *dataBuf, *motBuf, *maskBuf;
-
-	if (_decompBuffer == NULL) {
-		_decompBuffer = (byte *)malloc(_decompBufferSize);
-		memset(_decompBuffer, 0, _decompBufferSize);
-		if (_decompBuffer == NULL)
-			error("Error allocating decomp buffer (size %u)", _decompBufferSize);
-	}
-
-	/* decompress the input data */
-	decodeZlib(_decompBuffer, size, _decompBufferSize);
-
-	memcpy(_frameBuffer2, _frameBuffer1, _frameSize);
-
-	int codeSize = _videoInfo.width * _curHeight / 16;
-	int dataSize, motSize, maskSize;
-
-	dataSize = READ_BE_UINT32(&_decompBuffer[0]);
-	motSize  = READ_BE_UINT32(&_decompBuffer[4]);
-	maskSize = READ_BE_UINT32(&_decompBuffer[8]);
-
-	codeBuf = &_decompBuffer[12];
-	dataBuf = &codeBuf[codeSize];
-	motBuf = &dataBuf[dataSize];
-	maskBuf = &motBuf[motSize];
-
-	for (uint32 by = 0; by < _curHeight; by += BLOCKH) {
-		for (uint32 bx = 0; bx < _videoInfo.width; bx += BLOCKW) {
-			uint8 type = *codeBuf++;
-			uint8 *b2 = (uint8*)_frameBuffer1 + bx + by * _videoInfo.width;
-
-			switch (type) {
-			case 0:
-				break;
-
-			case 1: {
-				uint16 diffMap = READ_BE_UINT16(maskBuf);
-				maskBuf += 2;
-
-				for (int yc = 0; yc < BLOCKH; yc++) {
-					for (int xc = 0; xc < BLOCKW; xc++) {
-						if (diffMap & 0x8000) {
-							b2[xc] = *dataBuf++;
-						}
-						diffMap <<= 1;
-					}
-					b2 += _videoInfo.width;
-				}
-				break;
-			}
-			case 2: {
-				uint8 color = *dataBuf++;
-
-				for (int yc = 0; yc < BLOCKH; yc++) {
-					for (int xc = 0; xc < BLOCKW; xc++) {
-						b2[xc] = color;
-					}
-					b2 += _videoInfo.width;
-				}
-				break;
-			}
-			case 3: {
-				for (int yc = 0; yc < BLOCKH; yc++) {
-					for (int xc = 0; xc < BLOCKW; xc++) {
-						b2[xc] = *dataBuf++;
-					}
-					b2 += _videoInfo.width;
-				}
-				break;
-			}
-			case 4: {
-				uint8 mbyte = *motBuf++;
-
-				int mx = (mbyte >> 4) & 0x07;
-				if (mbyte & 0x80)
-					mx = -mx;
-				int my = mbyte & 0x07;
-				if (mbyte & 0x08)
-					my = -my;
-
-				uint8 *b1 = (uint8*)_frameBuffer2 + (bx+mx) + (by+my) * _videoInfo.width;
-				for (int yc = 0; yc < BLOCKH; yc++) {
-					memcpy(b2, b1, BLOCKW);
-					b1 += _videoInfo.width;
-					b2 += _videoInfo.width;
-				}
-				break;
-			}
-			case 8: {
-				static const int subX[4] = {0, 2, 0, 2};
-				static const int subY[4] = {0, 0, 2, 2};
-
-				uint8 subMask = *maskBuf++;
-
-				for (int subBlock = 0; subBlock < 4; subBlock++) {
-					int sx = bx + subX[subBlock], sy = by + subY[subBlock];
-					b2 = (uint8*)_frameBuffer1 + sx + sy * _videoInfo.width;
-					switch (subMask & 0xC0) {
-					// 00: skip
-					case 0x00:
-						break;
-					// 01: solid color
-					case 0x40: {
-						uint8 subColor = *dataBuf++;
-						for (int yc = 0; yc < BLOCKH / 2; yc++) {
-							for (int xc = 0; xc < BLOCKW / 2; xc++) {
-								b2[xc] = subColor;
-							}
-							b2 += _videoInfo.width;
-						}
-						break;
-					}
-					// 02: motion vector
-					case 0x80: {
-						uint8 mbyte = *motBuf++;
-
-						int mx = (mbyte >> 4) & 0x07;
-						if (mbyte & 0x80)
-							mx = -mx;
-
-						int my = mbyte & 0x07;
-						if (mbyte & 0x08)
-							my = -my;
-
-						uint8 *b1 = (uint8*)_frameBuffer2 + (sx+mx) + (sy+my) * _videoInfo.width;
-						for (int yc = 0; yc < BLOCKH / 2; yc++) {
-							memcpy(b2, b1, BLOCKW / 2);
-							b1 += _videoInfo.width;
-							b2 += _videoInfo.width;
-						}
-						break;
-					}
-					// 03: raw
-					case 0xC0:
-						for (int yc = 0; yc < BLOCKH / 2; yc++) {
-							for (int xc = 0; xc < BLOCKW / 2; xc++) {
-								b2[xc] = *dataBuf++;
-							}
-							b2 += _videoInfo.width;
-						}
-						break;
-					}
-					subMask <<= 2;
-				}
-				break;
-			}
-			case 32:
-			case 33:
-			case 34: {
-				int count = type - 30;
-				uint8 pixels[4];
-
-				memcpy(pixels, dataBuf, count);
-				dataBuf += count;
-
-				if (count == 2) {
-					uint16 code = READ_BE_UINT16(maskBuf);
-					maskBuf += 2;
-					for (int yc = 0; yc < BLOCKH; yc++) {
-						for (int xc = 0; xc < BLOCKW; xc++) {
-							b2[xc] = pixels[code & 1];
-							code >>= 1;
-						}
-						b2 += _videoInfo.width;
-					}
-				} else {
-					uint32 code = READ_BE_UINT32(maskBuf);
-					maskBuf += 4;
-					for (int yc = 0; yc < BLOCKH; yc++) {
-						for (int xc = 0; xc < BLOCKW; xc++) {
-							b2[xc] = pixels[code & 3];
-							code >>= 2;
-						}
-						b2 += _videoInfo.width;
-					}
-				}
-				break;
-			}
-			default:
-				error("decode13: Unknown type %d", type);
-			}
-		}
-	}
-#endif
-}
-
-bool DXADecoder::decodeNextFrame() {
-	uint32 tag;
-
-	if (_videoInfo.currentFrame == 0)
-		_videoInfo.startTime = g_system->getMillis();
-
-	tag = _fileStream->readUint32BE();
-	if (tag == MKID_BE('CMAP')) {
-		byte rgb[768];
-
-		_fileStream->read(rgb, ARRAYSIZE(rgb));
-		setPalette(rgb);
-	}
-
-	tag = _fileStream->readUint32BE();
-	if (tag == MKID_BE('FRAM')) {
-		byte type = _fileStream->readByte();
-		uint32 size = _fileStream->readUint32BE();
-		if ((_inBuffer == NULL) || (_inBufferSize < size)) {
-			free(_inBuffer);
-			_inBuffer = (byte *)malloc(size);
-			memset(_inBuffer, 0, size);
-			if (_inBuffer == NULL)
-				error("Error allocating input buffer (size %u)", size);
-			_inBufferSize = size;
-		}
-
-		_fileStream->read(_inBuffer, size);
-
-		switch (type) {
-		case 2:
-			decodeZlib(_frameBuffer1, size, _frameSize);
-			break;
-		case 3:
-			decodeZlib(_frameBuffer2, size, _frameSize);
-			break;
-		case 12:
-			decode12(size);
-			break;
-		case 13:
-			decode13(size);
-			break;
-		default:
-			error("decodeFrame: Unknown compression type %d", type);
-		}
-
-		if (type == 3) {
-			for (uint32 j = 0; j < _curHeight; ++j) {
-				for (uint32 i = 0; i < _videoInfo.width; ++i) {
-					const int offs = j * _videoInfo.width + i;
-					_frameBuffer1[offs] ^= _frameBuffer2[offs];
-				}
-			}
-		}
-	}
-
-	switch (_scaleMode) {
-	case S_INTERLACED:
-		for (int cy = 0; cy < _curHeight; cy++) {
-			memcpy(&_scaledBuffer[2 * cy * _videoInfo.width], &_frameBuffer1[cy * _videoInfo.width], _videoInfo.width);
-			memset(&_scaledBuffer[((2 * cy) + 1) * _videoInfo.width], 0, _videoInfo.width);
-		}
-		_videoFrameBuffer = _scaledBuffer;
-		break;
-	case S_DOUBLE:
-		for (int cy = 0; cy < _curHeight; cy++) {
-			memcpy(&_scaledBuffer[2 * cy * _videoInfo.width], &_frameBuffer1[cy * _videoInfo.width], _videoInfo.width);
-			memcpy(&_scaledBuffer[((2 * cy) + 1) * _videoInfo.width], &_frameBuffer1[cy * _videoInfo.width], _videoInfo.width);
-		}
-		_videoFrameBuffer = _scaledBuffer;
-		break;
-	case S_NONE:
-		_videoFrameBuffer = _frameBuffer1;
-		break;
-	}
-
-	return ++_videoInfo.currentFrame < _videoInfo.frameCount;
-}
-
-} // End of namespace Graphics

Deleted: scummvm/trunk/graphics/video/dxa_player.h
===================================================================
--- scummvm/trunk/graphics/video/dxa_player.h	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/graphics/video/dxa_player.h	2009-05-21 13:02:56 UTC (rev 40759)
@@ -1,89 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-/**
- * Video decoder used in engines:
- *  - agos
- *  - sword1
- *  - sword2
- */
-
-#ifndef GRAPHICS_VIDEO_DXA_PLAYER_H
-#define GRAPHICS_VIDEO_DXA_PLAYER_H
-
-#include "graphics/video/video_player.h"
-
-namespace Graphics {
-
-class DXADecoder : public VideoDecoder {
-public:
-	DXADecoder();
-	virtual ~DXADecoder();
-
-	/**
-	 * Load a DXA encoded video file
-	 * @param filename	the filename to load
-	 */
-	bool loadFile(const char *fileName);
-
-	/**
-	 * Close a DXA encoded video file
-	 */
-	void closeFile();
-
-	bool decodeNextFrame();
-
-	/**
-	 * Get the sound chunk tag of the loaded DXA file
-	 */
-	uint32 getSoundTag() { return _soundTag; }
-
-private:
-	void decodeZlib(byte *data, int size, int totalSize);
-	void decode12(int size);
-	void decode13(int size);
-
-	enum ScaleMode {
-		S_NONE,
-		S_INTERLACED,
-		S_DOUBLE
-	};
-
-	byte *_frameBuffer1;
-	byte *_frameBuffer2;
-	byte *_scaledBuffer;
-	byte *_inBuffer;
-	uint32 _inBufferSize;
-	byte *_decompBuffer;
-	uint32 _decompBufferSize;
-	uint16 _curHeight;
-	uint32 _frameSize;
-	ScaleMode _scaleMode;
-	uint32 _soundTag;
-};
-
-} // End of namespace Graphics
-
-#endif

Copied: scummvm/trunk/graphics/video/flic_decoder.cpp (from rev 40752, scummvm/trunk/graphics/video/flic_player.cpp)
===================================================================
--- scummvm/trunk/graphics/video/flic_decoder.cpp	                        (rev 0)
+++ scummvm/trunk/graphics/video/flic_decoder.cpp	2009-05-21 13:02:56 UTC (rev 40759)
@@ -0,0 +1,312 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "graphics/video/flic_decoder.h"
+#include "common/archive.h"
+#include "common/stream.h"
+#include "common/endian.h"
+#include "common/system.h"
+
+namespace Graphics {
+
+FlicDecoder::FlicDecoder() {
+	_paletteChanged = false;
+	_fileStream = 0;
+	_videoFrameBuffer = 0;
+	memset(&_videoInfo, 0, sizeof(_videoInfo));
+}
+
+FlicDecoder::~FlicDecoder() {
+	closeFile();
+}
+
+bool FlicDecoder::loadFile(const char *fileName) {
+	closeFile();
+
+	_fileStream = SearchMan.createReadStreamForMember(fileName);
+	if (!_fileStream)
+		return false;
+
+	/* uint32 frameSize = */ _fileStream->readUint32LE();
+	uint16 frameType = _fileStream->readUint16LE();
+
+	// Check FLC magic number
+	if (frameType != 0xAF12) {
+		warning("FlicDecoder::FlicDecoder(): attempted to load non-FLC data (type = 0x%04X)", frameType);
+		delete _fileStream;
+		_fileStream = 0;
+		return false;
+	}
+
+	_videoInfo.frameCount = _fileStream->readUint16LE();
+	_videoInfo.width = _fileStream->readUint16LE();
+	_videoInfo.height = _fileStream->readUint16LE();
+	uint16 colorDepth = _fileStream->readUint16LE();
+	if (colorDepth != 8) {
+		warning("FlicDecoder::FlicDecoder(): attempted to load an FLC with a palette of color depth %d. Only 8-bit color palettes are supported", frameType);
+		delete _fileStream;
+		_fileStream = 0;
+		return false;
+	}
+	_fileStream->readUint16LE();	// flags
+	// Note: The normal delay is a 32-bit integer (dword), whereas the overriden delay is a 16-bit integer (word)
+	// frameDelay is the FLIC "speed", in milliseconds. Our frameDelay is calculated in 1/100 ms, so we convert it here
+	_videoInfo.frameDelay = 100 * _fileStream->readUint32LE();
+	_videoInfo.frameRate = 100 * 1000 / _videoInfo.frameDelay;
+
+	_fileStream->seek(80);
+	_offsetFrame1 = _fileStream->readUint32LE();
+	_offsetFrame2 = _fileStream->readUint32LE();
+
+	_videoFrameBuffer = new byte[_videoInfo.width * _videoInfo.height];
+	_palette = (byte *)malloc(3 * 256);
+	memset(_palette, 0, 3 * 256);
+	_paletteChanged = false;
+
+	// Seek to the first frame
+	_videoInfo.currentFrame = 0;
+	_fileStream->seek(_offsetFrame1);
+	return true;
+}
+
+void FlicDecoder::closeFile() {
+	if (!_fileStream)
+		return;
+
+	delete _fileStream;
+	_fileStream = 0;
+
+	delete[] _videoFrameBuffer;
+	_videoFrameBuffer = 0;
+
+	free(_palette);
+
+	_dirtyRects.clear();
+}
+
+void FlicDecoder::decodeByteRun(uint8 *data) {
+	byte *ptr = (uint8 *)_videoFrameBuffer;
+	while ((uint32)(ptr - _videoFrameBuffer) < (_videoInfo.width * _videoInfo.height)) {
+		int chunks = *data++;
+		while (chunks--) {
+			int count = (int8)*data++;
+			if (count > 0) {
+				memset(ptr, *data++, count);
+			} else {
+				count = -count;
+				memcpy(ptr, data, count);
+				data += count;
+			}
+			ptr += count;
+		}
+	}
+
+	// Redraw
+	_dirtyRects.clear();
+	_dirtyRects.push_back(Common::Rect(0, 0, _videoInfo.width, _videoInfo.height));
+}
+
+#define OP_PACKETCOUNT   0
+#define OP_UNDEFINED     1
+#define OP_LASTPIXEL     2
+#define OP_LINESKIPCOUNT 3
+
+void FlicDecoder::decodeDeltaFLC(uint8 *data) {
+	uint16 linesInChunk = READ_LE_UINT16(data); data += 2;
+	uint16 currentLine = 0;
+	uint16 packetCount = 0;
+
+	while (linesInChunk--) {
+		uint16 opcode;
+
+		// First process all the opcodes.
+		do {
+			opcode = READ_LE_UINT16(data); data += 2;
+
+			switch ((opcode >> 14) & 3) {
+			case OP_PACKETCOUNT:
+				packetCount = opcode;
+				break;
+			case OP_UNDEFINED:
+				break;
+			case OP_LASTPIXEL:
+				_videoFrameBuffer[currentLine * _videoInfo.width + _videoInfo.width - 1] = (opcode & 0xFF);
+				_dirtyRects.push_back(Common::Rect(_videoInfo.width - 1, currentLine, _videoInfo.width, currentLine + 1));
+				break;
+			case OP_LINESKIPCOUNT:
+				currentLine += -(int16)opcode;
+				break;
+			}
+		} while (((opcode >> 14) & 3) != OP_PACKETCOUNT);
+
+		uint16 column = 0;
+
+		// Now interpret the RLE data
+		while (packetCount--) {
+			column += *data++;
+			int rleCount = (int8)*data++;
+			if (rleCount > 0) {
+				memcpy(_videoFrameBuffer + (currentLine * _videoInfo.width) + column, data, rleCount * 2);
+				data += rleCount * 2;
+				_dirtyRects.push_back(Common::Rect(column, currentLine, column + rleCount * 2, currentLine + 1));
+			} else if (rleCount < 0) {
+				rleCount = -rleCount;
+				uint16 dataWord = READ_UINT16(data); data += 2;
+				for (int i = 0; i < rleCount; ++i) {
+					WRITE_UINT16(_videoFrameBuffer + currentLine * _videoInfo.width + column + i * 2, dataWord);
+				}
+				_dirtyRects.push_back(Common::Rect(column, currentLine, column + rleCount * 2, currentLine + 1));
+			} else { // End of cutscene ?
+				return;
+			}
+			column += rleCount * 2;
+		}
+
+		currentLine++;
+	}
+}
+
+#define FLI_SETPAL 4
+#define FLI_SS2    7
+#define FLI_BRUN   15
+#define PSTAMP     18
+#define FRAME_TYPE 0xF1FA
+
+bool FlicDecoder::decodeNextFrame() {
+	if (_videoInfo.currentFrame == 0)
+		_videoInfo.startTime = g_system->getMillis();
+
+	// Read chunk
+	uint32 frameSize = _fileStream->readUint32LE();
+	uint16 frameType = _fileStream->readUint16LE();
+	uint16 chunkCount = 0;
+
+	switch (frameType) {
+	case FRAME_TYPE: {
+		chunkCount = _fileStream->readUint16LE();
+		// Note: The overriden delay is a 16-bit integer (word), whereas the normal delay is a 32-bit integer (dword)
+		// frameDelay is the FLIC "speed", in milliseconds. Our frameDelay is calculated in 1/100 ms, so we convert it here
+		uint16 newFrameDelay = _fileStream->readUint16LE();	// "speed", in milliseconds
+		if (newFrameDelay > 0) {
+			_videoInfo.frameDelay = 100 * newFrameDelay;
+			_videoInfo.frameRate = 100 * 1000 / _videoInfo.frameDelay;
+		}
+		_fileStream->readUint16LE();	// reserved, always 0
+		uint16 newWidth = _fileStream->readUint16LE();
+		uint16 newHeight = _fileStream->readUint16LE();
+		if (newWidth > 0)
+			_videoInfo.width = newWidth;
+		if (newHeight > 0)
+			_videoInfo.height = newHeight;
+
+		_videoInfo.currentFrame++;
+		}
+		break;
+	default:
+		error("FlicDecoder::decodeFrame(): unknown main chunk type (type = 0x%02X)", frameType);
+		break;
+	 }
+
+	// Read subchunks
+	if (frameType == FRAME_TYPE) {
+		for (uint32 i = 0; i < chunkCount; ++i) {
+			frameSize = _fileStream->readUint32LE();
+			frameType = _fileStream->readUint16LE();
+			uint8 *data = new uint8[frameSize - 6];
+			_fileStream->read(data, frameSize - 6);
+			switch (frameType) {
+			case FLI_SETPAL:
+				unpackPalette(data);
+				setPalette(_palette);
+				_paletteChanged = true;
+				break;
+			case FLI_SS2:
+				decodeDeltaFLC(data);
+				break;
+			case FLI_BRUN:
+				decodeByteRun(data);
+				break;
+			case PSTAMP:
+				/* PSTAMP - skip for now */
+				break;
+			default:
+				error("FlicDecoder::decodeFrame(): unknown subchunk type (type = 0x%02X)", frameType);
+				break;
+			 }
+
+			delete[] data;
+		}
+	}
+
+	// If we just processed the ring frame, set the next frame
+	if (_videoInfo.currentFrame == _videoInfo.frameCount + 1) {
+		_videoInfo.currentFrame = 1;
+		_fileStream->seek(_offsetFrame2);
+	}
+
+	return _videoInfo.currentFrame < _videoInfo.frameCount;
+}
+
+void FlicDecoder::reset() {
+	_videoInfo.currentFrame = 0;
+	_fileStream->seek(_offsetFrame1);
+}
+
+void FlicDecoder::unpackPalette(uint8 *data) {
+	uint16 numPackets = READ_LE_UINT16(data); data += 2;
+
+	if (0 == READ_LE_UINT16(data)) { //special case
+		data += 2;
+		for (int i = 0; i < 256; ++i) {
+			memcpy(_palette + i * 3, data + i * 3, 3);
+		}
+	} else {
+		uint8 palPos = 0;
+
+		while (numPackets--) {
+			palPos += *data++;
+			uint8 change = *data++;
+
+			for (int i = 0; i < change; ++i) {
+				memcpy(_palette + (palPos + i) * 3, data + i * 3, 3);
+			}
+
+			palPos += change;
+			data += (change * 3);
+		}
+	}
+}
+
+void FlicDecoder::copyDirtyRectsToBuffer(uint8 *dst, uint pitch) {
+	for (Common::List<Common::Rect>::const_iterator it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
+		for (int y = (*it).top; y < (*it).bottom; ++y) {
+			const int x = (*it).left;
+			memcpy(dst + y * pitch + x, _videoFrameBuffer + y * _videoInfo.width + x, (*it).right - x);
+		}
+	}
+	_dirtyRects.clear();
+}
+
+} // End of namespace Graphics


Property changes on: scummvm/trunk/graphics/video/flic_decoder.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Copied: scummvm/trunk/graphics/video/flic_decoder.h (from rev 40752, scummvm/trunk/graphics/video/flic_player.h)
===================================================================
--- scummvm/trunk/graphics/video/flic_decoder.h	                        (rev 0)
+++ scummvm/trunk/graphics/video/flic_decoder.h	2009-05-21 13:02:56 UTC (rev 40759)
@@ -0,0 +1,89 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/**
+ * Video decoder used in engines:
+ *  - tucker
+ */
+
+#ifndef GRAPHICS_VIDEO_FlicDecoder_H
+#define GRAPHICS_VIDEO_FlicDecoder_H
+
+#include "graphics/video/video_player.h"
+#include "common/list.h"
+#include "common/rect.h"
+
+namespace Common {
+	class SeekableReadStream;
+}
+
+namespace Graphics {
+
+class FlicDecoder : public VideoDecoder {
+public:
+	FlicDecoder();
+	virtual ~FlicDecoder();
+
+	/**
+	 * Load a FLIC encoded video file
+	 * @param filename	the filename to load
+	 */
+	bool loadFile(const char *fileName);
+
+	/**
+	 * Close a FLIC encoded video file
+	 */
+	void closeFile();
+
+	/**
+	 * Decode the next frame
+	 */
+	bool decodeNextFrame();
+
+	const Common::List<Common::Rect> *getDirtyRects() const { return &_dirtyRects; }
+	void clearDirtyRects() { _dirtyRects.clear(); }
+	void copyDirtyRectsToBuffer(uint8 *dst, uint pitch);
+
+	const byte *getPalette() { _paletteChanged = false; return _palette; }
+	bool paletteChanged() { return _paletteChanged; }
+	void reset();
+
+private:
+	uint16 _offsetFrame1;
+	uint16 _offsetFrame2;
+	byte *_palette;
+	bool _paletteChanged;
+
+	void decodeByteRun(uint8 *data);
+	void decodeDeltaFLC(uint8 *data);
+	void unpackPalette(uint8 *mem);
+
+	Common::List<Common::Rect> _dirtyRects;
+
+};
+
+} // End of namespace Graphics
+
+#endif


Property changes on: scummvm/trunk/graphics/video/flic_decoder.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Deleted: scummvm/trunk/graphics/video/flic_player.cpp
===================================================================
--- scummvm/trunk/graphics/video/flic_player.cpp	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/graphics/video/flic_player.cpp	2009-05-21 13:02:56 UTC (rev 40759)
@@ -1,312 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "graphics/video/flic_player.h"
-#include "common/archive.h"
-#include "common/stream.h"
-#include "common/endian.h"
-#include "common/system.h"
-
-namespace Graphics {
-
-FlicDecoder::FlicDecoder() {
-	_paletteChanged = false;
-	_fileStream = 0;
-	_videoFrameBuffer = 0;
-	memset(&_videoInfo, 0, sizeof(_videoInfo));
-}
-
-FlicDecoder::~FlicDecoder() {
-	closeFile();
-}
-
-bool FlicDecoder::loadFile(const char *fileName) {
-	closeFile();
-
-	_fileStream = SearchMan.createReadStreamForMember(fileName);
-	if (!_fileStream)
-		return false;
-
-	/* uint32 frameSize = */ _fileStream->readUint32LE();
-	uint16 frameType = _fileStream->readUint16LE();
-
-	// Check FLC magic number
-	if (frameType != 0xAF12) {
-		warning("FlicDecoder::FlicDecoder(): attempted to load non-FLC data (type = 0x%04X)", frameType);
-		delete _fileStream;
-		_fileStream = 0;
-		return false;
-	}
-
-	_videoInfo.frameCount = _fileStream->readUint16LE();
-	_videoInfo.width = _fileStream->readUint16LE();
-	_videoInfo.height = _fileStream->readUint16LE();
-	uint16 colorDepth = _fileStream->readUint16LE();
-	if (colorDepth != 8) {
-		warning("FlicDecoder::FlicDecoder(): attempted to load an FLC with a palette of color depth %d. Only 8-bit color palettes are supported", frameType);
-		delete _fileStream;
-		_fileStream = 0;
-		return false;
-	}
-	_fileStream->readUint16LE();	// flags
-	// Note: The normal delay is a 32-bit integer (dword), whereas the overriden delay is a 16-bit integer (word)
-	// frameDelay is the FLIC "speed", in milliseconds. Our frameDelay is calculated in 1/100 ms, so we convert it here
-	_videoInfo.frameDelay = 100 * _fileStream->readUint32LE();
-	_videoInfo.frameRate = 100 * 1000 / _videoInfo.frameDelay;
-
-	_fileStream->seek(80);
-	_offsetFrame1 = _fileStream->readUint32LE();
-	_offsetFrame2 = _fileStream->readUint32LE();
-
-	_videoFrameBuffer = new byte[_videoInfo.width * _videoInfo.height];
-	_palette = (byte *)malloc(3 * 256);
-	memset(_palette, 0, 3 * 256);
-	_paletteChanged = false;
-
-	// Seek to the first frame
-	_videoInfo.currentFrame = 0;
-	_fileStream->seek(_offsetFrame1);
-	return true;
-}
-
-void FlicDecoder::closeFile() {
-	if (!_fileStream)
-		return;
-
-	delete _fileStream;
-	_fileStream = 0;
-
-	delete[] _videoFrameBuffer;
-	_videoFrameBuffer = 0;
-
-	free(_palette);
-
-	_dirtyRects.clear();
-}
-
-void FlicDecoder::decodeByteRun(uint8 *data) {
-	byte *ptr = (uint8 *)_videoFrameBuffer;
-	while ((uint32)(ptr - _videoFrameBuffer) < (_videoInfo.width * _videoInfo.height)) {
-		int chunks = *data++;
-		while (chunks--) {
-			int count = (int8)*data++;
-			if (count > 0) {
-				memset(ptr, *data++, count);
-			} else {
-				count = -count;
-				memcpy(ptr, data, count);
-				data += count;
-			}
-			ptr += count;
-		}
-	}
-
-	// Redraw
-	_dirtyRects.clear();
-	_dirtyRects.push_back(Common::Rect(0, 0, _videoInfo.width, _videoInfo.height));
-}
-
-#define OP_PACKETCOUNT   0
-#define OP_UNDEFINED     1
-#define OP_LASTPIXEL     2
-#define OP_LINESKIPCOUNT 3
-
-void FlicDecoder::decodeDeltaFLC(uint8 *data) {
-	uint16 linesInChunk = READ_LE_UINT16(data); data += 2;
-	uint16 currentLine = 0;
-	uint16 packetCount = 0;
-
-	while (linesInChunk--) {
-		uint16 opcode;
-
-		// First process all the opcodes.
-		do {
-			opcode = READ_LE_UINT16(data); data += 2;
-
-			switch ((opcode >> 14) & 3) {
-			case OP_PACKETCOUNT:
-				packetCount = opcode;
-				break;
-			case OP_UNDEFINED:
-				break;
-			case OP_LASTPIXEL:
-				_videoFrameBuffer[currentLine * _videoInfo.width + _videoInfo.width - 1] = (opcode & 0xFF);
-				_dirtyRects.push_back(Common::Rect(_videoInfo.width - 1, currentLine, _videoInfo.width, currentLine + 1));
-				break;
-			case OP_LINESKIPCOUNT:
-				currentLine += -(int16)opcode;
-				break;
-			}
-		} while (((opcode >> 14) & 3) != OP_PACKETCOUNT);
-
-		uint16 column = 0;
-
-		// Now interpret the RLE data
-		while (packetCount--) {
-			column += *data++;
-			int rleCount = (int8)*data++;
-			if (rleCount > 0) {
-				memcpy(_videoFrameBuffer + (currentLine * _videoInfo.width) + column, data, rleCount * 2);
-				data += rleCount * 2;
-				_dirtyRects.push_back(Common::Rect(column, currentLine, column + rleCount * 2, currentLine + 1));
-			} else if (rleCount < 0) {
-				rleCount = -rleCount;
-				uint16 dataWord = READ_UINT16(data); data += 2;
-				for (int i = 0; i < rleCount; ++i) {
-					WRITE_UINT16(_videoFrameBuffer + currentLine * _videoInfo.width + column + i * 2, dataWord);
-				}
-				_dirtyRects.push_back(Common::Rect(column, currentLine, column + rleCount * 2, currentLine + 1));
-			} else { // End of cutscene ?
-				return;
-			}
-			column += rleCount * 2;
-		}
-
-		currentLine++;
-	}
-}
-
-#define FLI_SETPAL 4
-#define FLI_SS2    7
-#define FLI_BRUN   15
-#define PSTAMP     18
-#define FRAME_TYPE 0xF1FA
-
-bool FlicDecoder::decodeNextFrame() {
-	if (_videoInfo.currentFrame == 0)
-		_videoInfo.startTime = g_system->getMillis();
-
-	// Read chunk
-	uint32 frameSize = _fileStream->readUint32LE();
-	uint16 frameType = _fileStream->readUint16LE();
-	uint16 chunkCount = 0;
-
-	switch (frameType) {
-	case FRAME_TYPE: {
-		chunkCount = _fileStream->readUint16LE();
-		// Note: The overriden delay is a 16-bit integer (word), whereas the normal delay is a 32-bit integer (dword)
-		// frameDelay is the FLIC "speed", in milliseconds. Our frameDelay is calculated in 1/100 ms, so we convert it here
-		uint16 newFrameDelay = _fileStream->readUint16LE();	// "speed", in milliseconds
-		if (newFrameDelay > 0) {
-			_videoInfo.frameDelay = 100 * newFrameDelay;
-			_videoInfo.frameRate = 100 * 1000 / _videoInfo.frameDelay;
-		}
-		_fileStream->readUint16LE();	// reserved, always 0
-		uint16 newWidth = _fileStream->readUint16LE();
-		uint16 newHeight = _fileStream->readUint16LE();
-		if (newWidth > 0)
-			_videoInfo.width = newWidth;
-		if (newHeight > 0)
-			_videoInfo.height = newHeight;
-
-		_videoInfo.currentFrame++;
-		}
-		break;
-	default:
-		error("FlicDecoder::decodeFrame(): unknown main chunk type (type = 0x%02X)", frameType);
-		break;
-	 }
-
-	// Read subchunks
-	if (frameType == FRAME_TYPE) {
-		for (uint32 i = 0; i < chunkCount; ++i) {
-			frameSize = _fileStream->readUint32LE();
-			frameType = _fileStream->readUint16LE();
-			uint8 *data = new uint8[frameSize - 6];
-			_fileStream->read(data, frameSize - 6);
-			switch (frameType) {
-			case FLI_SETPAL:
-				unpackPalette(data);
-				setPalette(_palette);
-				_paletteChanged = true;
-				break;
-			case FLI_SS2:
-				decodeDeltaFLC(data);
-				break;
-			case FLI_BRUN:
-				decodeByteRun(data);
-				break;
-			case PSTAMP:
-				/* PSTAMP - skip for now */
-				break;
-			default:
-				error("FlicDecoder::decodeFrame(): unknown subchunk type (type = 0x%02X)", frameType);
-				break;
-			 }
-
-			delete[] data;
-		}
-	}
-
-	// If we just processed the ring frame, set the next frame
-	if (_videoInfo.currentFrame == _videoInfo.frameCount + 1) {
-		_videoInfo.currentFrame = 1;
-		_fileStream->seek(_offsetFrame2);
-	}
-
-	return _videoInfo.currentFrame < _videoInfo.frameCount;
-}
-
-void FlicDecoder::reset() {
-	_videoInfo.currentFrame = 0;
-	_fileStream->seek(_offsetFrame1);
-}
-
-void FlicDecoder::unpackPalette(uint8 *data) {
-	uint16 numPackets = READ_LE_UINT16(data); data += 2;
-
-	if (0 == READ_LE_UINT16(data)) { //special case
-		data += 2;
-		for (int i = 0; i < 256; ++i) {
-			memcpy(_palette + i * 3, data + i * 3, 3);
-		}
-	} else {
-		uint8 palPos = 0;
-
-		while (numPackets--) {
-			palPos += *data++;
-			uint8 change = *data++;
-
-			for (int i = 0; i < change; ++i) {
-				memcpy(_palette + (palPos + i) * 3, data + i * 3, 3);
-			}
-
-			palPos += change;
-			data += (change * 3);
-		}
-	}
-}
-
-void FlicDecoder::copyDirtyRectsToBuffer(uint8 *dst, uint pitch) {
-	for (Common::List<Common::Rect>::const_iterator it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
-		for (int y = (*it).top; y < (*it).bottom; ++y) {
-			const int x = (*it).left;
-			memcpy(dst + y * pitch + x, _videoFrameBuffer + y * _videoInfo.width + x, (*it).right - x);
-		}
-	}
-	_dirtyRects.clear();
-}
-
-} // End of namespace Graphics

Deleted: scummvm/trunk/graphics/video/flic_player.h
===================================================================
--- scummvm/trunk/graphics/video/flic_player.h	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/graphics/video/flic_player.h	2009-05-21 13:02:56 UTC (rev 40759)
@@ -1,89 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-/**
- * Video decoder used in engines:
- *  - tucker
- */
-
-#ifndef GRAPHICS_VIDEO_FlicDecoder_H
-#define GRAPHICS_VIDEO_FlicDecoder_H
-
-#include "graphics/video/video_player.h"
-#include "common/list.h"
-#include "common/rect.h"
-
-namespace Common {
-	class SeekableReadStream;
-}
-
-namespace Graphics {
-
-class FlicDecoder : public VideoDecoder {
-public:
-	FlicDecoder();
-	virtual ~FlicDecoder();
-
-	/**
-	 * Load a FLIC encoded video file
-	 * @param filename	the filename to load
-	 */
-	bool loadFile(const char *fileName);
-
-	/**
-	 * Close a FLIC encoded video file
-	 */
-	void closeFile();
-
-	/**
-	 * Decode the next frame
-	 */
-	bool decodeNextFrame();
-
-	const Common::List<Common::Rect> *getDirtyRects() const { return &_dirtyRects; }
-	void clearDirtyRects() { _dirtyRects.clear(); }
-	void copyDirtyRectsToBuffer(uint8 *dst, uint pitch);
-
-	const byte *getPalette() { _paletteChanged = false; return _palette; }
-	bool paletteChanged() { return _paletteChanged; }
-	void reset();
-
-private:
-	uint16 _offsetFrame1;
-	uint16 _offsetFrame2;
-	byte *_palette;
-	bool _paletteChanged;
-
-	void decodeByteRun(uint8 *data);
-	void decodeDeltaFLC(uint8 *data);
-	void unpackPalette(uint8 *mem);
-
-	Common::List<Common::Rect> _dirtyRects;
-
-};
-
-} // End of namespace Graphics
-
-#endif

Copied: scummvm/trunk/graphics/video/smk_decoder.cpp (from rev 40752, scummvm/trunk/graphics/video/smk_player.cpp)
===================================================================
--- scummvm/trunk/graphics/video/smk_decoder.cpp	                        (rev 0)
+++ scummvm/trunk/graphics/video/smk_decoder.cpp	2009-05-21 13:02:56 UTC (rev 40759)
@@ -0,0 +1,859 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+// Based on http://wiki.multimedia.cx/index.php?title=Smacker
+// and the FFmpeg Smacker decoder (libavcodec/smacker.c), revision 16143
+// http://svn.ffmpeg.org/ffmpeg/trunk/libavcodec/smacker.c?revision=16143&view=markup
+
+#include "graphics/video/smk_decoder.h"
+
+#include "common/archive.h"
+#include "common/array.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/stream.h"
+#include "common/system.h"
+
+#include "sound/mixer.h"
+#include "sound/audiostream.h"
+
+namespace Graphics {
+
+enum SmkBlockTypes {
+	SMK_BLOCK_MONO = 0,
+	SMK_BLOCK_FULL = 1,
+	SMK_BLOCK_SKIP = 2,
+	SMK_BLOCK_FILL = 3
+};
+
+/*
+ * class BitStream
+ * Keeps a two-byte lookahead, so overallocate buf by 2 bytes if
+ * you want to avoid OOB reads.
+ */
+
+class BitStream {
+public:
+	BitStream(byte *buf, uint32 length)
+		: _buf(buf), _end(buf+length), _curBit(8) {
+		_curBytes  = *_buf++;
+		_curBytes |= *_buf++ << 8;
+	}
+
+	bool getBit();
+	byte getBits8();
+
+	byte peek8() const;
+	void skip(int n);
+
+private:
+	byte *_buf;
+	byte *_end;
+	uint16 _curBytes;
+	byte  _curBit;
+};
+
+bool BitStream::getBit() {
+	bool v = _curBytes & 1;
+
+	_curBytes >>= 1;
+
+	if (--_curBit == 0) {
+		_curBytes |= *_buf++ << 8;
+		_curBit = 8;
+	}
+
+	return v;
+}
+
+byte BitStream::getBits8() {
+	byte v = _curBytes & 0xff;
+	_curBytes >>= 8;
+	_curBytes |= *_buf++ << _curBit;
+	return v;
+}
+
+byte BitStream::peek8() const {
+	return _curBytes & 0xff;
+}
+
+void BitStream::skip(int n) {
+	assert(n <= 8);
+	_curBytes >>= n;
+
+	if (_curBit > n) {
+		_curBit -= n;
+	} else {
+		_curBit = _curBit + 8 - n;
+		_curBytes |= *_buf++ << _curBit;
+	}
+}
+
+/*
+ * class SmallHuffmanTree
+ * A Huffman-tree to hold 8-bit values.
+ * Unoptimized since it's only used during smk initialization.
+ */
+
+class SmallHuffmanTree {
+public:
+	SmallHuffmanTree(BitStream &bs) : _bs(bs) {
+		uint32 bit = _bs.getBit();
+		assert(bit);
+
+		decodeTree(0);
+
+		bit = _bs.getBit();
+		assert(!bit);
+	}
+
+	uint16 getCode(BitStream &bs);
+private:
+	enum {
+		SMK_NODE = 0x8000
+	};
+
+	int decodeTree(int length);
+
+	Common::Array<uint16> _tree;
+	BitStream &_bs;
+};
+
+int SmallHuffmanTree::decodeTree(int length) {
+	if (!_bs.getBit()) { // Leaf
+		uint16 v = _bs.getBits8();
+
+		_tree.push_back(v);
+		return 1;
+	}
+
+	_tree.push_back(0); // placeholder for r1
+	int t = _tree.size() - 1;
+
+	int r1 = decodeTree(length + 1);
+
+	_tree[t] = (SMK_NODE | r1);
+
+	int r2 = decodeTree(length + 1);
+
+	return r1+r2+1;
+}
+
+uint16 SmallHuffmanTree::getCode(BitStream &bs) {
+	uint16 *p = &_tree[0];
+
+	while (*p & SMK_NODE) {
+		if (bs.getBit())
+			p += *p & ~SMK_NODE;
+		p++;
+	}
+
+	return *p;
+}
+
+/*
+ * class BigHuffmanTree
+ * A Huffman-tree to hold 16-bit values.
+ * Contains the beginnings of an optimization.
+ */
+
+class BigHuffmanTree {
+public:
+	BigHuffmanTree(BitStream &bs);
+
+	void reset();
+	uint32 getCode(BitStream &bs);
+private:
+	enum {
+		SMK_NODE = 0x80000000
+	};
+
+	int decodeTree(uint32 prefix, int length);
+
+	Common::Array<uint32> _tree;
+	uint32 _last[3];
+
+	int _prefixtree[256];
+	int _prefixlength[256];
+
+	/* Used during construction */
+	BitStream &_bs;
+	uint32 _markers[3];
+	SmallHuffmanTree *_loBytes;
+	SmallHuffmanTree *_hiBytes;
+};
+
+BigHuffmanTree::BigHuffmanTree(BitStream &bs)
+	: _bs(bs) {
+	uint32 bit = _bs.getBit();
+	if (!bit) {
+		_tree.push_back(0);
+		_last[0] = _last[1] = _last[2] = 0;
+		return;
+	}
+
+	int i;
+	for (i = 0; i < 256; ++i)
+		_prefixtree[i] = 0;
+
+	_loBytes = new SmallHuffmanTree(_bs);
+	_hiBytes = new SmallHuffmanTree(_bs);
+
+	_markers[0] = _bs.getBits8() | (_bs.getBits8() << 8);
+	_markers[1] = _bs.getBits8() | (_bs.getBits8() << 8);
+	_markers[2] = _bs.getBits8() | (_bs.getBits8() << 8);
+
+	_last[0] = _last[1] = _last[2] = 0xffffffff;
+
+	decodeTree(0, 0);
+	bit = _bs.getBit();
+	assert(!bit);
+
+	for (i = 0; i < 3; ++i) {
+		if (_last[i] == 0xffffffff) {
+			_tree.push_back(0);
+			_last[i] = _tree.size() - 1;
+		}
+	}
+
+	delete _loBytes;
+	delete _hiBytes;
+}
+
+void BigHuffmanTree::reset() {
+	_tree[_last[0]] = _tree[_last[1]] = _tree[_last[2]] = 0;
+}
+
+int BigHuffmanTree::decodeTree(uint32 prefix, int length) {
+	uint32 bit = _bs.getBit();
+
+	if (!bit) { // Leaf
+		uint32 lo = _loBytes->getCode(_bs);
+		uint32 hi = _hiBytes->getCode(_bs);
+
+		uint32 v = (hi << 8) | lo;
+		_tree.push_back(v);
+
+		int t = _tree.size() - 1;
+
+		if (length <= 8) {
+			uint32 i;
+			for (i = 0; i < 256; i += (1 << length)) {
+				_prefixtree[prefix | i] = t;
+				_prefixlength[prefix | i] = length;
+			}
+		}
+
+		int i;
+		for (i = 0; i < 3; ++i) {
+			if (_markers[i] == v) {
+				_last[i] = t;
+				_tree[t] = 0;
+			}
+		}
+
+		return 1;
+	}
+
+	_tree.push_back(0); // placeholder for r1
+	int t = _tree.size() - 1;
+
+	if (length == 8) {
+		_prefixtree[prefix] = t;
+		_prefixlength[prefix] = 8;
+	}
+
+	int r1 = decodeTree(prefix, length + 1);
+
+	_tree[t] = SMK_NODE | r1;
+
+	int r2 = decodeTree(prefix | (1 << length), length + 1);
+	return r1+r2+1;
+}
+
+uint32 BigHuffmanTree::getCode(BitStream &bs) {
+	uint32 *p = &_tree[0];
+
+	byte peek = bs.peek8();
+	p = &_tree[_prefixtree[peek]];
+	bs.skip(_prefixlength[peek]);
+
+	while (*p & SMK_NODE) {
+		if (bs.getBit())
+			p += (*p) & ~SMK_NODE;
+		p++;
+	}
+
+	uint32 v = *p;
+	if (v != _tree[_last[0]]) {
+		_tree[_last[2]] = _tree[_last[1]];
+		_tree[_last[1]] = _tree[_last[0]];
+		_tree[_last[0]] = v;
+	}
+
+	return v;
+}
+
+SmackerDecoder::SmackerDecoder(Audio::Mixer *mixer)
+	: _audioStarted(false), _audioStream(0), _mixer(mixer) {
+}
+
+SmackerDecoder::~SmackerDecoder() {
+	closeFile();
+}
+
+int SmackerDecoder::getHeight() {
+	if (!_fileStream)
+		return 0;
+	return (_header.flags ? 2 : 1) * _videoInfo.height;
+}
+
+int32 SmackerDecoder::getAudioLag() {
+	if (!_fileStream)
+		return 0;
+
+	int32 frameDelay = getFrameDelay();
+	int32 videoTime = _videoInfo.currentFrame * frameDelay;
+	int32 audioTime;
+
+	if (!_audioStream) {
+		/* No audio.
+		   Calculate the lag by how much time has gone by since the first frame
+		   and how much time *should* have passed.
+		*/
+
+		audioTime = (g_system->getMillis() - _videoInfo.startTime) * 100;
+	} else
+		audioTime = (((int32) _mixer->getSoundElapsedTime(_audioHandle)) * 100);
+
+	return videoTime - audioTime;
+}
+
+bool SmackerDecoder::loadFile(const char *fileName) {
+	int32 frameRate;
+
+	closeFile();
+
+	_fileStream = SearchMan.createReadStreamForMember(fileName);
+	if (!_fileStream)
+		return false;
+
+	// Seek to the first frame
+	_videoInfo.currentFrame = 0;
+	_header.signature = _fileStream->readUint32BE();
+
+	// No BINK support available
+	if (_header.signature == MKID_BE('BIKi')) {
+		delete _fileStream;
+		_fileStream = 0;
+		return false;
+	}
+
+	assert(_header.signature == MKID_BE('SMK2') || _header.signature == MKID_BE('SMK4'));
+
+	_videoInfo.width = _fileStream->readUint32LE();
+	_videoInfo.height = _fileStream->readUint32LE();
+	_videoInfo.frameCount = _fileStream->readUint32LE();
+	frameRate = _fileStream->readSint32LE();
+
+	if (frameRate > 0) {
+		_videoInfo.frameRate = 1000 / frameRate;
+		_videoInfo.frameDelay = frameRate * 100;
+	} else if (frameRate < 0) {
+		_videoInfo.frameRate = 100000 / (-frameRate);
+		_videoInfo.frameDelay = -frameRate;
+	} else {
+		_videoInfo.frameRate = 10;
+		_videoInfo.frameDelay = 10000;
+	}
+
+	// Flags are determined by which bit is set, which can be one of the following:
+	// 0 - set to 1 if file contains a ring frame.
+	// 1 - set to 1 if file is Y-interlaced
+	// 2 - set to 1 if file is Y-doubled
+	// If bits 1 or 2 are set, the frame should be scaled to twice its height
+    // before it is displayed.
+	_header.flags = _fileStream->readUint32LE();
+
+	// TODO: should we do any extra processing for Smacker files with ring frames?
+
+	// TODO: should we do any extra processing for Y-doubled videos? Are they the
+	// same as Y-interlaced videos?
+
+	uint32 i;
+	for (i = 0; i < 7; ++i)
+		_header.audioSize[i] = _fileStream->readUint32LE();
+
+	_header.treesSize = _fileStream->readUint32LE();
+	_header.mMapSize = _fileStream->readUint32LE();
+	_header.mClrSize = _fileStream->readUint32LE();
+	_header.fullSize = _fileStream->readUint32LE();
+	_header.typeSize = _fileStream->readUint32LE();
+
+	uint32 audioInfo;
+	for (i = 0; i < 7; ++i) {
+		// AudioRate - Frequency and format information for each sound track, up to 7 audio tracks.
+		// The 32 constituent bits have the following meaning:
+		// * bit 31 - data is compressed
+		// * bit 30 - indicates that audio data is present for this track
+		// * bit 29 - 1 = 16-bit audio; 0 = 8-bit audio
+		// * bit 28 - 1 = stereo audio; 0 = mono audio
+		// * bits 27-26 - if both set to zero - use v2 sound decompression
+		// * bits 25-24 - unused
+		// * bits 23-0 - audio sample rate
+		audioInfo = _fileStream->readUint32LE();
+		_header.audioInfo[i].isCompressed = audioInfo & 0x80000000;
+		_header.audioInfo[i].hasAudio = audioInfo & 0x40000000;
+		_header.audioInfo[i].is16Bits = audioInfo & 0x20000000;
+		_header.audioInfo[i].isStereo = audioInfo & 0x10000000;
+		_header.audioInfo[i].hasV2Compression = !(audioInfo & 0x8000000) &&
+												!(audioInfo & 0x4000000);
+		_header.audioInfo[i].sampleRate = audioInfo & 0xFFFFFF;
+
+		if (_header.audioInfo[i].hasAudio && i == 0) {
+			byte flags = 0;
+
+			if (_header.audioInfo[i].is16Bits)
+				flags = flags | Audio::Mixer::FLAG_16BITS;
+
+			if (_header.audioInfo[i].isStereo)
+				flags = flags | Audio::Mixer::FLAG_STEREO;
+
+			_audioStream = Audio::makeAppendableAudioStream(_header.audioInfo[i].sampleRate, flags);
+		}
+	}
+
+	_header.dummy = _fileStream->readUint32LE();
+
+	_frameSizes = (uint32 *)malloc(_videoInfo.frameCount * sizeof(uint32));
+	for (i = 0; i < _videoInfo.frameCount; ++i)
+		_frameSizes[i] = _fileStream->readUint32LE();
+
+	_frameTypes = (byte *)malloc(_videoInfo.frameCount);
+	for (i = 0; i < _videoInfo.frameCount; ++i)
+		_frameTypes[i] = _fileStream->readByte();
+
+	Common::Array<byte> huffmanTrees;
+	huffmanTrees.resize(_header.treesSize + 2);
+	_fileStream->read(&huffmanTrees[0], _header.treesSize);
+	huffmanTrees[_header.treesSize] = 0;
+	huffmanTrees[_header.treesSize + 1] = 0;
+
+	BitStream bs(&huffmanTrees[0], _header.treesSize);
+
+	_MMapTree = new BigHuffmanTree(bs);
+	_MClrTree = new BigHuffmanTree(bs);
+	_FullTree = new BigHuffmanTree(bs);
+	_TypeTree = new BigHuffmanTree(bs);
+
+	_videoFrameBuffer = (byte *)malloc(2 * _videoInfo.width * _videoInfo.height);
+	memset(_videoFrameBuffer, 0, 2 * _videoInfo.width * _videoInfo.height);
+	_palette = (byte *)malloc(3 * 256);
+	memset(_palette, 0, 3 * 256);
+
+	_videoInfo.firstframeOffset = _fileStream->pos();
+
+	return true;
+}
+
+void SmackerDecoder::closeFile() {
+	if (!_fileStream)
+		return;
+
+	if (_audioStarted && _audioStream) {
+		_mixer->stopHandle(_audioHandle);
+		_audioStream = 0;
+		_audioStarted = false;
+	}
+
+	delete _fileStream;
+	_fileStream = 0;
+
+	delete _MMapTree;
+	delete _MClrTree;
+	delete _FullTree;
+	delete _TypeTree;
+
+	free(_frameSizes);
+	free(_frameTypes);
+	free(_videoFrameBuffer);
+	free(_palette);
+}
+
+bool SmackerDecoder::decodeNextFrame() {
+	uint i;
+	uint32 chunkSize = 0;
+	uint32 dataSizeUnpacked = 0;
+
+	uint32 startPos = _fileStream->pos();
+
+	if (_videoInfo.currentFrame == 0)
+		_videoInfo.startTime = g_system->getMillis();
+
+	// Check if we got a frame with palette data, and
+	// call back the virtual setPalette function to set
+	// the current palette
+	if (_frameTypes[_videoInfo.currentFrame] & 1) {
+		unpackPalette();
+		setPalette(_palette);
+	}
+
+	// Load audio tracks
+	for (i = 0; i < 7; ++i) {
+		if (!(_frameTypes[_videoInfo.currentFrame] & (2 << i)))
+			continue;
+
+		chunkSize = _fileStream->readUint32LE();
+		chunkSize -= 4;    // subtract the first 4 bytes (chunk size)
+
+		if (_header.audioInfo[i].isCompressed) {
+			dataSizeUnpacked = _fileStream->readUint32LE();
+			chunkSize -= 4;    // subtract the next 4 bytes (unpacked data size)
+		} else {
+			dataSizeUnpacked = 0;
+		}
+
+		if (_header.audioInfo[i].hasAudio && chunkSize > 0 && i == 0) {
+			// If it's track 0, play the audio data
+			byte *soundBuffer = new byte[chunkSize + 2];
+
+			_fileStream->read(soundBuffer, chunkSize);
+			soundBuffer[chunkSize] = 0;
+			soundBuffer[chunkSize + 1] = 0;
+
+			if (_header.audioInfo[i].isCompressed) {
+				// Compressed audio (Huffman DPCM encoded)
+				queueCompressedBuffer(soundBuffer, chunkSize, dataSizeUnpacked, i);
+				delete[] soundBuffer;
+			} else {
+				// Uncompressed audio (PCM)
+				_audioStream->queueBuffer(soundBuffer, chunkSize);
+				// The sound buffer will be deleted by AppendableAudioStream
+			}
+
+			if (!_audioStarted) {
+				_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream, -1, 255);
+				_audioStarted = true;
+			}
+		} else {
+			// Ignore the rest of the audio tracks, if they exist
+			// TODO: Are there any Smacker videos with more than one audio stream?
+			// If yes, we should play the rest of the audio streams as well
+			if (chunkSize > 0)
+				_fileStream->skip(chunkSize);
+		}
+	}
+
+	uint32 frameSize = _frameSizes[_videoInfo.currentFrame] & ~3;
+
+	if (_fileStream->pos() - startPos > frameSize)
+		exit(1);
+
+	uint32 frameDataSize = frameSize - (_fileStream->pos() - startPos);
+
+	_frameData = (byte *)malloc(frameDataSize + 2);
+	_fileStream->read(_frameData, frameDataSize);
+	_frameData[frameDataSize] = 0;
+	_frameData[frameDataSize + 1] = 0;
+
+	BitStream bs(_frameData, frameDataSize);
+
+	_MMapTree->reset();
+	_MClrTree->reset();
+	_FullTree->reset();
+	_TypeTree->reset();
+
+	uint bw = _videoInfo.width / 4;
+	uint bh = _videoInfo.height / 4;
+	uint stride = _videoInfo.width;
+	uint block = 0, blocks = bw*bh;
+
+	uint doubleY = _header.flags ? 2 : 1;
+
+	byte *out;
+	uint type, run, j, mode;
+	uint32 p1, p2, clr, map;
+	byte hi, lo;
+
+	while (block < blocks) {
+		type = _TypeTree->getCode(bs);
+		run = getBlockRun((type >> 2) & 0x3f);
+
+		switch (type & 3) {
+		case SMK_BLOCK_MONO:
+			while (run-- && block < blocks) {
+				clr = _MClrTree->getCode(bs);
+				map = _MMapTree->getCode(bs);
+				out = _videoFrameBuffer + (block / bw) * (stride * 4 * doubleY) + (block % bw) * 4;
+				hi = clr >> 8;
+				lo = clr & 0xff;
+				for (i = 0; i < 4; i++) {
+					for (j = 0; j < doubleY; j++) {
+						out[0] = (map & 1) ? hi : lo;
+						out[1] = (map & 2) ? hi : lo;
+						out[2] = (map & 4) ? hi : lo;
+						out[3] = (map & 8) ? hi : lo;
+						out += stride;
+					}
+					map >>= 4;
+				}
+				++block;
+			}
+			break;
+		case SMK_BLOCK_FULL:
+			// Smacker v2 has one mode, Smacker v4 has three
+			if (_header.signature == MKID_BE('SMK2')) {
+				mode = 0;
+			} else {
+				// 00 - mode 0
+				// 10 - mode 1
+				// 01 - mode 2
+				mode = 0;
+				if (bs.getBit()) {
+					mode = 1;
+				} else if (bs.getBit()) {
+					mode = 2;
+				}
+			}
+
+			while (run-- && block < blocks) {
+				out = _videoFrameBuffer + (block / bw) * (stride * 4 * doubleY) + (block % bw) * 4;
+				switch (mode) {
+					case 0:
+						for (i = 0; i < 4; ++i) {
+							p1 = _FullTree->getCode(bs);
+							p2 = _FullTree->getCode(bs);
+							for (j = 0; j < doubleY; ++j) {
+								out[2] = p1 & 0xff;
+								out[3] = p1 >> 8;
+								out[0] = p2 & 0xff;
+								out[1] = p2 >> 8;
+								out += stride;
+							}
+						}
+						break;
+					case 1:
+						p1 = _FullTree->getCode(bs);
+						out[0] = out[1] = p1 & 0xFF;
+						out[2] = out[3] = p1 >> 8;
+						out += stride;
+						out[0] = out[1] = p1 & 0xFF;
+						out[2] = out[3] = p1 >> 8;
+						out += stride;
+						p2 = _FullTree->getCode(bs);
+						out[0] = out[1] = p2 & 0xFF;
+						out[2] = out[3] = p2 >> 8;
+						out += stride;
+						out[0] = out[1] = p2 & 0xFF;
+						out[2] = out[3] = p2 >> 8;
+						out += stride;
+						break;
+					case 2:
+						for (i = 0; i < 2; i++) {
+							// We first get p2 and then p1
+							// Check ffmpeg thread "[PATCH] Smacker video decoder bug fix"
+							// http://article.gmane.org/gmane.comp.video.ffmpeg.devel/78768
+							p2 = _FullTree->getCode(bs);
+							p1 = _FullTree->getCode(bs);
+							for (j = 0; j < doubleY; ++j) {
+								out[0] = p1 & 0xff;
+								out[1] = p1 >> 8;
+								out[2] = p2 & 0xff;
+								out[3] = p2 >> 8;
+								out += stride;
+							}
+							for (j = 0; j < doubleY; ++j) {
+								out[0] = p1 & 0xff;
+								out[1] = p1 >> 8;
+								out[2] = p2 & 0xff;
+								out[3] = p2 >> 8;
+								out += stride;
+							}
+						}
+						break;
+				}
+				++block;
+			}
+			break;
+		case SMK_BLOCK_SKIP:
+			while (run-- && block < blocks)
+				block++;
+			break;
+		case SMK_BLOCK_FILL:
+			uint32 col;
+			mode = type >> 8;
+			while (run-- && block < blocks) {
+				out = _videoFrameBuffer + (block / bw) * (stride * 4 * doubleY) + (block % bw) * 4;
+				col = mode * 0x01010101;
+				for (i = 0; i < 4 * doubleY; ++i) {
+					out[0] = out[1] = out[2] = out[3] = col;
+					out += stride;
+				}
+				++block;
+			}
+			break;
+		}
+	}
+
+	_fileStream->seek(startPos + frameSize);
+
+	free(_frameData);
+
+	return ++_videoInfo.currentFrame < _videoInfo.frameCount;
+}
+
+void SmackerDecoder::queueCompressedBuffer(byte *buffer, uint32 bufferSize,
+		uint32 unpackedSize, int streamNum) {
+
+	BitStream audioBS(buffer, bufferSize);
+	bool dataPresent = audioBS.getBit();
+
+	if (!dataPresent)
+		return;
+
+	bool isStereo = audioBS.getBit();
+	assert(isStereo == _header.audioInfo[streamNum].isStereo);
+	bool is16Bits = audioBS.getBit();
+	assert(is16Bits == _header.audioInfo[streamNum].is16Bits);
+
+	int numBytes = 1 * (isStereo ? 2 : 1) * (is16Bits ? 2 : 1);
+
+	byte *unpackedBuffer = new byte[unpackedSize];
+	byte *curPointer = unpackedBuffer;
+	uint32 curPos = 0;
+
+	SmallHuffmanTree *audioTrees[4];
+	for (int k = 0; k < numBytes; k++)
+		audioTrees[k] = new SmallHuffmanTree(audioBS);
+
+	// Base values, stored as big endian
+
+	int32 bases[2];
+
+	if (isStereo)
+		bases[1] = (!is16Bits) ?   audioBS.getBits8() :
+		               ((int16) (((audioBS.getBits8() << 8) | audioBS.getBits8())));
+
+	bases[0] = (!is16Bits) ?   audioBS.getBits8() :
+	               ((int16) (((audioBS.getBits8() << 8) | audioBS.getBits8())));
+
+
+	// The bases are the first samples, too
+	for (int i = 0; i < (isStereo ? 2 : 1); i++, curPointer += (is16Bits ? 2 : 1), curPos += (is16Bits ? 2 : 1)) {
+		if (is16Bits)
+			WRITE_BE_UINT16(curPointer, bases[i]);
+		else
+			*curPointer = (bases[i] & 0xFF) ^ 0x80;
+	}
+
+	// Next follow the deltas, which are added to the corresponding base values and
+	// are stored as little endian
+	// We store the unpacked bytes in big endian format
+
+	while (curPos < unpackedSize) {
+		// If the sample is stereo, the data is stored for the left and right channel, respectively
+		// (the exact opposite to the base values)
+		if (!is16Bits) {
+
+			for (int k = 0; k < (isStereo ? 2 : 1); k++) {
+				bases[k] += (int8) ((int16) audioTrees[k]->getCode(audioBS));
+				*curPointer++ = CLIP<int>(bases[k], 0, 255) ^ 0x80;
+				curPos++;
+			}
+
+		} else {
+
+			for (int k = 0; k < (isStereo ? 2 : 1); k++) {
+				bases[k] += (int16) (audioTrees[k * 2]->getCode(audioBS) |
+				                    (audioTrees[k * 2 + 1]->getCode(audioBS) << 8));
+
+				WRITE_BE_UINT16(curPointer, CLIP<int32>(bases[k], -32768, 32767));
+				curPointer += 2;
+				curPos += 2;
+			}
+		}
+
+	}
+
+	for (int k = 0; k < numBytes; k++)
+		delete audioTrees[k];
+
+	_audioStream->queueBuffer(unpackedBuffer, unpackedSize);
+	// unpackedBuffer will be deleted by AppendableAudioStream
+}
+
+void SmackerDecoder::unpackPalette() {
+	uint startPos = _fileStream->pos();
+	uint32 len = 4 * _fileStream->readByte();
+
+	byte *chunk = (byte *)malloc(len);
+	_fileStream->read(&chunk[0], len);
+	byte *p = &chunk[0];
+
+	byte oldPalette[3*256];
+	memcpy(oldPalette, _palette, 3 * 256);
+
+	byte *pal = _palette;
+
+	int sz = 0;
+	byte b0;
+	while (sz < 256) {
+		b0 = *p++;
+		if (b0 & 0x80) {               // if top bit is 1 (0x80 = 10000000)
+			sz += (b0 & 0x7f) + 1;     // get lower 7 bits + 1 (0x7f = 01111111)
+			pal += 3 * ((b0 & 0x7f) + 1);
+		} else if (b0 & 0x40) {        // if top 2 bits are 01 (0x40 = 01000000)
+			byte c = (b0 & 0x3f) + 1;  // get lower 6 bits + 1 (0x3f = 00111111)
+			uint s = 3 * *p++;
+			sz += c;
+
+			while (c--) {
+				*pal++ = oldPalette[s + 0];
+				*pal++ = oldPalette[s + 1];
+				*pal++ = oldPalette[s + 2];
+				s += 3;
+			}
+		} else {                       // top 2 bits are 00
+			sz++;
+			// get the lower 6 bits for each component (0x3f = 00111111)
+			byte b = b0 & 0x3f;
+			byte g = (*p++) & 0x3f;
+			byte r = (*p++) & 0x3f;
+
+			assert(g < 0xc0 && b < 0xc0);
+
+			// upscale to full 8-bit color values by multiplying by 4
+			*pal++ = b * 4;
+			*pal++ = g * 4;
+			*pal++ = r * 4;
+		}
+	}
+
+	_fileStream->seek(startPos + len);
+
+	free(chunk);
+}
+
+} // End of namespace Graphics


Property changes on: scummvm/trunk/graphics/video/smk_decoder.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Copied: scummvm/trunk/graphics/video/smk_decoder.h (from rev 40752, scummvm/trunk/graphics/video/smk_player.h)
===================================================================
--- scummvm/trunk/graphics/video/smk_decoder.h	                        (rev 0)
+++ scummvm/trunk/graphics/video/smk_decoder.h	2009-05-21 13:02:56 UTC (rev 40759)
@@ -0,0 +1,129 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/**
+ * Video decoder used in engines:
+ *  - agos
+ *  - saga
+ *  - scumm (he)
+ *  - sword1
+ *  - sword2
+ */
+
+// Based on http://wiki.multimedia.cx/index.php?title=Smacker
+// and the FFmpeg Smacker decoder (libavcodec/smacker.c), revision 16143
+// http://svn.ffmpeg.org/ffmpeg/trunk/libavcodec/smacker.c?revision=16143&view=markup
+
+#ifndef GRAPHICS_VIDEO_SMK_PLAYER_H
+#define GRAPHICS_VIDEO_SMK_PLAYER_H
+
+#include "graphics/video/video_player.h"
+#include "sound/mixer.h"
+
+namespace Audio {
+	class AppendableAudioStream;
+}
+
+namespace Graphics {
+
+class BigHuffmanTree;
+
+/**
+ * Implementation of a Smacker v2/v4 video decoder
+ */
+class SmackerDecoder : public VideoDecoder {
+public:
+	SmackerDecoder(Audio::Mixer *mixer);
+	virtual ~SmackerDecoder();
+
+	int getHeight();
+	int32 getAudioLag();
+
+	/**
+	 * Load an SMK encoded video file
+	 * @param filename	the filename to load
+	 */
+	bool loadFile(const char *filename);
+
+	/**
+	 * Close an SMK encoded video file
+	 */
+	void closeFile();
+
+	bool decodeNextFrame();
+
+private:
+	void unpackPalette();
+	// Possible runs of blocks
+	uint getBlockRun(int index) { return (index <= 58) ? index + 1 : 128 << (index - 59); }
+	void queueCompressedBuffer(byte *buffer, uint32 bufferSize, uint32 unpackedSize, int streamNum);
+
+	struct AudioInfo {
+		bool isCompressed;
+		bool hasAudio;
+		bool is16Bits;
+		bool isStereo;
+		bool hasV2Compression;
+		uint32 sampleRate;
+	};
+
+	struct {
+		uint32 signature;
+		uint32 flags;
+		uint32 audioSize[7];
+		uint32 treesSize;
+		uint32 mMapSize;
+		uint32 mClrSize;
+		uint32 fullSize;
+		uint32 typeSize;
+		AudioInfo audioInfo[7];
+		uint32 dummy;
+	} _header;
+
+	uint32 *_frameSizes;
+	// The FrameTypes section of a Smacker file contains an array of bytes, where
+	// the 8 bits of each byte describe the contents of the corresponding frame.
+	// The highest 7 bits correspond to audio frames (bit 7 is track 6, bit 6 track 5
+	// and so on), so there can be up to 7 different audio tracks. When the lowest bit
+	// (bit 0) is set, it denotes a frame that contains a palette record
+	byte *_frameTypes;
+	byte *_frameData;
+	// The RGB palette
+	byte *_palette;
+
+	Audio::Mixer *_mixer;
+	bool _audioStarted;
+	Audio::AppendableAudioStream *_audioStream;
+	Audio::SoundHandle _audioHandle;
+
+	BigHuffmanTree *_MMapTree;
+	BigHuffmanTree *_MClrTree;
+	BigHuffmanTree *_FullTree;
+	BigHuffmanTree *_TypeTree;
+};
+
+} // End of namespace Graphics
+
+#endif


Property changes on: scummvm/trunk/graphics/video/smk_decoder.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Deleted: scummvm/trunk/graphics/video/smk_player.cpp
===================================================================
--- scummvm/trunk/graphics/video/smk_player.cpp	2009-05-21 12:46:39 UTC (rev 40758)
+++ scummvm/trunk/graphics/video/smk_player.cpp	2009-05-21 13:02:56 UTC (rev 40759)
@@ -1,859 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-// Based on http://wiki.multimedia.cx/index.php?title=Smacker
-// and the FFmpeg Smacker decoder (libavcodec/smacker.c), revision 16143
-// http://svn.ffmpeg.org/ffmpeg/trunk/libavcodec/smacker.c?revision=16143&view=markup
-
-#include "graphics/video/smk_player.h"
-
-#include "common/archive.h"
-#include "common/array.h"
-#include "common/endian.h"
-#include "common/util.h"
-#include "common/stream.h"
-#include "common/system.h"
-
-#include "sound/mixer.h"
-#include "sound/audiostream.h"
-
-namespace Graphics {
-
-enum SmkBlockTypes {
-	SMK_BLOCK_MONO = 0,
-	SMK_BLOCK_FULL = 1,
-	SMK_BLOCK_SKIP = 2,
-	SMK_BLOCK_FILL = 3
-};
-
-/*
- * class BitStream
- * Keeps a two-byte lookahead, so overallocate buf by 2 bytes if
- * you want to avoid OOB reads.
- */
-
-class BitStream {
-public:
-	BitStream(byte *buf, uint32 length)
-		: _buf(buf), _end(buf+length), _curBit(8) {
-		_curBytes  = *_buf++;
-		_curBytes |= *_buf++ << 8;
-	}
-
-	bool getBit();
-	byte getBits8();
-
-	byte peek8() const;
-	void skip(int n);
-
-private:
-	byte *_buf;
-	byte *_end;
-	uint16 _curBytes;
-	byte  _curBit;
-};
-
-bool BitStream::getBit() {
-	bool v = _curBytes & 1;
-
-	_curBytes >>= 1;
-
-	if (--_curBit == 0) {
-		_curBytes |= *_buf++ << 8;
-		_curBit = 8;
-	}
-
-	return v;
-}
-
-byte BitStream::getBits8() {
-	byte v = _curBytes & 0xff;
-	_curBytes >>= 8;
-	_curBytes |= *_buf++ << _curBit;
-	return v;
-}
-
-byte BitStream::peek8() const {
-	return _curBytes & 0xff;
-}
-
-void BitStream::skip(int n) {
-	assert(n <= 8);
-	_curBytes >>= n;
-
-	if (_curBit > n) {
-		_curBit -= n;
-	} else {
-		_curBit = _curBit + 8 - n;
-		_curBytes |= *_buf++ << _curBit;
-	}
-}
-
-/*
- * class SmallHuffmanTree
- * A Huffman-tree to hold 8-bit values.
- * Unoptimized since it's only used during smk initialization.
- */
-
-class SmallHuffmanTree {
-public:
-	SmallHuffmanTree(BitStream &bs) : _bs(bs) {
-		uint32 bit = _bs.getBit();
-		assert(bit);
-
-		decodeTree(0);
-
-		bit = _bs.getBit();
-		assert(!bit);
-	}
-
-	uint16 getCode(BitStream &bs);
-private:
-	enum {
-		SMK_NODE = 0x8000
-	};
-
-	int decodeTree(int length);
-
-	Common::Array<uint16> _tree;
-	BitStream &_bs;
-};
-
-int SmallHuffmanTree::decodeTree(int length) {
-	if (!_bs.getBit()) { // Leaf
-		uint16 v = _bs.getBits8();
-
-		_tree.push_back(v);
-		return 1;
-	}
-
-	_tree.push_back(0); // placeholder for r1
-	int t = _tree.size() - 1;
-
-	int r1 = decodeTree(length + 1);
-
-	_tree[t] = (SMK_NODE | r1);
-
-	int r2 = decodeTree(length + 1);
-
-	return r1+r2+1;
-}
-
-uint16 SmallHuffmanTree::getCode(BitStream &bs) {
-	uint16 *p = &_tree[0];
-
-	while (*p & SMK_NODE) {
-		if (bs.getBit())
-			p += *p & ~SMK_NODE;
-		p++;
-	}
-
-	return *p;
-}
-
-/*
- * class BigHuffmanTree
- * A Huffman-tree to hold 16-bit values.
- * Contains the beginnings of an optimization.
- */
-
-class BigHuffmanTree {
-public:
-	BigHuffmanTree(BitStream &bs);
-
-	void reset();
-	uint32 getCode(BitStream &bs);
-private:
-	enum {
-		SMK_NODE = 0x80000000
-	};
-
-	int decodeTree(uint32 prefix, int length);
-
-	Common::Array<uint32> _tree;
-	uint32 _last[3];
-
-	int _prefixtree[256];
-	int _prefixlength[256];
-
-	/* Used during construction */
-	BitStream &_bs;
-	uint32 _markers[3];
-	SmallHuffmanTree *_loBytes;
-	SmallHuffmanTree *_hiBytes;
-};
-
-BigHuffmanTree::BigHuffmanTree(BitStream &bs)
-	: _bs(bs) {
-	uint32 bit = _bs.getBit();
-	if (!bit) {
-		_tree.push_back(0);
-		_last[0] = _last[1] = _last[2] = 0;
-		return;
-	}
-
-	int i;
-	for (i = 0; i < 256; ++i)
-		_prefixtree[i] = 0;
-
-	_loBytes = new SmallHuffmanTree(_bs);
-	_hiBytes = new SmallHuffmanTree(_bs);
-
-	_markers[0] = _bs.getBits8() | (_bs.getBits8() << 8);
-	_markers[1] = _bs.getBits8() | (_bs.getBits8() << 8);
-	_markers[2] = _bs.getBits8() | (_bs.getBits8() << 8);
-
-	_last[0] = _last[1] = _last[2] = 0xffffffff;
-
-	decodeTree(0, 0);
-	bit = _bs.getBit();
-	assert(!bit);
-
-	for (i = 0; i < 3; ++i) {
-		if (_last[i] == 0xffffffff) {
-			_tree.push_back(0);
-			_last[i] = _tree.size() - 1;
-		}
-	}
-
-	delete _loBytes;
-	delete _hiBytes;
-}
-
-void BigHuffmanTree::reset() {
-	_tree[_last[0]] = _tree[_last[1]] = _tree[_last[2]] = 0;
-}
-
-int BigHuffmanTree::decodeTree(uint32 prefix, int length) {
-	uint32 bit = _bs.getBit();
-
-	if (!bit) { // Leaf
-		uint32 lo = _loBytes->getCode(_bs);
-		uint32 hi = _hiBytes->getCode(_bs);
-
-		uint32 v = (hi << 8) | lo;
-		_tree.push_back(v);
-
-		int t = _tree.size() - 1;
-
-		if (length <= 8) {
-			uint32 i;
-			for (i = 0; i < 256; i += (1 << length)) {
-				_prefixtree[prefix | i] = t;
-				_prefixlength[prefix | i] = length;
-			}
-		}
-
-		int i;
-		for (i = 0; i < 3; ++i) {
-			if (_markers[i] == v) {
-				_last[i] = t;
-				_tree[t] = 0;
-			}
-		}
-
-		return 1;
-	}
-
-	_tree.push_back(0); // placeholder for r1
-	int t = _tree.size() - 1;
-
-	if (length == 8) {
-		_prefixtree[prefix] = t;
-		_prefixlength[prefix] = 8;
-	}
-
-	int r1 = decodeTree(prefix, length + 1);
-
-	_tree[t] = SMK_NODE | r1;
-
-	int r2 = decodeTree(prefix | (1 << length), length + 1);
-	return r1+r2+1;
-}
-
-uint32 BigHuffmanTree::getCode(BitStream &bs) {
-	uint32 *p = &_tree[0];
-
-	byte peek = bs.peek8();
-	p = &_tree[_prefixtree[peek]];
-	bs.skip(_prefixlength[peek]);
-
-	while (*p & SMK_NODE) {
-		if (bs.getBit())
-			p += (*p) & ~SMK_NODE;
-		p++;
-	}
-
-	uint32 v = *p;
-	if (v != _tree[_last[0]]) {
-		_tree[_last[2]] = _tree[_last[1]];
-		_tree[_last[1]] = _tree[_last[0]];
-		_tree[_last[0]] = v;
-	}
-
-	return v;
-}
-
-SmackerDecoder::SmackerDecoder(Audio::Mixer *mixer)
-	: _audioStarted(false), _audioStream(0), _mixer(mixer) {
-}
-
-SmackerDecoder::~SmackerDecoder() {
-	closeFile();
-}
-
-int SmackerDecoder::getHeight() {
-	if (!_fileStream)
-		return 0;
-	return (_header.flags ? 2 : 1) * _videoInfo.height;
-}
-
-int32 SmackerDecoder::getAudioLag() {
-	if (!_fileStream)
-		return 0;
-
-	int32 frameDelay = getFrameDelay();
-	int32 videoTime = _videoInfo.currentFrame * frameDelay;
-	int32 audioTime;
-
-	if (!_audioStream) {
-		/* No audio.
-		   Calculate the lag by how much time has gone by since the first frame
-		   and how much time *should* have passed.
-		*/
-
-		audioTime = (g_system->getMillis() - _videoInfo.startTime) * 100;
-	} else
-		audioTime = (((int32) _mixer->getSoundElapsedTime(_audioHandle)) * 100);
-
-	return videoTime - audioTime;
-}
-
-bool SmackerDecoder::loadFile(const char *fileName) {
-	int32 frameRate;
-
-	closeFile();
-
-	_fileStream = SearchMan.createReadStreamForMember(fileName);
-	if (!_fileStream)
-		return false;
-
-	// Seek to the first frame
-	_videoInfo.currentFrame = 0;
-	_header.signature = _fileStream->readUint32BE();
-
-	// No BINK support available
-	if (_header.signature == MKID_BE('BIKi')) {
-		delete _fileStream;
-		_fileStream = 0;
-		return false;
-	}
-
-	assert(_header.signature == MKID_BE('SMK2') || _header.signature == MKID_BE('SMK4'));
-
-	_videoInfo.width = _fileStream->readUint32LE();
-	_videoInfo.height = _fileStream->readUint32LE();
-	_videoInfo.frameCount = _fileStream->readUint32LE();
-	frameRate = _fileStream->readSint32LE();
-
-	if (frameRate > 0) {
-		_videoInfo.frameRate = 1000 / frameRate;
-		_videoInfo.frameDelay = frameRate * 100;
-	} else if (frameRate < 0) {
-		_videoInfo.frameRate = 100000 / (-frameRate);
-		_videoInfo.frameDelay = -frameRate;
-	} else {
-		_videoInfo.frameRate = 10;
-		_videoInfo.frameDelay = 10000;
-	}
-
-	// Flags are determined by which bit is set, which can be one of the following:
-	// 0 - set to 1 if file contains a ring frame.
-	// 1 - set to 1 if file is Y-interlaced
-	// 2 - set to 1 if file is Y-doubled
-	// If bits 1 or 2 are set, the frame should be scaled to twice its height
-    // before it is displayed.

@@ Diff output truncated at 100000 characters. @@

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