aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorPaweł Kołodziejski2004-04-13 19:20:16 +0000
committerPaweł Kołodziejski2004-04-13 19:20:16 +0000
commit6ea29bc7f8106b386cc9602ccd5e6b0334e13232 (patch)
tree69a946a2f34f0e38473fae4ae2117e0010f4268d /scumm
parent881c86c1e71a96d291140788b277a9952bd7bf52 (diff)
downloadscummvm-rg350-6ea29bc7f8106b386cc9602ccd5e6b0334e13232.tar.gz
scummvm-rg350-6ea29bc7f8106b386cc9602ccd5e6b0334e13232.tar.bz2
scummvm-rg350-6ea29bc7f8106b386cc9602ccd5e6b0334e13232.zip
added support for compressed FOBJ chunks in smush movie files.
the *.san files from 'data' dir in FT can NOT be compressed ! svn-id: r13577
Diffstat (limited to 'scumm')
-rw-r--r--scumm/smush/chunk_type.h1
-rw-r--r--scumm/smush/smush_player.cpp81
-rw-r--r--scumm/smush/smush_player.h1
3 files changed, 83 insertions, 0 deletions
diff --git a/scumm/smush/chunk_type.h b/scumm/smush/chunk_type.h
index 33edb2d06d..2fd0285ea0 100644
--- a/scumm/smush/chunk_type.h
+++ b/scumm/smush/chunk_type.h
@@ -32,6 +32,7 @@ static const Chunk::type TYPE_AHDR = 'AHDR';
static const Chunk::type TYPE_FRME = 'FRME';
static const Chunk::type TYPE_NPAL = 'NPAL';
static const Chunk::type TYPE_FOBJ = 'FOBJ';
+static const Chunk::type TYPE_ZFOB = 'ZFOB';
static const Chunk::type TYPE_PSAD = 'PSAD';
static const Chunk::type TYPE_TRES = 'TRES';
static const Chunk::type TYPE_XPAL = 'XPAL';
diff --git a/scumm/smush/smush_player.cpp b/scumm/smush/smush_player.cpp
index 7a09ae115f..ad8042ecf6 100644
--- a/scumm/smush/smush_player.cpp
+++ b/scumm/smush/smush_player.cpp
@@ -48,6 +48,10 @@
#include <png.h>
#endif
+#ifdef USE_ZLIB
+#include <zlib.h>
+#endif
+
namespace Scumm {
const int MAX_STRINGS = 200;
@@ -673,6 +677,78 @@ void SmushPlayer::handleNewPalette(Chunk &b) {
void smush_decode_codec1(byte *dst, byte *src, int left, int top, int height, int width, int dstWidth);
+#ifdef USE_ZLIB
+void SmushPlayer::handleZlibFrameObject(Chunk &b) {
+ if (_skipNext) {
+ _skipNext = false;
+ return;
+ }
+
+ int32 chunkSize = b.getSize();
+ byte *chunkBuffer = (byte *)malloc(chunkSize);
+ assert(chunkBuffer);
+ b.read(chunkBuffer, chunkSize);
+
+ unsigned long decompressedSize = READ_BE_UINT32(chunkBuffer);
+ byte *fobjBuffer = (byte *)malloc(decompressedSize);
+ int result = uncompress(fobjBuffer, &decompressedSize, chunkBuffer + 4, chunkSize - 4);
+ if (result != Z_OK)
+ error("SmushPlayer::handleZlibFrameObject() Zlib uncompress error");
+ free(chunkBuffer);
+
+ byte *ptr = fobjBuffer;
+ int codec = READ_LE_UINT16(ptr); ptr += 2;
+ int left = READ_LE_UINT16(ptr); ptr += 2;
+ int top = READ_LE_UINT16(ptr); ptr += 2;
+ int width = READ_LE_UINT16(ptr); ptr += 2;
+ int height = READ_LE_UINT16(ptr); ptr += 2;
+
+ if ((height == 242) && (width == 384)) {
+ _dst = _specialBuffer = (byte *)malloc(242 * 384);
+ } else if ((height > _vm->_screenHeight) || (width > _vm->_screenWidth))
+ return;
+ // FT Insane uses smaller frames to draw overlays with moving objects
+ // Other .san files do have them as well but their purpose in unknown
+ // and often it causes memory overdraw. So just skip those frames
+ else if (!_insanity && ((height != _vm->_screenHeight) || (width != _vm->_screenWidth)))
+ return;
+
+ if (!_alreadyInit) {
+ _codec37.init(width, height);
+ _codec47.init(width, height);
+ _alreadyInit = true;
+ }
+
+ _width = width;
+ _height = height;
+
+ switch (codec) {
+ case 1:
+ case 3:
+ smush_decode_codec1(_dst, fobjBuffer + 14, left, top, height, width, _vm->_screenWidth);
+ break;
+ case 37:
+ _codec37.decode(_dst, fobjBuffer + 14);
+ break;
+ case 47:
+ _codec47.decode(_dst, fobjBuffer + 14);
+ break;
+ default:
+ error("Invalid codec for frame object : %d", (int)codec);
+ }
+
+ if (_storeFrame) {
+ if (_frameBuffer == NULL) {
+ _frameBuffer = (byte *)malloc(_width * _height);
+ }
+ memcpy(_frameBuffer, _dst, _width * _height);
+ _storeFrame = false;
+ }
+
+ free(fobjBuffer);
+}
+#endif
+
void SmushPlayer::handleFrameObject(Chunk &b) {
checkBlock(b, TYPE_FOBJ, 14);
if (_skipNext) {
@@ -760,6 +836,11 @@ void SmushPlayer::handleFrame(Chunk &b) {
case TYPE_FOBJ:
handleFrameObject(*sub);
break;
+#ifdef USE_ZLIB
+ case TYPE_ZFOB:
+ handleZlibFrameObject(*sub);
+ break;
+#endif
case TYPE_PSAD:
handleSoundFrame(*sub);
break;
diff --git a/scumm/smush/smush_player.h b/scumm/smush/smush_player.h
index 4a1704c6dd..27f29e69e7 100644
--- a/scumm/smush/smush_player.h
+++ b/scumm/smush/smush_player.h
@@ -100,6 +100,7 @@ private:
void handleAnimHeader(Chunk &);
void handleFrame(Chunk &);
void handleNewPalette(Chunk &);
+ void handleZlibFrameObject(Chunk &b);
void handleFrameObject(Chunk &);
void handleSoundBuffer(int32, int32, int32, int32, int32, int32, Chunk &, int32);
void handleSoundFrame(Chunk &);