From 7ed456f268d9f6db71b07fd3e7e8859556295e6c Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Fri, 21 Jan 2011 01:58:53 +0000 Subject: MOHAWK: Add support for installer files from Riven and other Broderbund games svn-id: r55368 --- engines/mohawk/installer_archive.cpp | 125 +++++++++++++++++++++++++++++++++++ engines/mohawk/installer_archive.h | 67 +++++++++++++++++++ engines/mohawk/module.mk | 1 + engines/mohawk/riven.cpp | 6 ++ engines/mohawk/riven.h | 2 + 5 files changed, 201 insertions(+) create mode 100644 engines/mohawk/installer_archive.cpp create mode 100644 engines/mohawk/installer_archive.h (limited to 'engines/mohawk') diff --git a/engines/mohawk/installer_archive.cpp b/engines/mohawk/installer_archive.cpp new file mode 100644 index 0000000000..8a486a2a58 --- /dev/null +++ b/engines/mohawk/installer_archive.cpp @@ -0,0 +1,125 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "mohawk/installer_archive.h" + +#include "common/dcl.h" +#include "common/debug.h" +#include "common/substream.h" +#include "common/util.h" + +namespace Mohawk { + +InstallerArchive::InstallerArchive() : Common::Archive() { + _stream = 0; +} + +InstallerArchive::~InstallerArchive() { + close(); +} + +bool InstallerArchive::open(const Common::String &filename) { + close(); + + _stream = SearchMan.createReadStreamForMember(filename); + + if (!_stream) + return false; + + // Check for the magic uint32 + // No idea what it means, but it's how "file" recognizes them + if (_stream->readUint32BE() != 0x135D658C) { + close(); + return false; + } + + // Let's move to the directory + _stream->seek(41); + uint32 offset = _stream->readUint32LE(); + _stream->seek(offset); + + // Now read in each file from the directory + uint16 fileCount = _stream->readUint16LE(); + debug(2, "File count = %d", fileCount); + + for (uint16 i = 0; i < fileCount; i++) { + FileEntry entry; + + _stream->skip(12); // Unknown + + entry.uncompressedSize = _stream->readUint32LE(); + entry.compressedSize = _stream->readUint32LE(); + entry.offset = _stream->readUint32LE(); + + _stream->skip(14); // Unknown + + byte nameLength = _stream->readByte(); + Common::String name; + while (nameLength--) + name += _stream->readByte(); + + _stream->skip(4); // Unknown + + _map[name] = entry; + + debug(3, "Found file '%s' at 0x%08x (Comp: 0x%08x, Uncomp: 0x%08x)", name.c_str(), + entry.offset, entry.compressedSize, entry.uncompressedSize); + } + + return true; +} + +void InstallerArchive::close() { + delete _stream; _stream = 0; + _map.clear(); +} + +bool InstallerArchive::hasFile(const Common::String &name) { + return _map.contains(name); +} + +int InstallerArchive::listMembers(Common::ArchiveMemberList &list) { + for (FileMap::const_iterator it = _map.begin(); it != _map.end(); it++) + list.push_back(getMember(it->_key)); + + return _map.size(); +} + +Common::ArchiveMemberPtr InstallerArchive::getMember(const Common::String &name) { + return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this)); +} + +Common::SeekableReadStream *InstallerArchive::createReadStreamForMember(const Common::String &name) const { + if (!_stream || !_map.contains(name)) + return 0; + + const FileEntry &entry = _map[name]; + + // Seek to our offset and then send it off to the decompressor + _stream->seek(entry.offset); + return Common::decompressDCL(_stream, entry.compressedSize, entry.uncompressedSize); +} + +} // End of namespace Mohawk diff --git a/engines/mohawk/installer_archive.h b/engines/mohawk/installer_archive.h new file mode 100644 index 0000000000..565b363be3 --- /dev/null +++ b/engines/mohawk/installer_archive.h @@ -0,0 +1,67 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/archive.h" +#include "common/scummsys.h" +#include "common/endian.h" +#include "common/file.h" +#include "common/str.h" + +#ifndef MOHAWK_INSTALLER_ARCHIVE_H +#define MOHAWK_INSTALLER_ARCHIVE_H + +namespace Mohawk { + +class InstallerArchive : public Common::Archive { +public: + InstallerArchive(); + ~InstallerArchive(); + + bool open(const Common::String &filename); + void close(); + bool isOpen() const { return _stream != 0; } + + // Common::Archive API implementation + bool hasFile(const Common::String &name); + int listMembers(Common::ArchiveMemberList &list); + Common::ArchiveMemberPtr getMember(const Common::String &name); + Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; + +private: + struct FileEntry { + uint32 uncompressedSize; + uint32 compressedSize; + uint32 offset; + }; + + Common::SeekableReadStream *_stream; + + typedef Common::HashMap FileMap; + FileMap _map; +}; + +} // End of namespace Mohawk + +#endif diff --git a/engines/mohawk/module.mk b/engines/mohawk/module.mk index 82e38ad5b3..858a5d35bb 100644 --- a/engines/mohawk/module.mk +++ b/engines/mohawk/module.mk @@ -12,6 +12,7 @@ MODULE_OBJS = \ detection.o \ dialogs.o \ graphics.o \ + installer_archive.o \ livingbooks.o \ livingbooks_code.o \ mohawk.o \ diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index 5ca49de944..00d0e5255f 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -31,6 +31,7 @@ #include "mohawk/cursors.h" #include "mohawk/graphics.h" +#include "mohawk/installer_archive.h" #include "mohawk/resource.h" #include "mohawk/riven.h" #include "mohawk/riven_external.h" @@ -108,6 +109,11 @@ GUI::Debugger *MohawkEngine_Riven::getDebugger() { Common::Error MohawkEngine_Riven::run() { MohawkEngine::run(); + // Let's try to open the installer file (it holds extras.mhk) + // Though, we set a low priority to prefer the extracted version + if (_installerArchive.open("arcriven.z")) + SearchMan.add("arcriven.z", &_installerArchive, 0, false); + _gfx = new RivenGraphics(this); _console = new RivenConsole(this); _saveLoad = new RivenSaveLoad(this, _saveFileMan); diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h index 251a0fc753..16acf9419c 100644 --- a/engines/mohawk/riven.h +++ b/engines/mohawk/riven.h @@ -26,6 +26,7 @@ #ifndef MOHAWK_RIVEN_H #define MOHAWK_RIVEN_H +#include "mohawk/installer_archive.h" #include "mohawk/mohawk.h" #include "mohawk/riven_scripts.h" @@ -131,6 +132,7 @@ private: RivenConsole *_console; RivenSaveLoad *_saveLoad; RivenOptionsDialog *_optionsDialog; + InstallerArchive _installerArchive; // Stack/Card-related functions and variables uint16 _curCard; -- cgit v1.2.3