aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mohawk')
-rw-r--r--engines/mohawk/installer_archive.cpp125
-rw-r--r--engines/mohawk/installer_archive.h67
-rw-r--r--engines/mohawk/module.mk1
-rw-r--r--engines/mohawk/riven.cpp6
-rw-r--r--engines/mohawk/riven.h2
5 files changed, 201 insertions, 0 deletions
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<Common::String, FileEntry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> 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;