[Scummvm-cvs-logs] SF.net SVN: scummvm: [30838] scummvm/trunk/engines/kyra

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Sat Feb 9 17:18:45 CET 2008


Revision: 30838
          http://scummvm.svn.sourceforge.net/scummvm/?rev=30838&view=rev
Author:   lordhoto
Date:     2008-02-09 08:18:44 -0800 (Sat, 09 Feb 2008)

Log Message:
-----------
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

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/resource.cpp
    scummvm/trunk/engines/kyra/resource.h

Modified: scummvm/trunk/engines/kyra/resource.cpp
===================================================================
--- scummvm/trunk/engines/kyra/resource.cpp	2008-02-09 15:46:06 UTC (rev 30837)
+++ scummvm/trunk/engines/kyra/resource.cpp	2008-02-09 16:18:44 UTC (rev 30838)
@@ -154,9 +154,41 @@
 
 	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 @@
 		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 @@
 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 @@
 	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 @@
 			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 @@
 		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 @@
 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 @@
 	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 @@
 		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;
 }

Modified: scummvm/trunk/engines/kyra/resource.h
===================================================================
--- scummvm/trunk/engines/kyra/resource.h	2008-02-09 15:46:06 UTC (rev 30837)
+++ scummvm/trunk/engines/kyra/resource.h	2008-02-09 16:18:44 UTC (rev 30838)
@@ -62,13 +62,22 @@
 
 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:


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list