2025-11-28 16:46:23 -08:00

181 lines
5.7 KiB
C#

using AssetRipper.DocExtraction.DataStructures;
namespace AssetRipper.AssemblyDumper.Passes;
internal static class Pass039_InjectEnumValues
{
private static readonly List<InjectedTypeData> injectedTypes = new()
{
new()
{
Name = "CurveLoopTypes",
Summary = "Enum for AnimationCurve.PreInfinity and AnimationCurve.PostInfinity",
Members = new()
{
("Constant", 0, ""),
("Cycle", 1, ""),
("CycleWithOffset", 2, ""),
("Oscillate", 3, ""),
("Linear", 4, ""),
},
},
};
private static readonly Dictionary<string, List<(string, long, string?)>> injectedValues = new()
{
{ "UnityEngine.TextureFormat",
new()
{
("ARGBFloat", 6, ""),
("BGR24", 8, ""),
("DXT3", 11, ""),
} },
{ "UnityEditor.TextureImporterFormat",
new()
{
("ARGBFloat", 6, ""),
("BGR24", 8, ""),
("DXT3", 11, ""),
} },
{ "UnityEngine.MeshTopology",
new()
{
("TriangleStrip", 1, "Mesh is a triangle strip."),
} },
{ "UnityEngine.SpritePackingRotation",
new()
{
("Rotate90", 4, "Might not exist. It was included in legacy code."),
("Any_Old", 5, "Might not exist. It was included in legacy code."),
} },
{ "UnityEngine.AnimatorControllerParameterType",
new()
{
("Vector", 0, "Added to allow merging. Remove once complex merging is implemented."),
} },
{ "UnityEditor.Animations.AnimatorConditionMode",
new()
{
("ExitTime", 5, "The condition is true when the source state has stepped over the exit time value."),
} },
};
private static readonly Dictionary<string, List<(string?, string)>> injectedDocumentation = new()
{
{ "UnityEditor.ModelImporterMeshCompression",
new()
{
(null, "Compressing meshes saves space in the built game, but more compression introduces more artifacts in vertex data."),
}
},
{ "UnityEditor.TextureUsageMode",
new()
{
("Default", "Not a lightmap"),
("LightmapDoubleLDR", "Range [0;2] packed to [0;1] with loss of precision"),
("BakedLightmapDoubleLDR", "Range [0;2] packed to [0;1] with loss of precision"),
("LightmapRGBM", "Range [0;kLightmapRGBMMax] packed to [0;1] with multiplier stored in the alpha channel"),
("BakedLightmapRGBM", "Range [0;kLightmapRGBMMax] packed to [0;1] with multiplier stored in the alpha channel"),
("NormalmapDXT5nm", "Compressed DXT5 normal map"),
("NormalmapPlain", "Plain RGB normal map"),
("AlwaysPadded", "Texture is always padded if NPOT and on low-end hardware"),
("BakedLightmapFullHDR", "Baked lightmap without any encoding"),
} },
};
public static void DoPass()
{
Dictionary<string, EnumHistory> dictionary = SharedState.Instance.HistoryFile.Enums;
//Inject types
foreach (InjectedTypeData injectedTypeData in injectedTypes)
{
UnityVersion minVersion = SharedState.Instance.MinSourceVersion;
EnumHistory history = new();
history.Name = injectedTypeData.Name;
history.FullName = $"Injected.{injectedTypeData.Name}";
history.IsFlagsEnum = injectedTypeData.IsFlags;
history.ElementType.Add(minVersion, injectedTypeData.ElementType);
history.NativeName.Add(minVersion, null);
history.DocumentationString.Add(minVersion, injectedTypeData.Summary);
history.ObsoleteMessage.Add(minVersion, null);
history.Exists.Add(minVersion, true);
foreach ((string fieldName, long value, string? description) in injectedTypeData.Members)
{
EnumMemberHistory member = new();
member.Name = fieldName;
member.NativeName.Add(minVersion, null);
member.Value.Add(minVersion, value);
member.DocumentationString.Add(minVersion, string.IsNullOrEmpty(description) ? null : description);
member.ObsoleteMessage.Add(minVersion, null);
member.Exists.Add(minVersion, true);
history.Members.Add(fieldName, member);
}
dictionary.Add(history.FullName, history);
}
//Inject values
foreach ((string fullName, List<(string, long, string?)> list) in injectedValues)
{
EnumHistory history = dictionary[fullName];
UnityVersion minVersion = history.Exists[0].Key;
foreach ((string fieldName, long value, string? description) in list)
{
if (history.Members.ContainsKey(fieldName))
{
Console.WriteLine($"{fullName} already has an entry for {fieldName}");
}
else
{
EnumMemberHistory member = new();
member.Name = fieldName;
member.NativeName.Add(minVersion, null);
member.Value.Add(minVersion, value);
member.DocumentationString.Add(minVersion, string.IsNullOrEmpty(description) ? "Injected" : $"Injected. {description}");
member.ObsoleteMessage.Add(minVersion, null);
member.Exists.Add(minVersion, true);
history.Members.Add(fieldName, member);
}
}
}
//Inject documentation
foreach ((string fullName, List<(string?, string)> list) in injectedDocumentation)
{
EnumHistory history = dictionary[fullName];
foreach ((string? fieldName, string description) in list)
{
if (string.IsNullOrEmpty(fieldName))
{
//Inject documentation for the enum itself
history.InjectedDocumentation = description;
}
else
{
EnumMemberHistory member = history.Members[fieldName];
member.InjectedDocumentation = description;
}
}
}
//Fix TextureFormat
{
EnumHistory history = dictionary["UnityEngine.TextureFormat"];
foreach (EnumMemberHistory member in history.Members.Values)
{
if (member.Value.Count == 2 && member.Value[1].Value == -127)
{
member.Value.RemoveAt(1);
}
}
}
}
private record class InjectedTypeData
{
public required string Name { get; init; }
public string? Summary { get; init; }
public bool IsFlags { get; init; } = false;
public ElementType ElementType { get; init; } = ElementType.I4;
public required List<(string, long, string?)> Members { get; init; }
}
}