Add big speed and memory improvements to bfres, bntx, and other formats

This commit is contained in:
KillzXGaming 2019-06-25 14:56:19 -04:00
parent 07c37ef3d4
commit d664a47426
32 changed files with 1006 additions and 722 deletions

Binary file not shown.

View file

@ -9,9 +9,9 @@ using Switch_Toolbox.Library;
using Switch_Toolbox.Library.IO; using Switch_Toolbox.Library.IO;
using Switch_Toolbox.Library.Forms; using Switch_Toolbox.Library.Forms;
namespace FirstPlugin namespace FirstPlugin.New
{ {
public class SARC : TreeNodeFile, IFileFormat public class SARC : IArchiveFile, IFileFormat
{ {
public FileType FileType { get; set; } = FileType.Archive; public FileType FileType { get; set; } = FileType.Archive;
@ -39,8 +39,13 @@ namespace FirstPlugin
} }
} }
public Dictionary<string, byte[]> OpenedFiles = new Dictionary<string, byte[]>(); public bool CanAddFiles { get; set; } = true;
public Dictionary<string, byte[]> Files = new Dictionary<string, byte[]>(); public bool CanRenameFiles { get; set; } = true;
public bool CanReplaceFiles { get; set; } = true;
public bool CanDeleteFiles { get; set; } = true;
public List<SarcEntry> files = new List<SarcEntry>();
public IEnumerable<ArchiveFileInfo> Files => files;
public SarcData sarcData; public SarcData sarcData;
public string SarcHash; public string SarcHash;
@ -56,28 +61,25 @@ namespace FirstPlugin
sarcData.endianness = GetByteOrder(stream); sarcData.endianness = GetByteOrder(stream);
SarcHash = Utils.GenerateUniqueHashID(); SarcHash = Utils.GenerateUniqueHashID();
FillTreeNodes(this, SzsFiles.Files, sarcData.HashOnly); foreach (var file in SzsFiles.Files)
files.Add(SetupFileEntry(file.Key, file.Value));
Text = FileName;
ContextMenuStrip = new STContextMenuStrip();
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Save",null, Save, Keys.Control | Keys.S));
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Rename Actor Files (Odyssey)", null, RenameActors, Keys.Control | Keys.S));
// ContextMenuStrip.Items.Add(new STToolStipMenuItem("Unpack to Folder", null, UnpackToFolder, Keys.Control | Keys.E));
// ContextMenuStrip.Items.Add(new STToolStipMenuItem("Pack From Folder", null, PackFromFolder, Keys.Control | Keys.R));
ContextMenuStrip.Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Batch Texture Editor", null, PreviewTextures, Keys.Control | Keys.P));
ContextMenuStrip.Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Sort Childern", null, SortChildern, Keys.Control | Keys.E));
CanDelete = true;
sarcData.Files.Clear(); sarcData.Files.Clear();
} }
public bool AddFile(ArchiveFileInfo archiveFileInfo)
{
return false;
}
public bool DeleteFile(ArchiveFileInfo archiveFileInfo)
{
return false;
}
private void RenameActors(object sender, EventArgs args) private void RenameActors(object sender, EventArgs args)
{ {
string ActorName = Path.GetFileNameWithoutExtension(Text); string ActorName = Path.GetFileNameWithoutExtension(FileName);
RenameDialog dialog = new RenameDialog(); RenameDialog dialog = new RenameDialog();
dialog.SetString(ActorName); dialog.SetString(ActorName);
@ -85,19 +87,19 @@ namespace FirstPlugin
if (dialog.ShowDialog() == DialogResult.OK) if (dialog.ShowDialog() == DialogResult.OK)
{ {
string NewActorName = dialog.textBox1.Text; string NewActorName = dialog.textBox1.Text;
Text = NewActorName + ".szs"; FileName = NewActorName + ".szs";
foreach (TreeNode node in Nodes) foreach (var file in files)
{ {
string NodeName = Path.GetFileNameWithoutExtension(node.Text); string NodeName = Path.GetFileNameWithoutExtension(file.FileName);
string ext = Utils.GetExtension(node.Text); string ext = Utils.GetExtension(file.FileName);
if (NodeName == ActorName) if (NodeName == ActorName)
{ {
node.Text = $"{NewActorName}{ext}"; file.FileName = $"{NewActorName}{ext}";
} }
else if (node.Text.Contains("Attribute.byml")) else if (file.FileName.Contains("Attribute.byml"))
{ {
node.Text = $"{NewActorName}Attribute.byml"; file.FileName = $"{NewActorName}Attribute.byml";
} }
} }
} }
@ -113,38 +115,6 @@ namespace FirstPlugin
} }
private void Delete(object sender, EventArgs args) {
Unload();
var editor = LibraryGUI.Instance.GetObjectEditor();
if (editor != null)
editor.ResetControls();
}
private void SortChildern(object sender, EventArgs args)
{
TreeView.TreeViewNodeSorter = new TreeChildSorter();
TreeView.Sort();
}
public class FolderEntry : TreeNode
{
public FolderEntry(string text, int imageIndex, int selectedImageIndex)
{
Text = text;
ImageIndex = imageIndex;
SelectedImageIndex = selectedImageIndex;
ContextMenu = new ContextMenu();
ContextMenu.MenuItems.Add(new MenuItem("Sort Childern", SortChildern));
}
private void SortChildern(object sender, EventArgs args)
{
TreeView.TreeViewNodeSorter = new TreeChildSorter();
TreeView.Sort();
}
}
public Syroot.BinaryData.ByteOrder GetByteOrder(System.IO.Stream data) public Syroot.BinaryData.ByteOrder GetByteOrder(System.IO.Stream data)
{ {
using (FileReader reader = new FileReader(data)) using (FileReader reader = new FileReader(data))
@ -164,7 +134,7 @@ namespace FirstPlugin
public void Unload() public void Unload()
{ {
Nodes.Clear(); files.Clear();
} }
IEnumerable<TreeNode> Collect(TreeNodeCollection nodes) IEnumerable<TreeNode> Collect(TreeNodeCollection nodes)
@ -186,30 +156,10 @@ namespace FirstPlugin
} }
public byte[] Save() public byte[] Save()
{ {
Console.WriteLine("Saving sarc");
sarcData.Files.Clear(); sarcData.Files.Clear();
foreach (TreeNode node in Collect(Nodes)) foreach (var file in files)
{ {
if (node is SarcEntry) sarcData.Files.Add(file.FileName, file.FileData);
{
Console.WriteLine("Saving " + node);
SaveFileEntryData((SarcEntry)node);
}
else if (node is IFileFormat && node != this)
{
IFileFormat fileFormat = (IFileFormat)node;
if (fileFormat != null && ((IFileFormat)node).CanSave)
{
sarcData.Files.Add(SetSarcPath(node, this),
STLibraryCompression.CompressFile(fileFormat.Save(), fileFormat));
}
else
{
sarcData.Files.Add(SetSarcPath(node, this),
STLibraryCompression.CompressFile(OpenedFiles[node.FullPath], fileFormat));
}
}
} }
Tuple<int, byte[]> sarc = SARCExt.SARC.PackN(sarcData); Tuple<int, byte[]> sarc = SARCExt.SARC.PackN(sarcData);
@ -218,388 +168,41 @@ namespace FirstPlugin
return sarc.Item2; return sarc.Item2;
} }
public static string SetSarcPath(TreeNode node, TreeNode sarcNode)
{
string nodePath = node.FullPath;
int startIndex = nodePath.IndexOf(sarcNode.Text);
if (startIndex > 0)
nodePath = nodePath.Substring(startIndex);
string slash = Path.DirectorySeparatorChar.ToString();
string slashAlt = Path.AltDirectorySeparatorChar.ToString();
string SetPath = nodePath.Replace(sarcNode.Text + slash, string.Empty).Replace(slash ?? "", slashAlt);
return !(SetPath == string.Empty) ? SetPath : node.Text;
}
private void SaveFileEntryData(SarcEntry sarc)
{
string dir = Path.GetDirectoryName(sarc.FullName);
if (!sarcData.HashOnly)
{
if (dir == string.Empty)
sarc.FullName = sarc.Text;
else
sarc.FullName = Path.Combine(dir, sarc.Text);
sarc.FullName = sarc.FullName.Replace(@"\", "/");
}
sarcData.Files.Add(sarc.FullName, sarc.Data);
}
public static void ReplaceNode(TreeNode node, TreeNode replaceNode, TreeNode NewNode)
{
if (NewNode == null)
return;
int index = node.Nodes.IndexOf(replaceNode);
node.Nodes.RemoveAt(index);
node.Nodes.Insert(index, NewNode);
if (NewNode is TreeNodeFile)
((TreeNodeFile)NewNode).OnAfterAdded();
}
private void Save(object sender, EventArgs args) public class SarcEntry : ArchiveFileInfo
{
List<IFileFormat> formats = new List<IFileFormat>();
formats.Add(this);
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = Utils.GetAllFilters(formats);
sfd.FileName = FileName;
if (sfd.ShowDialog() == DialogResult.OK)
{
STFileSaver.SaveFileFormat(this, sfd.FileName);
}
}
public static bool SuppressFormDialog = false;
private void PreviewTextures(object sender, EventArgs args)
{
SuppressFormDialog = true;
List<IFileFormat> Formats = new List<IFileFormat>();
try
{
CallRecursive(TreeView, Formats);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
ArchiveListPreviewForm editor = new ArchiveListPreviewForm();
editor.LoadArchive(Formats);
editor.Show();
SuppressFormDialog = false;
}
private void CallRecursive(TreeView treeView, List<IFileFormat> Formats)
{
// Print each node recursively.
TreeNodeCollection nodes = treeView.Nodes;
foreach (TreeNode n in nodes)
{
GetNodeFileFormat(n, Formats);
}
}
private void GetNodeFileFormat(TreeNode treeNode, List<IFileFormat> Formats)
{
// Print the node.
if (treeNode is SarcEntry)
{
var format = ((SarcEntry)treeNode).OpenFile();
if (format != null)
Formats.Add(format);
}
// Print each node recursively.
foreach (TreeNode tn in treeNode.Nodes)
{
GetNodeFileFormat(tn, Formats);
}
}
public class SarcEntry : TreeNodeCustom
{ {
public SARC sarc; //Sarc file the entry is located in public SARC sarc; //Sarc file the entry is located in
public byte[] Data;
public string sarcHash;
public SarcEntry() public SarcEntry()
{ {
ImageKey = "fileBlank";
SelectedImageKey = "fileBlank";
ContextMenuStrip = new STContextMenuStrip();
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Export Raw Data", null, Export, Keys.Control | Keys.E));
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Export Raw Data to File Location", null, ExportToFileLoc, Keys.Control | Keys.F));
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Replace Raw Data", null, Replace, Keys.Control | Keys.R));
ContextMenuStrip.Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Open With Text Editor", null, OpenTextEditor, Keys.Control | Keys.T));
ContextMenuStrip.Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Remove", null, Remove, Keys.Control | Keys.Delete));
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Rename", null, Rename, Keys.Control | Keys.N));
}
public override void OnClick(TreeView treeView)
{
UpdateHexView();
} }
private void UpdateHexView() public override Dictionary<string, string> ExtensionImageKeyLookup
{ {
HexEditor editor = (HexEditor)LibraryGUI.Instance.GetActiveContent(typeof(HexEditor)); get { return new Dictionary<string, string>()
if (editor == null)
{ {
editor = new HexEditor(); { ".byml", "byaml" },
LibraryGUI.Instance.LoadEditor(editor); { ".byaml", "byaml" },
} { ".bfres", "bfres" },
editor.Text = Text; { ".sbfres", "bfres" },
editor.Dock = DockStyle.Fill; { ".aamp", "aamp" },
editor.LoadData(Data); };
}
public IFileFormat OpenFile()
{
return STFileLoader.OpenFileFormat(FullName, Data, false, true, this);
}
public override void OnDoubleMouseClick(TreeView treeView)
{
if (Data.Length <= 0)
return;
IFileFormat file = OpenFile();
if (file == null) //File returns null if no supported format is found
return;
if (Utils.HasInterface(file.GetType(), typeof(IEditor<>)) && !SuppressFormDialog)
{
OpenFormDialog(file);
}
else if (file != null)
{
sarc.OpenedFiles.Add(FullPath, Data);
ReplaceNode(this.Parent, this, (TreeNode)file);
}
}
private void OpenFormDialog(IFileFormat fileFormat)
{
UserControl form = GetEditorForm(fileFormat);
form.Text = (((IFileFormat)fileFormat).FileName);
var parentForm = LibraryGUI.Instance.GetActiveForm();
GenericEditorForm editorForm = new GenericEditorForm(true, form);
editorForm.FormClosing += (sender, e) => FormClosing(sender, e, fileFormat);
if (editorForm.ShowDialog() == DialogResult.OK)
{
if (fileFormat.CanSave)
{
Data = fileFormat.Save();
UpdateHexView();
} }
} }
} }
private void FormClosing(object sender, EventArgs args, IFileFormat fileFormat) public SarcEntry SetupFileEntry(string fullName, byte[] data)
{
if (((Form)sender).DialogResult != DialogResult.OK)
return;
if (fileFormat.CanSave)
{
Data = fileFormat.Save();
UpdateHexView();
}
}
private UserControl GetEditorForm(IFileFormat fileFormat)
{
Type objectType = fileFormat.GetType();
foreach (var inter in objectType.GetInterfaces())
{
if (inter.IsGenericType && inter.GetGenericTypeDefinition() == typeof(IEditor<>))
{
System.Reflection.MethodInfo method = objectType.GetMethod("OpenForm");
return (UserControl)method.Invoke(fileFormat, new object[0]);
}
}
return null;
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
TreeNode node = TreeView.SelectedNode;
// Determine by checking the Text property.
}
public string FullName;
private void Replace(object sender, EventArgs args)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.FileName = Text;
ofd.DefaultExt = Path.GetExtension(Text);
ofd.Filter = "Raw Data (*.*)|*.*";
if (ofd.ShowDialog() == DialogResult.OK)
{
Data = File.ReadAllBytes(ofd.FileName);
}
}
private void ExportToFileLoc(object sender, EventArgs args)
{
Cursor.Current = Cursors.WaitCursor;
File.WriteAllBytes($"{Path.GetDirectoryName(sarc.FilePath)}/{Text}", Data);
Cursor.Current = Cursors.Default;
}
private void Export(object sender, EventArgs args)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.FileName = Text;
sfd.DefaultExt = Path.GetExtension(Text);
sfd.Filter = "Raw Data (*.*)|*.*";
if (sfd.ShowDialog() == DialogResult.OK)
{
File.WriteAllBytes(sfd.FileName, Data);
}
}
private void OpenTextEditor(object sender, EventArgs args)
{
TextEditor editor = (TextEditor)LibraryGUI.Instance.GetActiveContent(typeof(TextEditor));
if (editor == null)
{
editor = new TextEditor();
LibraryGUI.Instance.LoadEditor(editor);
}
editor.Text = Text;
editor.Dock = DockStyle.Fill;
editor.FillEditor(Data);
}
private void Remove(object sender, EventArgs args)
{
DialogResult result = MessageBox.Show($"Are your sure you want to remove {Text}? This cannot be undone!", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
Parent.Nodes.Remove(this);
}
}
private void Rename(object sender, EventArgs args)
{
RenameDialog dialog = new RenameDialog();
dialog.SetString(Text);
if (dialog.ShowDialog() == DialogResult.OK)
{
Text = dialog.textBox1.Text;
}
}
}
void FillTreeNodes(TreeNode root, Dictionary<string, byte[]> files, bool HashOnly)
{
var rootText = root.Text;
var rootTextLength = rootText.Length;
var nodeStrings = files;
foreach (var node in nodeStrings)
{
string nodeString = node.Key;
if (HashOnly)
nodeString = SARCExt.SARC.TryGetNameFromHashTable(nodeString);
var roots = nodeString.Split(new char[] { '/' },
StringSplitOptions.RemoveEmptyEntries);
// The initial parent is the root node
var parentNode = root;
var sb = new StringBuilder(rootText, nodeString.Length + rootTextLength);
for (int rootIndex = 0; rootIndex < roots.Length; rootIndex++)
{
// Build the node name
var parentName = roots[rootIndex];
sb.Append("/");
sb.Append(parentName);
var nodeName = sb.ToString();
// Search for the node
var index = parentNode.Nodes.IndexOfKey(nodeName);
if (index == -1)
{
// Node was not found, add it
var folder = new FolderEntry(parentName, 0, 0);
if (rootIndex == roots.Length - 1)
{
var file = SetupFileEntry(node.Value, parentName, node.Key);
file.Name = nodeName;
parentNode.Nodes.Add(file);
parentNode = file;
}
else
{
folder.Name = nodeName;
parentNode.Nodes.Add(folder);
parentNode = folder;
}
}
else
{
// Node was found, set that as parent and continue
parentNode = parentNode.Nodes[index];
}
}
}
}
List<string> BuildFinalList(List<string> paths)
{
var finalList = new List<string>();
foreach (var path in paths)
{
bool found = false;
foreach (var item in finalList)
{
if (item.StartsWith(path, StringComparison.Ordinal))
{
found = true;
break;
}
}
if (!found)
{
finalList.Add(path);
}
}
return finalList;
}
public SarcEntry SetupFileEntry(byte[] data, string name, string fullName)
{ {
SarcEntry sarcEntry = new SarcEntry(); SarcEntry sarcEntry = new SarcEntry();
sarcEntry.FullName = fullName; sarcEntry.FileName = fullName;
sarcEntry.Name = name; sarcEntry.FileData = data;
sarcEntry.Text = name;
sarcEntry.sarc = this;
sarcEntry.Data = data;
Files.Add(fullName, data); string ext = Path.GetExtension(fullName);
string ext = Path.GetExtension(name);
string SarcEx = SARCExt.SARC.GuessFileExtension(data); string SarcEx = SARCExt.SARC.GuessFileExtension(data);
if (SarcEx == ".bfres" || ext == ".sbfres") /* if (SarcEx == ".bfres" || ext == ".sbfres")
{ {
sarcEntry.ImageKey = "bfres"; sarcEntry.ImageKey = "bfres";
sarcEntry.SelectedImageKey = "bfres"; sarcEntry.SelectedImageKey = "bfres";
@ -618,7 +221,7 @@ namespace FirstPlugin
{ {
sarcEntry.ImageKey = "aamp"; sarcEntry.ImageKey = "aamp";
sarcEntry.SelectedImageKey = "aamp"; sarcEntry.SelectedImageKey = "aamp";
} }*/
return sarcEntry; return sarcEntry;
} }
} }

View file

@ -0,0 +1,635 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Switch_Toolbox;
using System.Windows.Forms;
using SARCExt;
using Switch_Toolbox.Library;
using Switch_Toolbox.Library.IO;
using Switch_Toolbox.Library.Forms;
namespace FirstPlugin
{
public class SARC : TreeNodeFile, IFileFormat
{
public FileType FileType { get; set; } = FileType.Archive;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "SARC", "SARC", "SARC", "SARC", "SARC", "SARC" };
public string[] Extension { get; set; } = new string[] { "*.pack", "*.sarc", "*.bgenv", "*.sblarc", "*.sbactorpack", ".arc" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool Identify(System.IO.Stream stream)
{
using (var reader = new Switch_Toolbox.Library.IO.FileReader(stream, true))
{
return reader.CheckSignature(4, "SARC");
}
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
public Dictionary<string, byte[]> OpenedFiles = new Dictionary<string, byte[]>();
public Dictionary<string, byte[]> Files = new Dictionary<string, byte[]>();
public SarcData sarcData;
public string SarcHash;
public void Load(System.IO.Stream stream)
{
CanSave = true;
IFileInfo.UseEditMenu = true;
var SzsFiles = SARCExt.SARC.UnpackRamN(stream);
sarcData = new SarcData();
sarcData.HashOnly = SzsFiles.HashOnly;
sarcData.Files = SzsFiles.Files;
sarcData.endianness = GetByteOrder(stream);
SarcHash = Utils.GenerateUniqueHashID();
FillTreeNodes(this, SzsFiles.Files, sarcData.HashOnly);
Text = FileName;
ContextMenuStrip = new STContextMenuStrip();
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Save", null, Save, Keys.Control | Keys.S));
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Rename Actor Files (Odyssey)", null, RenameActors, Keys.Control | Keys.S));
// ContextMenuStrip.Items.Add(new STToolStipMenuItem("Unpack to Folder", null, UnpackToFolder, Keys.Control | Keys.E));
// ContextMenuStrip.Items.Add(new STToolStipMenuItem("Pack From Folder", null, PackFromFolder, Keys.Control | Keys.R));
ContextMenuStrip.Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Batch Texture Editor", null, PreviewTextures, Keys.Control | Keys.P));
ContextMenuStrip.Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Sort Childern", null, SortChildern, Keys.Control | Keys.E));
CanDelete = true;
sarcData.Files.Clear();
}
private void RenameActors(object sender, EventArgs args)
{
string ActorName = Path.GetFileNameWithoutExtension(Text);
RenameDialog dialog = new RenameDialog();
dialog.SetString(ActorName);
if (dialog.ShowDialog() == DialogResult.OK)
{
string NewActorName = dialog.textBox1.Text;
Text = NewActorName + ".szs";
foreach (TreeNode node in Nodes)
{
string NodeName = Path.GetFileNameWithoutExtension(node.Text);
string ext = Utils.GetExtension(node.Text);
if (NodeName == ActorName)
{
node.Text = $"{NewActorName}{ext}";
}
else if (node.Text.Contains("Attribute.byml"))
{
node.Text = $"{NewActorName}Attribute.byml";
}
}
}
}
private void UnpackToFolder(object sender, EventArgs args)
{
}
private void PackFromFolder(object sender, EventArgs args)
{
}
private void Delete(object sender, EventArgs args)
{
Unload();
var editor = LibraryGUI.Instance.GetObjectEditor();
if (editor != null)
editor.ResetControls();
}
private void SortChildern(object sender, EventArgs args)
{
TreeView.TreeViewNodeSorter = new TreeChildSorter();
TreeView.Sort();
}
public class FolderEntry : TreeNode, IContextMenuNode
{
public FolderEntry(string text, int imageIndex, int selectedImageIndex)
{
Text = text;
ImageIndex = imageIndex;
SelectedImageIndex = selectedImageIndex;
}
public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
Items.Add(new ToolStripMenuItem("Sort Childern", null, SortChildern, Keys.Control | Keys.W));
return Items.ToArray();
}
private void SortChildern(object sender, EventArgs args)
{
TreeView.TreeViewNodeSorter = new TreeChildSorter();
TreeView.Sort();
}
}
public Syroot.BinaryData.ByteOrder GetByteOrder(System.IO.Stream data)
{
using (FileReader reader = new FileReader(data))
{
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
reader.Seek(6);
ushort bom = reader.ReadUInt16();
reader.Close();
reader.Dispose();
if (bom == 0xFFFE)
return Syroot.BinaryData.ByteOrder.LittleEndian;
else
return Syroot.BinaryData.ByteOrder.BigEndian;
}
}
public void Unload()
{
Nodes.Clear();
}
IEnumerable<TreeNode> Collect(TreeNodeCollection nodes)
{
foreach (TreeNode node in nodes)
{
yield return node;
bool IsNodeFile = node is IFileFormat;
if (!IsNodeFile)
{
//We don't need to save the child of IFIleFormats
//If opened the file should save it's own children
foreach (var child in Collect(node.Nodes))
yield return child;
}
}
}
public byte[] Save()
{
Console.WriteLine("Saving sarc");
sarcData.Files.Clear();
foreach (TreeNode node in Collect(Nodes))
{
if (node is SarcEntry)
{
Console.WriteLine("Saving " + node);
SaveFileEntryData((SarcEntry)node);
}
else if (node is IFileFormat && node != this)
{
IFileFormat fileFormat = (IFileFormat)node;
if (fileFormat != null && ((IFileFormat)node).CanSave)
{
sarcData.Files.Add(SetSarcPath(node, this),
STLibraryCompression.CompressFile(fileFormat.Save(), fileFormat));
}
else
{
sarcData.Files.Add(SetSarcPath(node, this),
STLibraryCompression.CompressFile(OpenedFiles[node.FullPath], fileFormat));
}
}
}
Tuple<int, byte[]> sarc = SARCExt.SARC.PackN(sarcData);
IFileInfo.Alignment = sarc.Item1;
return sarc.Item2;
}
public static string SetSarcPath(TreeNode node, TreeNode sarcNode)
{
string nodePath = node.FullPath;
int startIndex = nodePath.IndexOf(sarcNode.Text);
if (startIndex > 0)
nodePath = nodePath.Substring(startIndex);
string slash = Path.DirectorySeparatorChar.ToString();
string slashAlt = Path.AltDirectorySeparatorChar.ToString();
string SetPath = nodePath.Replace(sarcNode.Text + slash, string.Empty).Replace(slash ?? "", slashAlt);
return !(SetPath == string.Empty) ? SetPath : node.Text;
}
private void SaveFileEntryData(SarcEntry sarc)
{
string dir = Path.GetDirectoryName(sarc.FullName);
if (!sarcData.HashOnly)
{
if (dir == string.Empty)
sarc.FullName = sarc.Text;
else
sarc.FullName = Path.Combine(dir, sarc.Text);
sarc.FullName = sarc.FullName.Replace(@"\", "/");
}
sarcData.Files.Add(sarc.FullName, sarc.Data);
}
public static void ReplaceNode(TreeNode node, TreeNode replaceNode, TreeNode NewNode)
{
if (NewNode == null)
return;
int index = node.Nodes.IndexOf(replaceNode);
node.Nodes.RemoveAt(index);
node.Nodes.Insert(index, NewNode);
if (NewNode is TreeNodeFile)
((TreeNodeFile)NewNode).OnAfterAdded();
}
private void Save(object sender, EventArgs args)
{
List<IFileFormat> formats = new List<IFileFormat>();
formats.Add(this);
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = Utils.GetAllFilters(formats);
sfd.FileName = FileName;
if (sfd.ShowDialog() == DialogResult.OK)
{
STFileSaver.SaveFileFormat(this, sfd.FileName);
}
}
public static bool SuppressFormDialog = false;
private void PreviewTextures(object sender, EventArgs args)
{
SuppressFormDialog = true;
List<IFileFormat> Formats = new List<IFileFormat>();
try
{
CallRecursive(TreeView, Formats);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
ArchiveListPreviewForm editor = new ArchiveListPreviewForm();
editor.LoadArchive(Formats);
editor.Show();
SuppressFormDialog = false;
}
private void CallRecursive(TreeView treeView, List<IFileFormat> Formats)
{
// Print each node recursively.
TreeNodeCollection nodes = treeView.Nodes;
foreach (TreeNode n in nodes)
{
GetNodeFileFormat(n, Formats);
}
}
private void GetNodeFileFormat(TreeNode treeNode, List<IFileFormat> Formats)
{
// Print the node.
if (treeNode is SarcEntry)
{
var format = ((SarcEntry)treeNode).OpenFile();
if (format != null)
Formats.Add(format);
}
// Print each node recursively.
foreach (TreeNode tn in treeNode.Nodes)
{
GetNodeFileFormat(tn, Formats);
}
}
public class SarcEntry : TreeNodeCustom
{
public SARC sarc; //Sarc file the entry is located in
public byte[] Data;
public string sarcHash;
public SarcEntry()
{
ImageKey = "fileBlank";
SelectedImageKey = "fileBlank";
}
public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
Items.Add(new STToolStipMenuItem("Export Raw Data", null, Export, Keys.Control | Keys.E));
Items.Add(new STToolStipMenuItem("Export Raw Data to File Location", null, ExportToFileLoc, Keys.Control | Keys.F));
Items.Add(new STToolStipMenuItem("Replace Raw Data", null, Replace, Keys.Control | Keys.R));
Items.Add(new STToolStripSeparator());
Items.Add(new STToolStipMenuItem("Open With Text Editor", null, OpenTextEditor, Keys.Control | Keys.T));
Items.Add(new STToolStripSeparator());
Items.Add(new STToolStipMenuItem("Remove", null, Remove, Keys.Control | Keys.Delete));
Items.Add(new STToolStipMenuItem("Rename", null, Rename, Keys.Control | Keys.N));
return Items.ToArray();
}
public override void OnClick(TreeView treeView)
{
UpdateHexView();
}
private void UpdateHexView()
{
HexEditor editor = (HexEditor)LibraryGUI.Instance.GetActiveContent(typeof(HexEditor));
if (editor == null)
{
editor = new HexEditor();
LibraryGUI.Instance.LoadEditor(editor);
}
editor.Text = Text;
editor.Dock = DockStyle.Fill;
editor.LoadData(Data);
}
public IFileFormat OpenFile()
{
return STFileLoader.OpenFileFormat(FullName, Data, false, true, this);
}
public override void OnDoubleMouseClick(TreeView treeView)
{
if (Data.Length <= 0)
return;
IFileFormat file = OpenFile();
if (file == null) //File returns null if no supported format is found
return;
if (Utils.HasInterface(file.GetType(), typeof(IEditor<>)) && !SuppressFormDialog)
{
OpenFormDialog(file);
}
else if (file != null)
{
sarc.OpenedFiles.Add(FullPath, Data);
ReplaceNode(this.Parent, this, (TreeNode)file);
}
}
private void OpenFormDialog(IFileFormat fileFormat)
{
UserControl form = GetEditorForm(fileFormat);
form.Text = (((IFileFormat)fileFormat).FileName);
var parentForm = LibraryGUI.Instance.GetActiveForm();
GenericEditorForm editorForm = new GenericEditorForm(true, form);
editorForm.FormClosing += (sender, e) => FormClosing(sender, e, fileFormat);
if (editorForm.ShowDialog() == DialogResult.OK)
{
if (fileFormat.CanSave)
{
Data = fileFormat.Save();
UpdateHexView();
}
}
}
private void FormClosing(object sender, EventArgs args, IFileFormat fileFormat)
{
if (((Form)sender).DialogResult != DialogResult.OK)
return;
if (fileFormat.CanSave)
{
Data = fileFormat.Save();
UpdateHexView();
}
}
private UserControl GetEditorForm(IFileFormat fileFormat)
{
Type objectType = fileFormat.GetType();
foreach (var inter in objectType.GetInterfaces())
{
if (inter.IsGenericType && inter.GetGenericTypeDefinition() == typeof(IEditor<>))
{
System.Reflection.MethodInfo method = objectType.GetMethod("OpenForm");
return (UserControl)method.Invoke(fileFormat, new object[0]);
}
}
return null;
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
TreeNode node = TreeView.SelectedNode;
// Determine by checking the Text property.
}
public string FullName;
private void Replace(object sender, EventArgs args)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.FileName = Text;
ofd.DefaultExt = Path.GetExtension(Text);
ofd.Filter = "Raw Data (*.*)|*.*";
if (ofd.ShowDialog() == DialogResult.OK)
{
Data = File.ReadAllBytes(ofd.FileName);
}
}
private void ExportToFileLoc(object sender, EventArgs args)
{
Cursor.Current = Cursors.WaitCursor;
File.WriteAllBytes($"{Path.GetDirectoryName(sarc.FilePath)}/{Text}", Data);
Cursor.Current = Cursors.Default;
}
private void Export(object sender, EventArgs args)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.FileName = Text;
sfd.DefaultExt = Path.GetExtension(Text);
sfd.Filter = "Raw Data (*.*)|*.*";
if (sfd.ShowDialog() == DialogResult.OK)
{
File.WriteAllBytes(sfd.FileName, Data);
}
}
private void OpenTextEditor(object sender, EventArgs args)
{
TextEditor editor = (TextEditor)LibraryGUI.Instance.GetActiveContent(typeof(TextEditor));
if (editor == null)
{
editor = new TextEditor();
LibraryGUI.Instance.LoadEditor(editor);
}
editor.Text = Text;
editor.Dock = DockStyle.Fill;
editor.FillEditor(Data);
}
private void Remove(object sender, EventArgs args)
{
DialogResult result = MessageBox.Show($"Are your sure you want to remove {Text}? This cannot be undone!", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
Parent.Nodes.Remove(this);
}
}
private void Rename(object sender, EventArgs args)
{
RenameDialog dialog = new RenameDialog();
dialog.SetString(Text);
if (dialog.ShowDialog() == DialogResult.OK)
{
Text = dialog.textBox1.Text;
}
}
}
void FillTreeNodes(TreeNode root, Dictionary<string, byte[]> files, bool HashOnly)
{
var rootText = root.Text;
var rootTextLength = rootText.Length;
var nodeStrings = files;
foreach (var node in nodeStrings)
{
string nodeString = node.Key;
if (HashOnly)
nodeString = SARCExt.SARC.TryGetNameFromHashTable(nodeString);
var roots = nodeString.Split(new char[] { '/' },
StringSplitOptions.RemoveEmptyEntries);
// The initial parent is the root node
var parentNode = root;
var sb = new StringBuilder(rootText, nodeString.Length + rootTextLength);
for (int rootIndex = 0; rootIndex < roots.Length; rootIndex++)
{
// Build the node name
var parentName = roots[rootIndex];
sb.Append("/");
sb.Append(parentName);
var nodeName = sb.ToString();
// Search for the node
var index = parentNode.Nodes.IndexOfKey(nodeName);
if (index == -1)
{
// Node was not found, add it
var folder = new FolderEntry(parentName, 0, 0);
if (rootIndex == roots.Length - 1)
{
var file = SetupFileEntry(node.Value, parentName, node.Key);
file.Name = nodeName;
parentNode.Nodes.Add(file);
parentNode = file;
}
else
{
folder.Name = nodeName;
parentNode.Nodes.Add(folder);
parentNode = folder;
}
}
else
{
// Node was found, set that as parent and continue
parentNode = parentNode.Nodes[index];
}
}
}
}
List<string> BuildFinalList(List<string> paths)
{
var finalList = new List<string>();
foreach (var path in paths)
{
bool found = false;
foreach (var item in finalList)
{
if (item.StartsWith(path, StringComparison.Ordinal))
{
found = true;
break;
}
}
if (!found)
{
finalList.Add(path);
}
}
return finalList;
}
public SarcEntry SetupFileEntry(byte[] data, string name, string fullName)
{
SarcEntry sarcEntry = new SarcEntry();
sarcEntry.FullName = fullName;
sarcEntry.Name = name;
sarcEntry.Text = name;
sarcEntry.sarc = this;
sarcEntry.Data = data;
Files.Add(fullName, data);
string ext = Path.GetExtension(name);
string SarcEx = SARCExt.SARC.GuessFileExtension(data);
if (SarcEx == ".bfres" || ext == ".sbfres")
{
sarcEntry.ImageKey = "bfres";
sarcEntry.SelectedImageKey = "bfres";
}
if (SarcEx == ".bntx")
{
sarcEntry.ImageKey = "bntx";
sarcEntry.SelectedImageKey = "bntx";
}
if (SarcEx == ".byaml")
{
sarcEntry.ImageKey = "byaml";
sarcEntry.SelectedImageKey = "byaml";
}
if (SarcEx == ".aamp")
{
sarcEntry.ImageKey = "aamp";
sarcEntry.SelectedImageKey = "aamp";
}
return sarcEntry;
}
}
}

View file

@ -213,7 +213,6 @@ namespace FirstPlugin
public class FileEntry : ArchiveFileInfo public class FileEntry : ArchiveFileInfo
{ {
public SDF SDFParent; public SDF SDFParent;
public string FilePath;
public string FolderPath; public string FolderPath;
public string FileBlockPath; public string FileBlockPath;
public ulong PackageID; public ulong PackageID;
@ -258,10 +257,10 @@ namespace FirstPlugin
if (CompressedSizes.Count == 0) if (CompressedSizes.Count == 0)
{ {
//Decompressed File //Decompressed File
string FileNameBlock = Path.Combine(FolderPath, FilePath); // string FileNameBlock = Path.Combine(FolderPath, FileName);
string FolerPath = Path.GetDirectoryName(FileNameBlock); // string FolerPath = Path.GetDirectoryName(FileNameBlock);
if (!Directory.Exists(FolerPath)) // if (!Directory.Exists(FolerPath))
Directory.CreateDirectory(FolerPath); // Directory.CreateDirectory(FolerPath);
Data.Add(stream.getSection((int)Offset, (int)DecompressedSize)); Data.Add(stream.getSection((int)Offset, (int)DecompressedSize));
} }
@ -459,10 +458,6 @@ namespace FirstPlugin
string ID = packageId.ToString("D" + 4); string ID = packageId.ToString("D" + 4);
string BlockFilePath = Path.Combine(PathFolder, $"sdf-{layer}-{ID}.sdfdata"); string BlockFilePath = Path.Combine(PathFolder, $"sdf-{layer}-{ID}.sdfdata");
if (Append)
{
}
bool IsFile = !Name.Contains("dummy") && decompresedSize > 5; bool IsFile = !Name.Contains("dummy") && decompresedSize > 5;
@ -473,7 +468,6 @@ namespace FirstPlugin
SDFParent = this, SDFParent = this,
FileName = Name, FileName = Name,
FileBlockPath = BlockFilePath, FileBlockPath = BlockFilePath,
FilePath = Name,
FolderPath = PathFolder, FolderPath = PathFolder,
CompressedSizes = compressedSize, CompressedSizes = compressedSize,
DdsType = ddsType, DdsType = ddsType,

View file

@ -37,23 +37,11 @@ namespace FirstPlugin
public BCRESGroupNode() : base() public BCRESGroupNode() : base()
{ {
ImageKey = "folder"; ImageKey = "folder";
LoadContextMenus();
} }
public BCRESGroupNode(string name) : base() { Text = name; } public BCRESGroupNode(string name) : base() { Text = name; }
public BCRESGroupNode(BCRESGroupType type) : base() { Type = type; SetNameByType(); } public BCRESGroupNode(BCRESGroupType type) : base() { Type = type; SetNameByType(); }
public override void LoadContextMenus()
{
ContextMenuStrip = new STContextMenuStrip();
CanExport = false;
CanReplace = false;
CanRename = false;
CanDelete = false;
}
public void SetNameByType() public void SetNameByType()
{ {
Text = SetName(); Text = SetName();

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Windows.Forms; using System.Windows.Forms;
using Switch_Toolbox.Library.NodeWrappers; using Switch_Toolbox.Library.NodeWrappers;
using Switch_Toolbox.Library.Animations; using Switch_Toolbox.Library.Animations;
@ -10,7 +11,7 @@ using FirstPlugin;
namespace Bfres.Structs namespace Bfres.Structs
{ {
public class BFRESAnimFolder : STGenericWrapper public class BFRESAnimFolder : STGenericWrapper, IContextMenuNode
{ {
public BFRESAnimFolder() public BFRESAnimFolder()
{ {
@ -51,10 +52,12 @@ namespace Bfres.Structs
public void LoadMenus(bool isWiiUBfres) public void LoadMenus(bool isWiiUBfres)
{ {
IsWiiU = isWiiUBfres; IsWiiU = isWiiUBfres;
}
ContextMenuStrip.Items.Clear(); public ToolStripItem[] GetContextMenuItems()
{
ContextMenuStrip.Items.Add(new ToolStripMenuItem("New", null, List<ToolStripItem> Items = new List<ToolStripItem>();
Items.Add(new ToolStripMenuItem("New", null,
new ToolStripMenuItem("Skeletal Animation", null, NewSkeletalAnimAction), new ToolStripMenuItem("Skeletal Animation", null, NewSkeletalAnimAction),
new ToolStripMenuItem("Shader Param Animation", null, NewShaderParamAnimAction), new ToolStripMenuItem("Shader Param Animation", null, NewShaderParamAnimAction),
new ToolStripMenuItem("Color Animation", null, NewColorAnimAction), new ToolStripMenuItem("Color Animation", null, NewColorAnimAction),
@ -66,7 +69,7 @@ namespace Bfres.Structs
new ToolStripMenuItem("Scene Aniation", null, NewSceneAnimAction) new ToolStripMenuItem("Scene Aniation", null, NewSceneAnimAction)
)); ));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Import", null, Items.Add(new ToolStripMenuItem("Import", null,
new ToolStripMenuItem("Skeletal Animation", null, ImportSkeletalAnimAction), new ToolStripMenuItem("Skeletal Animation", null, ImportSkeletalAnimAction),
new ToolStripMenuItem("Shader Param Animation", null, ImportShaderParamAnimAction), new ToolStripMenuItem("Shader Param Animation", null, ImportShaderParamAnimAction),
new ToolStripMenuItem("Color Animation", null, ImportColorAnimAction), new ToolStripMenuItem("Color Animation", null, ImportColorAnimAction),
@ -78,9 +81,12 @@ namespace Bfres.Structs
new ToolStripMenuItem("Scene Aniation", null, ImportSceneAnimAction) new ToolStripMenuItem("Scene Aniation", null, ImportSceneAnimAction)
)); ));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Clear", null, ClearAction, Keys.Control | Keys.C)); Items.Add(new ToolStripMenuItem("Clear", null, ClearAction, Keys.Control | Keys.C));
return Items.ToArray();
} }
protected void NewSkeletalAnimAction(object sender, EventArgs e) { NewSkeletalAnim(); } protected void NewSkeletalAnimAction(object sender, EventArgs e) { NewSkeletalAnim(); }
protected void NewShaderParamAnimAction(object sender, EventArgs e) { NewShaderParamAnim(); } protected void NewShaderParamAnimAction(object sender, EventArgs e) { NewShaderParamAnim(); }
protected void NewColorAnimAction(object sender, EventArgs e) { NewColorAnim(); } protected void NewColorAnimAction(object sender, EventArgs e) { NewColorAnim(); }

View file

@ -30,13 +30,9 @@ namespace Bfres.Structs
Embedded, Embedded,
} }
public class BFRESGroupNode : STGenericWrapper public class BFRESGroupNode : STGenericWrapper, IContextMenuNode
{ {
public bool ShowNewContextMenu public bool ShowNewContextMenu = true;
{
set { ContextMenuStrip.Items[0].Visible = value; }
get { return ContextMenuStrip.Items[0].Visible; }
}
public bool IsWiiU; public bool IsWiiU;
@ -56,39 +52,38 @@ namespace Bfres.Structs
ImageKey = "folder"; ImageKey = "folder";
IsWiiU = isWiiU; IsWiiU = isWiiU;
LoadContextMenus();
}
public override void LoadContextMenus()
{
ContextMenuStrip = new STContextMenuStrip();
CanExport = false; CanExport = false;
CanReplace = false; CanReplace = false;
CanRename = false; CanRename = false;
CanDelete = false; CanDelete = false;
}
//Folder Operations public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
ContextMenuStrip.Items.Add(new STToolStipMenuItem("New", null, NewAction, Keys.Control | Keys.N)); Items.Add(new STToolStipMenuItem("New", null, NewAction, Keys.Control | Keys.N) { Enabled = ShowNewContextMenu });
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Import", null, ImportAction, Keys.Control | Keys.I)); Items.Add(new STToolStipMenuItem("Import", null, ImportAction, Keys.Control | Keys.I));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export All", null, ExportAllAction, Keys.Control | Keys.E)); Items.Add(new ToolStripMenuItem("Export All", null, ExportAllAction, Keys.Control | Keys.E));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Replace (From Folder)", null, ReplaceAllAction, Keys.Control | Keys.R)); Items.Add(new ToolStripMenuItem("Replace (From Folder)", null, ReplaceAllAction, Keys.Control | Keys.R));
ContextMenuStrip.Items.Add(new STToolStripSeparator()); Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Sort", null, SortAction, Keys.Control | Keys.S)); Items.Add(new STToolStipMenuItem("Sort", null, SortAction, Keys.Control | Keys.S));
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Clear", null, ClearAction, Keys.Control | Keys.C)); Items.Add(new STToolStipMenuItem("Clear", null, ClearAction, Keys.Control | Keys.C));
if (Type == BRESGroupType.Textures) if (Type == BRESGroupType.Textures)
{ {
ContextMenuStrip.Items.Add(new STToolStripSeparator()); Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Batch Generate Mipmaps", null, BatchGenerateMipmapsAction, Keys.Control | Keys.M)); Items.Add(new STToolStipMenuItem("Batch Generate Mipmaps", null, BatchGenerateMipmapsAction, Keys.Control | Keys.M));
} }
if (Type == BRESGroupType.Models) if (Type == BRESGroupType.Models)
{ {
ContextMenuStrip.Items.Add(new STToolStripSeparator()); Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Show All Models", null, ShowAllModelsAction, Keys.Control | Keys.A)); Items.Add(new STToolStipMenuItem("Show All Models", null, ShowAllModelsAction, Keys.Control | Keys.A));
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Hide All Models", null, HideAllModelsAction, Keys.Control | Keys.H)); Items.Add(new STToolStipMenuItem("Hide All Models", null, HideAllModelsAction, Keys.Control | Keys.H));
} }
return Items.ToArray();
} }
public override string ExportFilter { get { return GetSubfileExtensions(true); } } public override string ExportFilter { get { return GetSubfileExtensions(true); } }

View file

@ -59,6 +59,11 @@ namespace Bfres.Structs
{ {
MaterialAnimData = data; MaterialAnimData = data;
matAnimWrapper = materialAnimation; matAnimWrapper = materialAnimation;
CanRename = true;
CanReplace = true;
CanExport = true;
CanDelete = true;
} }
public void CreateSampler(string Name, bool IsConstant) public void CreateSampler(string Name, bool IsConstant)
@ -326,9 +331,6 @@ namespace Bfres.Structs
{ {
ImageKey = "materialAnim"; ImageKey = "materialAnim";
SelectedImageKey = "materialAnim"; SelectedImageKey = "materialAnim";
ContextMenuStrip = new ContextMenuStrip();
LoadFileMenus(false);
} }
protected void NewAction(object sender, EventArgs e) { NewMaterialAnim(); } protected void NewAction(object sender, EventArgs e) { NewMaterialAnim(); }

View file

@ -16,7 +16,7 @@ using OpenTK;
namespace Bfres.Structs namespace Bfres.Structs
{ {
public class FMDL : STGenericModel public class FMDL : STGenericModel, IContextMenuNode
{ {
//These get updated on UpdateVertexData() //These get updated on UpdateVertexData()
public Vector3 MaxPosition = new Vector3(0); public Vector3 MaxPosition = new Vector3(0);
@ -70,29 +70,36 @@ namespace Bfres.Structs
Checked = true; Checked = true;
CanReplace = true; CanReplace = true;
CanDelete = true; CanDelete = true;
IsFolder = false;
Nodes.Add(new FSHPFolder()); Nodes.Add(new FSHPFolder());
Nodes.Add(new FMATFolder()); Nodes.Add(new FMATFolder());
Nodes.Add(new FSKL.fsklNode()); Nodes.Add(new FSKL.fsklNode());
}
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Transform", null, TransformToolAction, Keys.Control | Keys.T)); public ToolStripItem[] GetContextMenuItems()
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Calculate Tangents/Bitangents", null, CalcTansBitansAllShapesAction, Keys.Control | Keys.C)); {
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Normals", null, List<ToolStripItem> Items = new List<ToolStripItem>();
Items.AddRange(base.GetContextMenuItems());
Items.Add(new ToolStripMenuItem("Transform", null, TransformToolAction, Keys.Control | Keys.T));
Items.Add(new ToolStripMenuItem("Calculate Tangents/Bitangents", null, CalcTansBitansAllShapesAction, Keys.Control | Keys.C));
Items.Add(new ToolStripMenuItem("Normals", null,
new ToolStripMenuItem("Smooth (Multiple Meshes)", null, MultiMeshSmoothNormals), new ToolStripMenuItem("Smooth (Multiple Meshes)", null, MultiMeshSmoothNormals),
new ToolStripMenuItem("Smooth", null, SmoothNormalsAction), new ToolStripMenuItem("Smooth", null, SmoothNormalsAction),
new ToolStripMenuItem("Recalculate", null, RecalculateNormalsAction) new ToolStripMenuItem("Recalculate", null, RecalculateNormalsAction)
)); ));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("UVs", null, Items.Add(new ToolStripMenuItem("UVs", null,
new ToolStripMenuItem("Flip Vertical", null, FlipUvsVerticalAction), new ToolStripMenuItem("Flip Vertical", null, FlipUvsVerticalAction),
new ToolStripMenuItem("Flip Horizontal", null, FlipUvsHorizontalAction), new ToolStripMenuItem("Flip Horizontal", null, FlipUvsHorizontalAction),
new ToolStripMenuItem("Copy UV Channel", null, CopyUVChannels) new ToolStripMenuItem("Copy UV Channel", null, CopyUVChannels)
)); ));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Colors", null, Items.Add(new ToolStripMenuItem("Colors", null,
new ToolStripMenuItem(" Set Color", null, SetVertexColorDialogAction), new ToolStripMenuItem(" Set Color", null, SetVertexColorDialogAction),
new ToolStripMenuItem("Set White Color", null, SetVertexColorWhiteAction) new ToolStripMenuItem("Set White Color", null, SetVertexColorWhiteAction)
)); ));
return Items.ToArray();
} }
protected void TransformToolAction(object sender, EventArgs e) { TransformTool(); } protected void TransformToolAction(object sender, EventArgs e) { TransformTool(); }

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.IO; using System.IO;
using Syroot.NintenTools.NSW.Bfres; using Syroot.NintenTools.NSW.Bfres;
using System.Windows.Forms; using System.Windows.Forms;
@ -207,6 +208,56 @@ namespace Bfres.Structs
return ((BFRES)Parent.Parent.Parent.Parent).BFRESRender; return ((BFRES)Parent.Parent.Parent.Parent).BFRESRender;
} }
public void UpdateRenderPass()
{
if (ImageKey != "material")
{
ImageKey = "material";
SelectedImageKey = "material";
}
bool IsTranslucent = false;
bool IsTransparentMask = false;
for (int i = 0; i < renderinfo.Count; i++)
{
if (renderinfo[i].Name == "gsys_render_state_mode")
{
IsTranslucent = renderinfo[i].ValueString.Contains("translucent");
IsTransparentMask = renderinfo[i].ValueString.Contains("mask");
}
if (renderinfo[i].Name == "renderPass")
{
IsTransparentMask = renderinfo[i].ValueString.Contains("xlu");
}
}
if (shaderassign.options.ContainsKey("enable_translucent"))
IsTranslucent = shaderassign.options["enable_translucent"] == "1";
if (shaderassign.options.ContainsKey("enable_translucent"))
IsTransparentMask = shaderassign.options["enable_transparent"] == "1";
if (MaterialU != null)
{
IsTranslucent = MaterialU.RenderState.FlagsMode == ResU.RenderStateFlagsMode.Translucent;
IsTransparentMask = MaterialU.RenderState.FlagsMode == ResU.RenderStateFlagsMode.AlphaMask;
}
isTransparent = IsTransparentMask || IsTranslucent;
SetMaterialIcon(IsTranslucent, "MaterialTranslucent");
SetMaterialIcon(IsTransparentMask, "MaterialTransparent");
}
private void SetMaterialIcon(bool IsEffect, string Key)
{
if (IsEffect)
{
ImageKey = Key;
SelectedImageKey = Key;
}
}
public bool IsNormalMapTexCoord2() public bool IsNormalMapTexCoord2()
{ {
//for BOTW if it uses UV layer 2 for normal maps use second UV map //for BOTW if it uses UV layer 2 for normal maps use second UV map

View file

@ -16,22 +16,24 @@ using OpenTK;
namespace Bfres.Structs namespace Bfres.Structs
{ {
public class FSHPFolder : TreeNodeCustom public class FSHPFolder : TreeNodeCustom, IContextMenuNode
{ {
public FSHPFolder() public FSHPFolder()
{ {
Text = "Objects"; Text = "Objects";
Name = "FshpFolder"; Name = "FshpFolder";
}
ContextMenuStrip = new STContextMenuStrip(); public ToolStripItem[] GetContextMenuItems()
{
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Import Object", null, Import, Keys.Control | Keys.I)); List<ToolStripItem> Items = new List<ToolStripItem>();
ContextMenuStrip.Items.Add(new ToolStripSeparator()); Items.Add(new ToolStripMenuItem("Import Object", null, Import, Keys.Control | Keys.I));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("New Empty Object", null, CreateEmpty, Keys.Control | Keys.N)); Items.Add(new ToolStripSeparator());
ContextMenuStrip.Items.Add(new ToolStripSeparator()); Items.Add(new ToolStripMenuItem("New Empty Object", null, CreateEmpty, Keys.Control | Keys.N));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export All Objects", null, ExportAll, Keys.Control | Keys.A)); Items.Add(new ToolStripSeparator());
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Clear All Objects", null, Clear, Keys.Control | Keys.C)); Items.Add(new ToolStripMenuItem("Export All Objects", null, ExportAll, Keys.Control | Keys.A));
Items.Add(new ToolStripMenuItem("Clear All Objects", null, Clear, Keys.Control | Keys.C));
return Items.ToArray();
} }
private void CreateEmpty(object sender, EventArgs args) private void CreateEmpty(object sender, EventArgs args)
@ -139,7 +141,7 @@ namespace Bfres.Structs
public static int Size = 4 * (3 + 3 + 3 + 3 + 2 + 4 + 4 + 4 + 2 + 2 + 3 + 3); public static int Size = 4 * (3 + 3 + 3 + 3 + 2 + 4 + 4 + 4 + 2 + 2 + 3 + 3);
} }
public class FSHP : STGenericObject public class FSHP : STGenericObject, IContextMenuNode
{ {
public bool IsWiiU public bool IsWiiU
{ {
@ -154,23 +156,25 @@ namespace Bfres.Structs
Checked = true; Checked = true;
ImageKey = "mesh"; ImageKey = "mesh";
SelectedImageKey = "mesh"; SelectedImageKey = "mesh";
}
ContextMenuStrip = new STContextMenuStrip(); public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export", null, Export, Keys.Control | Keys.E)); Items.Add(new ToolStripMenuItem("Export", null, Export, Keys.Control | Keys.E));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Replace", null, Replace, Keys.Control | Keys.R)); Items.Add(new ToolStripMenuItem("Replace", null, Replace, Keys.Control | Keys.R));
Items.Add(new ToolStripSeparator());
ContextMenuStrip.Items.Add(new ToolStripSeparator()); Items.Add(new ToolStripMenuItem("Rename", null, Rename, Keys.Control | Keys.N));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Rename", null, Rename, Keys.Control | Keys.N)); Items.Add(new ToolStripSeparator());
ContextMenuStrip.Items.Add(new ToolStripSeparator());
ToolStripMenuItem lodMenu = new ToolStripMenuItem("Level Of Detail"); ToolStripMenuItem lodMenu = new ToolStripMenuItem("Level Of Detail");
lodMenu.DropDownItems.Add(new ToolStripMenuItem("Clear LOD Meshes", null, ClearLODMeshes)); lodMenu.DropDownItems.Add(new ToolStripMenuItem("Clear LOD Meshes", null, ClearLODMeshes));
ContextMenuStrip.Items.Add(lodMenu); Items.Add(lodMenu);
ToolStripMenuItem boundingsMenu = new ToolStripMenuItem("Boundings"); ToolStripMenuItem boundingsMenu = new ToolStripMenuItem("Boundings");
boundingsMenu.DropDownItems.Add(new ToolStripMenuItem("Regenerate Bounding Boxes/Radius", null, GenerateBoundingBoxes)); boundingsMenu.DropDownItems.Add(new ToolStripMenuItem("Regenerate Bounding Boxes/Radius", null, GenerateBoundingBoxes));
ContextMenuStrip.Items.Add(boundingsMenu); Items.Add(boundingsMenu);
ToolStripMenuItem uvMenu = new ToolStripMenuItem("UVs"); ToolStripMenuItem uvMenu = new ToolStripMenuItem("UVs");
uvMenu.DropDownItems.Add(new ToolStripMenuItem("Flip (Vertical)", null, FlipUvsVertical)); uvMenu.DropDownItems.Add(new ToolStripMenuItem("Flip (Vertical)", null, FlipUvsVertical));
@ -178,22 +182,23 @@ namespace Bfres.Structs
uvMenu.DropDownItems.Add(new ToolStripMenuItem("Copy Channel", null, CopyUVChannelAction)); uvMenu.DropDownItems.Add(new ToolStripMenuItem("Copy Channel", null, CopyUVChannelAction));
// uvMenu.DropDownItems.Add(new ToolStripMenuItem("Unwrap By Position", null, UVUnwrapPosition)); // uvMenu.DropDownItems.Add(new ToolStripMenuItem("Unwrap By Position", null, UVUnwrapPosition));
ContextMenuStrip.Items.Add(uvMenu); Items.Add(uvMenu);
ToolStripMenuItem normalsMenu = new ToolStripMenuItem("Normals"); ToolStripMenuItem normalsMenu = new ToolStripMenuItem("Normals");
normalsMenu.DropDownItems.Add(new ToolStripMenuItem("Smooth (Multiple Meshes)", null, MultiMeshSmoothNormals)); normalsMenu.DropDownItems.Add(new ToolStripMenuItem("Smooth (Multiple Meshes)", null, MultiMeshSmoothNormals));
normalsMenu.DropDownItems.Add(new ToolStripMenuItem("Smooth", null, SmoothNormals)); normalsMenu.DropDownItems.Add(new ToolStripMenuItem("Smooth", null, SmoothNormals));
normalsMenu.DropDownItems.Add(new ToolStripMenuItem("Invert", null, InvertNormals)); normalsMenu.DropDownItems.Add(new ToolStripMenuItem("Invert", null, InvertNormals));
normalsMenu.DropDownItems.Add(new ToolStripMenuItem("Recalculate", null, RecalculateNormals)); normalsMenu.DropDownItems.Add(new ToolStripMenuItem("Recalculate", null, RecalculateNormals));
ContextMenuStrip.Items.Add(normalsMenu); Items.Add(normalsMenu);
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Recalulate Tangents/Bitangents", null, CalcTansBitans, Keys.Control | Keys.T)); Items.Add(new ToolStripMenuItem("Recalulate Tangents/Bitangents", null, CalcTansBitans, Keys.Control | Keys.T));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Fill Tangent Space with constant", null, FillTangentsAction, Keys.Control | Keys.W)); Items.Add(new ToolStripMenuItem("Fill Tangent Space with constant", null, FillTangentsAction, Keys.Control | Keys.W));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Fill Bitangent Space with constant", null, FillBitangentsAction, Keys.Control | Keys.B)); Items.Add(new ToolStripMenuItem("Fill Bitangent Space with constant", null, FillBitangentsAction, Keys.Control | Keys.B));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Open Material Editor", null, OpenMaterialEditor, Keys.Control | Keys.M)); Items.Add(new ToolStripMenuItem("Open Material Editor", null, OpenMaterialEditor, Keys.Control | Keys.M));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Delete", null, Remove, Keys.Control | Keys.Delete)); Items.Add(new ToolStripMenuItem("Delete", null, Remove, Keys.Control | Keys.Delete));
return Items.ToArray();
} }
public VertexBuffer VertexBuffer; public VertexBuffer VertexBuffer;

View file

@ -168,7 +168,7 @@ namespace Bfres.Structs
return (FMDL)node.Parent; return (FMDL)node.Parent;
} }
public class fsklNode : STGenericWrapper public class fsklNode : STGenericWrapper, IContextMenuNode
{ {
public FSKL fskl; public FSKL fskl;
@ -195,18 +195,20 @@ namespace Bfres.Structs
CanRename = false; CanRename = false;
} }
public override void LoadContextMenus() public ToolStripItem[] GetContextMenuItems()
{ {
ContextMenuStrip = new STContextMenuStrip(); return new ToolStripItem[]
ContextMenuStrip.Items.Add(new ToolStripMenuItem("New Bone", null, NewBoneAction, Keys.Control | Keys.N)); {
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Import Bone", null, ImportAction, Keys.Control | Keys.I)); new ToolStripMenuItem("New Bone", null, NewBoneAction, Keys.Control | Keys.N),
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export All Bones", null, ExportAllAction, Keys.Control | Keys.B)); new ToolStripMenuItem("Import Bone", null, ImportAction, Keys.Control | Keys.I),
ContextMenuStrip.Items.Add(new ToolStripSeparator()); new ToolStripMenuItem("Export All Bones", null, ExportAllAction, Keys.Control | Keys.B),
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Replace Matching Bones (From Skeleton)", null, ReplaceMatchingFileAction, Keys.Control | Keys.S)); new ToolStripSeparator(),
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Replace Matching Bones (From Folder)", null, ReplaceMatchingFolderAction, Keys.Control | Keys.F)); new ToolStripMenuItem("Replace Matching Bones (From Skeleton)", null, ReplaceMatchingFileAction, Keys.Control | Keys.S),
ContextMenuStrip.Items.Add(new ToolStripSeparator()); new ToolStripMenuItem("Replace Matching Bones (From Folder)", null, ReplaceMatchingFolderAction, Keys.Control | Keys.F),
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export Skeleton", null, ExportAction, Keys.Control | Keys.E)); new ToolStripSeparator(),
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Replace Skeleton", null, ReplaceAction, Keys.Control | Keys.R)); new ToolStripMenuItem("Export Skeleton", null, ExportAction, Keys.Control | Keys.E),
new ToolStripMenuItem("Replace Skeleton", null, ReplaceAction, Keys.Control | Keys.R),
};
} }
protected void NewBoneAction(object sender, EventArgs args) { NewChildBone(); } protected void NewBoneAction(object sender, EventArgs args) { NewChildBone(); }
@ -508,7 +510,7 @@ namespace Bfres.Structs
BfresWiiU.ReadSkeleton(node, skl, this); BfresWiiU.ReadSkeleton(node, skl, this);
} }
} }
public class BfresBone : STBone public class BfresBone : STBone, IContextMenuNode
{ {
public bool UseSmoothMatrix { get; set; } public bool UseSmoothMatrix { get; set; }
@ -582,14 +584,18 @@ namespace Bfres.Structs
ImageKey = "bone"; ImageKey = "bone";
SelectedImageKey = "bone"; SelectedImageKey = "bone";
Checked = true; Checked = true;
}
ContextMenuStrip = new STContextMenuStrip(); public ToolStripItem[] GetContextMenuItems()
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Rename", null, RenameAction, Keys.Control | Keys.I)); {
ContextMenuStrip.Items.Add(new ToolStripMenuItem("New Child Bone", null, NewAction, Keys.Control | Keys.I)); List<ToolStripItem> Items = new List<ToolStripItem>();
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Import Child Bone", null, ImportAction, Keys.Control | Keys.I)); Items.Add(new ToolStripMenuItem("Rename", null, RenameAction, Keys.Control | Keys.I));
ContextMenuStrip.Items.Add(new ToolStripSeparator()); Items.Add(new ToolStripMenuItem("New Child Bone", null, NewAction, Keys.Control | Keys.I));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export Bone", null, ExportAction, Keys.Control | Keys.I)); Items.Add(new ToolStripMenuItem("Import Child Bone", null, ImportAction, Keys.Control | Keys.I));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Replace Bone", null, ReplaceAction, Keys.Control | Keys.I)); Items.Add(new ToolStripSeparator());
Items.Add(new ToolStripMenuItem("Export Bone", null, ExportAction, Keys.Control | Keys.I));
Items.Add(new ToolStripMenuItem("Replace Bone", null, ReplaceAction, Keys.Control | Keys.I));
return Items.ToArray();
} }
protected void ExportAction(object sender, EventArgs args) { Export(); } protected void ExportAction(object sender, EventArgs args) { Export(); }

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Windows.Forms; using System.Windows.Forms;
using Switch_Toolbox.Library; using Switch_Toolbox.Library;
using FirstPlugin.Forms; using FirstPlugin.Forms;
@ -11,7 +12,7 @@ using Switch_Toolbox.Library.NodeWrappers;
namespace Bfres.Structs namespace Bfres.Structs
{ {
public class FSCN : STGenericWrapper public class FSCN : STGenericWrapper, IContextMenuNode
{ {
public SceneAnim SceneAnim; public SceneAnim SceneAnim;
public ResU.SceneAnim SceneAnimU; public ResU.SceneAnim SceneAnimU;
@ -30,19 +31,22 @@ namespace Bfres.Structs
ImageKey = "materialAnim"; ImageKey = "materialAnim";
SelectedImageKey = "materialAnim"; SelectedImageKey = "materialAnim";
ContextMenuStrip = new ContextMenuStrip();
ContextMenuStrip.Items.Add(new ToolStripMenuItem("New Camera Animation", null, NewCameraAction, Keys.Control | Keys.C));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("New Light Animation", null, NewLightAction, Keys.Control | Keys.L));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("New Fog Animation", null, NewFogAction, Keys.Control | Keys.F));
LoadFileMenus(false);
} }
public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
Items.Add(new ToolStripMenuItem("New Camera Animation", null, NewCameraAction, Keys.Control | Keys.C));
Items.Add(new ToolStripMenuItem("New Light Animation", null, NewLightAction, Keys.Control | Keys.L));
Items.Add(new ToolStripMenuItem("New Fog Animation", null, NewFogAction, Keys.Control | Keys.F));
return Items.ToArray();
}
protected void NewCameraAction(object sender, EventArgs e) { NewCameraAnim(); } protected void NewCameraAction(object sender, EventArgs e) { NewCameraAnim(); }
protected void NewLightAction(object sender, EventArgs e) { NewLightAnim(); } protected void NewLightAction(object sender, EventArgs e) { NewLightAnim(); }
protected void NewFogAction(object sender, EventArgs e) { NewFogAnim(); } protected void NewFogAction(object sender, EventArgs e) { NewFogAnim(); }
public void NewCameraAnim() public void NewCameraAnim()
{ {
BfresCameraAnim cameraAnim = new BfresCameraAnim(); BfresCameraAnim cameraAnim = new BfresCameraAnim();
@ -176,8 +180,6 @@ namespace Bfres.Structs
CanReplace = true; CanReplace = true;
CanExport = true; CanExport = true;
CanDelete = true; CanDelete = true;
ContextMenuStrip = new ContextMenuStrip();
} }
public void LoadAnim(CameraAnim anim) public void LoadAnim(CameraAnim anim)
@ -263,8 +265,6 @@ namespace Bfres.Structs
CanReplace = true; CanReplace = true;
CanExport = true; CanExport = true;
CanDelete = true; CanDelete = true;
ContextMenuStrip = new ContextMenuStrip();
} }
public void LoadAnim(LightAnim anim) public void LoadAnim(LightAnim anim)
@ -296,8 +296,6 @@ namespace Bfres.Structs
CanReplace = true; CanReplace = true;
CanExport = true; CanExport = true;
CanDelete = true; CanDelete = true;
ContextMenuStrip = new ContextMenuStrip();
} }
public void LoadAnim(FogAnim anim) public void LoadAnim(FogAnim anim)

