aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2016-09-20 12:10:59 +0300
committerFilippos Karapetis2016-10-03 00:33:29 +0300
commitc6ccd8bbe8da08534a9f1e23258dc4011a60382c (patch)
tree9c8dc00b5be289afc52575c7c6a07f7888875a35
parent676fa15c193bbd2a7fc2962d0c2bc26e260efd6a (diff)
downloadscummvm-rg350-c6ccd8bbe8da08534a9f1e23258dc4011a60382c.tar.gz
scummvm-rg350-c6ccd8bbe8da08534a9f1e23258dc4011a60382c.tar.bz2
scummvm-rg350-c6ccd8bbe8da08534a9f1e23258dc4011a60382c.zip
CHEWY: Use a specialized resource handler for each resource
-rw-r--r--engines/chewy/console.cpp32
-rw-r--r--engines/chewy/console.h1
-rw-r--r--engines/chewy/graphics.cpp12
-rw-r--r--engines/chewy/resource.cpp166
-rw-r--r--engines/chewy/resource.h48
-rw-r--r--engines/chewy/sound.cpp24
-rw-r--r--engines/chewy/sound.h6
7 files changed, 171 insertions, 118 deletions
diff --git a/engines/chewy/console.cpp b/engines/chewy/console.cpp
index b610dddf65..298e10baf4 100644
--- a/engines/chewy/console.cpp
+++ b/engines/chewy/console.cpp
@@ -32,6 +32,7 @@ namespace Chewy {
Console::Console(ChewyEngine *vm) : GUI::Debugger(), _vm(vm) {
registerCmd("dump", WRAP_METHOD(Console, Cmd_Dump));
+ registerCmd("dump_bg", WRAP_METHOD(Console, Cmd_DumpBg));
registerCmd("draw", WRAP_METHOD(Console, Cmd_Draw));
registerCmd("play_sound", WRAP_METHOD(Console, Cmd_PlaySound));
registerCmd("play_speech", WRAP_METHOD(Console, Cmd_PlaySpeech));
@@ -55,10 +56,6 @@ bool Console::Cmd_Dump(int argc, const char **argv) {
Chunk *chunk = res->getChunk(resNum);
byte *data = res->getChunkData(resNum);
uint32 size = chunk->size;
- if (chunk->type == kResourceTBF) {
- TBFChunk *tbf = res->getTBFChunk(resNum);
- size = tbf->unpackedSize;
- }
Common::DumpFile outFile;
outFile.open(dumpFilename);
@@ -72,6 +69,33 @@ bool Console::Cmd_Dump(int argc, const char **argv) {
return true;
}
+bool Console::Cmd_DumpBg(int argc, const char **argv) {
+ if (argc < 4) {
+ debugPrintf("Usage: dump_bg <file> <resource number> <dump file name>\n");
+ return true;
+ }
+
+ Common::String filename = argv[1];
+ int resNum = atoi(argv[2]);
+ Common::String dumpFilename = argv[3];
+
+ BackgroundResource *res = new BackgroundResource(filename);
+ TBFChunk *image = res->getImage(resNum);
+
+ Common::DumpFile outFile;
+ outFile.open(dumpFilename);
+ outFile.write(image->data, image->size);
+ outFile.flush();
+ outFile.close();
+
+ delete[] image->data;
+ delete image;
+ delete res;
+
+ return true;
+}
+
+
bool Console::Cmd_Draw(int argc, const char **argv) {
if (argc < 3) {
debugPrintf("Usage: draw <file> <resource number>\n");
diff --git a/engines/chewy/console.h b/engines/chewy/console.h
index 9877824fff..873359db40 100644
--- a/engines/chewy/console.h
+++ b/engines/chewy/console.h
@@ -38,6 +38,7 @@ private:
ChewyEngine *_vm;
bool Cmd_Dump(int argc, const char **argv);
+ bool Cmd_DumpBg(int argc, const char **argv);
bool Cmd_Draw(int argc, const char **argv);
bool Cmd_PlaySound(int argc, const char **argv);
bool Cmd_PlaySpeech(int argc, const char **argv);
diff --git a/engines/chewy/graphics.cpp b/engines/chewy/graphics.cpp
index ba16cfb74f..c3b29febff 100644
--- a/engines/chewy/graphics.cpp
+++ b/engines/chewy/graphics.cpp
@@ -29,13 +29,15 @@
namespace Chewy {
void Graphics::drawImage(Common::String filename, int imageNum) {
- Resource *res = new Resource(filename);
- TBFChunk *cur = res->getTBFChunk(imageNum);
- byte *buf = res->getChunkData(imageNum);
+ BackgroundResource *res = new BackgroundResource(filename);
+ TBFChunk *image = res->getImage(imageNum);
- g_system->getPaletteManager()->setPalette(cur->palette, 0, 256);
- g_system->copyRectToScreen(buf, cur->width, 0, 0, cur->width, cur->height);
+ g_system->getPaletteManager()->setPalette(image->palette, 0, 256);
+ g_system->copyRectToScreen(image->data, image->width, 0, 0, image->width, image->height);
g_system->updateScreen();
+
+ delete[] image->data;
+ delete image;
delete res;
}
diff --git a/engines/chewy/resource.cpp b/engines/chewy/resource.cpp
index 233e8cd4f4..1bd9583a72 100644
--- a/engines/chewy/resource.cpp
+++ b/engines/chewy/resource.cpp
@@ -43,12 +43,6 @@ Resource::Resource(Common::String filename) {
cur.type = (ResourceType)_stream.readUint16LE();
cur.pos = _stream.pos();
- if (cur.type == kResourceTBF) {
- cur.pos += TBF_CHUNK_HEADER_SIZE;
- cur.size -= TBF_CHUNK_HEADER_SIZE;
- readTBFChunk();
- }
-
_stream.skip(cur.size);
_chunkList.push_back(cur);
}
@@ -56,26 +50,9 @@ Resource::Resource(Common::String filename) {
Resource::~Resource() {
_chunkList.clear();
- _tbfChunkList.clear();
_stream.close();
}
-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();
}
@@ -84,77 +61,98 @@ Chunk *Resource::getChunk(int num) {
return &_chunkList[num];
}
-TBFChunk *Resource::getTBFChunk(int num) {
- assert(_resType == kResourceTGP);
- return &_tbfChunkList[num];
+byte *Resource::getChunkData(int num) {
+ Chunk *chunk = &_chunkList[num];
+ byte *data = new byte[chunk->size];
+
+ _stream.seek(chunk->pos, SEEK_SET);
+ _stream.read(data, chunk->size);
+
+ return data;
}
-byte *Resource::getChunkData(int num) {
+TBFChunk *BackgroundResource::getImage(int num) {
Chunk *chunk = &_chunkList[num];
- byte *data;
+ TBFChunk *tbf = new TBFChunk();
_stream.seek(chunk->pos, SEEK_SET);
- 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;
- }
+ if (_stream.readUint32BE() != MKTAG('T', 'B', 'F', '\0'))
+ error("Corrupt TBF resource");
+
+ tbf->screenMode = _stream.readUint16LE();
+ tbf->compressionFlag = _stream.readUint16LE();
+ tbf->size = _stream.readUint32LE();
+ tbf->width = _stream.readUint16LE();
+ tbf->height = _stream.readUint16LE();
+ for (int j = 0; j < 3 * 256; j++)
+ tbf->palette[j] = _stream.readByte() << 2;
+
+ tbf->data = new byte[tbf->size];
+
+ if (!tbf->compressionFlag) {
+ _stream.read(tbf->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 < tbf->size; i++) {
+ count = _stream.readByte();
+ value = _stream.readByte();
+ for (byte j = 0; j < count; j++) {
+ tbf->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;
+ return tbf;
+}
+
+SoundChunk *SoundResource::getSound(int num) {
+ Chunk *chunk = &_chunkList[num];
+ SoundChunk *sound = new SoundChunk();
+
+ _stream.seek(chunk->pos, SEEK_SET);
+
+ // 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
+ sound->size = totalLength;
+ sound->data = new byte[totalLength];
+ byte *ptr = sound->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);
+
+ return sound;
}
} // End of namespace Chewy
diff --git a/engines/chewy/resource.h b/engines/chewy/resource.h
index e0b4230b71..50a0d1b8fb 100644
--- a/engines/chewy/resource.h
+++ b/engines/chewy/resource.h
@@ -36,12 +36,12 @@ namespace Chewy {
enum ResourceType {
kResourcePCX = 0, // unused
- kResourceTBF = 1, // contained in TGPs
+ kResourceTBF = 1, // background art, contained in TGPs
kResourceTAF = 2,
kResourceTFF = 3,
- kResourceVOC = 4, // contained in TVPs
+ kResourceVOC = 4, // speech and SFX, contained in TVPs
kResourceTPF = 5, // unused
- kResourceTMF = 6, // unused
+ kResourceTMF = 6, // music, similar to a MOD file, contained in details.tap
kResourceMOD = 7, // unused
kResourceRAW = 8, // unused
kResourceLBM = 9, // unused
@@ -56,10 +56,10 @@ enum ResourceType {
kResourceAAD = 18, // unused
kResourceADS = 19, // unused
kResourceADH = 20, // used in txt/diah.adh
- kResourceTGP = 21, // background, used in back/comic.tgp, back/episode1.tgp and back/gbook.tgp
- kResourceTVP = 22, // speech, used in sound/speech.tvp
+ kResourceTGP = 21, // container for background art, used in back/comic.tgp, back/episode1.tgp and back/gbook.tgp
+ kResourceTVP = 22, // container for speech, used in sound/speech.tvp
kResourceTTP = 23, // unused
- kResourceTAP = 24, // sound effects, music and cutscenes, used in sound/details.tap and cut/cut.tap
+ kResourceTAP = 24, // container for sound effects, music and cutscenes, used in sound/details.tap and cut/cut.tap
kResourceCFO = 25, // unused
kResourceTCF = 26 // error messages, used in err/err_e.tcf (English) and err/err_d.tcf (German)
};
@@ -67,21 +67,30 @@ enum ResourceType {
// 4 + 2 + 2 + 4 + 2 + 2 + 768 = 784 bytes
#define TBF_CHUNK_HEADER_SIZE 784
+// Generic chunk header
struct Chunk {
uint32 size;
ResourceType type;
uint32 pos; // position of the actual data
};
+// TBF (background) chunk header
struct TBFChunk {
// TBF chunk header
// ID (TBF, followed by a zero)
uint16 screenMode;
uint16 compressionFlag;
- uint32 unpackedSize;
+ uint32 size;
uint16 width;
uint16 height;
byte palette[3 * 256];
+ byte *data;
+};
+
+// Sound chunk header
+struct SoundChunk {
+ uint32 size;
+ byte *data;
};
typedef Common::Array<Chunk> ChunkList;
@@ -90,24 +99,35 @@ typedef Common::Array<TBFChunk> TBFChunkList;
class Resource {
public:
Resource(Common::String filename);
- ~Resource();
+ virtual ~Resource();
ResourceType getType() const { return _resType; }
uint32 getChunkCount() const;
Chunk *getChunk(int num);
- TBFChunk *getTBFChunk(int num);
- byte *getChunkData(int num);
+ virtual byte *getChunkData(int num);
protected:
Common::File _stream;
uint16 _chunkCount;
ResourceType _resType;
-private:
- void readTBFChunk();
-
ChunkList _chunkList;
- TBFChunkList _tbfChunkList;
+};
+
+class BackgroundResource : public Resource {
+public:
+ BackgroundResource(Common::String filename) : Resource(filename) {}
+ ~BackgroundResource() {}
+
+ TBFChunk *getImage(int num);
+};
+
+class SoundResource : public Resource {
+public:
+ SoundResource(Common::String filename) : Resource(filename) {}
+ ~SoundResource() {}
+
+ SoundChunk *getSound(int num);
};
} // End of namespace Chewy
diff --git a/engines/chewy/sound.cpp b/engines/chewy/sound.cpp
index 41f91d0886..9ef4df97d9 100644
--- a/engines/chewy/sound.cpp
+++ b/engines/chewy/sound.cpp
@@ -31,8 +31,8 @@
namespace Chewy {
Sound::Sound() {
- _speechRes = new Resource("speech.tvp");
- _soundRes = new Resource("details.tap");
+ _speechRes = new SoundResource("speech.tvp");
+ _soundRes = new SoundResource("details.tap");
}
Sound::~Sound() {
@@ -41,16 +41,20 @@ Sound::~Sound() {
}
void Sound::playSound(int num, bool loop) {
- Chunk *chunk = _soundRes->getChunk(num);
- byte *data = _soundRes->getChunkData(num);
+ SoundChunk *sound = _soundRes->getSound(num);
+ byte *data = (byte *)malloc(sound->size);
+ memcpy(data, sound->data, sound->size);
Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
Audio::makeRawStream(data,
- chunk->size, 22050, Audio::FLAG_UNSIGNED,
+ sound->size, 22050, Audio::FLAG_UNSIGNED,
DisposeAfterUse::NO),
loop ? 0 : 1);
g_engine->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, stream);
+
+ delete[] sound->data;
+ delete sound;
}
void Sound::playMusic(int num, bool loop) {
@@ -72,16 +76,20 @@ void Sound::playMusic(int num, bool loop) {
}
void Sound::playSpeech(int num) {
- Chunk *chunk = _speechRes->getChunk(num);
- byte *data = _speechRes->getChunkData(num);
+ SoundChunk *sound = _speechRes->getSound(num);
+ byte *data = (byte *)malloc(sound->size);
+ memcpy(data, sound->data, sound->size);
Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
Audio::makeRawStream(data,
- chunk->size, 22050, Audio::FLAG_UNSIGNED,
+ sound->size, 22050, Audio::FLAG_UNSIGNED,
DisposeAfterUse::NO),
1);
g_engine->_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_speechHandle, stream);
+
+ delete[] sound->data;
+ delete sound;
}
} // End of namespace Chewy
diff --git a/engines/chewy/sound.h b/engines/chewy/sound.h
index 6537f3eabe..23610272e5 100644
--- a/engines/chewy/sound.h
+++ b/engines/chewy/sound.h
@@ -28,7 +28,7 @@
namespace Chewy {
-class Resource;
+class SoundResource;
class Sound {
public:
@@ -44,8 +44,8 @@ private:
Audio::SoundHandle _musicHandle;
Audio::SoundHandle _speechHandle;
- Resource *_speechRes;
- Resource *_soundRes;
+ SoundResource *_speechRes;
+ SoundResource *_soundRes;
};
} // End of namespace Chewy