diff options
| author | 2026-10-21 16:13:13 -0400 | |
|---|---|---|
| committer | 2026-10-21 16:13:13 -0400 | |
| commit | a83f8f9368e7a94b82df4abd1bd90801c9472932 (patch) | |
| tree | 0573b6d8b17c11f03e90da9ce02818c726066861 | |
| parent | 6621a5333d0d6b68f1152abe69f3d64269b1ab79 (diff) | |
| download | WorldTuningTool-a83f8f9368e7a94b82df4abd1bd90801c9472932.tar.gz WorldTuningTool-a83f8f9368e7a94b82df4abd1bd90801c9472932.tar.bz2 WorldTuningTool-a83f8f9368e7a94b82df4abd1bd90801c9472932.zip | |
Cleanup MemoryUtil usage, use header for overrides
Signed-off-by: Andrew Opalach <andrew@akon.city>
| -rw-r--r-- | LUT.cs | 12 | ||||
| -rw-r--r-- | Lights.cs | 97 | ||||
| -rw-r--r-- | Plugin.cs | 191 | ||||
| -rw-r--r-- | WorldTuningTool.csproj | 3 | ||||
| -rw-r--r-- | WorldTuningTool.sln | 4 |
5 files changed, 182 insertions, 125 deletions
@@ -15,7 +15,7 @@ namespace WorldTuningTool { using static Plugin; - public static class WorldLUTs + internal static class WorldLUTs { private const string addPath = "nativePC/plugins/CSharp/LUT"; @@ -160,7 +160,7 @@ namespace WorldTuningTool #endif } - private static unsafe bool overwriteFromFile(nint texture, string path) + private static bool overwriteFromFile(nint texture, string path) { string ext = path.Split('.').Last().ToLower(); using (FileStream stream = File.Open(path, FileMode.Open)) @@ -169,7 +169,7 @@ namespace WorldTuningTool } } - private static unsafe bool overwriteFromMtFile(nint texture, string path) + private static bool overwriteFromMtFile(nint texture, string path) { MtFileStream? file = MtFileStream.FromPath(path, OpenMode.Read, false); bool success = false; @@ -183,7 +183,7 @@ namespace WorldTuningTool private static void reloadBlendLUT(nint lightingObject) { - MemoryUtil.GetRef<float>(lightingObject + 0x1D4) = MemoryUtil.GetRef<float>(lightingObject + 0x1D0) + 1.0f; + GetRef<float>(lightingObject, 0x1D4) = GetRef<float>(lightingObject, 0x1D0) + 1.0f; } private static string[] fileList = []; @@ -191,10 +191,10 @@ namespace WorldTuningTool private static bool[] selectionStarted = [ false, false ]; private static bool[] selectedInvalid = [ false, false ]; - public static void DrawUI(nint texture, nint lightingObject, int i, float width) + internal static unsafe void drawUI(nint texture, nint lightingObject, int i, float width) { ImGui.PushID(i); - string lutPath = Marshal.PtrToStringAnsi(texture + 0xC)!; + string lutPath = new(GetPtrInline<sbyte>(texture, 0xC)); ImGui.Text($"LUT {i}: {lutPath}"); #if TEXTURE_FEATURE if (ImGui.Button("Reset")) @@ -11,7 +11,7 @@ namespace WorldTuningTool { using static Plugin; - public static class Lights + internal static class Lights { private class BaseLight { @@ -132,8 +132,8 @@ namespace WorldTuningTool private class uLlkInfiniteLight : uInfiniteLight { public override string Name => $"uLlkInfiniteLight"; - public nint CycleTimelineRes => MemoryUtil.Read<nint>(Object + 0x658); - public int CycleAnimNo => MemoryUtil.Read<int>(Object + 0x7A8); + public nint CycleTimelineRes => Get<nint>(Object, 0x658); + public int CycleAnimNo => Get<int>(Object, 0x7A8); public uLlkInfiniteLight(nint lightObject) : base(lightObject) { @@ -169,9 +169,9 @@ namespace WorldTuningTool public override int Type => 2; public override string Name => $"uPointLight"; public override string Info => $"0x{Object:X}" + (Parent != 0x0 ? $", Parent: 0x{Parent:X}" : ""); - public nint Parent => MemoryUtil.Read<nint>(Object + 0x5C0); - public int ParentNo => MemoryUtil.Read<int>(Object + 0x5C8); - public Vector3 Position => MemoryUtil.Read<Vector3>(Object + 0x5A0); + public nint Parent => Get<nint>(Object, 0x5C0); + public int ParentNo => Get<int>(Object, 0x5C8); + public Vector3 Position => Get<Vector3>(Object, 0x5A0); public uPointLight(nint lightObject) : base(lightObject) { @@ -220,12 +220,12 @@ namespace WorldTuningTool private class uLlkPointLight : uPointLight { public override string Name => $"uLlkPointLight"; - public nint TimelineRes => MemoryUtil.Read<nint>(Object + 0x8A4); - public int AnimNo => MemoryUtil.Read<int>(Object + 0x7A8); + public nint TimelineRes => Get<nint>(Object, 0x8A4); + public int AnimNo => Get<int>(Object, 0x7A8); public NativeAction<nint> PlayResource = new NativeAction<nint>(0x141F89CB0); public NativeAction<nint> StopResource = new NativeAction<nint>(0x141F8A0C0); - public nint CycleTimelineRes => MemoryUtil.Read<nint>(Object + 0x750); - public int CycleAnimNo => MemoryUtil.Read<int>(Object + 0x8A0); + public nint CycleTimelineRes => Get<nint>(Object, 0x750); + public int CycleAnimNo => Get<int>(Object, 0x8A0); public uLlkPointLight(nint lightObject) : base(lightObject) { @@ -276,13 +276,13 @@ namespace WorldTuningTool public override int Type => 3; public override string Name => $"uSpotLight"; public override string Info => $"0x{Object:X}" + (Parent != 0x0 ? $", Parent: 0x{Parent:X}" : ""); - public nint Parent => MemoryUtil.Read<nint>(Object + 0x600); - public int ParentNo => MemoryUtil.Read<int>(Object + 0x610); - public nint Target => MemoryUtil.Read<nint>(Object + 0x608); - public int TargetNo => MemoryUtil.Read<int>(Object + 0x614); - public nint Texture => MemoryUtil.Read<nint>(Object + 0x670); - public nint ShadowCacheResource => MemoryUtil.Read<nint>(Object + 0x698); - public Vector3 Position => MemoryUtil.Read<Vector3>(Object + 0x5A0); + public nint Parent => Get<nint>(Object, 0x600); + public int ParentNo => Get<int>(Object, 0x610); + public nint Target => Get<nint>(Object, 0x608); + public int TargetNo => Get<int>(Object, 0x614); + public nint Texture => Get<nint>(Object, 0x670); + public nint ShadowCacheResource => Get<nint>(Object, 0x698); + public Vector3 Position => Get<Vector3>(Object, 0x5A0); public uSpotLight(nint lightObject) : base(lightObject) { @@ -345,12 +345,12 @@ namespace WorldTuningTool private class uLlkSpotLight : uSpotLight { public override string Name => $"uLlkSpotLight"; - public nint TimelineRes => MemoryUtil.Read<nint>(Object + 0x790); - public int AnimNo => MemoryUtil.Read<int>(Object + 0x974); + public nint TimelineRes => Get<nint>(Object, 0x790); + public int AnimNo => Get<int>(Object, 0x974); public NativeAction<nint> PlayResource = new NativeAction<nint>(0x141F8D550); public NativeAction<nint> StopResource = new NativeAction<nint>(0x141F8D970); - public nint CycleTimelineRes => MemoryUtil.Read<nint>(Object + 0x820); - public int CycleAnimNo => MemoryUtil.Read<int>(Object + 0x970); + public nint CycleTimelineRes => Get<nint>(Object, 0x820); + public int CycleAnimNo => Get<int>(Object, 0x970); public uLlkSpotLight(nint lightObject) : base(lightObject) { @@ -445,8 +445,8 @@ namespace WorldTuningTool private class uLlkHemiSphereLight : uHemiSphereLight { public override string Name => $"uLlkHemiSphereLight"; - public nint CycleTimelineRes => MemoryUtil.Read<nint>(Object + 0x5D0); - public int CycleAnimNo => MemoryUtil.Read<int>(Object + 0x720); + public nint CycleTimelineRes => Get<nint>(Object, 0x5D0); + public int CycleAnimNo => Get<int>(Object, 0x720); public uLlkHemiSphereLight(nint lightObject) : base(lightObject) { @@ -554,7 +554,7 @@ namespace WorldTuningTool private static List<BaseLight> objectLights = new List<BaseLight>(); #endif - public static void Initialize() + internal static void Initialize() { createLightObject = Hook.Create<CreateLightObject>(0x142311420, CreateLightObjectHook); DestroyLightObject[] destructorHookFuncs = { @@ -584,7 +584,7 @@ namespace WorldTuningTool }; for (int i = 0; i < lightTypes.Count(); i++) // Not ordered. { - nint destructor = MemoryUtil.Read<nint>(lightTypes.Keys.ElementAt(i)); + nint destructor = Get<nint>(lightTypes.Keys.ElementAt(i)); lightObjectDestructorHooks[i] = Hook.Create<DestroyLightObject>(destructor, destructorHookFuncs[i]); } @@ -604,7 +604,7 @@ namespace WorldTuningTool removeFromScene = new NativeAction<nint>(0x142228F10); } - public static void PostUpdateLightLinker() + internal static void PostUpdateLightLinker() { foreach (uLight light in sceneLights) { @@ -615,28 +615,29 @@ namespace WorldTuningTool } } - public static void OnUpdate() + internal static void OnUpdate() { - // @TODO: Safe to check newLights.Count > 0? - // Apparently that read would be guaranteed atomic in c#. - lock (newLights) + if (newLights.Count > 0) { - for (int i = newLights.Count - 1; i >= 0; i--) + lock (newLights) { - uLight light = newLights[i]; - newLights.RemoveAt(i); - nint vTable = MemoryUtil.Read<nint>(light.Object); - if (lightTypes.ContainsKey(vTable)) + for (int i = newLights.Count - 1; i >= 0; i--) { - if (vTable == 0x143514168) + uLight light = newLights[i]; + newLights.RemoveAt(i); + nint vTable = Get<nint>(light.Object); + if (lightTypes.ContainsKey(vTable)) { - Log.Error("Light is still uLight OnUpdate()."); + if (vTable == 0x143514168) + { + Log.Error("Light is still uLight OnUpdate()."); + } + sceneLights.Add(lightTypes[vTable](light.Object)); + } + else + { + Log.Error($"Unknown Light Type: 0x{vTable:X}."); } - sceneLights.Add(lightTypes[vTable](light.Object)); - } - else - { - Log.Error($"Unknown Light Type: 0x{vTable:X}."); } } } @@ -944,7 +945,7 @@ namespace WorldTuningTool } } - public static unsafe void DrawUI(float width) + internal static unsafe void drawUI(float width) { int lightType = -1; nint lightObject = 0x0; @@ -1001,7 +1002,7 @@ namespace WorldTuningTool ourLights.Add(new uMhHemiSphereLight(lightObject, pos)); } // mov byte ptr[rsp+20],00 unaccounted for, hopefully it never matters. - addToScene.Invoke(MemoryUtil.Read<nint>(0x1451238C8), 0x16, lightObject, 0x0); + addToScene.Invoke(Get<nint>(0x1451238C8), 0x16, lightObject, 0x0); } ImGui.PushID("Ours"); for (int i = 0; i < ourLights.Count; i++) @@ -1050,12 +1051,12 @@ namespace WorldTuningTool Vector3 xPos = ((uPointLight)x).Position; if (((uPointLight)x).Parent != 0x0) { - xPos += MemoryUtil.GetRef<Vector3>(((uPointLight)x).Parent + 0x160); + xPos += Get<Vector3>(((uPointLight)x).Parent, 0x160); } Vector3 yPos = ((uPointLight)y).Position; if (((uPointLight)y).Parent != 0x0) { - yPos += MemoryUtil.GetRef<Vector3>(((uPointLight)y).Parent + 0x160); + yPos += Get<Vector3>(((uPointLight)y).Parent, 0x160); } float distX = Vector3.Distance(pos, xPos); float distY = Vector3.Distance(pos, yPos); @@ -1086,12 +1087,12 @@ namespace WorldTuningTool Vector3 xPos = ((uSpotLight)x).Position; if (((uSpotLight)x).Parent != 0x0) { - xPos += MemoryUtil.GetRef<Vector3>(((uSpotLight)x).Parent + 0x160); + xPos += Get<Vector3>(((uSpotLight)x).Parent, 0x160); } Vector3 yPos = ((uSpotLight)y).Position; if (((uSpotLight)y).Parent != 0x0) { - yPos += MemoryUtil.GetRef<Vector3>(((uSpotLight)y).Parent + 0x160); + yPos += Get<Vector3>(((uSpotLight)y).Parent, 0x160); } float distX = Vector3.Distance(pos, xPos); float distY = Vector3.Distance(pos, yPos); @@ -26,7 +26,6 @@ using SharpPluginLoader.Core.Resources; // @TODO: // - https://dev.epicgames.com/community/learning/tutorials/34xz/unreal-engine-ocio-3d-luts-applying-3d-luts-when-using-ocio -// - Hook sMhScene constructor to set hqMode. // - Configurable Broad Area Shadow Resolution. // - Optimized update logic. // - Only update non-override values when UI is shown. @@ -65,7 +64,7 @@ namespace WorldTuningTool public string Author => "Akon City Software"; private static bool loggedAssertFailed = false; - public static void Assert(bool condition, [CallerLineNumber] int line = 0) + internal static void Assert(bool condition = false, [CallerLineNumber] int line = 0) { if (!condition && !loggedAssertFailed) { @@ -79,6 +78,26 @@ namespace WorldTuningTool private static byte ByteFlag(bool f) { return f ? (byte)0x1 : (byte)0x0; } + internal static T Get<T>(nint addr, nint offset = 0x0) where T : unmanaged + { + return MemoryUtil.Read<T>(addr + offset); + } + + internal static T Get<T>(long addr, nint offset = 0x0) where T : unmanaged + { + return MemoryUtil.Read<T>((nint)addr + offset); + } + + internal static T *GetPtrInline<T>(nint addr, nint offset = 0x0) where T : unmanaged + { + return (T *)(addr + offset); + } + + internal static ref T GetRef<T>(nint addr, nint offset = 0x0) where T : unmanaged + { + return ref MemoryUtil.GetRef<T>(addr + offset); + } + private static int BitIndex(int mask) { return BitOperations.Log2((uint)(mask & (-mask))); @@ -112,7 +131,7 @@ namespace WorldTuningTool private static string BooleanToString(bool b) { return b.ToString(CultureInfo.InvariantCulture); } private static string Int32ToString(int i, string? format = null) { return i.ToString(format, CultureInfo.InvariantCulture); } - public static Vector2 StringToVector2(string s, char delim = ',') + internal static Vector2 StringToVector2(string s, char delim = ',') { if (String.IsNullOrEmpty(s)) throw new FormatException(); string[] sp = s.Split(delim).Select((v) => v.Trim()).ToArray(); @@ -120,7 +139,7 @@ namespace WorldTuningTool return new Vector2(StringToSingle(sp[0]), StringToSingle(sp[1])); } - public static Vector3 StringToVector3(string s, char delim = ',') + internal static Vector3 StringToVector3(string s, char delim = ',') { if (String.IsNullOrEmpty(s)) throw new FormatException(); string[] sp = s.Split(delim).Select((v) => v.Trim()).ToArray(); @@ -128,7 +147,7 @@ namespace WorldTuningTool return new Vector3(StringToSingle(sp[0]), StringToSingle(sp[1]), StringToSingle(sp[2])); } - public static Vector4 StringToVector4(string s, char delim = ',') + internal static Vector4 StringToVector4(string s, char delim = ',') { if (String.IsNullOrEmpty(s)) throw new FormatException(); string[] sp = s.Split(delim).Select((v) => v.Trim()).ToArray(); @@ -295,7 +314,7 @@ namespace WorldTuningTool return superseded; } - private static class ParameterFlags + public static class ParameterFlags { public const int ViewOnly = 1; } @@ -347,7 +366,7 @@ namespace WorldTuningTool Assert(mask != 0); break; case ParameterType.PATCH_FLOAT: - valueV.X = MemoryUtil.Read<float>(offset); + valueV.X = Get<float>(offset); pendingUpdate = false; break; case ParameterType.SHADOW_RESOLUTION: @@ -422,11 +441,11 @@ namespace WorldTuningTool { case ParameterType.BOOL: case ParameterType.BYTE: - MemoryUtil.GetRef<byte>(lastAddr + offset) = (byte)valueInt; + GetRef<byte>(lastAddr, offset) = (byte)valueInt; break; case ParameterType.FLAG: { - ref int i1 = ref MemoryUtil.GetRef<int>(lastAddr + offset); + ref int i1 = ref GetRef<int>(lastAddr, offset); if (valueInt != 0) { i1 |= mask; @@ -443,7 +462,7 @@ namespace WorldTuningTool case ParameterType.BITS: case ParameterType.COLOR: { - ref int i1 = ref MemoryUtil.GetRef<int>(lastAddr + offset); + ref int i1 = ref GetRef<int>(lastAddr, offset); if (mask != 0) { i1 = (i1 & ~mask) | ((valueInt << BitIndex(mask)) & mask); @@ -455,17 +474,17 @@ namespace WorldTuningTool break; } case ParameterType.FLOAT: - MemoryUtil.GetRef<float>(lastAddr + offset) = valueV.X; + GetRef<float>(lastAddr, offset) = valueV.X; break; case ParameterType.VECTOR2: - MemoryUtil.GetRef<Vector2>(lastAddr + offset) = new Vector2(valueV.X, valueV.Y); + GetRef<Vector2>(lastAddr, offset) = new Vector2(valueV.X, valueV.Y); break; case ParameterType.VECTOR3: case ParameterType.COLOR_FACTOR: - MemoryUtil.GetRef<Vector3>(lastAddr + offset) = new Vector3(valueV.X, valueV.Y, valueV.Z); + GetRef<Vector3>(lastAddr, offset) = new Vector3(valueV.X, valueV.Y, valueV.Z); break; case ParameterType.VECTOR4: - MemoryUtil.GetRef<Vector4>(lastAddr + offset) = valueV; + GetRef<Vector4>(lastAddr, offset) = valueV; break; } } @@ -596,7 +615,7 @@ namespace WorldTuningTool case ParameterType.BOOL: case ParameterType.BYTE: { - ref byte b1 = ref MemoryUtil.GetRef<byte>(baseObject + offset); + ref byte b1 = ref GetRef<byte>(baseObject, offset); byte b = b1; if (overrideValue) { @@ -614,7 +633,7 @@ namespace WorldTuningTool } case ParameterType.FLAG: { - ref int i1 = ref MemoryUtil.GetRef<int>(baseObject + offset); + ref int i1 = ref GetRef<int>(baseObject, offset); int b1 = ByteFlag((i1 & mask) == mask); if (overrideValue) { @@ -643,7 +662,7 @@ namespace WorldTuningTool case ParameterType.BITS: case ParameterType.COLOR: { - ref int i1 = ref MemoryUtil.GetRef<int>(baseObject + offset); + ref int i1 = ref GetRef<int>(baseObject, offset); int m = i1; if (mask != 0) { @@ -672,7 +691,7 @@ namespace WorldTuningTool } case ParameterType.FLOAT: { - ref float f1 = ref MemoryUtil.GetRef<float>(baseObject + offset); + ref float f1 = ref GetRef<float>(baseObject, offset); float f = f1; if (overrideValue) { @@ -690,7 +709,7 @@ namespace WorldTuningTool } case ParameterType.VECTOR2: { - ref Vector2 v2 = ref MemoryUtil.GetRef<Vector2>(baseObject + offset); + ref Vector2 v2 = ref GetRef<Vector2>(baseObject, offset); Vector2 v = v2; if (overrideValue) { @@ -710,7 +729,7 @@ namespace WorldTuningTool case ParameterType.VECTOR3: case ParameterType.COLOR_FACTOR: { - ref Vector3 v3 = ref MemoryUtil.GetRef<Vector3>(baseObject + offset); + ref Vector3 v3 = ref GetRef<Vector3>(baseObject, offset); Vector3 v = v3; if (overrideValue) { @@ -729,7 +748,7 @@ namespace WorldTuningTool } case ParameterType.VECTOR4: { - ref Vector4 v4 = ref MemoryUtil.GetRef<Vector4>(baseObject + offset); + ref Vector4 v4 = ref GetRef<Vector4>(baseObject, offset); Vector4 v = v4; if (overrideValue) { @@ -1215,28 +1234,47 @@ namespace WorldTuningTool { if (typeof(T) == typeof(float)) { + Assert(type == ParameterType.FLOAT || + type == ParameterType.VECTOR2 || + type == ParameterType.VECTOR3 || + type == ParameterType.VECTOR4 || + type == ParameterType.PATCH_FLOAT || + type == ParameterType.COLOR_FACTOR); this.stepf = (step != null) ? Convert.ToSingle(step) : 0.1f; this.minf = (min != null) ? Convert.ToSingle(min) : -Single.MaxValue; this.maxf = (max != null) ? Convert.ToSingle(max) : Single.MaxValue; } - else if (typeof(T) == typeof(int) || typeof(T) == typeof(byte) || typeof(T) == typeof(bool)) + else { this.step = (step != null) ? Convert.ToInt32(step) : 0; if (typeof(T) == typeof(int)) { + Assert(type == ParameterType.INT || + type == ParameterType.ALIGNED_INT || + type == ParameterType.HEX || + type == ParameterType.BITS || + type == ParameterType.COLOR || + type == ParameterType.SHADOW_RESOLUTION); this.min = (min != null) ? Convert.ToInt32(min) : Int32.MinValue; this.max = (max != null) ? Convert.ToInt32(max) : Int32.MaxValue; } else if (typeof(T) == typeof(byte)) { + Assert(type == ParameterType.BYTE); this.min = (min != null) ? Convert.ToInt32(min) : 0x0; this.max = (max != null) ? Convert.ToInt32(max) : 0xFF; } else if (typeof(T) == typeof(bool)) { + Assert(type == ParameterType.BOOL || + type == ParameterType.FLAG); this.min = 0; this.max = 1; } + else + { + Assert(); + } } } } @@ -1275,7 +1313,7 @@ namespace WorldTuningTool return new Parameter<T>(name, offset, mask, type, m.min, m.max, m.step, 0); } - private static Parameter? getParameterByName(string name) + internal static Parameter? getParameterByName(string name) { if (OldParameterNames.TryGetValue(name, out string? newName)) { @@ -1889,7 +1927,7 @@ namespace WorldTuningTool private delegate void UpdateSSLREnvMapIntensity(nint stackOffset, bool unknownBool); private Hook<UpdateSSLREnvMapIntensity>? updateSSLREnvMapIntensity; - private static Parameter sslrEnvMapIntensity = P<float>("SSLR Env Map Intensity", 0xB420, ParameterType.FLOAT); + private static Parameter sslrEnvMapIntensity = P<float>("SSLR Env Map Intensity", 0xB420, ParameterType.FLOAT, pMinStep(0.0f, 0.01f)); private static Parameter[] sslrParameters = { P<int>("SSLR Loop Count", 0xE628, ParameterType.INT, pStep(1)), P<float>("SSLR Eliminate Depth", 0xE630, ParameterType.FLOAT), @@ -1936,7 +1974,7 @@ namespace WorldTuningTool // can be seen when returning to title or opening a guild card for the first time. Setting 'Bloom Renormalize' // to 0.0 or 'Bloom Reduction Resolution' to -1 can both effectively disable bloom without that issue. //newFlag<byte>("Bloom Enabled", 0x14, ParameterType.FLAG, (1 << 1)), // Draw - P<float>("Bloom Threshold", 0x204, ParameterType.FLOAT), + P<float>("Bloom Threshold", 0x204, ParameterType.FLOAT, pStep(0.001f)), P<float>("Bloom Renormalize", 0x208, ParameterType.FLOAT, pMin(0.0f)), P<int>("Bloom Color", 0x200, ParameterType.COLOR), P<int>("Bloom Downsample Count", 0x168, ParameterType.INT, pMinMaxStep(0, 8, 1)), @@ -2043,9 +2081,9 @@ namespace WorldTuningTool P<float>("Sky Sun Light Mask UV Scale", 0x2D0, ParameterType.FLOAT, pStep(0.001f)), P<float>("Sky Sun Bloom Intensity", 0x2AC, ParameterType.FLOAT), P<float>("Sky Sun Bloom Transparency Coefficient", 0x2B0, ParameterType.FLOAT, pStep(0.025f)), - P<float>("Sky Sun Bloom Threshold", 0x2B4, ParameterType.FLOAT), + P<float>("Sky Sun Bloom Threshold", 0x2B4, ParameterType.FLOAT, pStep(0.001f)), P<float>("Sky Sun Bloom Dispersion", 0x2B8, ParameterType.FLOAT), - P<float>("Sky Sun Bloom Downsample Count", 0x2C0, ParameterType.FLOAT), + P<float>("Sky Sun Bloom Downsample Count", 0x2C0, ParameterType.FLOAT, pMinMaxStep(0, 8, 1)), P<int>("Sky Sun Bloom Reduction Resolution", 0x2C4, ParameterType.INT, pStep(1)), P<float>("Sky Sun Light Sky Color", 0x2E0, ParameterType.COLOR_FACTOR, pStep(0.001f)), P<float>("Sky Sun Light Sky Mask UV Scale", 0x2F0, ParameterType.FLOAT, pStep(0.001f)), @@ -2240,9 +2278,9 @@ namespace WorldTuningTool bool reset = multiplier == 1; int unused1Value = Math.Clamp(0x1000 * multiplier, 0x1000, 0x4000); int unused2Value = Math.Clamp(0xC00 * multiplier, 0xC00, 0x4000); - int highValue = Math.Clamp((reset ? 0x800 : 0xC00) * multiplier, reset ? 0x800 : 0xC00, 0x4000); - int midValue = Math.Clamp( (reset ? 0x600 : 0x800) * multiplier, reset ? 0x600 : 0x800, 0x4000); - int lowValue = Math.Clamp( (reset ? 0x400 : 0x600) * multiplier, reset ? 0x400 : 0x600, 0x4000); + int highValue = Math.Clamp((reset ? 0x800 : 0xC00) * multiplier, (reset ? 0x800 : 0xC00), 0x4000); + int midValue = Math.Clamp( (reset ? 0x600 : 0x800) * multiplier, (reset ? 0x600 : 0x800), 0x4000); + int lowValue = Math.Clamp( (reset ? 0x400 : 0x600) * multiplier, (reset ? 0x400 : 0x600), 0x4000); new Patch(broadAreaShadowRes1_Addr + 0x45, BitConverter.GetBytes(unused1Value)).Enable(); new Patch(broadAreaShadowRes1_Addr + 0x45 + 0xB, BitConverter.GetBytes(unused2Value)).Enable(); new Patch(broadAreaShadowRes1_Addr + 0x45 + 0x16, BitConverter.GetBytes(highValue)).Enable(); @@ -2311,7 +2349,7 @@ namespace WorldTuningTool } setBroadAreaShadowResolution(multiplier); currentShadowResMultiplier = multiplier; - setShadowQuality.Invoke(MemoryUtil.Read<int>(sMhScene!.Instance + 0x5530) + 1); + setShadowQuality.Invoke(sMhScene!.Get<int>(0x5530) + 1); } private static void shadowResDisable() @@ -2346,7 +2384,7 @@ namespace WorldTuningTool shadowRes1_4.Disable(); setBroadAreaShadowResolution(1); currentShadowResMultiplier = 1; - setShadowQuality.Invoke(MemoryUtil.Read<int>(sMhScene!.Instance + 0x5530) + 1); + setShadowQuality.Invoke(sMhScene!.Get<int>(0x5530) + 1); } #if SHADER_FEATURES @@ -2616,11 +2654,11 @@ namespace WorldTuningTool addr = PatternScanner.FindFirst(Pattern.FromString("48 83 EC 28 F3 0F 10 0D ?? ?? ?? ?? 80 F9 04 75 2F 48 8B 0D ?? ?? ?? ?? E8 D3 8A E4 01 48 8B 0D ?? ?? ?? ?? 33 D2 E8 ?? ?? ?? ??")); Assert(addr == 0x14043FF80); - Assert(MemoryUtil.Read<int>(0x142EE1A90) == 0x40000000); // 2.0. - Assert(MemoryUtil.Read<int>(0x142E4FE5C) == 0x40400000); // 3.0. - Assert(MemoryUtil.Read<int>(0x142F1FD4C) == 0x40800000); // 4.0. - Assert(MemoryUtil.Read<int>(0x142F1FD50) == 0x40A00000); // 5.0. - Assert(MemoryUtil.Read<int>(0x14321222C) == 0x40C00000); // 6.0. + Assert(Get<int>(0x142EE1A90) == 0x40000000); // 2.0. + Assert(Get<int>(0x142E4FE5C) == 0x40400000); // 3.0. + Assert(Get<int>(0x142F1FD4C) == 0x40800000); // 4.0. + Assert(Get<int>(0x142F1FD50) == 0x40A00000); // 5.0. + Assert(Get<int>(0x14321222C) == 0x40C00000); // 6.0. shadowRes1_2x = new Patch(addr + 0x8, [0x04, 0x1B, 0xAA, 0x02]); shadowRes1_3x = new Patch(addr + 0x8, [0xD0, 0xFE, 0xA0, 0x02]); shadowRes1_4x = new Patch(addr + 0x8, [0xC0, 0xFD, 0xAD, 0x02]); @@ -2968,13 +3006,13 @@ namespace WorldTuningTool if (adjustCtcParams && resource != null && resource.FileExtension == "ctc") { Log.Info($"Attempting to increase physics update rate of {resource.FilePath} @ {resource.Instance:X}."); - int numARecords = MemoryUtil.GetRef<int>(resource.Instance + 0xB8); - nint aRecords = MemoryUtil.GetRef<nint>(resource.Instance + 0xF8); + int numARecords = resource.Get<int>(0xB8); + nint aRecords = resource.Get<nint>(0xF8); for (int i = 0; i < numARecords; i++) { nint aRecord = aRecords + (0x50 * i); } - MemoryUtil.GetRef<float>(resource.Instance + 0xC4) = 1.0f / stepTimeFps; + resource.GetRef<float>(0xC4) = 1.0f / stepTimeFps; } } #endif @@ -3001,7 +3039,7 @@ namespace WorldTuningTool if (setWeatherMode) { - MemoryUtil.GetRef<int>(sQuest!.Instance + 0x293B4) = requestWeatherMode; + sQuest!.GetRef<int>(0x293B4) = requestWeatherMode; } foreach (Parameter param in sTimeParameters) @@ -3561,7 +3599,7 @@ namespace WorldTuningTool private void UpdatePrimaryLightParamsHook(nint primaryLightParams, nint stackOffset) { - bool isPrimary = MemoryUtil.Read<byte>(stackOffset + 0x1D) == 0x1; + bool isPrimary = Get<byte>(stackOffset, 0x1D) == 0x1; if (isPrimary) { foreach (Parameter param in primaryLightParameters) @@ -3778,12 +3816,8 @@ namespace WorldTuningTool drawList.AddRectFilled(windowPos, windowPos + new Vector2(boxWidth, boxHeight), (uint)ColorVectorToInt(boxColor)); } - public void OnImGuiRender() + private void drawOverrides(Config config, List<Override>? globalOverrides, List<Override>? stageOverrides, float width) { - float width = ImGui.GetWindowWidth(); - width /= width / (600.0f * ImGui.GetIO().FontGlobalScale); - - ImGui.Text($"Current Stage: {StageToString(currentStage)}"); ImGui.PushItemWidth(width * 0.35f); if (ImGui.BeginCombo("##Stage", StageToString(selectedStage), ImGuiComboFlags.HeightLarge)) { @@ -3800,7 +3834,6 @@ namespace WorldTuningTool ImGui.EndCombo(); } ImGui.SameLine(); - Config config = getConfig(); bool errorStage = !config.Overrides.ContainsKey(currentStage); if (errorStage) { @@ -3849,8 +3882,7 @@ namespace WorldTuningTool selectedOrderChanged = true; } } - List<Override>? stageOverrides = maybeGetStageOverrides(config); - List<Override>? globalOverrides = null; + if (selectedStage != globalStage) { globalOverrides = config.Overrides[globalStage]; @@ -3884,6 +3916,7 @@ namespace WorldTuningTool } } ImGui.PopItemWidth(); + for (int i = 0; i < selectedOverrides.Count; i++) { ImGui.PushID(i); @@ -3930,6 +3963,7 @@ namespace WorldTuningTool } ImGui.PopID(); } + if (ImGui.Button("Save")) { for (int i = 0; i < selectedOverrides.Count; i++) @@ -3962,12 +3996,31 @@ namespace WorldTuningTool } ImGui.Separator(); + } + + public void OnImGuiRender() + { + float width = ImGui.GetWindowWidth(); + width /= width / (600.0f * ImGui.GetIO().FontGlobalScale); + + Config config = getConfig(); + + List<Override>? stageOverrides = maybeGetStageOverrides(config); + List<Override>? globalOverrides = null; + + bool expand = ImGui.CollapsingHeader("Current Stage:", ImGuiTreeNodeFlags.DefaultOpen); + ImGui.SameLine(); + ImGui.Text($"{StageToString(currentStage)}"); + if (expand) + { + drawOverrides(config, globalOverrides, stageOverrides, width); + } // From this point forward, we have to consider both globalOverrides and stageOverrides. globalOverrides = config.Overrides[globalStage]; ImGui.PushID("Set"); - ImGui.Text("Quick Sets:"); + ImGui.Text("Quick Sets"); ImGui.PushItemWidth(width * 0.35f); string prevSet = selectedSet; if (ImGui.Button("+")) @@ -4165,7 +4218,7 @@ namespace WorldTuningTool ImGui.Separator(); ImGui.PushID("External"); - ImGui.Text("External:"); + ImGui.Text("External"); foreach (Override ovE in externalOverrides.Values) { Vector2 cursorPos = default; @@ -4383,11 +4436,11 @@ namespace WorldTuningTool { if (ImGui.CollapsingHeader("Lights")) { - Lights.DrawUI(width); + Lights.drawUI(width); } } - bool expand = ImGui.CollapsingHeader("Parameters"); + expand = ImGui.CollapsingHeader("Parameters"); if (ImGui.BeginItemTooltip()) { ImGui.Text("(Original: X) may be inaccurate for various reasons, such as\n 1. The game set the parameter to the same value as an override from this mod.\n 2. The game is dynamically updating the parameter in a location unknown to this mod."); @@ -4476,10 +4529,16 @@ namespace WorldTuningTool ImGui.PopID(); ImGui.PushID("PrimaryLight"); - if (ImGui.CollapsingHeader("Primary Light")) + expand = ImGui.CollapsingHeader("Primary Light"); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("These are the per-frame parameters of the Primary uMhInfiniteLight, which can also be found under Lights -> Scene Lights -> Infinite"); + ImGui.EndTooltip(); + } + if (expand) { // MonsterHunterWorld.exe+1AB99E0 - mov rax,[MonsterHunterWorld.exe+500E180] - nint primaryLightObject = MemoryUtil.Read<nint>(MemoryUtil.Read<nint>(0x14500E180) + 0x4B0); + nint primaryLightObject = Get<nint>(Get<nint>(0x14500E180), 0x4B0); ImGui.Text($"Address: 0x{primaryLightObject:X}"); foreach (Parameter param in primaryLightParameters) { @@ -4550,17 +4609,17 @@ namespace WorldTuningTool { if (ImGui.CollapsingHeader("LUTs")) { - nint lutBlendTexture = MemoryUtil.Read<nint>(toneMapObject + 0x1C0); + nint lutBlendTexture = Get<nint>(toneMapObject, 0x1C0); ImGui.Text($"LUT Blend: 0x{lutBlendTexture:X}"); - nint lutMap0 = MemoryUtil.Read<nint>(toneMapObject + 0x1A8); + nint lutMap0 = Get<nint>(toneMapObject, 0x1A8); if (lutMap0 != 0x0) { - WorldLUTs.DrawUI(lutMap0, toneMapObject, 0, width); + WorldLUTs.drawUI(lutMap0, toneMapObject, 0, width); } - nint lutMap1 = MemoryUtil.Read<nint>(toneMapObject + 0x1B0); + nint lutMap1 = Get<nint>(toneMapObject, 0x1B0); if (lutMap1 != 0x0) { - WorldLUTs.DrawUI(lutMap1, toneMapObject, 1, width); + WorldLUTs.drawUI(lutMap1, toneMapObject, 1, width); } } foreach (Parameter param in toneMapParameters) @@ -4866,16 +4925,16 @@ namespace WorldTuningTool } ImGui.PushItemWidth(width * 0.15f); - ImGui.Text($"FPS: {MemoryUtil.GetRef<float>(sMhMain!.Instance + 0x68)}"); - ImGui.Text($"Delta Time: {MemoryUtil.GetRef<float>(sMhMain!.Instance + 0x94)}"); + ImGui.Text($"FPS: {sMhMain!.Get<float>(0x68)}"); + ImGui.Text($"Delta Time: {sMhMain!.Get<float>(0x94)}"); // Locations taken from MHW-DTI-Dumps/wip_dump_15_20_00.h. - ImGui.InputFloat("Simulation FPS", ref MemoryUtil.GetRef<float>(sMhMain!.Instance + 0x58)); + ImGui.InputFloat("Simulation FPS", ref sMhMain!.GetRef<float>(0x58)); if (ImGui.BeginItemTooltip()) { ImGui.Text("This does not apply to jiggle physics."); ImGui.EndTooltip(); } - ImGui.InputFloat("Max FPS", ref MemoryUtil.GetRef<float>(sMhMain!.Instance + 0x5C)); + ImGui.InputFloat("Max FPS", ref sMhMain!.GetRef<float>(0x5C)); ImGui.PopItemWidth(); ImGui.Text($"sLightLinker: 0x{sLightLinker!.Instance:X}"); @@ -4911,7 +4970,7 @@ namespace WorldTuningTool private const string shaderPath = "nativePC/plugins/CSharp/Shaders"; private bool shadersLoadedOnce = false; - public unsafe void OnCreateShader(ShaderInfo *info) + public void OnCreateShader(ShaderInfo *info) { string hash = new string(info->DxbcHash); diff --git a/WorldTuningTool.csproj b/WorldTuningTool.csproj index 35aa9b3..f62728b 100644 --- a/WorldTuningTool.csproj +++ b/WorldTuningTool.csproj @@ -18,9 +18,6 @@ <Reference Include="SharpPluginLoader.Core"> <HintPath>..\SharpPluginLoader-fork\SharpPluginLoader.Core\bin\Release\net8.0\SharpPluginLoader.Core.dll</HintPath> </Reference> - <Reference Include="SharpPluginLoader.InternalCallGenerator"> - <HintPath>..\SharpPluginLoader-fork\SharpPluginLoader.InternalCallGenerator\bin\Release\netstandard2.0\SharpPluginLoader.InternalCallGenerator.dll</HintPath> - </Reference> </ItemGroup> </Project> diff --git a/WorldTuningTool.sln b/WorldTuningTool.sln index 6f9c96e..734f2b3 100644 --- a/WorldTuningTool.sln +++ b/WorldTuningTool.sln @@ -1,9 +1,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.12.35514.174 d17.12 +VisualStudioVersion = 17.12.35514.174 MinimumVisualStudioVersion = 10.0.40219.1 -Project("F2C49107-DDB9-415B-9A7F-DE6B9BA1E104") = "WorldTuningTool", "WorldTuningTool.csproj", "{E9DE1105-BC7A-4753-9181-E7DA03727E54}" +Project("{F2C49107-DDB9-415B-9A7F-DE6B9BA1E104}") = "WorldTuningTool", "WorldTuningTool.csproj", "{E9DE1105-BC7A-4753-9181-E7DA03727E54}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution |