aboutsummaryrefslogtreecommitdiff
path: root/engines/chewy/resource.cpp
diff options
context:
space:
mode:
authorFilippos Karapetis2016-09-20 10:50:59 +0300
committerFilippos Karapetis2016-10-03 00:33:16 +0300
commit8ab1846f59504dc7edd8d26b7702d520e3bab631 (patch)
treef33463e08dede2a9a636c4b4567567de6cbe534f /engines/chewy/resource.cpp
parentb7e4bcf3f20dc38ccd465acc07f42cb62557a2c9 (diff)
downloadscummvm-rg350-8ab1846f59504dc7edd8d26b7702d520e3bab631.tar.gz
scummvm-rg350-8ab1846f59504dc7edd8d26b7702d520e3bab631.tar.bz2
scummvm-rg350-8ab1846f59504dc7edd8d26b7702d520e3bab631.zip
CHEWY: Add support for SFX and speech resources to the resource manager
Diffstat (limited to 'engines/chewy/resource.cpp')
-rw-r--r--engines/chewy/resource.cpp130
1 files changed, 95 insertions, 35 deletions
diff --git a/engines/chewy/resource.cpp b/engines/chewy/resource.cpp
index 40db53abe6..233e8cd4f4 100644
--- a/engines/chewy/resource.cpp
+++ b/engines/chewy/resource.cpp
@@ -34,64 +34,124 @@ Resource::Resource(Common::String filename) {
uint32 magicBytes = MKTAG('N', 'G', 'S', '\0');
if (_stream.readUint32BE() != magicBytes)
error("Invalid resource - %s", filename.c_str());
- _stream.skip(2); // type
+ _resType = (ResourceType)_stream.readUint16LE();
_chunkCount = _stream.readUint16LE();
- uint32 tbfID = MKTAG('T', 'B', 'F', '\0');
-
for (uint i = 0; i < _chunkCount; i++) {
- TBFChunk cur;
- cur.packedSize = _stream.readUint32LE() - TBF_CHUNK_HEADER_SIZE;
- cur.type = _stream.readUint16LE();
- if (_stream.readUint32BE() != tbfID)
- error("Corrupt resource %s", filename.c_str());
-
- cur.screenMode = _stream.readUint16LE();
- cur.compressionFlag = _stream.readUint16LE();
- cur.unpackedSize = _stream.readUint32LE();
- cur.width = _stream.readUint16LE();
- cur.height = _stream.readUint16LE();
- for (int j = 0; j < 3 * 256; j++)
- cur.palette[j] = _stream.readByte() << 2;
+ Chunk cur;
+ cur.size = _stream.readUint32LE();
+ cur.type = (ResourceType)_stream.readUint16LE();
cur.pos = _stream.pos();
- _stream.skip(cur.packedSize);
+ if (cur.type == kResourceTBF) {
+ cur.pos += TBF_CHUNK_HEADER_SIZE;
+ cur.size -= TBF_CHUNK_HEADER_SIZE;
+ readTBFChunk();
+ }
- _tbfChunkList.push_back(cur);
+ _stream.skip(cur.size);
+ _chunkList.push_back(cur);
}
-
}
Resource::~Resource() {
+ _chunkList.clear();
_tbfChunkList.clear();
_stream.close();
}
-TBFChunk *Resource::getChunk(int num) {
+void Resource::readTBFChunk() {
+ TBFChunk cur;
+ if (_stream.readUint32BE() != MKTAG('T', 'B', 'F', '\0'))
+ error("Corrupt TBF resource");
+
+ cur.screenMode = _stream.readUint16LE();
+ cur.compressionFlag = _stream.readUint16LE();
+ cur.unpackedSize = _stream.readUint32LE();
+ cur.width = _stream.readUint16LE();
+ cur.height = _stream.readUint16LE();
+ for (int j = 0; j < 3 * 256; j++)
+ cur.palette[j] = _stream.readByte() << 2;
+
+ _tbfChunkList.push_back(cur);
+}
+
+uint32 Resource::getChunkCount() const {
+ return _chunkList.size();
+}
+
+Chunk *Resource::getChunk(int num) {
+ return &_chunkList[num];
+}
+
+TBFChunk *Resource::getTBFChunk(int num) {
+ assert(_resType == kResourceTGP);
return &_tbfChunkList[num];
}
byte *Resource::getChunkData(int num) {
- TBFChunk *chunk = &_tbfChunkList[num];
- byte *data = new byte[chunk->unpackedSize];
+ Chunk *chunk = &_chunkList[num];
+ byte *data;
_stream.seek(chunk->pos, SEEK_SET);
- if (!chunk->compressionFlag) {
- _stream.read(data, chunk->packedSize);
- } else {
- // Compressed resources are packed using a very simple RLE compression
- byte count;
- byte value;
- uint32 outPos = 0;
-
- for (uint i = 0; i < (chunk->packedSize) / 2 && outPos < chunk->unpackedSize; i++) {
- count = _stream.readByte();
- value = _stream.readByte();
- for (byte j = 0; j < count; j++) {
- data[outPos++] = value;
+ if (chunk->type == kResourceTBF) {
+ TBFChunk *tbfChunk = &_tbfChunkList[num];
+ data = new byte[tbfChunk->unpackedSize];
+
+ if (!tbfChunk->compressionFlag) {
+ _stream.read(data, chunk->size);
+ } else {
+ // Compressed images are packed using a very simple RLE compression
+ byte count;
+ byte value;
+ uint32 outPos = 0;
+
+ for (uint i = 0; i < (chunk->size) / 2 && outPos < tbfChunk->unpackedSize; i++) {
+ count = _stream.readByte();
+ value = _stream.readByte();
+ for (byte j = 0; j < count; j++) {
+ data[outPos++] = value;
+ }
}
}
+ } else if (chunk->type == kResourceVOC) {
+ // Voice files are split in blocks, so reassemble them here
+ byte blocksRemaining;
+ uint32 totalLength = 0;
+ uint32 blockSize;
+
+ // Find the total length of the voice file
+ do {
+ blocksRemaining = _stream.readByte();
+ blockSize =
+ _stream.readByte() +
+ (_stream.readByte() << 8) +
+ (_stream.readByte() << 16);
+
+ totalLength += blockSize;
+ _stream.skip(blockSize);
+ } while (blocksRemaining > 1);
+
+ // Read the voice data
+ data = new byte[totalLength];
+ byte *ptr = data;
+
+ _stream.seek(chunk->pos, SEEK_SET);
+
+ do {
+ blocksRemaining = _stream.readByte();
+ blockSize =
+ _stream.readByte() +
+ (_stream.readByte() << 8) +
+ (_stream.readByte() << 16);
+
+ _stream.read(ptr, blockSize);
+ ptr += blockSize;
+ } while (blocksRemaining > 1);
+ } else {
+ data = new byte[chunk->size];
+ _stream.read(data, chunk->size);
}
return data;