Add .mc creation and editing. Fix TXTG updating in viewer.

This commit is contained in:
KillzXGaming 2023-06-03 15:31:08 -04:00
parent d302c38563
commit ebf09c9fac
11 changed files with 179 additions and 18 deletions

Binary file not shown.

View file

@ -2013,7 +2013,7 @@
</member> </member>
<member name="M:Syroot.NintenTools.NSW.Bfres.Core.ResFileLoader.ReadOffsets(System.Int32)"> <member name="M:Syroot.NintenTools.NSW.Bfres.Core.ResFileLoader.ReadOffsets(System.Int32)">
<summary> <summary>
Reads BFRES offsets which is the absolute addresses. Reads BFRES offsets which is the absolute addresses.+
</summary> </summary>
<param name="count">The number of offsets to read.</param> <param name="count">The number of offsets to read.</param>
<returns>The absolute addresses of the offsets.</returns> <returns>The absolute addresses of the offsets.</returns>
@ -2275,7 +2275,7 @@
<param name="str">The name to save.</param> <param name="str">The name to save.</param>
<param name="encoding">The <see cref="T:System.Text.Encoding"/> in which the name will be stored.</param> <param name="encoding">The <see cref="T:System.Text.Encoding"/> in which the name will be stored.</param>
</member> </member>
<member name="M:Syroot.NintenTools.NSW.Bfres.Core.ResFileSaver.SaveStrings(System.Collections.Generic.IEnumerable{System.String},System.Text.Encoding)"> <member name="M:Syroot.NintenTools.NSW.Bfres.Core.ResFileSaver.SaveStrings(System.Collections.Generic.IEnumerable{System.String},System.Boolean,System.Text.Encoding)">
<summary> <summary>
Reserves space for offsets to the <paramref name="strings"/> written later in the string pool with the Reserves space for offsets to the <paramref name="strings"/> written later in the string pool with the
specified <paramref name="encoding"/> specified <paramref name="encoding"/>
@ -3160,6 +3160,11 @@
Gets or sets the <see cref="T:Syroot.NintenTools.NSW.Bfres.Material"/> instance applied on the <see cref="P:Syroot.NintenTools.NSW.Bfres.Model.Shapes"/> to color their surface. Gets or sets the <see cref="T:Syroot.NintenTools.NSW.Bfres.Material"/> instance applied on the <see cref="P:Syroot.NintenTools.NSW.Bfres.Model.Shapes"/> to color their surface.
</summary> </summary>
</member> </member>
<member name="F:Syroot.NintenTools.NSW.Bfres.Model.ShaderAssigns">
<summary>
</summary>
</member>
<member name="P:Syroot.NintenTools.NSW.Bfres.Model.UserDataDict"> <member name="P:Syroot.NintenTools.NSW.Bfres.Model.UserDataDict">
<summary> <summary>
Gets or sets customly attached <see cref="P:Syroot.NintenTools.NSW.Bfres.Model.UserData"/> names. Gets or sets customly attached <see cref="P:Syroot.NintenTools.NSW.Bfres.Model.UserData"/> names.
@ -3713,7 +3718,7 @@
rigidbodies (no skinning), 1 equal rigid skinning and 2 or more smooth skinning. rigidbodies (no skinning), 1 equal rigid skinning and 2 or more smooth skinning.
</summary> </summary>
</member> </member>
<member name="P:Syroot.NintenTools.NSW.Bfres.VertexBuffer.VertexCount"> <member name="F:Syroot.NintenTools.NSW.Bfres.VertexBuffer.VertexCount">
<summary> <summary>
Gets the number of vertices stored by the <see cref="P:Syroot.NintenTools.NSW.Bfres.VertexBuffer.Buffers"/>. It is calculated from the size of the first Gets the number of vertices stored by the <see cref="P:Syroot.NintenTools.NSW.Bfres.VertexBuffer.Buffers"/>. It is calculated from the size of the first
<see cref="!:Buffer"/> in bytes divided by the <see cref="P:Syroot.NintenTools.NSW.Bfres.VertexBuffer.StrideArray"/>. <see cref="!:Buffer"/> in bytes divided by the <see cref="P:Syroot.NintenTools.NSW.Bfres.VertexBuffer.StrideArray"/>.
@ -4850,6 +4855,16 @@
Gets or sets <see cref="T:Syroot.NintenTools.NSW.Bfres.AnimCurve"/> instances animating properties of objects stored in this section. Gets or sets <see cref="T:Syroot.NintenTools.NSW.Bfres.AnimCurve"/> instances animating properties of objects stored in this section.
</summary> </summary>
</member> </member>
<member name="P:Syroot.NintenTools.NSW.Bfres.BoneAnim.UserDataDict">
<summary>
Gets or sets customly attached <see cref="P:Syroot.NintenTools.NSW.Bfres.BoneAnim.UserData"/> names.
</summary>
</member>
<member name="P:Syroot.NintenTools.NSW.Bfres.BoneAnim.UserData">
<summary>
Gets or sets customly attached <see cref="P:Syroot.NintenTools.NSW.Bfres.BoneAnim.UserData"/> instances.
</summary>
</member>
<member name="P:Syroot.NintenTools.NSW.Bfres.BoneAnim.BaseData"> <member name="P:Syroot.NintenTools.NSW.Bfres.BoneAnim.BaseData">
<summary> <summary>
Gets or sets initial transformation values. Only stores specific transformations according to Gets or sets initial transformation values. Only stores specific transformations according to
@ -5173,6 +5188,12 @@
Euler XYZ, 3 components. Euler XYZ, 3 components.
</summary> </summary>
</member> </member>
<member name="T:Syroot.NintenTools.NSW.Bfres.StringCache">
<summary>
A cache of strings that are saved through raw IDs in place of the pointer field of a name offset.
This is used and required for TOTK models.
</summary>
</member>
<member name="T:Syroot.NintenTools.NSW.Bfres.VisibilityAnim"> <member name="T:Syroot.NintenTools.NSW.Bfres.VisibilityAnim">
<summary> <summary>
Represents an FVIS subfile in a <see cref="T:Syroot.NintenTools.NSW.Bfres.ResFile"/>, storing visibility animations of <see cref="T:Syroot.NintenTools.NSW.Bfres.Bone"/> or Represents an FVIS subfile in a <see cref="T:Syroot.NintenTools.NSW.Bfres.ResFile"/>, storing visibility animations of <see cref="T:Syroot.NintenTools.NSW.Bfres.Bone"/> or

