Add massive speed boost and memory improvements for archives with 1000s of files

This also fixes transparency on PBR shader.
Fixes odyssey costume viewer framing bfes
This commit is contained in:
KillzXGaming 2019-06-24 15:45:54 -04:00
parent a317c88e3c
commit 6798db20de
18 changed files with 237 additions and 611 deletions

View file

@ -48,12 +48,7 @@ namespace FirstPlugin
public IEnumerable<ArchiveFileInfo> Files => files;
SDFTOC_Header Header;
SDFTOC_ID startId;
int[] block1;
SDFTOC_ID[] blockIds;
public SDFTOC_Block2[] block2Array;
byte[] DecompressedBlock;
SDFTOC_ID endId;
//Thanks to https://github.com/GoldFarmer/rouge_sdf/blob/master/main.cpp for docs/structs
public void Load(System.IO.Stream stream)
@ -67,7 +62,7 @@ namespace FirstPlugin
Header.Read(reader);
//Read first id
startId = new SDFTOC_ID(reader);
var startId = new SDFTOC_ID(reader);
//Check this flag
byte Flag1 = reader.ReadByte();
@ -76,11 +71,11 @@ namespace FirstPlugin
byte[] unk = reader.ReadBytes(0x140);
}
//Read first block
block1 = reader.ReadInt32s((int)Header.Block1Count);
//Read first block
var block1 = reader.ReadInt32s((int)Header.Block1Count);
//Read ID blocks
blockIds = new SDFTOC_ID[Header.Block1Count];
var blockIds = new SDFTOC_ID[Header.Block1Count];
for (int i = 0; i < Header.Block1Count; i++)
{
blockIds[i] = new SDFTOC_ID(reader);
@ -102,22 +97,25 @@ namespace FirstPlugin
DecompressNameBlock(magic, reader.ReadBytes((int)Header.CompressedSize), Header);
//Read last id
endId = new SDFTOC_ID(reader);
var endId = new SDFTOC_ID(reader);
for (int i = 0; i < FileEntries.Count; i++)
{
FileEntries[i].CanLoadFile = SupportedExtensions.Contains(Utils.GetExtension(FileEntries[i].FileName));
files.Add(FileEntries[i]);
}
//Remove unused data
reader.Dispose();
startId = null;
block1 = new int[0];
blockIds = new SDFTOC_ID[0];
endId = null;
}
}
private List<string> SupportedExtensions = new List<string>()
{".mgraphobject" };
// private List<string> SupportedExtensions = new List<string>()
// { ".dds", ".tga" ,".mmb", ".png", ".jpg", ".mgraphobject" };
{ ".dds", ".tga" ,".mmb", ".png", ".jpg", ".mgraphobject" };
private TreeNode GetNodes(TreeNode parent, string[] fileList)
{
@ -164,6 +162,11 @@ namespace FirstPlugin
{
ParseNames(reader);
}
CompressedBlock = new byte[0];
decomp = new byte[0];
decomp = null;
CompressedBlock = null;
}
private ulong readVariadicInteger(int Count, FileReader reader)

View file

