Add support for loading decompressed TOTK bfres files

This commit is contained in:
KillzXGaming 2023-05-28 15:06:34 -04:00
parent 3fd67dd66f
commit 934a430e89
13 changed files with 179 additions and 30 deletions

View file

@ -6,6 +6,10 @@
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View file

@ -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();

View file

@ -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)

View file

@ -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;
}
}
}
}

View file

@ -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)

View file

@ -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()));

View file

@ -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;

View file

@ -162,8 +162,8 @@
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Numerics" />
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">

View file

@ -1,24 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<loadFromRemoteSources enabled="true"/>
<loadFromRemoteSources enabled="true" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="OpenTK" publicKeyToken="bad199fe84eb3df4" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0"/>
<assemblyIdentity name="OpenTK" publicKeyToken="bad199fe84eb3df4" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="LZ4pn" publicKeyToken="62e1b5ec1eec9bdd" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-1.0.10.93" newVersion="1.0.10.93"/>
<assemblyIdentity name="LZ4pn" publicKeyToken="62e1b5ec1eec9bdd" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.10.93" newVersion="1.0.10.93" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="K4os.Hash.xxHash" publicKeyToken="32cd54395057cec3" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-1.0.5.0" newVersion="1.0.5.0"/>
<assemblyIdentity name="K4os.Hash.xxHash" publicKeyToken="32cd54395057cec3" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.5.0" newVersion="1.0.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0"/>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" /></startup></configuration>

View file

@ -14,7 +14,7 @@
<package id="System.Buffers" version="4.4.0" targetFramework="net462" />
<package id="System.Memory" version="4.5.1" targetFramework="net462" />
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net462" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net462" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" />
<package id="System.Threading.Tasks.Extensions" version="4.5.3" targetFramework="net462" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net462" requireReinstallation="true" />
</packages>

View file

@ -1,27 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<loadFromRemoteSources enabled="true"/>
<loadFromRemoteSources enabled="true" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0"/>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0"/>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="OpenTK" publicKeyToken="bad199fe84eb3df4" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0"/>
<assemblyIdentity name="OpenTK" publicKeyToken="bad199fe84eb3df4" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0"/>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>

View file

@ -692,9 +692,6 @@
<Content Include="System.Numerics.Vectors.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="System.Runtime.CompilerServices.Unsafe.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Tool.ico" />
<None Include="Resources\Logo.png" />
<Content Include="Version.txt">