aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
authorJohannes Schickel2008-02-09 16:18:44 +0000
committerJohannes Schickel2008-02-09 16:18:44 +0000
commit76182fbd59878cdbb25915df69c149954fb0c556 (patch)
treea39a1481ab38cf787560825e9fba09d64bdd9aae /engines/kyra
parentbacdc6eff09abdb9a91a515fcf245687df244c7e (diff)
downloadscummvm-rg350-76182fbd59878cdbb25915df69c149954fb0c556.tar.gz
scummvm-rg350-76182fbd59878cdbb25915df69c149954fb0c556.tar.bz2
scummvm-rg350-76182fbd59878cdbb25915df69c149954fb0c556.zip
Revised way of how archive files are mounted:
- file entries from protected archives do not get overwritten anymore - preload indicator of archives will be unflagged, if embedded file entries are overwritten by other archives svn-id: r30838
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/resource.cpp85
-rw-r--r--engines/kyra/resource.h13
2 files changed, 59 insertions, 39 deletions
diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp
index fecda49158..9a70cc69b8 100644
--- a/engines/kyra/resource.cpp
+++ b/engines/kyra/resource.cpp
@@ -154,9 +154,41 @@ bool Resource::loadPakFile(const Common::String &filename) {
iter->_value.mounted = true;
iter->_value.preload = true;
- loader->loadFile(filename, *stream, _map);
+ ResArchiveLoader::FileList files;
+ loader->loadFile(filename, *stream, files);
delete stream;
stream = 0;
+
+ for (ResArchiveLoader::FileList::iterator i = files.begin(); i != files.end(); ++i) {
+ iter = _map.find(i->filename);
+ if (iter == _map.end()) {
+ _map[i->filename] = i->entry;
+ } else if (!iter->_value.parent.empty()) {
+ if (!iter->_value.parent.equalsIgnoreCase(filename)) {
+ ResFileMap::iterator oldParent = _map.find(iter->_value.parent);
+ if (oldParent != _map.end()) {
+ // Protected files and their embedded files don't get overwritten!
+ if (!oldParent->_value.prot) {
+ // If it's not protected we mark the old parent as not preload anymore,
+ // since not all of its embedded files are not in the filemap now anymore.
+ oldParent->_value.preload = false;
+ _map[i->filename] = i->entry;
+ }
+ } else {
+ // Old parent not found? That's strange... But we just overwrite the old
+ // entry.
+ _map[i->filename] = i->entry;
+ }
+ } else {
+ // The parent has the same filenames as we, but we are sure and overwrite the
+ // old file entry.
+ _map[i->filename] = i->entry;
+ }
+ }
+ // 'else' case would mean here an existing fileentry in the map without parent.
+ // We don't support that though, so one can overwrite files from archives by putting
+ // them in the gamepath.
+ }
detectFileTypes();
return true;
@@ -322,7 +354,7 @@ Common::SeekableReadStream *Resource::getFileStream(const Common::String &file)
const ResArchiveLoader *loader = getLoader(parentIter->_value.type);
assert(loader);
- return loader->loadFileFromArchive(file, parent, _map);
+ return loader->loadFileFromArchive(file, parent, iter->_value);
} else {
Common::File *stream = new Common::File();
if (!stream->open(file.c_str())) {
@@ -393,8 +425,8 @@ class ResLoaderPak : public ResArchiveLoader {
public:
bool checkFilename(Common::String filename) const;
bool isLoadable(const Common::String &filename, Common::SeekableReadStream &stream) const;
- bool loadFile(const Common::String &filename, Common::SeekableReadStream &stream, ResFileMap &map) const;
- Common::SeekableReadStream *loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileMap &map) const;
+ bool loadFile(const Common::String &filename, Common::SeekableReadStream &stream, FileList &files) const;
+ Common::SeekableReadStream *loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileEntry entry) const;
ResFileEntry::kType getType() const {
return ResFileEntry::kPak;
@@ -450,12 +482,9 @@ bool ResLoaderPak::isLoadable(const Common::String &filename, Common::SeekableRe
return true;
}
-bool ResLoaderPak::loadFile(const Common::String &filename, Common::SeekableReadStream &stream, ResFileMap &map) const {
+bool ResLoaderPak::loadFile(const Common::String &filename, Common::SeekableReadStream &stream, FileList &files) const {
uint32 filesize = stream.size();
- Common::List<Common::String> filenames;
- Common::List<ResFileEntry> entries;
-
uint32 startoffset = 0, endoffset = 0;
bool switchEndian = false;
bool firstFile = true;
@@ -510,8 +539,7 @@ bool ResLoaderPak::loadFile(const Common::String &filename, Common::SeekableRead
entry.prot = false;
entry.preload = false;
- filenames.push_back(file);
- entries.push_back(entry);
+ files.push_back(File(file, entry));
}
if (endoffset == filesize)
@@ -520,26 +548,14 @@ bool ResLoaderPak::loadFile(const Common::String &filename, Common::SeekableRead
startoffset = endoffset;
}
- assert(filenames.size() == entries.size());
-
- Common::List<ResFileEntry>::iterator entry = entries.begin();
- Common::List<Common::String>::iterator file = filenames.begin();
-
- for (; entry != entries.end(); ++entry, ++file)
- map[*file] = *entry;
-
return true;
}
-Common::SeekableReadStream *ResLoaderPak::loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileMap &map) const {
+Common::SeekableReadStream *ResLoaderPak::loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileEntry entry) const {
assert(archive);
- ResFileMap::const_iterator entry = map.find(file);
- if (entry == map.end())
- return 0;
-
- archive->seek(entry->_value.offset, SEEK_SET);
- Common::SeekableSubReadStream *stream = new Common::SeekableSubReadStream(archive, entry->_value.offset, entry->_value.offset + entry->_value.size, true);
+ archive->seek(entry.offset, SEEK_SET);
+ Common::SeekableSubReadStream *stream = new Common::SeekableSubReadStream(archive, entry.offset, entry.offset + entry.size, true);
assert(stream);
return stream;
}
@@ -548,8 +564,8 @@ class ResLoaderIns : public ResArchiveLoader {
public:
bool checkFilename(Common::String filename) const;
bool isLoadable(const Common::String &filename, Common::SeekableReadStream &stream) const;
- bool loadFile(const Common::String &filename, Common::SeekableReadStream &stream, ResFileMap &map) const;
- Common::SeekableReadStream *loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileMap &map) const;
+ bool loadFile(const Common::String &filename, Common::SeekableReadStream &stream, FileList &files) const;
+ Common::SeekableReadStream *loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileEntry entry) const;
ResFileEntry::kType getType() const {
return ResFileEntry::kIns;
@@ -575,7 +591,7 @@ bool ResLoaderIns::isLoadable(const Common::String &filename, Common::SeekableRe
return (buffer[0] == 0x0D && buffer[1] == 0x0A);
}
-bool ResLoaderIns::loadFile(const Common::String &filename, Common::SeekableReadStream &stream, ResFileMap &map) const {
+bool ResLoaderIns::loadFile(const Common::String &filename, Common::SeekableReadStream &stream, FileList &files) const {
Common::List<Common::String> filenames;
// thanks to eriktorbjorn for this code (a bit modified though)
@@ -614,22 +630,17 @@ bool ResLoaderIns::loadFile(const Common::String &filename, Common::SeekableRead
entry.size = stream.readUint32LE();
entry.offset = stream.pos();
stream.seek(entry.size, SEEK_CUR);
-
- map[*file] = entry;
+ files.push_back(File(*file, entry));
}
return true;
}
-Common::SeekableReadStream *ResLoaderIns::loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileMap &map) const {
+Common::SeekableReadStream *ResLoaderIns::loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileEntry entry) const {
assert(archive);
- ResFileMap::const_iterator entry = map.find(file);
- if (entry == map.end())
- return 0;
-
- archive->seek(entry->_value.offset, SEEK_SET);
- Common::SeekableSubReadStream *stream = new Common::SeekableSubReadStream(archive, entry->_value.offset, entry->_value.offset + entry->_value.size, true);
+ archive->seek(entry.offset, SEEK_SET);
+ Common::SeekableSubReadStream *stream = new Common::SeekableSubReadStream(archive, entry.offset, entry.offset + entry.size, true);
assert(stream);
return stream;
}
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 2a917bfb8c..17c93dcca5 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -62,13 +62,22 @@ class Resource;
class ResArchiveLoader {
public:
+ struct File {
+ File() : filename(), entry() {}
+ File(const Common::String &f, const ResFileEntry &e) : filename(f), entry(e) {}
+
+ Common::String filename;
+ ResFileEntry entry;
+ };
+ typedef Common::List<File> FileList;
+
virtual ~ResArchiveLoader() {}
virtual bool checkFilename(Common::String filename) const = 0;
virtual bool isLoadable(const Common::String &filename, Common::SeekableReadStream &stream) const = 0;
- virtual bool loadFile(const Common::String &filename, Common::SeekableReadStream &stream, ResFileMap &map) const = 0;
+ virtual bool loadFile(const Common::String &filename, Common::SeekableReadStream &stream, FileList &files) const = 0;
// parameter 'archive' can be deleted by this method and it may not be deleted from the caller
- virtual Common::SeekableReadStream *loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileMap &map) const = 0;
+ virtual Common::SeekableReadStream *loadFileFromArchive(const Common::String &file, Common::SeekableReadStream *archive, const ResFileEntry entry) const = 0;
virtual ResFileEntry::kType getType() const = 0;
protected: