aboutsummaryrefslogtreecommitdiff
path: root/engines/composer/resource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/composer/resource.cpp')
-rw-r--r--engines/composer/resource.cpp87
1 files changed, 87 insertions, 0 deletions
diff --git a/engines/composer/resource.cpp b/engines/composer/resource.cpp
index 390649ba52..cd77fa16fc 100644
--- a/engines/composer/resource.cpp
+++ b/engines/composer/resource.cpp
@@ -23,6 +23,7 @@
#include "composer/resource.h"
#include "common/debug.h"
+#include "common/memstream.h"
#include "common/substream.h"
#include "common/util.h"
#include "common/textconsole.h"
@@ -247,4 +248,90 @@ bool ComposerArchive::openStream(Common::SeekableReadStream *stream) {
return true;
}
+Pipe::Pipe(Common::SeekableReadStream *stream) {
+ _offset = 0;
+ _stream = stream;
+
+ nextFrame();
+}
+
+void Pipe::nextFrame() {
+ if (_offset == (uint)_stream->size())
+ return;
+
+ _stream->seek(_offset, SEEK_SET);
+
+ uint32 tagCount = _stream->readUint32LE();
+ _offset += 4;
+ for (uint i = 0; i < tagCount; i++) {
+ uint32 tag = _stream->readUint32BE();
+ uint32 count = _stream->readUint32LE();
+ _offset += 8;
+
+ ResourceMap &resMap = _types[tag];
+
+ _offset += (12 * count);
+ //uint32 baseOffset = _offset;
+ for (uint j = 0; j < count; j++) {
+ uint32 offset = _stream->readUint32LE();
+ uint32 size = _stream->readUint32LE();
+ uint16 id = _stream->readUint16LE();
+ uint32 unknown = _stream->readUint16LE(); // frame id?
+ debug(9, "pipe: %s/%d: offset %d, size %d, unknown %d", tag2str(tag), id, offset, size, unknown);
+
+ PipeResourceEntry entry;
+ entry.size = size;
+ entry.offset = _offset;
+ resMap[id].entries.push_back(entry);
+
+ _offset += size;
+ }
+ _stream->seek(_offset, SEEK_SET);
+ }
+}
+
+bool Pipe::hasResource(uint32 tag, uint16 id) const {
+ if (!_types.contains(tag))
+ return false;
+
+ return _types[tag].contains(id);
+}
+
+Common::SeekableReadStream *Pipe::getResource(uint32 tag, uint16 id, bool buffering) {
+ if (!_types.contains(tag))
+ error("Pipe does not contain '%s' %04x", tag2str(tag), id);
+
+ const ResourceMap &resMap = _types[tag];
+
+ if (!resMap.contains(id))
+ error("Archive does not contain '%s' %04x", tag2str(tag), id);
+
+ const PipeResource &res = resMap[id];
+
+ if (res.entries.size() == 1) {
+ Common::SeekableReadStream *stream = new Common::SeekableSubReadStream(_stream,
+ res.entries[0].offset, res.entries[0].offset + res.entries[0].size);
+ if (buffering)
+ _types[tag].erase(id);
+ return stream;
+ }
+
+ // If there are multiple entries in the pipe, we have to concaternate them together.
+
+ uint32 size = 0;
+ for (uint i = 0; i < res.entries.size(); i++)
+ size += res.entries[i].size;
+
+ byte *buffer = (byte *)malloc(size);
+ uint32 offset = 0;
+ for (uint i = 0; i < res.entries.size(); i++) {
+ _stream->seek(res.entries[i].offset, SEEK_SET);
+ _stream->read(buffer + offset, res.entries[i].size);
+ offset += res.entries[i].size;
+ }
+ if (buffering)
+ _types[tag].erase(id);
+ return new Common::MemoryReadStream(buffer, size, DisposeAfterUse::YES);
+}
+
} // End of namespace Composer