Skip to content

Commit 10fe130

Browse files
committed
- Colorset Editor now with 3D Visual and tile data.
1 parent ccb4e5f commit 10fe130

File tree

4 files changed

+221
-11
lines changed

4 files changed

+221
-11
lines changed

xivModdingFramework/SqPack/FileTypes/Dat.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,8 @@ await Task.Run(async () =>
10521052
var headerLength = br.ReadInt32();
10531053
var fileType = br.ReadInt32();
10541054
var uncompressedFileSize = br.ReadInt32();
1055-
br.ReadBytes(8);
1055+
var ikd1 = br.ReadInt32();
1056+
var ikd2 = br.ReadInt32();
10561057
xivTex.MipMapCount = br.ReadInt32();
10571058

10581059
var endOfHeader = offset + headerLength;
@@ -1063,6 +1064,9 @@ await Task.Run(async () =>
10631064
xivTex.TextureFormat = TextureTypeDictionary[br.ReadInt32()];
10641065
xivTex.Width = br.ReadInt16();
10651066
xivTex.Height = br.ReadInt16();
1067+
var pos = br.BaseStream.Position;
1068+
xivTex.Layers = br.ReadInt16();
1069+
var imageCount2 = br.ReadInt16();
10661070

10671071
for (int i = 0, j = 0; i < xivTex.MipMapCount; i++)
10681072
{

xivModdingFramework/Textures/DataContainers/XivTex.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ public class XivTex
3838
/// </summary>
3939
public int Height { get; set; }
4040

41+
/// <summary>
42+
/// Number of layers in the in the texture file.
43+
/// </summary>
44+
public int Layers { get; set; }
45+
4146
/// <summary>
4247
/// The amount of mipmaps the texture contains
4348
/// </summary>

xivModdingFramework/Textures/FileTypes/DDS.cs

Lines changed: 192 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,37 @@ public static void MakeDDS(XivTex xivTex, string savePath)
5454
case XivTexType.Icon:
5555
default:
5656
DDS.AddRange(CreateDDSHeader(xivTex));
57-
DDS.AddRange(xivTex.TexData);
57+
58+
var data = xivTex.TexData;
59+
if (xivTex.TextureFormat == XivTexFormat.A8R8G8B8 && xivTex.Layers > 1)
60+
{
61+
data = ShiftLayers(data);
62+
}
63+
DDS.AddRange(data);
5864
break;
5965
}
6066

6167
File.WriteAllBytes(savePath, DDS.ToArray());
6268
}
6369

70+
// This is a simple shift of the layers around in order to convert ARGB to RGBA
71+
private static byte[] ShiftLayers(byte[] data)
72+
{
73+
for(int i = 0; i < data.Length; i += 4)
74+
{
75+
var alpha = data[i];
76+
var red = data[i + 1];
77+
var green = data[i + 2];
78+
var blue = data[i + 3];
79+
80+
data[i] = red;
81+
data[i + 1] = green;
82+
data[i + 2] = blue;
83+
data[i + 3] = alpha;
84+
}
85+
return data;
86+
}
87+
6488
/// <summary>
6589
/// Creates the DDS header for given texture data.
6690
/// <see cref="https://msdn.microsoft.com/en-us/library/windows/desktop/bb943982(v=vs.85).aspx"/>
@@ -80,7 +104,11 @@ private static byte[] CreateDDSHeader(XivTex xivTex)
80104
header.AddRange(BitConverter.GetBytes(dwSize));
81105

82106
// Flags to indicate which members contain valid data.
83-
const uint dwFlags = 528391;
107+
uint dwFlags = 528391;
108+
if(xivTex.Layers > 1)
109+
{
110+
dwFlags = 0x00000004;
111+
}
84112
header.AddRange(BitConverter.GetBytes(dwFlags));
85113

86114
// Surface height (in pixels).
@@ -175,6 +203,13 @@ private static byte[] CreateDDSHeader(XivTex xivTex)
175203
default:
176204
return null;
177205
}
206+
207+
if(xivTex.Layers > 1)
208+
{
209+
var bytes = System.Text.Encoding.UTF8.GetBytes("DX10");
210+
dwFourCC = BitConverter.ToUInt32(bytes, 0);
211+
}
212+
178213
header.AddRange(BitConverter.GetBytes(dwFourCC));
179214

