diff --git a/.vs/Switch_Toolbox/v15/.suo b/.vs/Switch_Toolbox/v15/.suo index e9dbd1d9..dbae0e56 100644 Binary files a/.vs/Switch_Toolbox/v15/.suo and b/.vs/Switch_Toolbox/v15/.suo differ diff --git a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide index 9c7b71b0..9e7b9045 100644 Binary files a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide and b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide differ diff --git a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm index 81b9777d..8c0e92dd 100644 Binary files a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm and b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm differ diff --git a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal index eb7a5609..363d7d7f 100644 Binary files a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal and b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal differ diff --git a/Switch_FileFormatsMain/FileFormats/BFRES/BFRES.cs b/Switch_FileFormatsMain/FileFormats/BFRES/BFRES.cs index 0cb9897d..b42577da 100644 --- a/Switch_FileFormatsMain/FileFormats/BFRES/BFRES.cs +++ b/Switch_FileFormatsMain/FileFormats/BFRES/BFRES.cs @@ -72,10 +72,12 @@ namespace FirstPlugin public MenuExt() { + // toolExt[0] = new STToolStripItem("Models"); + // toolExt[0].DropDownItems.Add(new STToolStripItem("Batch Export (BFRES)", Export)); + editExt[0] = new STToolStripItem("Use Advanced Editor As Default", AdvancedEditor); newFileExt[0] = new STToolStripItem("BFRES (Switch)", NewSwitchBfres); newFileExt[1] = new STToolStripItem("BFRES (Wii U)", NewWiiUBfres); - editExt[0].Checked = !PluginRuntime.UseSimpleBfresEditor; } @@ -142,6 +144,71 @@ namespace FirstPlugin debugInfo.Show(); debugInfo.PrintDebugInfo(ofd.FileName); } + + private void Export(object sender, EventArgs args) + { + string formats = FileFilters.FMDL_EXPORT; + + string[] forms = formats.Split('|'); + + List Formats = new List(); + for (int i = 0; i < forms.Length; i++) + { + if (i > 1 || i == (forms.Length - 1)) //Skip lines with all extensions + { + if (!forms[i].StartsWith("*")) + Formats.Add(forms[i]); + } + } + + BatchFormatExport form = new BatchFormatExport(Formats); + if (form.ShowDialog() == DialogResult.OK) + { + string Extension = form.GetSelectedExtension(); + + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Multiselect = true; + ofd.Filter = Utils.GetAllFilters(new Type[] { typeof(BFRES), typeof(SARC) }); + + if (ofd.ShowDialog() == DialogResult.OK) + { + FolderSelectDialog folderDialog = new FolderSelectDialog(); + if (folderDialog.ShowDialog() == DialogResult.OK) + { + foreach (string file in ofd.FileNames) + { + var FileFormat = STFileLoader.OpenFileFormat(file, new Type[] { typeof(BFRES), typeof(SARC) }); + if (FileFormat == null) + continue; + + SearchBinary(FileFormat, folderDialog.SelectedPath, Extension); + } + } + } + } + } + + private void SearchBinary(IFileFormat FileFormat, string Folder, string Extension) + { + if (FileFormat is SARC) + { + foreach (var file in ((SARC)FileFormat).Files) + { + Console.WriteLine($"{FileFormat.FileName} {file.Text}"); + var archiveFile = STFileLoader.OpenFileFormat(file.FullName, new Type[] { typeof(BFRES), typeof(SARC) }, file.Data); + if (archiveFile == null) + continue; + + SearchBinary(archiveFile, Folder, Extension); + } + } + if (FileFormat is BFRES) + { + // ((BFRES)FileFormat).Export(Path.Combine(Folder, $"{FileFormat.FileName}{Extension}")); + } + + FileFormat.Unload(); + } } private static byte[] CreateNewBFRESSwitch(string Name) diff --git a/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache b/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache index 608bff0d..65703281 100644 Binary files a/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache and b/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache differ diff --git a/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache b/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache index d7855e1b..2f114320 100644 Binary files a/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache and b/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache differ diff --git a/Switch_Toolbox_Library/Config.cs b/Switch_Toolbox_Library/Config.cs index 19721cc1..3a164479 100644 --- a/Switch_Toolbox_Library/Config.cs +++ b/Switch_Toolbox_Library/Config.cs @@ -231,6 +231,9 @@ namespace Switch_Toolbox.Library case "FrameCamera": bool.TryParse(node.InnerText, out Runtime.FrameCamera); break; + case "UseDirectXTexDecoder": + bool.TryParse(node.InnerText, out Runtime.UseDirectXTexDecoder); + break; } } } @@ -353,6 +356,7 @@ namespace Switch_Toolbox.Library XmlNode mainSettingsNode = doc.CreateElement("MAINFORM"); parentNode.AppendChild(mainSettingsNode); + mainSettingsNode.AppendChild(createNode(doc, "UseDirectXTexDecoder", Runtime.UseDirectXTexDecoder.ToString())); mainSettingsNode.AppendChild(createNode(doc, "DisplayViewport", Runtime.DisplayViewport.ToString())); mainSettingsNode.AppendChild(createNode(doc, "UseOpenGL", Runtime.UseOpenGL.ToString())); mainSettingsNode.AppendChild(createNode(doc, "UseDebugDomainExceptionHandler", Runtime.UseDebugDomainExceptionHandler.ToString())); diff --git a/Switch_Toolbox_Library/FileFormats/DDSCompressor.cs b/Switch_Toolbox_Library/FileFormats/DDSCompressor.cs index 749ced87..d304d7a7 100644 --- a/Switch_Toolbox_Library/FileFormats/DDSCompressor.cs +++ b/Switch_Toolbox_Library/FileFormats/DDSCompressor.cs @@ -237,13 +237,11 @@ namespace Switch_Toolbox.Library int W = (width + 3) / 4; int H = (height + 3) / 4; - byte[] Output = new byte[W * H * 64]; for (int Y = 0; Y < H; Y++) { for (int X = 0; X < W; X++) - { int IOffs = (Y * W + X) * 16; byte[] Red = new byte[8]; diff --git a/Switch_Toolbox_Library/Generics/GenericTexture.cs b/Switch_Toolbox_Library/Generics/GenericTexture.cs index 5689c5b3..dfee79c9 100644 --- a/Switch_Toolbox_Library/Generics/GenericTexture.cs +++ b/Switch_Toolbox_Library/Generics/GenericTexture.cs @@ -377,10 +377,16 @@ namespace Switch_Toolbox.Library case TEX_FORMAT.ETC1_A4: return BitmapExtension.GetBitmap(ETC1.ETC1Decompress(data, (int)width, (int)height, true), (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - default: - return BitmapExtension.GetBitmap(DecodeBlock(data, width, height, Format), - (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); } + + if (Runtime.UseDirectXTexDecoder) + { + return BitmapExtension.GetBitmap(DecodeBlock(data, width, height, Format), + (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + } + else + return DecodeNotDirectXTex(data, width, height, Format); + } catch (Exception ex) { @@ -388,29 +394,7 @@ namespace Switch_Toolbox.Library try { - if (Format == TEX_FORMAT.BC1_UNORM) - return DDSCompressor.DecompressBC1(data, (int)Width, (int)Height, false); - else if (Format == TEX_FORMAT.BC1_UNORM_SRGB) - return DDSCompressor.DecompressBC1(data, (int)Width, (int)Height, true); - else if (Format == TEX_FORMAT.BC3_UNORM_SRGB) - return DDSCompressor.DecompressBC3(data, (int)Width, (int)Height, false); - else if (Format == TEX_FORMAT.BC3_UNORM) - return DDSCompressor.DecompressBC3(data, (int)Width, (int)Height, true); - else if (Format == TEX_FORMAT.BC4_UNORM) - return DDSCompressor.DecompressBC4(data, (int)Width, (int)Height, false); - else if (Format == TEX_FORMAT.BC4_SNORM) - return DDSCompressor.DecompressBC4(data, (int)Width, (int)Height, true); - else if (Format == TEX_FORMAT.BC5_UNORM) - return DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, false); - else - { - if (Runtime.UseOpenGL) - { - Runtime.OpenTKInitialized = true; - LoadOpenGLTexture(); - return RenderableTex.GLTextureToBitmap(RenderableTex); - } - } + return DecodeNotDirectXTex(data, width, height, Format); } catch { @@ -421,6 +405,40 @@ namespace Switch_Toolbox.Library } } + private Bitmap DecodeNotDirectXTex(byte[] data, uint Width, uint Height, TEX_FORMAT Format) + { + if (Format == TEX_FORMAT.BC1_UNORM) + return DDSCompressor.DecompressBC1(data, (int)Width, (int)Height, false); + else if (Format == TEX_FORMAT.BC1_UNORM_SRGB) + return DDSCompressor.DecompressBC1(data, (int)Width, (int)Height, true); + else if (Format == TEX_FORMAT.BC3_UNORM_SRGB) + return DDSCompressor.DecompressBC3(data, (int)Width, (int)Height, false); + else if (Format == TEX_FORMAT.BC3_UNORM) + return DDSCompressor.DecompressBC3(data, (int)Width, (int)Height, true); + else if (Format == TEX_FORMAT.BC4_UNORM) + return DDSCompressor.DecompressBC4(data, (int)Width, (int)Height, false); + else if (Format == TEX_FORMAT.BC4_SNORM) + return DDSCompressor.DecompressBC4(data, (int)Width, (int)Height, true); + else if (Format == TEX_FORMAT.BC5_UNORM) + return DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, false); + else if (Format == TEX_FORMAT.BC7_UNORM) + return BitmapExtension.GetBitmap(CSharpImageLibrary.DDS.Dxt.DecompressBc7(data, (int)Width, (int)Height), (int)Width, (int)Height); + else if (Format == TEX_FORMAT.BC7_UNORM_SRGB) + return BitmapExtension.GetBitmap(CSharpImageLibrary.DDS.Dxt.DecompressBc7(data, (int)Width, (int)Height), (int)Width, (int)Height); + else + { + if (Runtime.UseOpenGL) + { + Runtime.OpenTKInitialized = true; + if (RenderableTex == null || !RenderableTex.GLInitialized) + LoadOpenGLTexture(); + + return RenderableTex.ToBitmap(); + } + } + return null; + } + public static Bitmap DecodeBlockGetBitmap(byte[] data, uint Width, uint Height, TEX_FORMAT Format) { Bitmap bitmap = BitmapExtension.GetBitmap(DecodeBlock(data, Width, Height, Format), diff --git a/Switch_Toolbox_Library/Generics/RenderableTex.cs b/Switch_Toolbox_Library/Generics/RenderableTex.cs index d3a36706..5716af04 100644 --- a/Switch_Toolbox_Library/Generics/RenderableTex.cs +++ b/Switch_Toolbox_Library/Generics/RenderableTex.cs @@ -66,17 +66,21 @@ namespace Switch_Toolbox.Library.Rendering case TEX_FORMAT.BC4_SNORM: //Convert to rgb to prevent red output //While shaders could prevent this, converting is easier and works fine across all editors - data = STGenericTexture.DecodeBlock(data, + if (Runtime.UseDirectXTexDecoder) + { + data = STGenericTexture.DecodeBlock(data, GenericTexture.Width, GenericTexture.Height, GenericTexture.Format, GenericTexture.PlatformSwizzle); - - pixelInternalFormat = PixelInternalFormat.Rgba; - pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; - - // pixelInternalFormat = PixelInternalFormat.CompressedRedRgtc1; - // pixelInternalFormat = PixelInternalFormat.CompressedSignedRedRgtc1; + pixelInternalFormat = PixelInternalFormat.Rgba; + pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; + } + else + { + pixelInternalFormat = PixelInternalFormat.CompressedRedRgtc1; + pixelInternalFormat = PixelInternalFormat.CompressedSignedRedRgtc1; + } break; case TEX_FORMAT.BC5_SNORM: pixelInternalFormat = PixelInternalFormat.CompressedRgRgtc2; @@ -110,14 +114,17 @@ namespace Switch_Toolbox.Library.Rendering pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; break; default: - data = STGenericTexture.DecodeBlock(data, - GenericTexture.Width, - GenericTexture.Height, + if (Runtime.UseDirectXTexDecoder) + { + data = STGenericTexture.DecodeBlock(data, + GenericTexture.Width, + GenericTexture.Height, GenericTexture.Format, GenericTexture.PlatformSwizzle); - pixelInternalFormat = PixelInternalFormat.Rgba; - pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; + pixelInternalFormat = PixelInternalFormat.Rgba; + pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; + } break; } GLInitialized = true; @@ -198,7 +205,7 @@ namespace Switch_Toolbox.Library.Rendering System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, t.width, t.height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); GL.BindTexture(TextureTarget.Texture2D, t.TexID); GL.GetTexImage(TextureTarget.Texture2D, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bitmapData.Scan0); - + bitmap.UnlockBits(bitmapData); return bitmap; } diff --git a/Switch_Toolbox_Library/IO/STFileLoader.cs b/Switch_Toolbox_Library/IO/STFileLoader.cs index cd3d4ddb..ab5d1e2e 100644 --- a/Switch_Toolbox_Library/IO/STFileLoader.cs +++ b/Switch_Toolbox_Library/IO/STFileLoader.cs @@ -33,6 +33,8 @@ namespace Switch_Toolbox.Library.IO public static IFileFormat OpenFileFormat(string FileName, Type[] FileTypes, byte[] data = null) { + CheckCompression(FileName, data); + Stream stream; if (data != null) stream = new MemoryStream(data); @@ -56,6 +58,8 @@ namespace Switch_Toolbox.Library.IO public static IFileFormat OpenFileFormat(string FileName, Type FileType, byte[] data = null) { + CheckCompression(FileName, data); + Stream stream; if (data != null) stream = new MemoryStream(data); @@ -71,6 +75,46 @@ namespace Switch_Toolbox.Library.IO return null; } + private static void CheckCompression(string FileName, byte[] data) + { + if (data != null) + { + using (var reader = new FileReader(data)) + { + DecompressData(reader, FileName, data); + } + } + else + { + using (var reader = new FileReader(FileName)) + { + DecompressData(reader, FileName, data); + } + } + } + + private static void DecompressData(FileReader reader, string FileName, byte[] data) + { + reader.ByteOrder = ByteOrder.BigEndian; + uint MagicHex = reader.ReadUInt32(); + string Magic = reader.ReadMagic(0, 4); + reader.Position = 0; + + if (Magic == "Yaz0") + { + if (data != null) + data = EveryFileExplorer.YAZ0.Decompress(data); + else + data = EveryFileExplorer.YAZ0.Decompress(FileName); + } + if (MagicHex == 0x28B52FFD || MagicHex == 0xFD2FB528) + { + if (data != null) + data = STLibraryCompression.ZSTD.Decompress(data); + else + data = STLibraryCompression.ZSTD.Decompress(File.ReadAllBytes(FileName)); + } + } /// /// Gets the from a file or byte array. diff --git a/Switch_Toolbox_Library/Runtime.cs b/Switch_Toolbox_Library/Runtime.cs index bae77c95..88de49e4 100644 --- a/Switch_Toolbox_Library/Runtime.cs +++ b/Switch_Toolbox_Library/Runtime.cs @@ -15,6 +15,8 @@ namespace Switch_Toolbox.Library public class Runtime { + public static bool UseDirectXTexDecoder = true; + public static bool DEVELOPER_DEBUG_MODE = false; public static class ResourceTables diff --git a/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.dll b/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.dll index 5c7bf387..01b40cbc 100644 Binary files a/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.dll and b/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.dll differ diff --git a/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.pdb b/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.pdb index cf1fa2fd..9a236145 100644 Binary files a/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.pdb and b/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.pdb differ