diff --git a/Switch_FileFormatsMain/FileFormats/BARS.cs b/Switch_FileFormatsMain/FileFormats/BARS.cs index 221edab6..5144204b 100644 --- a/Switch_FileFormatsMain/FileFormats/BARS.cs +++ b/Switch_FileFormatsMain/FileFormats/BARS.cs @@ -117,26 +117,33 @@ namespace FirstPlugin if (ofd.ShowDialog() == DialogResult.OK) { Data = File.ReadAllBytes(ofd.FileName); + UpdateEditor(); } } + public void UpdateEditor() + { + if (Viewport.Instance.gL_ControlModern1.Visible == false) + PluginRuntime.FSHPDockState = WeifenLuo.WinFormsUI.Docking.DockState.Document; + + BFAVEditor docked = (BFAVEditor)LibraryGUI.Instance.GetContentDocked(new BFAVEditor()); + if (docked == null) + { + docked = new BFAVEditor(); + LibraryGUI.Instance.LoadDockContent(docked, PluginRuntime.FSHPDockState); + } + docked.Text = Text; + docked.Dock = DockStyle.Fill; + docked.LoadFile(this); + } public override void OnClick(TreeView treeview) { if (Type == AudioType.Bfwav) { - LoadBFWAVEditor(); + UpdateEditor(); } - } - private void LoadBFWAVEditor() - { - BFAVEditor BFAVEditor = new BFAVEditor(); - BFAVEditor.Text = Text; - BFAVEditor.Dock = DockStyle.Fill; - BFAVEditor.LoadFile(this); - LibraryGUI.Instance.LoadDockContent(BFAVEditor, PluginRuntime.FSHPDockState); - } - public bool EditorIsActive(DockContent dock) + } bool EditorIsActive(DockContent dock) { foreach (Control ctrl in dock.Controls) { diff --git a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/FMDL.cs b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/FMDL.cs index 4808fb3b..8cd0f73a 100644 --- a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/FMDL.cs +++ b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/FMDL.cs @@ -433,7 +433,6 @@ namespace Bfres.Structs shape.VertexBufferIndex = shapes.Count; shape.vertices = obj.vertices; shape.MaterialIndex = 0; - shape.VertexSkinCount = obj.GetMaxSkinInfluenceCount(); shape.vertexAttributes = csvsettings.CreateNewAttributes(); shape.boneIndx = 0; shape.Text = obj.ObjectName; @@ -441,6 +440,7 @@ namespace Bfres.Structs shape.CreateNewBoundingBoxes(); shape.CreateBoneList(obj, this); shape.CreateIndexList(obj, this); + shape.VertexSkinCount = obj.GetMaxSkinInfluenceCount(); shape.ApplyImportSettings(csvsettings, GetMaterial(shape.MaterialIndex)); shape.SaveShape(); shape.SaveVertexBuffer(); diff --git a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/FSHP.cs b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/FSHP.cs index fefc4bf4..25dc59b0 100644 --- a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/FSHP.cs +++ b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/FSHP.cs @@ -819,8 +819,8 @@ namespace Bfres.Structs // vtx.nrm = TransformLocal(vtx.nrm, false); // Console.WriteLine("New " + vtx.pos); } - // Console.WriteLine($"Weight count {vtx.boneWeights.Count}"); - // Console.WriteLine($"Index count {vtx.boneIds.Count}"); + //Console.WriteLine($"Weight count {vtx.boneWeights.Count}"); + //Console.WriteLine($"Index count {vtx.boneIds.Count}"); verts.Add(new Syroot.Maths.Vector4F(vtx.pos.X, vtx.pos.Y, vtx.pos.Z, 1.0f)); norms.Add(new Syroot.Maths.Vector4F(vtx.nrm.X, vtx.nrm.Y, vtx.nrm.Z, 0)); diff --git a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/ResourceFile.cs b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/ResourceFile.cs index a175094a..c7e7ecad 100644 --- a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/ResourceFile.cs +++ b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/ResourceFile.cs @@ -272,9 +272,6 @@ namespace Bfres.Structs } private void AddFTEXTextures(ResU.ResFile resFile) { - MessageBox.Show("Note! Textures are disabled atm."); - return; - FTEXContainer ftexContainer = new FTEXContainer(); Nodes.Add(ftexContainer); foreach (ResU.Texture tex in resFile.Textures.Values) @@ -285,7 +282,7 @@ namespace Bfres.Structs ftexContainer.Nodes.Add(texture); ftexContainer.Textures.Add(texture.Text, texture); } - PluginRuntime.ftexContainers.Add(ftexContainer); + // PluginRuntime.ftexContainers.Add(ftexContainer); } private void AddSkeletonAnims(ResU.ResFile resFile) { diff --git a/Switch_FileFormatsMain/FileFormats/CsvModels.cs b/Switch_FileFormatsMain/FileFormats/CsvModels.cs index 7ed45809..eefb90cd 100644 --- a/Switch_FileFormatsMain/FileFormats/CsvModels.cs +++ b/Switch_FileFormatsMain/FileFormats/CsvModels.cs @@ -277,6 +277,17 @@ namespace FirstPlugin foreach (float f in obj.weightsT[v]) obj.vertices[v].boneWeights.Add(f); } + foreach (Vertex v in obj.vertices) + { + if (v.boneNames.Count == 1) + Console.WriteLine($"{v.boneNames[0]} {v.boneWeights[0]}"); + if (v.boneNames.Count == 2) + Console.WriteLine($"{v.boneNames[0]} {v.boneWeights[0]} {v.boneNames[1]} {v.boneWeights[1]}"); + if (v.boneNames.Count == 3) + Console.WriteLine($"{v.boneNames[0]} {v.boneWeights[0]} {v.boneNames[1]} {v.boneWeights[1]} {v.boneNames[2]} {v.boneWeights[2]}"); + if (v.boneNames.Count == 4) + Console.WriteLine($"{v.boneNames[0]} {v.boneWeights[0]} {v.boneNames[1]} {v.boneWeights[1]} {v.boneNames[2]} {v.boneWeights[2]} {v.boneNames[3]} {v.boneWeights[3]}"); + } } csv.Close(); diff --git a/Switch_FileFormatsMain/FileFormats/Texture/BNTX.cs b/Switch_FileFormatsMain/FileFormats/Texture/BNTX.cs index d6f05067..88773af5 100644 --- a/Switch_FileFormatsMain/FileFormats/Texture/BNTX.cs +++ b/Switch_FileFormatsMain/FileFormats/Texture/BNTX.cs @@ -803,6 +803,9 @@ namespace FirstPlugin } public void UpdateBNTXEditor() { + if (Viewport.Instance.gL_ControlModern1.Visible == false) + PluginRuntime.FSHPDockState = WeifenLuo.WinFormsUI.Docking.DockState.Document; + BNTXEditor docked = (BNTXEditor)LibraryGUI.Instance.GetContentDocked(new BNTXEditor()); if (docked == null) { diff --git a/Switch_FileFormatsMain/FileFormats/Texture/FTEX.cs b/Switch_FileFormatsMain/FileFormats/Texture/FTEX.cs index 53004303..3cbf0f4d 100644 --- a/Switch_FileFormatsMain/FileFormats/Texture/FTEX.cs +++ b/Switch_FileFormatsMain/FileFormats/Texture/FTEX.cs @@ -174,11 +174,28 @@ namespace FirstPlugin GTX.GX2Surface surf = new GTX.GX2Surface(); surf.bpp = bpp; + surf.height = (int)tex.Height; + surf.width = (int)tex.Width; + surf.aa = (int)tex.AAMode; + surf.alignment = (int)tex.Alignment; + surf.depth = (int)tex.Depth; + surf.dim = (int)tex.Dim; + surf.format = (int)tex.Format; + surf.use = (int)tex.Use; + surf.pitch = (int)tex.Pitch; + surf.data = tex.Data; + surf.numMips = (int)tex.MipCount; + surf.mipOffset = tex.MipOffsets; + surf.mipData = tex.MipData; + surf.tileMode = (int)tex.TileMode; + surf.swizzle = (int)tex.Swizzle; - for (int surfaceLevel = 0; surfaceLevel < tex.ArrayLength; surfaceLevel++) - { - } - GTX.Decode(surf, tex.MipData); + List mips = GTX.Decode(surf); + renderedTex.mipmaps.Add(mips); + + // LoadOpenGLTexture(); + // else + // Console.WriteLine("Failed to load image!"); } public void Export(string FileName, bool ExportSurfaceLevel = false, diff --git a/Switch_FileFormatsMain/FileFormats/Texture/GTX.cs b/Switch_FileFormatsMain/FileFormats/Texture/GTX.cs index a387f5af..3150330b 100644 --- a/Switch_FileFormatsMain/FileFormats/Texture/GTX.cs +++ b/Switch_FileFormatsMain/FileFormats/Texture/GTX.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; -using Switch_Toolbox.Library.IO; using System.Text; namespace FirstPlugin @@ -19,54 +18,54 @@ namespace FirstPlugin GeometryShaderProgram = 0x09, } - public class GTXHeader - { - public uint MajorVersion; - public uint MinorVersion; - public uint GpuVersion; - public uint AlignMode; - - public void Read(FileReader reader) + /* public class GTXHeader { - string Signature = reader.ReadString(4, Encoding.ASCII); - if (Signature != "Gfx2") - throw new Exception($"Invalid signature {Signature}! Expected Gfx2."); + public uint MajorVersion; + public uint MinorVersion; + public uint GpuVersion; + public uint AlignMode; - uint HeaderSize = reader.ReadUInt32(); - MajorVersion = reader.ReadUInt32(); - MinorVersion = reader.ReadUInt32(); - GpuVersion = reader.ReadUInt32(); - AlignMode = reader.ReadUInt32(); - uint Reserved = reader.ReadUInt32(); - uint Reserved2 = reader.ReadUInt32(); + public void Read(FileReader reader) + { + string Signature = reader.ReadString(4, Encoding.ASCII); + if (Signature != "Gfx2") + throw new Exception($"Invalid signature {Signature}! Expected Gfx2."); + + uint HeaderSize = reader.ReadUInt32(); + MajorVersion = reader.ReadUInt32(); + MinorVersion = reader.ReadUInt32(); + GpuVersion = reader.ReadUInt32(); + AlignMode = reader.ReadUInt32(); + uint Reserved = reader.ReadUInt32(); + uint Reserved2 = reader.ReadUInt32(); + } + public void Write(FileWriter reader) + { + } } - public void Write(FileWriter reader) + public class GTXDataBlock { - } - } - public class GTXDataBlock - { - public uint MajorVersion; - public uint MinorVersion; - public BlockType BlockType; - public uint Identifier; - public uint index; + public uint MajorVersion; + public uint MinorVersion; + public BlockType BlockType; + public uint Identifier; + public uint index; - public void Read(FileReader reader, GTXHeader header) - { - string Signature = reader.ReadString(4, Encoding.ASCII); - if (Signature != "BLK") - throw new Exception($"Invalid signature {Signature}! Expected BLK."); - uint HeaderSize = reader.ReadUInt32(); + public void Read(FileReader reader, GTXHeader header) + { + string Signature = reader.ReadString(4, Encoding.ASCII); + if (Signature != "BLK") + throw new Exception($"Invalid signature {Signature}! Expected BLK."); + uint HeaderSize = reader.ReadUInt32(); - MajorVersion = reader.ReadUInt32(); //Must be 0x01 for 6.x.x - MinorVersion = reader.ReadUInt32(); //Must be 0x00 for 6.x.x - BlockType = reader.ReadEnum(false); - uint DataSize = reader.ReadUInt32(); - Identifier = reader.ReadUInt32(); - index = reader.ReadUInt32(); - } - } + MajorVersion = reader.ReadUInt32(); //Must be 0x01 for 6.x.x + MinorVersion = reader.ReadUInt32(); //Must be 0x00 for 6.x.x + BlockType = reader.ReadEnum(false); + uint DataSize = reader.ReadUInt32(); + Identifier = reader.ReadUInt32(); + index = reader.ReadUInt32(); + } + }*/ public class GTX { //From https://github.com/jam1garner/Smash-Forge/blob/master/Smash%20Forge/Filetypes/Textures/GTX.cs @@ -94,56 +93,58 @@ namespace FirstPlugin public uint bpp; public byte[] data; + public byte[] mipData; - public int[] mipOffset; + public uint[] mipOffset; }; public static int m_configFlags = 4; public static int ADDR_OK = 0; - public static int expPitch = 0; - public static int expHeight = 0; - public static int expNumSlices = 0; + public static uint expPitch = 0; + public static uint expHeight = 0; + public static uint expNumSlices = 0; public class surfaceIn { - public int size = 0; - public int tileMode = 0; - public int format = 0; - public int bpp = 0; - public int numSamples = 0; - public int width = 0; - public int height = 0; - public int numSlices = 0; - public int slice = 0; - public int mipLevel = 0; + public uint size = 0; + public uint tileMode = 0; + public uint format = 0; + public uint bpp = 0; + public uint numSamples = 0; + public uint width = 0; + public uint height = 0; + public uint numSlices = 0; + public uint slice = 0; + public uint mipLevel = 0; public Flags flags = new Flags(); - public int numFrags = 0; - public TileInfo tileType = new TileInfo(); + public uint numFrags = 0; + public uint tileType = 0; + public TileInfo pTileInfo = new TileInfo(); public int tileIndex = 0; } public class surfaceOut { - public int size = 0; - public int pitch = 0; - public int height = 0; - public int depth = 0; - public int surfSize = 0; - public int tileMode = 0; - public int baseAlign = 0; - public int pitchAlign = 0; - public int heightAlign = 0; - public int depthAlign = 0; - public int bpp = 0; - public int pixelPitch = 0; - public int pixelHeight = 0; - public int pixelBits = 0; - public int sliceSize = 0; - public int pitchTileMax = 0; - public int heightTileMax = 0; - public int sliceTileMax = 0; - public int pTileInfo = 0; - public TileInfo tileType = new TileInfo(); + public uint size = 0; + public uint pitch = 0; + public uint height = 0; + public uint depth = 0; + public long surfSize = 0; + public uint tileMode = 0; + public uint baseAlign = 0; + public uint pitchAlign = 0; + public uint heightAlign = 0; + public uint depthAlign = 0; + public uint bpp = 0; + public uint pixelPitch = 0; + public uint pixelHeight = 0; + public uint pixelBits = 0; + public uint sliceSize = 0; + public uint pitchTileMax = 0; + public uint heightTileMax = 0; + public uint sliceTileMax = 0; + public uint tileType = 0; + public TileInfo pTileInfo = new TileInfo(); public int tileIndex = 0; } @@ -162,7 +163,7 @@ namespace FirstPlugin public int pipeConfig = 0; } - static surfaceIn pIn = new surfaceIn(); + static surfaceIn pIn = new surfaceIn(); static surfaceOut pOut = new surfaceOut(); public enum GX2SurfaceDimension @@ -456,9 +457,40 @@ namespace FirstPlugin ADDR_FMT_RESERVED_63 = 0x3F, }; - public static List Decode(GX2Surface tex, byte[] MipData) + public static void Debug(surfaceOut surf) + { + if (surf == null) + surf = getSurfaceInfo((GX2SurfaceFormat)0x33, 701, 77, 1, 0, 13, 1, 0); + + Console.WriteLine($"size {surf.size}"); + Console.WriteLine($"pitch {surf.pitch}"); + Console.WriteLine($"height {surf.height}"); + Console.WriteLine($"depth {surf.depth}"); + Console.WriteLine($"surfSize {surf.surfSize}"); + Console.WriteLine($"tileMode {surf.tileMode}"); + Console.WriteLine($"baseAlign {surf.baseAlign}"); + Console.WriteLine($"pitchAlign {surf.pitchAlign}"); + Console.WriteLine($"heightAlign {surf.heightAlign}"); + Console.WriteLine($"depthAlign {surf.depthAlign}"); + Console.WriteLine($"bpp {surf.bpp}"); + Console.WriteLine($"pixelPitch {surf.pixelPitch}"); + Console.WriteLine($"pixelHeight {surf.pixelHeight}"); + Console.WriteLine($"pixelBits {surf.pixelBits}"); + Console.WriteLine($"sliceSize {surf.sliceSize}"); + Console.WriteLine($"pitchTileMax {surf.pitchTileMax}"); + Console.WriteLine($"heightTileMax {surf.heightTileMax}"); + Console.WriteLine($"sliceTileMax {surf.sliceTileMax}"); + Console.WriteLine($"tileType {surf.tileType}"); + Console.WriteLine($"tileIndex {surf.tileIndex}"); + } + static bool DebugSurface = true; + + public static List Decode(GX2Surface tex) { var surfInfo = getSurfaceInfo((GX2SurfaceFormat)tex.format, tex.width, tex.height, tex.depth, (uint)tex.dim, (uint)tex.tileMode, (uint)tex.aa, 0); + + Console.WriteLine(tex.tileMode); + if (surfInfo.depth != 1) throw new Exception("Unsupported Depth!"); @@ -478,22 +510,26 @@ namespace FirstPlugin } else { - int mipOffset; + uint mipOffset; if (mipLevel == 1) - mipOffset = tex.mipOffset[mipLevel - 1] - surfInfo.surfSize; + mipOffset = (uint)(tex.mipOffset[mipLevel - 1] - surfInfo.surfSize); else - mipOffset = tex.mipOffset[mipLevel - 1]; + mipOffset = (uint)tex.mipOffset[mipLevel - 1]; + + // Console.WriteLine("mipOffset " + tex.mipOffset[mipLevel - 1]); + // Console.WriteLine("surfSize " + surfInfo.surfSize); surfInfo = getSurfaceInfo((GX2SurfaceFormat)tex.format, tex.width, tex.height, tex.depth, (uint)tex.dim, (uint)tex.tileMode, (uint)tex.aa, mipLevel); - data = new byte[surfInfo.surfSize - mipOffset]; - Array.Copy(MipData, mipOffset, data, 0, surfInfo.surfSize); + data = new byte[surfInfo.surfSize + mipOffset]; + Array.Copy(tex.mipData, mipOffset, data, 0, surfInfo.surfSize); } byte[] deswizzled = deswizzle(Math.Max(1, (uint)tex.width >> mipLevel), Math.Max(1, (uint)tex.height >> mipLevel), (uint)surfInfo.height, (uint)tex.format, (uint)surfInfo.tileMode, (uint)tex.swizzle, (uint)surfInfo.pitch, (uint)surfInfo.bpp, data); //Create a copy and use that to remove uneeded data byte[] result_ = new byte[size]; Array.Copy(deswizzled, 0, result_, 0, size); + result.Add(result_); } return result; } @@ -552,37 +588,33 @@ namespace FirstPlugin return swizzleSurf(width, height, height_, format_, tileMode, swizzle_, pitch, bpp, data, 1); } - static uint m_banks = 4; - static uint m_banksBitcount = 2; - static uint m_pipes = 2; - static uint m_pipesBitcount = 1; - static uint m_pipeInterleaveBytes = 256; - static uint m_pipeInterleaveBytesBitcount = 8; - static uint m_rowSize = 2048; - static uint m_swapSize = 256; - static uint m_splitSize = 2048; - - static uint m_chipFamily = 2; - - static uint MicroTilePixels = 64; - - private static byte[] swizzleSurf(uint width, uint height, uint height_, uint format, uint tileMode, uint swizzle_, uint pitch, uint bitsPerPixel, byte[] data, int swizzle) { - byte[] result = new byte[data.Length]; + Console.WriteLine("swizzle"); + Console.WriteLine("---------------------------"); + Console.WriteLine(width); + Console.WriteLine(height); + Console.WriteLine(height_); + Console.WriteLine(format); + Console.WriteLine(tileMode); + Console.WriteLine(swizzle_); + Console.WriteLine(pitch); + Console.WriteLine(bitsPerPixel); + Console.WriteLine(swizzle); + Console.WriteLine("---------------------------"); uint bytesPerPixel = bitsPerPixel / 8; + byte[] result = new byte[data.Length]; uint pipeSwizzle, bankSwizzle, pos_; - uint pos; + ulong pos; if (IsFormatBCN((GX2SurfaceFormat)format)) { width = (width + 3) / 4; height = (height + 3) / 4; } - pipeSwizzle = (swizzle_ >> 8) & 1; bankSwizzle = (swizzle_ >> 9) & 3; @@ -590,25 +622,21 @@ namespace FirstPlugin { for (int x = 0; x < width; x++) { - var tileGrp1 = new List { 0, 1 }; - var tileGrp2 = new List { 2, 3 }; - - - if (tileGrp1.Contains(tileMode)) + if (tileMode == 0 || tileMode == 1) pos = (uint)(y * pitch + x) * bytesPerPixel; - else if (tileGrp2.Contains(tileMode)) + else if (tileMode == 2 || tileMode == 3) { - pos = computeSurfaceAddrFromCoordMicroTiled(x, y, bitsPerPixel, pitch, tileMode); + pos = computeSurfaceAddrFromCoordMicroTiled((uint)x, (uint)y, bitsPerPixel, pitch, (AddrTileMode)tileMode); } else { - pos = computeSurfaceAddrFromCoordMacroTiled(x, y, bitsPerPixel, (int)pitch, (int)height_, (int)tileMode, (int)pipeSwizzle, (int)bankSwizzle); + pos = computeSurfaceAddrFromCoordMacroTiled((uint)x, (uint)y, bitsPerPixel, pitch, height_, (AddrTileMode)tileMode, pipeSwizzle, bankSwizzle); } - pos = 0; - pos_ = (uint)(y * width + x) * bytesPerPixel; - if (pos_ + bytesPerPixel <= data.Length && pos + bytesPerPixel <= data.Length) + pos_ = (uint)(y * width + x) * bytesPerPixel; + + if (pos_ + bytesPerPixel <= data.Length && pos + bytesPerPixel <= (ulong)data.Length) { if (swizzle == 0) { @@ -666,144 +694,24 @@ namespace FirstPlugin public static uint surfaceGetBitsPerPixel(uint surfaceFormat) { - return formatHwInfo[(surfaceFormat & 0x35) + 4]; + return formatHwInfo[(surfaceFormat & 0x3F) * 4]; } - private static uint computePipeFromCoordWoRotation(uint x, uint y) + public static uint nextPow2(uint dim) { - return ((y >> 3) ^ (x >> 3)) & 1; - } - - private static uint computeBankFromCoordWoRotation(uint x, uint y) - { - return ((y >> 5) ^ (x >> 3)) & 1 | 2 * (((y >> 4) ^ (x >> 4)) & 1); - } - - private static bool isThickMacroTiled(uint tileMode) - { - var Grp1 = new List { 7, 11, 13, 15 }; - if (Grp1.Contains(tileMode)) - return true; - - return false; - } - - private static bool isBankSwapped(uint tileMode) - { - var Grp1 = new List { 8, 9, 10, 11, 14, 15 }; - if (Grp1.Contains(tileMode)) - return true; - - return false; - } - - private static uint computeMacroTileAspectRatio(uint tileMode) - { - var Grp1 = new List { 5, 9 }; - var Grp2 = new List { 6, 10 }; - - if (Grp1.Contains(tileMode)) - return 2; - - if (Grp2.Contains(tileMode)) - return 4; - - return 1; - } - - private static uint computeSurfaceBankSwappedWidth(uint tileMode, uint bpp, uint pitch, uint numSamplers) - { - if (isBankSwapped(tileMode) == true) - return 0; - - return 0; - } - - private static uint computeSurfaceAddrFromCoordMicroTiled(int x, int y, uint bpp, uint pitch, uint tileMode) - { - return 0; //Todo - - /* uint microTileThickness = 1; - - if (tileMode == 3) - microTileThickness = 4; - - uint microTileBytes = (MicroTilePixels * microTileThickness * bpp + 7) / 8; - uint microTilesPerRow = pitch >> 3; - uint microTileIndexX = (uint)x >> 3; - uint microTileIndexY = (uint)y >> 3; - - uint microTileOffset = microTileBytes * (microTileIndexX + microTileIndexY * microTilesPerRow); - - uint pixelIndex = computePixelIndexWithinMicroTile(x, y, bpp, tileMode); - - uint pixelOffset = bpp * pixelIndex; - pixelOffset >>= 3; - - return pixelOffset + microTileOffset;*/ - } - - - - private static int getBPP(int i) - { - switch ((GX2SurfaceFormat)i) + uint newDim = 1; + if (dim < 0x7FFFFFFF) { - case GX2SurfaceFormat.GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM: - return 0x10; - case GX2SurfaceFormat.GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM: - return 0x20; - case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_UNORM: - case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_UNORM: - case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_SRGB: - case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_SNORM: - return 0x40; - case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_UNORM: - case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_UNORM: - case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_UNORM: - case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_SRGB: - case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_SRGB: - case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_SNORM: - return 0x80; + while (newDim < dim) + newDim *= 2; } - return -1; + else + newDim = 0x80000000; + + return newDim; } - - - private static uint computeSurfaceAddrFromCoordMacroTiled(int x, int y, uint bpp, int pitch, - int height, int tileMode, int pipeSwizzle, int bankSwizzle) - { - return 0; //Todo - } - - private static int computePixelIndexWithinMicroTile(int x, int y, uint bpp) - { - int bits = ((x & 4) << 1) | ((y & 2) << 3) | ((y & 4) << 3); - - if (bpp == 0x20 || bpp == 0x60) - { - bits |= (x & 1) | (x & 2) | ((y & 1) << 2); - } - else if (bpp == 0x40) - { - bits |= (x & 1) | ((y & 1) << 1) | ((x & 2) << 1); - } - else if (bpp == 0x80) - { - bits |= (y & 1) | ((x & 1) << 1) | ((x & 2) << 1); - } - - return bits; - } - - private static int getFormatBpp(int format) - { - int hwFormat = format & 0x3F; - return formatHwInfo[hwFormat * 4]; - } - - private static int computeSurfaceThickness(AddrTileMode tileMode) + private static uint computeSurfaceThickness(AddrTileMode tileMode) { switch (tileMode) { @@ -812,20 +720,60 @@ namespace FirstPlugin case AddrTileMode.ADDR_TM_2B_TILED_THICK: case AddrTileMode.ADDR_TM_3D_TILED_THICK: case AddrTileMode.ADDR_TM_3B_TILED_THICK: - { - return 4; - } + return 4; + case AddrTileMode.ADDR_TM_2D_TILED_XTHICK: case AddrTileMode.ADDR_TM_3D_TILED_XTHICK: - { - return 8; - } - } + return 8; - return 1; + default: + return 1; + } } - private static int isThickMacroTiled(AddrTileMode tileMode) + private static uint computePixelIndexWithinMicroTile(uint x, uint y, uint bpp) + { + switch (bpp) + { + case 0x08: + return (32 * ((y & 4) >> 2) | 16 * (y & 1) | 8 * ((y & 2) >> 1) | + 4 * ((x & 4) >> 2) | 2 * ((x & 2) >> 1) | x & 1); + + case 0x10: + return (32 * ((y & 4) >> 2) | 16 * ((y & 2) >> 1) | 8 * (y & 1) | + 4 * ((x & 4) >> 2) | 2 * ((x & 2) >> 1) | x & 1); + + case 0x20: + case 0x60: + return (32 * ((y & 4) >> 2) | 16 * ((y & 2) >> 1) | 8 * ((x & 4) >> 2) | + 4 * (y & 1) | 2 * ((x & 2) >> 1) | x & 1); + + case 0x40: + return (32 * ((y & 4) >> 2) | 16 * ((y & 2) >> 1) | 8 * ((x & 4) >> 2) | + 4 * ((x & 2) >> 1) | 2 * (y & 1) | x & 1); + + case 0x80: + return (32 * ((y & 4) >> 2) | 16 * ((y & 2) >> 1) | 8 * ((x & 4) >> 2) | + 4 * ((x & 2) >> 1) | 2 * (x & 1) | y & 1); + + default: + return (32 * ((y & 4) >> 2) | 16 * ((y & 2) >> 1) | 8 * ((x & 4) >> 2) | + 4 * (y & 1) | 2 * ((x & 2) >> 1) | x & 1); + } + } + + private static uint computePipeFromCoordWoRotation(uint x, uint y) + { + return ((y >> 3) ^ (x >> 3)) & 1; + } + + + private static uint computeBankFromCoordWoRotation(uint x, uint y) + { + return ((y >> 5) ^ (x >> 3)) & 1 | 2 * (((y >> 4) ^ (x >> 4)) & 1); + } + + private static uint isThickMacroTiled(AddrTileMode tileMode) { switch (tileMode) { @@ -833,15 +781,14 @@ namespace FirstPlugin case AddrTileMode.ADDR_TM_2B_TILED_THICK: case AddrTileMode.ADDR_TM_3D_TILED_THICK: case AddrTileMode.ADDR_TM_3B_TILED_THICK: - { - return 1; - } - } + return 1; - return 0; + default: + return 0; + } } - private static int isBankSwappedTileMode(AddrTileMode tileMode) + private static uint isBankSwappedTileMode(AddrTileMode tileMode) { switch (tileMode) { @@ -851,17 +798,496 @@ namespace FirstPlugin case AddrTileMode.ADDR_TM_2B_TILED_THICK: case AddrTileMode.ADDR_TM_3B_TILED_THIN1: case AddrTileMode.ADDR_TM_3B_TILED_THICK: - { - return 1; - } + return 1; + + default: + return 0; } - return 0; } - private static int computeSurfaceRotationFromTileMode(AddrTileMode tileMode) + private static uint computeMacroTileAspectRatio(AddrTileMode tileMode) { - switch ((int)tileMode) + switch (tileMode) { + case AddrTileMode.ADDR_TM_2D_TILED_THIN2: + case AddrTileMode.ADDR_TM_2B_TILED_THIN2: + return 2; + + case AddrTileMode.ADDR_TM_2D_TILED_THIN4: + case AddrTileMode.ADDR_TM_2B_TILED_THIN4: + return 4; + + default: + return 1; + } + } + + private static uint computeSurfaceBankSwappedWidth(AddrTileMode tileMode, uint bpp, uint pitch, uint numSamples) + { + if (isBankSwappedTileMode(tileMode) == 0) + return 0; + + uint bytesPerSample = 8 * bpp; + uint samplesPerTile, slicesPerTile; + + if (bytesPerSample != 0) + { + samplesPerTile = 2048 / bytesPerSample; + slicesPerTile = Math.Max(1, numSamples / samplesPerTile); + } + + else + slicesPerTile = 1; + + if (isThickMacroTiled(tileMode) != 0) + numSamples = 4; + + uint bytesPerTileSlice = numSamples * bytesPerSample / slicesPerTile; + + uint factor = computeMacroTileAspectRatio(tileMode); + uint swapTiles = Math.Max(1, 128 / bpp); + + uint swapWidth = swapTiles * 32; + uint heightBytes = numSamples * factor * bpp * 2 / slicesPerTile; + uint swapMax = 0x4000 / heightBytes; + uint swapMin = 256 / bytesPerTileSlice; + + uint bankSwapWidth = Math.Min(swapMax, Math.Max(swapMin, swapWidth)); + + while (bankSwapWidth >= 2 * pitch) + bankSwapWidth >>= 1; + + return bankSwapWidth; + } + + + private static ulong computeSurfaceAddrFromCoordMicroTiled(uint x, uint y, uint bpp, uint pitch, AddrTileMode tileMode) + { + int microTileThickness = 1; + + if (tileMode == AddrTileMode.ADDR_TM_1D_TILED_THICK) + microTileThickness = 4; + + uint microTileBytes = (uint)(64 * microTileThickness * bpp + 7) / 8; + uint microTilesPerRow = pitch >> 3; + uint microTileIndexX = x >> 3; + uint microTileIndexY = y >> 3; + + ulong microTileOffset = microTileBytes * (microTileIndexX + microTileIndexY * microTilesPerRow); + uint pixelIndex = computePixelIndexWithinMicroTile(x, y, bpp); + ulong pixelOffset = (bpp * pixelIndex) >> 3; + + return pixelOffset + microTileOffset; + } + + private static byte[] bankSwapOrder = { 0, 1, 3, 2, 6, 7, 5, 4, 0, 0 }; + + private static ulong computeSurfaceAddrFromCoordMacroTiled(uint x, uint y, uint bpp, uint pitch, uint height, + AddrTileMode tileMode, uint pipeSwizzle, uint bankSwizzle) + { + + uint sampleSlice, numSamples, samplesPerSlice; + uint numSampleSplits, bankSwapWidth, swapIndex; + + uint microTileThickness = computeSurfaceThickness(tileMode); + + uint microTileBits = bpp * (microTileThickness * 64); + uint microTileBytes = (microTileBits + 7) / 8; + + uint pixelIndex = computePixelIndexWithinMicroTile(x, y, bpp); + ulong elemOffset = bpp * pixelIndex; + + uint bytesPerSample = microTileBytes; + + if (microTileBytes <= 2048) + { + numSamples = 1; + sampleSlice = 0; + } + + else + { + samplesPerSlice = 2048 / bytesPerSample; + numSampleSplits = 1; + numSamples = samplesPerSlice; + sampleSlice = (uint)(elemOffset / (microTileBits / numSampleSplits)); + elemOffset %= microTileBits / numSampleSplits; + } + + elemOffset = (elemOffset + 7) / 8; + + uint pipe = computePipeFromCoordWoRotation(x, y); + uint bank = computeBankFromCoordWoRotation(x, y); + + uint swizzle_ = pipeSwizzle + 2 * bankSwizzle; + uint bankPipe = ((pipe + 2 * bank) ^ (6 * sampleSlice ^ swizzle_)) % 8; + + pipe = bankPipe % 2; + bank = bankPipe / 2; + + uint sliceBytes = (height * pitch * microTileThickness * bpp * numSamples + 7) / 8; + uint sliceOffset = sliceBytes * (sampleSlice / microTileThickness); + + uint macroTilePitch = 32; + uint macroTileHeight = 16; + + switch (tileMode) + { + case AddrTileMode.ADDR_TM_2D_TILED_THIN2: + case AddrTileMode.ADDR_TM_2B_TILED_THIN2: + { + macroTilePitch = 16; + macroTileHeight = 32; + break; + } + + case AddrTileMode.ADDR_TM_2D_TILED_THIN4: + case AddrTileMode.ADDR_TM_2B_TILED_THIN4: + { + macroTilePitch = 8; + macroTileHeight = 64; + break; + } + } + + uint macroTilesPerRow = pitch / macroTilePitch; + uint macroTileBytes = (numSamples * microTileThickness * bpp * macroTileHeight + * macroTilePitch + 7) / 8; + uint macroTileIndexX = x / macroTilePitch; + uint macroTileIndexY = y / macroTileHeight; + ulong macroTileOffset = (macroTileIndexX + macroTilesPerRow * macroTileIndexY) * macroTileBytes; + + switch (tileMode) + { + case AddrTileMode.ADDR_TM_2B_TILED_THIN1: + case AddrTileMode.ADDR_TM_2B_TILED_THIN2: + case AddrTileMode.ADDR_TM_2B_TILED_THIN4: + case AddrTileMode.ADDR_TM_2B_TILED_THICK: + case AddrTileMode.ADDR_TM_3B_TILED_THIN1: + case AddrTileMode.ADDR_TM_3B_TILED_THICK: + { + bankSwapWidth = computeSurfaceBankSwappedWidth(tileMode, bpp, pitch, 1); + swapIndex = macroTilePitch * macroTileIndexX / bankSwapWidth; + bank ^= bankSwapOrder[swapIndex & 3]; + break; + } + } + + ulong totalOffset = elemOffset + ((macroTileOffset + sliceOffset) >> 3); + return bank << 9 | pipe << 8 | 255 & totalOffset | (ulong)((int)totalOffset & -256) << 3; + } + + public static uint computeSurfaceMipLevelTileMode(uint baseTileMode, uint bpp, uint level, uint width, uint height, + uint numSlices, uint numSamples, uint isDepth, uint noRecursive) + { + uint widthAlignFactor = 1; + uint macroTileWidth = 32; + uint macroTileHeight = 16; + uint tileSlices = computeSurfaceTileSlices(baseTileMode, bpp, numSamples); + + + uint expTileMode, widtha, heighta, numSlicesa, thickness, microTileBytes; + expTileMode = baseTileMode; + + if (DebugSurface) + Console.WriteLine("baseTileMode " + baseTileMode); + if (baseTileMode == 7) + { + if (numSamples > 1 || tileSlices > 1 || isDepth != 0) + expTileMode = 4; + } + else if (baseTileMode == 13) + { + if (numSamples > 1 || tileSlices > 1 || isDepth != 0) + expTileMode = 12; + } + else if (baseTileMode == 11) + { + if (numSamples > 1 || tileSlices > 1 || isDepth != 0) + expTileMode = 8; + } + else if (baseTileMode == 15) + { + if (numSamples > 1 || tileSlices > 1 || isDepth != 0) + expTileMode = 14; + } + else if (baseTileMode == 2) + { + if (numSamples > 1 && ((4 >> 2) & 1) != 0) + expTileMode = 4; + } + else if (baseTileMode == 3) + { + if (numSamples > 1 || isDepth != 0) + expTileMode = 2; + + if (numSamples == 2 || numSamples == 4) + { + expTileMode = 7; + } + } + else + { + expTileMode = baseTileMode; + } + if (DebugSurface) + Console.WriteLine("computeSurfaceMipLevelTileMode expTileMode " + expTileMode); + if (expTileMode != 12 && expTileMode != 13 && expTileMode != 14 && + expTileMode != 15) + { + if (expTileMode == 12) + expTileMode = 4; + else if (expTileMode == 13) + expTileMode = 7; + else if (expTileMode == 14) + expTileMode = 8; + else if (expTileMode == 15) + expTileMode = 11; + } + if (noRecursive == 0) + { + switch (bpp) + { + case 24: + case 48: + case 96: + bpp /= 3; + break; + } + if (bpp == 24) ; + + widtha = nextPow2(width); + heighta = nextPow2(height); + numSlicesa = nextPow2(numSlices); + + if (level != 0) + { + expTileMode = convertToNonBankSwappedMode((AddrTileMode)expTileMode); + thickness = computeSurfaceThickness((AddrTileMode)expTileMode); + microTileBytes = (numSamples * bpp * (thickness << 6) + 7) >> 3; + + if (microTileBytes < 256) + { + widthAlignFactor = Math.Max(1, 256 / microTileBytes); + } + if (expTileMode == 4 || expTileMode == 12) + { + if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight) + expTileMode = 2; + } + else if (expTileMode == 5) + { + macroTileWidth = 16; + macroTileHeight = 32; + + if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight) + expTileMode = 2; + } + else if (expTileMode == 6) + { + macroTileWidth = 8; + macroTileHeight = 64; + + if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight) + expTileMode = 2; + } + else if (expTileMode == 7 || expTileMode == 13) + { + if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight) + expTileMode = 3; + } + else if (expTileMode == 3) + { + if (numSlicesa < 4) + expTileMode = 2; + } + else if (expTileMode == 7) + { + if (numSlicesa < 4) + expTileMode = 4; + } + else if (expTileMode == 13 && numSlicesa < 4) + { + expTileMode = 13; + } + + return computeSurfaceMipLevelTileMode( + expTileMode, + bpp, + level, + widtha, + heighta, + numSlicesa, + numSamples, + isDepth, + 1); + } + } + + return expTileMode; + } + private static uint computeSurfaceTileSlices(uint tileMode, uint bpp, uint numSamples) + { + uint bytePerSample = ((bpp << 6) + 7) >> 3; + uint tileSlices = 1; + uint samplePerTile; + + if (computeSurfaceThickness((AddrTileMode)tileMode) > 1) + numSamples = 4; + + if (bytePerSample != 0) + { + samplePerTile = 2048 / bytePerSample; + if (samplePerTile < numSamples) + tileSlices = Math.Max(1, numSamples / samplePerTile); + } + + return tileSlices; + } + + private static int getFillSizeFieldsFlags() + { + return (m_configFlags >> 6) & 1; + } + + private static uint ComputeSurfaceInfoEx() + { + uint tileMode = pIn.tileMode; + uint bpp = pIn.bpp; + uint numSamples = Math.Max(1, pIn.numSamples); + uint pitch = pIn.width; + Console.WriteLine("ComputeSurfaceInfoEx pitch " + pitch); + uint height = pIn.height; + uint numSlices = pIn.numSlices; + uint mipLevel = pIn.mipLevel; + Flags flags = new Flags(); + uint pPitchOut = pOut.pitch; + uint pHeightOut = pOut.height; + uint pNumSlicesOut = pOut.depth; + uint pTileModeOut = pOut.tileMode; + long pSurfSize = pOut.surfSize; + uint pBaseAlign = pOut.baseAlign; + uint pPitchAlign = pOut.pitchAlign; + uint pHeightAlign = pOut.heightAlign; + uint pDepthAlign = pOut.depthAlign; + uint padDims = 0; + uint valid = 0; + uint baseTileMode = tileMode; + + if (DebugSurface) + { + Console.WriteLine("---------------------------"); + Console.WriteLine(tileMode); + Console.WriteLine(bpp); + Console.WriteLine(numSamples); + Console.WriteLine(pitch); + Console.WriteLine(height); + Console.WriteLine(numSlices); + Console.WriteLine(mipLevel); + Console.WriteLine(flags); + Console.WriteLine(pPitchOut); + Console.WriteLine(pHeightOut); + Console.WriteLine(pNumSlicesOut); + Console.WriteLine(pTileModeOut); + Console.WriteLine(pSurfSize); + Console.WriteLine(pBaseAlign); + Console.WriteLine(pPitchAlign); + Console.WriteLine(pHeightAlign); + Console.WriteLine(pDepthAlign); + Console.WriteLine(padDims); + Console.WriteLine(valid); + Console.WriteLine(baseTileMode); + Console.WriteLine("---------------------------"); + } + + + flags.value = pIn.flags.value; + + Console.WriteLine("padDims " + padDims); + + if (((flags.value >> 4) & 1) != mipLevel) + padDims = 2; + + Console.WriteLine("padDims " + padDims); + + if (((flags.value >> 6) & 1) != 0) + tileMode = convertToNonBankSwappedMode((AddrTileMode)tileMode); + else + { + if (DebugSurface) + Console.WriteLine(tileMode); + + tileMode = computeSurfaceMipLevelTileMode( + tileMode, + bpp, + mipLevel, + pitch, + height, + numSlices, + numSamples, + (flags.value >> 1) & 1, 0); + + if (DebugSurface) + { + Console.WriteLine("---------------------------"); + Console.WriteLine(tileMode); + Console.WriteLine("---------------------------"); + } + } + + + switch (tileMode) + { + case 0: + case 1: + var compSurfInfoLinear = computeSurfaceInfoLinear( + tileMode, + bpp, + numSamples, + pitch, + height, + numSlices, + mipLevel, + padDims, + flags); + + valid = compSurfInfoLinear[0]; + pPitchOut = compSurfInfoLinear[1]; + pHeightOut = compSurfInfoLinear[2]; + pNumSlicesOut = compSurfInfoLinear[3]; + pSurfSize = compSurfInfoLinear[4]; + pBaseAlign = compSurfInfoLinear[5]; + pPitchAlign = compSurfInfoLinear[6]; + pHeightAlign = compSurfInfoLinear[7]; + pDepthAlign = compSurfInfoLinear[8]; + + pTileModeOut = tileMode; + break; + case 2: + case 3: + var compSurfInfoMicroTile = computeSurfaceInfoMicroTiled( + tileMode, + bpp, + numSamples, + pitch, + height, + numSlices, + mipLevel, + padDims, + flags); + + valid = compSurfInfoMicroTile[0]; + pPitchOut = compSurfInfoMicroTile[1]; + pHeightOut = compSurfInfoMicroTile[2]; + pNumSlicesOut = compSurfInfoMicroTile[3]; + pSurfSize = compSurfInfoMicroTile[4]; + pTileModeOut = compSurfInfoMicroTile[5]; + pBaseAlign = compSurfInfoMicroTile[6]; + pPitchAlign = compSurfInfoMicroTile[7]; + pHeightAlign = compSurfInfoMicroTile[8]; + pDepthAlign = compSurfInfoMicroTile[9]; + + break; case 4: case 5: case 6: @@ -870,449 +1296,826 @@ namespace FirstPlugin case 9: case 10: case 11: - { - return 2; - } case 12: case 13: case 14: case 15: - { - return 1; - } - } + var compSurfInfoMacoTile = computeSurfaceInfoMacroTiled( + tileMode, + baseTileMode, + bpp, + numSamples, + pitch, + height, + numSlices, + mipLevel, + padDims, + flags); - return 0; - } - - private static int computePipeFromCoordWoRotation(int x, int y) - { - int pipe = ((y >> 3) ^ (x >> 3)) & 1; - return pipe; - } - - private static int computeBankFromCoordWoRotation(int x, int y) - { - int bankBit0 = ((y / (16 * 2)) ^ (x >> 3)) & 1; - int bank = bankBit0 | 2 * (((y / (8 * 2)) ^ (x >> 4)) & 1); - - return bank; - } - - private static int computeMacroTileAspectRatio(AddrTileMode tileMode) - { - switch (tileMode) - { - case AddrTileMode.ADDR_TM_2B_TILED_THIN1: - case AddrTileMode.ADDR_TM_3D_TILED_THIN1: - case AddrTileMode.ADDR_TM_3B_TILED_THIN1: - { - return 1; - } - case AddrTileMode.ADDR_TM_2D_TILED_THIN2: - case AddrTileMode.ADDR_TM_2B_TILED_THIN2: - { - return 2; - } - case AddrTileMode.ADDR_TM_2D_TILED_THIN4: - case AddrTileMode.ADDR_TM_2B_TILED_THIN4: - { - return 4; - } - } - - return 1; - } - - private static int computeSurfaceBankSwappedWidth(AddrTileMode tileMode, int bpp, int numSamples, int pitch, int pSlicesPerTile) - { - int bankSwapWidth = 0; - int numBanks = 4; - int numPipes = 2; - int swapSize = 256; - int rowSize = 2048; - int splitSize = 2048; - int groupSize = 256; - int slicesPerTile = 1; - int bytesPerSample = 8 * bpp & 0x1FFFFFFF; - int samplesPerTile = splitSize / bytesPerSample; - - if ((splitSize / bytesPerSample) != 0) - { - slicesPerTile = numSamples / samplesPerTile; - if ((numSamples / samplesPerTile) == 0) - { - slicesPerTile = 1; - } - } - - if (pSlicesPerTile != 0) - { - pSlicesPerTile = slicesPerTile; - } - - if (isThickMacroTiled(tileMode) == 1) - { - numSamples = 4; - } - - int bytesPerTileSlice = numSamples * bytesPerSample / slicesPerTile; - - if (isBankSwappedTileMode(tileMode) == 1) - { - int v7; - int v8; - int v9; - - int factor = computeMacroTileAspectRatio(tileMode); - int swapTiles = (swapSize >> 1) / bpp; - - if (swapTiles != 0) - { - v9 = swapTiles; - } - else - { - v9 = 1; - } - - int swapWidth = v9 * 8 * numBanks; - int heightBytes = numSamples * factor * numPipes * bpp / slicesPerTile; - int swapMax = numPipes * numBanks * rowSize / heightBytes; - int swapMin = groupSize * 8 * numBanks / bytesPerTileSlice; - - if (swapMax >= swapWidth) - { - if (swapMin <= swapWidth) - { - v7 = swapWidth; - } - else - { - v7 = swapMin; - } - - v8 = v7; - } - else - { - v8 = swapMax; - } - - bankSwapWidth = v8; - - while (bankSwapWidth >= (2 * pitch)) - { - bankSwapWidth >>= 1; - } - } - - return bankSwapWidth; - } - - private static int computePixelIndexWithinMicroTile(int x, int y, int z, int bpp, AddrTileMode tileMode, int microTileType) - { - int pixelBit0 = 0; - int pixelBit1 = 0; - int pixelBit2 = 0; - int pixelBit3 = 0; - int pixelBit4 = 0; - int pixelBit5 = 0; - int pixelBit6 = 0; - int pixelBit7 = 0; - int pixelBit8 = 0; - int thickness = computeSurfaceThickness(tileMode); - - if (microTileType == 3) - { - pixelBit0 = x & 1; - pixelBit1 = y & 1; - pixelBit2 = z & 1; - pixelBit3 = (x & 2) >> 1; - pixelBit4 = (y & 2) >> 1; - pixelBit5 = (z & 2) >> 1; - pixelBit6 = (x & 4) >> 2; - pixelBit7 = (y & 4) >> 2; - } - else - { - if (microTileType != 0) - { - pixelBit0 = x & 1; - pixelBit1 = y & 1; - pixelBit2 = (x & 2) >> 1; - pixelBit3 = (y & 2) >> 1; - pixelBit4 = (x & 4) >> 2; - pixelBit5 = (y & 4) >> 2; - } - else - { - if (bpp == 0x08) - { - pixelBit0 = x & 1; - pixelBit1 = (x & 2) >> 1; - pixelBit2 = (x & 4) >> 2; - pixelBit3 = (y & 2) >> 1; - pixelBit4 = y & 1; - pixelBit5 = (y & 4) >> 2; - } - else if (bpp == 0x10) - { - pixelBit0 = x & 1; - pixelBit1 = (x & 2) >> 1; - pixelBit2 = (x & 4) >> 2; - pixelBit3 = y & 1; - pixelBit4 = (y & 2) >> 1; - pixelBit5 = (y & 4) >> 2; - } - else if (bpp == 0x20 || bpp == 0x60) - { - pixelBit0 = x & 1; - pixelBit1 = (x & 2) >> 1; - pixelBit2 = y & 1; - pixelBit3 = (x & 4) >> 2; - pixelBit4 = (y & 2) >> 1; - pixelBit5 = (y & 4) >> 2; - } - else if (bpp == 0x40) - { - pixelBit0 = x & 1; - pixelBit1 = y & 1; - pixelBit2 = (x & 2) >> 1; - pixelBit3 = (x & 4) >> 2; - pixelBit4 = (y & 2) >> 1; - pixelBit5 = (y & 4) >> 2; - } - else if (bpp == 0x80) - { - pixelBit0 = y & 1; - pixelBit1 = x & 1; - pixelBit2 = (x & 2) >> 1; - pixelBit3 = (x & 4) >> 2; - pixelBit4 = (y & 2) >> 1; - pixelBit5 = (y & 4) >> 2; - } - else - { - pixelBit0 = x & 1; - pixelBit1 = (x & 2) >> 1; - pixelBit2 = y & 1; - pixelBit3 = (x & 4) >> 2; - pixelBit4 = (y & 2) >> 1; - pixelBit5 = (y & 4) >> 2; - } - } - - if (thickness > 1) - { - pixelBit6 = z & 1; - pixelBit7 = (z & 2) >> 1; - } - } - - if (thickness == 8) - { - pixelBit8 = (z & 4) >> 2; - } - - return pixelBit0 | - (pixelBit8 << 8) | - (pixelBit7 << 7) | - (pixelBit6 << 6) | - (pixelBit5 << 5) | - (pixelBit4 << 4) | - (pixelBit3 << 3) | - (pixelBit2 << 2) | - (pixelBit1 << 1); - } - - private static int surfaceAddrFromCoordMacroTiled( - int x, int y, int slice, int sample, int bpp, - int pitch, int height, int numSamples, AddrTileMode tileMode, - int isDepth, int tileBase, int compBits, - int pipeSwizzle, int bankSwizzle - ) - { - const int numPipes = 2; - const int numBanks = 4; - const int numGroupBits = 8; - const int numPipeBits = 1; - const int numBankBits = 2; - - int microTileThickness = computeSurfaceThickness(tileMode); - int microTileBits = numSamples * bpp * (microTileThickness * (8 * 8)); - int microTileBytes = microTileBits >> 3; - int microTileType = (isDepth == 1) ? 1 : 0; - int pixelIndex = computePixelIndexWithinMicroTile(x, y, slice, bpp, tileMode, microTileType); - - int sampleOffset; - int pixelOffset; - if (isDepth == 1) - { - if (compBits != 0 && compBits != bpp) - { - sampleOffset = tileBase + compBits * sample; - pixelOffset = numSamples * compBits * pixelIndex; - } - else - { - sampleOffset = bpp * sample; - pixelOffset = numSamples * compBits * pixelIndex; - } - } - else - { - sampleOffset = sample * (microTileBits / numSamples); - pixelOffset = bpp * pixelIndex; - } - - int elemOffset = pixelOffset + sampleOffset; - int bytesPerSample = microTileBytes / numSamples; - - int samplesPerSlice; - int numSampleSplits; - int sampleSlice; - - if (numSamples <= 1 || microTileBytes <= 2048) - { - samplesPerSlice = numSamples; - numSampleSplits = 1; - sampleSlice = 0; - } - else - { - samplesPerSlice = 2048 / bytesPerSample; - numSampleSplits = numSamples / samplesPerSlice; - numSamples = samplesPerSlice; - sampleSlice = elemOffset / (microTileBits / numSampleSplits); - elemOffset %= microTileBits / numSampleSplits; - } - - elemOffset >>= 3; - - int pipe = computePipeFromCoordWoRotation(x, y); - int bank = computeBankFromCoordWoRotation(x, y); - int bankPipe = pipe + numPipes * bank; - int rotation = computeSurfaceRotationFromTileMode(tileMode); - int swizzle = pipeSwizzle + numPipes * bankSwizzle; - int sliceIn = slice; - - if (isThickMacroTiled(tileMode) == 1) - { - sliceIn >>= 2; - } - - bankPipe ^= numPipes * sampleSlice * ((numBanks >> 1) + 1) ^ (swizzle + sliceIn * rotation); - bankPipe %= numPipes * numBanks; - pipe = bankPipe % numPipes; - bank = bankPipe / numPipes; - - int sliceBytes = (height * pitch * microTileThickness * bpp * numSamples + 7) / 8; - int sliceOffset = sliceBytes * ((sampleSlice + numSampleSplits * slice) / microTileThickness); - int macroTilePitch = 8 * 4; // m_banks - int macroTileHeight = 8 * 2; // m_pipes - int v18 = (int)tileMode - 5; - - if ((int)tileMode == 5 || (int)tileMode == 9) - { - macroTilePitch >>= 1; - macroTileHeight *= 2; - } - else if ((int)tileMode == 6 || (int)tileMode == 10) - { - macroTilePitch >>= 2; - macroTileHeight *= 4; - } - - int macroTilesPerRow = pitch / macroTilePitch; - int macroTileBytes = (numSamples * microTileThickness * bpp * macroTileHeight * macroTilePitch + 7) >> 3; - int macroTileIndexX = x / macroTilePitch; - int macroTileIndexY = y / macroTileHeight; - int macroTileOffset = (x / macroTilePitch + pitch / macroTilePitch * (y / macroTileHeight)) * macroTileBytes; - - int bankSwapWidth; - int swapIndex; - int bankMask; - - byte[] bankSwapOrder = { 0, 1, 3, 2 }; - switch ((int)tileMode) - { - case 8: - case 9: - case 10: - case 11: - case 14: - case 15: - { - bankSwapWidth = computeSurfaceBankSwappedWidth(tileMode, bpp, numSamples, pitch, 0); - swapIndex = macroTilePitch * macroTileIndexX / bankSwapWidth; - bankMask = 3; // m_banks-1 - bank ^= bankSwapOrder[swapIndex & bankMask]; - } + valid = compSurfInfoMacoTile[0]; + pPitchOut = compSurfInfoMacoTile[1]; + pHeightOut = compSurfInfoMacoTile[2]; + pNumSlicesOut = compSurfInfoMacoTile[3]; + pSurfSize = compSurfInfoMacoTile[4]; + pTileModeOut = compSurfInfoMacoTile[5]; + pBaseAlign = compSurfInfoMacoTile[6]; + pPitchAlign = compSurfInfoMacoTile[7]; + pHeightAlign = compSurfInfoMacoTile[8]; + pDepthAlign = compSurfInfoMacoTile[9]; break; } - int p4 = pipe << numGroupBits; - int p5 = bank << (numPipeBits + numGroupBits); - int numSwizzleBits = numBankBits + numPipeBits; - int unk1 = (macroTileOffset + sliceOffset) >> numSwizzleBits; - int unk2 = ~((1 << numGroupBits) - 1); - int unk3 = (elemOffset + unk1) & unk2; - int groupMask = (1 << numGroupBits) - 1; - int offset1 = macroTileOffset + sliceOffset; - int unk4 = elemOffset + (offset1 >> numSwizzleBits); + pOut.pitch = pPitchOut; + pOut.height = pHeightOut; + pOut.depth = pNumSlicesOut; + pOut.tileMode = pTileModeOut; + pOut.surfSize = pSurfSize; + pOut.baseAlign = pBaseAlign; + pOut.pitchAlign = pPitchAlign; + pOut.heightAlign = pHeightAlign; + pOut.depthAlign = pDepthAlign; - int subOffset1 = unk3 << numSwizzleBits; - int subOffset2 = groupMask & unk4; + if (DebugSurface) + { + Console.WriteLine(pOut.pitch); + Console.WriteLine(pOut.height); + Console.WriteLine(pOut.depth); + Console.WriteLine(pOut.tileMode); + Console.WriteLine(pOut.surfSize); + Console.WriteLine(pOut.baseAlign); + Console.WriteLine(pOut.pitchAlign); + Console.WriteLine(pOut.heightAlign); + Console.WriteLine(pOut.depthAlign); + } + - return subOffset1 | subOffset2 | p4 | p5; + if (valid == 0) + return 3; + + + return 0; + } + private static uint[] computeSurfaceInfoLinear(uint tileMode, uint bpp, uint numSamples, uint pitch, uint height, + uint numSlices, uint mipLevel, uint padDims, Flags flags) + { + expPitch = pitch; + expHeight = height; + expNumSlices = numSlices; + + uint valid = 1; + uint microTileThickness = computeSurfaceThickness((AddrTileMode)tileMode); + + uint baseAlign, pitchAlign, heightAlign, slices; + uint pPitchOut, pHeightOut, pNumSlicesOut, pSurfSize, pBaseAlign, pPitchAlign, pHeightAlign, pDepthAlign; + + var compAllignLinear = computeSurfaceAlignmentsLinear(tileMode, bpp, flags); + baseAlign = compAllignLinear.Item1; + pitchAlign = compAllignLinear.Item2; + heightAlign = compAllignLinear.Item3; + + if ((flags.value >> 9 & 1) != mipLevel) + { + expPitch /= 3; + expPitch = nextPow2(expPitch); + } + if (mipLevel != 0) + { + expPitch = nextPow2(expPitch); + expHeight = nextPow2(expHeight); + + if (((flags.value >> 4) & 1) != 0) + { + expNumSlices = numSlices; + + if (numSlices <= 1) + padDims = 2; + else + padDims = 0; + } + else + expNumSlices = nextPow2(numSlices); + } + + var padimens = padDimensions( + tileMode, + padDims, + (flags.value >> 4) & 1, + (flags.value >> 7) & 1, + pitchAlign, + heightAlign, + microTileThickness); + + expPitch = padimens.Item1; + expHeight = padimens.Item2; + expNumSlices = padimens.Item3; + + if (((flags.value >> 9) & 1) != mipLevel) + expPitch *= 3; + + + slices = expNumSlices * numSamples / microTileThickness; + pPitchOut = expPitch; + pHeightOut = expHeight; + pNumSlicesOut = expNumSlices; + pSurfSize = (expHeight * expPitch * slices * bpp * numSamples + 7) / 8; + pBaseAlign = baseAlign; + pPitchAlign = pitchAlign; + pHeightAlign = heightAlign; + pDepthAlign = microTileThickness; + + return new uint[] { valid, pPitchOut, pHeightOut, pNumSlicesOut, pSurfSize, pBaseAlign, pPitchAlign, pHeightAlign, pDepthAlign }; + } + private static Tuple computeSurfaceAlignmentsLinear(uint tileMode, uint bpp, Flags flags) + { + uint pixelsPerPipeInterleave; + uint baseAlign, pitchAlign, heightAlign; + + if (tileMode != 0) + { + if (tileMode == 1) + { + pixelsPerPipeInterleave = 2048 / bpp; + baseAlign = 256; + pitchAlign = Math.Max(0x40, pixelsPerPipeInterleave); + heightAlign = 1; + } + else + { + baseAlign = 1; + pitchAlign = 1; + heightAlign = 1; + } + } + else + { + baseAlign = 1; + if (bpp != 1) + pitchAlign = 1; + else + pitchAlign = 8; + + heightAlign = 1; + } + pitchAlign = adjustPitchAlignment(flags, pitchAlign); + + return new Tuple(baseAlign, pitchAlign, heightAlign); + } + private static uint convertToNonBankSwappedMode(AddrTileMode tileMode) + { + switch ((uint)tileMode) + { + case 8: + return 4; + case 9: + return 5; + case 10: + return 6; + case 11: + return 7; + case 14: + return 12; + case 15: + return 13; + } + return (uint)tileMode; } - private static int getFillSizeFieldsFlags() + private static Tuple getBitsPerPixel(uint format_) { - return (m_configFlags >> 6) & 1; + uint fmtIdx = format_ * 4; + return new Tuple + (formatExInfo[fmtIdx], formatExInfo[fmtIdx + 1], + formatExInfo[fmtIdx + 2], formatExInfo[fmtIdx + 3]); } - private static void computeSurfaceInfo(surfaceIn aSurfIn, surfaceOut aSurfOut) + private static void computeSurfaceInfo(surfaceIn aSurfIn, surfaceOut pSurfOut) { - //Todo! - surfaceIn pIn = aSurfIn; - surfaceOut pOut = aSurfOut; + if (DebugSurface) + { + Console.WriteLine(" computeSurfaceInfo ------------------------------------ "); - int v4 = 0; - int v6 = 0; - int v7 = 0; - int v8 = 0; - int v10 = 0; - int v11 = 0; - int v12 = 0; - int v18 = 0; + } + + pIn = aSurfIn; + pOut = pSurfOut; TileInfo tileInfoNull = new TileInfo(); - int sliceFlags = 0; - int returnCode = 0; + uint sliceFlags = 0; + uint returnCode = 0; - if (getFillSizeFieldsFlags() == 1 && (pIn.size != 60 || pOut.size != 96)) - returnCode = 6; + uint width, height, bpp, elemMode; + uint expandY, expandX; + + elemMode = 0; if (pIn.bpp > 0x80) returnCode = 3; - if (returnCode == ADDR_OK) - { - v18 = 0; + if (DebugSurface) + Console.WriteLine("returnCode " + returnCode); + if (returnCode == 0) + { + if (DebugSurface) + { + Console.WriteLine("-------------------------------------------"); + Console.WriteLine(" computeMipLevel"); + Console.WriteLine("-------------------------------------------"); + Console.WriteLine(" pIn.width " + pIn.width); + Console.WriteLine(" pIn.height " + pIn.height); + Console.WriteLine(" pIn.numSlices " + pIn.numSlices); + } computeMipLevel(); - int width = pIn.width; - int height = pIn.height; - int bpp = pIn.bpp; - int expandX = 1; - int expandY = 1; + width = pIn.width; + height = pIn.height; + bpp = pIn.bpp; + expandX = 1; + expandY = 1; + if (DebugSurface) + { + Console.WriteLine(pIn.width); + Console.WriteLine(pIn.height); + Console.WriteLine(pIn.numSlices); + Console.WriteLine("-------------------------------------------"); + } + + if (useTileIndex(pIn.tileIndex) == 0 && pIn.pTileInfo == null) + { + if (pOut.pTileInfo != null) + pIn.pTileInfo = pOut.pTileInfo; + + else + { + pOut.pTileInfo = tileInfoNull; + pIn.pTileInfo = tileInfoNull; + } + } + pOut.pixelBits = pIn.bpp; + + if (pIn.format != 0) + { + bpp = formatExInfo[pIn.format * 4]; + expandX = formatExInfo[pIn.format * 4 + 1]; + expandY = formatExInfo[pIn.format * 4 + 2]; + elemMode = formatExInfo[pIn.format * 4 + 3]; + + if (DebugSurface) + { + Console.WriteLine($"bpp {bpp}"); + Console.WriteLine($"expandX {expandX}"); + Console.WriteLine($"expandY {expandY}"); + Console.WriteLine($"elemMode {elemMode}"); + } + + + if (elemMode == 4 && expandX == 3 && pIn.tileMode == 1) + pIn.flags.value |= 0x200; + + bpp = adjustSurfaceInfo(elemMode, expandX, expandY, bpp, width, height); + + if (DebugSurface) + { + Console.WriteLine($"width {pIn.width}"); + Console.WriteLine($"height {pIn.height}"); + Console.WriteLine($"bpp {pIn.bpp}"); + } + } + else if (pIn.bpp != 0) + { + pIn.width = Math.Max(1, pIn.width); + pIn.height = Math.Max(1, pIn.height); + } + else + returnCode = 3; + + if (returnCode == 0) + returnCode = ComputeSurfaceInfoEx(); + + if (returnCode == 0) + { + pOut.bpp = pIn.bpp; + pOut.pixelPitch = pOut.pitch; + pOut.pixelHeight = pOut.height; + + if (pIn.format != 0 && (((pIn.flags.value >> 9) & 1) == 0 || pIn.mipLevel == 0)) + bpp = restoreSurfaceInfo(elemMode, expandX, expandY, bpp); + + if (sliceFlags == 1) + pOut.sliceSize = (pOut.height * pOut.pitch * pOut.bpp * pIn.numSamples + 7) / 8; + + else if (((pIn.flags.value >> 5) & 1) != 0) + pOut.sliceSize = (uint)pOut.surfSize; + + else + { + pOut.sliceSize = (uint)pOut.surfSize / pOut.depth; + + if (pIn.slice == (pIn.numSlices - 1) && pIn.numSlices > 1) + pOut.sliceSize += pOut.sliceSize * (pOut.depth - pIn.numSlices); + } + + pOut.pitchTileMax = (pOut.pitch >> 3) - 1; + pOut.heightTileMax = (pOut.height >> 3) - 1; + pOut.sliceTileMax = (pOut.height * pOut.pitch >> 6) - 1; + } } } + private static uint[] computeSurfaceInfoMicroTiled(uint tileMode, uint bpp, uint numSamples, uint pitch, uint height, uint numSlices, uint mipLevel, uint padDims, Flags flags) + { + expPitch = pitch; + expHeight = height; + expNumSlices = numSlices; + + uint valid = 1; + uint expTileMode = tileMode; + uint microTileThickness = computeSurfaceThickness((AddrTileMode)tileMode); + uint pPitchOut, pHeightOut, pNumSlicesOut, pSurfSize, pTileModeOut, pBaseAlign, pPitchAlign, pHeightAlign, pDepthAlign; + + if (mipLevel != 0) + { + expPitch = nextPow2(pitch); + expHeight = nextPow2(height); + if (((flags.value >> 4) & 1) != 0) + { + expNumSlices = numSlices; + + if (numSlices <= 1) + padDims = 2; + + else + padDims = 0; + } + + else + expNumSlices = nextPow2(numSlices); + + if (expTileMode == 3 && expNumSlices < 4) + { + expTileMode = 2; + microTileThickness = 1; + } + } + + var surfMicroAlign = computeSurfaceAlignmentsMicroTiled( + expTileMode, + bpp, + flags, + numSamples); + + uint baseAlign = surfMicroAlign.Item1; + uint pitchAlign = surfMicroAlign.Item2; + uint heightAlign = surfMicroAlign.Item3; + + var padDimens = padDimensions( + expTileMode, + padDims, + (flags.value >> 4) & 1, + (flags.value >> 7) & 1, + pitchAlign, + heightAlign, + microTileThickness); + + expPitch = padDimens.Item1; + expHeight = padDimens.Item2; + expNumSlices = padDimens.Item3; + + pPitchOut = expPitch; + pHeightOut = expHeight; + pNumSlicesOut = expNumSlices; + pSurfSize = (expHeight * expPitch * expNumSlices * bpp * numSamples + 7) / 8; + + Console.WriteLine("pSurfSize " + pSurfSize); + Console.WriteLine("expHeight " + expHeight); + Console.WriteLine("expPitch " + expPitch); + Console.WriteLine("expNumSlices " + expNumSlices); + Console.WriteLine("numSamples " + numSamples); + + pTileModeOut = expTileMode; + pBaseAlign = baseAlign; + pPitchAlign = pitchAlign; + pHeightAlign = heightAlign; + pDepthAlign = microTileThickness; + + return new uint[] { valid, pPitchOut, pHeightOut, pNumSlicesOut, pSurfSize, pTileModeOut, pBaseAlign, pPitchAlign, pHeightAlign, pDepthAlign }; + } + private static uint IsPow2(uint dim) + { + if ((dim & (dim - 1)) == 0) + return 1; + else + return 0; + } + private static Tuple padDimensions(uint tileMode, uint padDims, uint isCube, uint cubeAsArray, uint pitchAlign, uint heightAlign, uint sliceAlign) + { + uint thickness = computeSurfaceThickness((AddrTileMode)tileMode); + if (padDims == 0) + padDims = 3; + + Console.WriteLine("padDims " + padDims); + Console.WriteLine("pitchAlign " + pitchAlign); + + + + if ((pitchAlign & (pitchAlign - 1)) == 0) + expPitch = powTwoAlign(expPitch, pitchAlign); + else + { + expPitch = pitchAlign + expPitch - 1; + expPitch /= pitchAlign; + expPitch *= pitchAlign; + } + + if (padDims > 1) + expHeight = powTwoAlign(expHeight, heightAlign); + + Console.WriteLine("expPitch " + expPitch); + Console.WriteLine("expHeight " + expHeight); + Console.WriteLine("expNumSlices " + expNumSlices); + + if (padDims > 2 || thickness > 1) + { + if (isCube != 0) + expNumSlices = nextPow2(expNumSlices); + + if (thickness > 1) + expNumSlices = powTwoAlign(expNumSlices, sliceAlign); + } + Console.WriteLine("expPitch " + expPitch); + Console.WriteLine("expHeight " + expHeight); + Console.WriteLine("expNumSlices " + expNumSlices); + + return new Tuple(expPitch, expHeight, expNumSlices); + } + + + private static uint[] computeSurfaceInfoMacroTiled(uint tileMode, uint baseTileMode, uint bpp, uint numSamples, + uint pitch, uint height, uint numSlices, uint mipLevel, uint padDims, Flags flags) + { + expPitch = pitch; + + expHeight = height; + expNumSlices = numSlices; + + uint valid = 1; + uint expTileMode = tileMode; + uint microTileThickness = computeSurfaceThickness((AddrTileMode)tileMode); + + uint baseAlign, pitchAlign, heightAlign, macroWidth, macroHeight; + uint bankSwappedWidth, pitchAlignFactor; + uint result, pPitchOut, pHeightOut, pNumSlicesOut, pSurfSize, pTileModeOut, pBaseAlign, pPitchAlign, pHeightAlign, pDepthAlign; + + if (mipLevel != 0) + { + expPitch = nextPow2(pitch); + expHeight = nextPow2(height); + + if (((flags.value >> 4) & 1) != 0) + { + expNumSlices = numSlices; + + if (numSlices <= 1) + padDims = 2; + else + padDims = 0; + } + else + expNumSlices = nextPow2(numSlices); + + if (expTileMode == 7 && expNumSlices < 4) + { + expTileMode = 4; + microTileThickness = 1; + } + } + Console.WriteLine($"baseTileMode {baseTileMode}"); + Console.WriteLine($"tileMode {tileMode}"); + + if (tileMode == baseTileMode + || mipLevel == 0 + || isThickMacroTiled((AddrTileMode)baseTileMode) == 0 + || isThickMacroTiled((AddrTileMode)tileMode) != 0) + { + var tup = computeSurfaceAlignmentsMacroTiled( + tileMode, + bpp, + flags, + numSamples); + + baseAlign = tup.Item1; + pitchAlign = tup.Item2; + heightAlign = tup.Item3; + macroWidth = tup.Item4; + macroHeight = tup.Item5; + + bankSwappedWidth = computeSurfaceBankSwappedWidth((AddrTileMode)tileMode, bpp, pitch, numSamples); + + Console.WriteLine("---------------------"); + Console.WriteLine(baseAlign); + Console.WriteLine(pitchAlign); + Console.WriteLine(heightAlign); + Console.WriteLine(macroWidth); + Console.WriteLine(macroHeight); + Console.WriteLine(bankSwappedWidth); + Console.WriteLine("---------------------"); + + if (bankSwappedWidth > pitchAlign) + pitchAlign = bankSwappedWidth; + + Console.WriteLine("padDimensions"); + Console.WriteLine(tileMode); + Console.WriteLine(padDims); + Console.WriteLine((flags.value >> 4) & 1); + Console.WriteLine((flags.value >> 7) & 1); + Console.WriteLine(pitchAlign); + Console.WriteLine(heightAlign); + Console.WriteLine(microTileThickness); + Console.WriteLine("---------------------"); + Console.WriteLine("expPitch " + expPitch); + + var padDimens = padDimensions( + tileMode, + padDims, + (flags.value >> 4) & 1, + (flags.value >> 7) & 1, + pitchAlign, + heightAlign, + microTileThickness); + + expPitch = padDimens.Item1; + expHeight = padDimens.Item2; + expNumSlices = padDimens.Item3; + + Console.WriteLine(expPitch); + Console.WriteLine(expHeight); + Console.WriteLine(expNumSlices); + Console.WriteLine(bpp); + Console.WriteLine(numSamples); + + Console.WriteLine("---------------------"); + + pPitchOut = expPitch; + pHeightOut = expHeight; + pNumSlicesOut = expNumSlices; + pSurfSize = (expHeight * expPitch * expNumSlices * bpp * numSamples + 7) / 8; + pTileModeOut = expTileMode; + pBaseAlign = baseAlign; + pPitchAlign = pitchAlign; + pHeightAlign = heightAlign; + pDepthAlign = microTileThickness; + result = valid; + } + + else + { + var tup = computeSurfaceAlignmentsMacroTiled( + baseTileMode, + bpp, + flags, + numSamples); + + baseAlign = tup.Item1; + pitchAlign = tup.Item2; + heightAlign = tup.Item3; + macroWidth = tup.Item4; + macroHeight = tup.Item5; + + pitchAlignFactor = Math.Max(1, 32 / bpp); + + if (expPitch < pitchAlign * pitchAlignFactor || expHeight < heightAlign) + { + expTileMode = 2; + + var microTileInfo = computeSurfaceInfoMicroTiled( + 2, + bpp, + numSamples, + pitch, + height, + numSlices, + mipLevel, + padDims, + flags); + + result = microTileInfo[0]; + pPitchOut = microTileInfo[1]; + pHeightOut = microTileInfo[2]; + pNumSlicesOut = microTileInfo[3]; + pSurfSize = microTileInfo[4]; + pTileModeOut = microTileInfo[5]; + pBaseAlign = microTileInfo[6]; + pPitchAlign = microTileInfo[7]; + pHeightAlign = microTileInfo[8]; + pDepthAlign = microTileInfo[9]; + } + + else + { + tup = computeSurfaceAlignmentsMacroTiled( + tileMode, + bpp, + flags, + numSamples); + + baseAlign = tup.Item1; + pitchAlign = tup.Item2; + heightAlign = tup.Item3; + macroWidth = tup.Item4; + macroHeight = tup.Item5; + + bankSwappedWidth = computeSurfaceBankSwappedWidth((AddrTileMode)tileMode, bpp, pitch, numSamples); + if (bankSwappedWidth > pitchAlign) + pitchAlign = bankSwappedWidth; + + var padDimens = padDimensions( + tileMode, + padDims, + (flags.value >> 4) & 1, + (flags.value >> 7) & 1, + pitchAlign, + heightAlign, + microTileThickness); + + expPitch = padDimens.Item1; + expHeight = padDimens.Item2; + expNumSlices = padDimens.Item3; + + pPitchOut = expPitch; + pHeightOut = expHeight; + pNumSlicesOut = expNumSlices; + pSurfSize = (expHeight * expPitch * expNumSlices * bpp * numSamples + 7) / 8; + Console.WriteLine($"expHeight {expHeight}"); + Console.WriteLine($"expPitch {expPitch}"); + Console.WriteLine($"expNumSlices {expNumSlices}"); + Console.WriteLine($"bpp {bpp}"); + Console.WriteLine($"numSamples {numSamples}"); + Console.WriteLine($"bpp {bpp}"); + + pTileModeOut = expTileMode; + pBaseAlign = baseAlign; + pPitchAlign = pitchAlign; + pHeightAlign = heightAlign; + pDepthAlign = microTileThickness; + result = valid; + } + } + + return new uint[] { result, pPitchOut, pHeightOut, + pNumSlicesOut, pSurfSize, pTileModeOut, pBaseAlign, pitchAlign, heightAlign, pDepthAlign}; + } + private static Tuple computeSurfaceAlignmentsMicroTiled(uint tileMode, uint bpp, Flags flags, uint numSamples) + { + switch (bpp) + { + case 24: + case 48: + case 96: + bpp /= 3; + break; + } + uint thickness = computeSurfaceThickness((AddrTileMode)tileMode); + uint baseAlign = 256; + uint pitchAlign = Math.Max(8, 256 / bpp / numSamples / thickness); + uint heightAlign = 8; + + pitchAlign = adjustPitchAlignment(flags, pitchAlign); + + return new Tuple(baseAlign, pitchAlign, heightAlign); + + } + private static Tuple computeSurfaceAlignmentsMacroTiled(uint tileMode, uint bpp, Flags flags, uint numSamples) + { + uint aspectRatio = computeMacroTileAspectRatio((AddrTileMode)tileMode); + uint thickness = computeSurfaceThickness((AddrTileMode)tileMode); + + switch (bpp) + { + case 24: + case 48: + case 96: + bpp /= 3; + break; + case 3: + bpp = 1; + break; + } + uint macroTileWidth = 32 / aspectRatio; + uint macroTileHeight = aspectRatio * 16; + + uint pitchAlign = Math.Max(macroTileWidth, macroTileWidth * (256 / bpp / (8 * thickness) / numSamples)); + pitchAlign = adjustPitchAlignment(flags, pitchAlign); + + uint heightAlign = macroTileHeight; + uint macroTileBytes = numSamples * ((bpp * macroTileHeight * macroTileWidth + 7) >> 3); + + uint baseAlign; + + if (thickness == 1) + baseAlign = Math.Max(macroTileBytes, (numSamples * heightAlign * bpp * pitchAlign + 7) >> 3); + else + baseAlign = Math.Max(256, (4 * heightAlign * bpp * pitchAlign + 7) >> 3); + + uint microTileBytes = (thickness * numSamples * (bpp << 6) + 7) >> 3; + uint numSlicesPerMicroTile; + if (microTileBytes < 2048) + numSlicesPerMicroTile = 1; + else + numSlicesPerMicroTile = microTileBytes / 2048; + + baseAlign /= numSlicesPerMicroTile; + + return new Tuple(baseAlign, pitchAlign, heightAlign, macroTileWidth, macroTileHeight); + } + private static uint adjustPitchAlignment(Flags flags, uint pitchAlign) + { + if (((flags.value >> 13) & 1) != 0) + pitchAlign = powTwoAlign(pitchAlign, 0x20); + + return pitchAlign; + } + private static uint adjustSurfaceInfo(uint elemMode, uint expandX, uint expandY, uint bpp, uint width, uint height) + { + uint bBCnFormat = 0; + uint widtha, heighta; + + switch (elemMode) + { + case 9: + case 10: + case 11: + case 12: + case 13: + if (bpp != 0) + bBCnFormat = 1; + + break; + } + + if (width != 0 && height != 0) + { + if (expandX > 1 || expandY > 1) + { + if (elemMode == 4) + { + widtha = expandX * width; + heighta = expandY * height; + } + else if (bBCnFormat != 0) + { + widtha = width / expandX; + heighta = height / expandY; + } + else + { + widtha = (width + expandX - 1) / expandX; + heighta = (height + expandY - 1) / expandY; + } + + pIn.width = Math.Max(1, widtha); + pIn.height = Math.Max(1, heighta); + } + } + + if (bpp != 0) + { + switch (elemMode) + { + case 4: + pIn.bpp = bpp / expandX / expandY; + break; + + case 5: + case 6: + pIn.bpp = expandY * expandX * bpp; + break; + + case 9: + case 12: + pIn.bpp = 64; + break; + + case 10: + case 11: + case 13: + pIn.bpp = 128; + break; + + default: + pIn.bpp = bpp; + break; + } + + return pIn.bpp; + } + + return 0; + } + private static uint useTileIndex(int index) + { + return 0; + } private static void computeMipLevel() { uint slices = 0; @@ -1320,34 +2123,128 @@ namespace FirstPlugin uint width = 0; uint hwlHandled = 0; - if ((49 <= pIn.format && 49 <= 55 && pIn.mipLevel != 49) || 49 <= ((pIn.flags.value >> 12) & 1)) + if (49 <= pIn.format && pIn.format <= 55 && (pIn.mipLevel == 0 || ((pIn.flags.value >> 12) & 1) != 0)) { pIn.width = powTwoAlign(pIn.width, 4); pIn.height = powTwoAlign(pIn.height, 4); } - hwlHandled = hwlComputeMipLevel(); + + if (DebugSurface) + { + Console.WriteLine("-------------------------------------------"); + Console.WriteLine(" hwlComputeMipLevel"); + Console.WriteLine("-------------------------------------------"); + Console.WriteLine(" pIn.width " + pIn.width); + Console.WriteLine(" pIn.height " + pIn.height); + Console.WriteLine(" pIn.numSlices " + pIn.numSlices); + } + + hwlHandled = hwlComputeMipLevel(); + if (DebugSurface) + { + Console.WriteLine(" Output:"); + Console.WriteLine(" pIn.width " + pIn.width); + Console.WriteLine(" pIn.height " + pIn.height); + Console.WriteLine(" pIn.numSlices " + pIn.numSlices); + Console.WriteLine("-------------------------------------------"); + } + + if (hwlHandled == 0 && pIn.mipLevel != 0 && ((pIn.flags.value >> 12) & 1) != 0) + { + width = Math.Max(1, pIn.width >> (int)pIn.mipLevel); + height = Math.Max(1, pIn.height >> (int)pIn.mipLevel); + slices = Math.Max(1, pIn.numSlices); + + if (((pIn.flags.value >> 4) & 1) != 0) + slices = Math.Max(1, slices >> (int)pIn.mipLevel); + + if (pIn.format != 47 && pIn.format != 48) + { + width = nextPow2(width); + height = nextPow2(height); + slices = nextPow2(slices); + } + width = nextPow2(width); + height = nextPow2(height); + slices = nextPow2(slices); + } } + + private static uint restoreSurfaceInfo(uint elemMode, uint expandX, uint expandY, uint bpp) + { + uint width, height; + + if (pOut.pixelPitch != 0 && pOut.pixelHeight != 0) + { + width = pOut.pixelPitch; + height = pOut.pixelHeight; + + if (expandX > 1 || expandY > 1) + { + if (elemMode == 4) + { + width /= expandX; + height /= expandY; + } + + else + { + width *= expandX; + height *= expandY; + } + + pOut.pixelPitch = Math.Max(1, width); + pOut.pixelHeight = Math.Max(1, height); + } + } + if (bpp != 0) + { + switch (elemMode) + { + case 4: + return expandY * expandX * bpp; + + case 5: + case 6: + return bpp / expandX / expandY; + + case 9: + case 12: + return 64; + + case 10: + case 11: + case 13: + return 128; + + default: + return bpp; + } + } + + return 0; + } + private static uint hwlComputeMipLevel() { - //This part might be wrong? uint handled = 0; - if (49 <= pIn.format && 49 <= 55) + if (49 <= pIn.format && pIn.format <= 55) { if (pIn.mipLevel != 0) { - int width = pIn.width; - int height = pIn.height; - int slices = pIn.numSlices; + uint width = pIn.width; + uint height = pIn.height; + uint slices = pIn.numSlices; if (((pIn.flags.value >> 12) & 1) != 0) { - int widtha = width >> pIn.mipLevel; - int heighta = height >> pIn.mipLevel; + uint widtha = width >> (int)pIn.mipLevel; + uint heighta = height >> (int)pIn.mipLevel; if (((pIn.flags.value >> 4) & 1) == 0) - slices >>= pIn.mipLevel; + slices >>= (int)pIn.mipLevel; width = Math.Max(1, widtha); height = Math.Max(1, heighta); @@ -1363,22 +2260,9 @@ namespace FirstPlugin } return handled; } - private static int nextPow2(int dim) + private static uint powTwoAlign(uint x, uint align) { - uint newDim = 1; - if (newDim <= 0x7FFFFFFF) - { - while (newDim < dim) - newDim *= 2; - } - else - newDim = 2147483648; - - return (int)newDim; - } - private static int powTwoAlign(int x, int align) - { - return (int)(align - 1) & (x + align - 1); + return ~(align - 1) & (x + align - 1); } public static surfaceOut getSurfaceInfo(GX2SurfaceFormat surfaceFormat, int surfaceWidth, int surfaceHeight, int surfaceDepth, uint surfaceDim, uint surfaceTileMode, uint surfaceAA, int level) @@ -1396,6 +2280,7 @@ namespace FirstPlugin hwFormat = (int)surfaceFormat & 0x3F; + if (surfaceTileMode == 16) { numSamples = 1 << (int)surfaceAA; @@ -1405,19 +2290,20 @@ namespace FirstPlugin else blockSize = 4; - width = (uint)((blockSize - 1) & ((surfaceWidth >> level) + blockSize - 1)); + width = (uint)(~(blockSize - 1) & ((surfaceWidth >> level) + blockSize - 1)); if (hwFormat == 0x35) return pSurfOut; pSurfOut.bpp = formatHwInfo[hwFormat * 4]; pSurfOut.size = 96; - pSurfOut.pitch = (int)(width / blockSize); + pSurfOut.pitch = (uint)(width / blockSize); pSurfOut.pixelBits = formatHwInfo[hwFormat * 4]; pSurfOut.baseAlign = 1; pSurfOut.pitchAlign = 1; pSurfOut.heightAlign = 1; pSurfOut.depthAlign = 1; + dim = surfaceDim; if (dim == 0) { @@ -1426,44 +2312,43 @@ namespace FirstPlugin } else if (dim == 1) { - pSurfOut.height = Math.Max(1, surfaceHeight >> level); + pSurfOut.height = (uint)Math.Max(1, surfaceHeight >> level); pSurfOut.depth = 1; } else if (dim == 2) { - pSurfOut.height = Math.Max(1, surfaceHeight >> level); - pSurfOut.depth = Math.Max(1, surfaceDepth >> level); + pSurfOut.height = (uint)Math.Max(1, surfaceHeight >> level); + pSurfOut.depth = (uint)Math.Max(1, surfaceDepth >> level); } else if (dim == 3) { - pSurfOut.height = Math.Max(1, surfaceHeight >> level); - pSurfOut.depth = Math.Max(6, surfaceDepth); + pSurfOut.height = (uint)Math.Max(1, surfaceHeight >> level); + pSurfOut.depth = (uint)Math.Max(6, surfaceDepth); } else if (dim == 4) { pSurfOut.height = 1; - pSurfOut.depth = surfaceDepth; + pSurfOut.depth = (uint)surfaceDepth; } else if (dim == 5) { - pSurfOut.height = Math.Max(1, surfaceHeight >> level); - pSurfOut.depth = surfaceDepth; + pSurfOut.height = (uint)Math.Max(1, surfaceHeight >> level); + pSurfOut.depth = (uint)surfaceDepth; } - pSurfOut.height = (int)(((blockSize - 1) & (pSurfOut.height + blockSize - 1)) / blockSize); - pSurfOut.pixelPitch = (int)((blockSize - 1) & ((surfaceWidth >> level) + blockSize - 1)); - pSurfOut.pixelPitch = (int)Math.Max(blockSize, pSurfOut.pixelPitch); - pSurfOut.pixelHeight = (int)((blockSize - 1) & ((surfaceHeight >> level) + blockSize - 1)); - pSurfOut.pixelHeight = (int)Math.Max(blockSize, pSurfOut.pixelHeight); + pSurfOut.height = (uint)(~(blockSize - 1) & (pSurfOut.height + blockSize - 1)) / blockSize; + pSurfOut.pixelPitch = (uint)(~(blockSize - 1) & ((surfaceWidth >> level) + blockSize - 1)); + pSurfOut.pixelPitch = Math.Max(blockSize, pSurfOut.pixelPitch); + pSurfOut.pixelHeight = (uint)(~(blockSize - 1) & ((surfaceHeight >> level) + blockSize - 1)); + pSurfOut.pixelHeight = Math.Max(blockSize, pSurfOut.pixelHeight); pSurfOut.pitch = Math.Max(1, pSurfOut.pitch); pSurfOut.height = Math.Max(1, pSurfOut.height); pSurfOut.surfSize = pSurfOut.bpp * numSamples * pSurfOut.depth * pSurfOut.height * pSurfOut.pitch >> 3; if (surfaceDim == 2) - pSurfOut.sliceSize = pSurfOut.surfSize; - + pSurfOut.sliceSize = (uint)pSurfOut.surfSize; else - pSurfOut.sliceSize = pSurfOut.surfSize / pSurfOut.depth; + pSurfOut.sliceSize = (uint)pSurfOut.surfSize / pSurfOut.depth; pSurfOut.pitchTileMax = (pSurfOut.pitch >> 3) - 1; pSurfOut.heightTileMax = (pSurfOut.height >> 3) - 1; @@ -1472,12 +2357,13 @@ namespace FirstPlugin else { aSurfIn.size = 60; - aSurfIn.tileMode = (int)surfaceTileMode & 0x0F; - aSurfIn.format = hwFormat; + aSurfIn.tileMode = surfaceTileMode & 0x0F; + aSurfIn.format = (uint)hwFormat; aSurfIn.bpp = formatHwInfo[hwFormat * 4]; - aSurfIn.numSamples = 1 << (int)surfaceAA; + aSurfIn.numSamples = (uint)1 << (int)surfaceAA; aSurfIn.numFrags = aSurfIn.numSamples; - aSurfIn.width = Math.Max(1, surfaceWidth >> level); + aSurfIn.width = (uint)Math.Max(1, surfaceWidth >> level); + dim = surfaceDim; if (dim == 0) { @@ -1486,47 +2372,57 @@ namespace FirstPlugin } else if (dim == 1) { - aSurfIn.height = Math.Max(1, surfaceHeight >> level); + aSurfIn.height = (uint)Math.Max(1, surfaceHeight >> level); aSurfIn.numSlices = 1; } else if (dim == 2) { - aSurfIn.height = Math.Max(1, surfaceHeight >> level); - aSurfIn.numSlices = Math.Max(1, surfaceDepth >> level); + aSurfIn.height = (uint)Math.Max(1, surfaceHeight >> level); + aSurfIn.numSlices = (uint)Math.Max(1, surfaceDepth >> level); } else if (dim == 3) { - aSurfIn.height = Math.Max(1, surfaceHeight >> level); - aSurfIn.numSlices = Math.Max(6, surfaceDepth); + aSurfIn.height = (uint)Math.Max(1, surfaceHeight >> level); + aSurfIn.numSlices = (uint)Math.Max(6, surfaceDepth); aSurfIn.flags.value |= 0x10; } else if (dim == 4) { aSurfIn.height = 1; - aSurfIn.numSlices = surfaceDepth; + aSurfIn.numSlices = (uint)surfaceDepth; } else if (dim == 5) { - aSurfIn.height = Math.Max(1, surfaceHeight >> level); - aSurfIn.numSlices = surfaceDepth; + aSurfIn.height = (uint)Math.Max(1, surfaceHeight >> level); + aSurfIn.numSlices = (uint)surfaceDepth; } else if (dim == 6) { - aSurfIn.height = Math.Max(1, surfaceHeight >> level); + aSurfIn.height = (uint)Math.Max(1, surfaceHeight >> level); aSurfIn.numSlices = 1; } else if (dim == 7) { - aSurfIn.height = Math.Max(1, surfaceHeight >> level); - aSurfIn.numSlices = surfaceDepth; + aSurfIn.height = (uint)Math.Max(1, surfaceHeight >> level); + aSurfIn.numSlices = (uint)surfaceDepth; } + + aSurfIn.slice = 0; + aSurfIn.mipLevel = (uint)level; + + if (surfaceDim == 2) + aSurfIn.flags.value |= 0x20; + + if (level == 0) + aSurfIn.flags.value = (1 << 12) | aSurfIn.flags.value & 0xFFFFEFFF; + else + aSurfIn.flags.value = aSurfIn.flags.value & 0xFFFFEFFF; + + pSurfOut.size = 96; + computeSurfaceInfo(aSurfIn, pSurfOut); + + pSurfOut = pOut; } - - pSurfOut.size = 96; - computeSurfaceInfo(aSurfIn, pSurfOut); - - pSurfOut = pOut; - return pSurfOut; } } diff --git a/Switch_FileFormatsMain/FileFormats/Texture/NUTEXB.cs b/Switch_FileFormatsMain/FileFormats/Texture/NUTEXB.cs index ec4e95ef..1f97c0f4 100644 --- a/Switch_FileFormatsMain/FileFormats/Texture/NUTEXB.cs +++ b/Switch_FileFormatsMain/FileFormats/Texture/NUTEXB.cs @@ -28,10 +28,11 @@ namespace FirstPlugin public string FilePath { get; set; } public IFileInfo IFileInfo { get; set; } - public enum NUTEXImageFormat : uint + public enum NUTEXImageFormat : byte { R8G8B8A8_UNORM = 0x00, R8G8B8A8_SRGB = 0x05, + R32G32B32A32_FLOAT = 0x34, B8G8R8A8_UNORM = 0x50, B8G8R8A8_SRGB = 0x55, BC1_UNORM = 0x80, @@ -88,6 +89,7 @@ namespace FirstPlugin case (byte)NUTEXImageFormat.BC4_SNORM: return 8; + case (byte)NUTEXImageFormat.R32G32B32A32_FLOAT: case (byte)NUTEXImageFormat.BC2_UNORM: case (byte)NUTEXImageFormat.BC2_SRGB: case (byte)NUTEXImageFormat.BC3_UNORM: @@ -169,15 +171,21 @@ namespace FirstPlugin public bool BadSwizzle; public uint Width; public uint Height; - public byte Format; - public uint[] mipSizes; - public uint Alignment; + public uint unk; + public int unk2; + public int unk3; + + public NUTEXImageFormat Format; + public List mipSizes = new List(); + public int Alignment; public List> mipmaps = new List>(); public List> blocksCompressed = new List>(); bool IsSwizzled = true; public string ArcOffset; //Temp for exporting in batch + MenuItem save = new MenuItem("Save"); MenuItem export = new MenuItem("Export"); + MenuItem replace = new MenuItem("Replace"); public NuTex() { @@ -185,10 +193,41 @@ namespace FirstPlugin SelectedImageKey = "Texture"; ContextMenu = new ContextMenu(); + ContextMenu.MenuItems.Add(save); ContextMenu.MenuItems.Add(export); + ContextMenu.MenuItems.Add(replace); + save.Click += Save; + replace.Click += Replace; export.Click += Export; } + private void Replace(object sender, EventArgs args) + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = "Supported Formats|*.dds; *.png;*.tga;*.jpg;*.tiff|" + + "Microsoft DDS |*.dds|" + + "Portable Network Graphics |*.png|" + + "Joint Photographic Experts Group |*.jpg|" + + "Bitmap Image |*.bmp|" + + "Tagged Image File Format |*.tiff|" + + "All files(*.*)|*.*"; + + ofd.Multiselect = false; + if (ofd.ShowDialog() == DialogResult.OK) + { + throw new Exception("Not finished yet!"); + + var bntxFile = new BinaryTextureContainer(); + var tex = new TextureData(); + tex.Replace(ofd.FileName); + blocksCompressed = tex.Texture.TextureData; + mipmaps = tex.mipmaps; + Width = tex.Texture.Width; + Height = tex.Texture.Height; + + UpdateEditor(); + } + } private void Export(object sender, EventArgs args) { SaveFileDialog sfd = new SaveFileDialog(); @@ -207,6 +246,21 @@ namespace FirstPlugin Export(sfd.FileName); } } + private void Save(object sender, EventArgs args) + { + List formats = new List(); + formats.Add(FileHandler); + + SaveFileDialog sfd = new SaveFileDialog(); + sfd.Filter = Utils.GetAllFilters(formats); + sfd.FileName = FileHandler.FileName; + + if (sfd.ShowDialog() == DialogResult.OK) + { + Cursor.Current = Cursors.WaitCursor; + System.IO.File.WriteAllBytes(sfd.FileName, FileHandler.Save()); + } + } public void Export(string FileName, bool ExportSurfaceLevel = false, bool ExportMipMapLevel = false, int SurfaceLevel = 0, int MipLevel = 0) { @@ -264,47 +318,94 @@ namespace FirstPlugin uint padding2 = reader.ReadUInt32(); Width = reader.ReadUInt32(); Height = reader.ReadUInt32(); - uint ArrayCount = reader.ReadUInt32(); //6 for cubemaps - Format = reader.ReadByte(); - byte unk = reader.ReadByte(); //Might be unorm/snorm/srgb + unk3 = reader.ReadInt32(); + Format = reader.ReadEnum(true); + unk = reader.ReadByte(); //Related to pixel size?? ushort padding3 = reader.ReadUInt16(); - uint unk2 = reader.ReadUInt32(); + unk2 = reader.ReadInt32(); uint mipCount = reader.ReadUInt32(); - Alignment = reader.ReadUInt32(); - int unk3 = reader.ReadInt32(); + Alignment = reader.ReadInt32(); + uint ArrayCount = reader.ReadUInt32(); //6 for cubemaps int imagesize = reader.ReadInt32(); - reader.Seek(pos - 176, System.IO.SeekOrigin.Begin); //Get mipmap sizes - mipSizes = reader.ReadUInt32s((int)mipCount); + reader.Seek(imagesize, System.IO.SeekOrigin.Begin); //Get mipmap sizes + for (int arrayLevel = 0; arrayLevel < ArrayCount; arrayLevel++) + { + long mipPos = reader.Position; + uint[] mips = reader.ReadUInt32s((int)mipCount); + mipSizes.Add(mips); + + //Each mip section is 0x40 size for each array + //Seek to next one + reader.Seek(mipPos + 0x40, System.IO.SeekOrigin.Begin); + } + - List mips = new List(); reader.Seek(0, System.IO.SeekOrigin.Begin); + for (int arrayLevel = 1; arrayLevel < ArrayCount + 1; arrayLevel++) + { + List mipmaps = new List(); - if (mipCount == 1 && IsSwizzled) - { - mips.Add(reader.ReadBytes((int)imagesize)); - blocksCompressed.Add(mips); - } - else - { - for (int arrayLevel = 0; arrayLevel < ArrayCount; arrayLevel++) + for (int mipLevel = 0; mipLevel < mipCount; mipLevel++) { - for (int mipLevel = 0; mipLevel < mipCount; mipLevel++) - { - mips.Add(reader.ReadBytes((int)Width * (int)Height * (int)bpps(Format))); - break; - } - blocksCompressed.Add(mips); - } - } - } + //Get the size from the size array + int size = (int)mipSizes[arrayLevel - 1][mipLevel]; + //Align the size + if (mipLevel == 0) + if (size % Alignment != 0) size = size + (Alignment - (size % Alignment)); + + mipmaps.Add(reader.ReadBytes(imagesize)); + break; + } + blocksCompressed.Add(mipmaps); + //Seek the next array + reader.Seek(imagesize / (int)ArrayCount, System.IO.SeekOrigin.Begin); + } + LoadTexture(); + } + public void Write(FileWriter writer) + { + int arrayCount = blocksCompressed.Count; + + foreach (var array in blocksCompressed) + { + writer.Write(array[0]); //Write textue block first + } + long headerStart = writer.Position; + foreach (var mips in mipSizes) + { + long MipStart = writer.Position; + writer.Write(mips); //Write textue block first + + writer.Seek(MipStart + 0x40, System.IO.SeekOrigin.Begin); + } + long stringPos = writer.Position; + writer.Write((byte)0x20); + writer.WriteString(Text); + writer.Seek(stringPos + 0x40, System.IO.SeekOrigin.Begin); + writer.Seek(4); //padding + writer.Write(Width); + writer.Write(Height); + writer.Write(unk3); + writer.Write((byte)Format); + writer.Write((byte)unk); + writer.Seek(2); //padding + writer.Write(unk2); + writer.Write(blocksCompressed[0].Count); + writer.Write(Alignment); + writer.Write(arrayCount); + writer.Write(blocksCompressed[0][0].Length * arrayCount); + writer.WriteSignature(" XET"); + writer.Write(131073); + + } public override void OnClick(TreeView treeView) { UpdateEditor(); } - public Bitmap DisplayTexture(int DisplayMipIndex = 0, int ArrayIndex = 0) + public Bitmap DisplayTexture(int ArrayIndex = 0, int DisplayMipIndex = 0) { if (BadSwizzle) return BitmapExtension.GetBitmap(Properties.Resources.Black, 32, 32); @@ -312,26 +413,28 @@ namespace FirstPlugin if (IsSwizzled) LoadTexture(); else - mipmaps.Add(blocksCompressed[0]); + mipmaps.Add(blocksCompressed[ArrayIndex]); if (mipmaps[0].Count <= 0) { return BitmapExtension.GetBitmap(Properties.Resources.Black, 32, 32); } + Console.WriteLine(ArrayIndex); + uint width = (uint)Math.Max(1, Width >> DisplayMipIndex); uint height = (uint)Math.Max(1, Height >> DisplayMipIndex); byte[] data = mipmaps[ArrayIndex][DisplayMipIndex]; - - return DecodeBlock(data, width, height, (NUTEXImageFormat)Format); } public static Bitmap DecodeBlock(byte[] data, uint Width, uint Height, NUTEXImageFormat Format) { Bitmap decomp; + Console.WriteLine(Format); + if (Format == NUTEXImageFormat.BC5_SNORM) return DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true); @@ -352,31 +455,33 @@ namespace FirstPlugin { switch (Format) { + case NUTEXImageFormat.R32G32B32A32_FLOAT: return DDS.DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT; case NUTEXImageFormat.R8G8B8A8_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM; - case NUTEXImageFormat.R8G8B8A8_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + case NUTEXImageFormat.R8G8B8A8_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM; case NUTEXImageFormat.B8G8R8A8_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM; - case NUTEXImageFormat.B8G8R8A8_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + case NUTEXImageFormat.B8G8R8A8_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM; default: throw new Exception($"Cannot convert format {Format}"); } } private static DDS.DXGI_FORMAT GetCompressedDXGI_FORMAT(NUTEXImageFormat Format) { + //This uses UNORM instead of SRGB due to decod switch (Format) { case NUTEXImageFormat.BC1_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM; - case NUTEXImageFormat.BC1_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB; + case NUTEXImageFormat.BC1_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM; case NUTEXImageFormat.BC2_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM; - case NUTEXImageFormat.BC2_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB; + case NUTEXImageFormat.BC2_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM; case NUTEXImageFormat.BC3_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM; - case NUTEXImageFormat.BC3_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB; + case NUTEXImageFormat.BC3_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM; case NUTEXImageFormat.BC4_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM; case NUTEXImageFormat.BC4_SNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM; case NUTEXImageFormat.BC5_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM; case NUTEXImageFormat.BC5_SNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM; case NUTEXImageFormat.BC6_UFLOAT: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16; case NUTEXImageFormat.BC7_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM; - case NUTEXImageFormat.BC7_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB; + case NUTEXImageFormat.BC7_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM; default: throw new Exception($"Cannot convert format {Format}"); } @@ -408,7 +513,7 @@ namespace FirstPlugin { mipmaps.Clear(); - uint blk_dim = blk_dims(Format); + uint blk_dim = blk_dims((byte)Format); uint blkWidth = blk_dim >> 4; uint blkHeight = blk_dim & 0xF; @@ -418,7 +523,7 @@ namespace FirstPlugin int linesPerBlockHeight = (1 << (int)BlockHeightLog2) * 8; - uint bpp = bpps(Format); + uint bpp = bpps((byte)Format); for (int arrayLevel = 0; arrayLevel < blocksCompressed.Count; arrayLevel++) { @@ -448,7 +553,7 @@ namespace FirstPlugin } catch (Exception e) { - System.Windows.Forms.MessageBox.Show("Failed to swizzle texture!"); + System.Windows.Forms.MessageBox.Show($"Failed to swizzle texture {Text}!"); Console.WriteLine(e); BadSwizzle = true; break; @@ -489,7 +594,9 @@ namespace FirstPlugin } public byte[] Save() { - return null; + System.IO.MemoryStream mem = new System.IO.MemoryStream(); + ((NuTex)EditorRoot).Write(new FileWriter(mem)); + return mem.ToArray(); } } } diff --git a/Switch_FileFormatsMain/FileFormats/Texture/TegraX1Swizzle.cs b/Switch_FileFormatsMain/FileFormats/Texture/TegraX1Swizzle.cs index fc69e992..4ca24eb5 100644 --- a/Switch_FileFormatsMain/FileFormats/Texture/TegraX1Swizzle.cs +++ b/Switch_FileFormatsMain/FileFormats/Texture/TegraX1Swizzle.cs @@ -76,7 +76,7 @@ namespace FirstPlugin { uint block_height = (uint)(1 << blockHeightLog2); - Console.WriteLine($"Swizzle {width} {height} {blkWidth} {blkHeight} {roundPitch} {bpp} {tileMode} {blockHeightLog2} {data.Length} {toSwizzle}"); + // Console.WriteLine($"Swizzle {width} {height} {blkWidth} {blkHeight} {roundPitch} {bpp} {tileMode} {blockHeightLog2} {data.Length} {toSwizzle}"); width = DIV_ROUND_UP(width, blkWidth); height = DIV_ROUND_UP(height, blkHeight); diff --git a/Switch_FileFormatsMain/FileFormats/Texture/XTX.cs b/Switch_FileFormatsMain/FileFormats/Texture/XTX.cs index 5f0a9955..808bec4b 100644 --- a/Switch_FileFormatsMain/FileFormats/Texture/XTX.cs +++ b/Switch_FileFormatsMain/FileFormats/Texture/XTX.cs @@ -75,13 +75,6 @@ namespace FirstPlugin BC5S = 0x0000004c, }; - public enum BNTXImageTypes - { - UNORM = 0x01, - SNORM = 0x02, - SRGB = 0x06, - }; - public static uint blk_dims(uint format) { switch (format) @@ -164,14 +157,18 @@ namespace FirstPlugin public void UpdateEditor() { - NuTexEditor docked = (NuTexEditor)LibraryGUI.Instance.GetContentDocked(new NuTexEditor()); + if (Viewport.Instance.gL_ControlModern1.Visible == false) + PluginRuntime.FSHPDockState = WeifenLuo.WinFormsUI.Docking.DockState.Document; + + XTXEditor docked = (XTXEditor)LibraryGUI.Instance.GetContentDocked(new XTXEditor()); if (docked == null) { - docked = new NuTexEditor(); + docked = new XTXEditor(); LibraryGUI.Instance.LoadDockContent(docked, PluginRuntime.FSHPDockState); } docked.Text = Text; docked.Dock = DockStyle.Fill; + docked.LoadProperty(blockHeader.textureInfo); } public class BlockHeader @@ -222,7 +219,7 @@ namespace FirstPlugin public uint[] MipOffsets { get; set; } public BlockHeader DataBlockHeader { get; set; } public List mipmaps = new List(); - public byte[] data; + public List compressedBlocks = new List(); public void Read(FileReader reader) { @@ -248,8 +245,25 @@ namespace FirstPlugin DataBlockHeader.Read(reader); reader.Seek(DataBlockOff + DataBlockHeader.DataOffset, SeekOrigin.Begin); - data = reader.ReadBytes((int)DataBlockHeader.DataSize); + // data = reader.ReadBytes((int)DataBlockHeader.DataSize); + long datastart = reader.Position; + Console.WriteLine(DataBlockHeader.DataSize); + for (int i = 0; i < MipCount; i++) + { + int size = (int)((int)DataBlockHeader.DataSize - MipOffsets[i]); + Console.WriteLine(size); + + using (reader.TemporarySeek(datastart + MipOffsets[i], System.IO.SeekOrigin.Begin)) + { + compressedBlocks.Add(reader.ReadBytes(size)); + } + if (compressedBlocks[i].Length == 0) + throw new System.Exception("Empty mip size!"); + + break; //Only first mip level works? + } + reader.Seek(DataBlockOff + DataBlockHeader.DataOffset + (long)DataBlockHeader.DataSize, SeekOrigin.Begin); BlockHeader EndBlockHeader = new BlockHeader(); EndBlockHeader.Read(reader); } @@ -344,7 +358,7 @@ namespace FirstPlugin uint bpp = XTXFormats.bpps((uint)Format); int blockHeightShift = 0; - for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) + for (int mipLevel = 0; mipLevel < compressedBlocks.Count; mipLevel++) { uint width = (uint)Math.Max(1, Width >> mipLevel); uint height = (uint)Math.Max(1, Height >> mipLevel); @@ -352,12 +366,12 @@ namespace FirstPlugin // uint size = width * height * bpp; uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp; - byte[] mipData = GetMipBlock(MipOffsets[mipLevel], size); - + Console.WriteLine(mipLevel + " " + size); + if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight) blockHeightShift += 1; - byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, (int)Target, bpp, (uint)TileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), mipData); + byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, (int)Target, bpp, (uint)TileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), compressedBlocks[mipLevel]); //Create a copy and use that to remove uneeded data byte[] result_ = new byte[size]; Array.Copy(result, 0, result_, 0, size); @@ -369,12 +383,6 @@ namespace FirstPlugin Console.WriteLine("height " + height); } } - private byte[] GetMipBlock(uint offset, uint Size) - { - FileReader reader = new FileReader(new MemoryStream(data)); - reader.Seek(offset, SeekOrigin.Begin); - return reader.ReadBytes((int)Size); - } } } diff --git a/Switch_FileFormatsMain/GUI/BFRES/BfresShapeEditor.cs b/Switch_FileFormatsMain/GUI/BFRES/BfresShapeEditor.cs index 9adfef2f..71d01165 100644 --- a/Switch_FileFormatsMain/GUI/BFRES/BfresShapeEditor.cs +++ b/Switch_FileFormatsMain/GUI/BFRES/BfresShapeEditor.cs @@ -277,7 +277,7 @@ namespace FirstPlugin list.AddVector4(vtx.bitan); break; case "_w0": - list.AddWeights(vtx.weights); + list.AddWeights(vtx.boneWeights); break; case "_i0": List boneNames = new List(); @@ -287,7 +287,7 @@ namespace FirstPlugin boneNames = null; break; case "_w1": - list.AddWeights(vtx.weights); + list.AddWeights(vtx.boneWeights); break; case "_i1": List boneNames2 = new List(); diff --git a/Switch_FileFormatsMain/GUI/TextureUI/NuTexEditor.Designer.cs b/Switch_FileFormatsMain/GUI/TextureUI/NuTexEditor.Designer.cs new file mode 100644 index 00000000..1a46f28c --- /dev/null +++ b/Switch_FileFormatsMain/GUI/TextureUI/NuTexEditor.Designer.cs @@ -0,0 +1,353 @@ +namespace FirstPlugin +{ + partial class NuTexEditor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NuTexEditor)); + this.panel1 = new System.Windows.Forms.Panel(); + this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); + this.splitter1 = new System.Windows.Forms.Splitter(); + this.panel2 = new System.Windows.Forms.Panel(); + this.panel4 = new System.Windows.Forms.Panel(); + this.pictureBoxCustom1 = new Switch_Toolbox.Library.Forms.PictureBoxCustom(); + this.panel3 = new System.Windows.Forms.Panel(); + this.label5 = new System.Windows.Forms.Label(); + this.arrayLevelCounterLabel = new System.Windows.Forms.Label(); + this.btnRightArray = new System.Windows.Forms.Button(); + this.btnLeftArray = new System.Windows.Forms.Button(); + this.imageBGComboBox = new System.Windows.Forms.ComboBox(); + this.label1 = new System.Windows.Forms.Label(); + this.texSizeMipsLabel = new System.Windows.Forms.Label(); + this.mipLevelCounterLabel = new System.Windows.Forms.Label(); + this.BtnMipsRight = new System.Windows.Forms.Button(); + this.BtmMipsLeft = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.replaceSurfaceLevelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exportSurfaceLevelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.panel1.SuspendLayout(); + this.panel2.SuspendLayout(); + this.panel4.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom1)).BeginInit(); + this.panel3.SuspendLayout(); + this.contextMenuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.panel1.Controls.Add(this.propertyGrid1); + this.panel1.Dock = System.Windows.Forms.DockStyle.Top; + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(593, 296); + this.panel1.TabIndex = 1; + // + // propertyGrid1 + // + this.propertyGrid1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.propertyGrid1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40))))); + this.propertyGrid1.CategoryForeColor = System.Drawing.Color.WhiteSmoke; + this.propertyGrid1.CategorySplitterColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.propertyGrid1.CommandsActiveLinkColor = System.Drawing.Color.Red; + this.propertyGrid1.CommandsBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50))))); + this.propertyGrid1.CommandsDisabledLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50))))); + this.propertyGrid1.CommandsForeColor = System.Drawing.Color.White; + this.propertyGrid1.DisabledItemForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255))))); + this.propertyGrid1.HelpBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40))))); + this.propertyGrid1.HelpBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(45)))), ((int)(((byte)(45)))), ((int)(((byte)(45))))); + this.propertyGrid1.HelpForeColor = System.Drawing.Color.White; + this.propertyGrid1.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.propertyGrid1.Location = new System.Drawing.Point(0, 0); + this.propertyGrid1.Name = "propertyGrid1"; + this.propertyGrid1.SelectedItemWithFocusForeColor = System.Drawing.Color.Silver; + this.propertyGrid1.Size = new System.Drawing.Size(593, 299); + this.propertyGrid1.TabIndex = 2; + this.propertyGrid1.ToolbarVisible = false; + this.propertyGrid1.ViewBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40))))); + this.propertyGrid1.ViewBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.propertyGrid1.ViewForeColor = System.Drawing.Color.White; + this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged); + // + // splitter1 + // + this.splitter1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.splitter1.Dock = System.Windows.Forms.DockStyle.Top; + this.splitter1.Location = new System.Drawing.Point(0, 296); + this.splitter1.Name = "splitter1"; + this.splitter1.Size = new System.Drawing.Size(593, 3); + this.splitter1.TabIndex = 2; + this.splitter1.TabStop = false; + // + // panel2 + // + this.panel2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.panel2.Controls.Add(this.panel4); + this.panel2.Controls.Add(this.panel3); + this.panel2.Controls.Add(this.button1); + this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel2.Location = new System.Drawing.Point(0, 299); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(593, 297); + this.panel2.TabIndex = 3; + // + // panel4 + // + this.panel4.Controls.Add(this.pictureBoxCustom1); + this.panel4.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel4.Location = new System.Drawing.Point(0, 80); + this.panel4.Name = "panel4"; + this.panel4.Size = new System.Drawing.Size(593, 217); + this.panel4.TabIndex = 4; + // + // pictureBoxCustom1 + // + this.pictureBoxCustom1.BackColor = System.Drawing.Color.Transparent; + this.pictureBoxCustom1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBoxCustom1.BackgroundImage"))); + this.pictureBoxCustom1.Dock = System.Windows.Forms.DockStyle.Fill; + this.pictureBoxCustom1.Location = new System.Drawing.Point(0, 0); + this.pictureBoxCustom1.Name = "pictureBoxCustom1"; + this.pictureBoxCustom1.Size = new System.Drawing.Size(593, 217); + this.pictureBoxCustom1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBoxCustom1.TabIndex = 0; + this.pictureBoxCustom1.TabStop = false; + // + // panel3 + // + this.panel3.Controls.Add(this.label5); + this.panel3.Controls.Add(this.arrayLevelCounterLabel); + this.panel3.Controls.Add(this.btnRightArray); + this.panel3.Controls.Add(this.btnLeftArray); + this.panel3.Controls.Add(this.imageBGComboBox); + this.panel3.Controls.Add(this.label1); + this.panel3.Controls.Add(this.texSizeMipsLabel); + this.panel3.Controls.Add(this.mipLevelCounterLabel); + this.panel3.Controls.Add(this.BtnMipsRight); + this.panel3.Controls.Add(this.BtmMipsLeft); + this.panel3.Dock = System.Windows.Forms.DockStyle.Top; + this.panel3.Location = new System.Drawing.Point(0, 25); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(593, 55); + this.panel3.TabIndex = 2; + // + // label5 + // + this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label5.AutoSize = true; + this.label5.ForeColor = System.Drawing.Color.White; + this.label5.Location = new System.Drawing.Point(342, 30); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(74, 13); + this.label5.TabIndex = 9; + this.label5.Text = "Array Counter:"; + // + // arrayLevelCounterLabel + // + this.arrayLevelCounterLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.arrayLevelCounterLabel.AutoSize = true; + this.arrayLevelCounterLabel.ForeColor = System.Drawing.Color.White; + this.arrayLevelCounterLabel.Location = new System.Drawing.Point(415, 30); + this.arrayLevelCounterLabel.Name = "arrayLevelCounterLabel"; + this.arrayLevelCounterLabel.Size = new System.Drawing.Size(42, 13); + this.arrayLevelCounterLabel.TabIndex = 8; + this.arrayLevelCounterLabel.Text = "00 / 00"; + // + // btnRightArray + // + this.btnRightArray.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnRightArray.Location = new System.Drawing.Point(533, 26); + this.btnRightArray.Name = "btnRightArray"; + this.btnRightArray.Size = new System.Drawing.Size(57, 21); + this.btnRightArray.TabIndex = 7; + this.btnRightArray.Text = ">"; + this.btnRightArray.UseVisualStyleBackColor = true; + this.btnRightArray.Click += new System.EventHandler(this.btnRightArray_Click); + // + // btnLeftArray + // + this.btnLeftArray.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnLeftArray.Enabled = false; + this.btnLeftArray.Location = new System.Drawing.Point(470, 26); + this.btnLeftArray.Name = "btnLeftArray"; + this.btnLeftArray.Size = new System.Drawing.Size(57, 21); + this.btnLeftArray.TabIndex = 6; + this.btnLeftArray.Text = "<"; + this.btnLeftArray.UseVisualStyleBackColor = true; + this.btnLeftArray.Click += new System.EventHandler(this.btnLeftArray_Click); + // + // imageBGComboBox + // + this.imageBGComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.imageBGComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.imageBGComboBox.FormattingEnabled = true; + this.imageBGComboBox.Location = new System.Drawing.Point(215, 7); + this.imageBGComboBox.Name = "imageBGComboBox"; + this.imageBGComboBox.Size = new System.Drawing.Size(121, 21); + this.imageBGComboBox.TabIndex = 5; + this.imageBGComboBox.SelectedIndexChanged += new System.EventHandler(this.imageBGComboBox_SelectedIndexChanged); + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label1.AutoSize = true; + this.label1.ForeColor = System.Drawing.Color.White; + this.label1.Location = new System.Drawing.Point(342, 7); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(67, 13); + this.label1.TabIndex = 4; + this.label1.Text = "Mip Counter:"; + // + // texSizeMipsLabel + // + this.texSizeMipsLabel.AutoSize = true; + this.texSizeMipsLabel.ForeColor = System.Drawing.Color.White; + this.texSizeMipsLabel.Location = new System.Drawing.Point(127, 34); + this.texSizeMipsLabel.Name = "texSizeMipsLabel"; + this.texSizeMipsLabel.Size = new System.Drawing.Size(42, 13); + this.texSizeMipsLabel.TabIndex = 3; + this.texSizeMipsLabel.Text = "00 / 00"; + // + // mipLevelCounterLabel + // + this.mipLevelCounterLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.mipLevelCounterLabel.AutoSize = true; + this.mipLevelCounterLabel.ForeColor = System.Drawing.Color.White; + this.mipLevelCounterLabel.Location = new System.Drawing.Point(415, 7); + this.mipLevelCounterLabel.Name = "mipLevelCounterLabel"; + this.mipLevelCounterLabel.Size = new System.Drawing.Size(42, 13); + this.mipLevelCounterLabel.TabIndex = 2; + this.mipLevelCounterLabel.Text = "00 / 00"; + // + // BtnMipsRight + // + this.BtnMipsRight.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.BtnMipsRight.Location = new System.Drawing.Point(533, 3); + this.BtnMipsRight.Name = "BtnMipsRight"; + this.BtnMipsRight.Size = new System.Drawing.Size(57, 21); + this.BtnMipsRight.TabIndex = 1; + this.BtnMipsRight.Text = ">"; + this.BtnMipsRight.UseVisualStyleBackColor = true; + this.BtnMipsRight.Click += new System.EventHandler(this.BtnMipsRight_Click); + // + // BtmMipsLeft + // + this.BtmMipsLeft.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.BtmMipsLeft.Enabled = false; + this.BtmMipsLeft.Location = new System.Drawing.Point(470, 3); + this.BtmMipsLeft.Name = "BtmMipsLeft"; + this.BtmMipsLeft.Size = new System.Drawing.Size(57, 21); + this.BtmMipsLeft.TabIndex = 0; + this.BtmMipsLeft.Text = "<"; + this.BtmMipsLeft.UseVisualStyleBackColor = true; + this.BtmMipsLeft.Click += new System.EventHandler(this.BtmMipsLeft_Click); + // + // button1 + // + this.button1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.button1.Dock = System.Windows.Forms.DockStyle.Top; + this.button1.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(90)))), ((int)(((byte)(90)))), ((int)(((byte)(90))))); + this.button1.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Gray; + this.button1.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(90)))), ((int)(((byte)(90)))), ((int)(((byte)(90))))); + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.button1.ForeColor = System.Drawing.Color.White; + this.button1.Location = new System.Drawing.Point(0, 0); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(593, 25); + this.button1.TabIndex = 1; + this.button1.Text = "Hide"; + this.button1.UseVisualStyleBackColor = false; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.replaceSurfaceLevelToolStripMenuItem, + this.exportSurfaceLevelToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(188, 48); + // + // replaceSurfaceLevelToolStripMenuItem + // + this.replaceSurfaceLevelToolStripMenuItem.Name = "replaceSurfaceLevelToolStripMenuItem"; + this.replaceSurfaceLevelToolStripMenuItem.Size = new System.Drawing.Size(187, 22); + this.replaceSurfaceLevelToolStripMenuItem.Text = "Replace Surface Level"; + // + // exportSurfaceLevelToolStripMenuItem + // + this.exportSurfaceLevelToolStripMenuItem.Name = "exportSurfaceLevelToolStripMenuItem"; + this.exportSurfaceLevelToolStripMenuItem.Size = new System.Drawing.Size(187, 22); + this.exportSurfaceLevelToolStripMenuItem.Text = "Export Surface Level"; + // + // NuTexEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.panel2); + this.Controls.Add(this.splitter1); + this.Controls.Add(this.panel1); + this.Name = "NuTexEditor"; + this.Size = new System.Drawing.Size(593, 596); + this.panel1.ResumeLayout(false); + this.panel2.ResumeLayout(false); + this.panel4.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom1)).EndInit(); + this.panel3.ResumeLayout(false); + this.panel3.PerformLayout(); + this.contextMenuStrip1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Splitter splitter1; + private System.Windows.Forms.Panel panel2; + private Switch_Toolbox.Library.Forms.PictureBoxCustom pictureBoxCustom1; + private System.Windows.Forms.PropertyGrid propertyGrid1; + private System.Windows.Forms.Panel panel4; + private System.Windows.Forms.Panel panel3; + private System.Windows.Forms.Label mipLevelCounterLabel; + private System.Windows.Forms.Button BtnMipsRight; + private System.Windows.Forms.Button BtmMipsLeft; + private System.Windows.Forms.Label texSizeMipsLabel; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.ComboBox imageBGComboBox; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label arrayLevelCounterLabel; + private System.Windows.Forms.Button btnRightArray; + private System.Windows.Forms.Button btnLeftArray; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem replaceSurfaceLevelToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exportSurfaceLevelToolStripMenuItem; + } +} diff --git a/Switch_FileFormatsMain/GUI/TextureUI/NuTexEditor.cs b/Switch_FileFormatsMain/GUI/TextureUI/NuTexEditor.cs new file mode 100644 index 00000000..9eacb298 --- /dev/null +++ b/Switch_FileFormatsMain/GUI/TextureUI/NuTexEditor.cs @@ -0,0 +1,208 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using Syroot.NintenTools.NSW.Bntx; +using Syroot.NintenTools.NSW.Bntx.GFX; +using Switch_Toolbox.Library; + +namespace FirstPlugin +{ + public partial class NuTexEditor : UserControl + { + private Thread Thread; + + public NuTexEditor() + { + InitializeComponent(); + + foreach (var type in Enum.GetValues(typeof(Runtime.PictureBoxBG)).Cast()) + imageBGComboBox.Items.Add(type); + + imageBGComboBox.SelectedItem = Runtime.pictureBoxStyle; + UpdateBackgroundImage(); + } + + NUTEXB.NuTex textureData; + + int CurMipDisplayLevel = 0; + int CurArrayDisplayLevel = 0; + + class PropGridData + { + public string Name { get; set; } + public string Format { get; set; } + public uint Width { get; set; } + public uint Height { get; set; } + public uint MipCount { get; set; } + public uint ArrayCount { get; set; } + } + public void LoadProperty(NUTEXB.NuTex tex) + { + pictureBoxCustom1.Image = Imaging.GetLoadingImage(); + LoadImage(); + + CurMipDisplayLevel = 0; + CurArrayDisplayLevel = 0; + + textureData = tex; + + UpdateMipDisplay(); + + PropGridData prop = new PropGridData(); + prop.Name = textureData.Text; + prop.Width = textureData.Width; + prop.Height = textureData.Height; + if (textureData.mipmaps.Count > 0) + { + prop.MipCount = (uint)textureData.mipmaps[CurArrayDisplayLevel].Count; + prop.ArrayCount = (uint)textureData.mipmaps.Count; + } + prop.Height = textureData.Height; + + prop.Format = ((NUTEXB.NUTEXImageFormat)textureData.Format).ToString(); + + propertyGrid1.PropertySort = PropertySort.Categorized; + propertyGrid1.SelectedObject = prop; + } + private void LoadImage() + { + Thread = new Thread((ThreadStart)(() => + { + pictureBoxCustom1.Image = Imaging.GetLoadingImage(); + pictureBoxCustom1.Image = textureData.DisplayTexture(CurArrayDisplayLevel, CurMipDisplayLevel); + })); + Thread.Start(); + + GC.Collect(); + } + private void UpdateMipDisplay() + { + LoadImage(); + + int MipCount = 1; + if (textureData.mipmaps.Count <= 0) + return; + else + MipCount = textureData.mipmaps[CurArrayDisplayLevel].Count; + + + mipLevelCounterLabel.Text = $"{CurMipDisplayLevel} / {textureData.mipmaps[CurArrayDisplayLevel].Count - 1}"; + arrayLevelCounterLabel.Text = $"{CurArrayDisplayLevel} / {textureData.mipmaps.Count - 1}"; + + if (CurMipDisplayLevel != MipCount - 1) + BtnMipsRight.Enabled = true; + else + BtnMipsRight.Enabled = false; + + if (CurMipDisplayLevel != 0) + BtmMipsLeft.Enabled = true; + else + BtmMipsLeft.Enabled = false; + + if (CurArrayDisplayLevel != textureData.mipmaps.Count - 1) + btnRightArray.Enabled = true; + else + btnRightArray.Enabled = false; + + if (CurArrayDisplayLevel != 0) + btnLeftArray.Enabled = true; + else + btnLeftArray.Enabled = false; + } + + bool IsHidden = false; + private void button1_Click(object sender, EventArgs e) + { + if (IsHidden) + { + panel1.Visible = true; + IsHidden = false; + button1.Text = "Hide"; + } + else + { + panel1.Visible = false; + IsHidden = true; + button1.Text = "Show"; + } + } + + private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) + { + if (propertyGrid1.SelectedObject != null) + { + Texture tex = (Texture)propertyGrid1.SelectedObject; + textureData.Text = tex.Name; + } + } + + private void BtmMipsLeft_Click(object sender, EventArgs e) + { + if (CurMipDisplayLevel != 0) + CurMipDisplayLevel -= 1; + + UpdateMipDisplay(); + } + + private void BtnMipsRight_Click(object sender, EventArgs e) + { + if (CurMipDisplayLevel != textureData.mipmaps[CurArrayDisplayLevel].Count - 1) + CurMipDisplayLevel += 1; + + UpdateMipDisplay(); + } + + private void btnLeftArray_Click(object sender, EventArgs e) + { + if (CurArrayDisplayLevel != 0) + CurArrayDisplayLevel -= 1; + + UpdateMipDisplay(); + } + + private void btnRightArray_Click(object sender, EventArgs e) + { + if (CurArrayDisplayLevel != textureData.mipmaps.Count - 1) + CurArrayDisplayLevel += 1; + + UpdateMipDisplay(); + } + + + private void UpdateBackgroundImage() + { + switch (Runtime.pictureBoxStyle) + { + case Runtime.PictureBoxBG.Black: + pictureBoxCustom1.BackColor = Color.Black; + pictureBoxCustom1.BackgroundImage = null; + break; + case Runtime.PictureBoxBG.Checkerboard: + pictureBoxCustom1.BackColor = Color.Transparent; + pictureBoxCustom1.BackgroundImage = pictureBoxCustom1.GetCheckerBackground(); + break; + } + } + + private void imageBGComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + Runtime.pictureBoxStyle = (Runtime.PictureBoxBG)imageBGComboBox.SelectedItem; + UpdateBackgroundImage(); + } + + private void btnEdit_Click(object sender, EventArgs e) + { + Button btnSender = (Button)sender; + Point ptLowerLeft = new Point(0, btnSender.Height); + ptLowerLeft = btnSender.PointToScreen(ptLowerLeft); + contextMenuStrip1.Show(ptLowerLeft); + } + } +} diff --git a/Switch_FileFormatsMain/GUI/TextureUI/NuTexEditor.resx b/Switch_FileFormatsMain/GUI/TextureUI/NuTexEditor.resx new file mode 100644 index 00000000..3572d1d7 --- /dev/null +++ b/Switch_FileFormatsMain/GUI/TextureUI/NuTexEditor.resx @@ -0,0 +1,331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAACJuGjuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEXMzMzNzc3Ozs7Pz8/Q0NDR0dHS + 0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm + 5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6 + +vr7+/v8/Pz9/f3+/v7///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDTbOhAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGXRF + 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 + + + + 17, 17 + + \ No newline at end of file diff --git a/Switch_FileFormatsMain/GUI/TextureUI/XTXEditor.Designer.cs b/Switch_FileFormatsMain/GUI/TextureUI/XTXEditor.Designer.cs new file mode 100644 index 00000000..8fb8d895 --- /dev/null +++ b/Switch_FileFormatsMain/GUI/TextureUI/XTXEditor.Designer.cs @@ -0,0 +1,296 @@ +namespace FirstPlugin +{ + partial class XTXEditor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(XTXEditor)); + this.panel1 = new System.Windows.Forms.Panel(); + this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); + this.splitter1 = new System.Windows.Forms.Splitter(); + this.panel2 = new System.Windows.Forms.Panel(); + this.panel4 = new System.Windows.Forms.Panel(); + this.pictureBoxCustom1 = new Switch_Toolbox.Library.Forms.PictureBoxCustom(); + this.panel3 = new System.Windows.Forms.Panel(); + this.imageBGComboBox = new System.Windows.Forms.ComboBox(); + this.label1 = new System.Windows.Forms.Label(); + this.texSizeMipsLabel = new System.Windows.Forms.Label(); + this.mipLevelCounterLabel = new System.Windows.Forms.Label(); + this.BtnMipsRight = new System.Windows.Forms.Button(); + this.BtmMipsLeft = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.replaceSurfaceLevelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exportSurfaceLevelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.panel1.SuspendLayout(); + this.panel2.SuspendLayout(); + this.panel4.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom1)).BeginInit(); + this.panel3.SuspendLayout(); + this.contextMenuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.panel1.Controls.Add(this.propertyGrid1); + this.panel1.Dock = System.Windows.Forms.DockStyle.Top; + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(593, 296); + this.panel1.TabIndex = 1; + // + // propertyGrid1 + // + this.propertyGrid1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.propertyGrid1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40))))); + this.propertyGrid1.CategoryForeColor = System.Drawing.Color.WhiteSmoke; + this.propertyGrid1.CategorySplitterColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.propertyGrid1.CommandsActiveLinkColor = System.Drawing.Color.Red; + this.propertyGrid1.CommandsBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50))))); + this.propertyGrid1.CommandsDisabledLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50))))); + this.propertyGrid1.CommandsForeColor = System.Drawing.Color.White; + this.propertyGrid1.DisabledItemForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255))))); + this.propertyGrid1.HelpBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40))))); + this.propertyGrid1.HelpBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(45)))), ((int)(((byte)(45)))), ((int)(((byte)(45))))); + this.propertyGrid1.HelpForeColor = System.Drawing.Color.White; + this.propertyGrid1.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.propertyGrid1.Location = new System.Drawing.Point(0, 0); + this.propertyGrid1.Name = "propertyGrid1"; + this.propertyGrid1.SelectedItemWithFocusForeColor = System.Drawing.Color.Silver; + this.propertyGrid1.Size = new System.Drawing.Size(593, 299); + this.propertyGrid1.TabIndex = 2; + this.propertyGrid1.ToolbarVisible = false; + this.propertyGrid1.ViewBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40))))); + this.propertyGrid1.ViewBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.propertyGrid1.ViewForeColor = System.Drawing.Color.White; + this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged); + // + // splitter1 + // + this.splitter1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.splitter1.Dock = System.Windows.Forms.DockStyle.Top; + this.splitter1.Location = new System.Drawing.Point(0, 296); + this.splitter1.Name = "splitter1"; + this.splitter1.Size = new System.Drawing.Size(593, 3); + this.splitter1.TabIndex = 2; + this.splitter1.TabStop = false; + // + // panel2 + // + this.panel2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.panel2.Controls.Add(this.panel4); + this.panel2.Controls.Add(this.panel3); + this.panel2.Controls.Add(this.button1); + this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel2.Location = new System.Drawing.Point(0, 299); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(593, 297); + this.panel2.TabIndex = 3; + // + // panel4 + // + this.panel4.Controls.Add(this.pictureBoxCustom1); + this.panel4.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel4.Location = new System.Drawing.Point(0, 80); + this.panel4.Name = "panel4"; + this.panel4.Size = new System.Drawing.Size(593, 217); + this.panel4.TabIndex = 4; + // + // pictureBoxCustom1 + // + this.pictureBoxCustom1.BackColor = System.Drawing.Color.Transparent; + this.pictureBoxCustom1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBoxCustom1.BackgroundImage"))); + this.pictureBoxCustom1.Dock = System.Windows.Forms.DockStyle.Fill; + this.pictureBoxCustom1.Location = new System.Drawing.Point(0, 0); + this.pictureBoxCustom1.Name = "pictureBoxCustom1"; + this.pictureBoxCustom1.Size = new System.Drawing.Size(593, 217); + this.pictureBoxCustom1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBoxCustom1.TabIndex = 0; + this.pictureBoxCustom1.TabStop = false; + // + // panel3 + // + this.panel3.Controls.Add(this.imageBGComboBox); + this.panel3.Controls.Add(this.label1); + this.panel3.Controls.Add(this.texSizeMipsLabel); + this.panel3.Controls.Add(this.mipLevelCounterLabel); + this.panel3.Controls.Add(this.BtnMipsRight); + this.panel3.Controls.Add(this.BtmMipsLeft); + this.panel3.Dock = System.Windows.Forms.DockStyle.Top; + this.panel3.Location = new System.Drawing.Point(0, 25); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(593, 55); + this.panel3.TabIndex = 2; + // + // imageBGComboBox + // + this.imageBGComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.imageBGComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.imageBGComboBox.FormattingEnabled = true; + this.imageBGComboBox.Location = new System.Drawing.Point(215, 7); + this.imageBGComboBox.Name = "imageBGComboBox"; + this.imageBGComboBox.Size = new System.Drawing.Size(121, 21); + this.imageBGComboBox.TabIndex = 5; + this.imageBGComboBox.SelectedIndexChanged += new System.EventHandler(this.imageBGComboBox_SelectedIndexChanged); + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label1.AutoSize = true; + this.label1.ForeColor = System.Drawing.Color.White; + this.label1.Location = new System.Drawing.Point(342, 7); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(67, 13); + this.label1.TabIndex = 4; + this.label1.Text = "Mip Counter:"; + // + // texSizeMipsLabel + // + this.texSizeMipsLabel.AutoSize = true; + this.texSizeMipsLabel.ForeColor = System.Drawing.Color.White; + this.texSizeMipsLabel.Location = new System.Drawing.Point(127, 34); + this.texSizeMipsLabel.Name = "texSizeMipsLabel"; + this.texSizeMipsLabel.Size = new System.Drawing.Size(42, 13); + this.texSizeMipsLabel.TabIndex = 3; + this.texSizeMipsLabel.Text = "00 / 00"; + // + // mipLevelCounterLabel + // + this.mipLevelCounterLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.mipLevelCounterLabel.AutoSize = true; + this.mipLevelCounterLabel.ForeColor = System.Drawing.Color.White; + this.mipLevelCounterLabel.Location = new System.Drawing.Point(415, 7); + this.mipLevelCounterLabel.Name = "mipLevelCounterLabel"; + this.mipLevelCounterLabel.Size = new System.Drawing.Size(42, 13); + this.mipLevelCounterLabel.TabIndex = 2; + this.mipLevelCounterLabel.Text = "00 / 00"; + // + // BtnMipsRight + // + this.BtnMipsRight.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.BtnMipsRight.Location = new System.Drawing.Point(533, 3); + this.BtnMipsRight.Name = "BtnMipsRight"; + this.BtnMipsRight.Size = new System.Drawing.Size(57, 21); + this.BtnMipsRight.TabIndex = 1; + this.BtnMipsRight.Text = ">"; + this.BtnMipsRight.UseVisualStyleBackColor = true; + this.BtnMipsRight.Click += new System.EventHandler(this.BtnMipsRight_Click); + // + // BtmMipsLeft + // + this.BtmMipsLeft.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.BtmMipsLeft.Enabled = false; + this.BtmMipsLeft.Location = new System.Drawing.Point(470, 3); + this.BtmMipsLeft.Name = "BtmMipsLeft"; + this.BtmMipsLeft.Size = new System.Drawing.Size(57, 21); + this.BtmMipsLeft.TabIndex = 0; + this.BtmMipsLeft.Text = "<"; + this.BtmMipsLeft.UseVisualStyleBackColor = true; + this.BtmMipsLeft.Click += new System.EventHandler(this.BtmMipsLeft_Click); + // + // button1 + // + this.button1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.button1.Dock = System.Windows.Forms.DockStyle.Top; + this.button1.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(90)))), ((int)(((byte)(90)))), ((int)(((byte)(90))))); + this.button1.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Gray; + this.button1.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(90)))), ((int)(((byte)(90)))), ((int)(((byte)(90))))); + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.button1.ForeColor = System.Drawing.Color.White; + this.button1.Location = new System.Drawing.Point(0, 0); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(593, 25); + this.button1.TabIndex = 1; + this.button1.Text = "Hide"; + this.button1.UseVisualStyleBackColor = false; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.replaceSurfaceLevelToolStripMenuItem, + this.exportSurfaceLevelToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(188, 48); + // + // replaceSurfaceLevelToolStripMenuItem + // + this.replaceSurfaceLevelToolStripMenuItem.Name = "replaceSurfaceLevelToolStripMenuItem"; + this.replaceSurfaceLevelToolStripMenuItem.Size = new System.Drawing.Size(187, 22); + this.replaceSurfaceLevelToolStripMenuItem.Text = "Replace Surface Level"; + // + // exportSurfaceLevelToolStripMenuItem + // + this.exportSurfaceLevelToolStripMenuItem.Name = "exportSurfaceLevelToolStripMenuItem"; + this.exportSurfaceLevelToolStripMenuItem.Size = new System.Drawing.Size(187, 22); + this.exportSurfaceLevelToolStripMenuItem.Text = "Export Surface Level"; + // + // XTXEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.panel2); + this.Controls.Add(this.splitter1); + this.Controls.Add(this.panel1); + this.Name = "XTXEditor"; + this.Size = new System.Drawing.Size(593, 596); + this.panel1.ResumeLayout(false); + this.panel2.ResumeLayout(false); + this.panel4.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom1)).EndInit(); + this.panel3.ResumeLayout(false); + this.panel3.PerformLayout(); + this.contextMenuStrip1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Splitter splitter1; + private System.Windows.Forms.Panel panel2; + private Switch_Toolbox.Library.Forms.PictureBoxCustom pictureBoxCustom1; + private System.Windows.Forms.PropertyGrid propertyGrid1; + private System.Windows.Forms.Panel panel4; + private System.Windows.Forms.Panel panel3; + private System.Windows.Forms.Label mipLevelCounterLabel; + private System.Windows.Forms.Button BtnMipsRight; + private System.Windows.Forms.Button BtmMipsLeft; + private System.Windows.Forms.Label texSizeMipsLabel; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.ComboBox imageBGComboBox; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem replaceSurfaceLevelToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exportSurfaceLevelToolStripMenuItem; + } +} diff --git a/Switch_FileFormatsMain/GUI/TextureUI/XTXEditor.cs b/Switch_FileFormatsMain/GUI/TextureUI/XTXEditor.cs new file mode 100644 index 00000000..2dcde06d --- /dev/null +++ b/Switch_FileFormatsMain/GUI/TextureUI/XTXEditor.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using Syroot.NintenTools.NSW.Bntx; +using Syroot.NintenTools.NSW.Bntx.GFX; +using Switch_Toolbox.Library; + +namespace FirstPlugin +{ + public partial class XTXEditor : UserControl + { + private Thread Thread; + + public XTXEditor() + { + InitializeComponent(); + + foreach (var type in Enum.GetValues(typeof(Runtime.PictureBoxBG)).Cast()) + imageBGComboBox.Items.Add(type); + + imageBGComboBox.SelectedItem = Runtime.pictureBoxStyle; + UpdateBackgroundImage(); + } + + XTX.XTXFile.TextureInfo textureData; + + int CurMipDisplayLevel = 0; + int CurArrayDisplayLevel = 0; + + class PropGridData + { + public string Name { get; set; } + public string Format { get; set; } + public uint Width { get; set; } + public uint Height { get; set; } + public uint MipCount { get; set; } + public uint ArrayCount { get; set; } + } + public void LoadProperty(XTX.XTXFile.TextureInfo tex) + { + pictureBoxCustom1.Image = Imaging.GetLoadingImage(); + LoadImage(); + + CurMipDisplayLevel = 0; + CurArrayDisplayLevel = 0; + + textureData = tex; + + UpdateMipDisplay(); + + PropGridData prop = new PropGridData(); + prop.Name = textureData.Text; + prop.Width = textureData.Width; + prop.Height = textureData.Height; + // prop.MipCount = (uint)textureData.blocksCompressed[0].Count; + // prop.ArrayCount = (uint)textureData.blocksCompressed.Count; + prop.Height = textureData.Height; + + prop.Format = ((NUTEXB.NUTEXImageFormat)textureData.Format).ToString(); + + propertyGrid1.PropertySort = PropertySort.Categorized; + propertyGrid1.SelectedObject = prop; + } + private void LoadImage() + { + Thread = new Thread((ThreadStart)(() => + { + pictureBoxCustom1.Image = Imaging.GetLoadingImage(); + pictureBoxCustom1.Image = textureData.DisplayImage(CurMipDisplayLevel, CurArrayDisplayLevel); + })); + Thread.Start(); + + GC.Collect(); + } + private void UpdateMipDisplay() + { + LoadImage(); + + int MipCount = 1; + if (textureData.mipmaps.Count <= 0) + return; + else + MipCount = textureData.mipmaps.Count; + + + mipLevelCounterLabel.Text = $"{CurMipDisplayLevel} / {textureData.mipmaps.Count - 1}"; + + if (CurMipDisplayLevel != MipCount - 1) + BtnMipsRight.Enabled = true; + else + BtnMipsRight.Enabled = false; + + if (CurMipDisplayLevel != 0) + BtmMipsLeft.Enabled = true; + else + BtmMipsLeft.Enabled = false; + } + + bool IsHidden = false; + private void button1_Click(object sender, EventArgs e) + { + if (IsHidden) + { + panel1.Visible = true; + IsHidden = false; + button1.Text = "Hide"; + } + else + { + panel1.Visible = false; + IsHidden = true; + button1.Text = "Show"; + } + } + + private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) + { + if (propertyGrid1.SelectedObject != null) + { + Texture tex = (Texture)propertyGrid1.SelectedObject; + textureData.Text = tex.Name; + } + } + + private void BtmMipsLeft_Click(object sender, EventArgs e) + { + if (CurMipDisplayLevel != 0) + CurMipDisplayLevel -= 1; + + UpdateMipDisplay(); + } + + private void BtnMipsRight_Click(object sender, EventArgs e) + { + if (CurMipDisplayLevel != textureData.mipmaps.Count - 1) + CurMipDisplayLevel += 1; + + UpdateMipDisplay(); + } + + private void UpdateBackgroundImage() + { + switch (Runtime.pictureBoxStyle) + { + case Runtime.PictureBoxBG.Black: + pictureBoxCustom1.BackColor = Color.Black; + pictureBoxCustom1.BackgroundImage = null; + break; + case Runtime.PictureBoxBG.Checkerboard: + pictureBoxCustom1.BackColor = Color.Transparent; + pictureBoxCustom1.BackgroundImage = pictureBoxCustom1.GetCheckerBackground(); + break; + } + } + + private void imageBGComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + Runtime.pictureBoxStyle = (Runtime.PictureBoxBG)imageBGComboBox.SelectedItem; + UpdateBackgroundImage(); + } + + private void btnEdit_Click(object sender, EventArgs e) + { + Button btnSender = (Button)sender; + Point ptLowerLeft = new Point(0, btnSender.Height); + ptLowerLeft = btnSender.PointToScreen(ptLowerLeft); + contextMenuStrip1.Show(ptLowerLeft); + } + } +} diff --git a/Switch_FileFormatsMain/GUI/TextureUI/XTXEditor.resx b/Switch_FileFormatsMain/GUI/TextureUI/XTXEditor.resx new file mode 100644 index 00000000..3572d1d7 --- /dev/null +++ b/Switch_FileFormatsMain/GUI/TextureUI/XTXEditor.resx @@ -0,0 +1,331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAACJuGjuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEXMzMzNzc3Ozs7Pz8/Q0NDR0dHS + 0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm + 5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6 + +vr7+/v8/Pz9/f3+/v7///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDTbOhAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGXRF + 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 + + + + 17, 17 + + \ No newline at end of file diff --git a/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj b/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj index 8603e5fb..da264030 100644 --- a/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj +++ b/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj @@ -267,10 +267,16 @@ BfresShapeEditor.cs - + UserControl - + + XTXEditor.cs + + + UserControl + + NuTexEditor.cs @@ -418,7 +424,10 @@ BfresShapeEditor.cs - + + XTXEditor.cs + + NuTexEditor.cs diff --git a/Switch_Toolbox.sln b/Switch_Toolbox.sln index 65455d44..9f0653d4 100644 --- a/Switch_Toolbox.sln +++ b/Switch_Toolbox.sln @@ -18,6 +18,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Updater", "Updater\Updater. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "Switch_Toolbox\Lib\DirectXTex\DirectXTex.vcxproj", "{755AB64B-16B4-4C90-AA3B-BFF448E5A21E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GTXDEBUG", "GTXDEBUG\GTXDEBUG.csproj", "{C610B02F-97AE-48A8-B967-1F4E97DB2903}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -73,6 +75,14 @@ Global {755AB64B-16B4-4C90-AA3B-BFF448E5A21E}.Release|Any CPU.Build.0 = Release|Win32 {755AB64B-16B4-4C90-AA3B-BFF448E5A21E}.Release|x64.ActiveCfg = Release|x64 {755AB64B-16B4-4C90-AA3B-BFF448E5A21E}.Release|x64.Build.0 = Release|x64 + {C610B02F-97AE-48A8-B967-1F4E97DB2903}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C610B02F-97AE-48A8-B967-1F4E97DB2903}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C610B02F-97AE-48A8-B967-1F4E97DB2903}.Debug|x64.ActiveCfg = Debug|Any CPU + {C610B02F-97AE-48A8-B967-1F4E97DB2903}.Debug|x64.Build.0 = Debug|Any CPU + {C610B02F-97AE-48A8-B967-1F4E97DB2903}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C610B02F-97AE-48A8-B967-1F4E97DB2903}.Release|Any CPU.Build.0 = Release|Any CPU + {C610B02F-97AE-48A8-B967-1F4E97DB2903}.Release|x64.ActiveCfg = Release|Any CPU + {C610B02F-97AE-48A8-B967-1F4E97DB2903}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Switch_Toolbox/Lib/DirectXTex.dll b/Switch_Toolbox/Lib/DirectXTex.dll index c839ab80..06f75cf5 100644 Binary files a/Switch_Toolbox/Lib/DirectXTex.dll and b/Switch_Toolbox/Lib/DirectXTex.dll differ diff --git a/Switch_Toolbox/Lib/DirectXTex.iobj b/Switch_Toolbox/Lib/DirectXTex.iobj index 8ee4d3ea..794e3c7d 100644 Binary files a/Switch_Toolbox/Lib/DirectXTex.iobj and b/Switch_Toolbox/Lib/DirectXTex.iobj differ diff --git a/Switch_Toolbox/Lib/DirectXTex.ipdb b/Switch_Toolbox/Lib/DirectXTex.ipdb index 54aa79cb..24ac227e 100644 Binary files a/Switch_Toolbox/Lib/DirectXTex.ipdb and b/Switch_Toolbox/Lib/DirectXTex.ipdb differ diff --git a/Switch_Toolbox/Lib/DirectXTex.zip b/Switch_Toolbox/Lib/DirectXTex.zip index bb67df37..ca4d1919 100644 Binary files a/Switch_Toolbox/Lib/DirectXTex.zip and b/Switch_Toolbox/Lib/DirectXTex.zip differ diff --git a/Switch_Toolbox/Lib/DirectXTex/.vs/DirectXTex/v15/Browse.VC.db b/Switch_Toolbox/Lib/DirectXTex/.vs/DirectXTex/v15/Browse.VC.db new file mode 100644 index 00000000..9c7660f0 Binary files /dev/null and b/Switch_Toolbox/Lib/DirectXTex/.vs/DirectXTex/v15/Browse.VC.db differ diff --git a/Switch_Toolbox/Lib/DirectXTex/.vs/DirectXTex/v15/Browse.VC.opendb b/Switch_Toolbox/Lib/DirectXTex/.vs/DirectXTex/v15/Browse.VC.opendb new file mode 100644 index 00000000..cb68b727 Binary files /dev/null and b/Switch_Toolbox/Lib/DirectXTex/.vs/DirectXTex/v15/Browse.VC.opendb differ diff --git a/Switch_Toolbox/Lib/DirectXTex/wrapper.cpp b/Switch_Toolbox/Lib/DirectXTex/wrapper.cpp index e770fed6..f147edf8 100644 --- a/Switch_Toolbox/Lib/DirectXTex/wrapper.cpp +++ b/Switch_Toolbox/Lib/DirectXTex/wrapper.cpp @@ -55,6 +55,7 @@ namespace DirectXTex inputImage.slicePitch = slicePitch; DirectX::ScratchImage outputImage; + // decompress image DirectX::Decompress(inputImage, DXGI_FORMAT_R8G8B8A8_UNORM, outputImage); diff --git a/Switch_Toolbox/Resources/0x1d5f890b8.XTEX b/Switch_Toolbox/Resources/0x1d5f890b8.XTEX new file mode 100644 index 00000000..bbb05480 Binary files /dev/null and b/Switch_Toolbox/Resources/0x1d5f890b8.XTEX differ diff --git a/Switch_Toolbox_Library/FileFormats/DDS.cs b/Switch_Toolbox_Library/FileFormats/DDS.cs index c9bf17a6..57236072 100644 --- a/Switch_Toolbox_Library/FileFormats/DDS.cs +++ b/Switch_Toolbox_Library/FileFormats/DDS.cs @@ -418,6 +418,7 @@ namespace Switch_Toolbox.Library case DXGI_FORMAT.DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB: + header.ddspf.flags = (uint)DDPF.FOURCC; header.ddspf.fourCC = "DX10"; if (DX10header == null) DX10header = new DX10Header(); diff --git a/Switch_Toolbox_Library/IO/FileIO.cs b/Switch_Toolbox_Library/IO/FileIO.cs index 8f091aec..9975052f 100644 --- a/Switch_Toolbox_Library/IO/FileIO.cs +++ b/Switch_Toolbox_Library/IO/FileIO.cs @@ -158,6 +158,10 @@ namespace Switch_Toolbox.Library.IO { Write(Encoding.ASCII.GetBytes(value)); } + public void WriteString(string value) + { + Write(value, BinaryStringFormat.ZeroTerminated); + } public void WriteUint64Offset(long target) { long pos = Position; diff --git a/Switch_Toolbox_Library/Rendering/RenderLib.cs b/Switch_Toolbox_Library/Rendering/RenderLib.cs index adf959a1..b880c61b 100644 --- a/Switch_Toolbox_Library/Rendering/RenderLib.cs +++ b/Switch_Toolbox_Library/Rendering/RenderLib.cs @@ -473,7 +473,6 @@ namespace Switch_Toolbox.Library.Rendering public List boneWeights = new List(); public List boneNames = new List(); - public List weights = new List(); public List boneList = new List(); public class Bone diff --git a/Switch_Toolbox_Library/Switch_Toolbox_Library.csproj b/Switch_Toolbox_Library/Switch_Toolbox_Library.csproj index 2024f195..064e7cb5 100644 --- a/Switch_Toolbox_Library/Switch_Toolbox_Library.csproj +++ b/Switch_Toolbox_Library/Switch_Toolbox_Library.csproj @@ -108,7 +108,6 @@ -