Initial commit
This commit is contained in:
39
engines/scumm/smush/codec1.cpp
Normal file
39
engines/scumm/smush/codec1.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "common/endian.h"
|
||||
|
||||
#include "scumm/bomp.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
void smushDecodeRLE(byte *dst, const byte *src, int left, int top, int width, int height, int pitch) {
|
||||
dst += top * pitch;
|
||||
do {
|
||||
dst += left;
|
||||
bompDecodeLine(dst, src + 2, width, false);
|
||||
src += READ_LE_UINT16(src) + 2;
|
||||
dst += pitch - left;
|
||||
} while (--height);
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
40
engines/scumm/smush/codec20.cpp
Normal file
40
engines/scumm/smush/codec20.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "common/endian.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
void smushDecodeUncompressed(byte *dst, const byte *src, int left, int top, int width, int height, int pitch) {
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
dst += left * pitch + top;
|
||||
|
||||
while (height--) {
|
||||
memcpy(dst, src, width);
|
||||
src += width;
|
||||
dst += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
614
engines/scumm/smush/codec37.cpp
Normal file
614
engines/scumm/smush/codec37.cpp
Normal file
@@ -0,0 +1,614 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "common/endian.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "common/util.h"
|
||||
#include "scumm/bomp.h"
|
||||
#include "scumm/smush/codec37.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
SmushDeltaBlocksDecoder::SmushDeltaBlocksDecoder(int width, int height) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
_frameSize = _width * _height;
|
||||
_deltaSize = _frameSize * 3 + 0x13600;
|
||||
_deltaBuf = (byte *)calloc(_deltaSize, sizeof(byte));
|
||||
if (_deltaBuf == nullptr)
|
||||
error("SmushDeltaBlocksDecoder::SmushDeltaBlocksDecoder(): ERROR: Unable to allocate decoder buffer.");
|
||||
_deltaBufs[0] = _deltaBuf + 0x4D80;
|
||||
_deltaBufs[1] = _deltaBuf + 0xE880 + _frameSize;
|
||||
_offsetTable = new int16[255];
|
||||
if (_offsetTable == nullptr)
|
||||
error("SmushDeltaBlocksDecoder::SmushDeltaBlocksDecoder(): ERROR: Unable to allocate decoder offset table.");
|
||||
_curTable = 0;
|
||||
_prevSeqNb = 0;
|
||||
_tableLastPitch = -1;
|
||||
_tableLastIndex = -1;
|
||||
}
|
||||
|
||||
SmushDeltaBlocksDecoder::~SmushDeltaBlocksDecoder() {
|
||||
if (_offsetTable) {
|
||||
delete[] _offsetTable;
|
||||
_offsetTable = nullptr;
|
||||
_tableLastPitch = -1;
|
||||
_tableLastIndex = -1;
|
||||
}
|
||||
if (_deltaBuf) {
|
||||
free(_deltaBuf);
|
||||
_deltaSize = 0;
|
||||
_deltaBuf = nullptr;
|
||||
_deltaBufs[0] = nullptr;
|
||||
_deltaBufs[1] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SmushDeltaBlocksDecoder::makeTable(int pitch, int index) {
|
||||
static const int8 makeTableBytes[] = {
|
||||
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;
|
||||
|
||||
_tableLastPitch = pitch;
|
||||
_tableLastIndex = index;
|
||||
index *= 255;
|
||||
assert(index + 254 < (int32)(sizeof(makeTableBytes) / 2));
|
||||
|
||||
for (int32 i = 0; i < 255; i++) {
|
||||
int32 j = (i + index) * 2;
|
||||
_offsetTable[i] = makeTableBytes[j + 1] * pitch + makeTableBytes[j];
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SCUMM_NEED_ALIGNMENT)
|
||||
|
||||
#define DECLARE_LITERAL_TEMP(v) \
|
||||
byte v
|
||||
|
||||
#define READ_LITERAL_PIXEL(src, v) \
|
||||
v = *src++
|
||||
|
||||
#define READ_LITERAL_2PIXEL(src, v) \
|
||||
do { \
|
||||
v = *src | (*src << 8); \
|
||||
src++; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_4X1_LINE(dst, v) \
|
||||
do { \
|
||||
int j; \
|
||||
for (j = 0; j < 4; j++) \
|
||||
(dst)[j] = v; \
|
||||
} while (0)
|
||||
|
||||
#define COPY_4X1_LINE(dst, src) \
|
||||
do { \
|
||||
int j; \
|
||||
for (j = 0; j < 4; j++) \
|
||||
(dst)[j] = (src)[j]; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_2X1_LINE(dst, v) \
|
||||
do { \
|
||||
int j; \
|
||||
for (j = 0; j < 2; j++) \
|
||||
(dst)[j] = v; \
|
||||
} while (0)
|
||||
|
||||
#else /* SCUMM_NEED_ALIGNMENT */
|
||||
|
||||
#define DECLARE_LITERAL_TEMP(v) \
|
||||
uint32 v
|
||||
|
||||
#define READ_LITERAL_PIXEL(src, v) \
|
||||
do { \
|
||||
v = *src++; \
|
||||
v += (v << 8) + (v << 16) + (v << 24); \
|
||||
} while (0)
|
||||
|
||||
#define READ_LITERAL_2PIXEL(src, v) \
|
||||
do { \
|
||||
v = *src | (*src << 8); \
|
||||
src++; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_4X1_LINE(dst, v) \
|
||||
*(uint32 *)(dst) = v
|
||||
|
||||
#define COPY_4X1_LINE(dst, src) \
|
||||
*(uint32 *)(dst) = *(const uint32 *)(src)
|
||||
|
||||
#define WRITE_2X1_LINE(dst, v) \
|
||||
*(uint16 *)(dst) = v
|
||||
|
||||
#endif /* SCUMM_NEED_ALIGNMENT */
|
||||
|
||||
/* Fill a 4x4 pixel block with a literal pixel value */
|
||||
|
||||
#define LITERAL_4X4(src, dst, pitch) \
|
||||
do { \
|
||||
int x; \
|
||||
DECLARE_LITERAL_TEMP(t); \
|
||||
READ_LITERAL_PIXEL(src, t); \
|
||||
for (x = 0; x < 4; x++) { \
|
||||
WRITE_4X1_LINE(dst + pitch * x, t); \
|
||||
} \
|
||||
dst += 4; \
|
||||
} while (0)
|
||||
|
||||
/* Fill four 4x1 pixel blocks with literal pixel values */
|
||||
|
||||
#define LITERAL_4X1(src, dst, pitch) \
|
||||
do { \
|
||||
int x; \
|
||||
DECLARE_LITERAL_TEMP(t); \
|
||||
for (x = 0; x < 4; x++) { \
|
||||
READ_LITERAL_PIXEL(src, t); \
|
||||
WRITE_4X1_LINE(dst + pitch * x, t); \
|
||||
} \
|
||||
dst += 4; \
|
||||
} while (0)
|
||||
|
||||
/* Fill a 4x4 pixel block with four 2x2 sub-blocks of different pixel values */
|
||||
|
||||
#define LITERAL_2X2(src, dst, pitch) \
|
||||
do { \
|
||||
uint16 p1, p2, p3, p4; \
|
||||
READ_LITERAL_2PIXEL(src, p1); \
|
||||
READ_LITERAL_2PIXEL(src, p2); \
|
||||
READ_LITERAL_2PIXEL(src, p3); \
|
||||
READ_LITERAL_2PIXEL(src, p4); \
|
||||
WRITE_2X1_LINE(dst, p1); \
|
||||
WRITE_2X1_LINE(dst + pitch, p1); \
|
||||
WRITE_2X1_LINE(dst + 2, p2); \
|
||||
WRITE_2X1_LINE(dst + pitch + 2, p2); \
|
||||
WRITE_2X1_LINE(dst + pitch * 2, p3); \
|
||||
WRITE_2X1_LINE(dst + pitch * 2 + 2, p4); \
|
||||
WRITE_2X1_LINE(dst + pitch * 3, p3); \
|
||||
WRITE_2X1_LINE(dst + pitch * 3 + 2, p4); \
|
||||
dst += 4; \
|
||||
} while (0)
|
||||
|
||||
/* Fill sixteen 1x1 pixel blocks with literal pixel values */
|
||||
|
||||
#define LITERAL_1X1(src, dst, pitch) \
|
||||
do { \
|
||||
int x; \
|
||||
for (x = 0; x < 4; x++) { \
|
||||
COPY_4X1_LINE(dst + pitch * x, src); \
|
||||
src += 4; \
|
||||
} \
|
||||
dst += 4; \
|
||||
} while (0)
|
||||
|
||||
/* Copy a 4x4 pixel block from a different place in the framebuffer */
|
||||
|
||||
#define COPY_4X4(dst2, dst, pitch) \
|
||||
do { \
|
||||
int x; \
|
||||
for (x=0; x<4; x++) { \
|
||||
COPY_4X1_LINE(dst + pitch * x, dst2 + pitch * x); \
|
||||
} \
|
||||
dst += 4; \
|
||||
} while (0)
|
||||
|
||||
void SmushDeltaBlocksDecoder::proc1(byte *dst, const byte *src, int32 nextOffs, int bw, int bh, int pitch, int16 *offsetTable) {
|
||||
uint8 code;
|
||||
bool filling, skipCode;
|
||||
int32 len;
|
||||
int i, p;
|
||||
uint32 pitches[16];
|
||||
|
||||
i = bw;
|
||||
for (p = 0; p < 16; ++p) {
|
||||
pitches[p] = (p >> 2) * pitch + (p & 0x3);
|
||||
}
|
||||
code = 0;
|
||||
filling = false;
|
||||
len = -1;
|
||||
while (1) {
|
||||
if (len < 0) {
|
||||
filling = (*src & 1) == 1;
|
||||
len = *src++ >> 1;
|
||||
skipCode = false;
|
||||
} else {
|
||||
skipCode = true;
|
||||
}
|
||||
if (!filling || !skipCode) {
|
||||
code = *src++;
|
||||
if (code == 0xFF) {
|
||||
--len;
|
||||
for (p = 0; p < 0x10; ++p) {
|
||||
if (len < 0) {
|
||||
filling = (*src & 1) == 1;
|
||||
len = *src++ >> 1;
|
||||
if (filling) {
|
||||
code = *src++;
|
||||
}
|
||||
}
|
||||
if (filling) {
|
||||
*(dst + pitches[p]) = code;
|
||||
} else {
|
||||
*(dst + pitches[p]) = *src++;
|
||||
}
|
||||
--len;
|
||||
}
|
||||
dst += 4;
|
||||
--i;
|
||||
if (i == 0) {
|
||||
dst += pitch * 3;
|
||||
--bh;
|
||||
if (bh == 0) return;
|
||||
i = bw;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
byte *dst2 = dst + offsetTable[code] + nextOffs;
|
||||
COPY_4X4(dst2, dst, pitch);
|
||||
--i;
|
||||
if (i == 0) {
|
||||
dst += pitch * 3;
|
||||
--bh;
|
||||
if (bh == 0) return;
|
||||
i = bw;
|
||||
}
|
||||
--len;
|
||||
}
|
||||
}
|
||||
|
||||
void SmushDeltaBlocksDecoder::proc3WithFDFE(byte *dst, const byte *src, int32 nextOffs, int bw, int bh, int pitch, int16 *offsetTable) {
|
||||
do {
|
||||
int32 i = bw;
|
||||
do {
|
||||
int32 code = *src++;
|
||||
if (code == 0xFD) {
|
||||
LITERAL_4X4(src, dst, pitch);
|
||||
} else if (code == 0xFE) {
|
||||
LITERAL_2X2(src, dst, pitch);
|
||||
} else if (code == 0xFF) {
|
||||
LITERAL_1X1(src, dst, pitch);
|
||||
} else {
|
||||
byte *dst2 = dst + _offsetTable[code] + nextOffs;
|
||||
COPY_4X4(dst2, dst, pitch);
|
||||
}
|
||||
} while (--i);
|
||||
dst += pitch * 3;
|
||||
} while (--bh);
|
||||
}
|
||||
|
||||
void SmushDeltaBlocksDecoder::proc3WithoutFDFE(byte *dst, const byte *src, int32 nextOffs, int bw, int bh, int pitch, int16 *offsetTable) {
|
||||
do {
|
||||
int32 i = bw;
|
||||
do {
|
||||
int32 code = *src++;
|
||||
if (code == 0xFF) {
|
||||
LITERAL_1X1(src, dst, pitch);
|
||||
} else {
|
||||
byte *dst2 = dst + _offsetTable[code] + nextOffs;
|
||||
COPY_4X4(dst2, dst, pitch);
|
||||
}
|
||||
} while (--i);
|
||||
dst += pitch * 3;
|
||||
} while (--bh);
|
||||
}
|
||||
|
||||
void SmushDeltaBlocksDecoder::proc4WithFDFE(byte *dst, const byte *src, int32 nextOffs, int bw, int bh, int pitch, int16 *offsetTable) {
|
||||
do {
|
||||
int32 i = bw;
|
||||
do {
|
||||
int32 code = *src++;
|
||||
if (code == 0xFD) {
|
||||
LITERAL_4X4(src, dst, pitch);
|
||||
} else if (code == 0xFE) {
|
||||
LITERAL_4X1(src, dst, pitch);
|
||||
} else if (code == 0xFF) {
|
||||
LITERAL_1X1(src, dst, pitch);
|
||||
} else if (code == 0x00) {
|
||||
int32 length = *src++ + 1;
|
||||
for (int32 l = 0; l < length; l++) {
|
||||
byte *dst2 = dst + nextOffs;
|
||||
COPY_4X4(dst2, dst, pitch);
|
||||
i--;
|
||||
if (i == 0) {
|
||||
dst += pitch * 3;
|
||||
bh--;
|
||||
i = bw;
|
||||
}
|
||||
}
|
||||
if (bh == 0) {
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
} else {
|
||||
byte *dst2 = dst + _offsetTable[code] + nextOffs;
|
||||
COPY_4X4(dst2, dst, pitch);
|
||||
}
|
||||
} while (--i);
|
||||
dst += pitch * 3;
|
||||
} while (--bh);
|
||||
}
|
||||
|
||||
void SmushDeltaBlocksDecoder::proc4WithoutFDFE(byte *dst, const byte *src, int32 nextOffs, int bw, int bh, int pitch, int16 *offsetTable) {
|
||||
do {
|
||||
int32 i = bw;
|
||||
do {
|
||||
int32 code = *src++;
|
||||
if (code == 0xFF) {
|
||||
LITERAL_1X1(src, dst, pitch);
|
||||
} else if (code == 0x00) {
|
||||
int32 length = *src++ + 1;
|
||||
for (int32 l = 0; l < length; l++) {
|
||||
byte *dst2 = dst + nextOffs;
|
||||
COPY_4X4(dst2, dst, pitch);
|
||||
i--;
|
||||
if (i == 0) {
|
||||
dst += pitch * 3;
|
||||
bh--;
|
||||
i = bw;
|
||||
}
|
||||
}
|
||||
if (bh == 0) {
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
} else {
|
||||
byte *dst2 = dst + _offsetTable[code] + nextOffs;
|
||||
COPY_4X4(dst2, dst, pitch);
|
||||
}
|
||||
} while (--i);
|
||||
dst += pitch * 3;
|
||||
} while (--bh);
|
||||
}
|
||||
|
||||
void SmushDeltaBlocksDecoder::decode(byte *dst, const byte *src) {
|
||||
int32 bw = (_width + 3) / 4, bh = (_height + 3) / 4;
|
||||
int32 pitch = bw * 4;
|
||||
|
||||
int16 seqNb = READ_LE_UINT16(src + 2);
|
||||
int32 decodedSize = READ_LE_UINT32(src + 4);
|
||||
byte maskFlags = src[12];
|
||||
makeTable(pitch, src[1]);
|
||||
int32 tmp;
|
||||
|
||||
switch (src[0]) {
|
||||
case 0:
|
||||
if ((_deltaBufs[_curTable] - _deltaBuf) > 0) {
|
||||
memset(_deltaBuf, 0, _deltaBufs[_curTable] - _deltaBuf);
|
||||
}
|
||||
tmp = (_deltaBuf + _deltaSize) - _deltaBufs[_curTable] - decodedSize;
|
||||
if (tmp > 0) {
|
||||
memset(_deltaBufs[_curTable] + decodedSize, 0, tmp);
|
||||
}
|
||||
memcpy(_deltaBufs[_curTable], src + 16, decodedSize);
|
||||
break;
|
||||
case 1:
|
||||
if ((seqNb & 1) || !(maskFlags & 1)) {
|
||||
_curTable ^= 1;
|
||||
}
|
||||
proc1(_deltaBufs[_curTable], src + 16, _deltaBufs[_curTable ^ 1] - _deltaBufs[_curTable],
|
||||
bw, bh, pitch, _offsetTable);
|
||||
break;
|
||||
case 2:
|
||||
bompDecodeLine(_deltaBufs[_curTable], src + 16, decodedSize);
|
||||
if ((_deltaBufs[_curTable] - _deltaBuf) > 0) {
|
||||
memset(_deltaBuf, 0, _deltaBufs[_curTable] - _deltaBuf);
|
||||
}
|
||||
tmp = (_deltaBuf + _deltaSize) - _deltaBufs[_curTable] - decodedSize;
|
||||
if (tmp > 0) {
|
||||
memset(_deltaBufs[_curTable] + decodedSize, 0, tmp);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if ((seqNb & 1) || !(maskFlags & 1)) {
|
||||
_curTable ^= 1;
|
||||
}
|
||||
|
||||
if ((maskFlags & 4) != 0) {
|
||||
proc3WithFDFE(_deltaBufs[_curTable], src + 16,
|
||||
_deltaBufs[_curTable ^ 1] - _deltaBufs[_curTable], bw, bh,
|
||||
pitch, _offsetTable);
|
||||
} else {
|
||||
proc3WithoutFDFE(_deltaBufs[_curTable], src + 16,
|
||||
_deltaBufs[_curTable ^ 1] - _deltaBufs[_curTable], bw, bh,
|
||||
pitch, _offsetTable);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if ((seqNb & 1) || !(maskFlags & 1)) {
|
||||
_curTable ^= 1;
|
||||
}
|
||||
|
||||
if ((maskFlags & 4) != 0) {
|
||||
proc4WithFDFE(_deltaBufs[_curTable], src + 16,
|
||||
_deltaBufs[_curTable ^ 1] - _deltaBufs[_curTable], bw, bh,
|
||||
pitch, _offsetTable);
|
||||
} else {
|
||||
proc4WithoutFDFE(_deltaBufs[_curTable], src + 16,
|
||||
_deltaBufs[_curTable ^ 1] - _deltaBufs[_curTable], bw, bh,
|
||||
pitch, _offsetTable);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_prevSeqNb = seqNb;
|
||||
|
||||
memcpy(dst, _deltaBufs[_curTable], _frameSize);
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
59
engines/scumm/smush/codec37.h
Normal file
59
engines/scumm/smush/codec37.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SCUMM_SMUSH_CODEC37_H
|
||||
#define SCUMM_SMUSH_CODEC37_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
class SmushDeltaBlocksDecoder {
|
||||
private:
|
||||
|
||||
int32 _deltaSize;
|
||||
byte *_deltaBufs[2];
|
||||
byte *_deltaBuf;
|
||||
int16 *_offsetTable;
|
||||
int _curTable;
|
||||
uint16 _prevSeqNb;
|
||||
int _tableLastPitch;
|
||||
int _tableLastIndex;
|
||||
int32 _frameSize;
|
||||
int _width, _height;
|
||||
|
||||
public:
|
||||
SmushDeltaBlocksDecoder(int width, int height);
|
||||
~SmushDeltaBlocksDecoder();
|
||||
protected:
|
||||
void makeTable(int, int);
|
||||
void proc1(byte *dst, const byte *src, int32, int, int, int, int16 *);
|
||||
void proc3WithFDFE(byte *dst, const byte *src, int32, int, int, int, int16 *);
|
||||
void proc3WithoutFDFE(byte *dst, const byte *src, int32, int, int, int, int16 *);
|
||||
void proc4WithFDFE(byte *dst, const byte *src, int32, int, int, int, int16 *);
|
||||
void proc4WithoutFDFE(byte *dst, const byte *src, int32, int, int, int, int16 *);
|
||||
public:
|
||||
void decode(byte *dst, const byte *src);
|
||||
};
|
||||
|
||||
} // End of namespace Scumm
|
||||
|
||||
#endif
|
||||
639
engines/scumm/smush/codec47.cpp
Normal file
639
engines/scumm/smush/codec47.cpp
Normal file
@@ -0,0 +1,639 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "common/endian.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "common/util.h"
|
||||
#include "scumm/bomp.h"
|
||||
#include "scumm/smush/codec47.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
#if defined(SCUMM_NEED_ALIGNMENT)
|
||||
|
||||
#define COPY_4X1_LINE(dst, src) \
|
||||
do { \
|
||||
(dst)[0] = (src)[0]; \
|
||||
(dst)[1] = (src)[1]; \
|
||||
(dst)[2] = (src)[2]; \
|
||||
(dst)[3] = (src)[3]; \
|
||||
} while (0)
|
||||
|
||||
#define COPY_2X1_LINE(dst, src) \
|
||||
do { \
|
||||
(dst)[0] = (src)[0]; \
|
||||
(dst)[1] = (src)[1]; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#else /* SCUMM_NEED_ALIGNMENT */
|
||||
|
||||
#define COPY_4X1_LINE(dst, src) \
|
||||
*(uint32 *)(dst) = *(const uint32 *)(src)
|
||||
|
||||
#define COPY_2X1_LINE(dst, src) \
|
||||
*(uint16 *)(dst) = *(const uint16 *)(src)
|
||||
|
||||
#endif
|
||||
|
||||
#define FILL_4X1_LINE(dst, val) \
|
||||
do { \
|
||||
(dst)[0] = val; \
|
||||
(dst)[1] = val; \
|
||||
(dst)[2] = val; \
|
||||
(dst)[3] = val; \
|
||||
} while (0)
|
||||
|
||||
#define FILL_2X1_LINE(dst, val) \
|
||||
do { \
|
||||
(dst)[0] = val; \
|
||||
(dst)[1] = val; \
|
||||
} while (0)
|
||||
|
||||
#define MOTION_OFFSET_TABLE_SIZE 0xF8
|
||||
#define PROCESS_SUBBLOCKS 0xFF
|
||||
#define FILL_SINGLE_COLOR 0xFE
|
||||
#define DRAW_GLYPH 0xFD
|
||||
#define COPY_PREV_BUFFER 0xFC
|
||||
|
||||
static const int8 codecGlyph4XVec[] = {
|
||||
0, 1, 2, 3, 3, 3, 3, 2, 1, 0, 0, 0, 1, 2, 2, 1,
|
||||
};
|
||||
|
||||
static const int8 codecGlyph4YVec[] = {
|
||||
0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 2,
|
||||
};
|
||||
|
||||
static const int8 codecGlyph8XVec[] = {
|
||||
0, 2, 5, 7, 7, 7, 7, 7, 7, 5, 2, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
static const int8 codecGlyph8YVec[] = {
|
||||
0, 0, 0, 0, 1, 3, 4, 6, 7, 7, 7, 7, 6, 4, 3, 1,
|
||||
};
|
||||
|
||||
static const int8 codecTable[] = {
|
||||
0, 0, -1, -43, 6, -43, -9, -42, 13, -41,
|
||||
-16, -40, 19, -39, -23, -36, 26, -34, -2, -33,
|
||||
4, -33, -29, -32, -9, -32, 11, -31, -16, -29,
|
||||
32, -29, 18, -28, -34, -26, -22, -25, -1, -25,
|
||||
3, -25, -7, -24, 8, -24, 24, -23, 36, -23,
|
||||
-12, -22, 13, -21, -38, -20, 0, -20, -27, -19,
|
||||
-4, -19, 4, -19, -17, -18, -8, -17, 8, -17,
|
||||
18, -17, 28, -17, 39, -17, -12, -15, 12, -15,
|
||||
-21, -14, -1, -14, 1, -14, -41, -13, -5, -13,
|
||||
5, -13, 21, -13, -31, -12, -15, -11, -8, -11,
|
||||
8, -11, 15, -11, -2, -10, 1, -10, 31, -10,
|
||||
-23, -9, -11, -9, -5, -9, 4, -9, 11, -9,
|
||||
42, -9, 6, -8, 24, -8, -18, -7, -7, -7,
|
||||
-3, -7, -1, -7, 2, -7, 18, -7, -43, -6,
|
||||
-13, -6, -4, -6, 4, -6, 8, -6, -33, -5,
|
||||
-9, -5, -2, -5, 0, -5, 2, -5, 5, -5,
|
||||
13, -5, -25, -4, -6, -4, -3, -4, 3, -4,
|
||||
9, -4, -19, -3, -7, -3, -4, -3, -2, -3,
|
||||
-1, -3, 0, -3, 1, -3, 2, -3, 4, -3,
|
||||
6, -3, 33, -3, -14, -2, -10, -2, -5, -2,
|
||||
-3, -2, -2, -2, -1, -2, 0, -2, 1, -2,
|
||||
2, -2, 3, -2, 5, -2, 7, -2, 14, -2,
|
||||
19, -2, 25, -2, 43, -2, -7, -1, -3, -1,
|
||||
-2, -1, -1, -1, 0, -1, 1, -1, 2, -1,
|
||||
3, -1, 10, -1, -5, 0, -3, 0, -2, 0,
|
||||
-1, 0, 1, 0, 2, 0, 3, 0, 5, 0,
|
||||
7, 0, -10, 1, -7, 1, -3, 1, -2, 1,
|
||||
-1, 1, 0, 1, 1, 1, 2, 1, 3, 1,
|
||||
-43, 2, -25, 2, -19, 2, -14, 2, -5, 2,
|
||||
-3, 2, -2, 2, -1, 2, 0, 2, 1, 2,
|
||||
2, 2, 3, 2, 5, 2, 7, 2, 10, 2,
|
||||
14, 2, -33, 3, -6, 3, -4, 3, -2, 3,
|
||||
-1, 3, 0, 3, 1, 3, 2, 3, 4, 3,
|
||||
19, 3, -9, 4, -3, 4, 3, 4, 7, 4,
|
||||
25, 4, -13, 5, -5, 5, -2, 5, 0, 5,
|
||||
2, 5, 5, 5, 9, 5, 33, 5, -8, 6,
|
||||
-4, 6, 4, 6, 13, 6, 43, 6, -18, 7,
|
||||
-2, 7, 0, 7, 2, 7, 7, 7, 18, 7,
|
||||
-24, 8, -6, 8, -42, 9, -11, 9, -4, 9,
|
||||
5, 9, 11, 9, 23, 9, -31, 10, -1, 10,
|
||||
2, 10, -15, 11, -8, 11, 8, 11, 15, 11,
|
||||
31, 12, -21, 13, -5, 13, 5, 13, 41, 13,
|
||||
-1, 14, 1, 14, 21, 14, -12, 15, 12, 15,
|
||||
-39, 17, -28, 17, -18, 17, -8, 17, 8, 17,
|
||||
17, 18, -4, 19, 0, 19, 4, 19, 27, 19,
|
||||
38, 20, -13, 21, 12, 22, -36, 23, -24, 23,
|
||||
-8, 24, 7, 24, -3, 25, 1, 25, 22, 25,
|
||||
34, 26, -18, 28, -32, 29, 16, 29, -11, 31,
|
||||
9, 32, 29, 32, -4, 33, 2, 33, -26, 34,
|
||||
23, 36, -19, 39, 16, 40, -13, 41, 9, 42,
|
||||
-6, 43, 1, 43, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
enum Edge {
|
||||
kEdgeLeft,
|
||||
kEdgeTop,
|
||||
kEdgeRight,
|
||||
kEdgeBottom,
|
||||
kEdgeNone,
|
||||
};
|
||||
|
||||
#define NGLYPHS 256
|
||||
|
||||
void SmushDeltaGlyphsDecoder::makeTablesInterpolation(int sideLength) {
|
||||
int32 pos, npoints;
|
||||
int32 edge0, edge1;
|
||||
int32 x1, x0, y1, y0;
|
||||
int32 tableSmallBig[64], s;
|
||||
const int8 *xGlyph = nullptr, *yGlyph = nullptr;
|
||||
int32 *ptrSmallBig;
|
||||
byte *ptr;
|
||||
int i, x, y;
|
||||
|
||||
if (sideLength == 8) {
|
||||
xGlyph = codecGlyph8XVec;
|
||||
yGlyph = codecGlyph8YVec;
|
||||
ptr = _tableBig;
|
||||
for (i = 0; i < NGLYPHS; i++) {
|
||||
ptr[384] = 0;
|
||||
ptr[385] = 0;
|
||||
ptr += 388;
|
||||
}
|
||||
} else if (sideLength == 4) {
|
||||
xGlyph = codecGlyph4XVec;
|
||||
yGlyph = codecGlyph4YVec;
|
||||
ptr = _tableSmall;
|
||||
for (i = 0; i < NGLYPHS; i++) {
|
||||
ptr[96] = 0;
|
||||
ptr[97] = 0;
|
||||
ptr += 128;
|
||||
}
|
||||
} else {
|
||||
error("SmushDeltaGlyphsDecoder::makeTablesInterpolation(): ERROR: Unknown sideLength %d.", sideLength);
|
||||
}
|
||||
|
||||
s = 0;
|
||||
for (x = 0; x < 16; x++) {
|
||||
x0 = xGlyph[x];
|
||||
y0 = yGlyph[x];
|
||||
|
||||
if (y0 == 0) {
|
||||
edge0 = kEdgeBottom;
|
||||
} else if (y0 == sideLength - 1) {
|
||||
edge0 = kEdgeTop;
|
||||
} else if (x0 == 0) {
|
||||
edge0 = kEdgeLeft;
|
||||
} else if (x0 == sideLength - 1) {
|
||||
edge0 = kEdgeRight;
|
||||
} else {
|
||||
edge0 = kEdgeNone;
|
||||
}
|
||||
|
||||
for (y = 0; y < 16; y++) {
|
||||
x1 = xGlyph[y];
|
||||
y1 = yGlyph[y];
|
||||
|
||||
if (y1 == 0) {
|
||||
edge1 = kEdgeBottom;
|
||||
} else if (y1 == sideLength - 1) {
|
||||
edge1 = kEdgeTop;
|
||||
} else if (x1 == 0) {
|
||||
edge1 = kEdgeLeft;
|
||||
} else if (x1 == sideLength - 1) {
|
||||
edge1 = kEdgeRight;
|
||||
} else {
|
||||
edge1 = kEdgeNone;
|
||||
}
|
||||
|
||||
memset(tableSmallBig, 0, sideLength * sideLength * 4);
|
||||
|
||||
npoints = MAX(ABS(y1 - y0), ABS(x1 - x0));
|
||||
|
||||
for (pos = 0; pos <= npoints; pos++) {
|
||||
int32 yPoint, xPoint;
|
||||
|
||||
if (npoints > 0) {
|
||||
// Linearly interpolate between x0 and x1
|
||||
// respectively y0 and y1.
|
||||
xPoint = (x0 * pos + x1 * (npoints - pos) + npoints / 2) / npoints;
|
||||
yPoint = (y0 * pos + y1 * (npoints - pos) + npoints / 2) / npoints;
|
||||
} else {
|
||||
xPoint = x0;
|
||||
yPoint = y0;
|
||||
}
|
||||
ptrSmallBig = &tableSmallBig[sideLength * yPoint + xPoint];
|
||||
*ptrSmallBig = 1;
|
||||
|
||||
if ((edge0 == kEdgeLeft && edge1 == kEdgeRight) || (edge1 == kEdgeLeft && edge0 == kEdgeRight) ||
|
||||
(edge0 == kEdgeBottom && edge1 != kEdgeTop) || (edge1 == kEdgeBottom && edge0 != kEdgeTop)) {
|
||||
if (yPoint >= 0) {
|
||||
i = yPoint + 1;
|
||||
while (i--) {
|
||||
*ptrSmallBig = 1;
|
||||
ptrSmallBig -= sideLength;
|
||||
}
|
||||
}
|
||||
} else if ((edge1 != kEdgeBottom && edge0 == kEdgeTop) || (edge0 != kEdgeBottom && edge1 == kEdgeTop)) {
|
||||
if (sideLength > yPoint) {
|
||||
i = sideLength - yPoint;
|
||||
while (i--) {
|
||||
*ptrSmallBig = 1;
|
||||
ptrSmallBig += sideLength;
|
||||
}
|
||||
}
|
||||
} else if ((edge0 == kEdgeLeft && edge1 != kEdgeRight) || (edge1 == kEdgeLeft && edge0 != kEdgeRight)) {
|
||||
if (xPoint >= 0) {
|
||||
i = xPoint + 1;
|
||||
while (i--) {
|
||||
*(ptrSmallBig--) = 1;
|
||||
}
|
||||
}
|
||||
} else if ((edge0 == kEdgeBottom && edge1 == kEdgeTop) || (edge1 == kEdgeBottom && edge0 == kEdgeTop) ||
|
||||
(edge0 == kEdgeRight && edge1 != kEdgeLeft) || (edge1 == kEdgeRight && edge0 != kEdgeLeft)) {
|
||||
if (sideLength > xPoint) {
|
||||
i = sideLength - xPoint;
|
||||
while (i--) {
|
||||
*(ptrSmallBig++) = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sideLength == 8) {
|
||||
for (i = 64 - 1; i >= 0; i--) {
|
||||
if (tableSmallBig[i] != 0) {
|
||||
_tableBig[256 + s + _tableBig[384 + s]] = (byte)i;
|
||||
_tableBig[384 + s]++;
|
||||
} else {
|
||||
_tableBig[320 + s + _tableBig[385 + s]] = (byte)i;
|
||||
_tableBig[385 + s]++;
|
||||
}
|
||||
}
|
||||
s += 388;
|
||||
}
|
||||
if (sideLength == 4) {
|
||||
for (i = 16 - 1; i >= 0; i--) {
|
||||
if (tableSmallBig[i] != 0) {
|
||||
_tableSmall[64 + s + _tableSmall[96 + s]] = (byte)i;
|
||||
_tableSmall[96 + s]++;
|
||||
} else {
|
||||
_tableSmall[80 + s + _tableSmall[97 + s]] = (byte)i;
|
||||
_tableSmall[97 + s]++;
|
||||
}
|
||||
}
|
||||
s += 128;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SmushDeltaGlyphsDecoder::makeCodecTables(int width) {
|
||||
if (_lastTableWidth == width)
|
||||
return;
|
||||
|
||||
_lastTableWidth = width;
|
||||
|
||||
int32 a, c, d;
|
||||
int16 tmp;
|
||||
|
||||
for (int l = 0; l < ARRAYSIZE(codecTable); l += 2) {
|
||||
_table[l / 2] = (int16)(codecTable[l + 1] * width + codecTable[l]);
|
||||
}
|
||||
// Note: _table[255] is never inited; but since only the first 0xF8
|
||||
// entries of it are used anyway, this doesn't matter.
|
||||
|
||||
a = 0;
|
||||
c = 0;
|
||||
do {
|
||||
for (d = 0; d < _tableSmall[96 + c]; d++) {
|
||||
tmp = _tableSmall[64 + c + d];
|
||||
tmp = (int16)((byte)(tmp >> 2) * width + (tmp & 3));
|
||||
_tableSmall[c + d * 2] = (byte)tmp;
|
||||
_tableSmall[c + d * 2 + 1] = tmp >> 8;
|
||||
}
|
||||
for (d = 0; d < _tableSmall[97 + c]; d++) {
|
||||
tmp = _tableSmall[80 + c + d];
|
||||
tmp = (int16)((byte)(tmp >> 2) * width + (tmp & 3));
|
||||
_tableSmall[32 + c + d * 2] = (byte)tmp;
|
||||
_tableSmall[32 + c + d * 2 + 1] = tmp >> 8;
|
||||
}
|
||||
for (d = 0; d < _tableBig[384 + a]; d++) {
|
||||
tmp = _tableBig[256 + a + d];
|
||||
tmp = (int16)((byte)(tmp >> 3) * width + (tmp & 7));
|
||||
_tableBig[a + d * 2] = (byte)tmp;
|
||||
_tableBig[a + d * 2 + 1] = tmp >> 8;
|
||||
}
|
||||
for (d = 0; d < _tableBig[385 + a]; d++) {
|
||||
tmp = _tableBig[320 + a + d];
|
||||
tmp = (int16)((byte)(tmp >> 3) * width + (tmp & 7));
|
||||
_tableBig[128 + a + d * 2] = (byte)tmp;
|
||||
_tableBig[128 + a + d * 2 + 1] = tmp >> 8;
|
||||
}
|
||||
|
||||
a += 388;
|
||||
c += 128;
|
||||
} while (c < 32768);
|
||||
}
|
||||
|
||||
#ifdef USE_ARM_SMUSH_ASM
|
||||
|
||||
#ifndef IPHONE
|
||||
#define ARM_Smush_decode2 _ARM_Smush_decode2
|
||||
#endif
|
||||
|
||||
extern "C" void ARM_Smush_decode2( byte *dst,
|
||||
const byte *src,
|
||||
int width,
|
||||
int height,
|
||||
const byte *param_ptr,
|
||||
int16 *_table,
|
||||
byte *_tableBig,
|
||||
int32 offset1,
|
||||
int32 offset2,
|
||||
byte *_tableSmall);
|
||||
|
||||
#define decode2(SRC,DST,WIDTH,HEIGHT,PARAM) \
|
||||
ARM_Smush_decode2(SRC,DST,WIDTH,HEIGHT,PARAM,_table,_tableBig, \
|
||||
_offset1,_offset2,_tableSmall)
|
||||
|
||||
#else
|
||||
void SmushDeltaGlyphsDecoder::level3(byte *dDst) {
|
||||
int32 tmp;
|
||||
byte code = *_dSrc++;
|
||||
|
||||
if (code < MOTION_OFFSET_TABLE_SIZE) {
|
||||
tmp = _table[code] + _offset1;
|
||||
COPY_2X1_LINE(dDst, dDst + tmp);
|
||||
COPY_2X1_LINE(dDst + _dPitch, dDst + _dPitch + tmp);
|
||||
} else if (code == PROCESS_SUBBLOCKS) {
|
||||
COPY_2X1_LINE(dDst, _dSrc + 0);
|
||||
COPY_2X1_LINE(dDst + _dPitch, _dSrc + 2);
|
||||
_dSrc += 4;
|
||||
} else if (code == FILL_SINGLE_COLOR) {
|
||||
byte t = *_dSrc++;
|
||||
FILL_2X1_LINE(dDst, t);
|
||||
FILL_2X1_LINE(dDst + _dPitch, t);
|
||||
} else if (code == COPY_PREV_BUFFER) {
|
||||
tmp = _offset2;
|
||||
COPY_2X1_LINE(dDst, dDst + tmp);
|
||||
COPY_2X1_LINE(dDst + _dPitch, dDst + _dPitch + tmp);
|
||||
} else {
|
||||
byte t = _paramPtr[code];
|
||||
FILL_2X1_LINE(dDst, t);
|
||||
FILL_2X1_LINE(dDst + _dPitch, t);
|
||||
}
|
||||
}
|
||||
|
||||
void SmushDeltaGlyphsDecoder::level2(byte *d_dst) {
|
||||
int32 tmp;
|
||||
byte code = *_dSrc++;
|
||||
int i;
|
||||
|
||||
if (code < MOTION_OFFSET_TABLE_SIZE) {
|
||||
tmp = _table[code] + _offset1;
|
||||
for (i = 0; i < 4; i++) {
|
||||
COPY_4X1_LINE(d_dst, d_dst + tmp);
|
||||
d_dst += _dPitch;
|
||||
}
|
||||
} else if (code == PROCESS_SUBBLOCKS) {
|
||||
level3(d_dst);
|
||||
d_dst += 2;
|
||||
level3(d_dst);
|
||||
d_dst += _dPitch * 2 - 2;
|
||||
level3(d_dst);
|
||||
d_dst += 2;
|
||||
level3(d_dst);
|
||||
} else if (code == FILL_SINGLE_COLOR) {
|
||||
byte t = *_dSrc++;
|
||||
for (i = 0; i < 4; i++) {
|
||||
FILL_4X1_LINE(d_dst, t);
|
||||
d_dst += _dPitch;
|
||||
}
|
||||
} else if (code == DRAW_GLYPH) {
|
||||
byte *tmpPtr = _tableSmall + *_dSrc++ * 128;
|
||||
int32 l = tmpPtr[96];
|
||||
byte val = *_dSrc++;
|
||||
int16 *tmpPtr2 = (int16 *)tmpPtr;
|
||||
while (l--) {
|
||||
*(d_dst + READ_LE_UINT16(tmpPtr2)) = val;
|
||||
tmpPtr2++;
|
||||
}
|
||||
l = tmpPtr[97];
|
||||
val = *_dSrc++;
|
||||
tmpPtr2 = (int16 *)(tmpPtr + 32);
|
||||
while (l--) {
|
||||
*(d_dst + READ_LE_UINT16(tmpPtr2)) = val;
|
||||
tmpPtr2++;
|
||||
}
|
||||
} else if (code == COPY_PREV_BUFFER) {
|
||||
tmp = _offset2;
|
||||
for (i = 0; i < 4; i++) {
|
||||
COPY_4X1_LINE(d_dst, d_dst + tmp);
|
||||
d_dst += _dPitch;
|
||||
}
|
||||
} else {
|
||||
byte t = _paramPtr[code];
|
||||
for (i = 0; i < 4; i++) {
|
||||
FILL_4X1_LINE(d_dst, t);
|
||||
d_dst += _dPitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SmushDeltaGlyphsDecoder::level1(byte *d_dst) {
|
||||
int32 tmp;
|
||||
byte code = *_dSrc++;
|
||||
int i;
|
||||
|
||||
if (code < MOTION_OFFSET_TABLE_SIZE) {
|
||||
tmp = _table[code] + _offset1;
|
||||
for (i = 0; i < 8; i++) {
|
||||
COPY_4X1_LINE(d_dst + 0, d_dst + tmp);
|
||||
COPY_4X1_LINE(d_dst + 4, d_dst + tmp + 4);
|
||||
d_dst += _dPitch;
|
||||
}
|
||||
} else if (code == PROCESS_SUBBLOCKS) {
|
||||
level2(d_dst);
|
||||
d_dst += 4;
|
||||
level2(d_dst);
|
||||
d_dst += _dPitch * 4 - 4;
|
||||
level2(d_dst);
|
||||
d_dst += 4;
|
||||
level2(d_dst);
|
||||
} else if (code == FILL_SINGLE_COLOR) {
|
||||
byte t = *_dSrc++;
|
||||
for (i = 0; i < 8; i++) {
|
||||
FILL_4X1_LINE(d_dst, t);
|
||||
FILL_4X1_LINE(d_dst + 4, t);
|
||||
d_dst += _dPitch;
|
||||
}
|
||||
} else if (code == DRAW_GLYPH) {
|
||||
tmp = *_dSrc++;
|
||||
byte *tmpPtr = _tableBig + tmp * 388;
|
||||
byte l = tmpPtr[384];
|
||||
byte val = *_dSrc++;
|
||||
int16 *tmpPtr2 = (int16 *)tmpPtr;
|
||||
while (l--) {
|
||||
*(d_dst + READ_LE_UINT16(tmpPtr2)) = val;
|
||||
tmpPtr2++;
|
||||
}
|
||||
l = tmpPtr[385];
|
||||
val = *_dSrc++;
|
||||
tmpPtr2 = (int16 *)(tmpPtr + 128);
|
||||
while (l--) {
|
||||
*(d_dst + READ_LE_UINT16(tmpPtr2)) = val;
|
||||
tmpPtr2++;
|
||||
}
|
||||
} else if (code == COPY_PREV_BUFFER) {
|
||||
tmp = _offset2;
|
||||
for (i = 0; i < 8; i++) {
|
||||
COPY_4X1_LINE(d_dst + 0, d_dst + tmp);
|
||||
COPY_4X1_LINE(d_dst + 4, d_dst + tmp + 4);
|
||||
d_dst += _dPitch;
|
||||
}
|
||||
} else {
|
||||
byte t = _paramPtr[code];
|
||||
for (i = 0; i < 8; i++) {
|
||||
FILL_4X1_LINE(d_dst, t);
|
||||
FILL_4X1_LINE(d_dst + 4, t);
|
||||
d_dst += _dPitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SmushDeltaGlyphsDecoder::decode2(byte *dst, const byte *src, int width, int height, const byte *param_ptr) {
|
||||
_dSrc = src;
|
||||
_paramPtr = param_ptr - MOTION_OFFSET_TABLE_SIZE;
|
||||
int bw = (width + 7) / 8;
|
||||
int bh = (height + 7) / 8;
|
||||
int nextLine = width * 7;
|
||||
_dPitch = width;
|
||||
|
||||
do {
|
||||
int tmpBw = bw;
|
||||
do {
|
||||
level1(dst);
|
||||
dst += 8;
|
||||
} while (--tmpBw);
|
||||
dst += nextLine;
|
||||
} while (--bh);
|
||||
}
|
||||
#endif
|
||||
|
||||
SmushDeltaGlyphsDecoder::SmushDeltaGlyphsDecoder(int width, int height) : _prevSeqNb(0), _dSrc(nullptr), _paramPtr(nullptr), _dPitch(0), _offset1(0), _offset2(0) {
|
||||
_lastTableWidth = -1;
|
||||
_width = width;
|
||||
_height = height;
|
||||
_tableBig = (byte *)malloc(NGLYPHS * 388);
|
||||
_tableSmall = (byte *)malloc(NGLYPHS * 128);
|
||||
if ((_tableBig != nullptr) && (_tableSmall != nullptr)) {
|
||||
makeTablesInterpolation(4);
|
||||
makeTablesInterpolation(8);
|
||||
}
|
||||
|
||||
_frameSize = _width * _height;
|
||||
_deltaSize = _frameSize * 3;
|
||||
_deltaBuf = (byte *)malloc(_deltaSize);
|
||||
_deltaBufs[0] = _deltaBuf;
|
||||
_deltaBufs[1] = _deltaBuf + _frameSize;
|
||||
_curBuf = _deltaBuf + _frameSize * 2;
|
||||
}
|
||||
|
||||
SmushDeltaGlyphsDecoder::~SmushDeltaGlyphsDecoder() {
|
||||
if (_tableBig) {
|
||||
free(_tableBig);
|
||||
_tableBig = nullptr;
|
||||
}
|
||||
if (_tableSmall) {
|
||||
free(_tableSmall);
|
||||
_tableSmall = nullptr;
|
||||
}
|
||||
_lastTableWidth = -1;
|
||||
if (_deltaBuf) {
|
||||
free(_deltaBuf);
|
||||
_deltaSize = 0;
|
||||
_deltaBuf = nullptr;
|
||||
_deltaBufs[0] = nullptr;
|
||||
_deltaBufs[1] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool SmushDeltaGlyphsDecoder::decode(byte *dst, const byte *src) {
|
||||
if ((_tableBig == nullptr) || (_tableSmall == nullptr) || (_deltaBuf == nullptr))
|
||||
return false;
|
||||
|
||||
_offset1 = _deltaBufs[1] - _curBuf;
|
||||
_offset2 = _deltaBufs[0] - _curBuf;
|
||||
|
||||
int32 seqNb = READ_LE_UINT16(src + 0);
|
||||
|
||||
const byte *gfxData = src + 26;
|
||||
|
||||
if (seqNb == 0) {
|
||||
makeCodecTables(_width);
|
||||
memset(_deltaBufs[0], src[12], _frameSize);
|
||||
memset(_deltaBufs[1], src[13], _frameSize);
|
||||
_prevSeqNb = -1;
|
||||
}
|
||||
|
||||
if ((src[4] & 1) != 0) {
|
||||
gfxData += 32896;
|
||||
}
|
||||
|
||||
switch (src[2]) {
|
||||
case 0:
|
||||
memcpy(_curBuf, gfxData, _frameSize);
|
||||
break;
|
||||
case 1:
|
||||
// Used by Outlaws, but not by any SCUMM game.
|
||||
error("SmushDeltaGlyphsDecoder::decode(): ERROR: Case 1 not implemented (used by Outlaws).");
|
||||
break;
|
||||
case 2:
|
||||
if (seqNb == _prevSeqNb + 1) {
|
||||
decode2(_curBuf, gfxData, _width, _height, src + 8);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
memcpy(_curBuf, _deltaBufs[1], _frameSize);
|
||||
break;
|
||||
case 4:
|
||||
memcpy(_curBuf, _deltaBufs[0], _frameSize);
|
||||
break;
|
||||
case 5:
|
||||
bompDecodeLine(_curBuf, gfxData, READ_LE_UINT32(src + 14));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(dst, _curBuf, _frameSize);
|
||||
|
||||
if (seqNb == _prevSeqNb + 1) {
|
||||
if (src[3] == 1) {
|
||||
SWAP(_curBuf, _deltaBufs[1]);
|
||||
} else if (src[3] == 2) {
|
||||
SWAP(_deltaBufs[0], _deltaBufs[1]);
|
||||
SWAP(_deltaBufs[1], _curBuf);
|
||||
}
|
||||
}
|
||||
_prevSeqNb = seqNb;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
62
engines/scumm/smush/codec47.h
Normal file
62
engines/scumm/smush/codec47.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SCUMM_SMUSH_CODEC_47_H
|
||||
#define SCUMM_SMUSH_CODEC_47_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
class SmushDeltaGlyphsDecoder {
|
||||
private:
|
||||
|
||||
int32 _deltaSize;
|
||||
byte *_deltaBufs[2];
|
||||
byte *_deltaBuf;
|
||||
byte *_curBuf;
|
||||
int32 _prevSeqNb;
|
||||
int _lastTableWidth;
|
||||
const byte *_dSrc, *_paramPtr;
|
||||
int _dPitch;
|
||||
int32 _offset1, _offset2;
|
||||
byte *_tableBig;
|
||||
byte *_tableSmall;
|
||||
int16 _table[256];
|
||||
int32 _frameSize;
|
||||
int _width, _height;
|
||||
|
||||
void makeTablesInterpolation(int param);
|
||||
void makeCodecTables(int width);
|
||||
void level1(byte *d_dst);
|
||||
void level2(byte *d_dst);
|
||||
void level3(byte *d_dst);
|
||||
void decode2(byte *dst, const byte *src, int width, int height, const byte *param_ptr);
|
||||
|
||||
public:
|
||||
SmushDeltaGlyphsDecoder(int width, int height);
|
||||
~SmushDeltaGlyphsDecoder();
|
||||
bool decode(byte *dst, const byte *src);
|
||||
};
|
||||
|
||||
} // End of namespace Scumm
|
||||
|
||||
#endif
|
||||
369
engines/scumm/smush/codec47ARM.s
Normal file
369
engines/scumm/smush/codec47ARM.s
Normal file
@@ -0,0 +1,369 @@
|
||||
@ 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ @author Robin Watts (robin@wss.co.uk)
|
||||
@
|
||||
@ This file, provides an ARM optimised version of sections of codec47.cpp.
|
||||
@ The algorithm is essentially the same as that within codec47.cpp
|
||||
@ so to understand this file you should understand codec47.cpp first.
|
||||
|
||||
.text
|
||||
|
||||
.global _ARM_Smush_decode2
|
||||
|
||||
.align 2
|
||||
_ARM_Smush_decode2:
|
||||
@ r0 = dst
|
||||
@ r1 = src
|
||||
@ r2 = width
|
||||
@ r3 = height
|
||||
@ r4 = param
|
||||
@ <> = _table
|
||||
@ <> = _tableBig
|
||||
@ <> = _offset1
|
||||
@ <> = _offset2
|
||||
@ <> = _tableSmall
|
||||
STMFD r13!,{r2,r4-r11,R14}
|
||||
|
||||
LDR r4,[r13,#40] @ r4 = param (40 = (9+1)*4)
|
||||
@ stall
|
||||
@ stall
|
||||
SUB r4,r4,#0xF8
|
||||
|
||||
@ r0 = dst
|
||||
@ r1 = _d_src
|
||||
@ r2 = _d_pitch
|
||||
@ r3 = height
|
||||
@ r4 = param
|
||||
ADD r7,r2,#7 @ r14 = bw
|
||||
MOV r7,r7,LSR #3
|
||||
y_loop:
|
||||
x_loop:
|
||||
@ LEVEL 1
|
||||
LDRB r6,[r1],#1 @ r6 = *_d_src++
|
||||
@ stall
|
||||
@ stall
|
||||
CMP r6,#0xF8
|
||||
BLT level1codeSMALL
|
||||
CMP r6,#0xFC
|
||||
BLT level1codeMID
|
||||
BEQ level1codeFC
|
||||
CMP r6,#0xFE
|
||||
BGT level1codeFF
|
||||
BEQ level1codeFE
|
||||
level1codeFD:
|
||||
LDRB r6,[r1],#1 @ r6 = tmp = *_d_src++
|
||||
LDR r8,[r13,#48] @ r8 = _tableBig (48 = (9+1+2)*4)
|
||||
@ stall
|
||||
ADD r12,r6,r6,LSL #1 @ r12= tmp*3
|
||||
ADD r6,r6,r12,LSL #5 @ r6 = tmp*97
|
||||
ADD r8,r8,r6,LSL #2 @ r8 = _tableBig + tmp*388
|
||||
LDRB r9,[r8,#384] @ r9 = l = tmp_ptr[384]
|
||||
LDRB r6,[r1],#1 @ r6 = val = *_d_src++
|
||||
ADD r12,r8,#384 @ r12= &tmp_ptr[384]
|
||||
@ I don''t really believe the next 2 lines are necessary, but...
|
||||
CMP r9,#0
|
||||
BEQ level1codeFD_over1
|
||||
level1codeFD_loop1:
|
||||
LDRB r10,[r8],#1
|
||||
LDRB r11,[r8],#1
|
||||
SUBS r9,r9,#1
|
||||
ADD r10,r10,r0
|
||||
STRB r6,[r10,r11,LSL #8] @ *(_d_dst + (*tmp_ptr2++)) = val
|
||||
BGT level1codeFD_loop1
|
||||
level1codeFD_over1:
|
||||
LDRB r9,[r12,#1] @ r9 = l = tmp_ptr[385]
|
||||
LDRB r6,[r1],#1 @ r6 = val = *_d_src++
|
||||
SUB r12,r12,#256 @ r12= &tmp_ptr[128] (256 = 384-128)
|
||||
@ I don''t really believe the next 2 lines are necessary, but...
|
||||
CMP r9,#0
|
||||
BEQ level1codeFD_over2
|
||||
level1codeFD_loop2:
|
||||
LDRB r10,[r12],#1
|
||||
LDRB r11,[r12],#1
|
||||
SUBS r9,r9,#1
|
||||
ADD r10,r10,r0
|
||||
STRB r6,[r10,r11,LSL #8] @ *(_d_dst + (*tmp_ptr2++)) = val
|
||||
BGT level1codeFD_loop2
|
||||
level1codeFD_over2:
|
||||
level1_end:
|
||||
|
||||
ADD r0,r0,#8
|
||||
SUBS r7,r7,#1
|
||||
BGT x_loop
|
||||
|
||||
ADD r7,r2,#7
|
||||
MOV r7,r7,LSR #3
|
||||
ADD r0,r0,r2,LSL #3
|
||||
SUB r0,r0,r7,LSL #3 @ r0 = dst += next_line
|
||||
SUBS r3,r3,#8 @ if (--bh > 0)
|
||||
BGT y_loop @ loop back
|
||||
|
||||
LDMFD r13!,{r2,r4-r11,PC}
|
||||
|
||||
level1codeSMALL:
|
||||
LDR r8,[r13,#44] @ r8 = _table (44 = (9+1+1)*4)
|
||||
LDR r9,[r13,#52] @ r9 = _offset1 (52 = (9+1+3)*4)
|
||||
MOV r6,r6,LSL #1 @ r6 = code<<1
|
||||
LDRSH r8,[r8,r6] @ tmp2 = _table[code]
|
||||
level1codeFC:
|
||||
@ EQ => FC
|
||||
LDREQ r9,[r13,#56] @ r9 = _offset2 (56 = (9+1+4)*4)
|
||||
MOVEQ r8,#0
|
||||
SUB r11,r2,#7 @ r11 = _d_pitch-7
|
||||
ADD r9,r9,r0 @ tmp2 = _d_dst+_offset
|
||||
ADD r8,r8,r9 @ tmp2 = _d_dst+_table[code]+_offset
|
||||
@ r8 = &_dst[tmp2]
|
||||
MOV r12,#8
|
||||
level1codeSMALL_loop:
|
||||
LDRB r5, [r8],#1 @ r5 = d_dst[tmp2]
|
||||
LDRB r6, [r8],#1 @ r10 = d_dst[tmp2]
|
||||
LDRB r9, [r8],#1 @ r10 = d_dst[tmp2]
|
||||
LDRB r10,[r8],#1 @ r10 = d_dst[tmp2]
|
||||
STRB r5, [r0],#1 @ d_dst[0] = r5
|
||||
STRB r6, [r0],#1 @ d_dst[1] = r6
|
||||
STRB r9, [r0],#1 @ d_dst[2] = r9
|
||||
STRB r10,[r0],#1 @ d_dst[3] = r10
|
||||
LDRB r5, [r8],#1 @ r5 = d_dst[tmp2]
|
||||
LDRB r6, [r8],#1 @ r10 = d_dst[tmp2]
|
||||
LDRB r9, [r8],#1 @ r10 = d_dst[tmp2]
|
||||
LDRB r10,[r8],r11 @ r10 = d_dst[tmp2]
|
||||
STRB r5, [r0],#1 @ d_dst[4] = r5
|
||||
STRB r6, [r0],#1 @ d_dst[5] = r6
|
||||
STRB r9, [r0],#1 @ d_dst[6] = r9
|
||||
STRB r10,[r0],r11 @ d_dst[7] = r10 d_dst += d_pitch
|
||||
SUBS r12,r12,#1
|
||||
BGT level1codeSMALL_loop
|
||||
SUB r0,r0,r2,LSL #3 @ revert d_dst
|
||||
B level1_end
|
||||
|
||||
level1codeMID:
|
||||
@ LT => F8<=code<FC case
|
||||
@ EQ => FE case
|
||||
LDRB r6,[r4,r6] @ r6 = t = _paramPtr[code]
|
||||
level1codeFE:
|
||||
LDREQB r6,[r1],#1 @ r6 = t = *_d_src++
|
||||
MOV r12,#8
|
||||
SUB r11,r2,#7 @ r11 = _d_pitch-7
|
||||
level1codeMID_loop:
|
||||
STRB r6,[r0],#1
|
||||
STRB r6,[r0],#1
|
||||
STRB r6,[r0],#1
|
||||
STRB r6,[r0],#1
|
||||
STRB r6,[r0],#1
|
||||
STRB r6,[r0],#1
|
||||
STRB r6,[r0],#1
|
||||
STRB r6,[r0],r11
|
||||
SUBS r12,r12,#1
|
||||
BGT level1codeMID_loop
|
||||
SUB r0,r0,r2,LSL #3 @ revert d_dst
|
||||
B level1_end
|
||||
|
||||
level1codeFF:
|
||||
BL level2
|
||||
ADD r0,r0,#4
|
||||
BL level2
|
||||
ADD r0,r0,r2,LSL #2
|
||||
SUB r0,r0,#4
|
||||
BL level2
|
||||
ADD r0,r0,#4
|
||||
BL level2
|
||||
SUB r0,r0,#4
|
||||
SUB r0,r0,r2,LSL #2
|
||||
B level1_end
|
||||
|
||||
level2:
|
||||
@ r0 = _d_dst
|
||||
@ r1 = _d_src
|
||||
@ r2 = _d_pitch
|
||||
@ r3 = PRESERVE
|
||||
@ r4 = param
|
||||
@ r7 = PRESERVE
|
||||
@ r14= return address
|
||||
LDRB r6,[r1],#1 @ r6 = *_d_src++
|
||||
@ stall
|
||||
@ stall
|
||||
CMP r6,#0xF8
|
||||
BLT level2codeSMALL
|
||||
CMP r6,#0xFC
|
||||
BLT level2codeMID
|
||||
BEQ level2codeFC
|
||||
CMP r6,#0xFE
|
||||
BGT level2codeFF
|
||||
BEQ level2codeFE
|
||||
level2codeFD:
|
||||
LDRB r6,[r1],#1 @ r6 = tmp = *_d_src++
|
||||
LDR r8,[r13,#60] @ r8 = _tableSmall (60 = (9+1+5)*4)
|
||||
@ stall
|
||||
@ stall
|
||||
ADD r8,r8,r6,LSL #7 @ r8 = _tableSmall + tmp*128
|
||||
LDRB r9,[r8,#96] @ r9 = l = tmp_ptr[96]
|
||||
LDRB r6,[r1],#1 @ r6 = val = *_d_src++
|
||||
ADD r12,r8,#32 @ r12 = tmp_ptr + 32
|
||||
@ I don''t really believe the next 2 lines are necessary, but...
|
||||
CMP r9,#0
|
||||
BEQ level2codeFD_over1
|
||||
level2codeFD_loop1:
|
||||
LDRB r10,[r8],#1
|
||||
LDRB r11,[r8],#1
|
||||
SUBS r9,r9,#1
|
||||
ADD r10,r10,r0
|
||||
STRB r6,[r10,r11,LSL #8] @ *(_d_dst + (*tmp_ptr2++)) = val
|
||||
BGT level2codeFD_loop1
|
||||
level2codeFD_over1:
|
||||
LDRB r9,[r12,#65] @ r9 = l = tmp_ptr[97] (65 = 97-32)
|
||||
LDRB r6,[r1],#1 @ r6 = val = *_d_src++
|
||||
@ I don''t really believe the next 2 lines are necessary, but...
|
||||
CMP r9,#0
|
||||
MOVEQ PC,R14
|
||||
level2codeFD_loop2:
|
||||
LDRB r10,[r12],#1
|
||||
LDRB r11,[r12],#1
|
||||
SUBS r9,r9,#1
|
||||
ADD r10,r10,r0
|
||||
STRB r6,[r10,r11,LSL #8] @ *(_d_dst + (*tmp_ptr2++)) = val
|
||||
BGT level2codeFD_loop2
|
||||
|
||||
MOV PC,R14
|
||||
|
||||
level2codeSMALL:
|
||||
LDR r8,[r13,#44] @ r8 = _table (44 = (9+1+1)*4)
|
||||
LDR r9,[r13,#52] @ r9 = _offset1 (52 = (9+1+3)*4)
|
||||
MOV r6,r6,LSL #1 @ r6 = code<<1
|
||||
LDRSH r8,[r8,r6] @ tmp2 = _table[code]
|
||||
level2codeFC:
|
||||
@ EQ => FC
|
||||
LDREQ r9,[r13,#56] @ r9 = _offset2 (56 = (9+1+4)*4)
|
||||
MOVEQ r8,#0
|
||||
SUB r11,r2,#3 @ r11 = _d_pitch-3
|
||||
ADD r9,r9,r0 @ tmp2 = _d_dst + _table[code]
|
||||
ADD r8,r8,r9 @ tmp2 = _d_dst+_table[code]+_offset1
|
||||
@ r8 = &_dst[tmp2]
|
||||
MOV r12,#4
|
||||
level2codeSMALL_loop:
|
||||
LDRB r5, [r8],#1 @ r5 = d_dst[tmp2]
|
||||
LDRB r6, [r8],#1 @ r10 = d_dst[tmp2]
|
||||
LDRB r9, [r8],#1 @ r10 = d_dst[tmp2]
|
||||
LDRB r10,[r8],r11 @ r10 = d_dst[tmp2]
|
||||
STRB r5, [r0],#1 @ d_dst[4] = r5
|
||||
STRB r6, [r0],#1 @ d_dst[5] = r6
|
||||
STRB r9, [r0],#1 @ d_dst[6] = r9
|
||||
STRB r10,[r0],r11 @ d_dst[7] = r10 d_dst += d_pitch
|
||||
SUBS r12,r12,#1
|
||||
BGT level2codeSMALL_loop
|
||||
SUB r0,r0,r2,LSL #2 @ revert d_dst
|
||||
MOV PC,R14
|
||||
|
||||
level2codeMID:
|
||||
@ LT => F8<=code<FC case
|
||||
@ EQ => FE case
|
||||
LDRB r6,[r4,r6] @ r6 = t = _paramPtr[code]
|
||||
level2codeFE:
|
||||
LDREQB r6,[r1],#1 @ r6 = t = *_d_src++
|
||||
MOV r12,#4
|
||||
SUB r11,r2,#3 @ r11 = _d_pitch-7
|
||||
level2codeMID_loop:
|
||||
STRB r6,[r0],#1
|
||||
STRB r6,[r0],#1
|
||||
STRB r6,[r0],#1
|
||||
STRB r6,[r0],r11
|
||||
SUBS r12,r12,#1
|
||||
BGT level2codeMID_loop
|
||||
SUB r0,r0,r2,LSL #2 @ revert d_dst
|
||||
MOV PC,R14
|
||||
|
||||
level2codeFF:
|
||||
MOV r5,r14
|
||||
BL level3
|
||||
ADD r0,r0,#2
|
||||
BL level3
|
||||
ADD r0,r0,r2,LSL #1
|
||||
SUB r0,r0,#2
|
||||
BL level3
|
||||
ADD r0,r0,#2
|
||||
BL level3
|
||||
SUB r0,r0,#2
|
||||
SUB r0,r0,r2,LSL #1
|
||||
MOV PC,R5
|
||||
|
||||
level3:
|
||||
@ r0 = _d_dst
|
||||
@ r1 = _d_src
|
||||
@ r2 = _d_pitch
|
||||
@ r3 = PRESERVE
|
||||
@ r4 = param
|
||||
@ r5 = preserve
|
||||
@ r7 = PRESERVE
|
||||
@ r14= return address
|
||||
LDRB r6,[r1],#1 @ r6 = code = *_d_src++
|
||||
@ stall
|
||||
@ stall
|
||||
CMP r6,#0xF8
|
||||
BLT level3codeSMALL
|
||||
CMP r6,#0xFC
|
||||
BLT level3codeMID
|
||||
BEQ level3codeFC
|
||||
CMP r6,#0xFE
|
||||
BGT level3codeFF
|
||||
level3codeFE:
|
||||
LDRB r6,[r1],#1 @ r6 = t = *_d_src++
|
||||
level3codeMID:
|
||||
@ LT => F8<=code<FC case
|
||||
@ EQ => FE case
|
||||
LDRLTB r6,[r4,r6] @ r6 = t = _paramPtr[code]
|
||||
@ stall
|
||||
@ stall
|
||||
STRB r6,[r0,#1]
|
||||
STRB r6,[r0],r2
|
||||
STRB r6,[r0,#1]
|
||||
STRB r6,[r0],-r2
|
||||
MOV PC,R14
|
||||
|
||||
level3codeFF:
|
||||
LDRB r6,[r1],#1
|
||||
LDRB r9,[r1],#1
|
||||
LDRB r10,[r1],#1
|
||||
LDRB r11,[r1],#1
|
||||
STRB r9, [r0,#1]
|
||||
STRB r6, [r0],r2
|
||||
STRB r11,[r0,#1]
|
||||
STRB r10,[r0],-r2
|
||||
MOV PC,R14
|
||||
|
||||
level3codeSMALL:
|
||||
LDR r8,[r13,#44] @ r8 = _table (44 = (9+1+1)*4)
|
||||
LDR r9,[r13,#52] @ r9 = _offset1 (52 = (9+1+3)*4)
|
||||
MOV r6,r6,LSL #1 @ r6 = code<<1
|
||||
LDRSH r8,[r8,r6] @ tmp2 = _table[code]
|
||||
level3codeFC:
|
||||
@ EQ => FC
|
||||
LDREQ r9,[r13,#56] @ r9 = _offset2 (56 = (9+1+4)*4)
|
||||
MOVEQ r8,#0
|
||||
ADD r9,r9,r0 @ tmp2 = _d_dst+offset
|
||||
ADD r8,r8,r9 @ tmp2 = _d_dst+_table[code]+_offset
|
||||
@ r8 = &_dst[tmp2]
|
||||
LDRB r6, [r8,#1] @ r6 = d_dst[tmp2+1]
|
||||
LDRB r9, [r8],r2 @ r9 = d_dst[tmp2+0]
|
||||
LDRB r10,[r8,#1] @ r10= d_dst[tmp2+dst+1]
|
||||
LDRB r11,[r8],-r2 @ r11= d_dst[tmp2+dst]
|
||||
STRB r6, [r0,#1] @ d_dst[1 ] = r6
|
||||
STRB r9, [r0],r2 @ d_dst[0 ] = r9
|
||||
STRB r10,[r0,#1] @ d_dst[dst+1] = r10
|
||||
STRB r11,[r0],-r2 @ d_dst[dst ] = r11
|
||||
MOV PC,R14
|
||||
70
engines/scumm/smush/smush_font.h
Normal file
70
engines/scumm/smush/smush_font.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SCUMM_SMUSH_FONT_H
|
||||
#define SCUMM_SMUSH_FONT_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "scumm/nut_renderer.h"
|
||||
#include "scumm/scumm.h"
|
||||
#include "scumm/string_v7.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
class SmushFont : public NutRenderer, public GlyphRenderer_v7 {
|
||||
public:
|
||||
SmushFont(ScummEngine *vm, const char *filename, bool useOriginalColors) :
|
||||
NutRenderer(vm, filename), _hardcodedFontColors(useOriginalColors) {
|
||||
_r = new TextRenderer_v7(vm, this);
|
||||
}
|
||||
|
||||
~SmushFont() override { delete _r;}
|
||||
|
||||
void drawString(const char *str, byte *buffer, Common::Rect &clipRect, int x, int y, int16 col, TextStyleFlags flags) {
|
||||
_r->drawString(str, buffer, clipRect, x, y, _vm->_screenWidth, col, flags);
|
||||
}
|
||||
|
||||
void drawStringWrap(const char *str, byte *buffer, Common::Rect &clipRect, int x, int y, int16 col, TextStyleFlags flags) {
|
||||
_r->drawStringWrap(str, buffer, clipRect, x, y, _vm->_screenWidth, col, flags);
|
||||
}
|
||||
|
||||
private:
|
||||
int draw2byte(byte *buffer, Common::Rect &clipRect, int x, int y, int pitch, int16 col, uint16 chr) override {
|
||||
return NutRenderer::draw2byte(buffer, clipRect, x, y, pitch, _vm->_game.id == GID_CMI ? 255 : (_vm->_game.id == GID_DIG && col == -1 ? 1 : col), chr);
|
||||
}
|
||||
|
||||
int drawCharV7(byte *buffer, Common::Rect &clipRect, int x, int y, int pitch, int16 col, TextStyleFlags flags, byte chr) override {
|
||||
return NutRenderer::drawCharV7(buffer, clipRect, x, y, pitch, col, flags, chr, _hardcodedFontColors, true);
|
||||
}
|
||||
|
||||
int getCharWidth(uint16 chr) const override { return NutRenderer::getCharWidth(chr & 0xFF); }
|
||||
int getCharHeight(uint16 chr) const override { return NutRenderer::getCharHeight(chr & 0xFF); }
|
||||
int getFontHeight() const override { return NutRenderer::getFontHeight(); }
|
||||
int setFont(int) override { return 0; }
|
||||
bool newStyleWrapping() const override { return true; }
|
||||
|
||||
TextRenderer_v7 *_r;
|
||||
const bool _hardcodedFontColors;
|
||||
};
|
||||
|
||||
} // End of namespace Scumm
|
||||
|
||||
#endif
|
||||
2138
engines/scumm/smush/smush_player.cpp
Normal file
2138
engines/scumm/smush/smush_player.cpp
Normal file
File diff suppressed because it is too large
Load Diff
268
engines/scumm/smush/smush_player.h
Normal file
268
engines/scumm/smush/smush_player.h
Normal file
@@ -0,0 +1,268 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(SCUMM_SMUSH_PLAYER_H) && defined(ENABLE_SCUMM_7_8)
|
||||
#define SCUMM_SMUSH_PLAYER_H
|
||||
|
||||
#include "common/util.h"
|
||||
|
||||
namespace Audio {
|
||||
class SoundHandle;
|
||||
class QueuingAudioStream;
|
||||
}
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
#define SMUSH_MAX_TRACKS 4
|
||||
#define SMUSH_FADE_SIZE 0xC00
|
||||
|
||||
#define IS_SFX 0x00
|
||||
#define IS_BKG_MUSIC 0x40
|
||||
#define IS_SPEECH 0x80
|
||||
|
||||
#define CHN_BKGMUS 1
|
||||
#define CHN_SPEECH 2
|
||||
#define CHN_OTHER 3
|
||||
|
||||
#define GRP_MASTER 0xFF01
|
||||
#define GRP_SFX 0xFF02
|
||||
#define GRP_BKGMUS 0xFF03
|
||||
#define GRP_SPEECH 0xFF04
|
||||
|
||||
#define TRK_STATE_INACTIVE 0
|
||||
#define TRK_STATE_PLAYING 1
|
||||
#define TRK_STATE_FADING 2
|
||||
#define TRK_STATE_ENDING 3
|
||||
|
||||
#define TRK_TYPE_MASK 0xC0
|
||||
|
||||
#define SAUD_OP_INIT 1
|
||||
#define SAUD_OP_UPDATE_HEADER 2
|
||||
#define SAUD_OP_SET_PARAM 3
|
||||
#define SAUD_OP_INCR_PARAM 4
|
||||
#define SAUD_OP_SET_OFFSET 6
|
||||
#define SAUD_OP_SET_LENGTH 7
|
||||
#define SAUD_OP_COMPARE_GT 8
|
||||
#define SAUD_OP_COMPARE_LT 9
|
||||
#define SAUD_OP_COMPARE_EQ 10
|
||||
#define SAUD_OP_COMPARE_NE 11
|
||||
|
||||
#define SAUD_VALUEID_ALL_VOLS 0xFF
|
||||
#define SAUD_VALUEID_TRK_VOL 0xFE
|
||||
#define SAUD_VALUEID_TRK_PAN 0xFD
|
||||
|
||||
#define TRK_USERID_SPEECH 1
|
||||
#define TRK_USERID_MUSIC 2
|
||||
#define TRK_USERID_SFX 3
|
||||
|
||||
#define SMUSH_CODEC_RLE 1
|
||||
#define SMUSH_CODEC_RLE_ALT 3
|
||||
#define SMUSH_CODEC_UNCOMPRESSED 20
|
||||
#define SMUSH_CODEC_DELTA_BLOCKS 37
|
||||
#define SMUSH_CODEC_DELTA_GLYPHS 47
|
||||
|
||||
class ScummEngine_v7;
|
||||
class SmushFont;
|
||||
class SmushMixer;
|
||||
class StringResource;
|
||||
class SmushDeltaBlocksDecoder;
|
||||
class SmushDeltaGlyphsDecoder;
|
||||
class IMuseDigital;
|
||||
class Insane;
|
||||
|
||||
class SmushPlayer {
|
||||
friend class Insane;
|
||||
private:
|
||||
struct SmushAudioDispatch {
|
||||
uint8 *headerPtr;
|
||||
uint8 *dataBuf;
|
||||
int32 dataSize;
|
||||
int32 audioRemaining;
|
||||
int32 currentOffset;
|
||||
int sampleRate;
|
||||
int state;
|
||||
int fadeSampleRate;
|
||||
int fadeVolume;
|
||||
int32 fadeRemaining;
|
||||
int volumeStep;
|
||||
int32 elapsedAudio;
|
||||
int32 audioLength;
|
||||
};
|
||||
|
||||
struct SmushAudioTrack {
|
||||
uint8 *blockPtr;
|
||||
uint8 *fadeBuf;
|
||||
uint8 *dataBuf;
|
||||
uint8 *subChunkPtr;
|
||||
int32 blockSize;
|
||||
byte volume;
|
||||
byte pan;
|
||||
int16 state;
|
||||
int16 flags;
|
||||
int groupId;
|
||||
int parsedChunks;
|
||||
int32 dataSize;
|
||||
int32 availableSize;
|
||||
int32 audioRemaining;
|
||||
int32 sdatSize;
|
||||
};
|
||||
|
||||
ScummEngine_v7 *_vm;
|
||||
IMuseDigital *_imuseDigital;
|
||||
Insane *_insane;
|
||||
int32 _nbframes;
|
||||
int16 _deltaPal[0x300];
|
||||
int32 _shiftedDeltaPal[0x300];
|
||||
byte _pal[0x300];
|
||||
SmushFont *_sf[5];
|
||||
StringResource *_strings;
|
||||
SmushDeltaBlocksDecoder *_deltaBlocksCodec;
|
||||
SmushDeltaGlyphsDecoder *_deltaGlyphsCodec;
|
||||
Common::SeekableReadStream *_base;
|
||||
uint32 _baseSize;
|
||||
byte *_frameBuffer;
|
||||
byte *_specialBuffer;
|
||||
|
||||
Common::String _seekFile;
|
||||
uint32 _startFrame;
|
||||
uint32 _startTime;
|
||||
int32 _seekPos;
|
||||
uint32 _seekFrame;
|
||||
|
||||
bool _skipNext;
|
||||
uint32 _frame;
|
||||
|
||||
Audio::SoundHandle *_IACTchannel;
|
||||
Audio::QueuingAudioStream *_IACTstream;
|
||||
|
||||
Audio::SoundHandle *_compressedFileSoundHandle;
|
||||
bool _compressedFileMode;
|
||||
byte _IACToutput[4096];
|
||||
int32 _IACTpos;
|
||||
bool _storeFrame;
|
||||
int _speed;
|
||||
bool _endOfFile;
|
||||
|
||||
byte *_dst;
|
||||
bool _updateNeeded;
|
||||
bool _warpNeeded;
|
||||
int _palDirtyMin, _palDirtyMax;
|
||||
int _warpX, _warpY;
|
||||
int _warpButtons;
|
||||
bool _insanity;
|
||||
bool _middleAudio;
|
||||
bool _skipPalette;
|
||||
int _iactTable[4];
|
||||
|
||||
SmushAudioTrack _smushTracks[SMUSH_MAX_TRACKS];
|
||||
SmushAudioDispatch _smushDispatch[SMUSH_MAX_TRACKS];
|
||||
|
||||
int _smushMaxFrames[SMUSH_MAX_TRACKS];
|
||||
int _smushTrackIds[SMUSH_MAX_TRACKS];
|
||||
int _smushTrackIdxs[SMUSH_MAX_TRACKS];
|
||||
uint8 _smushAudioTable[256];
|
||||
int _smushNumTracks;
|
||||
int _smushTrackFlags[SMUSH_MAX_TRACKS];
|
||||
int _smushTrackVols[SMUSH_MAX_TRACKS];
|
||||
|
||||
int _smushAudioSampleRate;
|
||||
int _gainReductionLowerBound;
|
||||
int _gainReductionFactor;
|
||||
int _gainReductionMultiplier;
|
||||
|
||||
bool _smushTracksNeedInit;
|
||||
bool _smushAudioInitialized;
|
||||
bool _smushAudioCallbackEnabled;
|
||||
|
||||
public:
|
||||
SmushPlayer(ScummEngine_v7 *scumm, IMuseDigital *_imuseDigital, Insane *insane);
|
||||
~SmushPlayer();
|
||||
|
||||
void pause();
|
||||
void unpause();
|
||||
|
||||
void play(const char *filename, int32 speed, int32 offset = 0, int32 startFrame = 0);
|
||||
void release();
|
||||
void warpMouse(int x, int y, int buttons);
|
||||
int setChanFlag(int id, int flagVal);
|
||||
void setGroupVolume(int groupId, int volValue);
|
||||
void processDispatches(int16 feedSize);
|
||||
bool isAudioCallbackEnabled();
|
||||
byte *getVideoPalette();
|
||||
void setCurVideoFlags(int16 flags);
|
||||
|
||||
|
||||
protected:
|
||||
int _width, _height;
|
||||
|
||||
int _origPitch, _origNumStrips;
|
||||
bool _paused;
|
||||
uint32 _pauseStartTime;
|
||||
uint32 _pauseTime;
|
||||
int16 _curVideoFlags = 0;
|
||||
|
||||
void insanity(bool);
|
||||
void setPalette(const byte *palette);
|
||||
void setPaletteValue(int n, byte r, byte g, byte b);
|
||||
void setDirtyColors(int min, int max);
|
||||
void seekSan(const char *file, int32 pos, int32 contFrame);
|
||||
const char *getString(int id);
|
||||
|
||||
private:
|
||||
SmushFont *getFont(int font);
|
||||
void parseNextFrame();
|
||||
void init(int32 spped);
|
||||
void setupAnim(const char *file);
|
||||
void updateScreen();
|
||||
void tryCmpFile(const char *filename);
|
||||
|
||||
bool readString(const char *file);
|
||||
void decodeFrameObject(int codec, const uint8 *src, int left, int top, int width, int height);
|
||||
void handleAnimHeader(int32 subSize, Common::SeekableReadStream &);
|
||||
void handleFrame(int32 frameSize, Common::SeekableReadStream &);
|
||||
void handleNewPalette(int32 subSize, Common::SeekableReadStream &);
|
||||
void handleZlibFrameObject(int32 subSize, Common::SeekableReadStream &b);
|
||||
void handleFrameObject(int32 subSize, Common::SeekableReadStream &);
|
||||
void handleSAUDChunk(uint8 *srcBuf, uint32 size, int groupId, int vol, int pan, int16 flags, int trkId, int index, int maxFrames);
|
||||
void handleStore(int32 subSize, Common::SeekableReadStream &);
|
||||
void handleFetch(int32 subSize, Common::SeekableReadStream &);
|
||||
void handleIACT(int32 subSize, Common::SeekableReadStream &);
|
||||
void handleTextResource(uint32 subType, int32 subSize, Common::SeekableReadStream &);
|
||||
void handleDeltaPalette(int32 subSize, Common::SeekableReadStream &);
|
||||
void readPalette(byte *, Common::SeekableReadStream &);
|
||||
|
||||
void initAudio(int samplerate, int32 maxChunkSize);
|
||||
void terminateAudio();
|
||||
int isChanActive(int flagId);
|
||||
int addAudioTrack(int32 trackBlockSize, int32 maxBlockSize);
|
||||
void resetAudioTracks();
|
||||
void setGainReductionParams(int16 gainReductionLowerBound, int16 gainReductionMultiplier);
|
||||
void fillAudioTrackInfo(uint8 *srcBuf, uint16 *flagsAccumulator, uint32 size, int groupId, int vol, int pan, int16 flags, int trkId, int index, int maxFrames);
|
||||
bool processAudioCodes(int idx, int32 &tmpFeedSize, int &mixVolume);
|
||||
void feedAudio(uint8 *srcBuf, int groupId, int volume, int pan, int16 flags);
|
||||
void sendAudioToDiMUSE(uint8 *mixBuf, int32 mixStartingPoint, int32 mixFeedSize, int32 mixInFrameCount, int volume, int pan);
|
||||
|
||||
void timerCallback();
|
||||
};
|
||||
|
||||
} // End of namespace Scumm
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user