[Scummvm-cvs-logs] SF.net SVN: scummvm:[35470] scummvm/trunk
sev at users.sourceforge.net
sev at users.sourceforge.net
Sun Dec 21 22:08:18 CET 2008
Revision: 35470
http://scummvm.svn.sourceforge.net/scummvm/?rev=35470&view=rev
Author: sev
Date: 2008-12-21 21:08:17 +0000 (Sun, 21 Dec 2008)
Log Message:
-----------
Move all video players to separate directory
Modified Paths:
--------------
scummvm/trunk/engines/agos/animation.h
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/
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/mpeg_player.cpp
scummvm/trunk/graphics/video/mpeg_player.h
scummvm/trunk/graphics/video/smk_player.cpp
scummvm/trunk/graphics/video/smk_player.h
Removed Paths:
-------------
scummvm/trunk/graphics/dxa_player.cpp
scummvm/trunk/graphics/dxa_player.h
scummvm/trunk/graphics/flic_player.cpp
scummvm/trunk/graphics/flic_player.h
scummvm/trunk/graphics/mpeg_player.cpp
scummvm/trunk/graphics/mpeg_player.h
scummvm/trunk/graphics/smk_player.cpp
scummvm/trunk/graphics/smk_player.h
Modified: scummvm/trunk/engines/agos/animation.h
===================================================================
--- scummvm/trunk/engines/agos/animation.h 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/engines/agos/animation.h 2008-12-21 21:08:17 UTC (rev 35470)
@@ -29,8 +29,8 @@
#include "common/file.h"
#include "common/stream.h"
-#include "graphics/dxa_player.h"
-#include "graphics/smk_player.h"
+#include "graphics/video/dxa_player.h"
+#include "graphics/video/smk_player.h"
#include "sound/mixer.h"
namespace AGOS {
Modified: scummvm/trunk/engines/scumm/he/animation_he.h
===================================================================
--- scummvm/trunk/engines/scumm/he/animation_he.h 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/engines/scumm/he/animation_he.h 2008-12-21 21:08:17 UTC (rev 35470)
@@ -28,7 +28,7 @@
#include "common/file.h"
-#include "graphics/smk_player.h"
+#include "graphics/video/smk_player.h"
#include "sound/mixer.h"
Modified: scummvm/trunk/engines/sword1/animation.h
===================================================================
--- scummvm/trunk/engines/sword1/animation.h 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/engines/sword1/animation.h 2008-12-21 21:08:17 UTC (rev 35470)
@@ -26,8 +26,8 @@
#ifndef SWORD1_ANIMATION_H
#define SWORD1_ANIMATION_H
-#include "graphics/dxa_player.h"
-#include "graphics/mpeg_player.h"
+#include "graphics/video/dxa_player.h"
+#include "graphics/video/mpeg_player.h"
#include "sword1/screen.h"
#include "sword1/sound.h"
Modified: scummvm/trunk/engines/sword2/animation.h
===================================================================
--- scummvm/trunk/engines/sword2/animation.h 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/engines/sword2/animation.h 2008-12-21 21:08:17 UTC (rev 35470)
@@ -28,8 +28,8 @@
#ifndef SWORD2_ANIMATION_H
#define SWORD2_ANIMATION_H
-#include "graphics/dxa_player.h"
-#include "graphics/mpeg_player.h"
+#include "graphics/video/dxa_player.h"
+#include "graphics/video/mpeg_player.h"
#include "sound/mixer.h"
#include "sword2/screen.h"
Modified: scummvm/trunk/engines/tucker/tucker.h
===================================================================
--- scummvm/trunk/engines/tucker/tucker.h 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/engines/tucker/tucker.h 2008-12-21 21:08:17 UTC (rev 35470)
@@ -32,7 +32,7 @@
#include "common/events.h"
#include "common/stream.h"
-#include "graphics/flic_player.h"
+#include "graphics/video/flic_player.h"
#include "sound/mixer.h"
Deleted: scummvm/trunk/graphics/dxa_player.cpp
===================================================================
--- scummvm/trunk/graphics/dxa_player.cpp 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/graphics/dxa_player.cpp 2008-12-21 21:08:17 UTC (rev 35470)
@@ -1,595 +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/endian.h"
-#include "common/archive.h"
-#include "graphics/dxa_player.h"
-#include "common/util.h"
-
-#ifdef USE_ZLIB
- #include "common/zlib.h"
-#endif
-
-namespace Graphics {
-
-DXAPlayer::DXAPlayer() {
- _fileStream = 0;
-
- _frameBuffer1 = 0;
- _frameBuffer2 = 0;
- _scaledBuffer = 0;
- _drawBuffer = 0;
-
- _inBuffer = 0;
- _inBufferSize = 0;
-
- _decompBuffer = 0;
- _decompBufferSize = 0;
-
- _width = 0;
- _height = 0;
-
- _frameSize = 0;
- _framesCount = 0;
- _frameNum = 0;
- _framesPerSec = 0;
- _frameTicks = 0;
-
- _scaleMode = S_NONE;
-}
-
-DXAPlayer::~DXAPlayer() {
- closeFile();
-}
-
-int DXAPlayer::getWidth() {
- if (!_fileStream)
- return 0;
- return _width;
-}
-
-int DXAPlayer::getHeight() {
- if (!_fileStream)
- return 0;
- return _height;
-}
-
-int32 DXAPlayer::getCurFrame() {
- if (!_fileStream)
- return -1;
- return _frameNum;
-}
-
-int32 DXAPlayer::getFrameCount() {
- if (!_fileStream)
- return 0;
- return _framesCount;
-}
-
-int32 DXAPlayer::getFrameRate() {
- if (!_fileStream)
- return 0;
- return _framesPerSec;
-}
-
-int32 DXAPlayer::getFrameDelay() {
- if (!_fileStream)
- return 0;
-
- return _frameTicks;
-}
-
-bool DXAPlayer::loadFile(const char *fileName) {
- uint32 tag;
- int32 frameRate;
-
- _fileStream = SearchMan.openFile(fileName);
- if (!_fileStream)
- return false;
-
- tag = _fileStream->readUint32BE();
- assert(tag == MKID_BE('DEXA'));
-
- uint8 flags = _fileStream->readByte();
- _framesCount = _fileStream->readUint16BE();
- frameRate = _fileStream->readUint32BE();
-
- if (frameRate > 0)
- _framesPerSec = 1000 / frameRate;
- else if (frameRate < 0)
- _framesPerSec = 100000 / (-frameRate);
- else
- _framesPerSec = 10;
-
- if (frameRate < 0)
- _frameTicks = -frameRate / 100;
- else
- _frameTicks = frameRate;
-
- _width = _fileStream->readUint16BE();
- _height = _fileStream->readUint16BE();
-
- if (flags & 0x80) {
- _scaleMode = S_INTERLACED;
- _curHeight = _height / 2;
- } else if (flags & 0x40) {
- _scaleMode = S_DOUBLE;
- _curHeight = _height / 2;
- } else {
- _scaleMode = S_NONE;
- _curHeight = _height;
- }
-
- debug(2, "flags 0x0%x framesCount %d width %d height %d rate %d ticks %d", flags, getFrameCount(), getWidth(), getHeight(), getFrameRate(), getFrameDelay());
-
- _frameSize = _width * _height;
- _decompBufferSize = _frameSize;
- _frameBuffer1 = (uint8 *)malloc(_frameSize);
- _frameBuffer2 = (uint8 *)malloc(_frameSize);
- if (!_frameBuffer1 || !_frameBuffer2)
- error("DXAPlayer: Error allocating frame buffers (size %u)", _frameSize);
-
- _scaledBuffer = 0;
- if (_scaleMode != S_NONE) {
- _scaledBuffer = (uint8 *)malloc(_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
- _frameNum = 0;
-
- return true;
-}
-
-void DXAPlayer::closeFile() {
- if (!_fileStream)
- return;
-
- delete _fileStream;
-
- free(_frameBuffer1);
- free(_frameBuffer2);
- free(_scaledBuffer);
- free(_inBuffer);
- free(_decompBuffer);
-
- _fileStream = 0;
- _inBuffer = 0;
- _decompBuffer = 0;
-}
-
-void DXAPlayer::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
- uint h = _height;
- uint w = _width;
-
- byte *src = _drawBuffer;
- dst += y * pitch + x;
-
- do {
- memcpy(dst, src, w);
- dst += pitch;
- src += _width;
- } while (--h);
-}
-
-void DXAPlayer::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 DXAPlayer::decode12(int size) {
-#ifdef USE_ZLIB
- if (_decompBuffer == NULL) {
- _decompBuffer = (byte *)malloc(_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 (int by = 0; by < _height; by += BLOCKH) {
- for (int bx = 0; bx < _width; bx += BLOCKW) {
- byte type = *dat++;
- byte *b2 = _frameBuffer1 + bx + by * _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 += _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 += _width;
- }
- break;
- }
- case 3: {
- for (int yc = 0; yc < BLOCKH; yc++) {
- for (int xc = 0; xc < BLOCKW; xc++) {
- b2[xc] = *dat++;
- }
- b2 += _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) * _width;
- for (int yc = 0; yc < BLOCKH; yc++) {
- memcpy(b2, b1, BLOCKW);
- b1 += _width;
- b2 += _width;
- }
- break;
- }
- case 5:
- break;
- default:
- error("decode12: Unknown type %d", type);
- }
- }
- }
-#endif
-}
-
-void DXAPlayer::decode13(int size) {
-#ifdef USE_ZLIB
- uint8 *codeBuf, *dataBuf, *motBuf, *maskBuf;
-
- if (_decompBuffer == NULL) {
- _decompBuffer = (byte *)malloc(_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 = _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 (int by = 0; by < _curHeight; by += BLOCKH) {
- for (int bx = 0; bx < _width; bx += BLOCKW) {
- uint8 type = *codeBuf++;
- uint8 *b2 = (uint8*)_frameBuffer1 + bx + by * _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 += _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 += _width;
- }
- break;
- }
- case 3: {
- for (int yc = 0; yc < BLOCKH; yc++) {
- for (int xc = 0; xc < BLOCKW; xc++) {
- b2[xc] = *dataBuf++;
- }
- b2 += _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) * _width;
- for (int yc = 0; yc < BLOCKH; yc++) {
- memcpy(b2, b1, BLOCKW);
- b1 += _width;
- b2 += _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 * _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 += _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) * _width;
- for (int yc = 0; yc < BLOCKH / 2; yc++) {
- memcpy(b2, b1, BLOCKW / 2);
- b1 += _width;
- b2 += _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 += _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 += _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 += _width;
- }
- }
- break;
- }
- default:
- error("decode13: Unknown type %d", type);
- }
- }
- }
-#endif
-}
-
-void DXAPlayer::decodeNextFrame() {
- uint32 tag;
-
- 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);
- 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 (int j = 0; j < _curHeight; ++j) {
- for (int i = 0; i < _width; ++i) {
- const int offs = j * _width + i;
- _frameBuffer1[offs] ^= _frameBuffer2[offs];
- }
- }
- }
- }
-
- switch (_scaleMode) {
- case S_INTERLACED:
- for (int cy = 0; cy < _curHeight; cy++) {
- memcpy(&_scaledBuffer[2 * cy * _width], &_frameBuffer1[cy * _width], _width);
- memset(&_scaledBuffer[((2 * cy) + 1) * _width], 0, _width);
- }
- _drawBuffer = _scaledBuffer;
- break;
- case S_DOUBLE:
- for (int cy = 0; cy < _curHeight; cy++) {
- memcpy(&_scaledBuffer[2 * cy * _width], &_frameBuffer1[cy * _width], _width);
- memcpy(&_scaledBuffer[((2 * cy) + 1) * _width], &_frameBuffer1[cy * _width], _width);
- }
- _drawBuffer = _scaledBuffer;
- break;
- case S_NONE:
- _drawBuffer = _frameBuffer1;
- break;
- }
-
- _frameNum++;
-}
-
-} // End of namespace Graphics
Deleted: scummvm/trunk/graphics/dxa_player.h
===================================================================
--- scummvm/trunk/graphics/dxa_player.h 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/graphics/dxa_player.h 2008-12-21 21:08:17 UTC (rev 35470)
@@ -1,141 +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$
- *
- */
-
-#ifndef GRAPHICS_DXA_PLAYER_H
-#define GRAPHICS_DXA_PLAYER_H
-
-#include "common/scummsys.h"
-#include "common/stream.h"
-
-namespace Graphics {
-
-enum ScaleMode {
- S_NONE,
- S_INTERLACED,
- S_DOUBLE
-};
-
-class DXAPlayer {
-protected:
- byte *_frameBuffer1;
- byte *_frameBuffer2;
- byte *_scaledBuffer;
- byte *_drawBuffer;
- byte *_inBuffer;
- uint32 _inBufferSize;
- byte *_decompBuffer;
- uint32 _decompBufferSize;
- uint16 _width;
- uint16 _height, _curHeight;
- uint16 _framesCount;
- uint32 _framesPerSec;
- uint16 _frameNum;
- uint32 _frameSize;
- uint32 _frameTicks;
- ScaleMode _scaleMode;
-
-public:
- DXAPlayer();
- virtual ~DXAPlayer();
-
- /**
- * Returns the width of the video
- * @return the width of the video
- */
- int getWidth();
-
- /**
- * Returns the height of the video
- * @return the height of the video
- */
- int getHeight();
-
- /**
- * Returns the current frame number of the video
- * @return the current frame number of the video
- */
- int32 getCurFrame();
-
- /**
- * Returns the amount of frames in the video
- * @return the amount of frames in the video
- */
- int32 getFrameCount();
-
- /**
- * Returns the frame rate of the video
- * @return the frame rate of the video
- */
- int32 getFrameRate();
-
- /**
- * Returns the time to wait for each frame in 1/100 ms
- * @return the time to wait for each frame in 1/100 ms
- */
- int32 getFrameDelay();
-
- /**
- * 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();
-
-protected:
- /**
- * Set palette, based on current frame
- * @param pal the palette data
- */
- virtual void setPalette(byte *pal) = 0;
-
- /**
- * Copy current frame into the specified position of the destination
- * buffer.
- * @param dst the buffer
- * @param x the x position of the buffer
- * @param y the y position of the buffer
- * @param pitch the pitch of buffer
- */
- void copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch);
-
- /**
- * Decode the next frame
- */
- void decodeNextFrame();
-
- void decodeZlib(byte *data, int size, int totalSize);
- void decode12(int size);
- void decode13(int size);
-
- Common::SeekableReadStream *_fileStream;
-};
-
-} // End of namespace Graphics
-
-#endif
Deleted: scummvm/trunk/graphics/flic_player.cpp
===================================================================
--- scummvm/trunk/graphics/flic_player.cpp 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/graphics/flic_player.cpp 2008-12-21 21:08:17 UTC (rev 35470)
@@ -1,276 +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 "flic_player.h"
-
-namespace Graphics {
-
-FlicPlayer::FlicPlayer()
- : _paletteDirty(false), _offscreen(0), _currFrame(0) {
- memset(&_flicInfo, 0, sizeof(_flicInfo));
-}
-
-FlicPlayer::~FlicPlayer() {
- closeFile();
-}
-
-bool FlicPlayer::loadFile(const char *fileName) {
- closeFile();
-
- if (!_fileStream.open(fileName)) {
- return false;
- }
-
- _flicInfo.size = _fileStream.readUint32LE();
- _flicInfo.type = _fileStream.readUint16LE();
- _flicInfo.numFrames = _fileStream.readUint16LE();
- _flicInfo.width = _fileStream.readUint16LE();
- _flicInfo.height = _fileStream.readUint16LE();
- _fileStream.skip(4);
- _flicInfo.speed = _fileStream.readUint32LE();
-
- _fileStream.seek(80);
- _flicInfo.offsetFrame1 = _fileStream.readUint32LE();
- _flicInfo.offsetFrame2 = _fileStream.readUint32LE();
-
- // Check FLC magic number
- if (_flicInfo.type != 0xAF12) {
- error("FlicPlayer::FlicPlayer(): attempted to load non-FLC data (type = 0x%04X)", _flicInfo.type);
- }
-
- _offscreen = new uint8[_flicInfo.width * _flicInfo.height];
- memset(_palette, 0, sizeof(_palette));
- _paletteDirty = false;
-
- // Seek to the first frame
- _currFrame = 0;
- _fileStream.seek(_flicInfo.offsetFrame1);
- return true;
-}
-
-void FlicPlayer::closeFile() {
- memset(&_flicInfo, 0, sizeof(_flicInfo));
- _fileStream.close();
- delete[] _offscreen;
- _offscreen = 0;
-}
-
-void FlicPlayer::redraw() {
- _dirtyRects.clear();
- _dirtyRects.push_back(Common::Rect(0, 0, _flicInfo.width, _flicInfo.height));
-}
-
-ChunkHeader FlicPlayer::readChunkHeader() {
- ChunkHeader head;
-
- head.size = _fileStream.readUint32LE();
- head.type = _fileStream.readUint16LE();
-
- return head;
-}
-
-FrameTypeChunkHeader FlicPlayer::readFrameTypeChunkHeader(ChunkHeader chunkHead) {
- FrameTypeChunkHeader head;
-
- head.header = chunkHead;
- head.numChunks = _fileStream.readUint16LE();
- head.delay = _fileStream.readUint16LE();
- head.reserved = _fileStream.readUint16LE();
- head.widthOverride = _fileStream.readUint16LE();
- head.heightOverride = _fileStream.readUint16LE();
-
- return head;
-}
-
-void FlicPlayer::decodeByteRun(uint8 *data) {
- uint8 *ptr = (uint8 *)_offscreen;
- while ((ptr - _offscreen) < (_flicInfo.width * _flicInfo.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();
-}
-
-#define OP_PACKETCOUNT 0
-#define OP_UNDEFINED 1
-#define OP_LASTPIXEL 2
-#define OP_LINESKIPCOUNT 3
-
-void FlicPlayer::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:
- _offscreen[currentLine * _flicInfo.width + _flicInfo.width - 1] = (opcode & 0xFF);
- _dirtyRects.push_back(Common::Rect(_flicInfo.width - 1, currentLine, _flicInfo.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(_offscreen + (currentLine * _flicInfo.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(_offscreen + currentLine * _flicInfo.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 COLOR_256 4
-#define FLI_SS2 7
-#define FLI_BRUN 15
-#define PSTAMP 18
-#define FRAME_TYPE 0xF1FA
-
-void FlicPlayer::decodeFrame() {
- FrameTypeChunkHeader frameHeader;
-
- // Read chunk
- ChunkHeader cHeader = readChunkHeader();
- switch (cHeader.type) {
- case FRAME_TYPE:
- frameHeader = readFrameTypeChunkHeader(cHeader);
- _currFrame++;
- break;
- default:
- error("FlicPlayer::decodeFrame(): unknown main chunk type (type = 0x%02X)", cHeader.type);
- break;
- }
-
- // Read subchunks
- if (cHeader.type == FRAME_TYPE) {
- for (int i = 0; i < frameHeader.numChunks; ++i) {
- cHeader = readChunkHeader();
- uint8 *data = new uint8[cHeader.size - 6];
- _fileStream.read(data, cHeader.size - 6);
- switch (cHeader.type) {
- case COLOR_256:
- setPalette(data);
- _paletteDirty = true;
- break;
- case FLI_SS2:
- decodeDeltaFLC(data);
- break;
- case FLI_BRUN:
- decodeByteRun(data);
- break;
- case PSTAMP:
- /* PSTAMP - skip for now */
- break;
- default:
- error("FlicPlayer::decodeFrame(): unknown subchunk type (type = 0x%02X)", cHeader.type);
- break;
- }
-
- delete[] data;
- }
- }
-
- // If we just processed the ring frame, set the next frame
- if (_currFrame == _flicInfo.numFrames + 1) {
- _currFrame = 1;
- _fileStream.seek(_flicInfo.offsetFrame2);
- }
-}
-
-void FlicPlayer::reset() {
- _currFrame = 0;
- _fileStream.seek(_flicInfo.offsetFrame1);
-}
-
-void FlicPlayer::setPalette(uint8 *mem) {
- uint16 numPackets = READ_LE_UINT16(mem); mem += 2;
-
- if (0 == READ_LE_UINT16(mem)) { //special case
- mem += 2;
- for (int i = 0; i < 256; ++i) {
- memcpy(_palette + i * 4, mem + i * 3, 3);
- _palette[i * 4 + 3] = 0;
- }
- } else {
- uint8 palPos = 0;
-
- while (numPackets--) {
- palPos += *mem++;
- uint8 change = *mem++;
-
- for (int i = 0; i < change; ++i) {
- memcpy(_palette + (palPos + i) * 4, mem + i * 3, 3);
- _palette[(palPos + i) * 4 + 3] = 0;
- }
-
- palPos += change;
- mem += (change * 3);
- }
- }
-}
-
-} // End of namespace Graphics
Deleted: scummvm/trunk/graphics/flic_player.h
===================================================================
--- scummvm/trunk/graphics/flic_player.h 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/graphics/flic_player.h 2008-12-21 21:08:17 UTC (rev 35470)
@@ -1,102 +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$
- *
- */
-
-#ifndef GRAPHICS_FLICPLAYER_H
-#define GRAPHICS_FLICPLAYER_H
-
-#include "common/endian.h"
-#include "common/list.h"
-#include "common/rect.h"
-#include "common/file.h"
-
-namespace Graphics {
-
-struct FlicHeader {
- uint32 size;
- uint16 type;
- uint16 numFrames;
- uint16 width;
- uint16 height;
- uint32 speed;
- uint16 offsetFrame1;
- uint16 offsetFrame2;
-};
-
-struct ChunkHeader {
- uint32 size;
- uint16 type;
-};
-
-struct FrameTypeChunkHeader {
- ChunkHeader header;
- uint16 numChunks;
- uint16 delay;
- uint16 reserved; // always zero
- uint16 widthOverride;
- uint16 heightOverride;
-};
-
-class FlicPlayer {
-public:
- FlicPlayer();
- ~FlicPlayer();
-
- bool loadFile(const char *fileName);
- void closeFile();
- void decodeFrame();
- int getWidth() const { return _flicInfo.width; }
- int getHeight() const { return _flicInfo.height; }
- bool hasFrames() const { return _flicInfo.numFrames > 0; }
- int getCurFrame() const { return _currFrame; }
- int getFrameCount() const { return _flicInfo.numFrames; }
- bool isLastFrame() const { return _currFrame == _flicInfo.numFrames; }
- uint32 getSpeed() const { return _flicInfo.speed; }
- bool isPaletteDirty() const { return _paletteDirty; }
- const uint8 *getPalette() { _paletteDirty = false; return _palette; }
- const uint8 *getOffscreen() const { return _offscreen; }
- const Common::List<Common::Rect> *getDirtyRects() const { return &_dirtyRects; }
- void clearDirtyRects() { _dirtyRects.clear(); }
- void redraw();
- void reset();
-
-protected:
- ChunkHeader readChunkHeader();
- FrameTypeChunkHeader readFrameTypeChunkHeader(ChunkHeader chunkHead);
- void decodeByteRun(uint8 *data);
- void decodeDeltaFLC(uint8 *data);
- void setPalette(uint8 *mem);
-
- Common::File _fileStream;
- bool _paletteDirty;
- uint8 *_offscreen;
- uint8 _palette[256 * 4];
- FlicHeader _flicInfo;
- uint16 _currFrame;
- Common::List<Common::Rect> _dirtyRects;
-};
-
-} // End of namespace Graphics
-
-#endif
Modified: scummvm/trunk/graphics/module.mk
===================================================================
--- scummvm/trunk/graphics/module.mk 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/graphics/module.mk 2008-12-21 21:08:17 UTC (rev 35470)
@@ -2,8 +2,6 @@
MODULE_OBJS := \
cursorman.o \
- dxa_player.o \
- flic_player.o \
font.o \
fontman.o \
fonts/consolefont.o \
@@ -13,15 +11,17 @@
iff.o \
imagedec.o \
imageman.o \
- mpeg_player.o \
primitives.o \
scaler.o \
scaler/thumbnail_intern.o \
- smk_player.o \
surface.o \
thumbnail.o \
VectorRenderer.o \
- VectorRendererSpec.o
+ VectorRendererSpec.o \
+ video/dxa_player.o \
+ video/flic_player.o \
+ video/mpeg_player.o \
+ video/smk_player.o
ifndef DISABLE_SCALERS
MODULE_OBJS += \
Deleted: scummvm/trunk/graphics/mpeg_player.cpp
===================================================================
--- scummvm/trunk/graphics/mpeg_player.cpp 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/graphics/mpeg_player.cpp 2008-12-21 21:08:17 UTC (rev 35470)
@@ -1,629 +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/mpeg_player.h"
-#include "common/file.h"
-#include "common/system.h"
-#include "common/util.h"
-#include "graphics/scaler/intern.h"
-
-namespace Graphics {
-
-BaseAnimationState::BaseAnimationState(OSystem *sys, int width, int height)
- : _movieWidth(width), _movieHeight(height), _frameWidth(width), _frameHeight(height), _sys(sys) {
-#ifndef BACKEND_8BIT
- const int screenW = _sys->getOverlayWidth();
- const int screenH = _sys->getOverlayHeight();
-
- _movieScale = MIN(screenW / _movieWidth, screenH / _movieHeight);
-
- assert(_movieScale >= 1);
- if (_movieScale > 3)
- _movieScale = 3;
-
- _colorTab = NULL;
- _rgbToPix = NULL;
- _bitFormat = 0;
-#endif
-}
-
-BaseAnimationState::~BaseAnimationState() {
-#ifdef USE_MPEG2
- if (_mpegDecoder)
- mpeg2_close(_mpegDecoder);
- delete _mpegFile;
-#ifndef BACKEND_8BIT
- _sys->hideOverlay();
- free(_overlay);
- free(_colorTab);
- free(_rgbToPix);
-#endif
-#endif
-}
-
-
-bool BaseAnimationState::init(const char *name) {
-#ifdef USE_MPEG2
- char tempFile[512];
-
- _mpegDecoder = NULL;
- _mpegFile = NULL;
-
-#ifdef BACKEND_8BIT
-
- uint i, p;
-
- // Load lookup palettes
- sprintf(tempFile, "%s.pal", name);
-
- Common::File f;
-
- if (!f.open(tempFile)) {
- warning("Cutscene: %s palette missing", tempFile);
- return false;
- }
-
- p = 0;
- while (1) {
- _palettes[p].end = f.readUint16LE();
- _palettes[p].cnt = f.readUint16LE();
-
- if (f.ioFailed())
- break;
-
- for (i = 0; i < _palettes[p].cnt; i++) {
- _palettes[p].pal[4 * i] = f.readByte();
- _palettes[p].pal[4 * i + 1] = f.readByte();
- _palettes[p].pal[4 * i + 2] = f.readByte();
- _palettes[p].pal[4 * i + 3] = 0;
- }
- for (; i < 256; i++) {
- _palettes[p].pal[4 * i] = 0;
- _palettes[p].pal[4 * i + 1] = 0;
- _palettes[p].pal[4 * i + 2] = 0;
- _palettes[p].pal[4 * i + 3] = 0;
- }
-
- p++;
- }
-
- f.close();
-
- _palNum = 0;
- _maxPalNum = p;
- setPalette(_palettes[_palNum].pal);
- _lut = _lut2 = _yuvLookup[0];
- _curPal = -1;
- _cr = 0;
- buildLookup(_palNum, 256);
- _lut2 = _yuvLookup[1];
- _lutCalcNum = (BITDEPTH + _palettes[_palNum].end + 2) / (_palettes[_palNum].end + 2);
-#else
- buildLookup();
- _overlay = (OverlayColor *)calloc(_movieScale * _movieWidth * _movieScale * _movieHeight, sizeof(OverlayColor));
- _sys->showOverlay();
-#endif
-
- // Open MPEG2 stream
- _mpegFile = new Common::File();
- sprintf(tempFile, "%s.mp2", name);
- if (!_mpegFile->open(tempFile)) {
- warning("Cutscene: Could not open %s", tempFile);
- return false;
- }
-
- // Load and configure decoder
- _mpegDecoder = mpeg2_init();
- if (_mpegDecoder == NULL) {
- warning("Cutscene: Could not allocate an MPEG2 decoder");
- return false;
- }
-
- _mpegInfo = mpeg2_info(_mpegDecoder);
- _frameNum = 0;
-
- return true;
-#else /* USE_MPEG2 */
- return false;
-#endif
-}
-
-bool BaseAnimationState::decodeFrame() {
-#ifdef USE_MPEG2
- mpeg2_state_t state;
- const mpeg2_sequence_t *sequence_i;
- size_t size = (size_t) -1;
- static byte buf[BUFFER_SIZE];
-
- do {
- state = mpeg2_parse(_mpegDecoder);
- sequence_i = _mpegInfo->sequence;
-
- switch (state) {
- case STATE_BUFFER:
- size = _mpegFile->read(buf, BUFFER_SIZE);
- mpeg2_buffer(_mpegDecoder, buf, buf + size);
- break;
-
- case STATE_SLICE:
- case STATE_END:
- if (_mpegInfo->display_fbuf) {
- checkPaletteSwitch();
- drawYUV(sequence_i->width, sequence_i->height, _mpegInfo->display_fbuf->buf);
-#ifdef BACKEND_8BIT
- buildLookup(_palNum + 1, _lutCalcNum);
-#endif
-
- _frameNum++;
- return true;
- }
- break;
-
- default:
- break;
- }
- } while (size);
-#endif
- return false;
-}
-
-bool BaseAnimationState::checkPaletteSwitch() {
-#ifdef BACKEND_8BIT
- // if we have reached the last image with this palette, switch to new one
- if (_frameNum == _palettes[_palNum].end) {
- unsigned char *l = _lut2;
- _palNum++;
- setPalette(_palettes[_palNum].pal);
- _lutCalcNum = (BITDEPTH + _palettes[_palNum].end - (_frameNum + 1) + 2) / (_palettes[_palNum].end - (_frameNum + 1) + 2);
- _lut2 = _lut;
- _lut = l;
- return true;
- }
-#endif
-
- return false;
-}
-
-void BaseAnimationState::handleScreenChanged() {
-#ifndef BACKEND_8BIT
- const int screenW = _sys->getOverlayWidth();
- const int screenH = _sys->getOverlayHeight();
-
- int newScale = MIN(screenW / _movieWidth, screenH / _movieHeight);
-
- assert(newScale >= 1);
- if (newScale > 3)
- newScale = 3;
-
- if (newScale != _movieScale) {
- // HACK: Since frames generally do not cover the entire screen,
- // We need to undraw the old frame. This is a very hacky
- // way of doing that.
- OverlayColor *buf = (OverlayColor *)calloc(screenW * screenH, sizeof(OverlayColor));
- _sys->copyRectToOverlay(buf, screenW, 0, 0, screenW, screenH);
- free(buf);
-
- free(_overlay);
- _movieScale = newScale;
- _overlay = (OverlayColor *)calloc(_movieScale * _movieWidth * _movieScale * _movieHeight, sizeof(OverlayColor));
- }
-
- buildLookup();
-#endif
-}
-
-#ifdef BACKEND_8BIT
-
-/**
- * Build 'Best-Match' RGB lookup table
- */
-void BaseAnimationState::buildLookup(int p, int lines) {
- int y, cb;
- int r, g, b, ii;
-
- if (p >= _maxPalNum)
- return;
-
- if (p != _curPal) {
- _curPal = p;
- _cr = 0;
- _pos = 0;
- }
-
- if (_cr > BITDEPTH)
- return;
-
- for (ii = 0; ii < lines; ii++) {
- r = (-16 * 256 + (int) (256 * 1.596) * ((_cr << SHIFT) - 128)) / 256;
- for (cb = 0; cb <= BITDEPTH; cb++) {
- g = (-16 * 256 - (int) (0.813 * 256) * ((_cr << SHIFT) - 128) - (int) (0.391 * 256) * ((cb << SHIFT) - 128)) / 256;
- b = (-16 * 256 + (int) (2.018 * 256) * ((cb << SHIFT) - 128)) / 256;
-
- for (y = 0; y <= BITDEPTH; y++) {
- int idx, bst = 0;
- int dis = 2 * SQR(r - _palettes[p].pal[0]) + 4 * SQR(g - _palettes[p].pal[1]) + SQR(b - _palettes[p].pal[2]);
-
- for (idx = 1; idx < 256; idx++) {
- long d2 = 2 * SQR(r - _palettes[p].pal[4 * idx]) + 4 * SQR(g - _palettes[p].pal[4 * idx + 1]) + SQR(b - _palettes[p].pal[4 * idx + 2]);
- if (d2 < dis) {
- bst = idx;
- dis = d2;
- }
- }
- _lut2[_pos++] = bst;
-
- r += (1 << SHIFT);
- g += (1 << SHIFT);
- b += (1 << SHIFT);
- }
- r -= (BITDEPTH + 1) * (1 << SHIFT);
- }
- _cr++;
- if (_cr > BITDEPTH)
- return;
- }
-}
-
-#else
-
-// The YUV to RGB conversion code is derived from SDL's YUV overlay code, which
-// in turn appears to be derived from mpeg_play. The following copyright
-// notices have been included in accordance with the original license. Please
-// note that the term "software" in this context only applies to the two
-// functions buildLookup() and plotYUV() below.
-
-// Copyright (c) 1995 The Regents of the University of California.
-// All rights reserved.
-//
-// Permission to use, copy, modify, and distribute this software and its
-// documentation for any purpose, without fee, and without written agreement is
-// hereby granted, provided that the above copyright notice and the following
-// two paragraphs appear in all copies of this software.
-//
-// IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
-// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
-// OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
-// CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
-// ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
-// PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-
-// Copyright (c) 1995 Erik Corry
-// All rights reserved.
-//
-// Permission to use, copy, modify, and distribute this software and its
-// documentation for any purpose, without fee, and without written agreement is
-// hereby granted, provided that the above copyright notice and the following
-// two paragraphs appear in all copies of this software.
-//
-// IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
-// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
-// THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED
-// OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
-// BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
-// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-
-// Portions of this software Copyright (c) 1995 Brown University.
-// All rights reserved.
-//
-// Permission to use, copy, modify, and distribute this software and its
-// documentation for any purpose, without fee, and without written agreement
-// is hereby granted, provided that the above copyright notice and the
-// following two paragraphs appear in all copies of this software.
-//
-// IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
-// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
-// OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
-// UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
-// BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
-// SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-
-void BaseAnimationState::buildLookup() {
- // Do we already have lookup tables for this bit format?
- if (gBitFormat == _bitFormat && _colorTab && _rgbToPix)
- return;
-
- free(_colorTab);
- free(_rgbToPix);
-
- _colorTab = (int16 *)malloc(4 * 256 * sizeof(int16));
-
- int16 *Cr_r_tab = &_colorTab[0 * 256];
- int16 *Cr_g_tab = &_colorTab[1 * 256];
- int16 *Cb_g_tab = &_colorTab[2 * 256];
- int16 *Cb_b_tab = &_colorTab[3 * 256];
-
- _rgbToPix = (OverlayColor *)malloc(3 * 768 * sizeof(OverlayColor));
-
- OverlayColor *r_2_pix_alloc = &_rgbToPix[0 * 768];
- OverlayColor *g_2_pix_alloc = &_rgbToPix[1 * 768];
- OverlayColor *b_2_pix_alloc = &_rgbToPix[2 * 768];
-
- int16 CR, CB;
- int i;
-
- // Generate the tables for the display surface
-
- for (i = 0; i < 256; i++) {
- // Gamma correction (luminescence table) and chroma correction
- // would be done here. See the Berkeley mpeg_play sources.
-
- CR = CB = (i - 128);
- Cr_r_tab[i] = (int16) ( (0.419 / 0.299) * CR) + 0 * 768 + 256;
- Cr_g_tab[i] = (int16) (-(0.299 / 0.419) * CR) + 1 * 768 + 256;
- Cb_g_tab[i] = (int16) (-(0.114 / 0.331) * CB);
- Cb_b_tab[i] = (int16) ( (0.587 / 0.331) * CB) + 2 * 768 + 256;
- }
-
- // Set up entries 0-255 in rgb-to-pixel value tables.
- Graphics::PixelFormat format = _sys->getOverlayFormat();
- for (i = 0; i < 256; i++) {
- r_2_pix_alloc[i + 256] = Graphics::RGBToColor(i, 0, 0, format);
- g_2_pix_alloc[i + 256] = Graphics::RGBToColor(0, i, 0, format);
- b_2_pix_alloc[i + 256] = Graphics::RGBToColor(0, 0, i, format);
- }
-
- // Spread out the values we have to the rest of the array so that we do
- // not need to check for overflow.
- for (i = 0; i < 256; i++) {
- r_2_pix_alloc[i] = r_2_pix_alloc[256];
- r_2_pix_alloc[i + 512] = r_2_pix_alloc[511];
- g_2_pix_alloc[i] = g_2_pix_alloc[256];
- g_2_pix_alloc[i + 512] = g_2_pix_alloc[511];
- b_2_pix_alloc[i] = b_2_pix_alloc[256];
- b_2_pix_alloc[i + 512] = b_2_pix_alloc[511];
- }
-
- _bitFormat = gBitFormat;
-}
-
-void BaseAnimationState::plotYUV(int width, int height, byte *const *dat) {
- switch (_movieScale) {
- case 1:
- plotYUV1x(width, height, dat);
- break;
- case 2:
- plotYUV2x(width, height, dat);
- break;
- case 3:
- plotYUV3x(width, height, dat);
- break;
- }
-}
-
-void BaseAnimationState::plotYUV1x(int width, int height, byte *const *dat) {
- byte *lum = dat[0];
- byte *cr = dat[2];
- byte *cb = dat[1];
-
- byte *lum2 = lum + width;
-
- int16 cr_r;
- int16 crb_g;
- int16 cb_b;
-
- OverlayColor *row1 = _overlay;
- OverlayColor *row2 = row1 + _movieWidth;
-
- int x;
-
- for (; height > 0; height -= 2) {
- OverlayColor *r1 = row1;
- OverlayColor *r2 = row2;
-
- for (x = width; x > 0; x -= 2) {
- register OverlayColor *L;
-
- cr_r = _colorTab[*cr + 0 * 256];
- crb_g = _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256];
- cb_b = _colorTab[*cb + 3 * 256];
- ++cr;
- ++cb;
-
- L = &_rgbToPix[*lum++];
- *r1++ = L[cr_r] | L[crb_g] | L[cb_b];
-
- L = &_rgbToPix[*lum++];
- *r1++ = L[cr_r] | L[crb_g] | L[cb_b];
-
- // Now, do second row.
-
- L = &_rgbToPix[*lum2++];
- *r2++ = L[cr_r] | L[crb_g] | L[cb_b];
-
- L = &_rgbToPix[*lum2++];
- *r2++ = L[cr_r] | L[crb_g] | L[cb_b];
- }
-
- lum += width;
- lum2 += width;
- row1 += 2 * _movieWidth;
- row2 += 2 * _movieWidth;
- }
-}
-
-void BaseAnimationState::plotYUV2x(int width, int height, byte *const *dat) {
- byte *lum = dat[0];
- byte *cr = dat[2];
- byte *cb = dat[1];
-
- byte *lum2 = lum + width;
-
- int16 cr_r;
- int16 crb_g;
- int16 cb_b;
-
- OverlayColor *row1 = _overlay;
- OverlayColor *row2 = row1 + 2 * 2 * _movieWidth;
-
- int x;
-
- for (; height > 0; height -= 2) {
- OverlayColor *r1 = row1;
- OverlayColor *r2 = row2;
-
- for (x = width; x > 0; x -= 2) {
- register OverlayColor *L;
- register OverlayColor C;
-
- cr_r = _colorTab[*cr + 0 * 256];
- crb_g = _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256];
- cb_b = _colorTab[*cb + 3 * 256];
- ++cr;
- ++cb;
-
- L = &_rgbToPix[*lum++];
- C = L[cr_r] | L[crb_g] | L[cb_b];
- *r1++ = C;
- *r1++ = C;
-
- L = &_rgbToPix[*lum++];
- C = L[cr_r] | L[crb_g] | L[cb_b];
- *r1++ = C;
- *r1++ = C;
-
- // Now, do second row.
-
- L = &_rgbToPix[*lum2++];
- C = L[cr_r] | L[crb_g] | L[cb_b];
- *r2++ = C;
- *r2++ = C;
-
- L = &_rgbToPix[*lum2++];
- C = L[cr_r] | L[crb_g] | L[cb_b];
- *r2++ = C;
- *r2++ = C;
- }
-
- memcpy(row1 + 2 * _movieWidth, row1, 2 * _movieWidth * sizeof(OverlayColor));
- memcpy(row2 + 2 * _movieWidth, row2, 2 * _movieWidth * sizeof(OverlayColor));
-
- lum += width;
- lum2 += width;
- row1 += 4 * 2 * _movieWidth;
- row2 += 4 * 2 * _movieWidth;
- }
-}
-
-void BaseAnimationState::plotYUV3x(int width, int height, byte *const *dat) {
- byte *lum = dat[0];
- byte *cr = dat[2];
- byte *cb = dat[1];
-
- byte *lum2 = lum + width;
-
- int16 cr_r;
- int16 crb_g;
- int16 cb_b;
-
- OverlayColor *row1 = _overlay;
- OverlayColor *row2 = row1 + 3 * 3 * _movieWidth;
-
- int x;
-
- for (; height > 0; height -= 2) {
- OverlayColor *r1 = row1;
- OverlayColor *r2 = row2;
-
- for (x = width; x > 0; x -= 2) {
- register OverlayColor *L;
- register OverlayColor C;
-
- cr_r = _colorTab[*cr + 0 * 256];
- crb_g = _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256];
- cb_b = _colorTab[*cb + 3 * 256];
- ++cr;
- ++cb;
-
- L = &_rgbToPix[*lum++];
- C = L[cr_r] | L[crb_g] | L[cb_b];
- *r1++ = C;
- *r1++ = C;
- *r1++ = C;
-
- L = &_rgbToPix[*lum++];
- C = L[cr_r] | L[crb_g] | L[cb_b];
- *r1++ = C;
- *r1++ = C;
- *r1++ = C;
-
- // Now, do second row.
-
- L = &_rgbToPix[*lum2++];
- C = L[cr_r] | L[crb_g] | L[cb_b];
- *r2++ = C;
- *r2++ = C;
- *r2++ = C;
-
- L = &_rgbToPix[*lum2++];
- C = L[cr_r] | L[crb_g] | L[cb_b];
- *r2++ = C;
- *r2++ = C;
- *r2++ = C;
- }
-
- memcpy(row1 + 3 * _movieWidth, row1, 3 * _movieWidth * sizeof(OverlayColor));
- memcpy(row1 + 2 * 3 * _movieWidth, row1, 3 * _movieWidth * sizeof(OverlayColor));
- memcpy(row2 + 3 * _movieWidth, row2, 3 * _movieWidth * sizeof(OverlayColor));
- memcpy(row2 + 2 * 3 * _movieWidth, row2, 3 * _movieWidth * sizeof(OverlayColor));
-
- lum += width;
- lum2 += width;
- row1 += 6 * 3 * _movieWidth;
- row2 += 6 * 3 * _movieWidth;
- }
-}
-
-#endif
-
-void BaseAnimationState::updateScreen() {
-#ifndef BACKEND_8BIT
- int width = _movieScale * _frameWidth;
- int height = _movieScale * _frameHeight;
- int pitch = _movieScale * _movieWidth;
-
- const int screenW = _sys->getOverlayWidth();
- const int screenH = _sys->getOverlayHeight();
-
- int x = (screenW - _movieScale * _frameWidth) / 2;
- int y = (screenH - _movieScale * _frameHeight) / 2;
-
- _sys->copyRectToOverlay(_overlay, pitch, x, y, width, height);
-#endif
- _sys->updateScreen();
-}
-
-} // End of namespace Graphics
Deleted: scummvm/trunk/graphics/mpeg_player.h
===================================================================
--- scummvm/trunk/graphics/mpeg_player.h 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/graphics/mpeg_player.h 2008-12-21 21:08:17 UTC (rev 35470)
@@ -1,163 +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$
- *
- */
-
-#ifndef GRAPHICS_MPEG_PLAYER_H
-#define GRAPHICS_MPEG_PLAYER_H
-
-#include "common/scummsys.h"
-
-// Uncomment this if you are using libmpeg2 0.3.1.
-// #define USE_MPEG2_0_3_1
-
-#ifdef USE_MPEG2
-
-#ifdef __PLAYSTATION2__
-typedef uint8 uint8_t;
-typedef uint16 uint16_t;
-typedef uint32 uint32_t;
-#endif
-
-#if !defined(_MSC_VER)
-#ifndef PALMOS_MODE
-# include <inttypes.h>
-#else
-# include <stdint.h>
-#endif
-#endif
-
-extern "C" {
- #include <mpeg2dec/mpeg2.h>
-}
-
-#ifdef USE_MPEG2_0_3_1
-typedef int mpeg2_state_t;
-typedef sequence_t mpeg2_sequence_t;
-#define STATE_BUFFER -1
-#endif
-
-#endif
-
-#ifdef BACKEND_8BIT
-#define SQR(x) ((x) * (x))
-#define SHIFT 3
-#else
-#define SHIFT 1
-#endif
-
-#define BITDEPTH (1 << (8 - SHIFT))
-#define ROUNDADD (1 << (SHIFT - 1))
-
-#define BUFFER_SIZE 4096
-
-namespace Common {
- class File;
-}
-
-class OSystem;
-
-namespace Graphics {
-
-class BaseAnimationState {
-protected:
- const int _movieWidth;
- const int _movieHeight;
-
- int _frameWidth;
- int _frameHeight;
-
-#ifndef BACKEND_8BIT
- int _movieScale;
-#endif
-
- OSystem *_sys;
-
- uint _frameNum;
-
-#ifdef USE_MPEG2
- mpeg2dec_t *_mpegDecoder;
- const mpeg2_info_t *_mpegInfo;
-#endif
-
- Common::File *_mpegFile;
-
-#ifdef BACKEND_8BIT
- int _palNum;
- int _maxPalNum;
-
- byte _yuvLookup[2][(BITDEPTH+1) * (BITDEPTH+1) * (BITDEPTH+1)];
- byte *_lut;
- byte *_lut2;
- int _lutCalcNum;
-
- int _curPal;
- int _cr;
- int _pos;
-
- struct {
- uint cnt;
- uint end;
- byte pal[4 * 256];
- } _palettes[50];
-#else
- OverlayColor *_overlay;
- int _bitFormat;
- int16 *_colorTab;
- OverlayColor *_rgbToPix;
-#endif
-
-public:
- BaseAnimationState(OSystem *sys, int width, int height);
- virtual ~BaseAnimationState();
-
- bool init(const char *name);
- bool decodeFrame();
- void handleScreenChanged();
- void updateScreen();
-
-#ifndef BACKEND_8BIT
- void buildLookup();
-#endif
-
- int getFrameWidth() { return _frameWidth; }
- int getFrameHeight() { return _frameHeight; }
-
-protected:
- bool checkPaletteSwitch();
- virtual void drawYUV(int width, int height, byte *const *dat) = 0;
-
-#ifdef BACKEND_8BIT
- void buildLookup(int p, int lines);
- virtual void setPalette(byte *pal) = 0;
-#else
- void plotYUV(int width, int height, byte *const *dat);
- void plotYUV1x(int width, int height, byte *const *dat);
- void plotYUV2x(int width, int height, byte *const *dat);
- void plotYUV3x(int width, int height, byte *const *dat);
-#endif
-};
-
-} // End of namespace Graphics
-
-#endif
Deleted: scummvm/trunk/graphics/smk_player.cpp
===================================================================
--- scummvm/trunk/graphics/smk_player.cpp 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/graphics/smk_player.cpp 2008-12-21 21:08:17 UTC (rev 35470)
@@ -1,887 +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/smk_player.h"
-#include "common/archive.h"
-#include "common/system.h"
-#include "common/util.h"
-#include "common/array.h"
-#include "common/endian.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;
-}
-
-SMKPlayer::SMKPlayer(Audio::Mixer *mixer)
- : _currentSMKFrame(0), _fileStream(0), _audioStarted(false), _audioStream(0), _mixer(mixer) {
-}
-
-SMKPlayer::~SMKPlayer() {
- closeFile();
-}
-
-int SMKPlayer::getWidth() {
- if (!_fileStream)
- return 0;
- return _header.width;
-}
-
-int SMKPlayer::getHeight() {
- if (!_fileStream)
- return 0;
- return (_header.flags ? 2 : 1) * _header.height;
-}
-
-int32 SMKPlayer::getCurFrame() {
- if (!_fileStream)
- return -1;
- return _currentSMKFrame;
-}
-
-int32 SMKPlayer::getFrameCount() {
- if (!_fileStream)
- return 0;
- return _header.frames;
-}
-
-int32 SMKPlayer::getFrameRate() {
- if (!_fileStream)
- return 0;
-
- if (_header.frameRate > 0)
- return 1000 / _header.frameRate;
- else if (_header.frameRate < 0)
- return 100000 / (-_header.frameRate);
- else
- return 10;
-}
-
-int32 SMKPlayer::getFrameDelay() {
- if (!_fileStream)
- return 0;
-
- if (_header.frameRate > 0)
- return _header.frameRate * 100;
- if (_header.frameRate < 0)
- return -_header.frameRate;
-
- return 10000;
-}
-
-int32 SMKPlayer::getAudioLag() {
- if (!_fileStream || !_audioStream)
- return 0;
-
- int32 frameDelay = getFrameDelay();
- int32 videoTime = _currentSMKFrame * frameDelay;
- int32 audioTime = (((int32) _mixer->getSoundElapsedTime(_audioHandle)) * 100);
-
- return videoTime - audioTime;
-}
-
-uint32 SMKPlayer::getFrameWaitTime() {
- int32 waitTime = (getFrameDelay() + getAudioLag()) / 100;
-
- if (waitTime < 0)
- return 0;
-
- return waitTime;
-}
-
-bool SMKPlayer::loadFile(const char *fileName) {
- closeFile();
-
- _fileStream = SearchMan.openFile(fileName);
- if (!_fileStream)
- return false;
-
- // Seek to the first frame
- _currentSMKFrame = 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'));
-
- _header.width = _fileStream->readUint32LE();
- _header.height = _fileStream->readUint32LE();
- _header.frames = _fileStream->readUint32LE();
- _header.frameRate = (int32)_fileStream->readUint32LE();
- // 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(_header.frames * sizeof(uint32));
- for (i = 0; i < _header.frames; ++i)
- _frameSizes[i] = _fileStream->readUint32LE();
-
- _frameTypes = (byte *)malloc(_header.frames);
- for (i = 0; i < _header.frames; ++i)
- _frameTypes[i] = _fileStream->readByte();
-
- Common::Array<byte> huffmanTrees;
- huffmanTrees.resize(_header.treesSize + 2);
- _fileStream->read(&huffmanTrees[0], _header.treesSize);
-
- BitStream bs(&huffmanTrees[0], _header.treesSize + 2);
-
- _MMapTree = new BigHuffmanTree(bs);
- _MClrTree = new BigHuffmanTree(bs);
- _FullTree = new BigHuffmanTree(bs);
- _TypeTree = new BigHuffmanTree(bs);
-
- _image = (byte *)malloc(2 * _header.width * _header.height);
- memset(_image, 0, 2 * _header.width * _header.height);
- _palette = (byte *)malloc(3 * 256);
- memset(_palette, 0, 3 * 256);
-
- return true;
-}
-
-void SMKPlayer::closeFile() {
- if (!_fileStream)
- return;
-
- if (_audioStarted && _audioStream) {
- _mixer->stopHandle(_audioHandle);
- _audioStream = 0;
- _audioStarted = false;
- }
-
- delete _fileStream;
-
- delete _MMapTree;
- delete _MClrTree;
- delete _FullTree;
- delete _TypeTree;
-
- free(_frameSizes);
- free(_frameTypes);
- free(_image);
- free(_palette);
-
- _fileStream = 0;
-}
-
-void SMKPlayer::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
- uint h = (_header.flags ? 2 : 1) * _header.height;
- uint w = _header.width;
-
- byte *src = _image;
- dst += y * pitch + x;
-
- do {
- memcpy(dst, src, w);
- dst += pitch;
- src += _header.width;
- } while (--h);
-}
-
-bool SMKPlayer::decodeNextFrame() {
- uint i;
- uint32 chunkSize = 0;
- uint32 dataSizeUnpacked = 0;
-
- uint32 startPos = _fileStream->pos();
-
- // Check if we got a frame with palette data, and
- // call back the virtual setPalette function to set
- // the current palette
- if (_frameTypes[_currentSMKFrame] & 1) {
- unpackPalette();
- setPalette(_palette);
- }
-
- // Load audio tracks
- for (i = 0; i < 7; ++i) {
- if (!(_frameTypes[_currentSMKFrame] & (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];
-
- _fileStream->read(soundBuffer, chunkSize);
-
- 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[_currentSMKFrame] & ~3;
-
- if (_fileStream->pos() - startPos > frameSize)
- exit(1);
-
- uint32 frameDataSize = frameSize - (_fileStream->pos() - startPos);
-
- _frameData = (byte *)malloc(frameDataSize + 2);
- _fileStream->read(_frameData, frameDataSize);
-
- BitStream bs(_frameData, frameDataSize + 2);
-
- _MMapTree->reset();
- _MClrTree->reset();
- _FullTree->reset();
- _TypeTree->reset();
-
- uint bw = _header.width / 4;
- uint bh = _header.height / 4;
- uint stride = _header.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 = _image + (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 = _image + (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 = _image + (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 ++_currentSMKFrame < _header.frames;
-}
-
-void SMKPlayer::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 SMKPlayer::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
Deleted: scummvm/trunk/graphics/smk_player.h
===================================================================
--- scummvm/trunk/graphics/smk_player.h 2008-12-21 17:53:38 UTC (rev 35469)
+++ scummvm/trunk/graphics/smk_player.h 2008-12-21 21:08:17 UTC (rev 35470)
@@ -1,196 +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
-
-#ifndef GRAPHICS_SMK_PLAYER_H
-#define GRAPHICS_SMK_PLAYER_H
-
-#include "common/scummsys.h"
-#include "common/stream.h"
-#include "sound/mixer.h"
-#include "sound/audiostream.h"
-
-class OSystem;
-
-namespace Graphics {
-
-class BigHuffmanTree;
-
-/**
- * Implementation of a Smacker v2/v4 video decoder
- */
-class SMKPlayer {
-public:
- SMKPlayer(Audio::Mixer *mixer);
- virtual ~SMKPlayer();
-
- /**
- * Returns the width of the video
- * @return the width of the video
- */
- int getWidth();
-
- /**
- * Returns the height of the video
- * @return the height of the video
- */
- int getHeight();
-
- /**
- * Returns the current frame number of the video
- * @return the current frame number of the video
- */
- int32 getCurFrame();
-
- /**
- * Returns the amount of frames in the video
- * @return the amount of frames in the video
- */
- int32 getFrameCount();
-
- /**
- * Returns the frame rate of the video
- * @return the frame rate of the video
- */
- int32 getFrameRate();
-
- /**
- * Returns the time to wait for each frame in 1/100 ms
- * @return the time to wait for each frame in 1/100 ms
- */
- int32 getFrameDelay();
-
- /**
- * Returns the current A/V lag in 1/100 ms
- * If > 0, audio lags behind
- * If < 0, video lags behind
- * @return the current A/V lag in 1/100 ms
- */
- int32 getAudioLag();
-
- /**
- * Returns the time to wait until the next frame in ms, minding any lag
- * @return the time to wait until the next frame in ms
- */
- uint32 getFrameWaitTime();
-
- /**
- * 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();
-
-protected:
- /**
- * Set palette, based on current frame
- * @param pal the palette data
- */
- virtual void setPalette(byte *pal) = 0;
-
- /**
- * Copy current frame into the specified position of the destination
- * buffer.
- * @param dst the buffer
- * @param x the x position of the buffer
- * @param y the y position of the buffer
- * @param pitch the pitch of buffer
- */
- void copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch);
-
- /**
- * Decode the next frame
- */
- bool decodeNextFrame();
-
- Common::SeekableReadStream *_fileStream;
-
- byte *_image;
-
-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 width;
- uint32 height;
- uint32 frames;
- int32 frameRate;
- 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;
- byte *_palette;
-
- Audio::Mixer *_mixer;
- bool _audioStarted;
- Audio::AppendableAudioStream *_audioStream;
- Audio::SoundHandle _audioHandle;
-
- uint32 _currentSMKFrame;
-
- BigHuffmanTree *_MMapTree;
- BigHuffmanTree *_MClrTree;
- BigHuffmanTree *_FullTree;
- BigHuffmanTree *_TypeTree;
-};
-
-} // End of namespace Graphics
-
-#endif
Copied: scummvm/trunk/graphics/video/dxa_player.cpp (from rev 35469, scummvm/trunk/graphics/dxa_player.cpp)
===================================================================
--- scummvm/trunk/graphics/video/dxa_player.cpp (rev 0)
+++ scummvm/trunk/graphics/video/dxa_player.cpp 2008-12-21 21:08:17 UTC (rev 35470)
@@ -0,0 +1,595 @@
+/* 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/endian.h"
+#include "common/archive.h"
+#include "graphics/video/dxa_player.h"
+#include "common/util.h"
+
+#ifdef USE_ZLIB
+ #include "common/zlib.h"
+#endif
+
+namespace Graphics {
+
+DXAPlayer::DXAPlayer() {
+ _fileStream = 0;
+
+ _frameBuffer1 = 0;
+ _frameBuffer2 = 0;
+ _scaledBuffer = 0;
+ _drawBuffer = 0;
+
+ _inBuffer = 0;
+ _inBufferSize = 0;
+
+ _decompBuffer = 0;
+ _decompBufferSize = 0;
+
+ _width = 0;
+ _height = 0;
+
+ _frameSize = 0;
+ _framesCount = 0;
+ _frameNum = 0;
+ _framesPerSec = 0;
+ _frameTicks = 0;
+
+ _scaleMode = S_NONE;
+}
+
+DXAPlayer::~DXAPlayer() {
+ closeFile();
+}
+
+int DXAPlayer::getWidth() {
+ if (!_fileStream)
+ return 0;
+ return _width;
+}
+
+int DXAPlayer::getHeight() {
+ if (!_fileStream)
+ return 0;
+ return _height;
+}
+
+int32 DXAPlayer::getCurFrame() {
+ if (!_fileStream)
+ return -1;
+ return _frameNum;
+}
+
+int32 DXAPlayer::getFrameCount() {
+ if (!_fileStream)
+ return 0;
+ return _framesCount;
+}
+
+int32 DXAPlayer::getFrameRate() {
+ if (!_fileStream)
+ return 0;
+ return _framesPerSec;
+}
+
+int32 DXAPlayer::getFrameDelay() {
+ if (!_fileStream)
+ return 0;
+
+ return _frameTicks;
+}
+
+bool DXAPlayer::loadFile(const char *fileName) {
+ uint32 tag;
+ int32 frameRate;
+
+ _fileStream = SearchMan.openFile(fileName);
+ if (!_fileStream)
+ return false;
+
+ tag = _fileStream->readUint32BE();
+ assert(tag == MKID_BE('DEXA'));
+
+ uint8 flags = _fileStream->readByte();
+ _framesCount = _fileStream->readUint16BE();
+ frameRate = _fileStream->readUint32BE();
+
+ if (frameRate > 0)
+ _framesPerSec = 1000 / frameRate;
+ else if (frameRate < 0)
+ _framesPerSec = 100000 / (-frameRate);
+ else
+ _framesPerSec = 10;
+
+ if (frameRate < 0)
+ _frameTicks = -frameRate / 100;
+ else
+ _frameTicks = frameRate;
+
+ _width = _fileStream->readUint16BE();
+ _height = _fileStream->readUint16BE();
+
+ if (flags & 0x80) {
+ _scaleMode = S_INTERLACED;
+ _curHeight = _height / 2;
+ } else if (flags & 0x40) {
+ _scaleMode = S_DOUBLE;
+ _curHeight = _height / 2;
+ } else {
+ _scaleMode = S_NONE;
+ _curHeight = _height;
+ }
+
+ debug(2, "flags 0x0%x framesCount %d width %d height %d rate %d ticks %d", flags, getFrameCount(), getWidth(), getHeight(), getFrameRate(), getFrameDelay());
+
+ _frameSize = _width * _height;
+ _decompBufferSize = _frameSize;
+ _frameBuffer1 = (uint8 *)malloc(_frameSize);
+ _frameBuffer2 = (uint8 *)malloc(_frameSize);
+ if (!_frameBuffer1 || !_frameBuffer2)
+ error("DXAPlayer: Error allocating frame buffers (size %u)", _frameSize);
+
+ _scaledBuffer = 0;
+ if (_scaleMode != S_NONE) {
+ _scaledBuffer = (uint8 *)malloc(_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
+ _frameNum = 0;
+
+ return true;
+}
+
+void DXAPlayer::closeFile() {
+ if (!_fileStream)
+ return;
+
+ delete _fileStream;
+
+ free(_frameBuffer1);
+ free(_frameBuffer2);
+ free(_scaledBuffer);
+ free(_inBuffer);
+ free(_decompBuffer);
+
+ _fileStream = 0;
+ _inBuffer = 0;
+ _decompBuffer = 0;
+}
+
+void DXAPlayer::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
+ uint h = _height;
+ uint w = _width;
+
+ byte *src = _drawBuffer;
+ dst += y * pitch + x;
+
+ do {
+ memcpy(dst, src, w);
+ dst += pitch;
+ src += _width;
+ } while (--h);
+}
+
+void DXAPlayer::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 DXAPlayer::decode12(int size) {
+#ifdef USE_ZLIB
+ if (_decompBuffer == NULL) {
+ _decompBuffer = (byte *)malloc(_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 (int by = 0; by < _height; by += BLOCKH) {
+ for (int bx = 0; bx < _width; bx += BLOCKW) {
+ byte type = *dat++;
+ byte *b2 = _frameBuffer1 + bx + by * _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 += _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 += _width;
+ }
+ break;
+ }
+ case 3: {
+ for (int yc = 0; yc < BLOCKH; yc++) {
+ for (int xc = 0; xc < BLOCKW; xc++) {
+ b2[xc] = *dat++;
+ }
+ b2 += _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) * _width;
+ for (int yc = 0; yc < BLOCKH; yc++) {
+ memcpy(b2, b1, BLOCKW);
+ b1 += _width;
+ b2 += _width;
+ }
+ break;
+ }
+ case 5:
+ break;
+ default:
+ error("decode12: Unknown type %d", type);
+ }
+ }
+ }
+#endif
+}
+
+void DXAPlayer::decode13(int size) {
+#ifdef USE_ZLIB
+ uint8 *codeBuf, *dataBuf, *motBuf, *maskBuf;
+
+ if (_decompBuffer == NULL) {
+ _decompBuffer = (byte *)malloc(_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 = _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 (int by = 0; by < _curHeight; by += BLOCKH) {
+ for (int bx = 0; bx < _width; bx += BLOCKW) {
+ uint8 type = *codeBuf++;
+ uint8 *b2 = (uint8*)_frameBuffer1 + bx + by * _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 += _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 += _width;
+ }
+ break;
+ }
+ case 3: {
+ for (int yc = 0; yc < BLOCKH; yc++) {
+ for (int xc = 0; xc < BLOCKW; xc++) {
+ b2[xc] = *dataBuf++;
+ }
+ b2 += _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) * _width;
+ for (int yc = 0; yc < BLOCKH; yc++) {
+ memcpy(b2, b1, BLOCKW);
+ b1 += _width;
+ b2 += _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 * _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 += _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) * _width;
+ for (int yc = 0; yc < BLOCKH / 2; yc++) {
+ memcpy(b2, b1, BLOCKW / 2);
+ b1 += _width;
+ b2 += _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 += _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 += _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 += _width;
+ }
+ }
+ break;
+ }
+ default:
+ error("decode13: Unknown type %d", type);
+ }
+ }
+ }
+#endif
+}
+
+void DXAPlayer::decodeNextFrame() {
+ uint32 tag;
+
+ 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);
+ 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 (int j = 0; j < _curHeight; ++j) {
+ for (int i = 0; i < _width; ++i) {
+ const int offs = j * _width + i;
+ _frameBuffer1[offs] ^= _frameBuffer2[offs];
+ }
+ }
+ }
+ }
+
+ switch (_scaleMode) {
+ case S_INTERLACED:
+ for (int cy = 0; cy < _curHeight; cy++) {
+ memcpy(&_scaledBuffer[2 * cy * _width], &_frameBuffer1[cy * _width], _width);
+ memset(&_scaledBuffer[((2 * cy) + 1) * _width], 0, _width);
+ }
+ _drawBuffer = _scaledBuffer;
+ break;
+ case S_DOUBLE:
+ for (int cy = 0; cy < _curHeight; cy++) {
+ memcpy(&_scaledBuffer[2 * cy * _width], &_frameBuffer1[cy * _width], _width);
+ memcpy(&_scaledBuffer[((2 * cy) + 1) * _width], &_frameBuffer1[cy * _width], _width);
+ }
+ _drawBuffer = _scaledBuffer;
+ break;
+ case S_NONE:
+ _drawBuffer = _frameBuffer1;
+ break;
+ }
+
+ _frameNum++;
+}
+
+} // End of namespace Graphics
Copied: scummvm/trunk/graphics/video/dxa_player.h (from rev 35469, scummvm/trunk/graphics/dxa_player.h)
===================================================================
--- scummvm/trunk/graphics/video/dxa_player.h (rev 0)
+++ scummvm/trunk/graphics/video/dxa_player.h 2008-12-21 21:08:17 UTC (rev 35470)
@@ -0,0 +1,141 @@
+/* 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$
+ *
+ */
+
+#ifndef GRAPHICS_VIDEO_DXA_PLAYER_H
+#define GRAPHICS_VIDEO_DXA_PLAYER_H
+
+#include "common/scummsys.h"
+#include "common/stream.h"
+
+namespace Graphics {
+
+enum ScaleMode {
+ S_NONE,
+ S_INTERLACED,
+ S_DOUBLE
+};
+
+class DXAPlayer {
+protected:
+ byte *_frameBuffer1;
+ byte *_frameBuffer2;
+ byte *_scaledBuffer;
+ byte *_drawBuffer;
+ byte *_inBuffer;
+ uint32 _inBufferSize;
+ byte *_decompBuffer;
+ uint32 _decompBufferSize;
+ uint16 _width;
+ uint16 _height, _curHeight;
+ uint16 _framesCount;
+ uint32 _framesPerSec;
+ uint16 _frameNum;
+ uint32 _frameSize;
+ uint32 _frameTicks;
+ ScaleMode _scaleMode;
+
+public:
+ DXAPlayer();
+ virtual ~DXAPlayer();
+
+ /**
+ * Returns the width of the video
+ * @return the width of the video
+ */
+ int getWidth();
+
+ /**
+ * Returns the height of the video
+ * @return the height of the video
+ */
+ int getHeight();
+
+ /**
+ * Returns the current frame number of the video
+ * @return the current frame number of the video
+ */
+ int32 getCurFrame();
+
+ /**
+ * Returns the amount of frames in the video
+ * @return the amount of frames in the video
+ */
+ int32 getFrameCount();
+
+ /**
+ * Returns the frame rate of the video
+ * @return the frame rate of the video
+ */
+ int32 getFrameRate();
+
+ /**
+ * Returns the time to wait for each frame in 1/100 ms
+ * @return the time to wait for each frame in 1/100 ms
+ */
+ int32 getFrameDelay();
+
+ /**
+ * 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();
+
+protected:
+ /**
+ * Set palette, based on current frame
+ * @param pal the palette data
+ */
+ virtual void setPalette(byte *pal) = 0;
+
+ /**
+ * Copy current frame into the specified position of the destination
+ * buffer.
+ * @param dst the buffer
+ * @param x the x position of the buffer
+ * @param y the y position of the buffer
+ * @param pitch the pitch of buffer
+ */
+ void copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch);
+
+ /**
+ * Decode the next frame
+ */
+ void decodeNextFrame();
+
+ void decodeZlib(byte *data, int size, int totalSize);
+ void decode12(int size);
+ void decode13(int size);
+
+ Common::SeekableReadStream *_fileStream;
+};
+
+} // End of namespace Graphics
+
+#endif
Copied: scummvm/trunk/graphics/video/flic_player.cpp (from rev 35469, scummvm/trunk/graphics/flic_player.cpp)
===================================================================
--- scummvm/trunk/graphics/video/flic_player.cpp (rev 0)
+++ scummvm/trunk/graphics/video/flic_player.cpp 2008-12-21 21:08:17 UTC (rev 35470)
@@ -0,0 +1,276 @@
+/* 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"
+
+namespace Graphics {
+
+FlicPlayer::FlicPlayer()
+ : _paletteDirty(false), _offscreen(0), _currFrame(0) {
+ memset(&_flicInfo, 0, sizeof(_flicInfo));
+}
+
+FlicPlayer::~FlicPlayer() {
+ closeFile();
+}
+
+bool FlicPlayer::loadFile(const char *fileName) {
+ closeFile();
+
+ if (!_fileStream.open(fileName)) {
+ return false;
+ }
+
+ _flicInfo.size = _fileStream.readUint32LE();
+ _flicInfo.type = _fileStream.readUint16LE();
+ _flicInfo.numFrames = _fileStream.readUint16LE();
+ _flicInfo.width = _fileStream.readUint16LE();
+ _flicInfo.height = _fileStream.readUint16LE();
+ _fileStream.skip(4);
+ _flicInfo.speed = _fileStream.readUint32LE();
+
+ _fileStream.seek(80);
+ _flicInfo.offsetFrame1 = _fileStream.readUint32LE();
+ _flicInfo.offsetFrame2 = _fileStream.readUint32LE();
+
+ // Check FLC magic number
+ if (_flicInfo.type != 0xAF12) {
+ error("FlicPlayer::FlicPlayer(): attempted to load non-FLC data (type = 0x%04X)", _flicInfo.type);
+ }
+
+ _offscreen = new uint8[_flicInfo.width * _flicInfo.height];
+ memset(_palette, 0, sizeof(_palette));
+ _paletteDirty = false;
+
+ // Seek to the first frame
+ _currFrame = 0;
+ _fileStream.seek(_flicInfo.offsetFrame1);
+ return true;
+}
+
+void FlicPlayer::closeFile() {
+ memset(&_flicInfo, 0, sizeof(_flicInfo));
+ _fileStream.close();
+ delete[] _offscreen;
+ _offscreen = 0;
+}
+
+void FlicPlayer::redraw() {
+ _dirtyRects.clear();
+ _dirtyRects.push_back(Common::Rect(0, 0, _flicInfo.width, _flicInfo.height));
+}
+
+ChunkHeader FlicPlayer::readChunkHeader() {
+ ChunkHeader head;
+
+ head.size = _fileStream.readUint32LE();
+ head.type = _fileStream.readUint16LE();
+
+ return head;
+}
+
+FrameTypeChunkHeader FlicPlayer::readFrameTypeChunkHeader(ChunkHeader chunkHead) {
+ FrameTypeChunkHeader head;
+
+ head.header = chunkHead;
+ head.numChunks = _fileStream.readUint16LE();
+ head.delay = _fileStream.readUint16LE();
+ head.reserved = _fileStream.readUint16LE();
+ head.widthOverride = _fileStream.readUint16LE();
+ head.heightOverride = _fileStream.readUint16LE();
+
+ return head;
+}
+
+void FlicPlayer::decodeByteRun(uint8 *data) {
+ uint8 *ptr = (uint8 *)_offscreen;
+ while ((ptr - _offscreen) < (_flicInfo.width * _flicInfo.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();
+}
+
+#define OP_PACKETCOUNT 0
+#define OP_UNDEFINED 1
+#define OP_LASTPIXEL 2
+#define OP_LINESKIPCOUNT 3
+
+void FlicPlayer::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:
+ _offscreen[currentLine * _flicInfo.width + _flicInfo.width - 1] = (opcode & 0xFF);
+ _dirtyRects.push_back(Common::Rect(_flicInfo.width - 1, currentLine, _flicInfo.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(_offscreen + (currentLine * _flicInfo.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(_offscreen + currentLine * _flicInfo.width + column + i * 2, dataWord);
+ }
@@ 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