/* 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 3 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, see . * */ #ifndef STARK_SERVICES_ARCHIVE_LOADER_H #define STARK_SERVICES_ARCHIVE_LOADER_H #include "common/list.h" #include "common/str.h" #include "common/substream.h" #include "common/util.h" #include "math/quat.h" #include "math/vector3d.h" #include "engines/stark/formats/xarc.h" #include "engines/stark/resources/object.h" namespace Stark { namespace Resources { class Level; class Location; } /** * A read stream with helper functions to read usual data types */ class ArchiveReadStream : public Common::SeekableSubReadStream { public: ArchiveReadStream(Common::SeekableReadStream *parentStream, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::YES); virtual ~ArchiveReadStream(); Common::String readString(); Common::String readString16(); Math::Vector3d readVector3(); Math::Quaternion readQuaternion(); float readFloat(); }; /** * XARC Archive loader. * * Maintains a list of opened archive files. * Loads the resources from the XRC tree. */ class ArchiveLoader { public: ~ArchiveLoader(); /** Load a Xarc archive, and add it to the managed archives list */ bool load(const Common::Path &archiveName); /** Unload all the unused Xarc archives */ void unloadUnused(); /** Retrieve a file from a specified archive */ ArchiveReadStream *getFile(const Common::Path &fileName, const Common::Path &archiveName); /** Get the resource tree root for an archive, and increment the archive use count */ template T *useRoot(const Common::Path &archiveName); /** Decrement the root's archive use count */ bool returnRoot(const Common::Path &archiveName); /** Build the archive filename for a level or a location */ Common::Path buildArchiveName(Resources::Level *level, Resources::Location *location = nullptr) const; /** Retrieve a file relative to a specified archive */ Common::SeekableReadStream *getExternalFile(const Common::Path &fileName, const Common::Path &archiveName) const; Common::Path getExternalFilePath(const Common::Path &fileName, const Common::Path &archiveName) const; private: class LoadedArchive { public: explicit LoadedArchive(const Common::Path &archiveName); ~LoadedArchive(); const Common::Path &getFilename() const { return _filename; } const Formats::XARCArchive &getXArc() const { return _xarc; } Resources::Object *getRoot() const { return _root; } void importResources(); bool isInUse() const { return _useCount > 0; } void incUsage() { _useCount++; } void decUsage() { _useCount = MAX(_useCount - 1, 0); } private: uint _useCount; Common::Path _filename; Formats::XARCArchive _xarc; Resources::Object *_root; }; typedef Common::List LoadedArchiveList; bool hasArchive(const Common::Path &archiveName) const; LoadedArchive *findArchive(const Common::Path &archiveName) const; LoadedArchiveList _archives; }; template T *ArchiveLoader::useRoot(const Common::Path &archiveName) { LoadedArchive *archive = findArchive(archiveName); archive->incUsage(); return Resources::Object::cast(archive->getRoot()); } } // End of namespace Stark #endif // STARK_SERVICES_ARCHIVE_LOADER_H