diff --git a/BrawlboxHelper/app.config b/BrawlboxHelper/app.config
index f6e7dca8..996f4bcc 100644
--- a/BrawlboxHelper/app.config
+++ b/BrawlboxHelper/app.config
@@ -6,6 +6,10 @@
+
+
+
+
\ No newline at end of file
diff --git a/File_Format_Library/FileFormats/BFRES/BFRES.cs b/File_Format_Library/FileFormats/BFRES/BFRES.cs
index 19e21f60..b200e416 100644
--- a/File_Format_Library/FileFormats/BFRES/BFRES.cs
+++ b/File_Format_Library/FileFormats/BFRES/BFRES.cs
@@ -802,6 +802,9 @@ namespace FirstPlugin
BFRESRender.ModelTransform = MarioCostumeEditor.SetTransform(FileName);
BFRESRender.ResFileNode = this;
+ if (this.FileName.Contains("bfres.mc"))
+ MeshCodec.Prepare();
+
if (IsWiiU)
{
LoadFile(new Syroot.NintenTools.Bfres.ResFile(stream));
@@ -835,6 +838,7 @@ namespace FirstPlugin
}
}
}
+
public void Unload()
{
BFRESRender.Destroy();
diff --git a/File_Format_Library/FileFormats/BFRES/BfresSwitch.cs b/File_Format_Library/FileFormats/BFRES/BfresSwitch.cs
index 1f07e891..75f20c25 100644
--- a/File_Format_Library/FileFormats/BFRES/BfresSwitch.cs
+++ b/File_Format_Library/FileFormats/BFRES/BfresSwitch.cs
@@ -266,7 +266,9 @@ namespace FirstPlugin
Syroot.Maths.Vector4F[] vec4t0 = new Syroot.Maths.Vector4F[0];
Syroot.Maths.Vector4F[] vec4b0 = new Syroot.Maths.Vector4F[0];
Syroot.Maths.Vector4F[] vec4w0 = new Syroot.Maths.Vector4F[0];
+ Syroot.Maths.Vector4F[] vec4w1 = new Syroot.Maths.Vector4F[0];
Syroot.Maths.Vector4F[] vec4i0 = new Syroot.Maths.Vector4F[0];
+ Syroot.Maths.Vector4F[] vec4i1 = new Syroot.Maths.Vector4F[0];
//For shape morphing
Syroot.Maths.Vector4F[] vec4Positions1 = new Syroot.Maths.Vector4F[0];
@@ -298,6 +300,10 @@ namespace FirstPlugin
vec4w0 = AttributeData(att, helper, "_w0");
if (att.Name == "_i0")
vec4i0 = AttributeData(att, helper, "_i0");
+ if (att.Name == "_w1")
+ vec4w1 = AttributeData(att, helper, "_w1");
+ if (att.Name == "_i1")
+ vec4i1 = AttributeData(att, helper, "_i1");
if (att.Name == "_p1")
vec4Positions1 = AttributeData(att, helper, "_p1");
@@ -335,6 +341,17 @@ namespace FirstPlugin
if (fshp.VertexSkinCount > 3)
v.boneWeights.Add(vec4w0[i].W);
}
+ if (vec4w1.Length > 0)
+ {
+ if (fshp.VertexSkinCount > 4)
+ v.boneWeights.Add(vec4w1[i].X);
+ if (fshp.VertexSkinCount > 5)
+ v.boneWeights.Add(vec4w1[i].Y);
+ if (fshp.VertexSkinCount > 6)
+ v.boneWeights.Add(vec4w1[i].Z);
+ if (fshp.VertexSkinCount > 7)
+ v.boneWeights.Add(vec4w1[i].W);
+ }
if (vec4i0.Length > 0)
{
if (fshp.VertexSkinCount > 0)
@@ -346,7 +363,17 @@ namespace FirstPlugin
if (fshp.VertexSkinCount > 3)
v.boneIds.Add((int)vec4i0[i].W);
}
-
+ if (vec4i1.Length > 0)
+ {
+ if (fshp.VertexSkinCount > 4)
+ v.boneIds.Add((int)vec4i1[i].X);
+ if (fshp.VertexSkinCount > 5)
+ v.boneIds.Add((int)vec4i1[i].Y);
+ if (fshp.VertexSkinCount > 6)
+ v.boneIds.Add((int)vec4i1[i].Z);
+ if (fshp.VertexSkinCount > 7)
+ v.boneIds.Add((int)vec4i1[i].W);
+ }
if (vec4t0.Length > 0)
v.tan = new Vector4(vec4t0[i].X, vec4t0[i].Y, vec4t0[i].Z, vec4t0[i].W);
if (vec4b0.Length > 0)
diff --git a/File_Format_Library/FileFormats/MeshCodec/MeshCodec.cs b/File_Format_Library/FileFormats/MeshCodec/MeshCodec.cs
new file mode 100644
index 00000000..48f0914c
--- /dev/null
+++ b/File_Format_Library/FileFormats/MeshCodec/MeshCodec.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Syroot.NintenTools.NSW.Bfres;
+using Toolbox.Library;
+using ZstdSharp.Unsafe;
+
+namespace FirstPlugin
+{
+ internal class MeshCodec
+ {
+ static ResFile ExternalStringBinary;
+
+ public static void Prepare()
+ {
+ //Check if a valid directory exists
+ string path = Path.Combine(Runtime.TotkGamePath, "Shader", "ExternalBinaryString.bfres.mc");
+ if (!File.Exists(path))
+ {
+ MessageBox.Show("A game dump of TOTK is required to load this file. Please select the romfs folder path.");
+
+ FolderSelectDialog dlg = new FolderSelectDialog();
+ if (dlg.ShowDialog() == DialogResult.OK)
+ {
+ Runtime.TotkGamePath = dlg.SelectedPath;
+ path = Path.Combine(Runtime.TotkGamePath, "Shader", "ExternalBinaryString.bfres.mc");
+ Toolbox.Library.Config.Save();
+ }
+ }
+
+ if (!File.Exists(path))
+ {
+ MessageBox.Show($"Given folder was not valid! Expecting file {path}");
+ return;
+ }
+
+ LoadExternalStrings();
+ }
+
+ static void LoadExternalStrings()
+ {
+ if (ExternalStringBinary != null)
+ return;
+
+ string path = Path.Combine(Runtime.TotkGamePath, "Shader", "ExternalBinaryString.bfres.mc");
+ byte[] data = DecompressMeshCodec(path);
+ //Load string table into memory
+ //Strings are stored in a static list which will be used for opened bfres
+ ExternalStringBinary = new ResFile(new MemoryStream(data));
+ }
+
+ static byte[] DecompressMeshCodec(string file)
+ {
+ using (var fs = File.OpenRead(file))
+ using (var reader = new BinaryReader(fs))
+ {
+ reader.ReadUInt32(); //Magic
+ reader.ReadUInt32(); //Version 1.1.0.0
+ var flags = reader.ReadInt32();
+ var decompressed_size = (flags >> 5) << (flags & 0xf);
+
+ reader.BaseStream.Seek(0xC, SeekOrigin.Begin);
+ byte[] src = reader.ReadBytes((int)reader.BaseStream.Length - 0xC);
+ return Decompress(src, (uint)decompressed_size);
+ }
+ }
+
+ static unsafe byte[] Decompress(byte[] src, uint decompressed_size)
+ {
+ var dctx = Methods.ZSTD_createDCtx();
+ Methods.ZSTD_DCtx_setFormat(dctx, ZSTD_format_e.ZSTD_f_zstd1_magicless);
+ var uncompressed = new byte[decompressed_size];
+ fixed (byte* srcPtr = src)
+ fixed (byte* uncompressedPtr = uncompressed)
+ {
+ var decompressedLength = Methods.ZSTD_decompressDCtx(dctx, uncompressedPtr, (uint)uncompressed.Length, srcPtr, (uint)src.Length);
+
+ byte[] arr = new byte[(uint)decompressed_size];
+ Marshal.Copy((IntPtr)uncompressedPtr, arr, 0, arr.Length);
+ return arr;
+ }
+ }
+ }
+}
diff --git a/Switch_Toolbox_Library/Compression/Formats/Zstb.cs b/Switch_Toolbox_Library/Compression/Formats/Zstb.cs
index 74c8a477..069d0dbb 100644
--- a/Switch_Toolbox_Library/Compression/Formats/Zstb.cs
+++ b/Switch_Toolbox_Library/Compression/Formats/Zstb.cs
@@ -82,7 +82,26 @@ namespace Toolbox.Library
{
byte[] dictionary = new byte[0];
- string folder = Path.Combine(Runtime.ExecutableDir, "Lib", "ZstdDictionaries");
+ var userDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "SwitchToolbox");
+ if (!Directory.Exists(userDir))
+ Directory.CreateDirectory(userDir);
+
+ string folder = Path.Combine(userDir, "TOTK", "ZstdDictionaries");
+
+ //Check if old directory exists and move it
+ string folderOld = Path.Combine(Runtime.ExecutableDir, "Lib", "ZstdDictionaries");
+ if (Directory.Exists(folderOld))
+ {
+ //Create folder for TOTK contents if it does not exist
+ if (!Directory.Exists(Path.Combine(userDir, "TOTK")))
+ Directory.CreateDirectory(Path.Combine(userDir, "TOTK"));
+ //Remove previous folder with any old files incase it gets updated with additional content
+ if (Directory.Exists(folder))
+ Directory.Delete(folder, true);
+ //Move old to new directory
+ Directory.Move(folderOld, folder);
+ }
+
if (Directory.Exists(folder))
{
void CheckZDic(string fileName, string expectedExtension)
diff --git a/Switch_Toolbox_Library/Config.cs b/Switch_Toolbox_Library/Config.cs
index 873ecd70..63e6da8b 100644
--- a/Switch_Toolbox_Library/Config.cs
+++ b/Switch_Toolbox_Library/Config.cs
@@ -181,6 +181,9 @@ namespace Toolbox.Library
case "BotwGamePath":
Runtime.BotwGamePath = node.InnerText;
break;
+ case "TotkGamePath":
+ Runtime.TotkGamePath = node.InnerText;
+ break;
case "SpecularCubeMapPath":
Runtime.PBR.SpecularCubeMapPath = node.InnerText;
break;
@@ -511,6 +514,7 @@ namespace Toolbox.Library
PathsNode.AppendChild(createNode(doc, "Mk8dGamePath", Runtime.Mk8dGamePath.ToString()));
PathsNode.AppendChild(createNode(doc, "TpGamePath", Runtime.TpGamePath.ToString()));
PathsNode.AppendChild(createNode(doc, "BotwGamePath", Runtime.BotwGamePath.ToString()));
+ PathsNode.AppendChild(createNode(doc, "TotkGamePath", Runtime.TotkGamePath.ToString()));
PathsNode.AppendChild(createNode(doc, "SpecularCubeMapPath", Runtime.PBR.SpecularCubeMapPath.ToString()));
PathsNode.AppendChild(createNode(doc, "DiffuseCubeMapPath", Runtime.PBR.DiffuseCubeMapPath.ToString()));
PathsNode.AppendChild(createNode(doc, "PkSwShGamePath", Runtime.PkSwShGamePath.ToString()));
diff --git a/Switch_Toolbox_Library/Runtime.cs b/Switch_Toolbox_Library/Runtime.cs
index 03edf497..f6eda5b5 100644
--- a/Switch_Toolbox_Library/Runtime.cs
+++ b/Switch_Toolbox_Library/Runtime.cs
@@ -39,6 +39,7 @@ namespace Toolbox.Library
public static string SmoGamePath = "";
public static string TpGamePath = "";
public static string BotwGamePath = "";
+ public static string TotkGamePath = "";
public static bool ShowCloseDialog = true;
diff --git a/Switch_Toolbox_Library/Toolbox_Library.csproj b/Switch_Toolbox_Library/Toolbox_Library.csproj
index 93c4a470..11825169 100644
--- a/Switch_Toolbox_Library/Toolbox_Library.csproj
+++ b/Switch_Toolbox_Library/Toolbox_Library.csproj
@@ -162,8 +162,8 @@
-
- ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
diff --git a/Switch_Toolbox_Library/app.config b/Switch_Toolbox_Library/app.config
index 32c837a6..ccfe1f06 100644
--- a/Switch_Toolbox_Library/app.config
+++ b/Switch_Toolbox_Library/app.config
@@ -1,24 +1,28 @@
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
+
-
+
diff --git a/Switch_Toolbox_Library/packages.config b/Switch_Toolbox_Library/packages.config
index 36dd0209..b4f74633 100644
--- a/Switch_Toolbox_Library/packages.config
+++ b/Switch_Toolbox_Library/packages.config
@@ -14,7 +14,7 @@
-
+
\ No newline at end of file
diff --git a/Toolbox/App.config b/Toolbox/App.config
index 6e97d895..5e55850d 100644
--- a/Toolbox/App.config
+++ b/Toolbox/App.config
@@ -1,27 +1,27 @@
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
diff --git a/Toolbox/System.Runtime.CompilerServices.Unsafe.dll b/Toolbox/System.Runtime.CompilerServices.Unsafe.dll
deleted file mode 100644
index 63403d72..00000000
Binary files a/Toolbox/System.Runtime.CompilerServices.Unsafe.dll and /dev/null differ
diff --git a/Toolbox/Toolbox.csproj b/Toolbox/Toolbox.csproj
index 505ee49e..aa60a46c 100644
--- a/Toolbox/Toolbox.csproj
+++ b/Toolbox/Toolbox.csproj
@@ -692,9 +692,6 @@
PreserveNewest
-
- PreserveNewest
-