mirror of
https://github.com/KillzXGaming/Switch-Toolbox
synced 2024-11-24 21:43:20 +00:00
Update retro formats to support Metroid Prime Remastered
This commit is contained in:
parent
976939bec0
commit
afe7ab3890
13 changed files with 322 additions and 128 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -356,3 +356,4 @@ Toolbox/Lib.zip
|
||||||
yuzu-glsl-decompiler
|
yuzu-glsl-decompiler
|
||||||
AnimSetupPrevious.zip
|
AnimSetupPrevious.zip
|
||||||
AnimSetupNew.zip
|
AnimSetupNew.zip
|
||||||
|
Switch_Toolbox_Library/Forms/Editors/UV/UVEditor.cs
|
||||||
|
|
|
@ -140,8 +140,10 @@ namespace DKCTF
|
||||||
{
|
{
|
||||||
string guid = texMap.Value.FileID.ToString();
|
string guid = texMap.Value.FileID.ToString();
|
||||||
if (texFolder.Nodes.ContainsKey(guid) || !Textures.ContainsKey(guid))
|
if (texFolder.Nodes.ContainsKey(guid) || !Textures.ContainsKey(guid))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Texture not present in pak file! {mat.Name} {texMap.Key} {guid}");
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (Textures[guid].FileFormat == null)
|
if (Textures[guid].FileFormat == null)
|
||||||
Textures[guid].OpenFile();
|
Textures[guid].OpenFile();
|
||||||
|
|
||||||
|
@ -153,7 +155,7 @@ namespace DKCTF
|
||||||
t.Tag = tex;
|
t.Tag = tex;
|
||||||
texFolder.Nodes.Add(t);
|
texFolder.Nodes.Add(t);
|
||||||
|
|
||||||
if (texMap.Key == "DIFT")
|
if (texMap.Key == "DIFT" || texMap.Key == "BCLR")
|
||||||
{
|
{
|
||||||
tex.Text = guid;
|
tex.Text = guid;
|
||||||
|
|
||||||
|
@ -167,6 +169,7 @@ namespace DKCTF
|
||||||
|
|
||||||
TreeNode texFolder = new STTextureFolder("Textures");
|
TreeNode texFolder = new STTextureFolder("Textures");
|
||||||
TreeNode skeletonFolder = new STTextureFolder("Skeleton");
|
TreeNode skeletonFolder = new STTextureFolder("Skeleton");
|
||||||
|
TreeNode shaderFolder = new STTextureFolder("Materials");
|
||||||
|
|
||||||
public void Load(System.IO.Stream stream)
|
public void Load(System.IO.Stream stream)
|
||||||
{
|
{
|
||||||
|
@ -179,11 +182,14 @@ namespace DKCTF
|
||||||
Nodes.Add(meshFolder);
|
Nodes.Add(meshFolder);
|
||||||
|
|
||||||
Nodes.Add(texFolder);
|
Nodes.Add(texFolder);
|
||||||
|
|
||||||
Nodes.Add(skeletonFolder);
|
Nodes.Add(skeletonFolder);
|
||||||
|
Nodes.Add(shaderFolder);
|
||||||
|
|
||||||
Model = ToGeneric();
|
Model = ToGeneric();
|
||||||
|
|
||||||
|
foreach (var mat in ModelData.Materials)
|
||||||
|
shaderFolder.Nodes.Add(new TreeNode(mat.Name + "_" + mat.ID.ToString()));
|
||||||
|
|
||||||
foreach (GenericRenderedObject mesh in Model.Objects)
|
foreach (GenericRenderedObject mesh in Model.Objects)
|
||||||
{
|
{
|
||||||
Renderer.Meshes.Add(mesh);
|
Renderer.Meshes.Add(mesh);
|
||||||
|
@ -235,6 +241,7 @@ namespace DKCTF
|
||||||
if (tex.Key == "DIFT") type = STGenericMatTexture.TextureType.Diffuse;
|
if (tex.Key == "DIFT") type = STGenericMatTexture.TextureType.Diffuse;
|
||||||
if (tex.Key == "NMAP") type = STGenericMatTexture.TextureType.Normal;
|
if (tex.Key == "NMAP") type = STGenericMatTexture.TextureType.Normal;
|
||||||
if (tex.Key == "SPCT") type = STGenericMatTexture.TextureType.Specular;
|
if (tex.Key == "SPCT") type = STGenericMatTexture.TextureType.Specular;
|
||||||
|
if (tex.Key == "BCLR") type = STGenericMatTexture.TextureType.Diffuse;
|
||||||
|
|
||||||
genericMaterial.TextureMaps.Add(new STGenericMatTexture()
|
genericMaterial.TextureMaps.Add(new STGenericMatTexture()
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,13 +134,16 @@ namespace DKCTF
|
||||||
|
|
||||||
Header = new TXTR(stream);
|
Header = new TXTR(stream);
|
||||||
|
|
||||||
if (Header.IsSwitch)
|
if (!Header.IsSwitch)
|
||||||
PlatformSwizzle = PlatformSwizzle.Platform_WiiU;
|
PlatformSwizzle = PlatformSwizzle.Platform_WiiU;
|
||||||
|
|
||||||
Width = Header.TextureHeader.Width;
|
Width = Header.TextureHeader.Width;
|
||||||
Height = Header.TextureHeader.Height;
|
Height = Header.TextureHeader.Height;
|
||||||
MipCount = (uint)Header.MipSizes.Length;
|
MipCount = (uint)Header.MipSizes.Length;
|
||||||
Format = FormatList[Header.TextureHeader.Format];
|
Format = FormatList[Header.TextureHeader.Format];
|
||||||
|
|
||||||
|
if (Header.TextureHeader.Type == 3)
|
||||||
|
this.ArrayCount = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(System.IO.Stream stream)
|
public void Save(System.IO.Stream stream)
|
||||||
|
@ -225,18 +228,6 @@ namespace DKCTF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
public class STextureHeader
|
|
||||||
{
|
|
||||||
public uint Type;
|
|
||||||
public uint Format;
|
|
||||||
public uint Width;
|
|
||||||
public uint Height;
|
|
||||||
public uint Depth;
|
|
||||||
public uint TileMode;
|
|
||||||
public uint Swizzle;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dictionary<uint, TEX_FORMAT> FormatList = new Dictionary<uint, TEX_FORMAT>()
|
Dictionary<uint, TEX_FORMAT> FormatList = new Dictionary<uint, TEX_FORMAT>()
|
||||||
{
|
{
|
||||||
{ 12, TEX_FORMAT.R8G8B8A8_UNORM },
|
{ 12, TEX_FORMAT.R8G8B8A8_UNORM },
|
||||||
|
@ -257,11 +248,40 @@ namespace DKCTF
|
||||||
{ 32, TEX_FORMAT.R16G16_FLOAT },
|
{ 32, TEX_FORMAT.R16G16_FLOAT },
|
||||||
{ 33, TEX_FORMAT.R8G8_UNORM },
|
{ 33, TEX_FORMAT.R8G8_UNORM },
|
||||||
|
|
||||||
|
{ 53, TEX_FORMAT.ASTC_4x4_UNORM },
|
||||||
{ 54, TEX_FORMAT.ASTC_5x4_UNORM },
|
{ 54, TEX_FORMAT.ASTC_5x4_UNORM },
|
||||||
{ 55, TEX_FORMAT.ASTC_5x5_UNORM },
|
{ 55, TEX_FORMAT.ASTC_5x5_UNORM },
|
||||||
{ 56, TEX_FORMAT.ASTC_6x5_UNORM },
|
{ 56, TEX_FORMAT.ASTC_6x5_UNORM },
|
||||||
{ 57, TEX_FORMAT.ASTC_6x6_UNORM },
|
{ 57, TEX_FORMAT.ASTC_6x6_UNORM },
|
||||||
{ 58, TEX_FORMAT.ASTC_8x5_UNORM },
|
{ 58, TEX_FORMAT.ASTC_8x5_UNORM },
|
||||||
|
{ 59, TEX_FORMAT.ASTC_8x6_UNORM },
|
||||||
|
{ 60, TEX_FORMAT.ASTC_8x8_UNORM },
|
||||||
|
{ 61, TEX_FORMAT.ASTC_10x5_UNORM },
|
||||||
|
{ 62, TEX_FORMAT.ASTC_10x6_UNORM},
|
||||||
|
{ 63, TEX_FORMAT.ASTC_10x8_UNORM},
|
||||||
|
{ 64, TEX_FORMAT.ASTC_10x10_UNORM},
|
||||||
|
{ 65, TEX_FORMAT.ASTC_12x10_UNORM},
|
||||||
|
{ 66, TEX_FORMAT.ASTC_12x12_UNORM},
|
||||||
|
|
||||||
|
{ 67, TEX_FORMAT.ASTC_4x4_SRGB},
|
||||||
|
{ 68, TEX_FORMAT.ASTC_5x4_SRGB },
|
||||||
|
{ 69, TEX_FORMAT.ASTC_5x5_SRGB },
|
||||||
|
{ 70, TEX_FORMAT.ASTC_6x5_SRGB },
|
||||||
|
{ 71, TEX_FORMAT.ASTC_6x6_SRGB },
|
||||||
|
{ 72, TEX_FORMAT.ASTC_8x5_SRGB },
|
||||||
|
{ 73, TEX_FORMAT.ASTC_8x6_SRGB },
|
||||||
|
{ 74, TEX_FORMAT.ASTC_8x8_SRGB},
|
||||||
|
{ 75, TEX_FORMAT.ASTC_10x5_SRGB },
|
||||||
|
{ 76, TEX_FORMAT.ASTC_10x6_SRGB},
|
||||||
|
{ 77, TEX_FORMAT.ASTC_10x8_SRGB},
|
||||||
|
{ 78, TEX_FORMAT.ASTC_10x10_SRGB},
|
||||||
|
{ 79, TEX_FORMAT.ASTC_12x10_SRGB},
|
||||||
|
{ 80, TEX_FORMAT.ASTC_12x12_SRGB},
|
||||||
|
|
||||||
|
{ 81, TEX_FORMAT.BC6H_UF16 },
|
||||||
|
{ 82, TEX_FORMAT.BC6H_SF16 },
|
||||||
|
{ 83, TEX_FORMAT.BC7_UNORM },
|
||||||
|
{ 84, TEX_FORMAT.BC7_UNORM_SRGB },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,19 +42,23 @@ namespace DKCTF
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a vertex list from the provided buffer and descriptor info.
|
/// Gets a vertex list from the provided buffer and descriptor info.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static List<CMDL.CVertex> LoadVertexBuffer(byte[] buffer, CMDL.VertexBuffer vertexBuffer, bool isLittleEndian)
|
public static CMDL.CVertex[] LoadVertexBuffer(List<byte[]> buffers, int startIndex, CMDL.VertexBuffer vertexInfo, bool isLittleEndian)
|
||||||
{
|
{
|
||||||
List<CMDL.CVertex> vertices = new List<CMDL.CVertex>();
|
var vertices = new CMDL.CVertex[vertexInfo.VertexCount];
|
||||||
|
|
||||||
using (var reader = new FileReader(buffer))
|
foreach (var comp in vertexInfo.Components)
|
||||||
{
|
{
|
||||||
reader.SetByteOrder(!isLittleEndian); //switch is little endianness
|
var buffer = buffers[startIndex + (int)comp.BufferID];
|
||||||
|
using (var reader = new FileReader(buffer))
|
||||||
|
{
|
||||||
|
reader.SetByteOrder(!isLittleEndian); //switch is little endianness
|
||||||
|
|
||||||
for (int i = 0; i < vertexBuffer.VertexCount; i++) {
|
for (int i = 0; i < vertexInfo.VertexCount; i++)
|
||||||
CMDL.CVertex vertex = new CMDL.CVertex();
|
{
|
||||||
vertices.Add(vertex);
|
if (vertices[i] == null) vertices[i] = new CMDL.CVertex();
|
||||||
|
|
||||||
|
CMDL.CVertex vertex = vertices[i];
|
||||||
|
|
||||||
foreach (var comp in vertexBuffer.Components) {
|
|
||||||
reader.SeekBegin(comp.Offset + i * comp.Stride);
|
reader.SeekBegin(comp.Offset + i * comp.Stride);
|
||||||
switch (comp.Type)
|
switch (comp.Type)
|
||||||
{
|
{
|
||||||
|
@ -68,7 +72,7 @@ namespace DKCTF
|
||||||
vertex.TexCoord0 = ReadData(reader, comp.Format).Xy;
|
vertex.TexCoord0 = ReadData(reader, comp.Format).Xy;
|
||||||
break;
|
break;
|
||||||
case CMDL.EVertexComponent.in_texCoord1:
|
case CMDL.EVertexComponent.in_texCoord1:
|
||||||
vertex.TexCoord1 = ReadData(reader, comp.Format).Xy;
|
vertex.TexCoord0 = ReadData(reader, comp.Format).Xy;
|
||||||
break;
|
break;
|
||||||
case CMDL.EVertexComponent.in_texCoord2:
|
case CMDL.EVertexComponent.in_texCoord2:
|
||||||
vertex.TexCoord2 = ReadData(reader, comp.Format).Xy;
|
vertex.TexCoord2 = ReadData(reader, comp.Format).Xy;
|
||||||
|
@ -89,7 +93,6 @@ namespace DKCTF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return vertices;
|
return vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace DKCTF
|
||||||
|
|
||||||
public override void Read(FileReader reader)
|
public override void Read(FileReader reader)
|
||||||
{
|
{
|
||||||
reader.ReadStruct<CAssetHeader>();
|
var assetHeader = reader.ReadStruct<CAssetHeader>();
|
||||||
reader.ReadStruct<SInfo>();
|
reader.ReadStruct<SInfo>();
|
||||||
//Dumb hack atm
|
//Dumb hack atm
|
||||||
bool IsSwitch = false;
|
bool IsSwitch = false;
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace DKCTF
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ReadMetaData(FileReader reader)
|
public override void ReadMetaData(FileReader reader, CFormDescriptor pakVersion)
|
||||||
{
|
{
|
||||||
Meta = new SMetaData();
|
Meta = new SMetaData();
|
||||||
Meta.Unknown = reader.ReadUInt32();
|
Meta.Unknown = reader.ReadUInt32();
|
||||||
|
@ -60,13 +60,12 @@ namespace DKCTF
|
||||||
Meta.ReadBufferInfo = IOFileExtension.ReadList<SReadBufferInfo>(reader);
|
Meta.ReadBufferInfo = IOFileExtension.ReadList<SReadBufferInfo>(reader);
|
||||||
Meta.VertexBuffers = IOFileExtension.ReadList<SBufferInfo>(reader);
|
Meta.VertexBuffers = IOFileExtension.ReadList<SBufferInfo>(reader);
|
||||||
Meta.IndexBuffers = IOFileExtension.ReadList<SBufferInfo>(reader);
|
Meta.IndexBuffers = IOFileExtension.ReadList<SBufferInfo>(reader);
|
||||||
Console.WriteLine();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteMetaData(FileWriter writer)
|
public override void WriteMetaData(FileWriter writer, CFormDescriptor pakVersion)
|
||||||
{
|
{
|
||||||
writer.Write(Meta.GPUOffset);
|
|
||||||
writer.Write(Meta.Unknown);
|
writer.Write(Meta.Unknown);
|
||||||
|
writer.Write(Meta.GPUOffset);
|
||||||
IOFileExtension.WriteList(writer, Meta.ReadBufferInfo);
|
IOFileExtension.WriteList(writer, Meta.ReadBufferInfo);
|
||||||
IOFileExtension.WriteList(writer, Meta.VertexBuffers);
|
IOFileExtension.WriteList(writer, Meta.VertexBuffers);
|
||||||
IOFileExtension.WriteList(writer, Meta.IndexBuffers);
|
IOFileExtension.WriteList(writer, Meta.IndexBuffers);
|
||||||
|
@ -130,47 +129,41 @@ namespace DKCTF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Prepare buffer list
|
||||||
|
List<byte[]> vertexData = new List<byte[]>();
|
||||||
for (int i = 0; i < Meta.VertexBuffers.Count; i++)
|
for (int i = 0; i < Meta.VertexBuffers.Count; i++)
|
||||||
{
|
{
|
||||||
var vertexInfo = VertexBuffers[i];
|
|
||||||
|
|
||||||
var buffer = Meta.VertexBuffers[i];
|
var buffer = Meta.VertexBuffers[i];
|
||||||
//First buffer or specific buffer
|
//First buffer or specific buffer
|
||||||
var info = Meta.ReadBufferInfo[(int)buffer.ReadBufferIndex];
|
var info = Meta.ReadBufferInfo[(int)buffer.ReadBufferIndex];
|
||||||
//Seek into the buffer region
|
//Seek into the buffer region
|
||||||
reader.SeekBegin(info.Offset + buffer.Offset);
|
reader.SeekBegin(info.Offset + buffer.Offset);
|
||||||
|
|
||||||
using (reader.TemporarySeek(reader.Position, System.IO.SeekOrigin.Begin))
|
|
||||||
{
|
|
||||||
reader.SetByteOrder(false);
|
|
||||||
var type = reader.ReadUInt32();
|
|
||||||
reader.SetByteOrder(true);
|
|
||||||
|
|
||||||
if (type != 13)
|
|
||||||
{
|
|
||||||
byte[] b = reader.ReadBytes((int)buffer.CompressedSize - 4);
|
|
||||||
System.IO.File.WriteAllBytes($"{Toolbox.Library.Runtime.ExecutableDir}\\VBuffer_{type}_{i}_{buffer.DecompressedSize}.bin", b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Decompress
|
//Decompress
|
||||||
var data = IOFileExtension.DecompressedBuffer(reader, buffer.CompressedSize, buffer.DecompressedSize, IsSwitch);
|
var data = IOFileExtension.DecompressedBuffer(reader, buffer.CompressedSize, buffer.DecompressedSize, IsSwitch);
|
||||||
if (buffer.DecompressedSize != data.Length)
|
if (buffer.DecompressedSize != data.Length)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
|
|
||||||
var vertices = BufferHelper.LoadVertexBuffer(data, vertexInfo,IsSwitch);
|
vertexData.Add(data);
|
||||||
|
|
||||||
|
startPos += buffer.CompressedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (int j = 0; j < VertexBuffers.Count; j++)
|
||||||
|
{
|
||||||
|
var vertexInfo = VertexBuffers[j];
|
||||||
|
var bufferID = j * 2;
|
||||||
|
if (!this.IsMPR)
|
||||||
|
bufferID = j;
|
||||||
|
|
||||||
|
var vertices = BufferHelper.LoadVertexBuffer(vertexData, bufferID, vertexInfo, IsSwitch);
|
||||||
|
|
||||||
//Read
|
//Read
|
||||||
foreach (var mesh in Meshes)
|
foreach (var mesh in Meshes)
|
||||||
{
|
if (mesh.Header.VertexBufferIndex == j)
|
||||||
if (mesh.Header.VertexBufferIndex == i)
|
mesh.SetupVertices(vertices.ToList());
|
||||||
{
|
|
||||||
//Only use the vertices referenced in the indices
|
|
||||||
//Some meshes use the same big buffer and can add too many unecessary vertices
|
|
||||||
mesh.SetupVertices(vertices);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startPos += buffer.CompressedSize;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -241,6 +234,8 @@ namespace DKCTF
|
||||||
|
|
||||||
private void ReadMaterials(FileReader reader)
|
private void ReadMaterials(FileReader reader)
|
||||||
{
|
{
|
||||||
|
if (this.IsMPR)
|
||||||
|
reader.ReadUInt32();
|
||||||
uint numMaterials = reader.ReadUInt32();
|
uint numMaterials = reader.ReadUInt32();
|
||||||
for (int i = 0; i < numMaterials; i++)
|
for (int i = 0; i < numMaterials; i++)
|
||||||
{
|
{
|
||||||
|
@ -250,8 +245,26 @@ namespace DKCTF
|
||||||
uint size = reader.ReadUInt32();
|
uint size = reader.ReadUInt32();
|
||||||
material.Name = reader.ReadString((int)size, true);
|
material.Name = reader.ReadString((int)size, true);
|
||||||
material.ID = reader.ReadStruct<CObjectId>();
|
material.ID = reader.ReadStruct<CObjectId>();
|
||||||
material.Type = reader.ReadStruct<Magic>();
|
if (this.IsMPR)
|
||||||
material.Flags = reader.ReadUInt32();
|
{
|
||||||
|
reader.ReadBytes(24); //Shader guid and extras?
|
||||||
|
uint numTypes = reader.ReadByte();
|
||||||
|
reader.ReadBytes(3);
|
||||||
|
reader.ReadUInt32s((int)numTypes); //type list, fourcc
|
||||||
|
|
||||||
|
uint numDataInts = reader.ReadUInt32();
|
||||||
|
|
||||||
|
//A list of data types with extra flags
|
||||||
|
for (int j = 0; j < numDataInts; j++)
|
||||||
|
{
|
||||||
|
var dtype = reader.ReadStruct<Magic>();
|
||||||
|
var dformat = reader.ReadStruct<Magic>();
|
||||||
|
reader.ReadUInt16();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
reader.ReadBytes(8); //Type, Flags
|
||||||
|
|
||||||
uint numData = reader.ReadUInt32();
|
uint numData = reader.ReadUInt32();
|
||||||
|
|
||||||
//A list of data types
|
//A list of data types
|
||||||
|
@ -304,6 +317,9 @@ namespace DKCTF
|
||||||
reader.ReadStruct<STextureUsageInfo>();
|
reader.ReadStruct<STextureUsageInfo>();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "MA4": //Matrix4x4
|
||||||
|
material.Matrices.Add(dtype, reader.ReadSingles(16));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Exception($"Unsupported material type {dformat}!");
|
throw new Exception($"Unsupported material type {dformat}!");
|
||||||
}
|
}
|
||||||
|
@ -315,10 +331,31 @@ namespace DKCTF
|
||||||
{
|
{
|
||||||
uint numMeshes = reader.ReadUInt32();
|
uint numMeshes = reader.ReadUInt32();
|
||||||
for (int i = 0; i < numMeshes; i++)
|
for (int i = 0; i < numMeshes; i++)
|
||||||
|
{
|
||||||
|
var mesh = new CRenderMesh();
|
||||||
|
|
||||||
|
if (this.IsMPR)
|
||||||
|
mesh = reader.ReadStruct<CRenderMesh>();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint type = reader.ReadUInt32(); //prim type
|
||||||
|
mesh.MaterialIndex = reader.ReadUInt16();
|
||||||
|
mesh.VertexBufferIndex = reader.ReadByte();
|
||||||
|
mesh.IndexBufferIndex = reader.ReadByte();
|
||||||
|
mesh.IndexStart = reader.ReadUInt32();
|
||||||
|
mesh.IndexCount = reader.ReadUInt32();
|
||||||
|
reader.ReadUInt16(); //0x10
|
||||||
|
reader.ReadByte(); //0x12
|
||||||
|
reader.ReadByte(); //0x13
|
||||||
|
reader.ReadByte(); //flags
|
||||||
|
}
|
||||||
|
|
||||||
Meshes.Add(new CMesh()
|
Meshes.Add(new CMesh()
|
||||||
{
|
{
|
||||||
Header = reader.ReadStruct<CRenderMesh>(),
|
Header = mesh,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadVertexBuffer(FileReader reader)
|
private void ReadVertexBuffer(FileReader reader)
|
||||||
|
@ -334,6 +371,8 @@ namespace DKCTF
|
||||||
for (int j = 0; j < numAttributes; j++)
|
for (int j = 0; j < numAttributes; j++)
|
||||||
vertexBuffer.Components.Add(reader.ReadStruct<SVertexDataComponent>());
|
vertexBuffer.Components.Add(reader.ReadStruct<SVertexDataComponent>());
|
||||||
VertexBuffers.Add(vertexBuffer);
|
VertexBuffers.Add(vertexBuffer);
|
||||||
|
if (this.IsMPR)
|
||||||
|
reader.ReadByte();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,6 +420,7 @@ namespace DKCTF
|
||||||
public Dictionary<string, float> Scalars = new Dictionary<string, float>();
|
public Dictionary<string, float> Scalars = new Dictionary<string, float>();
|
||||||
public Dictionary<string, int> Int = new Dictionary<string, int>();
|
public Dictionary<string, int> Int = new Dictionary<string, int>();
|
||||||
public Dictionary<string, int[]> Int4 = new Dictionary<string, int[]>();
|
public Dictionary<string, int[]> Int4 = new Dictionary<string, int[]>();
|
||||||
|
public Dictionary<string, float[]> Matrices = new Dictionary<string, float[]>();
|
||||||
|
|
||||||
public Dictionary<string, Color4f> Colors = new Dictionary<string, Color4f>();
|
public Dictionary<string, Color4f> Colors = new Dictionary<string, Color4f>();
|
||||||
}
|
}
|
||||||
|
@ -416,16 +456,13 @@ namespace DKCTF
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public class CRenderMesh
|
public class CRenderMesh
|
||||||
{
|
{
|
||||||
public PrimtiiveType PrimtiiveMode;
|
|
||||||
public ushort MaterialIndex;
|
public ushort MaterialIndex;
|
||||||
public byte VertexBufferIndex;
|
public byte VertexBufferIndex;
|
||||||
public byte IndexBufferIndex;
|
public byte IndexBufferIndex;
|
||||||
public uint IndexStart;
|
public uint IndexStart;
|
||||||
public uint IndexCount;
|
public uint IndexCount;
|
||||||
public ushort field_10;
|
public ushort field_C;
|
||||||
public byte field_12;
|
public ushort field_E; //0x4000
|
||||||
public byte field_13;
|
|
||||||
public byte field_14;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
@ -465,7 +502,7 @@ namespace DKCTF
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public class SVertexDataComponent
|
public class SVertexDataComponent
|
||||||
{
|
{
|
||||||
public uint field_0;
|
public uint BufferID;
|
||||||
public uint Offset;
|
public uint Offset;
|
||||||
public uint Stride;
|
public uint Stride;
|
||||||
public VertexFormat Format;
|
public VertexFormat Format;
|
||||||
|
|
|
@ -20,11 +20,22 @@ namespace DKCTF
|
||||||
|
|
||||||
public FileForm() { }
|
public FileForm() { }
|
||||||
|
|
||||||
|
public bool IsLittleEndian = false;
|
||||||
|
public bool IsMPR = false;
|
||||||
|
|
||||||
public FileForm(Stream stream, bool leaveOpen = false)
|
public FileForm(Stream stream, bool leaveOpen = false)
|
||||||
{
|
{
|
||||||
using (var reader = new FileReader(stream, leaveOpen))
|
using (var reader = new FileReader(stream, leaveOpen))
|
||||||
{
|
{
|
||||||
reader.SetByteOrder(true);
|
//Small "hack" to detect endianness.
|
||||||
|
using (reader.TemporarySeek(4, SeekOrigin.Begin)) {
|
||||||
|
//Size is a uint64. If the first 4 bytes are present, file is little endian
|
||||||
|
IsLittleEndian = reader.ReadUInt32() != 0;
|
||||||
|
//MPR is only game currently that is little endian
|
||||||
|
IsMPR = IsLittleEndian;
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.SetByteOrder(!IsLittleEndian);
|
||||||
FileHeader = reader.ReadStruct<CFormDescriptor>();
|
FileHeader = reader.ReadStruct<CFormDescriptor>();
|
||||||
Read(reader);
|
Read(reader);
|
||||||
AfterLoad();
|
AfterLoad();
|
||||||
|
@ -61,7 +72,7 @@ namespace DKCTF
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads meta data information within the pak archive.
|
/// Reads meta data information within the pak archive.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void ReadMetaData(FileReader reader)
|
public virtual void ReadMetaData(FileReader reader, CFormDescriptor pakVersion)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -69,7 +80,7 @@ namespace DKCTF
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes meta data information within the pak archive.
|
/// Writes meta data information within the pak archive.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void WriteMetaData(FileWriter writer)
|
public virtual void WriteMetaData(FileWriter writer, CFormDescriptor pakVersion)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -87,22 +98,28 @@ namespace DKCTF
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long ReadMetaFooter(FileReader reader)
|
public long ReadMetaFooter(FileReader reader)
|
||||||
{
|
{
|
||||||
using (reader.TemporarySeek(reader.BaseStream.Length - 12, SeekOrigin.Begin))
|
using (reader.TemporarySeek(reader.BaseStream.Length - 20, SeekOrigin.Begin))
|
||||||
{
|
{
|
||||||
if (reader.ReadString(4, Encoding.ASCII) != "META")
|
if (reader.ReadString(4, Encoding.ASCII) != "META")
|
||||||
return reader.BaseStream.Length;
|
return reader.BaseStream.Length;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using (reader.TemporarySeek(reader.BaseStream.Length - 12, SeekOrigin.Begin))
|
using (reader.TemporarySeek(reader.BaseStream.Length - 20, SeekOrigin.Begin))
|
||||||
{
|
{
|
||||||
reader.ReadSignature(4, "META");
|
reader.ReadSignature(4, "META");
|
||||||
reader.ReadString(4); //type of file
|
reader.ReadString(4); //type of file
|
||||||
|
uint versionA = reader.ReadUInt32(); //pak version A
|
||||||
|
uint versionB = reader.ReadUInt32(); //pak version B
|
||||||
uint size = reader.ReadUInt32(); //size of meta data
|
uint size = reader.ReadUInt32(); //size of meta data
|
||||||
//Seek back to meta data
|
//Seek back to meta data
|
||||||
reader.SeekBegin(reader.Position - size);
|
reader.SeekBegin(reader.Position - size);
|
||||||
//Read meta data
|
//Read meta data
|
||||||
ReadMetaData(reader);
|
CFormDescriptor pakHeader = new CFormDescriptor();
|
||||||
|
pakHeader.VersionA = versionA;
|
||||||
|
pakHeader.VersionB = versionB;
|
||||||
|
|
||||||
|
ReadMetaData(reader, pakHeader);
|
||||||
|
|
||||||
return reader.BaseStream.Length - size;
|
return reader.BaseStream.Length - size;
|
||||||
}
|
}
|
||||||
|
@ -111,22 +128,24 @@ namespace DKCTF
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes a footer to a file for accessing meta data information outside a .pak archive.
|
/// Writes a footer to a file for accessing meta data information outside a .pak archive.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static byte[] WriteMetaFooter(FileReader reader, uint metaOffset, string type)
|
public static byte[] WriteMetaFooter(FileReader reader, uint metaOffset, string type, PACK pack)
|
||||||
{
|
{
|
||||||
//Magic + meta offset first
|
//Magic + meta offset first
|
||||||
var mem = new MemoryStream();
|
var mem = new MemoryStream();
|
||||||
using (var writer = new FileWriter(mem))
|
using (var writer = new FileWriter(mem))
|
||||||
{
|
{
|
||||||
writer.SetByteOrder(true);
|
writer.SetByteOrder(!pack.IsLittleEndian);
|
||||||
|
|
||||||
reader.SeekBegin(metaOffset);
|
reader.SeekBegin(metaOffset);
|
||||||
var file = GetFileForm(type);
|
var file = GetFileForm(type);
|
||||||
file.ReadMetaData(reader);
|
file.ReadMetaData(reader, pack.FileHeader);
|
||||||
file.WriteMetaData(writer);
|
file.WriteMetaData(writer, pack.FileHeader);
|
||||||
|
|
||||||
//Write footer header last
|
//Write footer header last
|
||||||
writer.WriteSignature("META");
|
writer.WriteSignature("META");
|
||||||
writer.WriteSignature(type);
|
writer.WriteSignature(type);
|
||||||
|
writer.Write(pack.FileHeader.VersionA);
|
||||||
|
writer.Write(pack.FileHeader.VersionB);
|
||||||
writer.Write((uint)(writer.BaseStream.Length + 4)); //size
|
writer.Write((uint)(writer.BaseStream.Length + 4)); //size
|
||||||
}
|
}
|
||||||
return mem.ToArray();
|
return mem.ToArray();
|
||||||
|
|
|
@ -58,14 +58,12 @@ namespace DKCTF
|
||||||
reader.SetByteOrder(true);
|
reader.SetByteOrder(true);
|
||||||
|
|
||||||
Console.WriteLine($"type {type}");
|
Console.WriteLine($"type {type}");
|
||||||
// File.WriteAllBytes($"Buffer{type}.bin", reader.ReadBytes((int)(compSize - 4)));
|
|
||||||
|
|
||||||
var data = reader.ReadBytes((int)compSize - 4);
|
var data = reader.ReadBytes((int)compSize - 4);
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case CompressionType.None:
|
case CompressionType.None:
|
||||||
return reader.ReadBytes((int)decompSize);
|
return data;
|
||||||
//LZSS with byte, short, and uint types
|
//LZSS with byte, short, and uint types
|
||||||
case CompressionType.LZSS_8: return DecompressLZSS(data, 1, decompSize);
|
case CompressionType.LZSS_8: return DecompressLZSS(data, 1, decompSize);
|
||||||
case CompressionType.LZSS_16: return DecompressLZSS(data, 2, decompSize);
|
case CompressionType.LZSS_16: return DecompressLZSS(data, 2, decompSize);
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace DKCTF
|
||||||
for (int i = 0; i < numEntries; i++)
|
for (int i = 0; i < numEntries; i++)
|
||||||
{
|
{
|
||||||
DirectoryAssetEntry entry = new DirectoryAssetEntry();
|
DirectoryAssetEntry entry = new DirectoryAssetEntry();
|
||||||
entry.Read(reader);
|
entry.Read(reader, this.FileHeader);
|
||||||
Assets.Add(entry);
|
Assets.Add(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,8 @@ namespace DKCTF
|
||||||
var id = IOFileExtension.ReadID(reader);
|
var id = IOFileExtension.ReadID(reader);
|
||||||
|
|
||||||
uint offset = reader.ReadUInt32();
|
uint offset = reader.ReadUInt32();
|
||||||
MetaOffsets.Add(id.ToString(), offset);
|
if (!MetaOffsets.ContainsKey(id.ToString()))
|
||||||
|
MetaOffsets.Add(id.ToString(), offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,14 +119,27 @@ namespace DKCTF
|
||||||
public CObjectId FileID;
|
public CObjectId FileID;
|
||||||
|
|
||||||
public long Offset;
|
public long Offset;
|
||||||
|
public long DecompressedSize;
|
||||||
public long Size;
|
public long Size;
|
||||||
|
|
||||||
public void Read(FileReader reader)
|
public void Read(FileReader reader, CFormDescriptor header)
|
||||||
{
|
{
|
||||||
Type = reader.ReadString(4, Encoding.ASCII);
|
Type = reader.ReadString(4, Encoding.ASCII);
|
||||||
FileID = IOFileExtension.ReadID(reader);
|
FileID = IOFileExtension.ReadID(reader);
|
||||||
Offset = reader.ReadInt64();
|
if (header.VersionA >= 1 && header.VersionB >= 1)
|
||||||
Size = reader.ReadInt64();
|
{
|
||||||
|
long flag1 = reader.ReadUInt32();
|
||||||
|
long flag2 = reader.ReadUInt32();
|
||||||
|
Offset = reader.ReadInt64();
|
||||||
|
DecompressedSize = reader.ReadInt64();
|
||||||
|
Size = reader.ReadInt64();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Offset = reader.ReadInt64();
|
||||||
|
Size = reader.ReadInt64();
|
||||||
|
DecompressedSize = Size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ namespace DKCTF
|
||||||
|
|
||||||
public uint Unknown { get; set; }
|
public uint Unknown { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public bool IsSwitch => this.FileHeader.VersionA >= 0x0F;
|
public bool IsSwitch => this.FileHeader.VersionA >= 0x0F;
|
||||||
|
|
||||||
public TXTR() { }
|
public TXTR() { }
|
||||||
|
@ -35,34 +34,57 @@ namespace DKCTF
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] CreateUncompressedFile(byte[] fileData)
|
public byte[] CreateUncompressedFile(byte[] fileData, CFormDescriptor pakHeader, bool isLittleEndian)
|
||||||
{
|
{
|
||||||
var mem = new MemoryStream();
|
var mem = new MemoryStream();
|
||||||
using (var writer = new FileWriter(mem))
|
using (var writer = new FileWriter(mem))
|
||||||
using (var reader = new FileReader(fileData))
|
using (var reader = new FileReader(fileData))
|
||||||
{
|
{
|
||||||
writer.SetByteOrder(true);
|
reader.SetByteOrder(!isLittleEndian);
|
||||||
reader.SetByteOrder(true);
|
writer.SetByteOrder(!isLittleEndian);
|
||||||
|
|
||||||
FileHeader = reader.ReadStruct<CFormDescriptor>();
|
FileHeader = reader.ReadStruct<CFormDescriptor>();
|
||||||
ReadMetaFooter(reader);
|
ReadMetaFooter(reader);
|
||||||
|
|
||||||
|
//Rewrite header for saving uncompressed file
|
||||||
reader.Position = 0;
|
reader.Position = 0;
|
||||||
byte[] textureInfo = reader.ReadBytes((int)Meta.GPUOffset + 24);
|
byte[] textureInfo = reader.ReadBytes((int)Meta.GPUOffset + 24);
|
||||||
|
|
||||||
long pos = reader.BaseStream.Position - 24;
|
long pos = reader.BaseStream.Position - 24;
|
||||||
|
|
||||||
var buffer = Meta.BufferInfo[0];
|
List<byte[]> combinedBuffer = new List<byte[]>();
|
||||||
reader.Seek(buffer.Offset);
|
|
||||||
|
|
||||||
byte[] BufferData = IOFileExtension.DecompressedBuffer(reader, buffer.CompressedSize, buffer.DecompressedSize, IsSwitch);
|
byte[] textureData = new byte[Meta.DecompressedSize];
|
||||||
|
|
||||||
|
if (pakHeader.VersionA >= 1 && pakHeader.VersionB >= 1)
|
||||||
|
{
|
||||||
|
//Decompress all buffers
|
||||||
|
foreach (var info in Meta.TextureInfo)
|
||||||
|
{
|
||||||
|
var buff = Meta.BufferInfo[info.Index];
|
||||||
|
|
||||||
|
//Go to the buffer
|
||||||
|
reader.SeekBegin(info.StartOffset + buff.StartOffset);
|
||||||
|
//Decompress the buffer
|
||||||
|
byte[] BufferData = IOFileExtension.DecompressedBuffer(reader, buff.CompressedSize, buff.DestSize, IsSwitch || isLittleEndian);
|
||||||
|
combinedBuffer.Add(BufferData);
|
||||||
|
|
||||||
|
Array.Copy(BufferData, 0, textureData, (int)buff.DestOffset, (int)buff.DestSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var buffer = Meta.BufferInfoV1[0];
|
||||||
|
reader.SeekBegin(Meta.GPUDataStart + buffer.Offset);
|
||||||
|
|
||||||
|
textureData = IOFileExtension.DecompressedBuffer(reader, buffer.CompressedSize, buffer.DecompressedSize, IsSwitch);
|
||||||
|
}
|
||||||
|
|
||||||
writer.Write(textureInfo);
|
writer.Write(textureInfo);
|
||||||
writer.Write(BufferData);
|
writer.Write(textureData);
|
||||||
|
|
||||||
using (writer.TemporarySeek(pos + 4, SeekOrigin.Begin))
|
using (writer.TemporarySeek(pos + 4, SeekOrigin.Begin)) {
|
||||||
{
|
writer.Write((long)textureData.Length);
|
||||||
writer.Write((long)BufferData.Length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mem.ToArray();
|
return mem.ToArray();
|
||||||
|
@ -84,9 +106,8 @@ namespace DKCTF
|
||||||
if (Meta != null)
|
if (Meta != null)
|
||||||
{
|
{
|
||||||
var buffer = Meta.BufferInfo[0];
|
var buffer = Meta.BufferInfo[0];
|
||||||
|
reader.SeekBegin(buffer.StartOffset);
|
||||||
reader.Seek(buffer.Offset);
|
BufferData = IOFileExtension.DecompressedBuffer(reader, (uint)buffer.CompressedSize, (uint)buffer.DestSize, IsSwitch);
|
||||||
BufferData = IOFileExtension.DecompressedBuffer(reader, buffer.CompressedSize, buffer.DecompressedSize, IsSwitch);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -96,33 +117,63 @@ namespace DKCTF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ReadMetaData(FileReader reader)
|
public override void ReadMetaData(FileReader reader, CFormDescriptor pakVersion)
|
||||||
{
|
{
|
||||||
Meta = new SMetaData();
|
Meta = new SMetaData();
|
||||||
Meta.Unknown = reader.ReadUInt32();
|
// MPR
|
||||||
Meta.AllocCategory = reader.ReadUInt32();
|
if (pakVersion.VersionA >= 1 && pakVersion.VersionB >= 1)
|
||||||
Meta.GPUOffset = reader.ReadUInt32();
|
{
|
||||||
Meta.BaseAlignment = reader.ReadUInt32();
|
reader.ReadUInt32(); //Extra uint in MPR
|
||||||
Meta.GPUDataStart = reader.ReadUInt32();
|
Meta.Unknown = reader.ReadUInt32();
|
||||||
Meta.GPUDataSize = reader.ReadUInt32();
|
Meta.AllocCategory = reader.ReadUInt32();
|
||||||
Meta.BufferInfo = IOFileExtension.ReadList<SCompressedBufferInfo>(reader);
|
Meta.GPUOffset = reader.ReadUInt32();
|
||||||
|
Meta.BaseAlignment = reader.ReadUInt32();
|
||||||
|
Meta.DecompressedSize = reader.ReadUInt32(); //total decomp size
|
||||||
|
Meta.TextureInfo = IOFileExtension.ReadList<STextureInfo>(reader);
|
||||||
|
Meta.BufferInfo = IOFileExtension.ReadList<SCompressedBufferInfo>(reader);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Meta.Unknown = reader.ReadUInt32();
|
||||||
|
Meta.AllocCategory = reader.ReadUInt32();
|
||||||
|
Meta.GPUOffset = reader.ReadUInt32();
|
||||||
|
Meta.BaseAlignment = reader.ReadUInt32();
|
||||||
|
Meta.GPUDataStart = reader.ReadUInt32();
|
||||||
|
Meta.GPUDataSize = reader.ReadUInt32();
|
||||||
|
Meta.BufferInfoV1 = IOFileExtension.ReadList<SCompressedBufferInfoV1>(reader);
|
||||||
|
}
|
||||||
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteMetaData(FileWriter writer)
|
public override void WriteMetaData(FileWriter writer, CFormDescriptor pakVersion)
|
||||||
{
|
{
|
||||||
writer.Write(Meta.Unknown);
|
if (pakVersion.VersionA >= 1 && pakVersion.VersionB >= 1)
|
||||||
writer.Write(Meta.AllocCategory);
|
{
|
||||||
writer.Write(Meta.GPUOffset);
|
writer.Write(Meta.Unknown);
|
||||||
writer.Write(Meta.BaseAlignment);
|
writer.Write(0);
|
||||||
writer.Write(Meta.GPUDataStart);
|
writer.Write(Meta.AllocCategory);
|
||||||
writer.Write(Meta.GPUDataSize);
|
writer.Write(Meta.GPUOffset);
|
||||||
IOFileExtension.WriteList(writer, Meta.BufferInfo);
|
writer.Write(Meta.BaseAlignment);
|
||||||
|
writer.Write(Meta.DecompressedSize);
|
||||||
|
IOFileExtension.WriteList(writer, Meta.TextureInfo);
|
||||||
|
IOFileExtension.WriteList(writer, Meta.BufferInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.Write(Meta.Unknown);
|
||||||
|
writer.Write(Meta.AllocCategory);
|
||||||
|
writer.Write(Meta.GPUOffset);
|
||||||
|
writer.Write(Meta.BaseAlignment);
|
||||||
|
writer.Write(Meta.GPUDataStart);
|
||||||
|
writer.Write(Meta.GPUDataSize);
|
||||||
|
IOFileExtension.WriteList(writer, Meta.BufferInfoV1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public class STextureHeader
|
public class STextureHeader
|
||||||
{
|
{
|
||||||
public uint Type;
|
public uint Type; //1 = 2D 3 = Cubemap
|
||||||
public uint Format;
|
public uint Format;
|
||||||
public uint Width;
|
public uint Width;
|
||||||
public uint Height;
|
public uint Height;
|
||||||
|
@ -135,16 +186,38 @@ namespace DKCTF
|
||||||
public class SMetaData
|
public class SMetaData
|
||||||
{
|
{
|
||||||
public uint Unknown; //4
|
public uint Unknown; //4
|
||||||
|
public uint Unknown2;
|
||||||
public uint AllocCategory;
|
public uint AllocCategory;
|
||||||
public uint GPUOffset;
|
public uint GPUOffset;
|
||||||
public uint BaseAlignment;
|
|
||||||
public uint GPUDataStart;
|
public uint GPUDataStart;
|
||||||
public uint GPUDataSize;
|
public uint GPUDataSize;
|
||||||
|
public uint BaseAlignment;
|
||||||
|
public uint DecompressedSize;
|
||||||
|
public List<STextureInfo> TextureInfo = new List<STextureInfo>();
|
||||||
public List<SCompressedBufferInfo> BufferInfo = new List<SCompressedBufferInfo>();
|
public List<SCompressedBufferInfo> BufferInfo = new List<SCompressedBufferInfo>();
|
||||||
|
public List<SCompressedBufferInfoV1> BufferInfoV1 = new List<SCompressedBufferInfoV1>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
public class STextureInfo
|
||||||
|
{
|
||||||
|
public byte Index;
|
||||||
|
public uint StartOffset;
|
||||||
|
public uint EndOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public class SCompressedBufferInfo
|
public class SCompressedBufferInfo
|
||||||
|
{
|
||||||
|
public uint Index;
|
||||||
|
public uint StartOffset;
|
||||||
|
public uint CompressedSize;
|
||||||
|
public uint DestOffset;
|
||||||
|
public uint DestSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
public class SCompressedBufferInfoV1
|
||||||
{
|
{
|
||||||
public uint DecompressedSize;
|
public uint DecompressedSize;
|
||||||
public uint CompressedSize;
|
public uint CompressedSize;
|
||||||
|
|
|
@ -58,9 +58,14 @@ namespace DKCTF
|
||||||
public Dictionary<string, CHAR> CharFiles = new Dictionary<string, CHAR>();
|
public Dictionary<string, CHAR> CharFiles = new Dictionary<string, CHAR>();
|
||||||
public Dictionary<string, FileEntry> AnimFiles = new Dictionary<string, FileEntry>();
|
public Dictionary<string, FileEntry> AnimFiles = new Dictionary<string, FileEntry>();
|
||||||
|
|
||||||
|
public PACK PakData;
|
||||||
|
|
||||||
|
internal bool IsMPR;
|
||||||
|
|
||||||
public void Load(System.IO.Stream stream)
|
public void Load(System.IO.Stream stream)
|
||||||
{
|
{
|
||||||
PACK pack = new PACK(stream);
|
PACK pack = new PACK(stream);
|
||||||
|
PakData = pack;
|
||||||
|
|
||||||
for (int i = 0; i < pack.Assets.Count; i++)
|
for (int i = 0; i < pack.Assets.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -124,12 +129,13 @@ namespace DKCTF
|
||||||
if (file.AssetEntry.Type == "ANIM") file.FileName = file.FileName.Replace("exportData", "animations");
|
if (file.AssetEntry.Type == "ANIM") file.FileName = file.FileName.Replace("exportData", "animations");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
files = files.OrderBy(x => x.FileName).ToList();
|
// files = files.OrderBy(x => x.FileName).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<string, string> DirectoryLabels = new Dictionary<string, string>()
|
Dictionary<string, string> DirectoryLabels = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "CHAR", "Characters" },
|
{ "CHAR", "Characters" },
|
||||||
|
{ "CHPR", "Character Project" },
|
||||||
{ "CMDL", "Static Models" },
|
{ "CMDL", "Static Models" },
|
||||||
{ "SMDL", "Skinned Models" },
|
{ "SMDL", "Skinned Models" },
|
||||||
{ "TXTR", "Textures" },
|
{ "TXTR", "Textures" },
|
||||||
|
@ -185,14 +191,20 @@ namespace DKCTF
|
||||||
|
|
||||||
using (var reader = new FileReader(SubData, true))
|
using (var reader = new FileReader(SubData, true))
|
||||||
{
|
{
|
||||||
Data.Add(reader.ReadBytes((int)reader.BaseStream.Length));
|
var data = reader.ReadBytes((int)reader.BaseStream.Length);
|
||||||
|
|
||||||
|
reader.Position = 0;
|
||||||
|
if (AssetEntry.DecompressedSize != AssetEntry.Size)
|
||||||
|
data = IOFileExtension.DecompressedBuffer(reader, (uint)AssetEntry.Size, (uint)AssetEntry.DecompressedSize, true);
|
||||||
|
|
||||||
|
Data.Add(data);
|
||||||
|
|
||||||
if (WriteMetaData)
|
if (WriteMetaData)
|
||||||
{
|
{
|
||||||
using (var r = new FileReader(ArchiveStream, true)) {
|
using (var r = new FileReader(ArchiveStream, true)) {
|
||||||
r.SetByteOrder(true);
|
r.SetByteOrder(!ParentArchive.PakData.IsLittleEndian);
|
||||||
|
|
||||||
Data.Add(FileForm.WriteMetaFooter(r, (uint)MetaPointer, AssetEntry.Type));
|
Data.Add(FileForm.WriteMetaFooter(r, (uint)MetaPointer, AssetEntry.Type, ParentArchive.PakData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +212,7 @@ namespace DKCTF
|
||||||
if (AssetEntry.Type == "TXTR")
|
if (AssetEntry.Type == "TXTR")
|
||||||
{
|
{
|
||||||
var txt = new TXTR();
|
var txt = new TXTR();
|
||||||
return txt.CreateUncompressedFile(Utils.CombineByteArray(Data.ToArray()));
|
return txt.CreateUncompressedFile(Utils.CombineByteArray(Data.ToArray()), ParentArchive.PakData.FileHeader, ParentArchive.PakData.IsMPR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -255,7 +267,7 @@ namespace DKCTF
|
||||||
}
|
}
|
||||||
if (file is CCharacter)
|
if (file is CCharacter)
|
||||||
((CCharacter)file).LoadModels(pak);
|
((CCharacter)file).LoadModels(pak);
|
||||||
|
|
||||||
this.FileFormat = file;
|
this.FileFormat = file;
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace Toolbox.Library.Forms
|
||||||
{
|
{
|
||||||
if (genericObjects.Count == 0) return;
|
if (genericObjects.Count == 0) return;
|
||||||
|
|
||||||
|
|
||||||
foreach (var genericObject in genericObjects)
|
foreach (var genericObject in genericObjects)
|
||||||
{
|
{
|
||||||
int divisions = 4;
|
int divisions = 4;
|
||||||
|
@ -83,8 +84,6 @@ namespace Toolbox.Library.Forms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine($"displayFaceSize {f.Count} {displayFaceSize} {genericObject.vertices.Count }");
|
|
||||||
|
|
||||||
for (int v = 0; v < displayFaceSize; v += 3)
|
for (int v = 0; v < displayFaceSize; v += 3)
|
||||||
{
|
{
|
||||||
if (displayFaceSize < 3 || genericObject.vertices.Count < 3)
|
if (displayFaceSize < 3 || genericObject.vertices.Count < 3)
|
||||||
|
|
|
@ -202,13 +202,22 @@ namespace Toolbox.Library.Forms
|
||||||
{
|
{
|
||||||
if (meshesCB.SelectedIndex >= 0)
|
if (meshesCB.SelectedIndex >= 0)
|
||||||
{
|
{
|
||||||
uvViewport1.ActiveObjects.Clear();
|
|
||||||
|
|
||||||
if (Objects.Count > meshesCB.SelectedIndex)
|
|
||||||
uvViewport1.ActiveObjects.Add(Objects[meshesCB.SelectedIndex]);
|
|
||||||
|
|
||||||
ActiveMaterial = Materials[meshesCB.SelectedIndex];
|
ActiveMaterial = Materials[meshesCB.SelectedIndex];
|
||||||
|
|
||||||
|
uvViewport1.ActiveObjects.Clear();
|
||||||
|
foreach (var obj in Objects)
|
||||||
|
{
|
||||||
|
if (obj.GetMaterial() == ActiveMaterial)
|
||||||
|
uvViewport1.ActiveObjects.Add(obj);
|
||||||
|
|
||||||
|
foreach (var p in obj.PolygonGroups)
|
||||||
|
{
|
||||||
|
if (p.Material == ActiveMaterial && !uvViewport1.ActiveObjects.Contains(obj))
|
||||||
|
uvViewport1.ActiveObjects.Add(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ChannelTextures.Clear();
|
ChannelTextures.Clear();
|
||||||
Textures.Clear();
|
Textures.Clear();
|
||||||
textureCB.Items.Clear();
|
textureCB.Items.Clear();
|
||||||
|
@ -235,6 +244,8 @@ namespace Toolbox.Library.Forms
|
||||||
|
|
||||||
if (textureCB.Items.Count > 0)
|
if (textureCB.Items.Count > 0)
|
||||||
textureCB.SelectedIndex = 0;
|
textureCB.SelectedIndex = 0;
|
||||||
|
|
||||||
|
uvViewport1.UpdateViewport();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue