mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-26 17:02:53 +08:00
Added code to generate Shaders.xml for XML plugins
This commit is contained in:
parent
6f1d148875
commit
bee7eb22f7
@ -198,6 +198,7 @@ namespace CodeWalker.GameFiles
|
|||||||
//TestYmaps();
|
//TestYmaps();
|
||||||
//TestPlacements();
|
//TestPlacements();
|
||||||
//TestDrawables();
|
//TestDrawables();
|
||||||
|
//GetShadersXml();
|
||||||
//GetArchetypeTimesList();
|
//GetArchetypeTimesList();
|
||||||
//string typestr = PsoTypes.GetTypesString();
|
//string typestr = PsoTypes.GetTypesString();
|
||||||
}
|
}
|
||||||
@ -3925,6 +3926,16 @@ namespace CodeWalker.GameFiles
|
|||||||
{ continue; }
|
{ continue; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if (ydd?.DrawableDict?.Hashes != null)
|
||||||
|
{
|
||||||
|
uint h = 0;
|
||||||
|
foreach (uint th in ydd.DrawableDict.Hashes)
|
||||||
|
{
|
||||||
|
if (th <= h)
|
||||||
|
{ } //should never happen
|
||||||
|
h = th;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//catch (Exception ex)
|
//catch (Exception ex)
|
||||||
@ -4415,6 +4426,173 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
UpdateStatus((DateTime.Now - starttime).ToString() + " elapsed, " + drawablecount.ToString() + " drawables, " + errs.Count.ToString() + " errors.");
|
UpdateStatus((DateTime.Now - starttime).ToString() + " elapsed, " + drawablecount.ToString() + " drawables, " + errs.Count.ToString() + " errors.");
|
||||||
|
|
||||||
|
}
|
||||||
|
public void GetShadersXml()
|
||||||
|
{
|
||||||
|
bool doydr = true;
|
||||||
|
bool doydd = true;
|
||||||
|
bool doyft = true;
|
||||||
|
bool doypt = true;
|
||||||
|
|
||||||
|
var data = new Dictionary<MetaHash, ShaderXmlDataCollection>();
|
||||||
|
|
||||||
|
void collectDrawable(DrawableBase d)
|
||||||
|
{
|
||||||
|
if (d?.AllModels == null) return;
|
||||||
|
foreach (var model in d.AllModels)
|
||||||
|
{
|
||||||
|
if (model?.Geometries == null) continue;
|
||||||
|
foreach (var geom in model.Geometries)
|
||||||
|
{
|
||||||
|
var s = geom?.Shader;
|
||||||
|
if (s == null) continue;
|
||||||
|
ShaderXmlDataCollection dc = null;
|
||||||
|
if (!data.TryGetValue(s.Name, out dc))
|
||||||
|
{
|
||||||
|
dc = new ShaderXmlDataCollection();
|
||||||
|
dc.Name = s.Name;
|
||||||
|
data.Add(s.Name, dc);
|
||||||
|
}
|
||||||
|
dc.AddShaderUse(s, geom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
foreach (RpfFile file in AllRpfs)
|
||||||
|
{
|
||||||
|
foreach (RpfEntry entry in file.AllEntries)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (doydr && entry.NameLower.EndsWith(".ydr"))
|
||||||
|
{
|
||||||
|
UpdateStatus(entry.Path);
|
||||||
|
YdrFile ydr = RpfMan.GetFile<YdrFile>(entry);
|
||||||
|
|
||||||
|
if (ydr == null) { continue; }
|
||||||
|
if (ydr.Drawable == null) { continue; }
|
||||||
|
collectDrawable(ydr.Drawable);
|
||||||
|
}
|
||||||
|
else if (doydd & entry.NameLower.EndsWith(".ydd"))
|
||||||
|
{
|
||||||
|
UpdateStatus(entry.Path);
|
||||||
|
YddFile ydd = RpfMan.GetFile<YddFile>(entry);
|
||||||
|
|
||||||
|
if (ydd == null) { continue; }
|
||||||
|
if (ydd.Dict == null) { continue; }
|
||||||
|
foreach (var drawable in ydd.Dict.Values)
|
||||||
|
{
|
||||||
|
collectDrawable(drawable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (doyft && entry.NameLower.EndsWith(".yft"))
|
||||||
|
{
|
||||||
|
UpdateStatus(entry.Path);
|
||||||
|
YftFile yft = RpfMan.GetFile<YftFile>(entry);
|
||||||
|
|
||||||
|
if (yft == null) { continue; }
|
||||||
|
if (yft.Fragment == null) { continue; }
|
||||||
|
if (yft.Fragment.Drawable != null)
|
||||||
|
{
|
||||||
|
collectDrawable(yft.Fragment.Drawable);
|
||||||
|
}
|
||||||
|
if ((yft.Fragment.Cloths != null) && (yft.Fragment.Cloths.data_items != null))
|
||||||
|
{
|
||||||
|
foreach (var cloth in yft.Fragment.Cloths.data_items)
|
||||||
|
{
|
||||||
|
collectDrawable(cloth.Drawable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((yft.Fragment.DrawableArray != null) && (yft.Fragment.DrawableArray.data_items != null))
|
||||||
|
{
|
||||||
|
foreach (var drawable in yft.Fragment.DrawableArray.data_items)
|
||||||
|
{
|
||||||
|
collectDrawable(drawable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (doypt && entry.NameLower.EndsWith(".ypt"))
|
||||||
|
{
|
||||||
|
UpdateStatus(entry.Path);
|
||||||
|
YptFile ypt = RpfMan.GetFile<YptFile>(entry);
|
||||||
|
|
||||||
|
if (ypt == null) { continue; }
|
||||||
|
if (ypt.DrawableDict == null) { continue; }
|
||||||
|
foreach (var drawable in ypt.DrawableDict.Values)
|
||||||
|
{
|
||||||
|
collectDrawable(drawable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch //(Exception ex)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var shaders = data.Values.ToList();
|
||||||
|
shaders.Sort((a, b) => { return b.GeomCount.CompareTo(a.GeomCount); });
|
||||||
|
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.AppendLine(MetaXml.XmlHeader);
|
||||||
|
MetaXml.OpenTag(sb, 0, "Shaders");
|
||||||
|
foreach (var s in shaders)
|
||||||
|
{
|
||||||
|
MetaXml.OpenTag(sb, 1, "Item");
|
||||||
|
MetaXml.StringTag(sb, 2, "Name", MetaXml.HashString(s.Name));
|
||||||
|
MetaXml.WriteHashItemArray(sb, s.GetSortedList(s.FileNames).ToArray(), 2, "FileName");
|
||||||
|
MetaXml.WriteRawArray(sb, s.GetSortedList(s.RenderBuckets).ToArray(), 2, "RenderBucket", "");
|
||||||
|
MetaXml.OpenTag(sb, 2, "Layout");
|
||||||
|
var layouts = s.GetSortedList(s.VertexLayouts);
|
||||||
|
foreach (var l in layouts)
|
||||||
|
{
|
||||||
|
var vd = new VertexDeclaration();
|
||||||
|
vd.Types = l.Types;
|
||||||
|
vd.Flags = l.Flags;
|
||||||
|
vd.WriteXml(sb, 3, "Item");
|
||||||
|
}
|
||||||
|
MetaXml.CloseTag(sb, 2, "Layout");
|
||||||
|
MetaXml.OpenTag(sb, 2, "Parameters");
|
||||||
|
var otstr = "Item name=\"{0}\" type=\"{1}\"";
|
||||||
|
var texparams = s.GetSortedList(s.TexParams);
|
||||||
|
var valparams = s.ValParams;
|
||||||
|
var arrparams = s.ArrParams;
|
||||||
|
foreach (var tp in texparams)
|
||||||
|
{
|
||||||
|
MetaXml.SelfClosingTag(sb, 3, string.Format(otstr, ((ShaderParamNames)tp).ToString(), "Texture"));
|
||||||
|
}
|
||||||
|
foreach (var vp in valparams)
|
||||||
|
{
|
||||||
|
var svp = s.GetSortedList(vp.Value);
|
||||||
|
var defval = svp.FirstOrDefault();
|
||||||
|
MetaXml.SelfClosingTag(sb, 3, string.Format(otstr, ((ShaderParamNames)vp.Key).ToString(), "Vector") + " " + FloatUtil.GetVector4XmlString(defval));
|
||||||
|
}
|
||||||
|
foreach (var ap in arrparams)
|
||||||
|
{
|
||||||
|
var defval = ap.Value.FirstOrDefault();
|
||||||
|
MetaXml.OpenTag(sb, 3, string.Format(otstr, ((ShaderParamNames)ap.Key).ToString(), "Array"));
|
||||||
|
foreach (var vec in defval)
|
||||||
|
{
|
||||||
|
MetaXml.SelfClosingTag(sb, 4, "Value " + FloatUtil.GetVector4XmlString(vec));
|
||||||
|
}
|
||||||
|
MetaXml.CloseTag(sb, 3, "Item");
|
||||||
|
}
|
||||||
|
MetaXml.CloseTag(sb, 2, "Parameters");
|
||||||
|
MetaXml.CloseTag(sb, 1, "Item");
|
||||||
|
}
|
||||||
|
MetaXml.CloseTag(sb, 0, "Shaders");
|
||||||
|
|
||||||
|
var xml = sb.ToString();
|
||||||
|
|
||||||
|
File.WriteAllText("C:\\Shaders.xml", xml);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public void GetArchetypeTimesList()
|
public void GetArchetypeTimesList()
|
||||||
{
|
{
|
||||||
@ -4450,6 +4628,123 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class ShaderXmlDataCollection
|
||||||
|
{
|
||||||
|
public MetaHash Name { get; set; }
|
||||||
|
public Dictionary<MetaHash, int> FileNames { get; set; } = new Dictionary<MetaHash, int>();
|
||||||
|
public Dictionary<byte, int> RenderBuckets { get; set; } = new Dictionary<byte, int>();
|
||||||
|
public Dictionary<ShaderXmlVertexLayout, int> VertexLayouts { get; set; } = new Dictionary<ShaderXmlVertexLayout, int>();
|
||||||
|
public Dictionary<MetaName, int> TexParams { get; set; } = new Dictionary<MetaName, int>();
|
||||||
|
public Dictionary<MetaName, Dictionary<Vector4, int>> ValParams { get; set; } = new Dictionary<MetaName, Dictionary<Vector4, int>>();
|
||||||
|
public Dictionary<MetaName, List<Vector4[]>> ArrParams { get; set; } = new Dictionary<MetaName, List<Vector4[]>>();
|
||||||
|
public int GeomCount { get; set; } = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public void AddShaderUse(ShaderFX s, DrawableGeometry g)
|
||||||
|
{
|
||||||
|
GeomCount++;
|
||||||
|
|
||||||
|
AddItem(s.FileName, FileNames);
|
||||||
|
AddItem(s.RenderBucket, RenderBuckets);
|
||||||
|
|
||||||
|
var info = g.VertexBuffer?.Info;
|
||||||
|
if (info != null)
|
||||||
|
{
|
||||||
|
AddItem(new ShaderXmlVertexLayout() { Flags = info.Flags, Types = info.Types }, VertexLayouts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.ParametersList?.Parameters == null) return;
|
||||||
|
if (s.ParametersList?.Hashes == null) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < s.ParametersList.Count; i++)
|
||||||
|
{
|
||||||
|
var h = s.ParametersList.Hashes[i];
|
||||||
|
var p = s.ParametersList.Parameters[i];
|
||||||
|
|
||||||
|
if (p.DataType == 0)//texture
|
||||||
|
{
|
||||||
|
AddItem(h, TexParams);
|
||||||
|
}
|
||||||
|
else if (p.DataType == 1)//vector
|
||||||
|
{
|
||||||
|
var vp = GetItem(h, ValParams);
|
||||||
|
if (p.Data is Vector4 vec)
|
||||||
|
{
|
||||||
|
AddItem(vec, vp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (p.DataType > 1)//array
|
||||||
|
{
|
||||||
|
var ap = GetItem(h, ArrParams);
|
||||||
|
if (p.Data is Vector4[] arr)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
foreach (var exarr in ap)
|
||||||
|
{
|
||||||
|
if (exarr.Length != arr.Length) continue;
|
||||||
|
bool match = true;
|
||||||
|
for (int j = 0; j < exarr.Length; j++)
|
||||||
|
{
|
||||||
|
if (exarr[j] != arr[j])
|
||||||
|
{
|
||||||
|
match = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (match)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
ap.Add(arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public void AddItem<T>(T t, Dictionary<T, int> d)
|
||||||
|
{
|
||||||
|
if (d.ContainsKey(t))
|
||||||
|
{
|
||||||
|
d[t]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d[t] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public U GetItem<T, U>(T t, Dictionary<T, U> d) where U:new()
|
||||||
|
{
|
||||||
|
U r = default(U);
|
||||||
|
if (!d.TryGetValue(t, out r))
|
||||||
|
{
|
||||||
|
r = new U();
|
||||||
|
d[t] = r;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
public List<T> GetSortedList<T>(Dictionary<T, int> d)
|
||||||
|
{
|
||||||
|
var kvps = d.ToList();
|
||||||
|
kvps.Sort((a, b) => { return b.Value.CompareTo(a.Value); });
|
||||||
|
return kvps.Select((a) => { return a.Key; }).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private struct ShaderXmlVertexLayout
|
||||||
|
{
|
||||||
|
public VertexDeclarationTypes Types { get; set; }
|
||||||
|
public uint Flags { get; set; }
|
||||||
|
public VertexType VertexType { get { return (VertexType)Flags; } }
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Types.ToString() + ", " + VertexType.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user