summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2026-06-15 16:45:45 -0400
committerAndrew Opalach <andrew@akon.city> 2026-06-16 10:19:48 -0400
commit4e55d412c3fe79e62c396e209c509dff3ef3ee3c (patch)
treef6eea2dabb914da160bb3d4af5638a9e3586982d
parentd96a5827d9226e7e24e60300831837272f9c4cc9 (diff)
downloadWorldTuningTool-4e55d412c3fe79e62c396e209c509dff3ef3ee3c.tar.gz
WorldTuningTool-4e55d412c3fe79e62c396e209c509dff3ef3ee3c.tar.bz2
WorldTuningTool-4e55d412c3fe79e62c396e209c509dff3ef3ee3c.zip
Correctly display Shadow Map Size (aligned to 128)
Signed-off-by: Andrew Opalach <andrew@akon.city>
-rw-r--r--.gitignore4
-rwxr-xr-xPlugin.cs150
2 files changed, 104 insertions, 50 deletions
diff --git a/.gitignore b/.gitignore
index da66154..db4486f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,6 @@
+**/bin/
+**/obj/
+.vs/
+Archive/
Scripts/cmd_Decompiler.exe
Scripts/d3dcompiler_47.dll
diff --git a/Plugin.cs b/Plugin.cs
index 3c84d50..47dce7e 100755
--- a/Plugin.cs
+++ b/Plugin.cs
@@ -1,16 +1,18 @@
//#define ENABLE_ASSERTS
+//#define OVERSIZED_SHADOW_MAP
//#define SHADER_FEATURES
using System.Numerics;
using System.Globalization;
-using System.Runtime.InteropServices;
#if ENABLE_ASSERTS
using System.Diagnostics;
#endif
using ImGuiNET;
using SharpPluginLoader.Core;
+#if SHADER_FEATURES
using SharpPluginLoader.Core.Rendering;
+#endif
//using SharpPluginLoader.Core.Resources;
using SharpPluginLoader.Core.Configuration;
using SharpPluginLoader.Core.Memory;
@@ -111,6 +113,7 @@ namespace WorldTuningTool
FLAG,
BYTE,
INT,
+ ALIGNED_INT,
HEX,
COLOR,
FLOAT,
@@ -323,6 +326,7 @@ namespace WorldTuningTool
}
break;
case ParameterType.INT:
+ case ParameterType.ALIGNED_INT:
case ParameterType.HEX:
case ParameterType.COLOR:
MemoryUtil.GetRef<int>(lastAddr + offset) = valueInt;
@@ -397,8 +401,8 @@ namespace WorldTuningTool
{
valueV = oValueV;
valueInt = oValueInt;
- bValue = false;
maybeWriteCurrentValue();
+ bValue = false;
overrideValue = false;
}
}
@@ -480,6 +484,7 @@ namespace WorldTuningTool
break;
}
case ParameterType.INT:
+ case ParameterType.ALIGNED_INT:
case ParameterType.HEX:
case ParameterType.COLOR:
{
@@ -571,6 +576,44 @@ namespace WorldTuningTool
}
}
+ public void AdjustValue(ref Vector4 v4, ref int i1)
+ {
+ if (Type == ParameterType.SHADOW_RESOLUTION) // Hard limit.
+ {
+#if OVERSIZED_SHADOW_MAP
+ i1 = Math.Clamp(i1, 1, 6);
+#else
+ i1 = Math.Clamp(i1, 1, 5);
+#endif
+ }
+ else if (!ignoreMinMax)
+ {
+ switch (Type)
+ {
+ case ParameterType.BOOL:
+ case ParameterType.FLAG:
+ case ParameterType.BYTE:
+ case ParameterType.INT:
+ case ParameterType.HEX:
+ i1 = Math.Clamp(i1, min, max);
+ break;
+ case ParameterType.ALIGNED_INT:
+ i1 = Math.Clamp((i1 + (step - 1))&~(step - 1), min, max);
+ break;
+ case ParameterType.FLOAT:
+ case ParameterType.PATCH_FLOAT:
+ case ParameterType.VECTOR3:
+ case ParameterType.VECTOR4:
+ v4 = new Vector4(
+ Math.Clamp(v4.X, minf, maxf),
+ Math.Clamp(v4.Y, minf, maxf),
+ Math.Clamp(v4.Z, minf, maxf),
+ Math.Clamp(v4.W, minf, maxf));
+ break;
+ }
+ }
+ }
+
public bool DrawValue(ref Vector4 v4, ref int i1, float width, bool drawLabel)
{
bool valueChanged = false;
@@ -601,6 +644,7 @@ namespace WorldTuningTool
break;
}
case ParameterType.INT:
+ case ParameterType.ALIGNED_INT:
case ParameterType.HEX:
case ParameterType.SHADOW_RESOLUTION:
{
@@ -662,33 +706,7 @@ namespace WorldTuningTool
}
if (valueChanged)
{
- if (Type == ParameterType.SHADOW_RESOLUTION)
- {
- i1 = Math.Clamp(i1, 1, 5); // Hard limit.
- }
- else if (!ignoreMinMax)
- {
- switch (Type)
- {
- case ParameterType.BOOL:
- case ParameterType.FLAG:
- case ParameterType.BYTE:
- case ParameterType.INT:
- case ParameterType.HEX:
- i1 = Math.Clamp(i1, min, max);
- break;
- case ParameterType.FLOAT:
- case ParameterType.PATCH_FLOAT:
- case ParameterType.VECTOR3:
- case ParameterType.VECTOR4:
- v4 = new Vector4(
- Math.Clamp(v4.X, minf, maxf),
- Math.Clamp(v4.Y, minf, maxf),
- Math.Clamp(v4.Z, minf, maxf),
- Math.Clamp(v4.W, minf, maxf));
- break;
- }
- }
+ AdjustValue(ref v4, ref i1);
}
return valueChanged;
}
@@ -704,6 +722,7 @@ namespace WorldTuningTool
break;
case ParameterType.BYTE:
case ParameterType.INT:
+ case ParameterType.ALIGNED_INT:
case ParameterType.SHADOW_RESOLUTION:
ImGui.Text($"({name}: {i1})");
break;
@@ -985,6 +1004,7 @@ namespace WorldTuningTool
return BooleanToString(sValueInt != 0);
case ParameterType.BYTE:
case ParameterType.INT:
+ case ParameterType.ALIGNED_INT:
case ParameterType.SHADOW_RESOLUTION:
return Int32ToString(sValueInt);
case ParameterType.HEX:
@@ -1015,6 +1035,7 @@ namespace WorldTuningTool
break;
case ParameterType.BYTE:
case ParameterType.INT:
+ case ParameterType.ALIGNED_INT:
case ParameterType.SHADOW_RESOLUTION:
valueInt = StringToInt32(value);
break;
@@ -1042,6 +1063,7 @@ namespace WorldTuningTool
{
Log.Warn($"Value of '{Name}' override too large.");
}
+ Param.AdjustValue(ref valueV, ref valueInt);
Save();
}
}
@@ -1053,7 +1075,6 @@ namespace WorldTuningTool
private int sValueInt = 0;
public Override() { }
-
public Override(Parameter param, Vector4 v4, int i1)
{
Param = param;
@@ -1101,7 +1122,7 @@ namespace WorldTuningTool
ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true);
}
ImGui.PushItemWidth(width * 0.475f);
- if (ImGui.BeginCombo("##Parameters", (Param != null) ? Param.Name : ""))
+ if (ImGui.BeginCombo("##Parameters", (Param != null) ? Param.Name : "", ImGuiComboFlags.HeightLarge))
{
if (currentOverrides != null)
{
@@ -1180,9 +1201,9 @@ namespace WorldTuningTool
}
}
(Vector4 v4, int i1) = Param.GetValue();
- bool valueDiffers = (v4, i1) != (valueV, valueInt);
- // @TODO: Not sValue and valueDiffers should be seperated/more clear.
- if ((valueV, valueInt) != (sValueV, sValueInt) || (isSet && valueDiffers && !Param.PendingUpdate()))
+ bool valueDiffers = (valueV, valueInt) != (v4, i1);
+ bool valueNotSaved = (valueV, valueInt) != (sValueV, sValueInt);
+ if ((!Param.PendingUpdate() && valueDiffers && isSet) || valueNotSaved)
{
ImGui.SameLine();
if (ImGui.Button("⇄"))
@@ -1199,6 +1220,11 @@ namespace WorldTuningTool
{
ImGui.PopStyleVar();
}
+ if (valueNotSaved)
+ {
+ ImGui.SameLine();
+ Param.DrawReferenceValue("Saved", sValueV, sValueInt);
+ }
if (Param.PendingUpdate())
{
ImGui.SameLine();
@@ -1366,7 +1392,7 @@ namespace WorldTuningTool
newFrameParameter<bool>("Sunlight Is Primary", 0x1D, ParameterType.BOOL),
newFrameParameter<bool>("Do Volumetric", 0x1F, ParameterType.BOOL),
newFrameParameter<bool>("Shadow Cast", 0x23, ParameterType.BOOL),
- newFrameParameter<int>("Shadow Map Size", 0x30, ParameterType.INT), // Aligned to 128.
+ newFrameParameter<int>("Shadow Map Size", 0x30, ParameterType.ALIGNED_INT, pMinStep(0, 128)), // 0 = 64x64 no multiplier @TODO: Verify in the code.
newFrameParameter<float>("Shadow Near Clip Distance", 0x28, ParameterType.FLOAT),
newFrameParameter<int>("Shadow Cascade Mode", 0x174, ParameterType.INT, pMinMaxStep(0, 3, 1)),
newFrameParameter<float>("Shadow Cascade 2Way Bias", 0x17C, ParameterType.FLOAT),
@@ -1547,6 +1573,9 @@ namespace WorldTuningTool
private static Patch shadowRes1_3x;
private static Patch shadowRes1_4x;
private static Patch shadowRes1_5x;
+#if OVERSIZED_SHADOW_MAP
+ private static Patch shadowRes1_6x;
+#endif
private static Patch shadowRes1_1;
private static Patch shadowRes1_2;
private static Patch shadowRes1_3;
@@ -1583,6 +1612,11 @@ namespace WorldTuningTool
case 5:
shadowRes1_5x.Disable();
break;
+#if OVERSIZED_SHADOW_MAP
+ case 6:
+ shadowRes1_6x.Disable();
+ break;
+#endif
}
switch (multiplier)
{
@@ -1596,9 +1630,13 @@ namespace WorldTuningTool
shadowRes1_4x.Enable();
break;
case 5:
- case 6:
shadowRes1_5x.Enable();
break;
+#if OVERSIZED_SHADOW_MAP
+ case 6:
+ shadowRes1_6x.Enable();
+ break;
+#endif
}
currentShadowResMultiplier = multiplier;
setShadowQuality.Invoke(MemoryUtil.Read<int>(sMhScene!.Instance + 0x5530) + 1);
@@ -1624,6 +1662,11 @@ namespace WorldTuningTool
case 5:
shadowRes1_5x.Disable();
break;
+#if OVERSIZED_SHADOW_MAP
+ case 6:
+ shadowRes1_6x.Disable();
+ break;
+#endif
}
shadowRes1_1.Disable();
shadowRes1_2.Disable();
@@ -1720,7 +1763,7 @@ namespace WorldTuningTool
newFrameParameter<float>("Min Roughness", 0x58C, ParameterType.FLOAT, pStep(0.0025f)),
newParameter<bool>("Do Volumetric", 0x590, ParameterType.BOOL),
newFlag<bool>("Shadow Cast", 0x138, ParameterType.FLAG, (1 << 23)),
- newParameter<int>("Shadow Map Size", 0x1B8, ParameterType.INT), // Aligned to 128.
+ newParameter<int>("Shadow Map Size", 0x1B8, ParameterType.ALIGNED_INT, pMinStep(0, 128)),
newParameter<float>("Shadow Near Clip Distance", 0x1B4, ParameterType.FLOAT),
newFrameParameter<float>("Shadow Depth Bias", 0x57C, ParameterType.FLOAT, pStep(0.00001f)),
newFrameParameter<float>("Shadow Sloped Depth Bias", 0x580, ParameterType.FLOAT, pStep(0.00001f)),
@@ -1888,19 +1931,26 @@ 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);
- // @TODO: Allocate our own memory for this?
- Assert(MemoryUtil.Read<float>(0x142EE1A90) == 2.0f);
- Assert(MemoryUtil.Read<float>(0x142E4FE5C) == 3.0f);
- Assert(MemoryUtil.Read<float>(0x142C4A2F0) == 4.0f);
- Assert(MemoryUtil.Read<float>(0x142F0F260) == 5.0f);
- shadowRes1_2x = new Patch(addr + 0x8, [0x04, 0x1B, 0xAA, 0x02]); // 2.0.
- shadowRes1_3x = new Patch(addr + 0x8, [0xD0, 0xFE, 0xA0, 0x02]); // 3.0.
- shadowRes1_4x = new Patch(addr + 0x8, [0x64, 0xA3, 0x80, 0x02]); // 4.0.
- shadowRes1_5x = new Patch(addr + 0x8, [0xD4, 0xF2, 0xAC, 0x02]); // 5.0.
+ 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.
+ 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]);
+ shadowRes1_5x = new Patch(addr + 0x8, [0xC4, 0xFD, 0xAD, 0x02]);
+#if OVERSIZED_SHADOW_MAP
+ shadowRes1_6x = new Patch(addr + 0x8, [0xA0, 0x22, 0xDD, 0x02]);
+#endif
shadowRes1_1 = new Patch(addr + 0x65, [0x17]); // Always set "Value is not 1.0" flag.
shadowRes1_2 = new Patch(addr + 0x68, [0x59]); // movss -> mulss.
shadowRes1_3 = new Patch(addr + 0x77, [0x59]); // movss -> mulss.
+#if OVERSIZED_SHADOW_MAP
+ shadowRes1_4 = new Patch(new nint(0x142288AAA) + 0x4, [0x7A, 0x97, 0xF8, 0x00]); // Limit 4.0 -> 6.0.
+#else
shadowRes1_4 = new Patch(new nint(0x142288AAA) + 0x4, [0x9E]); // Limit 4.0 -> 5.0.
+#endif
// shadowRes2/3 control the detail of the infrequently updated fallback shadows (Broad Area).
addr = PatternScanner.FindFirst(Pattern.FromString("83 FA FF 74 06 89 91 1C 55 00 00 8B 91 30 55 00 00 83 FA FF 7F 06 8B 91 1C 55 00 00 85 D2 74 4B 83 EA 01 74 3B 83 EA 01 74 2B 83 EA 01 74 1B 83 FA 01 74 0B C7 81 20 55 00 00 01 00 00 00 C3 C7 81 20 55 00 00 00 10 00 00"));
@@ -2585,7 +2635,7 @@ namespace WorldTuningTool
if (!superseded)
{
ovR.Unset();
- if (globalOverrides != null && ovR.Param != null)
+ if (ovR.Param != null && globalOverrides != null)
{
setIfOverridesContainsParam(globalOverrides, ovR.Param);
}
@@ -2630,7 +2680,7 @@ namespace WorldTuningTool
ImGui.Text($"Current Stage: {Config.StageToString(currentStage)}");
ImGui.PushItemWidth(width * 0.35f);
- if (ImGui.BeginCombo("##Stage", Config.StageToString(selectedStage)))
+ if (ImGui.BeginCombo("##Stage", Config.StageToString(selectedStage), ImGuiComboFlags.HeightLarge))
{
foreach (Stage area in Enum.GetValues(typeof(Stage)))
{
@@ -3071,7 +3121,7 @@ namespace WorldTuningTool
{
Light light = ourLights[i];
ImGui.PushID(i);
- ImGui.Text($"Type: {light.Type}, Address: {light.Object:X}");
+ ImGui.Text($"Type: {light.Type}, Address: 0x{light.Object:X}");
foreach (Parameter param in light.Parameters)
{
param.Draw(width, true);
@@ -3107,7 +3157,7 @@ namespace WorldTuningTool
{
Light light = sceneLights[i];
ImGui.PushID(i);
- ImGui.Text($"Type: {light.Type}, Address: {light.Object:X}");
+ ImGui.Text($"Type: {light.Type}, Address: 0x{light.Object:X}");
foreach (Parameter param in light.Parameters)
{
param.Draw(width);