aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/platform/sdl/sdl.cpp6
-rw-r--r--common/archive.cpp13
-rw-r--r--common/archive.h18
-rw-r--r--engines/kyra/resource.cpp67
-rw-r--r--engines/kyra/resource.h13
-rw-r--r--engines/parallaction/disk_br.cpp21
-rw-r--r--graphics/imageman.cpp2
-rw-r--r--gui/ThemeEngine.cpp13
8 files changed, 87 insertions, 66 deletions
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index 1c7c2fd975..be69817d5a 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -282,8 +282,7 @@ void OSystem_SDL::addSysArchivesToSearchSet(Common::SearchSet &s, int priority)
// FIXME: We use depth = 4 for now, to match the old code. May want to change that
Common::FSNode dataNode(DATA_PATH);
if (dataNode.exists() && dataNode.isDirectory()) {
- Common::ArchivePtr dataArchive(new Common::FSDirectory(dataNode, 4));
- s.add(DATA_PATH, dataArchive, priority);
+ s.add(DATA_PATH, new Common::FSDirectory(dataNode, 4), priority);
}
#endif
@@ -296,8 +295,7 @@ void OSystem_SDL::addSysArchivesToSearchSet(Common::SearchSet &s, int priority)
if (CFURLGetFileSystemRepresentation(fileUrl, true, buf, sizeof(buf))) {
// Success: Add it to the search path
Common::String bundlePath((const char *)buf);
- Common::ArchivePtr bundleArchive(new Common::FSDirectory(bundlePath));
- s.add("__OSX_BUNDLE__", bundleArchive, priority);
+ s.add("__OSX_BUNDLE__", new Common::FSDirectory(bundlePath), priority);
}
CFRelease(fileUrl);
}
diff --git a/common/archive.cpp b/common/archive.cpp
index 3c5df35326..8881d44116 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -281,9 +281,9 @@ void SearchSet::insert(const Node &node) {
_list.insert(it, node);
}
-void SearchSet::add(const String& name, ArchivePtr archive, int priority) {
+void SearchSet::add(const String& name, Archive *archive, int priority, bool autoFree) {
if (find(name) == _list.end()) {
- Node node(priority, name, archive);
+ Node node(priority, name, archive, autoFree);
insert(node);
} else {
warning("SearchSet::add: archive '%s' already present", name.c_str());
@@ -294,6 +294,8 @@ void SearchSet::add(const String& name, ArchivePtr archive, int priority) {
void SearchSet::remove(const String& name) {
ArchiveList::iterator it = find(name);
if (it != _list.end()) {
+ if (it->_autoFree)
+ delete it->_arc;
_list.erase(it);
}
}
@@ -303,6 +305,11 @@ bool SearchSet::hasArchive(const String &name) const {
}
void SearchSet::clear() {
+ for (ArchiveList::iterator i = _list.begin(); i != _list.end(); ++i) {
+ if (i->_autoFree)
+ delete i->_arc;
+ }
+
_list.clear();
}
@@ -391,7 +398,7 @@ void SearchManager::addDirectory(const String &name, const FSNode &dir, int prio
if (!dir.exists() || !dir.isDirectory())
return;
- add(name, ArchivePtr(new FSDirectory(dir, depth)), priority);
+ add(name, new FSDirectory(dir, depth), priority);
}
void SearchManager::clear() {
diff --git a/common/archive.h b/common/archive.h
index 5f8cd9be60..1f29820aea 100644
--- a/common/archive.h
+++ b/common/archive.h
@@ -114,9 +114,6 @@ public:
};
-typedef SharedPtr<Archive> ArchivePtr;
-
-
/**
* FSDirectory models a directory tree from the filesystem and allows users
* to access it through the Archive interface. Searching is case-insensitive,
@@ -228,11 +225,12 @@ public:
*/
class SearchSet : public Archive {
struct Node {
- int _priority;
- String _name;
- ArchivePtr _arc;
- Node(int priority, const String &name, ArchivePtr arc)
- : _priority(priority), _name(name), _arc(arc) {
+ int _priority;
+ String _name;
+ Archive *_arc;
+ bool _autoFree;
+ Node(int priority, const String &name, Archive *arc, bool autoFree)
+ : _priority(priority), _name(name), _arc(arc), _autoFree(autoFree) {
}
};
typedef List<Node> ArchiveList;
@@ -244,10 +242,12 @@ class SearchSet : public Archive {
void insert(const Node& node);
public:
+ virtual ~SearchSet() { clear(); }
+
/**
* Add a new archive to the searchable set.
*/
- void add(const String& name, ArchivePtr archive, int priority = 0);
+ void add(const String& name, Archive *arch, int priority = 0, bool autoFree = true);
/**
* Remove an archive from the searchable set.
diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp
index c3ab6e5e70..2b09036b4e 100644
--- a/engines/kyra/resource.cpp
+++ b/engines/kyra/resource.cpp
@@ -35,23 +35,22 @@
namespace Kyra {
-Resource::Resource(KyraEngine_v1 *vm) : _archiveCache(), _files(), _archiveFiles(new Common::SearchSet()), _protectedFiles(new Common::SearchSet()), _loaders(), _vm(vm) {
+Resource::Resource(KyraEngine_v1 *vm) : _archiveCache(), _files(), _archiveFiles(), _protectedFiles(), _loaders(), _vm(vm) {
initializeLoaders();
- Common::SharedPtr<Common::Archive> path(new Common::FSDirectory(ConfMan.get("path"), 2));
- Common::SharedPtr<Common::Archive> extrapath(new Common::FSDirectory(ConfMan.get("extrapath")));
-
- _files.add("path", path, 4);
- _files.add("extrapath", extrapath, 4);
- _vm->_system->addSysArchivesToSearchSet(_files, 3);
+ _files.add("global_search", &Common::SearchManager::instance(), 3, false);
// compressed installer archives are added at level '2',
// but that's done in Resource::reset not here
- _files.add("protected", _protectedFiles, 1);
- _files.add("archives", _archiveFiles, 0);
+ _files.add("protected", &_protectedFiles, 1, false);
+ _files.add("archives", &_archiveFiles, 0, false);
}
Resource::~Resource() {
_loaders.clear();
+
+ for (ArchiveMap::iterator i = _archiveCache.begin(); i != _archiveCache.end(); ++i)
+ delete i->_value;
+ _archiveCache.clear();
}
bool Resource::reset() {
@@ -68,7 +67,7 @@ bool Resource::reset() {
return true;
} else if (_vm->game() == GI_KYRA2) {
if (_vm->gameFlags().useInstallerPackage)
- _files.add("installer", loadInstallerArchive("WESTWOOD", "%03d", 6), 2);
+ _files.add("installer", loadInstallerArchive("WESTWOOD", "%03d", 6), 2, false);
// mouse pointer, fonts, etc. required for initializing
if (_vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie) {
@@ -91,7 +90,7 @@ bool Resource::reset() {
return true;
} else if (_vm->game() == GI_LOL) {
if (_vm->gameFlags().useInstallerPackage)
- _files.add("installer", loadInstallerArchive("WESTWOOD", "%d", 0), 2);
+ _files.add("installer", loadInstallerArchive("WESTWOOD", "%d", 0), 2, false);
return true;
}
@@ -114,9 +113,9 @@ bool Resource::reset() {
if (fileList.empty())
error("Couldn't load PAK file '%s'", list[i]);
- Common::ArchivePtr archive = loadArchive(list[i], *fileList.begin());
+ Common::Archive *archive = loadArchive(list[i], *fileList.begin());
if (archive)
- _protectedFiles->add(list[i], archive, 0);
+ _protectedFiles.add(list[i], archive, 0, false);
}
} else {
for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
@@ -155,14 +154,14 @@ bool Resource::loadPakFile(Common::String filename) {
bool Resource::loadPakFile(Common::String name, Common::SharedPtr<Common::ArchiveMember> file) {
name.toUppercase();
- if (_archiveFiles->hasArchive(name) || _protectedFiles->hasArchive(name))
+ if (_archiveFiles.hasArchive(name) || _protectedFiles.hasArchive(name))
return true;
- Common::ArchivePtr archive = loadArchive(name, file);
+ Common::Archive *archive = loadArchive(name, file);
if (!archive)
return false;
- _archiveFiles->add(name, archive, 0);
+ _archiveFiles.add(name, archive, 0, false);
return true;
}
@@ -220,16 +219,24 @@ bool Resource::loadFileList(const char * const *filelist, uint32 numFiles) {
void Resource::unloadPakFile(Common::String filename, bool remFromCache) {
filename.toUppercase();
- _archiveFiles->remove(filename);
- if (remFromCache)
- _archiveCache.erase(filename);
+
// We do not remove files from '_protectedFiles' here, since
// those are protected against unloading.
+ if (_archiveFiles.hasArchive(filename)) {
+ _archiveFiles.remove(filename);
+ if (remFromCache) {
+ ArchiveMap::iterator iter = _archiveCache.find(filename);
+ if (iter != _archiveCache.end()) {
+ delete iter->_value;
+ _archiveCache.erase(filename);
+ }
+ }
+ }
}
bool Resource::isInPakList(Common::String filename) {
filename.toUppercase();
- return (_archiveFiles->hasArchive(filename) || _protectedFiles->hasArchive(filename));
+ return (_archiveFiles.hasArchive(filename) || _protectedFiles.hasArchive(filename));
}
bool Resource::isInCacheList(Common::String name) {
@@ -238,8 +245,8 @@ bool Resource::isInCacheList(Common::String name) {
}
void Resource::unloadAllPakFiles() {
- _archiveFiles->clear();
- _protectedFiles->clear();
+ _archiveFiles.clear();
+ _protectedFiles.clear();
}
void Resource::listFiles(const Common::String &pattern, Common::ArchiveMemberList &list) {
@@ -294,7 +301,7 @@ Common::SeekableReadStream *Resource::getFileStream(const Common::String &file)
return _files.openFile(file);
}
-Common::ArchivePtr Resource::loadArchive(const Common::String &name, Common::SharedPtr<Common::ArchiveMember> member) {
+Common::Archive *Resource::loadArchive(const Common::String &name, Common::SharedPtr<Common::ArchiveMember> member) {
ArchiveMap::iterator cachedArchive = _archiveCache.find(name);
if (cachedArchive != _archiveCache.end())
return cachedArchive->_value;
@@ -302,14 +309,14 @@ Common::ArchivePtr Resource::loadArchive(const Common::String &name, Common::Sha
Common::SeekableReadStream *stream = member->open();
if (!stream)
- return Common::ArchivePtr();
+ return 0;
- Common::ArchivePtr archive;
+ Common::Archive *archive = 0;
for (LoaderList::const_iterator i = _loaders.begin(); i != _loaders.end(); ++i) {
if ((*i)->checkFilename(name)) {
if ((*i)->isLoadable(name, *stream)) {
stream->seek(0, SEEK_SET);
- archive = Common::ArchivePtr((*i)->load(member, *stream));
+ archive = (*i)->load(member, *stream);
break;
} else {
stream->seek(0, SEEK_SET);
@@ -320,20 +327,20 @@ Common::ArchivePtr Resource::loadArchive(const Common::String &name, Common::Sha
delete stream;
if (!archive)
- return Common::ArchivePtr();
+ return 0;
_archiveCache[name] = archive;
return archive;
}
-Common::ArchivePtr Resource::loadInstallerArchive(const Common::String &file, const Common::String &ext, const uint8 offset) {
+Common::Archive *Resource::loadInstallerArchive(const Common::String &file, const Common::String &ext, const uint8 offset) {
ArchiveMap::iterator cachedArchive = _archiveCache.find(file);
if (cachedArchive != _archiveCache.end())
return cachedArchive->_value;
- Common::ArchivePtr archive(InstallerLoader::load(this, file, ext, offset));
+ Common::Archive *archive = InstallerLoader::load(this, file, ext, offset);
if (!archive)
- return Common::ArchivePtr();
+ return 0;
_archiveCache[file] = archive;
return archive;
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 0831acaed6..72846e273a 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -55,8 +55,11 @@ public:
bool loadPakFile(Common::String filename);
bool loadPakFile(Common::String name, Common::SharedPtr<Common::ArchiveMember> file);
+
void unloadPakFile(Common::String filename, bool remFromCache = false);
+
bool isInPakList(Common::String filename);
+
bool isInCacheList(Common::String name);
bool loadFileList(const Common::String &filedata);
@@ -75,15 +78,15 @@ public:
bool loadFileToBuf(const char *file, void *buf, uint32 maxSize);
protected:
- typedef Common::HashMap<Common::String, Common::ArchivePtr, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> ArchiveMap;
+ typedef Common::HashMap<Common::String, Common::Archive*, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> ArchiveMap;
ArchiveMap _archiveCache;
Common::SearchSet _files;
- Common::SharedPtr<Common::SearchSet> _archiveFiles;
- Common::SharedPtr<Common::SearchSet> _protectedFiles;
+ Common::SearchSet _archiveFiles;
+ Common::SearchSet _protectedFiles;
- Common::ArchivePtr loadArchive(const Common::String &name, Common::SharedPtr<Common::ArchiveMember> member);
- Common::ArchivePtr loadInstallerArchive(const Common::String &file, const Common::String &ext, const uint8 offset);
+ Common::Archive *loadArchive(const Common::String &name, Common::SharedPtr<Common::ArchiveMember> member);
+ Common::Archive *loadInstallerArchive(const Common::String &file, const Common::String &ext, const uint8 offset);
void initializeLoaders();
diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp
index 5d36076549..20b1370796 100644
--- a/engines/parallaction/disk_br.cpp
+++ b/engines/parallaction/disk_br.cpp
@@ -129,8 +129,7 @@ Common::String DosDisk_br::selectArchive(const Common::String& name) {
debugC(5, kDebugDisk, "DosDisk_br::selectArchive: adding part directory to search set");
_sset.remove("part");
- Common::SharedPtr<Common::FSDirectory> partDir(_baseDir->getSubDirectory(name, 3));
- _sset.add("part", partDir, 10);
+ _sset.add("part", _baseDir->getSubDirectory(name, 3), 10);
return oldPath;
}
@@ -149,7 +148,8 @@ void DosDisk_br::init() {
// TODO: clarify whether the engine or OSystem should add the base game directory to the search manager.
// Right now, I am keeping an internal search set to do the job.
_baseDir = Common::SharedPtr<Common::FSDirectory>(new Common::FSDirectory(ConfMan.get("path")));
- _sset.add("base", _baseDir, 5);
+ // FIXME: We use this gross hack here since we switched SearchSet to accept plain pointers
+ _sset.add("base", _baseDir.get(), 5, false);
}
@@ -392,7 +392,8 @@ void DosDemoDisk_br::init() {
// TODO: clarify whether the engine or OSystem should add the base game directory to the search manager.
// Right now, I am keeping an internal search set to do the job.
_baseDir = Common::SharedPtr<Common::FSDirectory>(new Common::FSDirectory(ConfMan.get("path"), 2));
- _sset.add("base", _baseDir, 5);
+ // FIXME: We use this gross hack here since we switched SearchSet to accept plain pointers
+ _sset.add("base", _baseDir.get(), 5, false);
}
@@ -413,14 +414,13 @@ AmigaDisk_br::AmigaDisk_br(Parallaction *vm) : DosDisk_br(vm) {
void AmigaDisk_br::init() {
_baseDir = Common::SharedPtr<Common::FSDirectory>(new Common::FSDirectory(ConfMan.get("path")));
- _sset.add("base", _baseDir, 5);
+ // FIXME: We use this gross hack here since we switched SearchSet to accept plain pointers
+ _sset.add("base", _baseDir.get(), 5, false);
const Common::String subDirNames[3] = { "fonts", "backs", "common" };
const Common::String subDirPrefixes[3] = { "fonts", "backs", Common::String::emptyString };
- for (int i = 0; i < 3; i++) {
- Common::SharedPtr<Common::Archive> subDir(_baseDir->getSubDirectory(subDirPrefixes[i], subDirNames[i], 2));
- _sset.add(subDirNames[i], subDir, 6);
- }
+ for (int i = 0; i < 3; i++)
+ _sset.add(subDirNames[i], _baseDir->getSubDirectory(subDirPrefixes[i], subDirNames[i], 2), 6);
}
AmigaDisk_br::~AmigaDisk_br() {
@@ -623,8 +623,7 @@ Common::String AmigaDisk_br::selectArchive(const Common::String& name) {
debugC(5, kDebugDisk, "AmigaDisk_br::selectArchive: adding part directory to search set");
_sset.remove("part");
- Common::SharedPtr<Common::FSDirectory> partDir(_baseDir->getSubDirectory(name, 3));
- _sset.add("part", partDir, 10);
+ _sset.add("part", _baseDir->getSubDirectory(name, 3), 10);
return oldPath;
}
diff --git a/graphics/imageman.cpp b/graphics/imageman.cpp
index 1a7bcdefd1..5b7b490cd7 100644
--- a/graphics/imageman.cpp
+++ b/graphics/imageman.cpp
@@ -66,7 +66,7 @@ bool ImageManager::addArchive(const Common::String &name) {
arch = dir;
}
- _archives.add(name, Common::ArchivePtr(arch));
+ _archives.add(name, arch);
return true;
}
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index 7d59720d7d..13fd1ea24d 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -525,38 +525,42 @@ bool ThemeEngine::loadThemeXML(const Common::String &themeName) {
if (!node.exists() || !node.isReadable())
return false;
- Common::ArchivePtr archive;
+ Common::Archive *archive;
if (node.getName().hasSuffix(".zip") && !node.isDirectory()) {
#ifdef USE_ZLIB
Common::ZipArchive *zipArchive = new Common::ZipArchive(node);
- archive = Common::ArchivePtr(zipArchive);
+ archive = zipArchive;
if (!zipArchive || !zipArchive->isOpen()) {
+ delete zipArchive;
warning("Failed to open Zip archive '%s'.", themeName.c_str());
return false;
}
#endif
} else if (node.isDirectory()) {
- archive = Common::ArchivePtr(new Common::FSDirectory(node));
+ archive = new Common::FSDirectory(node);
}
Common::File themercFile;
themercFile.open("THEMERC", *archive);
if (!themercFile.isOpen()) {
+ delete archive;
warning("Theme '%s' contains no 'THEMERC' file.", themeName.c_str());
return false;
}
Common::String stxHeader = themercFile.readLine();
if (!themeConfigParseHeader(stxHeader, _themeName) || _themeName.empty()) {
+ delete archive;
warning("Corrupted 'THEMERC' file in theme '%s'", _themeFileName.c_str());
return false;
}
Common::ArchiveMemberList members;
if (0 == archive->listMatchingMembers(members, "*.stx")) {
+ delete archive;
warning("Found no STX files for theme '%s'.", themeName.c_str());
return false;
}
@@ -566,12 +570,14 @@ bool ThemeEngine::loadThemeXML(const Common::String &themeName) {
assert((*i)->getName().hasSuffix(".stx"));
if (_parser->loadStream((*i)->open()) == false) {
+ delete archive;
warning("Failed to load STX file '%s'", (*i)->getName().c_str());
_parser->close();
return false;
}
if (_parser->parse() == false) {
+ delete archive;
warning("Failed to parse STX file '%s'", (*i)->getName().c_str());
_parser->close();
return false;
@@ -580,6 +586,7 @@ bool ThemeEngine::loadThemeXML(const Common::String &themeName) {
_parser->close();
}
+ delete archive;
assert(!_themeName.empty());
return true;
}