Add latest SHARCFB code for switch

This commit is contained in:
KillzXGaming 2023-06-07 19:00:44 -04:00
parent 3d943e7bcb
commit 916aeab313
4 changed files with 312 additions and 8 deletions

View file

@ -78,6 +78,13 @@ namespace FirstPlugin
if (header.sharcNX != null)
{
foreach (var item in header.sharcNX.header.Variations)
{
if (item.Type == SHARCFBNX.ShaderVariation.ShaderType.Vertex)
Nodes[0].Nodes[0].Nodes.Add(item);
else
Nodes[0].Nodes[1].Nodes.Add(item);
}
foreach (var item in header.sharcNX.header.ShaderPrograms)
{
Nodes[1].Nodes.Add(item);
@ -128,7 +135,7 @@ namespace FirstPlugin
uint unk = reader.ReadUInt32();
uint NameLength = reader.ReadUInt32();
if (NameLength == 4096)
if (NameLength == 4096 || NameLength == 8192)
{
IsNX = true;
sharcNX = new SHARCFBNX();

View file

@ -8,6 +8,8 @@ using Toolbox.Library;
using Toolbox.Library.Forms;
using System.Windows.Forms;
using FirstPlugin.Forms;
using static FirstPlugin.GMX.Header;
using static FirstPlugin.RARC_Parser;
namespace FirstPlugin
{
@ -18,6 +20,7 @@ namespace FirstPlugin
public class Header
{
public List<ShaderProgram> ShaderPrograms = new List<ShaderProgram>();
public List<ShaderVariation> Variations = new List<ShaderVariation>();
public void Read(FileReader reader)
{
@ -50,9 +53,13 @@ namespace FirstPlugin
var Position = reader.Position; //All offsets will be relative to this
uint ShaderProgramArrayOffset = reader.ReadUInt32();
uint VariationCount = reader.ReadUInt32();
for (int i = 0; i < VariationCount; i++)
{
ShaderVariation var = new ShaderVariation();
var.Read(reader);
Variations.Add(var);
}
reader.Seek(Position + ShaderProgramArrayOffset, System.IO.SeekOrigin.Begin);
uint ProgramArraySize = reader.ReadUInt32();
@ -60,19 +67,190 @@ namespace FirstPlugin
for (int i = 0; i < ProgramCount; i++)
{
ShaderProgram program = new ShaderProgram();
ShaderProgram program = new ShaderProgram(this);
program.Read(reader);
ShaderPrograms.Add(program);
}
}
}
public static string ReadString(FileReader reader)
{
var offset = reader.ReadUInt64();
using (reader.TemporarySeek(336 + (uint)offset, System.IO.SeekOrigin.Begin))
{
return reader.ReadZeroTerminatedString();
}
}
public class ShaderVariation : TreeNodeCustom
{
public ulong BinaryDataOffset;
public byte[] ShaderA;
public ShaderType Type;
public List<Symbol> Attributes = new List<Symbol>();
public List<Symbol> Samplers = new List<Symbol>();
public List<Symbol> Buffers = new List<Symbol>();
public List<SymbolUniform> Uniforms = new List<SymbolUniform>();
public List<SymbolUniformBlock> UniformBlocks = new List<SymbolUniformBlock>();
public override void OnClick(TreeView treeview)
{
ShaderEditor editor = (ShaderEditor)LibraryGUI.GetActiveContent(typeof(ShaderEditor));
if (editor == null)
{
editor = new ShaderEditor();
LibraryGUI.LoadEditor(editor);
}
editor.Text = Text;
editor.Dock = DockStyle.Fill;
editor.FillEditor(this);
}
public void Read(FileReader reader)
{
var pos = reader.Position;
uint SectionSize = reader.ReadUInt32();
Type = (ShaderType)reader.ReadUInt32();
reader.ReadUInt32(); //0
uint SectionSize2 = reader.ReadUInt32(); //next section size
uint p = (uint)reader.Position;
BinaryDataOffset = reader.ReadUInt64();
uint ShaderASize = reader.ReadUInt32();
uint ShaderAOffset = reader.ReadUInt32();
reader.ReadUInt32(); //0
uint numUniformBlocks = reader.ReadUInt32();
var uniformBlockOffset = reader.ReadUInt64();
uint numBuffers = 0;
ulong bufferOffset = 0;
//A dumb hack as version number isn't changed
bool isNewVersion = ShaderAOffset == 96 || uniformBlockOffset == 92;
if (isNewVersion)
{
numBuffers = reader.ReadUInt32();
bufferOffset = reader.ReadUInt64();
}
uint numAttributes = reader.ReadUInt32();
var attributeOffset = reader.ReadUInt64();
uint numUniforms = reader.ReadUInt32();
var uniformOffset = reader.ReadUInt64();
uint numSamplers = reader.ReadUInt32();
var samplerOffset = reader.ReadUInt64();
reader.SeekBegin(p + uniformBlockOffset);
for (int i = 0; i < numUniformBlocks; i++)
{
UniformBlocks.Add(new SymbolUniformBlock()
{
Name = ReadString(reader),
Location = reader.ReadInt32(),
Size = reader.ReadUInt32(),
});
}
reader.SeekBegin(p + attributeOffset);
for (int i = 0; i < numAttributes; i++)
{
Attributes.Add(new Symbol()
{
Name = ReadString(reader),
Location = reader.ReadInt32(),
});
}
reader.SeekBegin(p + bufferOffset);
for (int i = 0; i < numBuffers; i++)
{
Buffers.Add(new Symbol()
{
Name = ReadString(reader),
Location = reader.ReadInt32(),
});
}
reader.SeekBegin(p + uniformOffset);
for (int i = 0; i < numUniforms; i++)
{
Uniforms.Add(new SymbolUniform()
{
Name = ReadString(reader),
Offset = reader.ReadUInt32(),
});
}
reader.SeekBegin(p + samplerOffset);
for (int i = 0; i < numSamplers; i++)
{
Samplers.Add(new Symbol()
{
Name = ReadString(reader),
Location = reader.ReadInt32(),
});
}
if (ShaderAOffset < SectionSize)
{
reader.SeekBegin(p + ShaderAOffset);
ShaderA = reader.ReadBytes((int)ShaderASize);
}
reader.SeekBegin(pos + SectionSize);
}
public enum ShaderType
{
Vertex,
Pixel,
}
}
public class Symbol
{
public string Name;
public int Location;
}
public class SymbolUniform
{
public string Name;
public uint Offset;
}
public class SymbolUniformBlock
{
public string Name;
public int Location;
public uint Size;
}
public class ShaderProgram : TreeNodeCustom
{
public VariationMacroData variationMacroData;
public VariationSymbolData variationSymbolData;
public ShaderSymbolData UniformVariables;
public int BaseIndex;
private Header Header;
public ShaderProgram(Header header)
{
Header = header;
}
public override void OnClick(TreeView treeview)
{
ShaderEditor editor = (ShaderEditor)LibraryGUI.GetActiveContent(typeof(ShaderEditor));
@ -93,8 +271,8 @@ namespace FirstPlugin
uint SectionSize = reader.ReadUInt32();
uint NameLength = reader.ReadUInt32();
uint ShaderType = reader.ReadUInt32();
uint index = reader.ReadUInt32();
uint sectionCount = reader.ReadUInt32(); //3
BaseIndex = reader.ReadInt32();
Text = reader.ReadString((int)NameLength);
@ -102,12 +280,49 @@ namespace FirstPlugin
variationSymbolData = new VariationSymbolData();
UniformVariables = new ShaderSymbolData();
variationMacroData.Read(reader);
variationSymbolData.Read(reader);
variationMacroData.Read(reader);
UniformVariables.Read(reader);
reader.Seek(SectionSize + pos, System.IO.SeekOrigin.Begin);
}
public ShaderVariation GetDefaultVertexVariation()
{
Dictionary<string, string> settings = new Dictionary<string, string>();
foreach (var macro in variationSymbolData.symbols)
{
settings.Add(macro.Name, macro.Values.FirstOrDefault());
}
return GetVariation(0, settings);
}
public ShaderVariation GetDefaultPixelVariation()
{
Dictionary<string, string> settings = new Dictionary<string, string>();
foreach (var macro in variationSymbolData.symbols)
{
settings.Add(macro.Name, macro.Values.FirstOrDefault());
}
return GetVariation(1, settings);
}
public ShaderVariation GetVariation(int type, Dictionary<string, string> settings)
{
int index = GetVariationIndex(type, settings);
return Header.Variations[index];
}
public int GetVariationIndex(int type, Dictionary<string, string> settings)
{
int index = 0;
foreach (var macro in variationSymbolData.symbols)
{
index *= macro.Values.Count;
index += macro.Values.IndexOf(settings[macro.Name]);
}
return BaseIndex + type + index * 2;
}
}
}
}

View file

@ -30,6 +30,13 @@ namespace FirstPlugin.Forms
LoadProgram(program);
}
public void FillEditor(SHARCFBNX.ShaderVariation var)
{
string programXML = Sharc2XML.WriteProgram(var);
textEditor1.FillEditor(programXML);
textEditor1.IsXML = true;
}
public void FillEditor(SHARCFB.ShaderProgram program, SHARCFB.Header header)
{
LoadProgram(program);

View file

@ -34,6 +34,21 @@ namespace FirstPlugin
doc.AppendChild(mainNode);
}
public static string WriteProgram(SHARCFBNX.ShaderVariation program)
{
XmlDocument doc = new XmlDocument();
XmlNode mainNode = doc.CreateElement("ShaderVariation");
AddAttribute(doc, "Name", program.Text.Replace("\x00", ""), mainNode);
doc.AppendChild(mainNode);
WriteVariationSymbols(doc, program.Uniforms, "Uniform_Variables", mainNode);
WriteVariationSymbols(doc, program.UniformBlocks, "Uniform_Blocks", mainNode);
WriteVariationSymbols(doc, program.Samplers, "Sampler_Variables", mainNode);
WriteVariationSymbols(doc, program.Attributes, "Attribute_Variables", mainNode);
return DocumentToString(doc);
}
public static string WriteProgram(SHARC.ShaderProgram program)
{
XmlDocument doc = new XmlDocument();
@ -66,6 +81,25 @@ namespace FirstPlugin
WriteVariationSymbols(doc, program.variationSymbolData, "option_array", mainNode);
WriteShaderSymbolData(doc, program.UniformVariables, "Uniform_Variables", mainNode);
XmlNode vertexNode = doc.CreateElement("VertexVariation");
XmlNode pixelNode = doc.CreateElement("PixelVariation");
mainNode.AppendChild(vertexNode);
mainNode.AppendChild(pixelNode);
var var = program.GetDefaultVertexVariation();
WriteVariationSymbols(doc, var.Uniforms, "Uniform_Variables", vertexNode);
WriteVariationSymbols(doc, var.UniformBlocks, "Uniform_Blocks", vertexNode);
WriteVariationSymbols(doc, var.Samplers, "Sampler_Variables", vertexNode);
WriteVariationSymbols(doc, var.Attributes, "Attribute_Variables", vertexNode);
var = program.GetDefaultPixelVariation();
WriteVariationSymbols(doc, var.Uniforms, "Uniform_Variables", pixelNode);
WriteVariationSymbols(doc, var.UniformBlocks, "Uniform_Blocks", pixelNode);
WriteVariationSymbols(doc, var.Samplers, "Sampler_Variables", pixelNode);
WriteVariationSymbols(doc, var.Attributes, "Attribute_Variables", pixelNode);
return DocumentToString(doc);
}
@ -115,6 +149,47 @@ namespace FirstPlugin
node.AppendChild(rootNode);
}
private static void WriteVariationSymbols(XmlDocument doc, List<SHARCFBNX.SymbolUniformBlock> symbols, string Name, XmlNode node)
{
XmlNode rootNode = doc.CreateElement(Name);
foreach (var symbol in symbols)
{
XmlNode childNode = doc.CreateElement("option");
AddAttribute(doc, "name", symbol.Name.Replace("\x00", ""), childNode);
AddAttribute(doc, "location", symbol.Location.ToString(), childNode);
AddAttribute(doc, "size", symbol.Size.ToString(), childNode);
rootNode.AppendChild(childNode);
}
node.AppendChild(rootNode);
}
private static void WriteVariationSymbols(XmlDocument doc, List<SHARCFBNX.SymbolUniform> symbols, string Name, XmlNode node)
{
XmlNode rootNode = doc.CreateElement(Name);
foreach (var symbol in symbols)
{
XmlNode childNode = doc.CreateElement("option");
AddAttribute(doc, "name", symbol.Name.Replace("\x00", ""), childNode);
AddAttribute(doc, "offset", symbol.Offset.ToString(), childNode);
rootNode.AppendChild(childNode);
}
node.AppendChild(rootNode);
}
private static void WriteVariationSymbols(XmlDocument doc, List<SHARCFBNX.Symbol> symbols, string Name, XmlNode node)
{
XmlNode rootNode = doc.CreateElement(Name);
foreach (var symbol in symbols)
{
XmlNode childNode = doc.CreateElement("option");
AddAttribute(doc, "name", symbol.Name.Replace("\x00", ""), childNode);
AddAttribute(doc, "location", symbol.Location.ToString(), childNode);
rootNode.AppendChild(childNode);
}
node.AppendChild(rootNode);
}
private static void WriteShaderSymbolData(XmlDocument doc, ShaderSymbolData symbolData, string Name, XmlNode node)
{
XmlNode rootNode = doc.CreateElement(Name);