@ -1,114 +0,0 @@
namespace FirstPlugin.Forms
{
partial class AnimationLoader
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.btnSave = new Switch_Toolbox.Library.Forms.STButton();
this.animTreeView = new Switch_Toolbox.Library.TreeViewCustom();
this.animTypeCB = new Switch_Toolbox.Library.Forms.STComboBox();
this.btnOpen = new Switch_Toolbox.Library.Forms.STButton();
this.contentContainer.SuspendLayout();
this.SuspendLayout();
//
// contentContainer
//
this.contentContainer.Controls.Add(this.btnOpen);
this.contentContainer.Controls.Add(this.animTypeCB);
this.contentContainer.Controls.Add(this.animTreeView);
this.contentContainer.Controls.Add(this.btnSave);
this.contentContainer.Size = new System.Drawing.Size(321, 575);
this.contentContainer.Controls.SetChildIndex(this.btnSave, 0);
this.contentContainer.Controls.SetChildIndex(this.animTreeView, 0);
this.contentContainer.Controls.SetChildIndex(this.animTypeCB, 0);
this.contentContainer.Controls.SetChildIndex(this.btnOpen, 0);
//
// btnSave
//
this.btnSave.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnSave.Location = new System.Drawing.Point(93, 31);
this.btnSave.Name = "btnSave";
this.btnSave.Size = new System.Drawing.Size(75, 23);
this.btnSave.TabIndex = 0;
this.btnSave.Text = "Save";
this.btnSave.UseVisualStyleBackColor = false;
//
// animTreeView
//
this.animTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.animTreeView.ImageIndex = 0;
this.animTreeView.Location = new System.Drawing.Point(12, 88);
this.animTreeView.Name = "animTreeView";
this.animTreeView.SelectedImageIndex = 0;
this.animTreeView.Size = new System.Drawing.Size(306, 483);
this.animTreeView.TabIndex = 1;
this.animTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.animTreeView_AfterSelect);
this.animTreeView.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.selectItem);
//
// animTypeCB
//
this.animTypeCB.FormattingEnabled = true;
this.animTypeCB.Location = new System.Drawing.Point(12, 61);
this.animTypeCB.Name = "animTypeCB";
this.animTypeCB.Size = new System.Drawing.Size(305, 21);
this.animTypeCB.TabIndex = 2;
this.animTypeCB.SelectedIndexChanged += new System.EventHandler(this.animTypeCB_SelectedIndexChanged);
//
// btnOpen
//
this.btnOpen.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnOpen.Location = new System.Drawing.Point(12, 31);
this.btnOpen.Name = "btnOpen";
this.btnOpen.Size = new System.Drawing.Size(75, 23);
this.btnOpen.TabIndex = 3;
this.btnOpen.Text = "Open";
this.btnOpen.UseVisualStyleBackColor = false;
this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click);
//
// AnimationLoader
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(327, 580);
this.Name = "AnimationLoader";
this.Text = "Animation Loader";
this.contentContainer.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private Switch_Toolbox.Library.Forms.STButton btnSave;
private Switch_Toolbox.Library.TreeViewCustom animTreeView;
private Switch_Toolbox.Library.Forms.STComboBox animTypeCB;
private Switch_Toolbox.Library.Forms.STButton btnOpen;
}
}

View file

@ -1,192 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Switch_Toolbox.Library.Forms;
using Switch_Toolbox.Library;
using Switch_Toolbox.Library.IO;
using Switch_Toolbox.Library.Animations;
using System.Text.RegularExpressions;
using Bfres.Structs;
namespace FirstPlugin.Forms
{
public partial class AnimationLoader : STForm
{
public AnimationLoader()
{
InitializeComponent();
animTypeCB.Items.Add("Skeletal Animation");
animTypeCB.Items.Add("Material Animation");
animTypeCB.Items.Add("Bone Visibilty Animation");
animTypeCB.Items.Add("Scene Animation");
animTypeCB.Items.Add("Shape Animation");
}
public void LoadFile(string fileName)
{
}
public BFRES bfres;
private void btnOpen_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
List<IFileFormat> formats = new List<IFileFormat>();
formats.Add(new BFRES());
ofd.Filter = Utils.GetAllFilters(formats);
if (ofd.ShowDialog() == DialogResult.OK)
{
var format = STFileLoader.OpenFileFormat(ofd.FileName);
if (format != null)
{
if (format is SARC)
{
foreach (SARC.SarcEntry fileNode in ((SARC)format).Nodes)
{
if (fileNode.ImageKey == "bfres")
{
var sarcFile = STFileLoader.OpenFileFormat(fileNode.FullName, fileNode.Data, false, true);
bfres = (BFRES)sarcFile;
}
}
}
else if (format is BFRES)
{
bfres = (BFRES)format;
}
else
throw new Exception("Failed to load bfres file. ");
}
}
}
private void LoadAnimations(TreeNodeCollection nodes)
{
string cbText = animTypeCB.GetItemText(animTypeCB.SelectedItem);
animTreeView.Nodes.Clear();
foreach (var node in nodes)
{
if (node is BFRESGroupNode)
{
BFRESGroupNode group = (BFRESGroupNode)node;
switch (group.Type)
{
case BRESGroupType.SkeletalAnim:
case BRESGroupType.MaterialAnim:
case BRESGroupType.BoneVisAnim:
case BRESGroupType.ShapeAnim:
case BRESGroupType.SceneAnim:
case BRESGroupType.MatVisAnim:
case BRESGroupType.ShaderParamAnim:
case BRESGroupType.ColorAnim:
case BRESGroupType.TexSrtAnim:
case BRESGroupType.TexPatAnim:
AddAnims(group);
break;
}
}
}
}
private void AddAnims(TreeNode node)
{
foreach (TreeNode anim in node.Nodes)
{
animTreeView.Nodes.Add(anim);
}
}
private void selectItem(object sender, TreeNodeMouseClickEventArgs e)
{
Viewport viewport = LibraryGUI.Instance.GetActiveViewport();
if (viewport == null)
return;
if (e.Node is Animation)
{
string AnimName = e.Node.Text;
AnimName = Regex.Match(AnimName, @"([A-Z][0-9][0-9])(.*)").Groups[0].ToString();
if (AnimName.Length > 3)
AnimName = AnimName.Substring(3);
Console.WriteLine("AnimName " + AnimName);
Animation running = new Animation(AnimName);
running.ReplaceMe((Animation)e.Node);
running.Tag = e.Node;
Queue<TreeNode> NodeQueue = new Queue<TreeNode>();
foreach (TreeNode n in animTreeView.Nodes)
{
NodeQueue.Enqueue(n);
}
while (NodeQueue.Count > 0)
{
try
{
TreeNode n = NodeQueue.Dequeue();
string NodeName = Regex.Match(n.Text, @"([A-Z][0-9][0-9])(.*)").Groups[0].ToString();
if (NodeName.Length <= 3)
Console.WriteLine(NodeName);
else
NodeName = NodeName.Substring(3);
if (n is Animation)
{
if (n == e.Node)
continue;
if (NodeName.Equals(AnimName))
{
running.Children.Add(n);
}
}
if (n is AnimationGroupNode)
{
foreach (TreeNode tn in n.Nodes)
NodeQueue.Enqueue(tn);
}
}
catch
{
}
}
if (LibraryGUI.Instance.GetAnimationPanel() != null)
{
Console.WriteLine("running" + running.Text);
LibraryGUI.Instance.GetAnimationPanel().CurrentAnimation = running;
}
}
}
private void animTypeCB_SelectedIndexChanged(object sender, EventArgs e)
{
if (animTypeCB.SelectedIndex >= 0)
{
if (bfres != null)
{
LoadAnimations(bfres.Nodes);
}
}
}
private void animTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
}
}
}

View file

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -131,6 +131,8 @@ namespace FirstPlugin
if (costumSelector.ShowDialog() == DialogResult.OK)
{
LoadCostumes(costumSelector.SelectedCostumeName);
FrameBfres();
}
}
@ -201,6 +203,7 @@ namespace FirstPlugin
}
private ObjectEditor editor;
private BFRES MainCostume = null;
public void LoadCostume(string fileName)
{
List<BFRES> bfresFiles = new List<BFRES>();
@ -226,6 +229,9 @@ namespace FirstPlugin
LibraryGUI.Instance.CreateMdiWindow(editor);
}
if (MainCostume == null && bfresFiles.Count > 0)
MainCostume = bfresFiles[0];
foreach (var bfres in bfresFiles)
{
editor.AddNode(bfres);
@ -234,6 +240,14 @@ namespace FirstPlugin
}
}
private void FrameBfres()
{
BfresEditor bfresEditor = (BfresEditor)LibraryGUI.Instance.GetActiveContent(typeof(BfresEditor));
bfresEditor.FrameCamera(MainCostume.BFRESRender);
MainCostume = null;
}
private void DiableLoadCheck()
{
BfresEditor bfresEditor = (BfresEditor)LibraryGUI.Instance.GetActiveContent(typeof(BfresEditor));

View file

@ -504,12 +504,6 @@
<SubType>Form</SubType>
</Compile>
<Compile Include="GUI\AAMP\EditBox.Designer.cs" />
<Compile Include="GUI\AnimationLoader.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="GUI\AnimationLoader.Designer.cs">
<DependentUpon>AnimationLoader.cs</DependentUpon>
</Compile>
<Compile Include="GUI\BFRES\BfresEditor.cs">
<SubType>UserControl</SubType>
</Compile>
@ -931,9 +925,6 @@
<EmbeddedResource Include="GUI\Advanced Editor\TextureViewer.resx">
<DependentUpon>TextureViewer.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="GUI\AnimationLoader.resx">
<DependentUpon>AnimationLoader.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="GUI\AttributeEditor.resx">
<DependentUpon>AttributeEditor.cs</DependentUpon>
</EmbeddedResource>

View file

@ -234,7 +234,6 @@ C:\Users\Nathan\Documents\GitHub\SwitchToolboxV1\Switch_FileFormatsMain\obj\Rele
C:\Users\Nathan\Documents\GitHub\SwitchToolboxV1\Switch_FileFormatsMain\obj\Release\Switch_FileFormatsMain.csproj.ResolveComReference.cache
C:\Users\Nathan\Documents\GitHub\SwitchToolboxV1\Switch_FileFormatsMain\obj\Release\FirstPlugin.GUI.AAMP.EditBox.resources
C:\Users\Nathan\Documents\GitHub\SwitchToolboxV1\Switch_FileFormatsMain\obj\Release\FirstPlugin.TextureViewer.resources
C:\Users\Nathan\Documents\GitHub\SwitchToolboxV1\Switch_FileFormatsMain\obj\Release\FirstPlugin.Forms.AnimationLoader.resources
C:\Users\Nathan\Documents\GitHub\SwitchToolboxV1\Switch_FileFormatsMain\obj\Release\FirstPlugin.AttributeEditor.resources
C:\Users\Nathan\Documents\GitHub\SwitchToolboxV1\Switch_FileFormatsMain\obj\Release\FirstPlugin.Forms.BfresEditor.resources
C:\Users\Nathan\Documents\GitHub\SwitchToolboxV1\Switch_FileFormatsMain\obj\Release\FirstPlugin.Forms.BfresHeaderEditor.resources

View file

@ -160,14 +160,7 @@ namespace Switch_Toolbox.Library.Forms
private bool IsConvertableText(Type type)
{
foreach (var inter in type.GetInterfaces())
{
if (inter.IsGenericType && inter.GetGenericTypeDefinition() == typeof(IConvertableTextFormat))
{
return true;
}
}
return false;
return typeof(IConvertableTextFormat).IsAssignableFrom(type);
}
private void UpdatePropertiesView()

View file

@ -38,15 +38,16 @@
this.stPanel3 = new Switch_Toolbox.Library.Forms.STPanel();
this.searchImgPB = new System.Windows.Forms.PictureBox();
this.activeEditorChkBox = new Switch_Toolbox.Library.Forms.STCheckBox();
this.stContextMenuStrip1 = new Switch_Toolbox.Library.Forms.STMenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.sortToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.objectEditorMenu = new Switch_Toolbox.Library.Forms.STMenuStrip();
this.treeNodeContextMenu = new Switch_Toolbox.Library.Forms.STContextMenuStrip(this.components);
this.stPanel1.SuspendLayout();
this.stPanel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.searchImgPB)).BeginInit();
this.stContextMenuStrip1.SuspendLayout();
this.objectEditorMenu.SuspendLayout();
this.SuspendLayout();
//
// splitter1
@ -107,7 +108,7 @@
this.treeViewCustom1.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.treeViewCustom1_AfterCheck);
this.treeViewCustom1.DrawNode += new System.Windows.Forms.DrawTreeNodeEventHandler(this.treeViewCustom1_DrawNode);
this.treeViewCustom1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeViewCustom1_AfterSelect);
this.treeViewCustom1.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.selectItem);
this.treeViewCustom1.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeViewCustom1_MouseClick);
this.treeViewCustom1.DragDrop += new System.Windows.Forms.DragEventHandler(this.treeViewCustom1_DragDrop);
this.treeViewCustom1.DragOver += new System.Windows.Forms.DragEventHandler(this.treeViewCustom1_DragOver);
this.treeViewCustom1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.treeViewCustom1_DoubleClick);
@ -129,7 +130,7 @@
//
this.stPanel3.Controls.Add(this.searchImgPB);
this.stPanel3.Controls.Add(this.activeEditorChkBox);
this.stPanel3.Controls.Add(this.stContextMenuStrip1);
this.stPanel3.Controls.Add(this.objectEditorMenu);
this.stPanel3.Dock = System.Windows.Forms.DockStyle.Top;
this.stPanel3.Location = new System.Drawing.Point(0, 0);
this.stPanel3.Name = "stPanel3";
@ -159,18 +160,6 @@
this.activeEditorChkBox.UseVisualStyleBackColor = true;
this.activeEditorChkBox.CheckedChanged += new System.EventHandler(this.activeEditorChkBox_CheckedChanged);
//
// stContextMenuStrip1
//
this.stContextMenuStrip1.Dock = System.Windows.Forms.DockStyle.Fill;
this.stContextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.viewToolStripMenuItem});
this.stContextMenuStrip1.Location = new System.Drawing.Point(0, 0);
this.stContextMenuStrip1.Name = "stContextMenuStrip1";
this.stContextMenuStrip1.Size = new System.Drawing.Size(314, 26);
this.stContextMenuStrip1.TabIndex = 1;
this.stContextMenuStrip1.Text = "stContextMenuStrip1";
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -201,6 +190,23 @@
this.sortToolStripMenuItem.Text = "Sort";
this.sortToolStripMenuItem.Click += new System.EventHandler(this.sortToolStripMenuItem_Click);
//
// objectEditorMenu
//
this.objectEditorMenu.Dock = System.Windows.Forms.DockStyle.Fill;
this.objectEditorMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.viewToolStripMenuItem});
this.objectEditorMenu.Location = new System.Drawing.Point(0, 0);
this.objectEditorMenu.Name = "objectEditorMenu";
this.objectEditorMenu.Size = new System.Drawing.Size(314, 26);
this.objectEditorMenu.TabIndex = 1;
this.objectEditorMenu.Text = "stContextMenuStrip1";
//
// treeNodeContextMenu
//
this.treeNodeContextMenu.Name = "treeNodeContextMenu";
this.treeNodeContextMenu.Size = new System.Drawing.Size(61, 4);
//
// ObjectEditorTree
//
this.Controls.Add(this.splitter1);
@ -213,8 +219,8 @@
this.stPanel3.ResumeLayout(false);
this.stPanel3.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.searchImgPB)).EndInit();
this.stContextMenuStrip1.ResumeLayout(false);
this.stContextMenuStrip1.PerformLayout();
this.objectEditorMenu.ResumeLayout(false);
this.objectEditorMenu.PerformLayout();
this.ResumeLayout(false);
}
@ -226,14 +232,15 @@
private STPanel stPanel1;
private STPanel stPanel3;
private TreeViewCustom treeViewCustom1;
private STMenuStrip stContextMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem;
private STTextBox stTextBox1;
private System.Windows.Forms.PictureBox searchImgPB;
private STLabel searchLbl;
private STCheckBox activeEditorChkBox;
private STMenuStrip objectEditorMenu;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem sortToolStripMenuItem;
private STCheckBox activeEditorChkBox;
private STContextMenuStrip treeNodeContextMenu;
}
}

