diff --git a/CodeWalker.Core/GameFiles/Resources/Texture.cs b/CodeWalker.Core/GameFiles/Resources/Texture.cs index 36c558ee9..6a5c55654 100644 --- a/CodeWalker.Core/GameFiles/Resources/Texture.cs +++ b/CodeWalker.Core/GameFiles/Resources/Texture.cs @@ -712,9 +712,12 @@ public int CalcDataSize() public ushort CalculateStride() { if (Format == 0) return 0; - var dxgifmt = DDSIO.GetDXGIFormat(Format); + bool isCompressed; + var dxgifmt = DDSIO.GetDXGIFormat(Format, out isCompressed); DDSIO.DXTex.ComputePitch(dxgifmt, Width, Height, out var rowPitch, out var slicePitch, 0); - return (ushort)rowPitch; + // For compressed formats (BC/DXT): convert bytes to DWORD units (divide by 4) + // For uncompressed formats: return the original row pitch in bytes + return isCompressed ? (ushort)(rowPitch / 4) : (ushort)(rowPitch); } public TextureFormat GetLegacyFormat(TextureFormatG9 format) { @@ -938,6 +941,8 @@ public override void Read(ResourceDataReader reader, params object[] parameters) this.Unknown_88h = reader.ReadUInt32(); this.Unknown_8Ch = reader.ReadUInt32(); + // auto-calculate stride value to fix potential incorrect values in data textures + this.Stride = CalculateStride(); // read reference data this.Data = reader.ReadBlockAt(this.DataPointer, this.Format, this.Width, this.Height, this.Levels, this.Stride); diff --git a/CodeWalker.Core/GameFiles/Utils/DDSIO.cs b/CodeWalker.Core/GameFiles/Utils/DDSIO.cs index 285487e9d..60f189dd8 100644 --- a/CodeWalker.Core/GameFiles/Utils/DDSIO.cs +++ b/CodeWalker.Core/GameFiles/Utils/DDSIO.cs @@ -500,18 +500,19 @@ public static TextureFormat GetTextureFormat(DXGI_FORMAT f) return format; } - public static DXGI_FORMAT GetDXGIFormat(TextureFormat f) + public static DXGI_FORMAT GetDXGIFormat(TextureFormat f, out bool isCompressed) { var format = DXGI_FORMAT.DXGI_FORMAT_UNKNOWN; + isCompressed = false; switch (f) { // compressed - case TextureFormat.D3DFMT_DXT1: format = DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM; break; - case TextureFormat.D3DFMT_DXT3: format = DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM; break; - case TextureFormat.D3DFMT_DXT5: format = DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM; break; - case TextureFormat.D3DFMT_ATI1: format = DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM; break; - case TextureFormat.D3DFMT_ATI2: format = DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM; break; - case TextureFormat.D3DFMT_BC7: format = DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM; break; + case TextureFormat.D3DFMT_DXT1: format = DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM; isCompressed = true; break; + case TextureFormat.D3DFMT_DXT3: format = DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM; isCompressed = true; break; + case TextureFormat.D3DFMT_DXT5: format = DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM; isCompressed = true; break; + case TextureFormat.D3DFMT_ATI1: format = DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM; isCompressed = true; break; + case TextureFormat.D3DFMT_ATI2: format = DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM; isCompressed = true; break; + case TextureFormat.D3DFMT_BC7: format = DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM; isCompressed = true; break; // uncompressed case TextureFormat.D3DFMT_A1R5G5B5: format = DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM; break; @@ -524,6 +525,12 @@ public static DXGI_FORMAT GetDXGIFormat(TextureFormat f) return format; } + public static DXGI_FORMAT GetDXGIFormat(TextureFormat f) + { + bool isCompressed; + return GetDXGIFormat(f, out isCompressed); + } + private static ImageStruct GetImageStruct(Texture texture, DXGI_FORMAT format) { ImageStruct img = new ImageStruct();