View file

@ -15,9 +15,19 @@ namespace Bfres.Structs
public ResU.ShapeAnim ShapeAnimU; public ResU.ShapeAnim ShapeAnimU;
public FSHA() public FSHA()
{
}
public void Initialize()
{ {
ImageKey = "shapeAnimation"; ImageKey = "shapeAnimation";
SelectedImageKey = "shapeAnimation"; SelectedImageKey = "shapeAnimation";
CanRename = true;
CanReplace = true;
CanExport = true;
CanDelete = true;
} }
public class ShapeAnimEntry : STGenericWrapper public class ShapeAnimEntry : STGenericWrapper
@ -84,12 +94,14 @@ namespace Bfres.Structs
private void LoadAnim(ShapeAnim shapeAnim) private void LoadAnim(ShapeAnim shapeAnim)
{ {
Initialize();
Text = shapeAnim.Name; Text = shapeAnim.Name;
ShapeAnim = shapeAnim; ShapeAnim = shapeAnim;
} }
private void LoadAnim(ResU.ShapeAnim shapeAnim) private void LoadAnim(ResU.ShapeAnim shapeAnim)
{ {
Initialize();
Text = shapeAnim.Name; Text = shapeAnim.Name;
ShapeAnimU = shapeAnim; ShapeAnimU = shapeAnim;

View file

@ -20,8 +20,10 @@ namespace Bfres.Structs
ImageKey = "materialAnim"; ImageKey = "materialAnim";
SelectedImageKey = "materialAnim"; SelectedImageKey = "materialAnim";
ContextMenuStrip = new ContextMenuStrip(); CanRename = true;
LoadFileMenus(false); CanReplace = true;
CanExport = true;
CanDelete = true;
} }
protected void NewAction(object sender, EventArgs e) { NewMaterialAnim(); } protected void NewAction(object sender, EventArgs e) { NewMaterialAnim(); }