View file

@ -811,13 +811,13 @@ namespace FirstPlugin
var externalFlags = MeshCodec.GetExternalFlags(stream); var externalFlags = MeshCodec.GetExternalFlags(stream);
//External flags used //External flags used
if (externalFlags != (MeshCodec.ExternalFlags)0) if (externalFlags != 0 || this.FileName.EndsWith(".mc"))
{ {
//Ensure it uses mc compressor for save //Ensure it uses mc compressor for save
this.IFileInfo.FileIsCompressed = true; this.IFileInfo.FileIsCompressed = true;
if (this.IFileInfo.FileCompression == null) if (this.IFileInfo.FileCompression == null)
{ {
// this.IFileInfo.FileCompression = new MeshCodecFormat(); this.IFileInfo.FileCompression = new MeshCodecFormat();
if (!this.FileName.EndsWith(".mc")) if (!this.FileName.EndsWith(".mc"))
this.FileName += ".mc"; this.FileName += ".mc";
if (!this.FilePath.EndsWith(".mc")) if (!this.FilePath.EndsWith(".mc"))
@ -852,12 +852,8 @@ namespace FirstPlugin
if (externalFlags != (MeshCodec.ExternalFlags)0) if (externalFlags != (MeshCodec.ExternalFlags)0)
{ {
MeshCodec.PrepareTexToGo(resFile); MeshCodec.PrepareTexToGo(resFile);
STTextureFolder texfolder = new STTextureFolder("TexToGo"); MeshCodec.TextureFolder = new TexToGoFolder(MeshCodec);
this.Nodes.Add(texfolder); this.Nodes.Add(MeshCodec.TextureFolder);
foreach (var tex in MeshCodec.TextureList)
{
texfolder.Nodes.Add(tex);
}
} }
DrawableContainer.Drawables.Add(BFRESRender); DrawableContainer.Drawables.Add(BFRESRender);
@ -971,6 +967,9 @@ namespace FirstPlugin
SaveWiiU(stream); SaveWiiU(stream);
else else
SaveSwitch(stream); SaveSwitch(stream);
if (MeshCodec.TextureList.Count > 0)
MeshCodec.SaveTexToGo();
} }
public TreeNodeCollection GetModels() public TreeNodeCollection GetModels()

View file

@ -18,8 +18,12 @@ namespace FirstPlugin
{ {
static ResFile ExternalStringBinary; static ResFile ExternalStringBinary;
public TexToGoFolder TextureFolder;
public List<TXTG> TextureList = new List<TXTG>(); public List<TXTG> TextureList = new List<TXTG>();
public bool IsAnyTextureEdited => TextureList.Any(x => x.IsEdited);
public static ExternalFlags GetExternalFlags(Stream stream) public static ExternalFlags GetExternalFlags(Stream stream)
{ {
using (var reader = new FileReader(stream, true)) using (var reader = new FileReader(stream, true))
@ -179,6 +183,15 @@ namespace FirstPlugin
TextureList.Clear(); TextureList.Clear();
} }
public void SaveTexToGo()
{
if (!IsAnyTextureEdited)
return;
var msg = MessageBox.Show("Textures have been edited. Select the save location");
TextureFolder.SaveEdited();
}
public void PrepareTexToGo(ResFile resFile) public void PrepareTexToGo(ResFile resFile)
{ {
var materials = resFile.Models.SelectMany(x => x.Materials); var materials = resFile.Models.SelectMany(x => x.Materials);

View file

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using Toolbox.Library.IO;
using FirstPlugin;
namespace Toolbox.Library
{
public class MeshCodecFormat : ICompressionFormat
{
public string[] Description { get; set; } = new string[] { "Mesh Codec Compression" };
public string[] Extension { get; set; } = new string[] { "*.mc" };
public bool Identify(Stream stream, string fileName)
{
using (var reader = new FileReader(stream, true)) {
return reader.CheckSignature(4, "MCPK");
}
}
public bool CanCompress { get; } = true;
public Stream Decompress(Stream stream)
{
return new MemoryStream(MeshCodec.DecompressMeshCodec(stream));
}
public Stream Compress(Stream stream)
{
return new MemoryStream(MeshCodec.CompressMeshCodec(stream));
}
}
}

View file

@ -0,0 +1,80 @@
using GL_EditorFramework.EditorDrawables;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
namespace FirstPlugin
{
internal class TexToGoFolder : STTextureFolder
{
private MeshCodec MeshCodec;
public TexToGoFolder(MeshCodec codec) : base("TexToGo")
{
MeshCodec = codec;
foreach (var tex in MeshCodec.TextureList)
Nodes.Add(tex);
}
public override ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
Items.Add(new ToolStripMenuItem("Save Edited Textures", null, (o, e) => SaveEdited(), Keys.Control | Keys.E));
Items.Add(new ToolStripSeparator());
Items.AddRange(base.GetContextMenuItems());
Items.Add(new ToolStripSeparator());
Items.Add(new ToolStripMenuItem("Import TXTG", null, (o, e) => AddTexture(), Keys.Control | Keys.E));
return Items.ToArray();
}
public void SaveEdited()
{
if (MeshCodec.TextureList.Count == 0)
return;
var folder = System.IO.Path.GetDirectoryName(MeshCodec.TextureList[0].FilePath);
FolderSelectDialog dlg = new FolderSelectDialog(folder);
if (dlg.ShowDialog() == DialogResult.OK)
{
foreach (var tex in MeshCodec.TextureList)
if (tex.IsEdited)
STFileSaver.SaveFileFormat(tex, System.IO.Path.Combine(dlg.SelectedPath, $"{tex.Text}.txtg"), false);
}
}
private void AddTexture()
{
Dictionary<string, string> extensions = new Dictionary<string, string>();
extensions.Add(".txtg", "Tex To Go");
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = FileFilters.GetCompleteFilter(extensions);
ofd.Multiselect = false;
if (ofd.ShowDialog() == DialogResult.OK)
{
AddTexture(ofd.FileName);
}
}
private void AddTexture(string filePath)
{
TXTG txtg = STFileLoader.OpenFileFormat(filePath) as TXTG;
if (txtg == null)
{
MessageBox.Show($"File {filePath} not a valid TXTG file!");
return;
}
this.MeshCodec.TextureList.Add(txtg);
Nodes.Add(txtg);
}
}
}

View file

@ -367,7 +367,11 @@ namespace FirstPlugin
ArrayCount = (uint)ImageList.Count; ArrayCount = (uint)ImageList.Count;
Format = tex.Format; Format = tex.Format;
IsEdited = true;
UpdateEditor(); UpdateEditor();
this.LoadOpenGLTexture();
} }
class SurfaceInfo class SurfaceInfo

View file

@ -346,6 +346,8 @@
<Compile Include="FileFormats\LUAC.cs" /> <Compile Include="FileFormats\LUAC.cs" />
<Compile Include="FileFormats\MarioParty\HSF.cs" /> <Compile Include="FileFormats\MarioParty\HSF.cs" />
<Compile Include="FileFormats\MeshCodec\MeshCodec.cs" /> <Compile Include="FileFormats\MeshCodec\MeshCodec.cs" />
<Compile Include="FileFormats\MeshCodec\MeshCodecFormat.cs" />
<Compile Include="FileFormats\MeshCodec\TexToGoFolder.cs" />
<Compile Include="FileFormats\Message\MSYT.cs" /> <Compile Include="FileFormats\Message\MSYT.cs" />
<Compile Include="FileFormats\MKAGPDX\LM2_ARCADE_Model.cs" /> <Compile Include="FileFormats\MKAGPDX\LM2_ARCADE_Model.cs" />
<Compile Include="FileFormats\MT\CRC32Hash.cs" /> <Compile Include="FileFormats\MT\CRC32Hash.cs" />

View file

@ -334,6 +334,7 @@ namespace FirstPlugin
private Type[] LoadCompressionFormats() private Type[] LoadCompressionFormats()
{ {
List<Type> Formats = new List<Type>(); List<Type> Formats = new List<Type>();
Formats.Add(typeof(MeshCodecFormat));
return Formats.ToArray(); return Formats.ToArray();
} }

View file

@ -1,4 +1,5 @@
using System.ComponentModel; using System.ComponentModel;
using System.IO;
using System.Reflection; using System.Reflection;
namespace System.Windows.Forms namespace System.Windows.Forms
@ -18,15 +19,16 @@ namespace System.Windows.Forms
/// <summary> /// <summary>
/// Default constructor /// Default constructor
/// </summary> /// </summary>
public FolderSelectDialog() public FolderSelectDialog(string folder = "")
{ {
ofd = new System.Windows.Forms.OpenFileDialog(); ofd = new System.Windows.Forms.OpenFileDialog();
ofd.Filter = "Folders|\n"; ofd.Filter = "Folders|\n";
ofd.AddExtension = false; ofd.AddExtension = false;
ofd.CheckFileExists = false; ofd.CheckFileExists = false;
ofd.DereferenceLinks = true; ofd.DereferenceLinks = true;
ofd.Multiselect = false; ofd.Multiselect = false;
if (Directory.Exists(folder))
ofd.InitialDirectory = folder;
} }
#region Properties #region Properties

View file

@ -97,10 +97,13 @@ namespace Toolbox.Library.IO
} }
} }
if (EnableDialog)
{
if (compressionLog != string.Empty) if (compressionLog != string.Empty)
MessageBox.Show($"File has been saved to {FileName}. Compressed time: {compressionLog}", "Save Notification"); MessageBox.Show($"File has been saved to {FileName}. Compressed time: {compressionLog}", "Save Notification");
else else
MessageBox.Show($"File has been saved to {FileName}", "Save Notification"); MessageBox.Show($"File has been saved to {FileName}", "Save Notification");
}
// STSaveLogDialog.Show($"File has been saved to {FileName}", "Save Notification", DetailsLog); // STSaveLogDialog.Show($"File has been saved to {FileName}", "Save Notification", DetailsLog);
Cursor.Current = Cursors.Default; Cursor.Current = Cursors.Default;