diff options
| -rw-r--r-- | engines/zvision/zfsArchive.cpp | 144 | ||||
| -rw-r--r-- | engines/zvision/zfsArchive.h | 96 | ||||
| -rw-r--r-- | engines/zvision/zvision.cpp | 12 | 
3 files changed, 252 insertions, 0 deletions
| diff --git a/engines/zvision/zfsArchive.cpp b/engines/zvision/zfsArchive.cpp new file mode 100644 index 0000000000..a3111d7705 --- /dev/null +++ b/engines/zvision/zfsArchive.cpp @@ -0,0 +1,144 @@ +/* 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 "zfsArchive.h" +#include "common/hashmap.h" +#include "common/memstream.h" +#include "common/debug.h" + +namespace ZVision { + +ZfsArchive::ZfsArchive(const Common::String &fileName) : _fileName(fileName) { +	Common::File zfsFile; + +	if (!zfsFile.open(_fileName)) { +		warning("ZFSArchive::ZFSArchive(): Could not find the archive file"); +		return; +	} + +	readHeaders(&zfsFile); + +	debug(0, "ArjArchive::ArjArchive(%s): Located %d files", _fileName.c_str(), _entryHeaders.size()); +} + +ZfsArchive::ZfsArchive(const Common::String &fileName, Common::SeekableReadStream *stream) : _fileName(fileName) { +	readHeaders(stream); + +	debug(0, "ArjArchive::ArjArchive(%s): Located %d files", _fileName.c_str(), _entryHeaders.size()); +} + +ZfsArchive::~ZfsArchive() { +	debug(0, "ZfsArchive Destructor Called"); +	ZfsEntryHeaderMap::iterator it = _entryHeaders.begin(); +	for ( ; it != _entryHeaders.end(); ++it) { +		delete it->_value; +	} +} + +void ZfsArchive::readHeaders(Common::SeekableReadStream *stream) { +	ZfsHeader header; + +	// Don't do a straight struct cast since we can't guarantee endianness +	header.magic = stream->readUint32LE(); +	header.unknown1 = stream->readUint32LE(); +	header.unknown2 = stream->readUint32LE(); +	header.filesPerBlock = stream->readUint32LE(); +	header.fileCount = stream->readUint32LE(); +	header.xorKey = stream->readUint32LE(); +	header.fileSectionOffset = stream->readUint32LE(); + +	uint32 nextOffset; + +	do { +		// Read the offset to the next block +		nextOffset = stream->readUint32LE(); + +		// Read in each entry header +		for (int i = 0; i < header.filesPerBlock; i++) { +			ZfsEntryHeader entryHeader; +			 +			entryHeader.name = readEntryName(stream); +			entryHeader.offset = stream->readUint32LE(); +			entryHeader.id = stream->readUint32LE(); +			entryHeader.size = stream->readUint32LE(); +			entryHeader.time = stream->readUint32LE(); +			entryHeader.unknown = stream->readUint32LE(); + +			if (entryHeader.size != 0) +				_entryHeaders[entryHeader.name] = new ZfsEntryHeader(entryHeader); +		} + +		// Seek to the next block of headers +		stream->seek(nextOffset); +	} while (nextOffset != 0); +} + +Common::String ZfsArchive::readEntryName(Common::SeekableReadStream *stream) const { +	// Entry Names are at most 16 bytes and are null padded +	char buffer[16]; +	stream->read(buffer, 16); + +	return Common::String(buffer); +} + +bool ZfsArchive::hasFile(const Common::String &name) const { +	return _entryHeaders.contains(name); +} + +int ZfsArchive::listMembers(Common::ArchiveMemberList &list) const { +	int matches = 0; + +	for (ZfsEntryHeaderMap::const_iterator it = _entryHeaders.begin(); it != _entryHeaders.end(); ++it) { +		list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(it->_value->name, this))); +		matches++; +	} + +	return matches; +} + +const Common::ArchiveMemberPtr ZfsArchive::getMember(const Common::String &name) const { +	if (!_entryHeaders.contains(name)) +		return Common::ArchiveMemberPtr(); + +	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this)); +} + +Common::SeekableReadStream *ZfsArchive::createReadStreamForMember(const Common::String &name) const { +	if (!_entryHeaders.contains(name)) { +		return 0; +	} + +	ZfsEntryHeader *entryHeader = _entryHeaders[name]; + +	Common::File zfsArchive; +	zfsArchive.open(_fileName); +	zfsArchive.seek(entryHeader->offset); + +	byte* buffer = new byte[entryHeader->size]; +	zfsArchive.read(buffer, entryHeader->size); + +	return new Common::MemoryReadStream(buffer, entryHeader->size, DisposeAfterUse::YES); +} + +} // End namespace ZVision + + diff --git a/engines/zvision/zfsArchive.h b/engines/zvision/zfsArchive.h new file mode 100644 index 0000000000..96c002f815 --- /dev/null +++ b/engines/zvision/zfsArchive.h @@ -0,0 +1,96 @@ +/* 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. + * + */ + +#ifndef ZVISION_ZFS_ARCHIVE_H +#define ZVISION_ZFS_ARCHIVE_H + +#include "common/archive.h" +#include "common/file.h" +#include "common/fs.h" + +namespace ZVision { + +struct ZfsHeader { +	uint32 magic; +	uint32 unknown1; +	uint32 unknown2; +	uint32 filesPerBlock; +	uint32 fileCount; +	uint32 xorKey; +	uint32 fileSectionOffset; +}; + +struct ZfsEntryHeader { +	Common::String name; +	uint32 offset; +	uint32 id; +	uint32 size; +	uint32 time; +	uint32 unknown; +}; + +typedef Common::HashMap<Common::String, ZfsEntryHeader*, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ZfsEntryHeaderMap; + +class ZfsArchive : public Common::Archive { +public: +	ZfsArchive(const Common::String &fileName); +	ZfsArchive(const Common::String &fileName, Common::SeekableReadStream *stream); +	~ZfsArchive(); + +	/** +	 * Check if a member with the given name is present in the Archive. +	 * Patterns are not allowed, as this is meant to be a quick File::exists() +	 * replacement. +	 */ +	bool hasFile(const Common::String &fileName) const; + +	/** +	 * Add all members of the Archive to list. +	 * Must only append to list, and not remove elements from it. +	 * +	 * @return the number of names added to list +	 */ +	int listMembers(Common::ArchiveMemberList &list) const; + +	/** +	 * Returns a ArchiveMember representation of the given file. +	 */ +	const Common::ArchiveMemberPtr getMember(const Common::String &name) const; + +	/** +	 * Create a stream bound to a member with the specified name in the +	 * archive. If no member with this name exists, 0 is returned. +	 * @return the newly created input stream +	 */ +	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; + +private: +	const Common::String _fileName; +	ZfsEntryHeaderMap _entryHeaders; + +	void readHeaders(Common::SeekableReadStream *stream); +	Common::String readEntryName(Common::SeekableReadStream *stream) const; +}; + +} // End of namespace Common + +#endif diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp index 1a72ea0e8c..b347782f59 100644 --- a/engines/zvision/zvision.cpp +++ b/engines/zvision/zvision.cpp @@ -21,6 +21,7 @@  #include "engines/util.h"
  #include "zvision/zvision.h"
 +#include "zvision/zfsArchive.h"
  #include "zvision/zork_avi_decoder.h"
  #include "zvision/zork_raw.h"
 @@ -160,6 +161,17 @@ void playVideo(Video::VideoDecoder *videoDecoder /*, VideoState videoState*/) {  }
  Common::Error ZVision::run() {
 +	// Register the files within the zfs archive files with the SearchMan
 +	Common::ArchiveMemberList list;
 +	SearchMan.listMatchingMembers(list, "*.zfs");
 +
 +	for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
 +		Common::String name = (*iter)->getName();
 +		ZfsArchive *archive = new ZfsArchive(name, (*iter)->createReadStream());
 +
 +		SearchMan.add(name, archive);
 +	}
 +
  	//Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);	// ARGB8888
  	Graphics::PixelFormat format = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);	// RGB555
  	initGraphics(640, 480, true, &format);
 | 
