mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
Load iwis of version 6 (cod4)
This commit is contained in:
parent
8fbda2d1bb
commit
05303313be
@ -8,6 +8,54 @@ struct IwiVersion
|
|||||||
char version;
|
char version;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// IW3
|
||||||
|
namespace iwi6
|
||||||
|
{
|
||||||
|
struct IwiHeader
|
||||||
|
{
|
||||||
|
int8_t format;
|
||||||
|
int8_t flags;
|
||||||
|
uint16_t dimensions[3];
|
||||||
|
uint32_t fileSizeForPicmip[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class IwiFormat
|
||||||
|
{
|
||||||
|
IMG_FORMAT_INVALID = 0x0,
|
||||||
|
IMG_FORMAT_BITMAP_RGBA = 0x1,
|
||||||
|
IMG_FORMAT_BITMAP_RGB = 0x2,
|
||||||
|
IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3,
|
||||||
|
IMG_FORMAT_BITMAP_LUMINANCE = 0x4,
|
||||||
|
IMG_FORMAT_BITMAP_ALPHA = 0x5,
|
||||||
|
IMG_FORMAT_WAVELET_RGBA = 0x6,
|
||||||
|
IMG_FORMAT_WAVELET_RGB = 0x7,
|
||||||
|
IMG_FORMAT_WAVELET_LUMINANCE_ALPHA = 0x8,
|
||||||
|
IMG_FORMAT_WAVELET_LUMINANCE = 0x9,
|
||||||
|
IMG_FORMAT_WAVELET_ALPHA = 0xA,
|
||||||
|
IMG_FORMAT_DXT1 = 0xB,
|
||||||
|
IMG_FORMAT_DXT3 = 0xC,
|
||||||
|
IMG_FORMAT_DXT5 = 0xD,
|
||||||
|
IMG_FORMAT_DXN = 0xE,
|
||||||
|
|
||||||
|
IMG_FORMAT_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum IwiFlags
|
||||||
|
{
|
||||||
|
IMG_FLAG_NOPICMIP = 1 << 0,
|
||||||
|
IMG_FLAG_NOMIPMAPS = 1 << 1,
|
||||||
|
IMG_FLAG_CUBEMAP = 1 << 2,
|
||||||
|
IMG_FLAG_VOLMAP = 1 << 3,
|
||||||
|
IMG_FLAG_STREAMING = 1 << 4,
|
||||||
|
IMG_FLAG_LEGACY_NORMALS = 1 << 5,
|
||||||
|
IMG_FLAG_CLAMP_U = 1 << 6,
|
||||||
|
IMG_FLAG_CLAMP_V = 1 << 7,
|
||||||
|
IMG_FLAG_DYNAMIC = 1 << 16,
|
||||||
|
IMG_FLAG_RENDER_TARGET = 1 << 17,
|
||||||
|
IMG_FLAG_SYSTEMMEM = 1 << 18
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// IW4
|
// IW4
|
||||||
namespace iwi8
|
namespace iwi8
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,106 @@ IwiLoader::IwiLoader(MemoryManager* memoryManager)
|
|||||||
m_memory_manager = memoryManager;
|
m_memory_manager = memoryManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ImageFormat* IwiLoader::GetFormat6(int8_t format)
|
||||||
|
{
|
||||||
|
switch (static_cast<iwi6::IwiFormat>(format))
|
||||||
|
{
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_BITMAP_RGBA:
|
||||||
|
return &ImageFormat::FORMAT_R8_G8_B8_A8;
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_BITMAP_RGB:
|
||||||
|
return &ImageFormat::FORMAT_R8_G8_B8;
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_BITMAP_ALPHA:
|
||||||
|
return &ImageFormat::FORMAT_A8;
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_DXT1:
|
||||||
|
return &ImageFormat::FORMAT_BC1;
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_DXT3:
|
||||||
|
return &ImageFormat::FORMAT_BC2;
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_DXT5:
|
||||||
|
return &ImageFormat::FORMAT_BC3;
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_DXN:
|
||||||
|
return &ImageFormat::FORMAT_BC5;
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE_ALPHA:
|
||||||
|
return &ImageFormat::FORMAT_R8_A8;
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE:
|
||||||
|
return &ImageFormat::FORMAT_R8;
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_WAVELET_RGBA: // used
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_WAVELET_RGB: // used
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_WAVELET_LUMINANCE_ALPHA:
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_WAVELET_LUMINANCE:
|
||||||
|
case iwi6::IwiFormat::IMG_FORMAT_WAVELET_ALPHA:
|
||||||
|
printf("Unsupported IWI format: %i\n", format);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unknown IWI format: %i\n", format);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture* IwiLoader::LoadIwi6(std::istream& stream) const
|
||||||
|
{
|
||||||
|
iwi6::IwiHeader header{};
|
||||||
|
|
||||||
|
stream.read(reinterpret_cast<char*>(&header), sizeof(header));
|
||||||
|
if (stream.gcount() != sizeof(header))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const auto* format = GetFormat6(header.format);
|
||||||
|
if (format == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto width = header.dimensions[0];
|
||||||
|
auto height = header.dimensions[1];
|
||||||
|
auto depth = header.dimensions[2];
|
||||||
|
auto hasMipMaps = !(header.flags & iwi6::IwiFlags::IMG_FLAG_NOMIPMAPS);
|
||||||
|
|
||||||
|
Texture* texture;
|
||||||
|
if (header.flags & iwi6::IwiFlags::IMG_FLAG_CUBEMAP)
|
||||||
|
{
|
||||||
|
texture = m_memory_manager->Create<TextureCube>(format, width, height, hasMipMaps);
|
||||||
|
}
|
||||||
|
else if (header.flags & iwi6::IwiFlags::IMG_FLAG_VOLMAP)
|
||||||
|
{
|
||||||
|
texture = m_memory_manager->Create<Texture3D>(format, width, height, depth, hasMipMaps);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
texture = m_memory_manager->Create<Texture2D>(format, width, height, hasMipMaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->Allocate();
|
||||||
|
|
||||||
|
auto currentFileSize = sizeof(iwi6::IwiHeader) + sizeof(IwiVersion);
|
||||||
|
const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1;
|
||||||
|
|
||||||
|
for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
||||||
|
{
|
||||||
|
const auto sizeOfMipLevel = texture->GetSizeOfMipLevel(currentMipLevel) * texture->GetFaceCount();
|
||||||
|
currentFileSize += sizeOfMipLevel;
|
||||||
|
|
||||||
|
if (currentMipLevel < static_cast<int>(std::extent<decltype(iwi6::IwiHeader::fileSizeForPicmip)>::value)
|
||||||
|
&& currentFileSize != header.fileSizeForPicmip[currentMipLevel])
|
||||||
|
{
|
||||||
|
printf("Iwi has invalid file size for picmip %i\n", currentMipLevel);
|
||||||
|
|
||||||
|
m_memory_manager->Delete(texture);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.read(reinterpret_cast<char*>(texture->GetBufferForMipLevel(currentMipLevel)), sizeOfMipLevel);
|
||||||
|
if (stream.gcount() != sizeOfMipLevel)
|
||||||
|
{
|
||||||
|
printf("Unexpected eof of iwi in mip level %i\n", currentMipLevel);
|
||||||
|
|
||||||
|
m_memory_manager->Delete(texture);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
const ImageFormat* IwiLoader::GetFormat8(int8_t format)
|
const ImageFormat* IwiLoader::GetFormat8(int8_t format)
|
||||||
{
|
{
|
||||||
switch (static_cast<iwi8::IwiFormat>(format))
|
switch (static_cast<iwi8::IwiFormat>(format))
|
||||||
@ -252,6 +352,9 @@ Texture* IwiLoader::LoadIwi(std::istream& stream)
|
|||||||
|
|
||||||
switch (iwiVersion.version)
|
switch (iwiVersion.version)
|
||||||
{
|
{
|
||||||
|
case 6:
|
||||||
|
return LoadIwi6(stream);
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
return LoadIwi8(stream);
|
return LoadIwi8(stream);
|
||||||
|
|
||||||
|
@ -8,6 +8,9 @@ class IwiLoader
|
|||||||
{
|
{
|
||||||
MemoryManager* m_memory_manager;
|
MemoryManager* m_memory_manager;
|
||||||
|
|
||||||
|
static const ImageFormat* GetFormat6(int8_t format);
|
||||||
|
Texture* LoadIwi6(std::istream& stream) const;
|
||||||
|
|
||||||
static const ImageFormat* GetFormat8(int8_t format);
|
static const ImageFormat* GetFormat8(int8_t format);
|
||||||
Texture* LoadIwi8(std::istream& stream) const;
|
Texture* LoadIwi8(std::istream& stream) const;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user