180215
switch (xivTex.TextureFormat)
@@ -326,6 +361,35 @@ private static byte[] CreateDDSHeader(XivTex xivTex)
326361
}
327362
}
328363

364+
// Need to write DX10 header here.
365+
if(xivTex.Layers > 1)
366+
{
367+
// DXGI_FORMAT dxgiFormat
368+
uint dxgiFormat = 0;
369+
if (xivTex.TextureFormat == XivTexFormat.DXT1) {
370+
dxgiFormat = (uint)DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM;
371+
} else if (xivTex.TextureFormat == XivTexFormat.DXT5)
372+
{
373+
dxgiFormat = (uint)DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM;
374+
} else {
375+
dxgiFormat = (uint)DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM;
376+
}
377+
header.AddRange(BitConverter.GetBytes(dxgiFormat));
378+
379+
// D3D10_RESOURCE_DIMENSION resourceDimension
380+
header.AddRange(BitConverter.GetBytes((int)3));
381+
382+
383+
// UINT miscFlag
384+
header.AddRange(BitConverter.GetBytes((int)0));
385+
386+
// UINT arraySize
387+
header.AddRange(BitConverter.GetBytes(xivTex.Layers));
388+
389+
// UINT miscFlags2
390+
header.AddRange(BitConverter.GetBytes((int)0));
391+
}
392+
329393
return header.ToArray();
330394
}
331395

@@ -542,5 +606,131 @@ private static byte[] CreateColorDDSHeader()
542606