View file

@ -17,6 +17,8 @@ namespace Switch_Toolbox.Library.Forms
{
public partial class ObjectEditorTree : UserControl
{
private bool SuppressAfterSelectEvent = false;
public ObjectEditor ObjectEditor;
private TreeView _fieldsTreeCache;
@ -24,83 +26,13 @@ namespace Switch_Toolbox.Library.Forms
public void BeginUpdate() { treeViewCustom1.BeginUpdate(); }
public void EndUpdate() { treeViewCustom1.EndUpdate(); }
public readonly int MAX_TREENODE_VALUE = 4000;
public void AddIArchiveFile(IFileFormat FileFormat)
{
TreeNode FileRoot = new ArchiveRootNodeWrapper(FileFormat.FileName, (IArchiveFile)FileFormat);
FillTreeNodes(FileRoot, (IArchiveFile)FileFormat);
var FileRoot = new ArchiveRootNodeWrapper(FileFormat.FileName, (IArchiveFile)FileFormat);
FileRoot.FillTreeNodes();
AddNode(FileRoot);
}
void FillTreeNodes(TreeNode root, IArchiveFile archiveFile)
{
var rootText = root.Text;
var rootTextLength = rootText.Length;
var nodeFiles = archiveFile.Files;
int I = 0;
foreach (var node in nodeFiles)
{
if (!node.CanLoadFile)
continue;
if (I++ == MAX_TREENODE_VALUE)
{
var result = MessageBox.Show($"The amount of treenodes has reached over {MAX_TREENODE_VALUE} nodes. To prevent memory loss this is put in place. Do you want to continue loading all of them?",
"", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
if (result != DialogResult.Yes)
break;
}
string nodeString = node.FileName;
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 ArchiveFolderNodeWrapper(parentName, archiveFile);
if (rootIndex == roots.Length - 1)
{
ArchiveFileWrapper wrapperFile = new ArchiveFileWrapper(parentName, node, archiveFile);
wrapperFile.Name = nodeName;
parentNode.Nodes.Add(wrapperFile);
parentNode = wrapperFile;
}
else
{
folder.Name = nodeName;
parentNode.Nodes.Add(folder);
parentNode = folder;
}
}
else
{
// Node was found, set that as parent and continue
parentNode = parentNode.Nodes[index];
}
}
}
}
public void AddNodeCollection(TreeNodeCollection nodes, bool ClearNodes)
{
// Invoke the treeview to add the nodes
@ -224,6 +156,9 @@ namespace Switch_Toolbox.Library.Forms
bool RenderedObjectWasSelected = false;
private void treeViewCustom1_AfterSelect(object sender, TreeViewEventArgs e)
{
if (SuppressAfterSelectEvent)
return;
var node = treeViewCustom1.SelectedNode;
//Set the current index used determine what bone is selected.
@ -309,26 +244,48 @@ namespace Switch_Toolbox.Library.Forms
ClearNodes();
}
private void selectItem(object sender, TreeNodeMouseClickEventArgs e)
private void treeViewCustom1_MouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
Viewport viewport = LibraryGUI.Instance.GetActiveViewport();
if (viewport == null)
return;
if (e.Node is Animation)
if (e.Button == MouseButtons.Right)
{
if (((Animation)e.Node).Bones.Count <= 0)
((Animation)e.Node).OpenAnimationData();
if (e.Node is IContextMenuNode)
{
treeNodeContextMenu.Items.Clear();
treeNodeContextMenu.Items.AddRange(((IContextMenuNode)e.Node).GetContextMenuItems());
treeNodeContextMenu.Show(Cursor.Position);
string AnimName = e.Node.Text;
//Select the node without the evemt
//We don't want editors displaying on only right clicking
SuppressAfterSelectEvent = true;
treeViewCustom1.SelectedNode = e.Node;
SuppressAfterSelectEvent = false;
}
}
else
{
OnAnimationSelected(e.Node);
}
}
private void OnAnimationSelected(TreeNode Node)
{
if (Node is Animation)
{
Viewport viewport = LibraryGUI.Instance.GetActiveViewport();
if (viewport == null)
return;
if (((Animation)Node).Bones.Count <= 0)
((Animation)Node).OpenAnimationData();
string AnimName = Node.Text;
AnimName = Regex.Match(AnimName, @"([A-Z][0-9][0-9])(.*)").Groups[0].ToString();
if (AnimName.Length > 3)
AnimName = AnimName.Substring(3);
Animation running = new Animation(AnimName);
running.ReplaceMe((Animation)e.Node);
running.Tag = e.Node;
running.ReplaceMe((Animation)Node);
running.Tag = Node;
Queue<TreeNode> NodeQueue = new Queue<TreeNode>();
foreach (TreeNode n in treeViewCustom1.Nodes)
@ -347,7 +304,7 @@ namespace Switch_Toolbox.Library.Forms
NodeName = NodeName.Substring(3);
if (n is Animation)
{
if (n == e.Node)
if (n == Node)
continue;
if (NodeName.Equals(AnimName))
{

View file

@ -117,7 +117,10 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="stContextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<metadata name="objectEditorMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="treeNodeContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>166, 17</value>
</metadata>
</root>

View file

@ -171,7 +171,7 @@ namespace Switch_Toolbox.Library
}
//Wrapper for the archive file itself
public class ArchiveRootNodeWrapper : ArchiveBase
public class ArchiveRootNodeWrapper : ArchiveBase, IContextMenuNode
{
public virtual object PropertyDisplay { get; set; }
@ -180,29 +180,20 @@ namespace Switch_Toolbox.Library
{
Text = text;
ReloadMenus();
PropertyDisplay = new GenericArchiveProperties(archiveFile, text);
if (!((IFileFormat)archiveFile).CanSave) {
EnableContextMenu(ContextMenuStrip.Items, "Save", false);
}
if (!archiveFile.CanReplaceFiles) {
EnableContextMenu(ContextMenuStrip.Items, "Repack", false);
}
}
public void ReloadMenus(bool IsNewInstance = true)
public ToolStripItem[] GetContextMenuItems()
{
if (IsNewInstance)
ContextMenuStrip = new STContextMenuStrip();
ContextMenuStrip.Items.Add(new STToolStripItem("Save", SaveAction));
ContextMenuStrip.Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStripItem("Repack", RepackAction));
ContextMenuStrip.Items.Add(new STToolStripItem("Extract All", ExtractAllAction));
ContextMenuStrip.Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStripItem("Preview Archive", PreviewAction));
return new ToolStripItem[]
{
new STToolStripItem("Save", SaveAction) { Enabled = ((IFileFormat)ArchiveFile).CanSave},
new STToolStripSeparator(),
new STToolStripItem("Repack", RepackAction){ Enabled = ArchiveFile.CanReplaceFiles},
new STToolStripItem("Extract All", ExtractAllAction),
new STToolStripSeparator(),
new STToolStripItem("Preview Archive", PreviewAction),
};
}
private void EnableContextMenu(ToolStripItemCollection Items, string Key, bool Enabled)
@ -294,10 +285,75 @@ namespace Switch_Toolbox.Library
Name = text;
}
}
public void FillTreeNodes() {
FillTreeNodes(this, ArchiveFile);
}
private void FillTreeNodes(TreeNode root, IArchiveFile archiveFile)
{
Nodes.Clear();
var rootText = root.Text;
var rootTextLength = rootText.Length;
var nodeFiles = archiveFile.Files;
int I = 0;
foreach (var node in nodeFiles)
{
if (!node.CanLoadFile)
continue;
string nodeString = node.FileName;
var roots = nodeString.Split(new char[] { '/' },
StringSplitOptions.RemoveEmptyEntries);
// The initial parent is the root node
var parentNode = root;
var sb = new System.Text.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 ArchiveFolderNodeWrapper(parentName, archiveFile);
if (rootIndex == roots.Length - 1)
{
ArchiveFileWrapper wrapperFile = new ArchiveFileWrapper(parentName, node, archiveFile);
wrapperFile.Name = nodeName;
parentNode.Nodes.Add(wrapperFile);
parentNode = wrapperFile;
}
else
{
folder.Name = nodeName;
parentNode.Nodes.Add(folder);
parentNode = folder;
}
}
else
{
// Node was found, set that as parent and continue
parentNode = parentNode.Nodes[index];
}
}
}
}
}
//Wrapper for folders
public class ArchiveFolderNodeWrapper : ArchiveBase
public class ArchiveFolderNodeWrapper : ArchiveBase, IContextMenuNode
{
public virtual object PropertyDisplay { get; set; }
@ -329,18 +385,20 @@ namespace Switch_Toolbox.Library
PropertyDisplay = new GenericFolderProperties();
((GenericFolderProperties)PropertyDisplay).Name = Text;
ReloadMenus(archiveFile);
// ReloadMenus(archiveFile);
}
private void ReloadMenus(IArchiveFile archiveFile)
public ToolStripItem[] GetContextMenuItems()
{
ContextMenuStrip = new STContextMenuStrip();
ContextMenuStrip.Items.Add(new STToolStripItem("Rename", RenameAction) { Enabled = archiveFile.CanRenameFiles });
ContextMenuStrip.Items.Add(new STToolStripItem("Extract Folder", ExtractAction));
ContextMenuStrip.Items.Add(new STToolStripItem("Replace Folder", ReplaceAction) { Enabled = archiveFile.CanReplaceFiles });
ContextMenuStrip.Items.Add(new STToolStripItem("Delete Folder", DeleteAction) { Enabled = archiveFile.CanDeleteFiles });
ContextMenuStrip.Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStripItem("Add File", AddFileAction) { Enabled = archiveFile.CanAddFiles });
return new ToolStripItem[]
{
new STToolStripItem("Rename", RenameAction) { Enabled = ArchiveFile.CanRenameFiles },
new STToolStripItem("Extract Folder", ExtractAction),
new STToolStripItem("Replace Folder", ReplaceAction) { Enabled = ArchiveFile.CanReplaceFiles },
new STToolStripItem("Delete Folder", DeleteAction) { Enabled = ArchiveFile.CanDeleteFiles },
new STToolStripSeparator(),
new STToolStripItem("Add File", AddFileAction) { Enabled = ArchiveFile.CanAddFiles },
};
}
private void AddFileAction(object sender, EventArgs args)
@ -406,14 +464,14 @@ namespace Switch_Toolbox.Library
}
//Wrapper for files
public class ArchiveFileWrapper : ArchiveBase
public class ArchiveFileWrapper : ArchiveBase, IContextMenuNode
{
public virtual ArchiveFileInfo ArchiveFileInfo { get; set; }
public ArchiveFileWrapper(string text, ArchiveFileInfo archiveFileInfo, IArchiveFile archiveFile) : base(archiveFile)
{
Text = text;
ReloadMenus(archiveFile);
// ReloadMenus(archiveFile);
ArchiveFileInfo = archiveFileInfo;
@ -496,17 +554,19 @@ namespace Switch_Toolbox.Library
return new ArchiveFileWrapper(Path.GetFileName(FilePath), ArchiveFileInfo, archiveFile);
}
private void ReloadMenus(IArchiveFile archiveFile)
public ToolStripItem[] GetContextMenuItems()
{
ContextMenuStrip = new STContextMenuStrip();
ContextMenuStrip.Items.Add(new STToolStripItem("Rename", RenameAction) { Enabled = archiveFile.CanRenameFiles });
ContextMenuStrip.Items.Add(new STToolStripItem("Export Raw Data", ExtractAction));
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Export Raw Data to File Location", null, ExportToFileLocAction, Keys.Control | Keys.F));
ContextMenuStrip.Items.Add(new STToolStripItem("Replace Raw Data", ReplaceAction) { Enabled = archiveFile.CanReplaceFiles });
ContextMenuStrip.Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStipMenuItem("Open With Text Editor", null, OpenTextEditorAction, Keys.Control | Keys.T));
ContextMenuStrip.Items.Add(new STToolStripSeparator());
ContextMenuStrip.Items.Add(new STToolStripItem("Delete", DeleteAction) { Enabled = archiveFile.CanDeleteFiles });
return new ToolStripItem[]
{
new STToolStripItem("Rename", RenameAction) { Enabled = ArchiveFile.CanRenameFiles },
new STToolStripItem("Export Raw Data", ExtractAction),
new STToolStipMenuItem("Export Raw Data to File Location", null, ExportToFileLocAction, Keys.Control | Keys.F),
new STToolStripItem("Replace Raw Data", ReplaceAction) { Enabled = ArchiveFile.CanReplaceFiles },
new STToolStripSeparator(),
new STToolStipMenuItem("Open With Text Editor", null, OpenTextEditorAction, Keys.Control | Keys.T),
new STToolStripSeparator(),
new STToolStripItem("Delete", DeleteAction) { Enabled = ArchiveFile.CanDeleteFiles },
};
}
private void OpenTextEditorAction(object sender, EventArgs args)
@ -561,8 +621,14 @@ namespace Switch_Toolbox.Library
{
OpenFormDialog(file);
}
else if (file != null)
else if (file is TreeNode)
ReplaceNode(this.Parent, this, (TreeNode)file);
else if (file is IArchiveFile)
{
var FileRoot = new ArchiveRootNodeWrapper(file.FileName, (IArchiveFile)file);
FileRoot.FillTreeNodes();
ReplaceNode(this.Parent, this, FileRoot);
}
}
private void OpenFormDialog(IFileFormat fileFormat)

