diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 5642dfebb..098f6aba2 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -1,9 +1,12 @@ #include "niffile.hpp" #include "effect.hpp" +#include #include #include +#include + namespace Nif { @@ -137,15 +140,46 @@ void NIFFile::parse(Files::IStreamPtr stream) // Check the header string std::string head = nif.getVersionString(); - if(head.compare(0, 22, "NetImmerse File Format") != 0) + static const std::array verStrings = + { + "NetImmerse File Format", + "Gamebryo File Format" + }; + bool supported = false; + for (const std::string& verString : verStrings) + { + supported = (head.compare(0, verString.size(), verString) == 0); + if (supported) + break; + } + if (!supported) fail("Invalid NIF header: " + head); + supported = false; + // Get BCD version ver = nif.getUInt(); // 4.0.0.0 is an older, practically identical version of the format. // It's not used by Morrowind assets but Morrowind supports it. - if(ver != NIFStream::generateVersion(4,0,0,0) && ver != VER_MW) - fail("Unsupported NIF version: " + printVersion(ver)); + static const std::array supportedVers = + { + NIFStream::generateVersion(4,0,0,0), + VER_MW + }; + for (uint32_t supportedVer : supportedVers) + { + supported = (ver == supportedVer); + if (supported) + break; + } + if (!supported) + { + static const bool ignoreUnsupported = Settings::Manager::getBool("load unsupported nif files", "Models"); + if (ignoreUnsupported) + warn("Unsupported NIF version: " + printVersion(ver) + ". Proceed with caution!"); + else + fail("Unsupported NIF version: " + printVersion(ver)); + } // NIF data endianness if (ver >= NIFStream::generateVersion(20,0,0,4)) @@ -245,6 +279,9 @@ void NIFFile::parse(Files::IStreamPtr stream) else fail("Unknown record type " + rec); + if (!supported) + Log(Debug::Verbose) << "NIF Debug: Reading record of type " << rec << ", index " << i << " (" << filename << ")"; + assert(r != nullptr); assert(r->recType != RC_MISSING); r->recName = rec; diff --git a/docs/source/reference/modding/settings/index.rst b/docs/source/reference/modding/settings/index.rst index 2261fe8e1..586a99dbb 100644 --- a/docs/source/reference/modding/settings/index.rst +++ b/docs/source/reference/modding/settings/index.rst @@ -58,3 +58,4 @@ The ranges included with each setting are the physically possible ranges, not re windows navigator physics + models diff --git a/docs/source/reference/modding/settings/models.rst b/docs/source/reference/modding/settings/models.rst new file mode 100644 index 000000000..da56a1709 --- /dev/null +++ b/docs/source/reference/modding/settings/models.rst @@ -0,0 +1,27 @@ +Models Settings +############### + +load unsupported nif files +-------------------------- + +:Type: boolean +:Range: True/False +:Default: False + +At the moment OpenMW's NIF loader is only tailored to load models +that can also load in Morrowind. + +However, you can enable its limited and experimental support for updates in +the definitions of record types from later NIF revisions by toggling on +this setting. + +You must keep in mind that loading unsupported NIF files may fail, +and the degree of this failure may vary. In milder cases, OpenMW will reject +the file anyway because it lacks a definition for a certain record type +that the file may use. In more severe cases OpenMW's +incomplete understanding of a record type can lead to memory corruption, +crashes or even freezes. Don't enable this if you're not sure that +you know what you're doing. + +To help debug possible issues OpenMW will log its progress in loading +every file that uses an unsupported NIF version. diff --git a/files/settings-default.cfg b/files/settings-default.cfg index b9fb2fbf7..0b307ba09 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -945,3 +945,8 @@ lineofsight keep inactive cache = 0 # Defer bounding boxes update until collision detection. defer aabb update = true + +[Models] +# Attempt to load any valid NIF file regardless of its version and track the progress. +# Loading arbitrary meshes is not advised and may cause instability. +load unsupported nif files = false