543607
return (compressedDDS, mipPartOffsets, mipPartCount);
544608
}
609+
610+
public enum DXGI_FORMAT : uint
611+
{
612+
DXGI_FORMAT_UNKNOWN,
613+
DXGI_FORMAT_R32G32B32A32_TYPELESS,
614+
DXGI_FORMAT_R32G32B32A32_FLOAT,
615+
DXGI_FORMAT_R32G32B32A32_UINT,
616+
DXGI_FORMAT_R32G32B32A32_SINT,
617+
DXGI_FORMAT_R32G32B32_TYPELESS,
618+
DXGI_FORMAT_R32G32B32_FLOAT,
619+
DXGI_FORMAT_R32G32B32_UINT,
620+
DXGI_FORMAT_R32G32B32_SINT,
621+
DXGI_FORMAT_R16G16B16A16_TYPELESS,
622+
DXGI_FORMAT_R16G16B16A16_FLOAT,
623+
DXGI_FORMAT_R16G16B16A16_UNORM,
624+
DXGI_FORMAT_R16G16B16A16_UINT,
625+
DXGI_FORMAT_R16G16B16A16_SNORM,
626+
DXGI_FORMAT_R16G16B16A16_SINT,
627+
DXGI_FORMAT_R32G32_TYPELESS,
628+
DXGI_FORMAT_R32G32_FLOAT,
629+
DXGI_FORMAT_R32G32_UINT,
630+
DXGI_FORMAT_R32G32_SINT,
631+
DXGI_FORMAT_R32G8X24_TYPELESS,
632+
DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
633+
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS,
634+
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT,
635+
DXGI_FORMAT_R10G10B10A2_TYPELESS,
636+
DXGI_FORMAT_R10G10B10A2_UNORM,
637+
DXGI_FORMAT_R10G10B10A2_UINT,
638+
DXGI_FORMAT_R11G11B10_FLOAT,
639+
DXGI_FORMAT_R8G8B8A8_TYPELESS,
640+
DXGI_FORMAT_R8G8B8A8_UNORM,
641+
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
642+
DXGI_FORMAT_R8G8B8A8_UINT,
643+
DXGI_FORMAT_R8G8B8A8_SNORM,
644+
DXGI_FORMAT_R8G8B8A8_SINT,
645+
DXGI_FORMAT_R16G16_TYPELESS,
646+
DXGI_FORMAT_R16G16_FLOAT,
647+
DXGI_FORMAT_R16G16_UNORM,
648+
DXGI_FORMAT_R16G16_UINT,
649+
DXGI_FORMAT_R16G16_SNORM,
650+
DXGI_FORMAT_R16G16_SINT,
651+
DXGI_FORMAT_R32_TYPELESS,
652+
DXGI_FORMAT_D32_FLOAT,
653+
DXGI_FORMAT_R32_FLOAT,
654+
DXGI_FORMAT_R32_UINT,
655+
DXGI_FORMAT_R32_SINT,
656+
DXGI_FORMAT_R24G8_TYPELESS,
657+
DXGI_FORMAT_D24_UNORM_S8_UINT,
658+
DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
659+
DXGI_FORMAT_X24_TYPELESS_G8_UINT,
660+
DXGI_FORMAT_R8G8_TYPELESS,
661+
DXGI_FORMAT_R8G8_UNORM,
662+
DXGI_FORMAT_R8G8_UINT,
663+
DXGI_FORMAT_R8G8_SNORM,
664+
DXGI_FORMAT_R8G8_SINT,
665+
DXGI_FORMAT_R16_TYPELESS,
666+
DXGI_FORMAT_R16_FLOAT,
667+
DXGI_FORMAT_D16_UNORM,
668+
DXGI_FORMAT_R16_UNORM,
669+
DXGI_FORMAT_R16_UINT,
670+
DXGI_FORMAT_R16_SNORM,
671+
DXGI_FORMAT_R16_SINT,
672+
DXGI_FORMAT_R8_TYPELESS,
673+
DXGI_FORMAT_R8_UNORM,
674+
DXGI_FORMAT_R8_UINT,
675+
DXGI_FORMAT_R8_SNORM,
676+
DXGI_FORMAT_R8_SINT,
677+
DXGI_FORMAT_A8_UNORM,
678+
DXGI_FORMAT_R1_UNORM,
679+
DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
680+
DXGI_FORMAT_R8G8_B8G8_UNORM,
681+
DXGI_FORMAT_G8R8_G8B8_UNORM,
682+
DXGI_FORMAT_BC1_TYPELESS,
683+
DXGI_FORMAT_BC1_UNORM,
684+
DXGI_FORMAT_BC1_UNORM_SRGB,
685+
DXGI_FORMAT_BC2_TYPELESS,
686+
DXGI_FORMAT_BC2_UNORM,
687+
DXGI_FORMAT_BC2_UNORM_SRGB,
688+
DXGI_FORMAT_BC3_TYPELESS,
689+
DXGI_FORMAT_BC3_UNORM,
690+
DXGI_FORMAT_BC3_UNORM_SRGB,
691+
DXGI_FORMAT_BC4_TYPELESS,
692+
DXGI_FORMAT_BC4_UNORM,
693+
DXGI_FORMAT_BC4_SNORM,
694+
DXGI_FORMAT_BC5_TYPELESS,
695+
DXGI_FORMAT_BC5_UNORM,
696+
DXGI_FORMAT_BC5_SNORM,
697+
DXGI_FORMAT_B5G6R5_UNORM,
698+
DXGI_FORMAT_B5G5R5A1_UNORM,
699+
DXGI_FORMAT_B8G8R8A8_UNORM,
700+
DXGI_FORMAT_B8G8R8X8_UNORM,
701+
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM,
702+
DXGI_FORMAT_B8G8R8A8_TYPELESS,
703+
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
704+
DXGI_FORMAT_B8G8R8X8_TYPELESS,
705+
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB,
706+
DXGI_FORMAT_BC6H_TYPELESS,
707+
DXGI_FORMAT_BC6H_UF16,
708+
DXGI_FORMAT_BC6H_SF16,
709+
DXGI_FORMAT_BC7_TYPELESS,
710+
DXGI_FORMAT_BC7_UNORM,
711+
DXGI_FORMAT_BC7_UNORM_SRGB,
712+
DXGI_FORMAT_AYUV,
713+
DXGI_FORMAT_Y410,
714+
DXGI_FORMAT_Y416,
715+
DXGI_FORMAT_NV12,
716+
DXGI_FORMAT_P010,
717+
DXGI_FORMAT_P016,
718+
DXGI_FORMAT_420_OPAQUE,
719+
DXGI_FORMAT_YUY2,
720+
DXGI_FORMAT_Y210,
721+
DXGI_FORMAT_Y216,
722+
DXGI_FORMAT_NV11,
723+
DXGI_FORMAT_AI44,
724+
DXGI_FORMAT_IA44,
725+
DXGI_FORMAT_P8,
726+
DXGI_FORMAT_A8P8,
727+
DXGI_FORMAT_B4G4R4A4_UNORM,
728+
DXGI_FORMAT_P208,
729+
DXGI_FORMAT_V208,
730+
DXGI_FORMAT_V408,
731+
DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE,
732+
DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE,
733+
DXGI_FORMAT_FORCE_UINT
734+
};
545735
}
546736
}