View file

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Switch_Toolbox.Library
{
//Gets the context menus from a tree node when right clicked
//This can be used to save memory as storing lists of menus for every node takes up too much memory
public interface IContextMenuNode
{
ToolStripItem[] GetContextMenuItems();
}
}

View file

@ -603,6 +603,7 @@
</Compile>
<Compile Include="Helpers\TextureHelper.cs" />
<Compile Include="Helpers\TreeHelper.cs" />
<Compile Include="Interfaces\IContextMenuNode.cs" />
<Compile Include="Interfaces\IConvertableTextFormat.cs" />
<Compile Include="Interfaces\IEditor.cs" />
<Compile Include="Interfaces\IFIleEditor.cs" />

View file

@ -119,7 +119,7 @@ uniform int UseCavityMap;
uniform int UseMetalnessMap;
uniform int UseRoughnessMap;
int isTransparent;
uniform int isTransparent;
// Diffuse Channel Toggles
uniform int RedChannel;

View file

@ -94,7 +94,9 @@ vec3 ReflectionPass(vec3 N, vec3 I, vec4 diffuseMap, vec3 Specular, float aoBlen
vec3 viewNormal = mat3(sphereMatrix) * normalize(N.xyz);
vec3 sphereMapColor = SphereMapColor(vert.viewNormal, SphereMap);
reflectionPass += sphereMapColor * HasSphereMap;
if (HasSphereMap == 1)
reflectionPass += sphereMapColor;
reflectionPass = max(reflectionPass, vec3(0));
return reflectionPass;