1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-22 12:39:59 +00:00

Merge branch 'ba2' into 'master'

BA2 support fixes

See merge request OpenMW/openmw!4055
This commit is contained in:
psi29a 2024-04-28 07:40:40 +00:00
commit e4fd852df6
4 changed files with 52 additions and 27 deletions

View File

@ -113,19 +113,29 @@ namespace Bsa
input.read(reinterpret_cast<char*>(header), 16); input.read(reinterpret_cast<char*>(header), 16);
input.read(reinterpret_cast<char*>(&fileTableOffset), 8); input.read(reinterpret_cast<char*>(&fileTableOffset), 8);
if (header[0] == 0x00415342) /*"BSA\x00"*/ if (header[0] != ESM::fourCC("BTDX"))
fail("Unrecognized compressed BSA format"); fail("Unrecognized BA2 signature");
mVersion = header[1]; mVersion = header[1];
if (mVersion != 0x01 /*FO4*/ && mVersion != 0x02 /*Starfield*/) switch (static_cast<BA2Version>(mVersion))
fail("Unrecognized compressed BSA version"); {
case BA2Version::Fallout4:
case BA2Version::Fallout4NextGen_v7:
case BA2Version::Fallout4NextGen_v8:
break;
case BA2Version::StarfieldDDS:
uint64_t dummy;
input.read(reinterpret_cast<char*>(&dummy), 8);
uint32_t compressionMethod;
input.read(reinterpret_cast<char*>(&compressionMethod), 4);
if (compressionMethod == 3)
fail("Unsupported LZ4-compressed DDS BA2");
break;
default:
fail("Unrecognized DDS BA2 version");
}
type = header[2]; type = header[2];
fileCount = header[3]; fileCount = header[3];
if (mVersion == 0x02)
{
uint64_t dummy;
input.read(reinterpret_cast<char*>(&dummy), 8);
}
} }
if (type == ESM::fourCC("DX10")) if (type == ESM::fourCC("DX10"))

View File

@ -8,6 +8,15 @@ namespace Bsa
{ {
uint32_t generateHash(const std::string& name); uint32_t generateHash(const std::string& name);
uint32_t generateExtensionHash(std::string_view extension); uint32_t generateExtensionHash(std::string_view extension);
enum class BA2Version : std::uint32_t
{
Fallout4 = 1,
StarfieldGeneral = 2,
StarfieldDDS = 3,
Fallout4NextGen_v7 = 7,
Fallout4NextGen_v8 = 8,
};
} }
#endif #endif

View File

@ -107,19 +107,25 @@ namespace Bsa
input.read(reinterpret_cast<char*>(header), 16); input.read(reinterpret_cast<char*>(header), 16);
input.read(reinterpret_cast<char*>(&fileTableOffset), 8); input.read(reinterpret_cast<char*>(&fileTableOffset), 8);
if (header[0] == 0x00415342) /*"BSA\x00"*/ if (header[0] != ESM::fourCC("BTDX"))
fail("Unrecognized compressed BSA format"); fail("Unrecognized BA2 signature");
mVersion = header[1]; mVersion = header[1];
if (mVersion != 0x01 /*FO4*/ && mVersion != 0x02 /*Starfield*/) switch (static_cast<BA2Version>(mVersion))
fail("Unrecognized compressed BSA version"); {
case BA2Version::Fallout4:
case BA2Version::Fallout4NextGen_v7:
case BA2Version::Fallout4NextGen_v8:
break;
case BA2Version::StarfieldGeneral:
uint64_t dummy;
input.read(reinterpret_cast<char*>(&dummy), 8);
break;
default:
fail("Unrecognized general BA2 version");
}
type = header[2]; type = header[2];
fileCount = header[3]; fileCount = header[3];
if (mVersion == 0x02)
{
uint64_t dummy;
input.read(reinterpret_cast<char*>(&dummy), 8);
}
} }
if (type == ESM::fourCC("GNRL")) if (type == ESM::fourCC("GNRL"))

View File

@ -340,17 +340,17 @@ BsaVersion Bsa::BSAFile::detectVersion(const std::filesystem::path& filePath)
return BsaVersion::Uncompressed; return BsaVersion::Uncompressed;
} }
if (head[0] == static_cast<uint32_t>(BsaVersion::Compressed) || head[0] == ESM::fourCC("BTDX")) if (head[0] == static_cast<uint32_t>(BsaVersion::Compressed))
{ {
if (head[1] == static_cast<uint32_t>(0x01)) return BsaVersion::Compressed;
}
if (head[0] == ESM::fourCC("BTDX"))
{ {
if (head[2] == ESM::fourCC("GNRL")) if (head[2] == ESM::fourCC("GNRL"))
return BsaVersion::BA2GNRL; return BsaVersion::BA2GNRL;
if (head[2] == ESM::fourCC("DX10")) if (head[2] == ESM::fourCC("DX10"))
return BsaVersion::BA2DX10; return BsaVersion::BA2DX10;
return BsaVersion::Unknown;
}
return BsaVersion::Compressed;
} }
return BsaVersion::Unknown; return BsaVersion::Unknown;