xivModdingFramework/Textures/FileTypes/Tex.cs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ public void SaveTexAsDDS(IItem item, XivTex xivTex, DirectoryInfo saveDirectory,
415415
/// </summary>
416416
/// <param name="xivTex">The texture data</param>
417417
/// <returns>A byte array with the image data</returns>
418-
public Task<byte[]> GetImageData(XivTex xivTex)
418+
public Task<byte[]> GetImageData(XivTex xivTex, int layer = -1)
419419
{
420420
return Task.Run(async () =>
421421
{
@@ -424,26 +424,26 @@ public Task<byte[]> GetImageData(XivTex xivTex)
424424
switch (xivTex.TextureFormat)
425425
{
426426
case XivTexFormat.DXT1:
427-
imageData = DxtUtil.DecompressDxt1(xivTex.TexData, xivTex.Width, xivTex.Height);
427+
imageData = DxtUtil.DecompressDxt1(xivTex.TexData, xivTex.Width, xivTex.Height * xivTex.Layers);
428428
break;
429429
case XivTexFormat.DXT3:
430-
imageData = DxtUtil.DecompressDxt3(xivTex.TexData, xivTex.Width, xivTex.Height);
430+
imageData = DxtUtil.DecompressDxt3(xivTex.TexData, xivTex.Width, xivTex.Height * xivTex.Layers);
431431
break;
432432
case XivTexFormat.DXT5:
433-
imageData = DxtUtil.DecompressDxt5(xivTex.TexData, xivTex.Width, xivTex.Height);
433+
imageData = DxtUtil.DecompressDxt5(xivTex.TexData, xivTex.Width, xivTex.Height * xivTex.Layers);
434434
break;
435435
case XivTexFormat.A4R4G4B4:
436-
imageData = await Read4444Image(xivTex.TexData, xivTex.Width, xivTex.Height);
436+
imageData = await Read4444Image(xivTex.TexData, xivTex.Width, xivTex.Height * xivTex.Layers);
437437
break;
438438
case XivTexFormat.A1R5G5B5:
439-
imageData = await Read5551Image(xivTex.TexData, xivTex.Width, xivTex.Height);
439+
imageData = await Read5551Image(xivTex.TexData, xivTex.Width, xivTex.Height * xivTex.Layers);
440440
break;
441441
case XivTexFormat.A8R8G8B8:
442-
imageData = await SwapRBColors(xivTex.TexData, xivTex.Width, xivTex.Height);
442+
imageData = await SwapRBColors(xivTex.TexData, xivTex.Width, xivTex.Height * xivTex.Layers);
443443
break;
444444
case XivTexFormat.L8:
445445
case XivTexFormat.A8:
446-
imageData = await Read8bitImage(xivTex.TexData, xivTex.Width, xivTex.Height);
446+
imageData = await Read8bitImage(xivTex.TexData, xivTex.Width, xivTex.Height * xivTex.Layers);
447447
break;
448448
case XivTexFormat.X8R8G8B8:
449449
case XivTexFormat.R32F:
@@ -457,6 +457,17 @@ public Task<byte[]> GetImageData(XivTex xivTex)
457457
break;
458458
}
459459

460+
if(layer >= 0)
461+
{
462+
var bytesPerLayer = imageData.Length / xivTex.Layers;
463+
var offset = bytesPerLayer * layer;
464+
465+
byte[] nData = new byte[bytesPerLayer];
466+
Array.Copy(imageData, offset, nData, 0, bytesPerLayer);
467+
468+
imageData = nData;
469+
}
470+
460471
return imageData;
461472
});
462473
}

0 commit comments

Comments
 (0)