diff options
Diffstat (limited to 'scumm/smush')
-rw-r--r-- | scumm/smush/codec37.cpp | 669 | ||||
-rw-r--r-- | scumm/smush/codec37.h | 43 |
2 files changed, 380 insertions, 332 deletions
diff --git a/scumm/smush/codec37.cpp b/scumm/smush/codec37.cpp index 75197ca839..312d618114 100644 --- a/scumm/smush/codec37.cpp +++ b/scumm/smush/codec37.cpp @@ -24,7 +24,7 @@ #include "chunk.h" #include "blitter.h" -#include "common/engine.h" // for debug, warning, error +#include "common/engine.h" #include <assert.h> #include <string.h> @@ -40,13 +40,16 @@ bool Codec37Decoder::initSize(const Point & p, const Rect & r) { Decoder::initSize(p, r); clean(); int32 frame_size = getRect().width() * getRect().height(); - _deltaSize = frame_size * 2 + DELTA_ADD * 4; + _deltaSize = frame_size * 3 + 0x13600; _deltaBuf = new byte[_deltaSize]; + memset(_deltaBuf, 0, _deltaSize); if(_deltaBuf == 0) error("unable to allocate decoder buffer"); - _deltaBufs[0] = _deltaBuf + DELTA_ADD; - _deltaBufs[1] = _deltaBuf + frame_size + DELTA_ADD * 3; + _deltaBufs[0] = _deltaBuf + 0x4D80; + _deltaBufs[1] = _deltaBuf + 0xE880 + frame_size; _offsetTable = new int16[255]; - if(_offsetTable == 0) error("unable to allocate decoder offset table"); + _curtable = 0; + if(_offsetTable == 0) + error("unable to allocate decoder offset table"); _tableLastPitch = -1; _tableLastIndex = -1; return true; @@ -63,7 +66,7 @@ Codec37Decoder::Codec37Decoder() { _offsetTable = 0; _tableLastPitch = -1; _tableLastIndex = -1; - _prevSeqNb = 32768; // Some invalid number + _prevSeqNb = 0; } void Codec37Decoder::clean() { @@ -88,325 +91,392 @@ Codec37Decoder::~Codec37Decoder() { void Codec37Decoder::maketable(int32 pitch, int32 index) { static const int8 maketable_bytes[] = { - 0, 0, 1, 0, 2, 0, 3, 0, 5, 0, 8, 0, 13, 0, 21, 0, - -1, 0, -2, 0, -3, 0, -5, 0, -8, 0, -13, 0, -17, 0, -21, 0, - 0, 1, 1, 1, 2, 1, 3, 1, 5, 1, 8, 1, 13, 1, 21, 1, - -1, 1, -2, 1, -3, 1, -5, 1, -8, 1, -13, 1, -17, 1, -21, 1, - 0, 2, 1, 2, 2, 2, 3, 2, 5, 2, 8, 2, 13, 2, 21, 2, - -1, 2, -2, 2, -3, 2, -5, 2, -8, 2, -13, 2, -17, 2, -21, 2, - 0, 3, 1, 3, 2, 3, 3, 3, 5, 3, 8, 3, 13, 3, 21, 3, - -1, 3, -2, 3, -3, 3, -5, 3, -8, 3, -13, 3, -17, 3, -21, 3, - 0, 5, 1, 5, 2, 5, 3, 5, 5, 5, 8, 5, 13, 5, 21, 5, - -1, 5, -2, 5, -3, 5, -5, 5, -8, 5, -13, 5, -17, 5, -21, 5, - 0, 8, 1, 8, 2, 8, 3, 8, 5, 8, 8, 8, 13, 8, 21, 8, - -1, 8, -2, 8, -3, 8, -5, 8, -8, 8, -13, 8, -17, 8, -21, 8, - 0, 13, 1, 13, 2, 13, 3, 13, 5, 13, 8, 13, 13, 13, 21, 13, - -1, 13, -2, 13, -3, 13, -5, 13, -8, 13, -13, 13, -17, 13, -21, 13, - 0, 21, 1, 21, 2, 21, 3, 21, 5, 21, 8, 21, 13, 21, 21, 21, - -1, 21, -2, 21, -3, 21, -5, 21, -8, 21, -13, 21, -17, 21, -21, 21, - 0, -1, 1, -1, 2, -1, 3, -1, 5, -1, 8, -1, 13, -1, 21, -1, - -1, -1, -2, -1, -3, -1, -5, -1, -8, -1, -13, -1, -17, -1, -21, -1, - 0, -2, 1, -2, 2, -2, 3, -2, 5, -2, 8, -2, 13, -2, 21, -2, - -1, -2, -2, -2, -3, -2, -5, -2, -8, -2, -13, -2, -17, -2, -21, -2, - 0, -3, 1, -3, 2, -3, 3, -3, 5, -3, 8, -3, 13, -3, 21, -3, - -1, -3, -2, -3, -3, -3, -5, -3, -8, -3, -13, -3, -17, -3, -21, -3, - 0, -5, 1, -5, 2, -5, 3, -5, 5, -5, 8, -5, 13, -5, 21, -5, - -1, -5, -2, -5, -3, -5, -5, -5, -8, -5, -13, -5, -17, -5, -21, -5, - 0, -8, 1, -8, 2, -8, 3, -8, 5, -8, 8, -8, 13, -8, 21, -8, - -1, -8, -2, -8, -3, -8, -5, -8, -8, -8, -13, -8, -17, -8, -21, -8, - 0, -13, 1, -13, 2, -13, 3, -13, 5, -13, 8, -13, 13, -13, 21, -13, - -1, -13, -2, -13, -3, -13, -5, -13, -8, -13, -13, -13, -17, -13, -21, -13, - 0, -17, 1, -17, 2, -17, 3, -17, 5, -17, 8, -17, 13, -17, 21, -17, - -1, -17, -2, -17, -3, -17, -5, -17, -8, -17, -13, -17, -17, -17, -21, -17, - 0, -21, 1, -21, 2, -21, 3, -21, 5, -21, 8, -21, 13, -21, 21, -21, - -1, -21, -2, -21, -3, -21, -5, -21, -8, -21, -13, -21, -17, -21, 0, 0, - -8, -29, 8, -29, -18, -25, 17, -25, 0, -23, -6, -22, 6, -22, -13, -19, - 12, -19, 0, -18, 25, -18, -25, -17, -5, -17, 5, -17, -10, -15, 10, -15, - 0, -14, -4, -13, 4, -13, 19, -13, -19, -12, -8, -11, -2, -11, 0, -11, - 2, -11, 8, -11, -15, -10, -4, -10, 4, -10, 15, -10, -6, -9, -1, -9, - 1, -9, 6, -9, -29, -8, -11, -8, -8, -8, -3, -8, 3, -8, 8, -8, - 11, -8, 29, -8, -5, -7, -2, -7, 0, -7, 2, -7, 5, -7, -22, -6, - -9, -6, -6, -6, -3, -6, -1, -6, 1, -6, 3, -6, 6, -6, 9, -6, - 22, -6, -17, -5, -7, -5, -4, -5, -2, -5, 0, -5, 2, -5, 4, -5, - 7, -5, 17, -5, -13, -4, -10, -4, -5, -4, -3, -4, -1, -4, 0, -4, - 1, -4, 3, -4, 5, -4, 10, -4, 13, -4, -8, -3, -6, -3, -4, -3, - -3, -3, -2, -3, -1, -3, 0, -3, 1, -3, 2, -3, 4, -3, 6, -3, - 8, -3, -11, -2, -7, -2, -5, -2, -3, -2, -2, -2, -1, -2, 0, -2, - 1, -2, 2, -2, 3, -2, 5, -2, 7, -2, 11, -2, -9, -1, -6, -1, - -4, -1, -3, -1, -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, - 4, -1, 6, -1, 9, -1, -31, 0, -23, 0, -18, 0, -14, 0, -11, 0, - -7, 0, -5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 0, -31, 1, 0, - 2, 0, 3, 0, 4, 0, 5, 0, 7, 0, 11, 0, 14, 0, 18, 0, - 23, 0, 31, 0, -9, 1, -6, 1, -4, 1, -3, 1, -2, 1, -1, 1, - 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 6, 1, 9, 1, -11, 2, - -7, 2, -5, 2, -3, 2, -2, 2, -1, 2, 0, 2, 1, 2, 2, 2, - 3, 2, 5, 2, 7, 2, 11, 2, -8, 3, -6, 3, -4, 3, -2, 3, - -1, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 6, 3, 8, 3, - -13, 4, -10, 4, -5, 4, -3, 4, -1, 4, 0, 4, 1, 4, 3, 4, - 5, 4, 10, 4, 13, 4, -17, 5, -7, 5, -4, 5, -2, 5, 0, 5, - 2, 5, 4, 5, 7, 5, 17, 5, -22, 6, -9, 6, -6, 6, -3, 6, - -1, 6, 1, 6, 3, 6, 6, 6, 9, 6, 22, 6, -5, 7, -2, 7, - 0, 7, 2, 7, 5, 7, -29, 8, -11, 8, -8, 8, -3, 8, 3, 8, - 8, 8, 11, 8, 29, 8, -6, 9, -1, 9, 1, 9, 6, 9, -15, 10, - -4, 10, 4, 10, 15, 10, -8, 11, -2, 11, 0, 11, 2, 11, 8, 11, - 19, 12, -19, 13, -4, 13, 4, 13, 0, 14, -10, 15, 10, 15, -5, 17, - 5, 17, 25, 17, -25, 18, 0, 18, -12, 19, 13, 19, -6, 22, 6, 22, - 0, 23, -17, 25, 18, 25, -8, 29, 8, 29, 0, 31, 0, 0, -6, -22, - 6, -22, -13, -19, 12, -19, 0, -18, -5, -17, 5, -17, -10, -15, 10, -15, - 0, -14, -4, -13, 4, -13, 19, -13, -19, -12, -8, -11, -2, -11, 0, -11, - 2, -11, 8, -11, -15, -10, -4, -10, 4, -10, 15, -10, -6, -9, -1, -9, - 1, -9, 6, -9, -11, -8, -8, -8, -3, -8, 0, -8, 3, -8, 8, -8, - 11, -8, -5, -7, -2, -7, 0, -7, 2, -7, 5, -7, -22, -6, -9, -6, - -6, -6, -3, -6, -1, -6, 1, -6, 3, -6, 6, -6, 9, -6, 22, -6, - -17, -5, -7, -5, -4, -5, -2, -5, -1, -5, 0, -5, 1, -5, 2, -5, - 4, -5, 7, -5, 17, -5, -13, -4, -10, -4, -5, -4, -3, -4, -2, -4, - -1, -4, 0, -4, 1, -4, 2, -4, 3, -4, 5, -4, 10, -4, 13, -4, - -8, -3, -6, -3, -4, -3, -3, -3, -2, -3, -1, -3, 0, -3, 1, -3, - 2, -3, 3, -3, 4, -3, 6, -3, 8, -3, -11, -2, -7, -2, -5, -2, - -4, -2, -3, -2, -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, 3, -2, - 4, -2, 5, -2, 7, -2, 11, -2, -9, -1, -6, -1, -5, -1, -4, -1, - -3, -1, -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, - 5, -1, 6, -1, 9, -1, -23, 0, -18, 0, -14, 0, -11, 0, -7, 0, - -5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 0, -23, 1, 0, 2, 0, - 3, 0, 4, 0, 5, 0, 7, 0, 11, 0, 14, 0, 18, 0, 23, 0, - -9, 1, -6, 1, -5, 1, -4, 1, -3, 1, -2, 1, -1, 1, 0, 1, - 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 9, 1, -11, 2, - -7, 2, -5, 2, -4, 2, -3, 2, -2, 2, -1, 2, 0, 2, 1, 2, - 2, 2, 3, 2, 4, 2, 5, 2, 7, 2, 11, 2, -8, 3, -6, 3, - -4, 3, -3, 3, -2, 3, -1, 3, 0, 3, 1, 3, 2, 3, 3, 3, - 4, 3, 6, 3, 8, 3, -13, 4, -10, 4, -5, 4, -3, 4, -2, 4, - -1, 4, 0, 4, 1, 4, 2, 4, 3, 4, 5, 4, 10, 4, 13, 4, - -17, 5, -7, 5, -4, 5, -2, 5, -1, 5, 0, 5, 1, 5, 2, 5, - 4, 5, 7, 5, 17, 5, -22, 6, -9, 6, -6, 6, -3, 6, -1, 6, - 1, 6, 3, 6, 6, 6, 9, 6, 22, 6, -5, 7, -2, 7, 0, 7, - 2, 7, 5, 7, -11, 8, -8, 8, -3, 8, 0, 8, 3, 8, 8, 8, - 11, 8, -6, 9, -1, 9, 1, 9, 6, 9, -15, 10, -4, 10, 4, 10, - 15, 10, -8, 11, -2, 11, 0, 11, 2, 11, 8, 11, 19, 12, -19, 13, - -4, 13, 4, 13, 0, 14, -10, 15, 10, 15, -5, 17, 5, 17, 0, 18, - -12, 19, 13, 19, -6, 22, 6, 22, 0, 23, + 0, 0, 1, 0, 2, 0, 3, 0, 5, 0, + 8, 0, 13, 0, 21, 0, -1, 0, -2, 0, + -3, 0, -5, 0, -8, 0, -13, 0, -17, 0, + -21, 0, 0, 1, 1, 1, 2, 1, 3, 1, + 5, 1, 8, 1, 13, 1, 21, 1, -1, 1, + -2, 1, -3, 1, -5, 1, -8, 1, -13, 1, + -17, 1, -21, 1, 0, 2, 1, 2, 2, 2, + 3, 2, 5, 2, 8, 2, 13, 2, 21, 2, + -1, 2, -2, 2, -3, 2, -5, 2, -8, 2, + -13, 2, -17, 2, -21, 2, 0, 3, 1, 3, + 2, 3, 3, 3, 5, 3, 8, 3, 13, 3, + 21, 3, -1, 3, -2, 3, -3, 3, -5, 3, + -8, 3, -13, 3, -17, 3, -21, 3, 0, 5, + 1, 5, 2, 5, 3, 5, 5, 5, 8, 5, + 13, 5, 21, 5, -1, 5, -2, 5, -3, 5, + -5, 5, -8, 5, -13, 5, -17, 5, -21, 5, + 0, 8, 1, 8, 2, 8, 3, 8, 5, 8, + 8, 8, 13, 8, 21, 8, -1, 8, -2, 8, + -3, 8, -5, 8, -8, 8, -13, 8, -17, 8, + -21, 8, 0, 13, 1, 13, 2, 13, 3, 13, + 5, 13, 8, 13, 13, 13, 21, 13, -1, 13, + -2, 13, -3, 13, -5, 13, -8, 13, -13, 13, + -17, 13, -21, 13, 0, 21, 1, 21, 2, 21, + 3, 21, 5, 21, 8, 21, 13, 21, 21, 21, + -1, 21, -2, 21, -3, 21, -5, 21, -8, 21, + -13, 21, -17, 21, -21, 21, 0, -1, 1, -1, + 2, -1, 3, -1, 5, -1, 8, -1, 13, -1, + 21, -1, -1, -1, -2, -1, -3, -1, -5, -1, + -8, -1, -13, -1, -17, -1, -21, -1, 0, -2, + 1, -2, 2, -2, 3, -2, 5, -2, 8, -2, + 13, -2, 21, -2, -1, -2, -2, -2, -3, -2, + -5, -2, -8, -2, -13, -2, -17, -2, -21, -2, + 0, -3, 1, -3, 2, -3, 3, -3, 5, -3, + 8, -3, 13, -3, 21, -3, -1, -3, -2, -3, + -3, -3, -5, -3, -8, -3, -13, -3, -17, -3, + -21, -3, 0, -5, 1, -5, 2, -5, 3, -5, + 5, -5, 8, -5, 13, -5, 21, -5, -1, -5, + -2, -5, -3, -5, -5, -5, -8, -5, -13, -5, + -17, -5, -21, -5, 0, -8, 1, -8, 2, -8, + 3, -8, 5, -8, 8, -8, 13, -8, 21, -8, + -1, -8, -2, -8, -3, -8, -5, -8, -8, -8, + -13, -8, -17, -8, -21, -8, 0, -13, 1, -13, + 2, -13, 3, -13, 5, -13, 8, -13, 13, -13, + 21, -13, -1, -13, -2, -13, -3, -13, -5, -13, + -8, -13, -13, -13, -17, -13, -21, -13, 0, -17, + 1, -17, 2, -17, 3, -17, 5, -17, 8, -17, + 13, -17, 21, -17, -1, -17, -2, -17, -3, -17, + -5, -17, -8, -17, -13, -17, -17, -17, -21, -17, + 0, -21, 1, -21, 2, -21, 3, -21, 5, -21, + 8, -21, 13, -21, 21, -21, -1, -21, -2, -21, + -3, -21, -5, -21, -8, -21, -13, -21, -17, -21, + 0, 0, -8, -29, 8, -29, -18, -25, 17, -25, + 0, -23, -6, -22, 6, -22, -13, -19, 12, -19, + 0, -18, 25, -18, -25, -17, -5, -17, 5, -17, + -10, -15, 10, -15, 0, -14, -4, -13, 4, -13, + 19, -13, -19, -12, -8, -11, -2, -11, 0, -11, + 2, -11, 8, -11, -15, -10, -4, -10, 4, -10, + 15, -10, -6, -9, -1, -9, 1, -9, 6, -9, + -29, -8, -11, -8, -8, -8, -3, -8, 3, -8, + 8, -8, 11, -8, 29, -8, -5, -7, -2, -7, + 0, -7, 2, -7, 5, -7, -22, -6, -9, -6, + -6, -6, -3, -6, -1, -6, 1, -6, 3, -6, + 6, -6, 9, -6, 22, -6, -17, -5, -7, -5, + -4, -5, -2, -5, 0, -5, 2, -5, 4, -5, + 7, -5, 17, -5, -13, -4, -10, -4, -5, -4, + -3, -4, -1, -4, 0, -4, 1, -4, 3, -4, + 5, -4, 10, -4, 13, -4, -8, -3, -6, -3, + -4, -3, -3, -3, -2, -3, -1, -3, 0, -3, + 1, -3, 2, -3, 4, -3, 6, -3, 8, -3, + -11, -2, -7, -2, -5, -2, -3, -2, -2, -2, + -1, -2, 0, -2, 1, -2, 2, -2, 3, -2, + 5, -2, 7, -2, 11, -2, -9, -1, -6, -1, + -4, -1, -3, -1, -2, -1, -1, -1, 0, -1, + 1, -1, 2, -1, 3, -1, 4, -1, 6, -1, + 9, -1, -31, 0, -23, 0, -18, 0, -14, 0, + -11, 0, -7, 0, -5, 0, -4, 0, -3, 0, + -2, 0, -1, 0, 0, -31, 1, 0, 2, 0, + 3, 0, 4, 0, 5, 0, 7, 0, 11, 0, + 14, 0, 18, 0, 23, 0, 31, 0, -9, 1, + -6, 1, -4, 1, -3, 1, -2, 1, -1, 1, + 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, + 6, 1, 9, 1, -11, 2, -7, 2, -5, 2, + -3, 2, -2, 2, -1, 2, 0, 2, 1, 2, + 2, 2, 3, 2, 5, 2, 7, 2, 11, 2, + -8, 3, -6, 3, -4, 3, -2, 3, -1, 3, + 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, + 6, 3, 8, 3, -13, 4, -10, 4, -5, 4, + -3, 4, -1, 4, 0, 4, 1, 4, 3, 4, + 5, 4, 10, 4, 13, 4, -17, 5, -7, 5, + -4, 5, -2, 5, 0, 5, 2, 5, 4, 5, + 7, 5, 17, 5, -22, 6, -9, 6, -6, 6, + -3, 6, -1, 6, 1, 6, 3, 6, 6, 6, + 9, 6, 22, 6, -5, 7, -2, 7, 0, 7, + 2, 7, 5, 7, -29, 8, -11, 8, -8, 8, + -3, 8, 3, 8, 8, 8, 11, 8, 29, 8, + -6, 9, -1, 9, 1, 9, 6, 9, -15, 10, + -4, 10, 4, 10, 15, 10, -8, 11, -2, 11, + 0, 11, 2, 11, 8, 11, 19, 12, -19, 13, + -4, 13, 4, 13, 0, 14, -10, 15, 10, 15, + -5, 17, 5, 17, 25, 17, -25, 18, 0, 18, + -12, 19, 13, 19, -6, 22, 6, 22, 0, 23, + -17, 25, 18, 25, -8, 29, 8, 29, 0, 31, + 0, 0, -6, -22, 6, -22, -13, -19, 12, -19, + 0, -18, -5, -17, 5, -17, -10, -15, 10, -15, + 0, -14, -4, -13, 4, -13, 19, -13, -19, -12, + -8, -11, -2, -11, 0, -11, 2, -11, 8, -11, + -15, -10, -4, -10, 4, -10, 15, -10, -6, -9, + -1, -9, 1, -9, 6, -9, -11, -8, -8, -8, + -3, -8, 0, -8, 3, -8, 8, -8, 11, -8, + -5, -7, -2, -7, 0, -7, 2, -7, 5, -7, + -22, -6, -9, -6, -6, -6, -3, -6, -1, -6, + 1, -6, 3, -6, 6, -6, 9, -6, 22, -6, + -17, -5, -7, -5, -4, -5, -2, -5, -1, -5, + 0, -5, 1, -5, 2, -5, 4, -5, 7, -5, + 17, -5, -13, -4, -10, -4, -5, -4, -3, -4, + -2, -4, -1, -4, 0, -4, 1, -4, 2, -4, + 3, -4, 5, -4, 10, -4, 13, -4, -8, -3, + -6, -3, -4, -3, -3, -3, -2, -3, -1, -3, + 0, -3, 1, -3, 2, -3, 3, -3, 4, -3, + 6, -3, 8, -3, -11, -2, -7, -2, -5, -2, + -4, -2, -3, -2, -2, -2, -1, -2, 0, -2, + 1, -2, 2, -2, 3, -2, 4, -2, 5, -2, + 7, -2, 11, -2, -9, -1, -6, -1, -5, -1, + -4, -1, -3, -1, -2, -1, -1, -1, 0, -1, + 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, + 6, -1, 9, -1, -23, 0, -18, 0, -14, 0, + -11, 0, -7, 0, -5, 0, -4, 0, -3, 0, + -2, 0, -1, 0, 0, -23, 1, 0, 2, 0, + 3, 0, 4, 0, 5, 0, 7, 0, 11, 0, + 14, 0, 18, 0, 23, 0, -9, 1, -6, 1, + -5, 1, -4, 1, -3, 1, -2, 1, -1, 1, + 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, + 5, 1, 6, 1, 9, 1, -11, 2, -7, 2, + -5, 2, -4, 2, -3, 2, -2, 2, -1, 2, + 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, + 5, 2, 7, 2, 11, 2, -8, 3, -6, 3, + -4, 3, -3, 3, -2, 3, -1, 3, 0, 3, + 1, 3, 2, 3, 3, 3, 4, 3, 6, 3, + 8, 3, -13, 4, -10, 4, -5, 4, -3, 4, + -2, 4, -1, 4, 0, 4, 1, 4, 2, 4, + 3, 4, 5, 4, 10, 4, 13, 4, -17, 5, + -7, 5, -4, 5, -2, 5, -1, 5, 0, 5, + 1, 5, 2, 5, 4, 5, 7, 5, 17, 5, + -22, 6, -9, 6, -6, 6, -3, 6, -1, 6, + 1, 6, 3, 6, 6, 6, 9, 6, 22, 6, + -5, 7, -2, 7, 0, 7, 2, 7, 5, 7, + -11, 8, -8, 8, -3, 8, 0, 8, 3, 8, + 8, 8, 11, 8, -6, 9, -1, 9, 1, 9, + 6, 9, -15, 10, -4, 10, 4, 10, 15, 10, + -8, 11, -2, 11, 0, 11, 2, 11, 8, 11, + 19, 12, -19, 13, -4, 13, 4, 13, 0, 14, + -10, 15, 10, 15, -5, 17, 5, 17, 0, 18, + -12, 19, 13, 19, -6, 22, 6, 22, 0, 23, }; if (_tableLastPitch == pitch && _tableLastIndex == index) return; -#ifdef DEBUG_CODEC37 - debug(7, "codec37::maketable(%d, %d) called", pitch, index); -#endif _tableLastPitch = pitch; _tableLastIndex = index; index *= 255; assert(index + 254 < (int32)(sizeof(maketable_bytes) / 2)); for (int32 i = 0; i < 255; i++) { - int32 j = (i + index) << 1; // * 2 + int32 j = (i + index) << 1; _offsetTable[i] = maketable_bytes[j + 1] * pitch + maketable_bytes[j]; } } -void Codec37Decoder::proc1(Blitter & dst, Chunk & src, int32 next_offs, int32 bw, int32 bh, int32 size) { - byte * decoded = new byte[size]; - int32 w = 0; - while(!src.eof()) { - int32 code = src.getByte(); - int32 length = (code >> 1) + 1; +void Codec37Decoder::bompDecode(byte *dst, byte *src, int32 len) { + byte code; + byte color; + int32 num; + + do { + code = *src++; + num = (code >> 1) + 1; if (code & 1) { - byte val = src.getByte(); - while(length--) - decoded[w++] = val; - } else { - while(length--) { - decoded[w++] = src.getByte(); - } - } - } - assert(w == size); - w = 0; - // Now we have our stream ready... - for(int32 i = 0; i < size; i++) { - if(decoded[i] == 0xFF) { - dst.putBlock(decoded + i + 1); - i += 16; + color = *src++; + memset(dst, color, num); } else { - dst.blockCopy(_offsetTable[decoded[i]] + next_offs); + memcpy(dst, src, num); + src += num; } - if(++w == bw) { - w = 0; - dst.advance(0, 3); - } - } - delete []decoded; + dst += num; + len -= num; + } while (len > 0); + assert(len == 0); } -void Codec37Decoder::proc2(Blitter & dst, Chunk & src, int32 size) { // This is codec1 like... -#ifdef DEBUG_CODEC37_PROC2 - int32 decoded_size = 0; - int32 coded_size = 0; -#endif - do { - int32 code = src.getByte(); - int32 length = (code >> 1) + 1; - size -= length; -#ifdef DEBUG_CODEC37_PROC2 - decoded_size += length; - coded_size += 1 + ((code & 1) ? 1 : length); - - debug(7, "proc2() : code == %d : length == %d : decoded_size == %d : coded_size == %d : seek - header == %d : size == %d", - code, length, decoded_size, coded_size, src.tell() - 31, size + decoded_size); -#endif - if (code & 1) - dst.put(src.getChar(), length); - else - // while(length--) dst.put(src.get_char()); - dst.blit(src, length); - } while (size); -} +void Codec37Decoder::proc3WithFDFE(byte *dst, byte *src, int32 next_offs, int32 bw, int32 bh, int32 pitch, int16 *offset_table) { + uint32 t; -void Codec37Decoder::proc3WithFDFE(Blitter & dst, Chunk & src, int32 next_offs, int32 bw, int32 bh) { do { int32 i = bw; do { - int32 code = src.getByte(); + int32 code = *src++; if (code == 0xFD) { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(1)); -#else - dst.putBlock(expand(src.getByte())); -#endif + t = *src++; + t += (t << 8) + (t << 16) + (t << 24); + *(uint32*)(dst + pitch * 0) = t; + *(uint32*)(dst + pitch * 1) = t; + *(uint32*)(dst + pitch * 2) = t; + *(uint32*)(dst + pitch * 3) = t; + dst += 4; } else if (code == 0xFE) { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(2)); -#else - dst.putBlock(expand(src.getByte()), expand(src.getByte()), expand(src.getByte()), expand(src.getByte())); -#endif + t = *src++; + t += (t << 8) + (t << 16) + (t << 24); + *(uint32*)(dst + pitch * 0) = t; + t = *src++; + t += (t << 8) + (t << 16) + (t << 24); + *(uint32*)(dst + pitch * 1) = t; + t = *src++; + t += (t << 8) + (t << 16) + (t << 24); + *(uint32*)(dst + pitch * 2) = t; + t = *src++; + t += (t << 8) + (t << 16) + (t << 24); + *(uint32*)(dst + pitch * 3) = t; + dst += 4; } else if (code == 0xFF) { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(3)); -#else - dst.putBlock(src); -#endif + *(uint32*)(dst + pitch * 0) = *(uint32*)src; + src += 4; + *(uint32*)(dst + pitch * 1) = *(uint32*)src; + src += 4; + *(uint32*)(dst + pitch * 2) = *(uint32*)src; + src += 4; + *(uint32*)(dst + pitch * 3) = *(uint32*)src; + src += 4; + dst += 4; } else { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(4)); -#else - dst.blockCopy(_offsetTable[code] + next_offs); // copy from an offset ! -#endif + byte *dst2 = dst + _offsetTable[code] + next_offs; + *(uint32*)(dst + pitch * 0) = *(uint32*)(dst2 + pitch * 0); + *(uint32*)(dst + pitch * 1) = *(uint32*)(dst2 + pitch * 1); + *(uint32*)(dst + pitch * 2) = *(uint32*)(dst2 + pitch * 2); + *(uint32*)(dst + pitch * 3) = *(uint32*)(dst2 + pitch * 3); + dst += 4; } } while (--i); - dst.advance(0, 3); // advance 3 lines + dst += pitch * 3; } while (--bh); } -void Codec37Decoder::proc3WithoutFDFE(Blitter & dst, Chunk & src, int32 next_offs, int32 bw, int32 bh) { +void Codec37Decoder::proc3WithoutFDFE(byte *dst, byte *src, int32 next_offs, int32 bw, int32 bh, int32 pitch, int16 *offset_table) { do { int32 i = bw; do { - int32 code = src.getByte(); + int32 code = *src++; if (code == 0xFF) { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(5)); -#else - dst.putBlock(src); -#endif + *(uint32*)(dst + pitch * 0) = *(uint32*)src; + src += 4; + *(uint32*)(dst + pitch * 1) = *(uint32*)src; + src += 4; + *(uint32*)(dst + pitch * 2) = *(uint32*)src; + src += 4; + *(uint32*)(dst + pitch * 3) = *(uint32*)src; + src += 4; + dst += 4; } else { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(6)); -#else - dst.blockCopy(_offsetTable[code] + next_offs); // copy from an offset ! -#endif + byte *dst2 = dst + _offsetTable[code] + next_offs; + *(uint32*)(dst + pitch * 0) = *(uint32*)(dst2 + pitch * 0); + *(uint32*)(dst + pitch * 1) = *(uint32*)(dst2 + pitch * 1); + *(uint32*)(dst + pitch * 2) = *(uint32*)(dst2 + pitch * 2); + *(uint32*)(dst + pitch * 3) = *(uint32*)(dst2 + pitch * 3); + dst += 4; } } while (--i); - dst.advance(0, 3); // advance 3 lines + dst += pitch * 3; } while (--bh); } -void Codec37Decoder::proc4WithFDFE(Blitter & dst, Chunk & src, int32 next_offs, int32 bw, int32 bh) { +void Codec37Decoder::proc4WithFDFE(byte *dst, byte *src, int32 next_offs, int32 bw, int32 bh, int32 pitch, int16 *offset_table) { + uint32 t; + do { int32 i = bw; do { - int32 code = src.getByte(); + int32 code = *src++; if (code == 0xFD) { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(7)); -#else - dst.putBlock(expand(src.getByte())); -#endif + t = *src++; + t += (t << 8) + (t << 16) + (t << 24); + *(uint32*)(dst + pitch * 0) = t; + *(uint32*)(dst + pitch * 1) = t; + *(uint32*)(dst + pitch * 2) = t; + *(uint32*)(dst + pitch * 3) = t; + dst += 4; } else if (code == 0xFE) { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(8)); -#else - dst.putBlock(expand(src.getByte()), expand(src.getByte()), expand(src.getByte()), expand(src.getByte())); -#endif + t = *src++; + t += (t << 8) + (t << 16) + (t << 24); + *(uint32*)(dst + pitch * 0) = t; + t = *src++; + t += (t << 8) + (t << 16) + (t << 24); + *(uint32*)(dst + pitch * 1) = t; + t = *src++; + t += (t << 8) + (t << 16) + (t << 24); + *(uint32*)(dst + pitch * 2) = t; + t = *src++; + t += (t << 8) + (t << 16) + (t << 24); + *(uint32*)(dst + pitch * 3) = t; + dst += 4; } else if (code == 0xFF) { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(9)); -#else - dst.putBlock(src); -#endif + *(uint32*)(dst + pitch * 0) = *(uint32*)src; + src += 4; + *(uint32*)(dst + pitch * 1) = *(uint32*)src; + src += 4; + *(uint32*)(dst + pitch * 2) = *(uint32*)src; + src += 4; + *(uint32*)(dst + pitch * 3) = *(uint32*)src; + src += 4; + dst += 4; } else if (code == 0x00) { - int32 length = src.getByte() + 1; + int32 length = *src++ + 1; for (int32 l = 0; l < length; l++) { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(10)); -#else - dst.blockCopy(next_offs); -#endif + byte *dst2 = dst + next_offs; + *(uint32*)(dst + pitch * 0) = *(uint32*)(dst2 + pitch * 0); + *(uint32*)(dst + pitch * 1) = *(uint32*)(dst2 + pitch * 1); + *(uint32*)(dst + pitch * 2) = *(uint32*)(dst2 + pitch * 2); + *(uint32*)(dst + pitch * 3) = *(uint32*)(dst2 + pitch * 3); + dst += 4; i--; if (i == 0) { - dst.advance(0, 3); // advance 3 lines + dst += pitch * 3; bh--; i = bw; } } - if(bh == 0) return; + if(bh == 0) { + return; + } i++; } else { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(11)); -#else - dst.blockCopy(_offsetTable[code] + next_offs); // copy from an offset ! -#endif + byte *dst2 = dst + _offsetTable[code] + next_offs; + *(uint32*)(dst + pitch * 0) = *(uint32*)(dst2 + pitch * 0); + *(uint32*)(dst + pitch * 1) = *(uint32*)(dst2 + pitch * 1); + *(uint32*)(dst + pitch * 2) = *(uint32*)(dst2 + pitch * 2); + *(uint32*)(dst + pitch * 3) = *(uint32*)(dst2 + pitch * 3); + dst += 4; } } while (--i); - dst.advance(0, 3); // advance 3 lines + dst += pitch * 3; } while (--bh); } -void Codec37Decoder::proc4WithoutFDFE(Blitter & dst, Chunk & src, int32 next_offs, int32 bw, int32 bh) { +void Codec37Decoder::proc4WithoutFDFE(byte *dst, byte *src, int32 next_offs, int32 bw, int32 bh, int32 pitch, int16 *offset_table) { do { int32 i = bw; do { - int32 code = src.getByte(); + int32 code = *src++; if (code == 0xFF) { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(9)); -#else - dst.putBlock(src); -#endif + *(uint32*)(dst + pitch * 0) = *(uint32*)src; + src += 4; + *(uint32*)(dst + pitch * 1) = *(uint32*)src; + src += 4; + *(uint32*)(dst + pitch * 2) = *(uint32*)src; + src += 4; + *(uint32*)(dst + pitch * 3) = *(uint32*)src; + src += 4; + dst += 4; } else if (code == 0x00) { - int32 length = src.getByte() + 1; + int32 length = *src++ + 1; for (int32 l = 0; l < length; l++) { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(10)); -#else - dst.blockCopy(next_offs); -#endif + byte *dst2 = dst + next_offs; + *(uint32*)(dst + pitch * 0) = *(uint32*)(dst2 + pitch * 0); + *(uint32*)(dst + pitch * 1) = *(uint32*)(dst2 + pitch * 1); + *(uint32*)(dst + pitch * 2) = *(uint32*)(dst2 + pitch * 2); + *(uint32*)(dst + pitch * 3) = *(uint32*)(dst2 + pitch * 3); + dst += 4; i--; if (i == 0) { - dst.advance(0, 3); // advance 3 lines + dst += pitch * 3; bh--; i = bw; } } - if(bh == 0) return; + if(bh == 0) { + return; + } i++; } else { -#ifdef USE_COLOR_CODE_FOR_BLOCK - dst.putBlock(expand(11)); -#else - dst.blockCopy(_offsetTable[code] + next_offs); // copy from an offset ! -#endif + byte *dst2 = dst + _offsetTable[code] + next_offs; + *(uint32*)(dst + pitch * 0) = *(uint32*)(dst2 + pitch * 0); + *(uint32*)(dst + pitch * 1) = *(uint32*)(dst2 + pitch * 1); + *(uint32*)(dst + pitch * 2) = *(uint32*)(dst2 + pitch * 2); + *(uint32*)(dst + pitch * 3) = *(uint32*)(dst2 + pitch * 3); + dst += 4; } } while (--i); - dst.advance(0, 3); // advance 3 lines + dst += pitch * 3; } while (--bh); } @@ -415,68 +485,79 @@ bool Codec37Decoder::decode(Blitter & dst, Chunk & src) { int32 height = getRect().height(); int32 bw = (width + 3) >> 2, bh = (height + 3) >> 2; int32 pitch = bw << 2; -#ifdef DEBUG_CODEC37 - debug(7, "codec37::decode() : width == %d : height == %d : pitch == %d : _prevSeqNb == %d", - width, height, pitch, _prevSeqNb); -#endif - int32 code = src.getByte(); // 0 -> 1 (1) - int32 index = src.getByte(); // 1 -> 2 (1) - uint16 seq_nb = src.getWord(); // 2 -> 4 (2) - uint32 decoded_size = src.getDword(); // 4 -> 8 (4) -#ifdef DEBUG_CODEC37 - uint32 coded_size = src.getDword(); // 8 -> 12 (4) -#else - src.seek(4); -#endif - uint32 mask_flag = src.getDword(); // 12 -> 16 (4) -#ifdef DEBUG_CODEC37 - debug(7, "codec37::decode() : code == %d : index == %d : seq_nb == %d : decoded_size == %d : coded_size == %d : mask_flag == %d", - code, index, seq_nb, decoded_size, coded_size, mask_flag); -#endif - maketable(pitch, index); - if(code == 3 || code == 4 || code == 1) { - assert(seq_nb && _prevSeqNb + 1 == seq_nb); - if (seq_nb & 1 || !(mask_flag & 1)) _curtable ^= 1; - } - Blitter blit((byte *)_deltaBufs[_curtable], Point(width, height), Rect(0, 0, width, height)); - switch(code) { + + int32 chunk_size = src.getSize() - 14; + byte * chunk_buffer = (byte*)malloc(chunk_size); + src.read(chunk_buffer, chunk_size); + + int16 seq_nb = READ_LE_UINT16(chunk_buffer + 2); + int32 decoded_size = READ_LE_UINT32(chunk_buffer + 4); + byte mask_flags = chunk_buffer[12]; + maketable(pitch, chunk_buffer[1]); + int32 tmp; + + switch(chunk_buffer[0]) { case 0: - memset(_deltaBuf, 0, _deltaBufs[_curtable] - _deltaBuf); - memset(_deltaBufs[_curtable] + decoded_size, 0, _deltaBuf + _deltaSize - _deltaBufs[_curtable] - decoded_size); - blit.blit(src, decoded_size); + if ((_deltaBufs[_curtable] - _deltaBuf) > 0) { + memset(_deltaBuf, 0, _deltaBufs[_curtable] - _deltaBuf); + } + tmp = (_deltaBuf + _deltaSize) - _deltaBufs[_curtable] - decoded_size; + if (tmp > 0) { + memset(_deltaBufs[_curtable] + decoded_size, 0, tmp); + } + memcpy(_deltaBufs[_curtable], chunk_buffer + 16, decoded_size); break; case 1: - proc1(blit, src, _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh, decoded_size); + error("missing opcode codec47"); break; case 2: - memset(_deltaBuf, 0, _deltaBufs[_curtable] - _deltaBuf); - memset(_deltaBufs[_curtable] + decoded_size, 0, _deltaBuf + _deltaSize - _deltaBufs[_curtable] - decoded_size); - proc2(blit, src, decoded_size); + bompDecode(_deltaBufs[_curtable], chunk_buffer + 16, decoded_size); + if ((_deltaBufs[_curtable] - _deltaBuf) > 0) { + memset(_deltaBuf, 0, _deltaBufs[_curtable] - _deltaBuf); + } + tmp = (_deltaBuf + _deltaSize) - _deltaBufs[_curtable] - decoded_size; + if (tmp > 0) { + memset(_deltaBufs[_curtable] + decoded_size, 0, tmp); + } break; case 3: - if(mask_flag & 4) - proc3WithFDFE(blit, src, _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh); - else - proc3WithoutFDFE(blit, src, _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh); + if ((seq_nb & 1) || !(mask_flags & 1)) { + _curtable ^= 1; + } + + if((mask_flags & 4) != 0) { + proc3WithFDFE(_deltaBufs[_curtable], chunk_buffer + 16, + _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh, + pitch, _offsetTable); + } else { + proc3WithoutFDFE(_deltaBufs[_curtable], chunk_buffer + 16, + _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh, + pitch, _offsetTable); + } break; case 4: - if(mask_flag & 4) - proc4WithFDFE(blit, src, _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh); - else - proc4WithoutFDFE(blit, src, _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh); + if ((seq_nb & 1) || !(mask_flags & 1)) { + _curtable ^= 1; + } + + if((mask_flags & 4) != 0) { + proc4WithFDFE(_deltaBufs[_curtable], chunk_buffer + 16, + _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh, + pitch, _offsetTable); + } else { + proc4WithoutFDFE(_deltaBufs[_curtable], chunk_buffer + 16, + _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh, + pitch, _offsetTable); + } break; default: -#ifdef DEBUG_CODEC37 - error("codec37::decode() received an invalid code : %d", code); -#endif break; } - if(mask_flag & 2) { - error("smush:codec37 missing transparent_blitting"); - } else { - dst.blit((byte *)_deltaBufs[_curtable], width * height); - } _prevSeqNb = seq_nb; + + dst.blit(_deltaBufs[_curtable], width * height); + + free(chunk_buffer); return true; } diff --git a/scumm/smush/codec37.h b/scumm/smush/codec37.h index 14908d3cb0..a820aaf689 100644 --- a/scumm/smush/codec37.h +++ b/scumm/smush/codec37.h @@ -22,36 +22,8 @@ #ifndef CODEC37_H #define CODEC37_H -#include "config.h" - -#ifdef DEBUG -# ifndef NO_DEBUG_CODEC37 -# define DEBUG_CODEC37 -# endif -#else -# ifdef DEBUG_CODEC37 -# error DEBUG_CODEC37 defined without DEBUG -# endif -#endif - -#ifdef DEBUG_CODEC37 -# ifndef NO_DEBUG_CODEC37_PROCS -# define DEBUG_CODEC37_PROC1 -# define DEBUG_CODEC37_PROC2 -# define DEBUG_CODEC37_PROC3 -# define DEBUG_CODEC37_PROC4 -# endif -#endif - #include "decoder.h" -/*! @brief ::decoder for codec 37. - -*/ - -#define DELTA_ADD 0x3E00 // what is this 0x3E00 ?? == 320*200/4 - 128 - // It looks like it is a safe-guarding protection from bugs., but maybe not... - class Codec37Decoder : public Decoder { private: int32 _deltaSize; @@ -69,17 +41,12 @@ public: void clean(); virtual ~Codec37Decoder(); protected: - static inline uint32 expand(byte b) { - uint32 r = b | (b << 8); - return r | (r << 16); - } void maketable(int32, int32); - void proc1(Blitter &, Chunk &, int32, int32, int32, int32); - void proc2(Blitter &, Chunk &, int32); - void proc3WithFDFE(Blitter &, Chunk &, int32, int32, int32); - void proc3WithoutFDFE(Blitter &, Chunk &, int32, int32, int32); - void proc4WithFDFE(Blitter &, Chunk &, int32, int32, int32); - void proc4WithoutFDFE(Blitter &, Chunk &, int32, int32, int32); + void bompDecode(byte *dst, byte *src, int32 len); + void proc3WithFDFE(byte *, byte *, int32, int32, int32, int32, int16 *); + void proc3WithoutFDFE(byte *, byte *, int32, int32, int32, int32, int16 *); + void proc4WithFDFE(byte *, byte *, int32, int32, int32, int32, int16 *); + void proc4WithoutFDFE(byte *, byte *, int32, int32, int32, int32, int16 *); public: bool decode(Blitter &, Chunk &); }; |