aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMatthew Hoops2012-05-28 16:54:49 -0400
committerMatthew Hoops2012-05-28 16:54:49 -0400
commitab45e72e67c7effae9a9fecbaf5a77f9427d8df4 (patch)
tree344bc13beb3fddce3134aa0cb953b1523c133251 /engines
parentf7e515a361dac041e6693ed9a1056df6ad05975e (diff)
downloadscummvm-rg350-ab45e72e67c7effae9a9fecbaf5a77f9427d8df4.tar.gz
scummvm-rg350-ab45e72e67c7effae9a9fecbaf5a77f9427d8df4.tar.bz2
scummvm-rg350-ab45e72e67c7effae9a9fecbaf5a77f9427d8df4.zip
COMMON: Move InstallShield code to common
The code also now works for both data compressed with sync bytes and without
Diffstat (limited to 'engines')
-rw-r--r--engines/agos/installshield_cab.cpp220
-rw-r--r--engines/agos/installshield_cab.h41
-rw-r--r--engines/agos/module.mk1
-rw-r--r--engines/agos/res.cpp8
4 files changed, 6 insertions, 264 deletions
diff --git a/engines/agos/installshield_cab.cpp b/engines/agos/installshield_cab.cpp
deleted file mode 100644
index d4e636f7b3..0000000000
--- a/engines/agos/installshield_cab.cpp
+++ /dev/null
@@ -1,220 +0,0 @@
-/* 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.
- *
- */
-
-// The following code is based on unshield
-// Original copyright:
-
-// Copyright (c) 2003 David Eriksson <twogood@users.sourceforge.net>
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of
-// this software and associated documentation files (the "Software"), to deal in
-// the Software without restriction, including without limitation the rights to
-// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-// of the Software, and to permit persons to whom the Software is furnished to do
-// so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-#include "agos/installshield_cab.h"
-
-#include "common/debug.h"
-#include "common/file.h"
-#include "common/memstream.h"
-#include "common/zlib.h"
-
-namespace AGOS {
-
-class InstallShieldCabinet : public Common::Archive {
- Common::String _installShieldFilename;
-
-public:
- InstallShieldCabinet(const Common::String &filename);
- ~InstallShieldCabinet();
-
- // Common::Archive API implementation
- bool hasFile(const Common::String &name) const;
- int listMembers(Common::ArchiveMemberList &list) const;
- const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
- Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
-
-private:
- struct FileEntry {
- uint32 uncompressedSize;
- uint32 compressedSize;
- uint32 offset;
- uint16 flags;
- };
-
- typedef Common::HashMap<Common::String, FileEntry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
- FileMap _map;
-};
-
-InstallShieldCabinet::~InstallShieldCabinet() {
- _map.clear();
-}
-
-InstallShieldCabinet::InstallShieldCabinet(const Common::String &filename) : _installShieldFilename(filename) {
- Common::File installShieldFile;
-
- if (!installShieldFile.open(_installShieldFilename)) {
- warning("InstallShieldCabinet::InstallShieldCabinet(): Could not find the archive file %s", _installShieldFilename.c_str());
- return;
- }
-
- // Note that we only support a limited subset of cabinet files
- // Only single cabinet files and ones without data shared between
- // cabinets.
-
- // Check for the magic uint32
- if (installShieldFile.readUint32LE() != 0x28635349) {
- warning("InstallShieldCabinet::InstallShieldCabinet(): Magic ID doesn't match");
- return;
- }
-
- uint32 version = installShieldFile.readUint32LE();
-
- if (version != 0x01000004) {
- warning("Unsupported CAB version %08x", version);
- return;
- }
-
- /* uint32 volumeInfo = */ installShieldFile.readUint32LE();
- uint32 cabDescriptorOffset = installShieldFile.readUint32LE();
- /* uint32 cabDescriptorSize = */ installShieldFile.readUint32LE();
-
- installShieldFile.seek(cabDescriptorOffset);
-
- installShieldFile.skip(12);
- uint32 fileTableOffset = installShieldFile.readUint32LE();
- installShieldFile.skip(4);
- uint32 fileTableSize = installShieldFile.readUint32LE();
- uint32 fileTableSize2 = installShieldFile.readUint32LE();
- uint32 directoryCount = installShieldFile.readUint32LE();
- installShieldFile.skip(8);
- uint32 fileCount = installShieldFile.readUint32LE();
-
- if (fileTableSize != fileTableSize2)
- warning("file table sizes do not match");
-
- // We're ignoring file groups and components since we
- // should not need them. Moving on to the files...
-
- installShieldFile.seek(cabDescriptorOffset + fileTableOffset);
- uint32 fileTableCount = directoryCount + fileCount;
- uint32 *fileTableOffsets = new uint32[fileTableCount];
- for (uint32 i = 0; i < fileTableCount; i++)
- fileTableOffsets[i] = installShieldFile.readUint32LE();
-
- for (uint32 i = directoryCount; i < fileCount + directoryCount; i++) {
- installShieldFile.seek(cabDescriptorOffset + fileTableOffset + fileTableOffsets[i]);
- uint32 nameOffset = installShieldFile.readUint32LE();
- /* uint32 directoryIndex = */ installShieldFile.readUint32LE();
-
- // First read in data needed by us to get at the file data
- FileEntry entry;
- entry.flags = installShieldFile.readUint16LE();
- entry.uncompressedSize = installShieldFile.readUint32LE();
- entry.compressedSize = installShieldFile.readUint32LE();
- installShieldFile.skip(20);
- entry.offset = installShieldFile.readUint32LE();
-
- // Then let's get the string
- installShieldFile.seek(cabDescriptorOffset + fileTableOffset + nameOffset);
- Common::String fileName;
-
- char c = installShieldFile.readByte();
- while (c) {
- fileName += c;
- c = installShieldFile.readByte();
- }
- _map[fileName] = entry;
- }
-
- delete[] fileTableOffsets;
-}
-
-bool InstallShieldCabinet::hasFile(const Common::String &name) const {
- return _map.contains(name);
-}
-
-int InstallShieldCabinet::listMembers(Common::ArchiveMemberList &list) const {
- for (FileMap::const_iterator it = _map.begin(); it != _map.end(); it++)
- list.push_back(getMember(it->_key));
-
- return _map.size();
-}
-
-const Common::ArchiveMemberPtr InstallShieldCabinet::getMember(const Common::String &name) const {
- return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
-}
-
-Common::SeekableReadStream *InstallShieldCabinet::createReadStreamForMember(const Common::String &name) const {
- if (!_map.contains(name))
- return 0;
-
- const FileEntry &entry = _map[name];
-
- Common::File archiveFile;
- archiveFile.open(_installShieldFilename);
- archiveFile.seek(entry.offset);
-
- if (!(entry.flags & 0x04)) {
- // Not compressed
- return archiveFile.readStream(entry.uncompressedSize);
- }
-
-#ifdef USE_ZLIB
- byte *src = (byte *)malloc(entry.compressedSize);
- byte *dst = (byte *)malloc(entry.uncompressedSize);
-
- archiveFile.read(src, entry.compressedSize);
-
- bool result = Common::inflateZlibHeaderless(dst, entry.uncompressedSize, src, entry.compressedSize);
- free(src);
-
- if (!result) {
- warning("failed to inflate CAB file '%s'", name.c_str());
- free(dst);
- return 0;
- }
-
- return new Common::MemoryReadStream(dst, entry.uncompressedSize, DisposeAfterUse::YES);
-#else
- warning("zlib required to extract compressed CAB file '%s'", name.c_str());
- return 0;
-#endif
-}
-
-Common::Archive *makeInstallShieldArchive(const Common::String &name) {
- return new InstallShieldCabinet(name);
-}
-
-} // End of namespace AGOS
diff --git a/engines/agos/installshield_cab.h b/engines/agos/installshield_cab.h
deleted file mode 100644
index f7e8bed277..0000000000
--- a/engines/agos/installshield_cab.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* 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.
- *
- */
-
-#include "common/archive.h"
-#include "common/str.h"
-
-#ifndef AGOS_INSTALLSHIELD_CAB_H
-#define AGOS_INSTALLSHIELD_CAB_H
-
-namespace AGOS {
-
-/**
- * This factory method creates an Archive instance corresponding to the content
- * of the InstallShield compressed file with the given name.
- *
- * May return 0 in case of a failure.
- */
-Common::Archive *makeInstallShieldArchive(const Common::String &name);
-
-} // End of namespace AGOS
-
-#endif
diff --git a/engines/agos/module.mk b/engines/agos/module.mk
index 7ae5e17bf2..7069d8005b 100644
--- a/engines/agos/module.mk
+++ b/engines/agos/module.mk
@@ -51,7 +51,6 @@ ifdef ENABLE_AGOS2
MODULE_OBJS += \
animation.o \
feeble.o \
- installshield_cab.o \
oracle.o \
script_dp.o \
script_ff.o \
diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp
index 0305879390..2e44a6575c 100644
--- a/engines/agos/res.cpp
+++ b/engines/agos/res.cpp
@@ -23,6 +23,8 @@
// Resource file routines for Simon1/Simon2
+#include "common/archive.h"
+#include "common/installshield_cab.h"
#include "common/file.h"
#include "common/memstream.h"
#include "common/textconsole.h"
@@ -31,7 +33,6 @@
#include "agos/agos.h"
#include "agos/intern.h"
#include "agos/sound.h"
-#include "agos/installshield_cab.h"
#include "common/zlib.h"
@@ -43,7 +44,10 @@ ArchiveMan::ArchiveMan() {
#ifdef ENABLE_AGOS2
void ArchiveMan::registerArchive(const Common::String &filename, int priority) {
- add(filename, makeInstallShieldArchive(filename), priority);
+ Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(filename);
+
+ if (stream)
+ add(filename, makeInstallShieldArchive(stream, DisposeAfterUse::YES), priority);
}
#endif