diff options
author | Nipun Garg | 2019-07-30 03:10:18 +0530 |
---|---|---|
committer | Eugene Sandulenko | 2019-09-03 17:17:30 +0200 |
commit | 3acb70c759586faef9a5f9f5131c6da6e17e5f89 (patch) | |
tree | f5a2f13191b4288bfd421b2e7896ff9fc7d74f0a | |
parent | 52f2af77f314278451fdc6a4e5a537283c409629 (diff) | |
download | scummvm-rg350-3acb70c759586faef9a5f9f5131c6da6e17e5f89.tar.gz scummvm-rg350-3acb70c759586faef9a5f9f5131c6da6e17e5f89.tar.bz2 scummvm-rg350-3acb70c759586faef9a5f9f5131c6da6e17e5f89.zip |
HDB: Wrap ReadStreams pointing to compressed...
...files
-rw-r--r-- | engines/hdb/file-manager.cpp | 47 | ||||
-rw-r--r-- | engines/hdb/file-manager.h | 2 | ||||
-rw-r--r-- | engines/hdb/gfx.cpp | 2 |
3 files changed, 45 insertions, 6 deletions
diff --git a/engines/hdb/file-manager.cpp b/engines/hdb/file-manager.cpp index c205a4b123..4ce790c9ab 100644 --- a/engines/hdb/file-manager.cpp +++ b/engines/hdb/file-manager.cpp @@ -42,7 +42,7 @@ bool FileMan::openMPC(const Common::String &filename) { uint32 offset; if (!_mpcFile->open(filename)) { - error("FileMan::openMSD(): Error reading the MSD file"); + error("FileMan::openMPC(): Error reading the MSD/MPC file"); return false; } @@ -50,7 +50,7 @@ bool FileMan::openMPC(const Common::String &filename) { if (_dataHeader.id == MKTAG('M', 'P', 'C', 'C')) { _compressed = true; - debug("COMPRESSED FILE"); + debug("COMPRESSED MPC FILE"); return false; } else if (_dataHeader.id == MKTAG('M', 'P', 'C', 'U')) { @@ -64,7 +64,7 @@ bool FileMan::openMPC(const Common::String &filename) { _dataHeader.dirSize = _mpcFile->readUint32LE(); - debug(8, "MPC: Read %d entries", _dataHeader.dirSize); + debug(8, "MPCU: Read %d entries", _dataHeader.dirSize); for (uint32 fileIndex = 0; fileIndex < _dataHeader.dirSize; fileIndex++) { MPCEntry *dirEntry = new MPCEntry(); @@ -82,12 +82,43 @@ bool FileMan::openMPC(const Common::String &filename) { } return true; + } else if (_dataHeader.id == MKTAG('M', 'S', 'D', 'C')) { + _compressed = true; + + offset = _mpcFile->readUint32LE(); + _mpcFile->seek((int32)offset); + + // Note: The MPC archive format assumes the offset to be uint32, + // but Common::File::seek() takes the offset as int32. + + _dataHeader.dirSize = _mpcFile->readUint32LE(); + + debug(8, "MSDC: Read %d entries", _dataHeader.dirSize); + + for (uint32 fileIndex = 0; fileIndex < _dataHeader.dirSize; fileIndex++) { + MPCEntry *dirEntry = new MPCEntry(); + + for (int i = 0; i < 64; i++) { + dirEntry->filename[i] = tolower(_mpcFile->readByte()); + } + + dirEntry->offset = _mpcFile->readUint32LE(); + dirEntry->length = _mpcFile->readUint32LE(); + dirEntry->ulength = _mpcFile->readUint32LE(); + dirEntry->type = (DataType)_mpcFile->readUint32LE(); + _dir.push_back(dirEntry); + } + + return true; + } else if (_dataHeader.id == MKTAG('M', 'S', 'D', 'U')) { + _compressed = false; + debug("UNCOMPRESSED MSD FILE"); + return false; } - error("Invalid MPC File."); + error("Invalid MPC/MSD File."); return false; - } void FileMan::closeMPC() { @@ -139,7 +170,11 @@ Common::SeekableReadStream *FileMan::findFirstData(const char *string, DataType _mpcFile->read(buffer, file->ulength); // Return buffer wrapped in a MemoryReadStream - return new Common::MemoryReadStream(buffer, file->ulength, DisposeAfterUse::YES); + + if (_compressed) + return Common::wrapCompressedReadStream(new Common::MemoryReadStream(buffer, file->ulength, DisposeAfterUse::YES)); + else + return new Common::MemoryReadStream(buffer, file->ulength, DisposeAfterUse::YES); } int32 FileMan::getLength(const char *string, DataType type) { diff --git a/engines/hdb/file-manager.h b/engines/hdb/file-manager.h index d4cae4ddad..c7a6768dbc 100644 --- a/engines/hdb/file-manager.h +++ b/engines/hdb/file-manager.h @@ -23,6 +23,8 @@ #ifndef HDB_FILE_MANAGER_H #define HDB_FILE_MANAGER_H +#include "common/zlib.h" + namespace Common { class File; } diff --git a/engines/hdb/gfx.cpp b/engines/hdb/gfx.cpp index f380b9ffd1..5cf80a2a37 100644 --- a/engines/hdb/gfx.cpp +++ b/engines/hdb/gfx.cpp @@ -486,6 +486,8 @@ int Gfx::getTileIndex(const char *name) { Picture *Gfx::getPicture(const char *name) { Common::SeekableReadStream *stream = g_hdb->_fileMan->findFirstData(name, TYPE_PIC); + if (stream == nullptr) + return nullptr; Picture *picture = new Picture; picture->load(stream); delete stream; |