1
0
mirror of synced 2024-09-24 03:28:21 +02:00

A few additions

Add NLG hash calculator.
Add option to swap bone transform from csv max script.
This commit is contained in:
KillzXGaming 2019-11-03 10:38:17 -05:00
parent 973afc97ef
commit 14982b80be
10 changed files with 581 additions and 47 deletions

View File

@ -300,6 +300,81 @@ namespace Bfres.Structs
BfresSwitch.ReadSkeleton(this, Skeleton, fskl);
}
}
if (extension == ".csv")
{
using (var reader = new System.IO.StringReader(System.IO.File.ReadAllText(ofd.FileName)))
{
string value = reader.ReadLine();
if (value != "Bones Geometry")
return;
float X = 0;
float Y = 0;
float Z = 0;
float W = 0;
while (true)
{
string line = reader.ReadLine();
if (line != null)
{
foreach (BfresBone bone in fskl.bones)
{
if (bone.Text == line)
{
string name = line;
string scaleStr = reader.ReadLine();
string rotationStr = reader.ReadLine();
string translationStr = reader.ReadLine();
string[] valuesS = scaleStr.Replace("\n", "").Replace("\r", "").Split(',');
string[] valuesR = rotationStr.Replace("\n", "").Replace("\r", "").Split(',');
string[] valuesT = translationStr.Replace("\n", "").Replace("\r", "").Split(',');
Syroot.Maths.Vector3F translate;
Syroot.Maths.Vector3F scale;
Syroot.Maths.Vector4F rotate;
float.TryParse(valuesT[0], out X);
float.TryParse(valuesT[1], out Y);
float.TryParse(valuesT[2], out Z);
translate = new Syroot.Maths.Vector3F(X,Y,Z);
float.TryParse(valuesR[0], out X);
float.TryParse(valuesR[1], out Y);
float.TryParse(valuesR[2], out Z);
float.TryParse(valuesR[3], out W);
rotate = new Syroot.Maths.Vector4F(X, Y, Z,W);
float.TryParse(valuesS[0], out X);
float.TryParse(valuesS[1], out Y);
float.TryParse(valuesS[2], out Z);
scale = new Syroot.Maths.Vector3F(X, Y, Z);
if (bone.BoneU != null) {
bone.BoneU.Position = translate;
bone.BoneU.Scale = scale;
bone.BoneU.Rotation = rotate;
}
else {
bone.Bone.Position = translate;
bone.Bone.Scale = scale;
bone.Bone.Rotation = rotate;
}
}
}
}
else
break;
}
if (SkeletonU != null)
BfresWiiU.ReadSkeleton(this, SkeletonU, fskl);
else
BfresSwitch.ReadSkeleton(this, Skeleton, fskl);
LibraryGUI.UpdateViewport();
}
}
}
}
@ -371,6 +446,11 @@ namespace Bfres.Structs
}
}
private void SwapFromCsv()
{
}
public ResFile GetResFile()
{
return ((FMDL)Parent).GetResFile();

View File

@ -63,7 +63,7 @@ namespace FirstPlugin.LuigisMansion3
}
}
public static bool DebugMode = false;
public static bool DebugMode = true;
public List<ChunkDataEntry> chunkEntries = new List<ChunkDataEntry>();
@ -82,21 +82,24 @@ namespace FirstPlugin.LuigisMansion3
public static Dictionary<uint, string> HashNames = new Dictionary<uint, string>();
public List<string> StringList = new List<string>();
private void LoadHashes()
{
foreach (string hashStr in Properties.Resources.LM3_Hashes.Split('\n'))
{
//This hash txt includes a hash and then the string path after seperated by a comma
//The game does not store actual strings in the exefs so it's impossible to get the original names
//Instead I use a text file with user generated names based on the texture for easier searching
string[] hashes = hashStr.Split(',');
if (hashes.Length != 2) continue;
uint hash = 0;
uint.TryParse(hashes[0], System.Globalization.NumberStyles.HexNumber, null, out hash);
uint hash = (uint)NLG_Common.StringToHash(hashStr);
if (!HashNames.ContainsKey(hash))
HashNames.Add(hash, hashes[1]);
HashNames.Add(hash, hashStr);
string[] hashPaths = hashStr.Split('/');
for (int i = 0; i < hashPaths?.Length; i++)
{
hash = (uint)NLG_Common.StringToHash(hashPaths[i]);
if (!HashNames.ContainsKey(hash))
HashNames.Add(hash, hashStr);
}
}
}
@ -205,7 +208,7 @@ namespace FirstPlugin.LuigisMansion3
{
list2.Nodes.Add($"ChunkType 0x{chunk.ChunkType.ToString("X")} Size {chunk.ChunkSize} Offset {chunk.ChunkOffset}");
}
}
}
}
}
}
@ -234,6 +237,23 @@ namespace FirstPlugin.LuigisMansion3
//Image data block
var File065Data = fileEntries[65].GetData();
//Get a list of chunk hashes
List<uint> ModelHashes = new List<uint>();
for (int i = 0; i < ChunkTable.ChunkEntries.Count; i++)
{
if (ChunkTable.ChunkEntries[i].ChunkType == DataType.Model)
{
using (var chunkReader = new FileReader(File052Data, true))
{
chunkReader.SeekBegin(ChunkTable.ChunkEntries[i].ChunkOffset);
uint magic = chunkReader.ReadUInt32();
uint hash = chunkReader.ReadUInt32();
ModelHashes.Add(hash);
}
}
}
//Set an instance of our current data
//Chunks are in order, so you build off of when an instance gets loaded
LM3_Model currentModel = new LM3_Model(this);
@ -298,6 +318,13 @@ namespace FirstPlugin.LuigisMansion3
currentModel.ModelInfo = new LM3_ModelInfo();
currentModel.Text = $"Model {modelIndex}";
currentModel.ModelInfo.Data = chunkEntry.FileData.ToBytes();
if (ModelHashes.Count > modelIndex)
{
currentModel.Text = $"Model {modelIndex} {ModelHashes[(int)modelIndex].ToString("x")}";
if (HashNames.ContainsKey(ModelHashes[(int)modelIndex]))
currentModel.Text = HashNames[ModelHashes[(int)modelIndex]];
}
modelIndex++;
break;
case SubDataType.MeshBuffers:
@ -360,39 +387,45 @@ namespace FirstPlugin.LuigisMansion3
chunkEntry.DataFile = File053Data;
break;
case SubDataType.BoneData:
/* if (chunk.ChunkSize > 0x40 && currentModel.Skeleton == null)
if (chunk.ChunkSize > 0x40 && currentModel.Skeleton == null)
{
chunkEntry.DataFile = File052Data;
using (var boneReader = new FileReader(chunkEntry.FileData))
{
currentModel.Skeleton = new STSkeleton();
DrawableContainer.Drawables.Add(currentModel.Skeleton);
chunkEntry.DataFile = File052Data;
using (var boneReader = new FileReader(chunkEntry.FileData))
{
currentModel.Skeleton = new STSkeleton();
DrawableContainer.Drawables.Add(currentModel.Skeleton);
uint numBones = chunk.ChunkSize / 0x40;
for (int i = 0; i < numBones; i++)
{
boneReader.SeekBegin(i * 0x40);
STBone bone = new STBone(currentModel.Skeleton);
bone.position = new float[3] { 0, 0, 0 };
bone.rotation = new float[4] { 0, 0, 0, 1 };
bone.scale = new float[3] { 0.2f, 0.2f, 0.2f };
uint numBones = chunk.ChunkSize / 0x40;
for (int i = 0; i < numBones; i++)
{
boneReader.SeekBegin(i * 0x40);
uint hash = boneReader.ReadUInt32();
boneReader.SeekBegin(48 + (i * 0x40));
var Position = new OpenTK.Vector3(boneReader.ReadSingle(), boneReader.ReadSingle(), boneReader.ReadSingle());
Position = OpenTK.Vector3.TransformPosition(Position, OpenTK.Matrix4.CreateRotationX(OpenTK.MathHelper.DegreesToRadians(90)));
bone.position[0] = Position.X;
bone.position[2] = Position.Y;
bone.position[1] = Position.Z;
STBone bone = new STBone(currentModel.Skeleton);
bone.Text = hash.ToString("x");
if (HashNames.ContainsKey(hash))
bone.Text = HashNames[hash];
bone.position = new float[3] { 0, 0, 0 };
bone.rotation = new float[4] { 0, 0, 0, 1 };
bone.scale = new float[3] { 0.2f, 0.2f, 0.2f };
bone.RotationType = STBone.BoneRotationType.Euler;
currentModel.Skeleton.bones.Add(bone);
}
boneReader.SeekBegin(48 + (i * 0x40));
var Position = new OpenTK.Vector3(boneReader.ReadSingle(), boneReader.ReadSingle(), boneReader.ReadSingle());
Position = OpenTK.Vector3.TransformPosition(Position, OpenTK.Matrix4.CreateRotationX(OpenTK.MathHelper.DegreesToRadians(90)));
bone.position[0] = Position.X;
bone.position[2] = Position.Y;
bone.position[1] = Position.Z;
currentModel.Skeleton.reset();
currentModel.Skeleton.update();
}
}*/
bone.RotationType = STBone.BoneRotationType.Euler;
currentModel.Skeleton.bones.Add(bone);
}
currentModel.Skeleton.reset();
currentModel.Skeleton.update();
}
}
break;
case (SubDataType)0x5012:
case (SubDataType)0x5013:

