1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
/// Main header for reading .nif files
#ifndef OPENMW_COMPONENTS_NIF_NIFFILE_HPP
#define OPENMW_COMPONENTS_NIF_NIFFILE_HPP
#include <atomic>
#include <cstdint>
#include <vector>
#include <components/files/istreamptr.hpp>
#include <components/vfs/pathutil.hpp>
#include "record.hpp"
namespace ToUTF8
{
class StatelessUtf8Encoder;
}
namespace Nif
{
struct NIFFile
{
// For generic versions NIFStream::generateVersion() is used instead
enum NIFVersion
{
VER_MW = 0x04000002, // 4.0.0.2. Main Morrowind NIF version.
VER_OB_OLD = 0x0A000102, // 10.0.1.2. Main older Oblivion NIF version.
VER_OB = 0x14000005, // 20.0.0.5. Main Oblivion NIF version.
VER_BGS = 0x14020007 // 20.2.0.7. Main Fallout 3/4/76/New Vegas and Skyrim/SkyrimSE NIF version.
};
enum BethVersion
{
BETHVER_FO3 = 34, // Fallout 3
BETHVER_SKY = 83, // Skyrim
BETHVER_SSE = 100, // Skyrim SE
BETHVER_FO4 = 130, // Fallout 4
BETHVER_F76 = 155, // Fallout 76
BETHVER_STF = 172, // Starfield
};
/// File version, user version, Bethesda version
std::uint32_t mVersion = 0;
std::uint32_t mUserVersion = 0;
std::uint32_t mBethVersion = 0;
/// File name, used for error messages and opening the file
VFS::Path::Normalized mPath;
std::string mHash;
/// Record list
std::vector<std::unique_ptr<Record>> mRecords;
/// Root list. This is a select portion of the pointers from records
std::vector<Record*> mRoots;
bool mUseSkinning = false;
explicit NIFFile(VFS::Path::NormalizedView path)
: mPath(path)
{
}
};
class FileView
{
public:
FileView(const NIFFile& file)
: mFile(&file)
{
}
/// Get a given root
const Record* getRoot(std::size_t index) const { return mFile->mRoots.at(index); }
/// Number of roots
std::size_t numRoots() const { return mFile->mRoots.size(); }
/// Get the name of the file
const std::string& getFilename() const { return mFile->mPath; }
const std::string& getHash() const { return mFile->mHash; }
/// Get the version of the NIF format used
std::uint32_t getVersion() const { return mFile->mVersion; }
/// Get the user version of the NIF format used
std::uint32_t getUserVersion() const { return mFile->mUserVersion; }
/// Get the Bethesda version of the NIF format used
std::uint32_t getBethVersion() const { return mFile->mBethVersion; }
bool getUseSkinning() const { return mFile->mUseSkinning; }
private:
const NIFFile* mFile;
};
class Reader
{
/// File version, user version, Bethesda version
std::uint32_t& mVersion;
std::uint32_t& mUserVersion;
std::uint32_t& mBethVersion;
/// File name, used for error messages and opening the file
std::string_view mFilename;
std::string& mHash;
/// Record list
std::vector<std::unique_ptr<Record>>& mRecords;
/// Root list. This is a select portion of the pointers from records
std::vector<Record*>& mRoots;
/// String table
std::vector<std::string> mStrings;
bool& mUseSkinning;
const ToUTF8::StatelessUtf8Encoder* mEncoder;
static std::atomic_bool sLoadUnsupportedFiles;
static std::atomic_bool sWriteNifDebugLog;
/// Get the file's version in a human readable form
///\returns A string containing a human readable NIF version number
std::string versionToString(std::uint32_t version);
public:
/// Open a NIF stream. The name is used for error messages.
explicit Reader(NIFFile& file, const ToUTF8::StatelessUtf8Encoder* encoder);
/// Parse the file
void parse(Files::IStreamPtr&& stream);
/// Get a given record
Record* getRecord(size_t index) const { return mRecords.at(index).get(); }
/// Get a given string from the file's string table
std::string getString(std::uint32_t index) const;
/// Set whether there is skinning contained in this NIF file.
/// @note This is just a hint for users of the NIF file and has no effect on the loading procedure.
void setUseSkinning(bool skinning);
/// Get the name of the file
std::string_view getFilename() const { return mFilename; }
/// Get the version of the NIF format used
std::uint32_t getVersion() const { return mVersion; }
/// Get the user version of the NIF format used
std::uint32_t getUserVersion() const { return mUserVersion; }
/// Get the Bethesda version of the NIF format used
std::uint32_t getBethVersion() const { return mBethVersion; }
static void setLoadUnsupportedFiles(bool load);
static void setWriteNifDebugLog(bool load);
};
using NIFFilePtr = std::shared_ptr<const Nif::NIFFile>;
} // Namespace
#endif
|