mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:29:55 +00:00
Use the right archive type to load bsa according to their type
This commit is contained in:
parent
974799c011
commit
d30deef4b5
4 changed files with 91 additions and 161 deletions
|
@ -48,12 +48,14 @@ std::unique_ptr<VFS::Archive> makeBsaArchive(const std::filesystem::path& path)
|
|||
case Bsa::BSAVER_UNKNOWN:
|
||||
std::cerr << '"' << path << "\" is unknown BSA archive" << std::endl;
|
||||
return nullptr;
|
||||
case Bsa::BSAVER_UNCOMPRESSED:
|
||||
return std::make_unique<VFS::BsaArchive>(path);
|
||||
case Bsa::BSAVER_COMPRESSED:
|
||||
return std::make_unique<VFS::ArchiveSelector<Bsa::BSAVER_COMPRESSED>::type>(path);
|
||||
case Bsa::BSAVER_BA2_GNRL:
|
||||
return std::make_unique<VFS::ArchiveSelector<Bsa::BSAVER_BA2_GNRL>::type>(path);
|
||||
case Bsa::BSAVER_BA2_DX10:
|
||||
return std::make_unique<VFS::CompressedBsaArchive>(path);
|
||||
return std::make_unique<VFS::ArchiveSelector<Bsa::BSAVER_BA2_DX10>::type>(path);
|
||||
case Bsa::BSAVER_UNCOMPRESSED:
|
||||
return std::make_unique<VFS::ArchiveSelector<Bsa::BSAVER_UNCOMPRESSED>::type>(path);
|
||||
}
|
||||
|
||||
std::cerr << '"' << path << "\" is unsupported BSA archive" << std::endl;
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
#include "bsaarchive.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
namespace VFS
|
||||
{
|
||||
|
||||
BsaArchive::BsaArchive(const std::filesystem::path& filename)
|
||||
{
|
||||
mFile = std::make_unique<Bsa::BSAFile>();
|
||||
mFile->open(filename);
|
||||
|
||||
const Bsa::BSAFile::FileList& filelist = mFile->getList();
|
||||
for (Bsa::BSAFile::FileList::const_iterator it = filelist.begin(); it != filelist.end(); ++it)
|
||||
{
|
||||
mResources.emplace_back(&*it, mFile.get());
|
||||
}
|
||||
}
|
||||
|
||||
BsaArchive::BsaArchive() {}
|
||||
|
||||
BsaArchive::~BsaArchive() {}
|
||||
|
||||
void BsaArchive::listResources(std::map<std::string, File*>& out, char (*normalize_function)(char))
|
||||
{
|
||||
for (std::vector<BsaArchiveFile>::iterator it = mResources.begin(); it != mResources.end(); ++it)
|
||||
{
|
||||
std::string ent = it->mInfo->name();
|
||||
std::transform(ent.begin(), ent.end(), ent.begin(), normalize_function);
|
||||
|
||||
out[ent] = &*it;
|
||||
}
|
||||
}
|
||||
|
||||
bool BsaArchive::contains(const std::string& file, char (*normalize_function)(char)) const
|
||||
{
|
||||
for (const auto& it : mResources)
|
||||
{
|
||||
std::string ent = it.mInfo->name();
|
||||
std::transform(ent.begin(), ent.end(), ent.begin(), normalize_function);
|
||||
if (file == ent)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string BsaArchive::getDescription() const
|
||||
{
|
||||
return std::string{ "BSA: " } + mFile->getFilename();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
BsaArchiveFile::BsaArchiveFile(const Bsa::BSAFile::FileStruct* info, Bsa::BSAFile* bsa)
|
||||
: mInfo(info)
|
||||
, mFile(bsa)
|
||||
{
|
||||
}
|
||||
|
||||
Files::IStreamPtr BsaArchiveFile::open()
|
||||
{
|
||||
return mFile->getFile(mInfo);
|
||||
}
|
||||
|
||||
CompressedBsaArchive::CompressedBsaArchive(const std::filesystem::path& filename)
|
||||
: Archive()
|
||||
{
|
||||
mCompressedFile = std::make_unique<Bsa::CompressedBSAFile>();
|
||||
mCompressedFile->open(filename);
|
||||
|
||||
const Bsa::BSAFile::FileList& filelist = mCompressedFile->getList();
|
||||
for (Bsa::BSAFile::FileList::const_iterator it = filelist.begin(); it != filelist.end(); ++it)
|
||||
{
|
||||
mCompressedResources.emplace_back(&*it, mCompressedFile.get());
|
||||
}
|
||||
}
|
||||
|
||||
void CompressedBsaArchive::listResources(std::map<std::string, File*>& out, char (*normalize_function)(char))
|
||||
{
|
||||
for (std::vector<CompressedBsaArchiveFile>::iterator it = mCompressedResources.begin();
|
||||
it != mCompressedResources.end(); ++it)
|
||||
{
|
||||
std::string ent = it->mInfo->name();
|
||||
std::transform(ent.begin(), ent.end(), ent.begin(), normalize_function);
|
||||
|
||||
out[ent] = &*it;
|
||||
}
|
||||
}
|
||||
|
||||
bool CompressedBsaArchive::contains(const std::string& file, char (*normalize_function)(char)) const
|
||||
{
|
||||
for (const auto& it : mCompressedResources)
|
||||
{
|
||||
std::string ent = it.mInfo->name();
|
||||
std::transform(ent.begin(), ent.end(), ent.begin(), normalize_function);
|
||||
if (file == ent)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string CompressedBsaArchive::getDescription() const
|
||||
{
|
||||
return std::string{ "BSA: " } + mCompressedFile->getFilename();
|
||||
}
|
||||
|
||||
CompressedBsaArchiveFile::CompressedBsaArchiveFile(
|
||||
const Bsa::BSAFile::FileStruct* info, Bsa::CompressedBSAFile* bsa)
|
||||
: mInfo(info)
|
||||
, mCompressedFile(bsa)
|
||||
{
|
||||
}
|
||||
|
||||
Files::IStreamPtr CompressedBsaArchiveFile::open()
|
||||
{
|
||||
return mCompressedFile->getFile(mInfo);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,66 +3,108 @@
|
|||
|
||||
#include "archive.hpp"
|
||||
|
||||
#include <components/bsa/ba2dx10file.hpp>
|
||||
#include <components/bsa/ba2gnrlfile.hpp>
|
||||
#include <components/bsa/bsa_file.hpp>
|
||||
#include <components/bsa/compressedbsafile.hpp>
|
||||
|
||||
namespace VFS
|
||||
{
|
||||
template <typename FileType>
|
||||
class BsaArchiveFile : public File
|
||||
{
|
||||
public:
|
||||
BsaArchiveFile(const Bsa::BSAFile::FileStruct* info, Bsa::BSAFile* bsa);
|
||||
|
||||
Files::IStreamPtr open() override;
|
||||
|
||||
std::filesystem::path getPath() override { return mInfo->name(); }
|
||||
|
||||
const Bsa::BSAFile::FileStruct* mInfo;
|
||||
Bsa::BSAFile* mFile;
|
||||
};
|
||||
|
||||
class CompressedBsaArchiveFile : public File
|
||||
BsaArchiveFile(const Bsa::BSAFile::FileStruct* info, FileType* bsa)
|
||||
: mInfo(info)
|
||||
, mFile(bsa)
|
||||
{
|
||||
public:
|
||||
CompressedBsaArchiveFile(const Bsa::BSAFile::FileStruct* info, Bsa::CompressedBSAFile* bsa);
|
||||
}
|
||||
|
||||
Files::IStreamPtr open() override;
|
||||
Files::IStreamPtr open() override { return mFile->getFile(mInfo); }
|
||||
|
||||
std::filesystem::path getPath() override { return mInfo->name(); }
|
||||
|
||||
const Bsa::BSAFile::FileStruct* mInfo;
|
||||
Bsa::CompressedBSAFile* mCompressedFile;
|
||||
FileType* mFile;
|
||||
};
|
||||
|
||||
template <typename BSAFileType>
|
||||
class BsaArchive : public Archive
|
||||
{
|
||||
public:
|
||||
BsaArchive(const std::filesystem::path& filename);
|
||||
BsaArchive();
|
||||
virtual ~BsaArchive();
|
||||
void listResources(std::map<std::string, File*>& out, char (*normalize_function)(char)) override;
|
||||
bool contains(const std::string& file, char (*normalize_function)(char)) const override;
|
||||
std::string getDescription() const override;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Bsa::BSAFile> mFile;
|
||||
std::vector<BsaArchiveFile> mResources;
|
||||
};
|
||||
|
||||
class CompressedBsaArchive : public Archive
|
||||
BsaArchive(const std::filesystem::path& filename)
|
||||
: Archive()
|
||||
{
|
||||
public:
|
||||
CompressedBsaArchive(const std::filesystem::path& filename);
|
||||
virtual ~CompressedBsaArchive() {}
|
||||
void listResources(std::map<std::string, File*>& out, char (*normalize_function)(char)) override;
|
||||
bool contains(const std::string& file, char (*normalize_function)(char)) const override;
|
||||
std::string getDescription() const override;
|
||||
mFile = std::make_unique<BSAFileType>();
|
||||
mFile->open(filename);
|
||||
|
||||
const Bsa::BSAFile::FileList& filelist = mFile->getList();
|
||||
for (Bsa::BSAFile::FileList::const_iterator it = filelist.begin(); it != filelist.end(); ++it)
|
||||
{
|
||||
mResources.emplace_back(&*it, mFile.get());
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~BsaArchive() {}
|
||||
|
||||
void listResources(std::map<std::string, File*>& out, char (*normalize_function)(char)) override
|
||||
{
|
||||
for (auto& resource : mResources)
|
||||
{
|
||||
std::string ent = resource.mInfo->name();
|
||||
std::transform(ent.begin(), ent.end(), ent.begin(), normalize_function);
|
||||
|
||||
out[ent] = &resource;
|
||||
}
|
||||
}
|
||||
|
||||
bool contains(const std::string& file, char (*normalize_function)(char)) const override
|
||||
{
|
||||
for (const auto& it : mResources)
|
||||
{
|
||||
std::string ent = it.mInfo->name();
|
||||
std::transform(ent.begin(), ent.end(), ent.begin(), normalize_function);
|
||||
if (file == ent)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string getDescription() const override { return std::string{ "BSA: " } + mFile->getFilename(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<Bsa::CompressedBSAFile> mCompressedFile;
|
||||
std::vector<CompressedBsaArchiveFile> mCompressedResources;
|
||||
std::unique_ptr<BSAFileType> mFile;
|
||||
std::vector<BsaArchiveFile<BSAFileType>> mResources;
|
||||
};
|
||||
|
||||
template <Bsa::BsaVersion>
|
||||
struct ArchiveSelector
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ArchiveSelector<Bsa::BSAVER_UNCOMPRESSED>
|
||||
{
|
||||
using type = BsaArchive<Bsa::BSAFile>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ArchiveSelector<Bsa::BSAVER_COMPRESSED>
|
||||
{
|
||||
using type = BsaArchive<Bsa::CompressedBSAFile>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ArchiveSelector<Bsa::BSAVER_BA2_GNRL>
|
||||
{
|
||||
using type = BsaArchive<Bsa::BA2GNRLFile>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ArchiveSelector<Bsa::BSAVER_BA2_DX10>
|
||||
{
|
||||
using type = BsaArchive<Bsa::BA2DX10File>;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -28,9 +28,15 @@ namespace VFS
|
|||
Bsa::BsaVersion bsaVersion = Bsa::BSAFile::detectVersion(archivePath);
|
||||
|
||||
if (bsaVersion == Bsa::BSAVER_COMPRESSED)
|
||||
vfs->addArchive(std::make_unique<CompressedBsaArchive>(archivePath));
|
||||
vfs->addArchive(std::make_unique<ArchiveSelector<Bsa::BSAVER_COMPRESSED>::type>(archivePath));
|
||||
else if (bsaVersion == Bsa::BSAVER_BA2_GNRL)
|
||||
vfs->addArchive(std::make_unique<ArchiveSelector<Bsa::BSAVER_BA2_GNRL>::type>(archivePath));
|
||||
else if (bsaVersion == Bsa::BSAVER_BA2_DX10)
|
||||
vfs->addArchive(std::make_unique<ArchiveSelector<Bsa::BSAVER_BA2_DX10>::type>(archivePath));
|
||||
else if (bsaVersion == Bsa::BSAVER_UNCOMPRESSED)
|
||||
vfs->addArchive(std::make_unique<ArchiveSelector<Bsa::BSAVER_UNCOMPRESSED>::type>(archivePath));
|
||||
else
|
||||
vfs->addArchive(std::make_unique<BsaArchive>(archivePath));
|
||||
throw std::runtime_error("Unknown archive type '" + *archive + "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue