aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/chewy/console.cpp18
-rw-r--r--engines/chewy/console.h1
-rw-r--r--engines/chewy/resource.cpp70
-rw-r--r--engines/chewy/resource.h18
4 files changed, 95 insertions, 12 deletions
diff --git a/engines/chewy/console.cpp b/engines/chewy/console.cpp
index 298e10baf4..8d55651ffc 100644
--- a/engines/chewy/console.cpp
+++ b/engines/chewy/console.cpp
@@ -37,6 +37,7 @@ Console::Console(ChewyEngine *vm) : GUI::Debugger(), _vm(vm) {
registerCmd("play_sound", WRAP_METHOD(Console, Cmd_PlaySound));
registerCmd("play_speech", WRAP_METHOD(Console, Cmd_PlaySpeech));
registerCmd("play_music", WRAP_METHOD(Console, Cmd_PlayMusic));
+ registerCmd("text", WRAP_METHOD(Console, Cmd_Text));
}
Console::~Console() {
@@ -148,4 +149,21 @@ bool Console::Cmd_PlayMusic(int argc, const char **argv) {
return true;
}
+bool Console::Cmd_Text(int argc, const char **argv) {
+ if (argc < 2) {
+ debugPrintf("Usage: <file> <text number>\n");
+ return true;
+ }
+
+ Common::String filename = argv[1];
+ int resNum = atoi(argv[2]);
+
+ TextResource *res = new TextResource(filename);
+ Common::String str = res->getText(resNum);
+ this->debugPrintf("Text: %s\n", str.c_str());
+ delete res;
+
+ return true;
+}
+
} // End of namespace Chewy
diff --git a/engines/chewy/console.h b/engines/chewy/console.h
index 873359db40..bca8ea0b6a 100644
--- a/engines/chewy/console.h
+++ b/engines/chewy/console.h
@@ -43,6 +43,7 @@ private:
bool Cmd_PlaySound(int argc, const char **argv);
bool Cmd_PlaySpeech(int argc, const char **argv);
bool Cmd_PlayMusic(int argc, const char **argv);
+ bool Cmd_Text(int argc, const char **argv);
};
} // End of namespace Chewy
diff --git a/engines/chewy/resource.cpp b/engines/chewy/resource.cpp
index 1bd9583a72..b8fba3713c 100644
--- a/engines/chewy/resource.cpp
+++ b/engines/chewy/resource.cpp
@@ -30,17 +30,37 @@
namespace Chewy {
Resource::Resource(Common::String filename) {
+ const uint32 headerGeneric = MKTAG('N', 'G', 'S', '\0');
+ const uint32 headerTxtDec = MKTAG('T', 'C', 'F', '\0');
+ const uint32 headerTxtEnc = MKTAG('T', 'C', 'F', '\1');
+
_stream.open(filename);
- uint32 magicBytes = MKTAG('N', 'G', 'S', '\0');
- if (_stream.readUint32BE() != magicBytes)
+
+ uint32 header = _stream.readUint32BE();
+ bool isText = header == headerTxtDec || header == headerTxtEnc;
+
+ if (header != headerGeneric && !isText)
error("Invalid resource - %s", filename.c_str());
- _resType = (ResourceType)_stream.readUint16LE();
+
+ if (isText) {
+ _resType = kResourceTCF;
+ _encrypted = (header == headerTxtEnc);
+ } else {
+ _resType = (ResourceType)_stream.readUint16LE();
+ _encrypted = false;
+ }
+
_chunkCount = _stream.readUint16LE();
for (uint i = 0; i < _chunkCount; i++) {
Chunk cur;
cur.size = _stream.readUint32LE();
- cur.type = (ResourceType)_stream.readUint16LE();
+
+ if (!isText)
+ cur.type = (ResourceType)_stream.readUint16LE();
+ else
+ cur.num = _stream.readUint16LE();
+
cur.pos = _stream.pos();
_stream.skip(cur.size);
@@ -57,11 +77,15 @@ uint32 Resource::getChunkCount() const {
return _chunkList.size();
}
-Chunk *Resource::getChunk(int num) {
+Chunk *Resource::getChunk(uint num) {
+ assert(num < _chunkList.size());
+
return &_chunkList[num];
}
-byte *Resource::getChunkData(int num) {
+byte *Resource::getChunkData(uint num) {
+ assert(num < _chunkList.size());
+
Chunk *chunk = &_chunkList[num];
byte *data = new byte[chunk->size];
@@ -71,7 +95,9 @@ byte *Resource::getChunkData(int num) {
return data;
}
-TBFChunk *BackgroundResource::getImage(int num) {
+TBFChunk *BackgroundResource::getImage(uint num) {
+ assert(num < _chunkList.size());
+
Chunk *chunk = &_chunkList[num];
TBFChunk *tbf = new TBFChunk();
@@ -111,7 +137,9 @@ TBFChunk *BackgroundResource::getImage(int num) {
return tbf;
}
-SoundChunk *SoundResource::getSound(int num) {
+SoundChunk *SoundResource::getSound(uint num) {
+ assert(num < _chunkList.size());
+
Chunk *chunk = &_chunkList[num];
SoundChunk *sound = new SoundChunk();
@@ -155,4 +183,30 @@ SoundChunk *SoundResource::getSound(int num) {
return sound;
}
+Common::String TextResource::getText(uint num) {
+ assert(num < _chunkList.size());
+
+ Chunk *chunk = &_chunkList[num];
+ Common::String str;
+ byte *data = new byte[chunk->size];
+
+ _stream.seek(chunk->pos, SEEK_SET);
+
+ _stream.read(data, chunk->size);
+
+ if (_encrypted) {
+ byte *c = data;
+
+ for (uint i = 0; i < chunk->size; i++) {
+ *c = -(*c);
+ ++c;
+ }
+ }
+
+ str = (char *)data;
+ delete[] data;
+
+ return str;
+}
+
} // End of namespace Chewy
diff --git a/engines/chewy/resource.h b/engines/chewy/resource.h
index 50a0d1b8fb..cfaa802834 100644
--- a/engines/chewy/resource.h
+++ b/engines/chewy/resource.h
@@ -70,6 +70,7 @@ enum ResourceType {
// Generic chunk header
struct Chunk {
uint32 size;
+ uint16 num; // same as the type below, used in chunks where the type is substituted with count
ResourceType type;
uint32 pos; // position of the actual data
};
@@ -103,13 +104,14 @@ public:
ResourceType getType() const { return _resType; }
uint32 getChunkCount() const;
- Chunk *getChunk(int num);
- virtual byte *getChunkData(int num);
+ Chunk *getChunk(uint num);
+ virtual byte *getChunkData(uint num);
protected:
Common::File _stream;
uint16 _chunkCount;
ResourceType _resType;
+ byte _encrypted;
ChunkList _chunkList;
};
@@ -119,7 +121,7 @@ public:
BackgroundResource(Common::String filename) : Resource(filename) {}
~BackgroundResource() {}
- TBFChunk *getImage(int num);
+ TBFChunk *getImage(uint num);
};
class SoundResource : public Resource {
@@ -127,7 +129,15 @@ public:
SoundResource(Common::String filename) : Resource(filename) {}
~SoundResource() {}
- SoundChunk *getSound(int num);
+ SoundChunk *getSound(uint num);
+};
+
+class TextResource : public Resource {
+public:
+ TextResource(Common::String filename) : Resource(filename) {}
+ ~TextResource() {}
+
+ Common::String getText(uint num);
};
} // End of namespace Chewy