View file

@ -13,7 +13,7 @@ using SELib;
namespace Bfres.Structs namespace Bfres.Structs
{ {
public class FSKA : Animation public class FSKA : Animation, IContextMenuNode
{ {
public enum TrackType public enum TrackType
{ {
@ -41,13 +41,22 @@ namespace Bfres.Structs
ImageKey = "skeletonAnimation"; ImageKey = "skeletonAnimation";
SelectedImageKey = "skeletonAnimation"; SelectedImageKey = "skeletonAnimation";
ContextMenuStrip = new STContextMenuStrip(); CanRename = true;
ContextMenuStrip.Items.Add(new ToolStripMenuItem("New Bone Target", null, NewAction, Keys.Control | Keys.W)); CanReplace = true;
LoadFileMenus(false); CanExport = true;
CanDelete = true;
OpenAnimationData(); OpenAnimationData();
} }
public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
Items.AddRange(base.GetContextMenuItems());
Items.Add(new ToolStripMenuItem("New Bone Target", null, NewAction, Keys.Control | Keys.W));
return Items.ToArray();
}
protected void NewAction(object sender, EventArgs e) { NewBoneAnim(); } protected void NewAction(object sender, EventArgs e) { NewBoneAnim(); }
public void NewBoneAnim() public void NewBoneAnim()
@ -642,7 +651,7 @@ namespace Bfres.Structs
bone.UseSegmentScaleCompensate = bn.ApplySegmentScaleCompensate; bone.UseSegmentScaleCompensate = bn.ApplySegmentScaleCompensate;
Bones.Add(bone); Bones.Add(bone);
Nodes.Add(bone); // Nodes.Add(bone);
if (ska.FlagsRotate == SkeletalAnimFlagsRotate.EulerXYZ) if (ska.FlagsRotate == SkeletalAnimFlagsRotate.EulerXYZ)
bone.RotType = Animation.RotationType.EULER; bone.RotType = Animation.RotationType.EULER;

View file

@ -669,6 +669,8 @@ namespace FirstPlugin
if (Runtime.activeGame == Runtime.ActiveGame.KSA) if (Runtime.activeGame == Runtime.ActiveGame.KSA)
KsaShader.LoadRenderInfo(m, m.renderinfo); KsaShader.LoadRenderInfo(m, m.renderinfo);
m.UpdateRenderPass();
} }
public static void ReadTextureRefs(this FMAT m, Material mat) public static void ReadTextureRefs(this FMAT m, Material mat)
{ {
@ -742,7 +744,7 @@ namespace FirstPlugin
m.HasSpecularMap = true; m.HasSpecularMap = true;
texture.Type = MatTexture.TextureType.Specular; texture.Type = MatTexture.TextureType.Specular;
} }
else if (useSampler == "_x0") else if (useSampler == "_x0" && TextureName.Contains("Mlt"))
{ {
m.HasSphereMap = true; m.HasSphereMap = true;
texture.Type = MatTexture.TextureType.SphereMap; texture.Type = MatTexture.TextureType.SphereMap;

View file

@ -446,6 +446,7 @@ namespace FirstPlugin
m.ReadShaderParams(mat); m.ReadShaderParams(mat);
m.ReadTextureRefs(mat); m.ReadTextureRefs(mat);
m.ReadRenderState(mat.RenderState); m.ReadRenderState(mat.RenderState);
m.UpdateRenderPass();
} }
public static void ReadRenderState(this FMAT m, RenderState renderState) public static void ReadRenderState(this FMAT m, RenderState renderState)
{ {

View file

@ -14,7 +14,7 @@ using FirstPlugin.Turbo;
namespace FirstPlugin namespace FirstPlugin
{ {
public class BYAML : IEditor<ByamlEditor>, IFileFormat public class BYAML : IEditor<ByamlEditor>, IFileFormat, IConvertableTextFormat
{ {
public FileType FileType { get; set; } = FileType.Parameter; public FileType FileType { get; set; } = FileType.Parameter;
@ -50,6 +50,22 @@ namespace FirstPlugin
} }
} }
#region Text Converter Interface
public TextFileType TextFileType => TextFileType.Xml;
public bool CanConvertBack => false;
public string ConvertToString()
{
return XmlConverter.ToXml(data);
}
public void ConvertFromString(string text)
{
data = XmlConverter.ToByml(text);
}
#endregion
class MenuExt : IFileMenuExtension class MenuExt : IFileMenuExtension
{ {
public STToolStripItem[] NewFileMenuExtensions => null; public STToolStripItem[] NewFileMenuExtensions => null;

View file

@ -20,7 +20,7 @@ using Switch_Toolbox.Library.Animations;
namespace FirstPlugin namespace FirstPlugin
{ {
public class BNTX : TreeNodeFile, IFileFormat public class BNTX : TreeNodeFile, IFileFormat, IContextMenuNode
{ {
public FileType FileType { get; set; } = FileType.Image; public FileType FileType { get; set; } = FileType.Image;
@ -118,22 +118,6 @@ namespace FirstPlugin
public BntxFile BinaryTexFile; public BntxFile BinaryTexFile;
public string FileNameText; public string FileNameText;
private bool hasParent;
public bool HasParent
{
get
{
hasParent = Parent != null;
if (ContextMenuStrip != null)
{
ContextMenuStrip.Items[0].Enabled = hasParent;
ContextMenuStrip.Items[6].Enabled = hasParent;
}
return hasParent;
}
}
public bool CanReplace; public bool CanReplace;
public bool AllGLInitialized public bool AllGLInitialized
{ {
@ -159,24 +143,26 @@ namespace FirstPlugin
LoadFile(stream, Name); LoadFile(stream, Name);
PluginRuntime.bntxContainers.Add(this); PluginRuntime.bntxContainers.Add(this);
//Check if bntx is parented to determine if an archive is used
bool checkParent = HasParent;
ContextMenuStrip = new STContextMenuStrip();
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export", null, Save, Keys.Control | Keys.E));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Replace", null, Import, Keys.Control | Keys.R));
ContextMenuStrip.Items.Add(new ToolStripSeparator());
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Import Texture", null, ImportTextureAction, Keys.Control | Keys.I));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Replace Textures (From Folder)", null, ReplaceAll, Keys.Control | Keys.T));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export All Textures", null, ExportAll, Keys.Control | Keys.A));
ContextMenuStrip.Items.Add(new ToolStripSeparator());
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Rename", null, Rename, Keys.Control | Keys.N));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Sort", null, SortTextures, Keys.Control | Keys.S));
ContextMenuStrip.Items.Add(new ToolStripSeparator());
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Clear", null, Clear, Keys.Control | Keys.C));
} }
public ToolStripItem[] GetContextMenuItems()
{
return new ToolStripItem[]
{
new ToolStripMenuItem("Export", null, Save, Keys.Control | Keys.E),
new ToolStripMenuItem("Replace", null, Import, Keys.Control | Keys.R) { Enabled = Parent != null, },
new ToolStripSeparator(),
new ToolStripMenuItem("Import Texture", null, ImportTextureAction, Keys.Control | Keys.I),
new ToolStripMenuItem("Replace Textures (From Folder)", null, ReplaceAll, Keys.Control | Keys.T),
new ToolStripMenuItem("Export All Textures", null, ExportAll, Keys.Control | Keys.A),
new ToolStripSeparator(),
new ToolStripMenuItem("Rename", null, Rename, Keys.Control | Keys.N),
new ToolStripMenuItem("Sort", null, SortTextures, Keys.Control | Keys.S),
new ToolStripSeparator(),
new ToolStripMenuItem("Clear", null, Clear, Keys.Control | Keys.C),
};
}
public void Unload() public void Unload()
{ {
foreach (var tex in Textures.Values) foreach (var tex in Textures.Values)
@ -262,12 +248,6 @@ namespace FirstPlugin
public void OnPropertyChanged(){ Text = BinaryTexFile.Name; } public void OnPropertyChanged(){ Text = BinaryTexFile.Name; }
//Check right click to enable/disable certain context menus
public override void OnMouseRightClick(TreeView treeview)
{
bool checkParent = HasParent;
}
public void LoadFile(Stream stream, string Name = "") public void LoadFile(Stream stream, string Name = "")
{ {
Textures = new Dictionary<string, TextureData>(StringComparer.InvariantCultureIgnoreCase); Textures = new Dictionary<string, TextureData>(StringComparer.InvariantCultureIgnoreCase);

View file

@ -553,8 +553,6 @@ namespace FirstPlugin
ImageKey = "Texture"; ImageKey = "Texture";
SelectedImageKey = "Texture"; SelectedImageKey = "Texture";
LoadContextMenus();
CanDelete = false; CanDelete = false;
CanRename = false; CanRename = false;
} }

View file

@ -402,12 +402,6 @@ namespace FirstPlugin
{ {
if (models[m].Checked) if (models[m].Checked)
{ {
//Check render pass first!
for (int shp = 0; shp < models[m].shapes.Count; shp++)
{
CheckRenderPass(models[m].shapes[shp].GetMaterial());
}
List<FSHP> opaque = new List<FSHP>(); List<FSHP> opaque = new List<FSHP>();
List<FSHP> transparent = new List<FSHP>(); List<FSHP> transparent = new List<FSHP>();
@ -820,6 +814,9 @@ namespace FirstPlugin
for (int shp = 0; shp < models[m].shapes.Count; shp++) for (int shp = 0; shp < models[m].shapes.Count; shp++)
{ {
//Update render pass aswell
CheckRenderPass(models[m].shapes[shp].GetMaterial());
models[m].shapes[shp].Offset = poffset * 4; models[m].shapes[shp].Offset = poffset * 4;
List<DisplayVertex> pv = models[m].shapes[shp].CreateDisplayVertices(models[m]); List<DisplayVertex> pv = models[m].shapes[shp].CreateDisplayVertices(models[m]);
Vs.AddRange(pv); Vs.AddRange(pv);
@ -908,7 +905,6 @@ namespace FirstPlugin
CullBack = mat.renderinfo[i].ValueString.Contains("front"); CullBack = mat.renderinfo[i].ValueString.Contains("front");
} }
if (mat.shaderassign.ShaderArchive == "Turbo_UBER") if (mat.shaderassign.ShaderArchive == "Turbo_UBER")
{ {
AglShaderTurbo aglShader = new AglShaderTurbo(); AglShaderTurbo aglShader = new AglShaderTurbo();
@ -951,6 +947,10 @@ namespace FirstPlugin
IsTranslucent = mat.renderinfo[i].ValueString.Contains("translucent"); IsTranslucent = mat.renderinfo[i].ValueString.Contains("translucent");
IsTransparentMask = mat.renderinfo[i].ValueString.Contains("mask"); IsTransparentMask = mat.renderinfo[i].ValueString.Contains("mask");
} }
if (mat.renderinfo[i].Name == "renderPass")
{
IsTransparentMask = mat.renderinfo[i].ValueString.Contains("xlu");
}
} }
if (mat.shaderassign.options.ContainsKey("enable_translucent")) if (mat.shaderassign.options.ContainsKey("enable_translucent"))
@ -1013,7 +1013,6 @@ namespace FirstPlugin
shader.SetFloat("SRT_Rotate", 0); shader.SetFloat("SRT_Rotate", 0);
shader.SetVector2("SRT_Translate", new Vector2(0, 0)); shader.SetVector2("SRT_Translate", new Vector2(0, 0));
shader.SetInt("selectedBoneIndex", Runtime.SelectedBoneIndex); shader.SetInt("selectedBoneIndex", Runtime.SelectedBoneIndex);
SetUniformData(mat, shader, "base_color_mul_color"); SetUniformData(mat, shader, "base_color_mul_color");

View file

@ -12,7 +12,7 @@ using Bfres.Structs;
namespace FirstPlugin.NodeWrappers namespace FirstPlugin.NodeWrappers
{ {
public class BFRESWrapper : STGenericWrapper public class BFRESWrapper : STGenericWrapper, IContextMenuNode
{ {
public override void OnClick(TreeView treeview) public override void OnClick(TreeView treeview)
{ {
@ -20,25 +20,22 @@ namespace FirstPlugin.NodeWrappers
} }
public bool IsWiiU { get; set; } public bool IsWiiU { get; set; }
public bool SettingRemoveUnusedTextures;
public bool SettingRemoveUnusedTextures
{
get
{
return ((ToolStripMenuItem)SettingsToolStrip.DropDownItems[0]).Checked;
}
}
private ToolStripMenuItem SettingsToolStrip; private ToolStripMenuItem SettingsToolStrip;
public void LoadMenus(bool isWiiUBfres) { public void LoadMenus(bool isWiiUBfres) {
IsWiiU = isWiiUBfres; IsWiiU = isWiiUBfres;
}
LoadFileMenus(true); public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
Items.AddRange(base.GetContextMenuItems());
SettingsToolStrip = new ToolStripMenuItem("Settings", null); SettingsToolStrip = new ToolStripMenuItem("Settings", null);
SettingsToolStrip.DropDownItems.Add(new ToolStripMenuItem("Remove Unused Textures on Save", null, SettingBooleanAction)); SettingsToolStrip.DropDownItems.Add(new ToolStripMenuItem("Remove Unused Textures on Save", null, SettingBooleanAction));
ContextMenuStrip.Items.Add(SettingsToolStrip); Items.Add(SettingsToolStrip);
return Items.ToArray();
} }
public override void Delete() public override void Delete()

View file

@ -203,6 +203,7 @@
<Compile Include="FileFormats\Archives\MKGPDX_PAC.cs" /> <Compile Include="FileFormats\Archives\MKGPDX_PAC.cs" />
<Compile Include="FileFormats\Archives\NXARC.cs" /> <Compile Include="FileFormats\Archives\NXARC.cs" />
<Compile Include="FileFormats\Archives\RARC.cs" /> <Compile Include="FileFormats\Archives\RARC.cs" />
<Compile Include="FileFormats\Archives\SARC_OLD.cs" />
<Compile Include="FileFormats\Archives\SP2.cs" /> <Compile Include="FileFormats\Archives\SP2.cs" />
<Compile Include="FileFormats\Archives\TMPK.cs" /> <Compile Include="FileFormats\Archives\TMPK.cs" />
<Compile Include="FileFormats\Audio\Archives\BARS.cs" /> <Compile Include="FileFormats\Audio\Archives\BARS.cs" />

View file

@ -158,6 +158,16 @@ namespace Switch_Toolbox.Library.Forms
editor.FillEditor(ArchiveFileInfo.FileData); editor.FillEditor(ArchiveFileInfo.FileData);
} }
private void NotifyFormatSwitched()
{
}
private void SaveTextFormat()
{
}
private bool IsConvertableText(Type type) private bool IsConvertableText(Type type)
{ {
return typeof(IConvertableTextFormat).IsAssignableFrom(type); return typeof(IConvertableTextFormat).IsAssignableFrom(type);

View file

@ -12,7 +12,7 @@ namespace Switch_Toolbox.Library.NodeWrappers
{ {
//Generic wrapper based on https://github.com/libertyernie/brawltools/blob/40d7431b1a01ef4a0411cd69e51411bd581e93e2/BrawlBox/NodeWrappers/GenericWrapper //Generic wrapper based on https://github.com/libertyernie/brawltools/blob/40d7431b1a01ef4a0411cd69e51411bd581e93e2/BrawlBox/NodeWrappers/GenericWrapper
//Store useful generic functions in this wrapper for tree nodes //Store useful generic functions in this wrapper for tree nodes
public class STGenericWrapper : TreeNodeCustom public class STGenericWrapper : TreeNodeCustom, IContextMenuNode
{ {
public STGenericWrapper(string name) { Text = name; } public STGenericWrapper(string name) { Text = name; }
@ -30,50 +30,15 @@ namespace Switch_Toolbox.Library.NodeWrappers
return Name; return Name;
} }
private bool canExport; public bool IsFolder = false;
public bool CanExport
{
get { return canExport; }
set
{
canExport = value;
EnableContextMenu(ContextMenuStrip.Items, "Export", canExport);
}
}
private bool canReplace; public bool CanExport { get; set; }
public bool CanReplace
{
get { return canReplace; }
set
{
canReplace = value;
EnableContextMenu(ContextMenuStrip.Items, "Replace", canReplace);
}
}
private bool canRename; public bool CanReplace { get; set; }
public bool CanRename
{
get { return canRename; }
set
{
canRename = value;
EnableContextMenu(ContextMenuStrip.Items, "Rename", canRename);
} public bool CanRename { get; set; }
}
private bool canDelete; public bool CanDelete { get; set; }
public bool CanDelete
{
get { return canDelete; }
set
{
canDelete = value;
EnableContextMenu(ContextMenuStrip.Items,"Delete", canDelete);
}
}
private void EnableContextMenu(ToolStripItemCollection Items, string Key, bool Enabled) private void EnableContextMenu(ToolStripItemCollection Items, string Key, bool Enabled)
{ {
@ -86,52 +51,49 @@ namespace Switch_Toolbox.Library.NodeWrappers
public STGenericWrapper(bool LoadMenus = true) public STGenericWrapper(bool LoadMenus = true)
{ {
if (LoadMenus)
LoadContextMenus();
else
ContextMenuStrip = new STContextMenuStrip();
CanExport = true; CanExport = true;
CanReplace = false; CanReplace = false;
CanRename = true; CanRename = true;
CanDelete = false; CanDelete = false;
} }
public virtual void LoadContextMenus() public ToolStripItem[] GetContextMenuItems()
{ {
LoadFileMenus(); if (IsFolder)
{
return new ToolStripItem[]
{
new ToolStripMenuItem("Import", null, ImportAction, Keys.Control | Keys.I) {Enabled = CanReplace },
new ToolStripMenuItem("Export All", null, ExportAllAction, Keys.Control | Keys.E) {Enabled = CanExport },
new ToolStripMenuItem("Replace All", null, ReplaceAllAction, Keys.Control | Keys.R) {Enabled = CanReplace },
new ToolStripSeparator(),
new ToolStripMenuItem("Sort", null, SortAction, Keys.Control | Keys.N),
new ToolStripSeparator(),
new ToolStripMenuItem("Clear", null, ClearAction, Keys.Control | Keys.Delete) {Enabled = CanDelete } ,
};
} }
else
public void LoadFileMenus(bool Reset = true)
{ {
if (Reset) return new ToolStripItem[]
ContextMenuStrip = new STContextMenuStrip(); {
new ToolStripMenuItem("Export", null, ExportAction, Keys.Control | Keys.E) {Enabled = CanExport },
//File Operations new ToolStripMenuItem("Replace", null, ReplaceAction, Keys.Control | Keys.R) {Enabled = CanReplace },
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export", null, ExportAction, Keys.Control | Keys.E)); new ToolStripSeparator(),
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Replace", null, ReplaceAction, Keys.Control | Keys.R)); new ToolStripMenuItem("Rename", null, RenameAction, Keys.Control | Keys.N) {Enabled = CanRename },
ContextMenuStrip.Items.Add(new ToolStripSeparator()); new ToolStripSeparator(),
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Rename", null, RenameAction, Keys.Control | Keys.N)); new ToolStripMenuItem("Delete", null, DeleteAction, Keys.Control | Keys.Delete) {Enabled = CanDelete },
ContextMenuStrip.Items.Add(new ToolStripSeparator()); };
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Delete", null, DeleteAction, Keys.Control | Keys.Delete)); }
} }
public void LoadFolderMenus() public void LoadFolderMenus()
{ {
ContextMenuStrip = new STContextMenuStrip();
CanExport = false; CanExport = false;
CanReplace = false; CanReplace = false;
CanRename = false; CanRename = false;
CanDelete = false; CanDelete = false;
//Folder Operations IsFolder = true;
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Import", null, ImportAction, Keys.Control | Keys.I));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export All", null, ExportAllAction, Keys.Control | Keys.E));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Replace All", null, ReplaceAllAction, Keys.Control | Keys.R));
ContextMenuStrip.Items.Add(new ToolStripSeparator());
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Sort", null, SortAction, Keys.Control | Keys.N));
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Clear", null, ClearAction, Keys.Control | Keys.C));
} }
protected void ReplaceAllAction(object sender, EventArgs e) protected void ReplaceAllAction(object sender, EventArgs e)

View file

@ -85,6 +85,7 @@ namespace Switch_Toolbox.Library
} }
} }
public virtual Dictionary<string, string> ExtensionImageKeyLookup { get; }
public virtual void Replace() public virtual void Replace()
{ {
@ -475,16 +476,20 @@ namespace Switch_Toolbox.Library
ArchiveFileInfo = archiveFileInfo; ArchiveFileInfo = archiveFileInfo;
string Extension = ""; string Extension = Utils.GetExtension(text);
if (ArchiveFileInfo.CheckFileMagic) if (ArchiveFileInfo.CheckFileMagic)
{ {
Extension = FindMatch(archiveFileInfo.FileData); Extension = FindMatch(archiveFileInfo.FileData);
} }
if (ArchiveFileInfo.ExtensionImageKeyLookup.ContainsKey(Extension))
SetImageKey(ArchiveFileInfo.ExtensionImageKeyLookup[Extension]);
switch (Extension) switch (Extension)
{ {
case ".bntx": SetImageKey("bntx"); break; case ".bntx": SetImageKey("bntx"); break;
case ".byaml": SetImageKey("byaml"); break; case ".byaml": SetImageKey("byaml"); break;
case ".byml": SetImageKey("byaml"); break;
case ".aamp": SetImageKey("aamp"); break; case ".aamp": SetImageKey("aamp"); break;
case ".bfres": SetImageKey("bfres"); break; case ".bfres": SetImageKey("bfres"); break;
case ".sbfres": SetImageKey("sbfres"); break; case ".sbfres": SetImageKey("sbfres"); break;