PRINCE: Added support for unbundled compressed files

This commit is contained in:
Eugene Sandulenko 2018-05-05 14:16:49 +02:00
parent e3b9be6679
commit 6e58c5aaa5

View File

@ -24,14 +24,19 @@
#define PRINCE_RESOURCE_H
#include "common/stream.h"
#include "common/memstream.h"
#include "common/archive.h"
#include "common/debug-channels.h"
#include "common/ptr.h"
#include "prince/decompress.h"
namespace Prince {
namespace Resource {
static Common::SeekableReadStream *getDecompressedStream(Common::SeekableReadStream *stream);
template <typename T>
bool loadFromStream(T &resource, Common::SeekableReadStream &stream) {
return resource.loadStream(stream);
@ -39,13 +44,15 @@ bool loadFromStream(T &resource, Common::SeekableReadStream &stream) {
template<typename T>
bool loadResource(T *resource, const char *resourceName, bool required) {
Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
if (!stream) {
Common::SeekableReadStream *stream_(SearchMan.createReadStreamForMember(resourceName));
if (!stream_) {
if (required)
error("Can't load %s", resourceName);
return false;
}
Common::ScopedPtr<Common::SeekableReadStream> stream(getDecompressedStream(stream_));
return loadFromStream(*resource, *stream);
}
@ -61,26 +68,30 @@ bool loadResource(Common::Array<T> &array, Common::SeekableReadStream &stream, b
template <typename T>
bool loadResource(Common::Array<T> &array, const char *resourceName, bool required = true) {
Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
if (!stream) {
Common::SeekableReadStream *stream_(SearchMan.createReadStreamForMember(resourceName));
if (!stream_) {
if (required)
error("Can't load %s", resourceName);
return false;
}
Common::ScopedPtr<Common::SeekableReadStream> stream(getDecompressedStream(stream_));
return loadResource(array, *stream, required);
}
template <typename T>
bool loadResource(Common::Array<T *> &array, const char *resourceName, bool required = true) {
Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
if (!stream) {
Common::SeekableReadStream *stream_(SearchMan.createReadStreamForMember(resourceName));
if (!stream_) {
if (required)
error("Can't load %s", resourceName);
return false;
}
Common::ScopedPtr<Common::SeekableReadStream> stream(getDecompressedStream(stream_));
// FIXME: This is stupid. Maybe loadFromStream should be helper method that returns initialized object
while (true) {
T* t = new T();
@ -93,6 +104,28 @@ bool loadResource(Common::Array<T *> &array, const char *resourceName, bool requ
return true;
}
static Common::SeekableReadStream *getDecompressedStream(Common::SeekableReadStream *stream) {
byte header[4];
stream->read(header, 4);
stream->seek(0);
if (READ_BE_UINT32(header) == MKTAG('M', 'A', 'S', 'M')) {
byte *buffer = (byte *)malloc(stream->size());
stream->read(buffer, stream->size());
Decompressor dec;
uint32 decompLen = READ_BE_UINT32(buffer + 14);
byte *decompData = (byte *)malloc(decompLen);
dec.decompress(buffer + 18, decompData, decompLen);
free(buffer);
return new Common::MemoryReadStream(decompData, decompLen, DisposeAfterUse::YES);
} else {
return stream;
}
}
}
} // End of namespace Prince