Add support for loading decompressed TOTK bfres files
This commit is contained in:
parent
3fd67dd66f
commit
934a430e89
@ -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>
|
@ -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();
|
||||
|
@ -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)
|
||||
|
89
File_Format_Library/FileFormats/MeshCodec/MeshCodec.cs
Normal file
89
File_Format_Library/FileFormats/MeshCodec/MeshCodec.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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()));
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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">
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<loadFromRemoteSources enabled="true" />
|
||||
@ -19,6 +19,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>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" /></startup></configuration>
|
||||
|
@ -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>
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<loadFromRemoteSources enabled="true" />
|
||||
@ -17,7 +17,7 @@
|
||||
</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"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
Binary file not shown.
@ -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">
|
||||
|
Loading…
Reference in New Issue
Block a user