diff options
author | Paweł Kołodziejski | 2004-04-13 19:20:16 +0000 |
---|---|---|
committer | Paweł Kołodziejski | 2004-04-13 19:20:16 +0000 |
commit | 6ea29bc7f8106b386cc9602ccd5e6b0334e13232 (patch) | |
tree | 69a946a2f34f0e38473fae4ae2117e0010f4268d /scumm | |
parent | 881c86c1e71a96d291140788b277a9952bd7bf52 (diff) | |
download | scummvm-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.h | 1 | ||||
-rw-r--r-- | scumm/smush/smush_player.cpp | 81 | ||||
-rw-r--r-- | scumm/smush/smush_player.h | 1 |
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 &); |