View File

@ -187,7 +187,7 @@ namespace FirstPlugin.LuigisMansion3
{
//Note if a pointer is not used, it will be 0xFFFFF
public uint WeightTablePointer;
public uint WeightTablePointer = uint.MaxValue;
public uint VertexBufferPointer;
public uint IndexBufferPointer;
public uint IndexBufferPointer2;
@ -214,6 +214,11 @@ namespace FirstPlugin.LuigisMansion3
using (var reader = new FileReader(DataDictionary.GetFileBufferData()))
{
TreeNode texturesList = new TreeNode("Texture Maps");
TreeNode skeletonNode = new TreeNode("Skeleton");
for (int t = 0; t < Skeleton?.bones.Count; t++) {
skeletonNode.Nodes.Add(Skeleton.bones[t]);
}
for (int t = 0; t < TextureHashes.Count; t++)
{
if (DataDictionary.Renderer.TextureList.ContainsKey(TextureHashes[t].ToString("x")))
@ -230,6 +235,9 @@ namespace FirstPlugin.LuigisMansion3
Nodes.Add(TextureHashes[t].ToString("x"));
}
if (skeletonNode.Nodes.Count > 0)
Nodes.Add(skeletonNode);
if (texturesList.Nodes.Count > 0)
Nodes.Add(texturesList);
@ -255,6 +263,7 @@ namespace FirstPlugin.LuigisMansion3
genericObj.PolygonGroups.Add(polyGroup);
uint vertexBufferPointer = VertexBufferPointers[i].VertexBufferPointer;
uint weightTablePointer = VertexBufferPointers[i].WeightTablePointer;
using (reader.TemporarySeek(BufferStart + vertexBufferPointer, System.IO.SeekOrigin.Begin))
{
@ -387,6 +396,26 @@ namespace FirstPlugin.LuigisMansion3
genericObj.TransformPosition(new Vector3(0), new Vector3(-90, 0, 0), new Vector3(1));
}
if (weightTablePointer != uint.MaxValue)
{
using (reader.TemporarySeek(BufferStart + weightTablePointer, System.IO.SeekOrigin.Begin))
{
byte maxIndex = 0;
for (int v = 0; v < genericObj.vertices.Count; v++)
{
byte[] boneIndices = reader.ReadBytes(4);
float[] boneWeights = reader.ReadSingles(4);
for (int j = 0; j < 4; j++) {
maxIndex = Math.Max(maxIndex, boneIndices[j]);
genericObj.vertices[v].boneIds.Add(boneIndices[j]);
genericObj.vertices[v].boneWeights.Add(boneWeights[j]);
}
}
Console.WriteLine("maxIndex " + maxIndex);
}
}
genericObj.RemoveDuplicateVertices();
}
@ -435,6 +464,7 @@ namespace FirstPlugin.LuigisMansion3
while (!reader.EndOfStream && reader.Position < reader.BaseStream.Length - 4)
{
uint HashIDCheck = reader.ReadUInt32();
if (Hashes.Contains(HashIDCheck))
{
if (!model.TextureHashes.Contains(HashIDCheck))
@ -445,7 +475,6 @@ namespace FirstPlugin.LuigisMansion3
reader.Position = 0;
var meshSize = reader.BaseStream.Length / model.Meshes.Count;
Console.WriteLine($"meshSize {meshSize}");
for (int i = 0; i < model.Meshes.Count; i++)
{
reader.SeekBegin(i * meshSize);

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FirstPlugin
{
public class NLG_Common
{
public static uint StringToHash(string name, bool caseSensative = false)
{
//From (Works as tested comparing hashbin strings/hashes
//https://gist.github.com/RoadrunnerWMC/f4253ef38c8f51869674a46ee73eaa9f
byte[] data = Encoding.Default.GetBytes(name);
int h = -1;
for (int i = 0; i < data.Length; i++)
{
int c = (int)data[i];
if (caseSensative && ((c - 65) & 0xFFFFFFFF) <= 0x19)
c |= 0x20;
h = (int)((h * 33 + c) & 0xFFFFFFFF);
}
return (uint)h;
}
}
}

149
Toolbox/GUI/HashCalculatorForm.Designer.cs generated Normal file
View File

@ -0,0 +1,149 @@
namespace Toolbox
{
partial class HashCalculatorForm
{
/// <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.stringTB = new Toolbox.Library.Forms.STTextBox();
this.resultTB = new Toolbox.Library.Forms.STTextBox();
this.hashTypeCB = new Toolbox.Library.Forms.STComboBox();
this.stLabel1 = new Toolbox.Library.Forms.STLabel();
this.stLabel2 = new Toolbox.Library.Forms.STLabel();
this.stLabel3 = new Toolbox.Library.Forms.STLabel();
this.chkUseHex = new Toolbox.Library.Forms.STCheckBox();
this.contentContainer.SuspendLayout();
this.SuspendLayout();
//
// contentContainer
//
this.contentContainer.Controls.Add(this.chkUseHex);
this.contentContainer.Controls.Add(this.stLabel3);
this.contentContainer.Controls.Add(this.stLabel2);
this.contentContainer.Controls.Add(this.stLabel1);
this.contentContainer.Controls.Add(this.hashTypeCB);
this.contentContainer.Controls.Add(this.resultTB);
this.contentContainer.Controls.Add(this.stringTB);
this.contentContainer.Size = new System.Drawing.Size(469, 120);
this.contentContainer.Controls.SetChildIndex(this.stringTB, 0);
this.contentContainer.Controls.SetChildIndex(this.resultTB, 0);
this.contentContainer.Controls.SetChildIndex(this.hashTypeCB, 0);
this.contentContainer.Controls.SetChildIndex(this.stLabel1, 0);
this.contentContainer.Controls.SetChildIndex(this.stLabel2, 0);
this.contentContainer.Controls.SetChildIndex(this.stLabel3, 0);
this.contentContainer.Controls.SetChildIndex(this.chkUseHex, 0);
//
// stringTB
//
this.stringTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.stringTB.Location = new System.Drawing.Point(88, 76);
this.stringTB.Name = "stringTB";
this.stringTB.Size = new System.Drawing.Size(121, 20);
this.stringTB.TabIndex = 11;
this.stringTB.TextChanged += new System.EventHandler(this.stTextBox1_TextChanged);
//
// resultTB
//
this.resultTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.resultTB.Location = new System.Drawing.Point(299, 76);
this.resultTB.Name = "resultTB";
this.resultTB.Size = new System.Drawing.Size(160, 20);
this.resultTB.TabIndex = 12;
//
// hashTypeCB
//
this.hashTypeCB.BorderColor = System.Drawing.Color.Empty;
this.hashTypeCB.BorderStyle = System.Windows.Forms.ButtonBorderStyle.Solid;
this.hashTypeCB.ButtonColor = System.Drawing.Color.Empty;
this.hashTypeCB.FormattingEnabled = true;
this.hashTypeCB.IsReadOnly = false;
this.hashTypeCB.Location = new System.Drawing.Point(88, 45);
this.hashTypeCB.Name = "hashTypeCB";
this.hashTypeCB.Size = new System.Drawing.Size(121, 21);
this.hashTypeCB.TabIndex = 13;
//
// stLabel1
//
this.stLabel1.AutoSize = true;
this.stLabel1.Location = new System.Drawing.Point(20, 48);
this.stLabel1.Name = "stLabel1";
this.stLabel1.Size = new System.Drawing.Size(62, 13);
this.stLabel1.TabIndex = 14;
this.stLabel1.Text = "Hash Type:";
//
// stLabel2
//
this.stLabel2.AutoSize = true;
this.stLabel2.Location = new System.Drawing.Point(20, 78);
this.stLabel2.Name = "stLabel2";
this.stLabel2.Size = new System.Drawing.Size(37, 13);
this.stLabel2.TabIndex = 15;
this.stLabel2.Text = "String:";
//
// stLabel3
//
this.stLabel3.AutoSize = true;
this.stLabel3.Location = new System.Drawing.Point(225, 78);
this.stLabel3.Name = "stLabel3";
this.stLabel3.Size = new System.Drawing.Size(68, 13);
this.stLabel3.TabIndex = 16;
this.stLabel3.Text = "Hash Result:";
//
// chkUseHex
//
this.chkUseHex.AutoSize = true;
this.chkUseHex.Location = new System.Drawing.Point(299, 47);
this.chkUseHex.Name = "chkUseHex";
this.chkUseHex.Size = new System.Drawing.Size(86, 17);
this.chkUseHex.TabIndex = 17;
this.chkUseHex.Text = "Preview Hex";
this.chkUseHex.UseVisualStyleBackColor = true;
this.chkUseHex.CheckedChanged += new System.EventHandler(this.chkUseHex_CheckedChanged);
//
// HashCalculatorForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(475, 125);
this.Name = "HashCalculatorForm";
this.Text = "Hash Calculator";
this.contentContainer.ResumeLayout(false);
this.contentContainer.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private Library.Forms.STTextBox stringTB;
private Library.Forms.STComboBox hashTypeCB;
private Library.Forms.STTextBox resultTB;
private Library.Forms.STLabel stLabel3;
private Library.Forms.STLabel stLabel2;
private Library.Forms.STLabel stLabel1;
private Library.Forms.STCheckBox chkUseHex;
}
}

View File

@ -0,0 +1,66 @@
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 Toolbox.Library.Forms;
namespace Toolbox
{
public partial class HashCalculatorForm : STForm
{
private bool IsHex => chkUseHex.Checked;
public HashCalculatorForm()
{
InitializeComponent();
hashTypeCB.Items.Add("NLG_Hash");
hashTypeCB.SelectedIndex = 0;
}
private void stTextBox1_TextChanged(object sender, EventArgs e) {
UpdateHash();
}
private void UpdateHash()
{
uint Hash = 0;
if (hashTypeCB.GetSelectedText() == "NLG_Hash")
Hash = StringToHash(stringTB.Text);
if (IsHex)
resultTB.Text = Hash.ToString("X");
else
resultTB.Text = Hash.ToString();
}
private void chkUseHex_CheckedChanged(object sender, EventArgs e) {
UpdateHash();
}
public static uint StringToHash(string name, bool caseSensative = false)
{
//From (Works as tested comparing hashbin strings/hashes
//https://gist.github.com/RoadrunnerWMC/f4253ef38c8f51869674a46ee73eaa9f
byte[] data = Encoding.Default.GetBytes(name);
int h = -1;
for (int i = 0; i < data.Length; i++)
{
int c = (int)data[i];
if (caseSensative && ((c - 65) & 0xFFFFFFFF) <= 0x19)
c |= 0x20;
h = (int)((h * 33 + c) & 0xFFFFFFFF);
}
return (uint)h;
}
}
}

View File

@ -0,0 +1,120 @@
<?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

@ -43,6 +43,7 @@
this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.compressionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.batchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.experimentalToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.windowsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.cascadeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -71,7 +72,7 @@
this.stToolStrip1 = new Toolbox.Library.Forms.STToolStrip();
this.saveToolStripButton = new System.Windows.Forms.ToolStripButton();
this.updateToolstrip = new System.Windows.Forms.ToolStripButton();
this.batchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.hashCalculatorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip1.SuspendLayout();
this.stPanel1.SuspendLayout();
this.tabControlContextMenuStrip.SuspendLayout();
@ -86,6 +87,7 @@
//
this.menuStrip1.AllowMerge = false;
this.menuStrip1.Dock = System.Windows.Forms.DockStyle.Fill;
this.menuStrip1.HighlightSelectedTab = false;
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.editToolStripMenuItem,
@ -182,7 +184,8 @@
//
this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.compressionToolStripMenuItem,
this.batchToolStripMenuItem});
this.batchToolStripMenuItem,
this.hashCalculatorToolStripMenuItem});
this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
this.toolsToolStripMenuItem.Size = new System.Drawing.Size(47, 21);
this.toolsToolStripMenuItem.Text = "Tools";
@ -193,6 +196,13 @@
this.compressionToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.compressionToolStripMenuItem.Text = "Compression";
//
// batchToolStripMenuItem
//
this.batchToolStripMenuItem.Name = "batchToolStripMenuItem";
this.batchToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.batchToolStripMenuItem.Text = "Batch Set File Table";
this.batchToolStripMenuItem.Click += new System.EventHandler(this.batchToolStripMenuItem_Click);
//
// experimentalToolStripMenuItem
//
this.experimentalToolStripMenuItem.Name = "experimentalToolStripMenuItem";
@ -421,6 +431,7 @@
// stToolStrip1
//
this.stToolStrip1.Dock = System.Windows.Forms.DockStyle.Fill;
this.stToolStrip1.HighlightSelectedTab = false;
this.stToolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.saveToolStripButton,
this.updateToolstrip});
@ -454,12 +465,12 @@
this.updateToolstrip.ToolTipText = "Update Tool";
this.updateToolstrip.Click += new System.EventHandler(this.updateToolstrip_Click);
//
// batchToolStripMenuItem
// hashCalculatorToolStripMenuItem
//
this.batchToolStripMenuItem.Name = "batchToolStripMenuItem";
this.batchToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.batchToolStripMenuItem.Text = "Batch Set File Table";
this.batchToolStripMenuItem.Click += new System.EventHandler(this.batchToolStripMenuItem_Click);
this.hashCalculatorToolStripMenuItem.Name = "hashCalculatorToolStripMenuItem";
this.hashCalculatorToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.hashCalculatorToolStripMenuItem.Text = "Hash Calculator";
this.hashCalculatorToolStripMenuItem.Click += new System.EventHandler(this.hashCalculatorToolStripMenuItem_Click);
//
// MainForm
//
@ -540,5 +551,6 @@
private System.Windows.Forms.ToolStripMenuItem tutorialToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem openFolderToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem batchToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem hashCalculatorToolStripMenuItem;
}
}

View File

@ -1337,5 +1337,11 @@ namespace Toolbox
STFileSaver.BatchFileTable(folderDlg.SelectedPath);
}
}
private void hashCalculatorToolStripMenuItem_Click(object sender, EventArgs e)
{
HashCalculatorForm form = new HashCalculatorForm();
form.Show(this);
}
}
}

View File

@ -110,6 +110,12 @@
<Compile Include="GUI\GithubUpdateDialog.Designer.cs">
<DependentUpon>GithubUpdateDialog.cs</DependentUpon>
</Compile>
<Compile Include="GUI\HashCalculatorForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="GUI\HashCalculatorForm.Designer.cs">
<DependentUpon>HashCalculatorForm.cs</DependentUpon>
</Compile>
<Compile Include="GUI\NodeWrappers.cs" />
<Compile Include="GUI\PluginManager.cs">
<SubType>Form</SubType>
@ -152,6 +158,9 @@
<EmbeddedResource Include="GUI\GithubUpdateDialog.resx">
<DependentUpon>GithubUpdateDialog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="GUI\HashCalculatorForm.resx">
<DependentUpon>HashCalculatorForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="GUI\PluginManager.resx">
<DependentUpon>PluginManager.cs</DependentUpon>
</EmbeddedResource>