2019-06-01 01:08:55 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Switch_Toolbox.Library;
|
|
|
|
|
using Switch_Toolbox.Library.IO;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using Switch_Toolbox.Library.Forms;
|
|
|
|
|
|
|
|
|
|
namespace FirstPlugin
|
|
|
|
|
{
|
|
|
|
|
public class NUSHDB : TreeNodeFile, IFileFormat
|
|
|
|
|
{
|
|
|
|
|
public FileType FileType { get; set; } = FileType.Layout;
|
|
|
|
|
|
|
|
|
|
public bool CanSave { get; set; }
|
|
|
|
|
public string[] Description { get; set; } = new string[] { "Namco Shader Data Binary" };
|
|
|
|
|
public string[] Extension { get; set; } = new string[] { "*.nushdb" };
|
|
|
|
|
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, "HBSS") && reader.CheckSignature(4, "RDHS", 16) ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Type[] Types
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
List<Type> types = new List<Type>();
|
|
|
|
|
return types.ToArray();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Load(System.IO.Stream stream)
|
|
|
|
|
{
|
|
|
|
|
Text = FileName;
|
|
|
|
|
|
|
|
|
|
using (var reader = new FileReader(stream))
|
|
|
|
|
{
|
|
|
|
|
reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian;
|
|
|
|
|
|
|
|
|
|
//Skip the HBSS header
|
|
|
|
|
reader.Seek(0x10, System.IO.SeekOrigin.Begin);
|
|
|
|
|
reader.ReadSignature(4, "RDHS");
|
|
|
|
|
ushort VersionMajor = reader.ReadUInt16();
|
|
|
|
|
ushort VersionMinor = reader.ReadUInt16();
|
|
|
|
|
ulong Unknown = reader.ReadUInt64(); //Usually 16
|
|
|
|
|
ulong ProgramCount = reader.ReadUInt64();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < (int)ProgramCount; i++)
|
|
|
|
|
{
|
|
|
|
|
ShaderProgram program = new ShaderProgram();
|
|
|
|
|
program.Text = reader.LoadString(true, typeof(ulong));
|
2019-06-01 01:14:25 +02:00
|
|
|
|
uint Type = reader.ReadUInt32();
|
2019-06-01 01:08:55 +02:00
|
|
|
|
uint unk2 = reader.ReadUInt32(); //Usually 2
|
|
|
|
|
long BinaryOffset = reader.ReadOffset(true, typeof(ulong));
|
|
|
|
|
ulong BinarySize = reader.ReadUInt64();
|
|
|
|
|
ulong BinarySize2 = reader.ReadUInt64();
|
|
|
|
|
ulong padding = reader.ReadUInt64();
|
|
|
|
|
ulong padding2 = reader.ReadUInt64();
|
|
|
|
|
|
2019-06-01 01:14:25 +02:00
|
|
|
|
if (Type == 0)
|
|
|
|
|
program.ShaderType = NSWShaderDecompile.NswShaderType.Vertex;
|
|
|
|
|
if (Type == 2)
|
|
|
|
|
program.ShaderType = NSWShaderDecompile.NswShaderType.Fragment;
|
|
|
|
|
|
2019-06-01 01:08:55 +02:00
|
|
|
|
using (reader.TemporarySeek(BinaryOffset, System.IO.SeekOrigin.Begin))
|
|
|
|
|
{
|
|
|
|
|
program.Data = reader.ReadBytes((int)BinarySize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Nodes.Add(program);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void Unload()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
public byte[] Save()
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class ShaderProgram : TreeNodeCustom
|
|
|
|
|
{
|
2019-06-01 02:20:07 +02:00
|
|
|
|
public ShaderProgram()
|
|
|
|
|
{
|
|
|
|
|
ContextMenuStrip = new STContextMenuStrip();
|
|
|
|
|
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export Data", null, Export, Keys.Control | Keys.E));
|
|
|
|
|
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export Raw Binary", null, ExportBinary, Keys.Control | Keys.B));
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-01 01:14:25 +02:00
|
|
|
|
public NSWShaderDecompile.NswShaderType ShaderType { get; set; }
|
2019-06-01 01:08:55 +02:00
|
|
|
|
|
|
|
|
|
public byte[] Data { get; set; }
|
|
|
|
|
|
2019-06-01 02:20:07 +02:00
|
|
|
|
public byte[] RawBinaryData { get; set; }
|
|
|
|
|
|
2019-06-01 01:08:55 +02:00
|
|
|
|
public string Code { get; set; }
|
|
|
|
|
|
2019-06-01 02:20:07 +02:00
|
|
|
|
public void ParseBinary()
|
|
|
|
|
{
|
|
|
|
|
//Get the raw binary data
|
|
|
|
|
using (var reader = new FileReader(Data))
|
|
|
|
|
{
|
|
|
|
|
reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian;
|
|
|
|
|
|
|
|
|
|
reader.Seek(68, System.IO.SeekOrigin.Begin);
|
|
|
|
|
uint BinarySize = reader.ReadUInt32();
|
|
|
|
|
uint BinaryOffset = reader.ReadUInt32();
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Binary Size " + BinarySize);
|
|
|
|
|
Console.WriteLine("Binar yOffset " + BinaryOffset);
|
|
|
|
|
|
|
|
|
|
reader.Seek((int)BinaryOffset, System.IO.SeekOrigin.Begin);
|
|
|
|
|
RawBinaryData = reader.ReadBytes((int)BinarySize);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-01 01:08:55 +02:00
|
|
|
|
public bool TryDecompileBinary()
|
|
|
|
|
{
|
2019-06-01 02:20:07 +02:00
|
|
|
|
ParseBinary();
|
|
|
|
|
Code = NSWShaderDecompile.DecompileShader(ShaderType, RawBinaryData);
|
2019-06-01 01:08:55 +02:00
|
|
|
|
|
|
|
|
|
if (Code.Length > 0) return true;
|
|
|
|
|
else return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-01 02:20:07 +02:00
|
|
|
|
private void Export(object sender, EventArgs args)
|
|
|
|
|
{
|
|
|
|
|
SaveFileDialog sfd = new SaveFileDialog();
|
|
|
|
|
sfd.DefaultExt = "bin";
|
|
|
|
|
sfd.FileName = Text;
|
|
|
|
|
|
|
|
|
|
sfd.Filter = "Supported Formats|*.bin;";
|
|
|
|
|
|
|
|
|
|
if (sfd.ShowDialog() == DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
System.IO.File.WriteAllBytes(sfd.FileName, Data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ExportBinary(object sender, EventArgs args)
|
|
|
|
|
{
|
|
|
|
|
SaveFileDialog sfd = new SaveFileDialog();
|
|
|
|
|
sfd.DefaultExt = "bin";
|
|
|
|
|
sfd.FileName = Text;
|
|
|
|
|
|
|
|
|
|
sfd.Filter = "Supported Formats|*.bin;";
|
|
|
|
|
|
|
|
|
|
if (sfd.ShowDialog() == DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
System.IO.File.WriteAllBytes(sfd.FileName, RawBinaryData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-01 01:08:55 +02:00
|
|
|
|
public override void OnClick(TreeView treeview)
|
|
|
|
|
{
|
|
|
|
|
bool IsSuccess = TryDecompileBinary();
|
|
|
|
|
|
|
|
|
|
TextEditor editor = (TextEditor)LibraryGUI.Instance.GetActiveContent(typeof(TextEditor));
|
|
|
|
|
if (editor == null)
|
|
|
|
|
{
|
|
|
|
|
editor = new TextEditor();
|
|
|
|
|
editor.Dock = DockStyle.Fill;
|
|
|
|
|
LibraryGUI.Instance.LoadEditor(editor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
editor.Text = Text;
|
|
|
|
|
editor.FillEditor(string.Join("", Code));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|