diff options
| -rw-r--r--[-rwxr-xr-x] | Config.cs | 17 | ||||
| -rw-r--r-- | LUT.cs | 61 | ||||
| -rw-r--r-- | Lights.cs | 264 | ||||
| -rw-r--r--[-rwxr-xr-x] | Plugin.cs | 478 |
4 files changed, 410 insertions, 410 deletions
diff --git a/Config.cs b/Config.cs index 3c14fa4..d456269 100755..100644 --- a/Config.cs +++ b/Config.cs @@ -1,8 +1,12 @@ -using SharpPluginLoader.Core.Configuration;
+//#define SHADER_FEATURES
+
+using SharpPluginLoader.Core.Configuration;
using SharpPluginLoader.Core;
namespace WorldTuningTool
{
+ using static Plugin;
+
public enum StageExt : uint
{
Global = 0,
@@ -45,7 +49,7 @@ namespace WorldTuningTool SelianaRoom = 506
}
- internal class Config : IConfig
+ public class Config : IConfig
{
public String Name => "WorldTuningTool";
public String Version => "0.9.4";
@@ -136,6 +140,7 @@ namespace WorldTuningTool public static readonly StageExt[] OrderedStages =
{
+ StageExt.Global,
StageExt.Astera,
StageExt.AsteraHub,
StageExt.ResearchBase,
@@ -177,7 +182,9 @@ namespace WorldTuningTool public struct PatchConfig
{
+#if SHADER_FEATURES
public bool FullResolutionSSLR { get; set; } = false;
+#endif
public bool FullResolutionVolumeBlur { get; set; } = false;
public bool HigherThanHighestVolumeRendering { get; set; } = false;
public bool DisableLODLimits { get; set; } = false;
@@ -188,9 +195,9 @@ namespace WorldTuningTool public PatchConfig Patches { get; set; } = new PatchConfig();
- public Dictionary<string, List<Plugin.Override>> Globals { get; set; } = new Dictionary<string, List<Plugin.Override>>();
+ public Dictionary<string, List<Override>> Globals { get; set; } = new Dictionary<string, List<Override>>();
public string SelectedGlobal { get; set; } = "";
- public Dictionary<StageExt, List<Plugin.Override>> Overrides { get; set; } = new Dictionary<StageExt, List<Plugin.Override>>();
- public Dictionary<string, List<Plugin.Override>> Sets { get; set; } = new Dictionary<string, List<Plugin.Override>>();
+ public Dictionary<StageExt, List<Override>> Overrides { get; set; } = new Dictionary<StageExt, List<Override>>();
+ public Dictionary<string, List<Override>> Sets { get; set; } = new Dictionary<string, List<Override>>();
}
}
@@ -11,11 +11,13 @@ using SharpPluginLoader.Core.IO; namespace WorldTuningTool { - public class WorldLUTs + using static Plugin; + + public class LUT { private const string addPath = "nativePC/plugins/CSharp/LUT"; - public WorldLUTs() { } + public LUT() { } // https://github.com/AsteriskAmpersand/CrappyLUTStudio--CLUTS-/blob/5af10daaa5f295b106cc5db09530a6fe5a4320d4/LUT.py#L35 private byte[]? parseWorldLUT(BinaryReader reader) @@ -57,7 +59,7 @@ namespace WorldTuningTool { string? line; Vector3[]? parsed = null; - int dim = 0, idx = 0; + int dim = 0, i = 0; while ((line = reader.ReadLine()) != null) { if (line.StartsWith("LUT_3D_SIZE")) @@ -66,18 +68,8 @@ namespace WorldTuningTool { dim = Convert.ToInt32(line.Split(' ').Last()); } - catch (FormatException) - { - return null; - } - catch (OverflowException) - { - return null; - } - if (dim != 32) - { - return null; - } + catch (Exception) { return null; } + if (dim != 32) return null; parsed = new Vector3[dim * dim * dim]; while ((line = reader.ReadLine()) != null) { @@ -87,26 +79,15 @@ namespace WorldTuningTool break; } } - if (line == null) - { - break; - } + if (line == null) break; } if (parsed != null) { try { - parsed[idx] = Plugin.StringToVector3(line, ' '); - } - catch (FormatException) - { - return null; - } - catch (OverflowException) - { - return null; + parsed[i++] = StringToVector3(line, ' '); } - idx++; + catch (Exception) { return null; } } } if (parsed == null) @@ -116,24 +97,24 @@ namespace WorldTuningTool const int lutDataSize = 32 * 32 * 32 * 8; byte[] data = new byte[lutDataSize]; float scale = MathF.Pow(2, 14) - 1; - for (idx = 0; idx < lutDataSize; idx+=8) + for (i = 0; i < lutDataSize; i += 8) { - Vector3 v = parsed[idx/8]; + Vector3 v = parsed[i / 8]; ushort normX = (ushort)Math.Round(v.X * scale); ushort normY = (ushort)Math.Round(v.Y * scale); ushort normZ = (ushort)Math.Round(v.Z * scale); byte[] bytes = BitConverter.GetBytes(normX); - data[idx] = bytes[0]; - data[idx + 1] = bytes[1]; + data[i] = bytes[0]; + data[i + 1] = bytes[1]; bytes = BitConverter.GetBytes(normY); - data[idx + 2] = bytes[0]; - data[idx + 3] = bytes[1]; + data[i + 2] = bytes[0]; + data[i + 3] = bytes[1]; bytes = BitConverter.GetBytes(normZ); - data[idx + 4] = bytes[0]; - data[idx + 5] = bytes[1]; + data[i + 4] = bytes[0]; + data[i + 5] = bytes[1]; bytes = BitConverter.GetBytes(0x2B88); // Alpha constant. - data[idx + 6] = bytes[0]; - data[idx + 7] = bytes[1]; + data[i + 6] = bytes[0]; + data[i + 7] = bytes[1]; } return data; } @@ -189,7 +170,7 @@ namespace WorldTuningTool private static bool[] selectionStarted = [ false, false ]; private static bool[] selectedInvalid = [ false, false ]; - public void DrawLUT(nint texture, nint lightingObject, int i, float width) + public void DrawUI(nint texture, nint lightingObject, int i, float width) { ImGui.PushID(i); string lutPath = Marshal.PtrToStringAnsi(texture + 0xC)!; diff --git a/Lights.cs b/Lights.cs new file mode 100644 index 0000000..0eed477 --- /dev/null +++ b/Lights.cs @@ -0,0 +1,264 @@ +using System.Numerics; + +using ImGuiNET; +using SharpPluginLoader.Core; +using SharpPluginLoader.Core.Memory; +using SharpPluginLoader.Core.Entities; + +namespace WorldTuningTool +{ + using static Plugin; + + public class Lights + { + public Lights() { } + + private class Light + { + public nint Object; + public int Type; + public Parameter[] Parameters = { + newParameter<int>("Group", 0x13C, ParameterType.INT, pMinMaxStep(1, 255, 1)), // 1 = World, (1 << 1) = Player/Palico, (1 << 2) = NPCs + newFrameParameter<float>("Position", 0x5A0, ParameterType.VECTOR3, pStep(0.15f)), + newFrameParameter<int>("Color", 0x140, ParameterType.COLOR), + newFrameParameter<float>("Intensity", 0x8A8, ParameterType.FLOAT), + newFrameParameter<float>("Radius", 0x6A0, ParameterType.FLOAT, pStep(0.25f)), + newFrameParameter<float>("Effective Radius", 0x588, ParameterType.FLOAT, pStep(0.25f)), + 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.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)), + newFrameParameter<float>("Shadow Max Depth Bias", 0x584, ParameterType.FLOAT, pStep(0.00001f)), + }; + + public Light(nint lightObject, int type) + { + Object = lightObject; + Type = type; + foreach (Parameter param in Parameters) + { + param.Update(lightObject); + } + } + + public Light(nint lightObject, int type, Vector3 pos) + { + Object = lightObject; + Type = type; + foreach (Parameter param in Parameters) + { + param.OverrideOn(false); + } + Parameters[0].SetOverrideValue(default, 255); + Parameters[1].SetOverrideValue(new Vector4(pos.X, pos.Y, pos.Z, 0.0f), 0); + Parameters[3].SetOverrideValue(new Vector4(10.0f, 0.0f, 0.0f, 0.0f), 0); + foreach (Parameter param in Parameters) + { + param.Update(lightObject); + } + } + } + + // Point Light (2): + // Create1: 0x141F875A0 () + // Create2: 0x141F87CD0 (nint) + // Destroy: 0x141F87D90 (nint, int) + // + // Spot Light (3): + // Create1: 0x141F8AE80 () + // Create2: 0x141F8B2D0 (nint) + // Destroy: 0x141F8B390 (nint, int) + // + // Hemi Sphere Light (4): + // Create1: 0x141F84840 () + // Create2: 0x141F84990 (nint) + // Destroy: 0x141F84A40 (nint, int) + // + // Wrapper? (8): + // Create1: 0x141F816C0 () + // Create2: 0x141F81800 () + // Destroy: 0x141F81940 (nint, int) + + private int requestLightType = 2; + private NativeFunction<int, nint> createLight; + //private bool interceptCreateLight = false; + private List<Light> ourLights = new List<Light>(); + //private List<Light> sceneLights = new List<Light>(); + private NativeAction<nint, int, nint, int> addToScene; + private NativeAction<nint> removeFromScene; + //private delegate nint CreateLightObject(int type); + //private Hook<CreateLightObject>? createLightObject; + private delegate void DestroyLightObject(nint lightObject, int unknownInt); + private Hook<DestroyLightObject>? destroyLightObject; + private delegate void UpdateLights(nint lightObject); + private Hook<UpdateLights>? updateLights; + + public void Initialize() + { + createLight = new NativeFunction<int, nint>(0x1418A3EF0); + //createLightObject = Hook.Create<CreateLightObject>(0x1418A3EF0, CreateLightObjectHook); + destroyLightObject = Hook.Create<DestroyLightObject>(0x141F87D90, DestroyLightObjectHook); + addToScene = new NativeAction<nint, int, nint, int>(0x142219070); + removeFromScene = new NativeAction<nint>(0x142228F10); + updateLights = Hook.Create<UpdateLights>(0x141F88F30, UpdateLightsHook); + } + + /* + private nint CreateLightObjectHook(int type) + { + nint lightObject = createLightObject!.Original(type); + if (interceptCreateLight) + { + interceptCreateLight = false; + } + //else if (type == 2) + else + { + sceneLights.Add(new Light(lightObject, type)); + } + return lightObject; + } + */ + + private void UpdateLightsHook(nint lightObject) + { + Light? light = null; + /* + for (int i = 0; i < sceneLights.Count; i++) + { + if (lightObject == sceneLights[i].Object) + { + light = sceneLights[i]; + break; + } + } + */ + if (light == null) + { + for (int i = 0; i < ourLights.Count; i++) + { + if (lightObject == ourLights[i].Object) + { + light = ourLights[i]; + break; + } + } + } + updateLights!.Original(lightObject); + if (light != null) + { + foreach (Parameter param in light.Parameters) + { + param.Update(lightObject); + } + } + } + + private void DestroyLightObjectHook(nint lightObject, int unknownInt) + { + /* + for (int i = 0; i < sceneLights.Count; i++) + { + if (lightObject == sceneLights[i].Object) + { + sceneLights.RemoveAt(i); + break; + } + } + */ + for (int i = 0; i < ourLights.Count; i++) + { + if (lightObject == ourLights[i].Object) + { + ourLights.RemoveAt(i); + break; + } + } + destroyLightObject!.Original(lightObject, unknownInt); + } + + public unsafe void DrawUI(float width) + { + /* + ImGui.NextItemWidth(width * 0.25f); + ImGui.InputInt("Type", ref requestLightType, 1); + ImGui.SameLine(); + */ + if (ImGui.Button("New")) + { + //interceptCreateLight = true; + nint lightObject = createLight.Invoke(requestLightType); + Vector3 pos = default; + Player? player = Player.MainPlayer; + if (player != null) + { + pos = player.Position; + pos.Y += 30.0f; + } + ourLights.Add(new Light(lightObject, requestLightType, pos)); + // mov byte ptr[rsp+20],00 unaccounted for, hopefully it never matters. + addToScene.Invoke(MemoryUtil.Read<nint>(0x1451238C8), 0x16, lightObject, 0x0); + } + ImGui.Separator(); + ImGui.PushID("Ours"); + for (int i = 0; i < ourLights.Count; i++) + { + Light light = ourLights[i]; + ImGui.PushID(i); + ImGui.Text($"Type: {light.Type}, Address: 0x{light.Object:X}"); + foreach (Parameter param in light.Parameters) + { + param.Draw(width, true); + } + /* + if (ImGui.CollapsingHeader("Random Move")) + { + foreach (Parameter param in light.RandomMoveParameters) + { + param.Draw(width, true); + } + } + */ + if (ImGui.Button("Remove")) + { + /* + nint vTable = MemoryUtil.Read<nint>(lightObject); + NativeAction<nint, int> freeLight = new NativeAction<nint, int>(MemoryUtil.Read<nint>(vTable)); + freeLight.Invoke(lightObject, 1); + */ + // removeFromScene triggers destructor. + removeFromScene.Invoke(light.Object); + } + ImGui.PopID(); + ImGui.Separator(); + } + ImGui.PopID(); + ImGui.PushID("Scene"); + /* + if (ImGui.CollapsingHeader("Scene Lights")) + { + for (int i = 0; i < sceneLights.Count; i++) + { + Light light = sceneLights[i]; + ImGui.PushID(i); + ImGui.Text($"Type: {light.Type}, Address: 0x{light.Object:X}"); + foreach (Parameter param in light.Parameters) + { + param.Draw(width); + } + if (ImGui.Button("Remove")) + { + removeFromScene.Invoke(light.Object); + } + ImGui.PopID(); + ImGui.Separator(); + } + } + */ + ImGui.PopID(); + } + } +} diff --git a/Plugin.cs b/Plugin.cs index f05fbee..2241a88 100755..100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -1,4 +1,4 @@ -//#define ENABLE_ASSERTS
+#define ENABLE_ASSERTS
//#define OVERSIZED_SHADOW_MAP
//#define SHADER_FEATURES
//#define RESOURCE_ADJUSTMENT
@@ -14,7 +14,6 @@ using ImGuiNET; using SharpPluginLoader.Core;
using SharpPluginLoader.Core.Configuration;
using SharpPluginLoader.Core.Memory;
-using SharpPluginLoader.Core.Entities;
#if SHADER_FEATURES
using SharpPluginLoader.Core.Rendering;
#endif
@@ -31,33 +30,33 @@ using SharpPluginLoader.Core.Resources; // - Lights refactor.
// - Descriptions.
// - float format.
-// - Min/Max.
// - Lights iterop.
// - SPL Patches:
// - No crash on empty config.
// - Style change
-// - Create light hook.
-// - Shadow distance retuning.
-// - Weird shadow area in Rotten Vale.
// - Hotload nukes config?
//
// Areas that need Shadow Distance retuning:
-// - Exit of central camp in Horfrost Reach.
-// - Sporepuff area in The Ancient Forest.
-// - Wildspire Waste entrence to enclosed area past the waterfall.
-// - The Rotten Vale jump out of Southeast Camp. Wall on the opposite side slightly to the left.
-// - Special Arena.
-// - Elder's Recess Lavasioth area.
-// - Hoarfrost pit area with wedge beetles.
+// - Exit of central camp in Horfrost Reach.
+// - Sporepuff area in The Ancient Forest.
+// - Wildspire Waste entrence to enclosed area past the waterfall.
+// - The Rotten Vale jump out of Southeast Camp. Wall on the opposite side slightly to the left.
+// - Rotten vale lower area.
+// - Special Arena.
+// - Elder's Recess Lavasioth area.
+// - Hoarfrost pit area with wedge beetles.
//
// Known issues to think about:
-// - Hair clipping while looking down.
+// - Hair clipping when character looks down.
+// - Vangis headband.
// - Volume rendering can look really bad with multiple overlapped sources(?) (Guding lands vines).
// - Screen space reflections often look bad.
-// - Facial contact shadows incorrectly move based on camera position.
+// - Facial contact shadows unnaturally move based on camera position.
namespace WorldTuningTool
{
+ using static Config;
+
public unsafe class Plugin : IPlugin
{
public string Name => "World Tuning Tool";
@@ -101,11 +100,8 @@ namespace WorldTuningTool private static bool StringToBoolean(string s) { return Convert.ToBoolean(s, CultureInfo.InvariantCulture); }
private static int StringToInt32(string s, int fromBase = 10)
{
- if (fromBase == 10) {
- return Convert.ToInt32(s, CultureInfo.InvariantCulture);
- } else {
- return Convert.ToInt32(s, fromBase);
- }
+ if (fromBase == 10) return Convert.ToInt32(s, CultureInfo.InvariantCulture);
+ return Convert.ToInt32(s, fromBase);
}
private static string SingleToString(float f, string? format = null) { return f.ToString(format, CultureInfo.InvariantCulture); }
private static string BooleanToString(bool b) { return b.ToString(CultureInfo.InvariantCulture); }
@@ -113,16 +109,10 @@ namespace WorldTuningTool public static Vector3 StringToVector3(string s, char delim = ',')
{
- if (String.IsNullOrEmpty(s))
- {
- throw new FormatException();
- }
- string[] vs = s.Split(delim).Select(v => v.Trim()).ToArray();
- if (vs.Length != 3)
- {
- throw new FormatException();
- }
- return new Vector3(StringToSingle(vs[0]), StringToSingle(vs[1]), StringToSingle(vs[2]));
+ if (String.IsNullOrEmpty(s)) throw new FormatException();
+ string[] sp = s.Split(delim).Select(v => v.Trim()).ToArray();
+ if (sp.Length != 3) throw new FormatException();
+ return new Vector3(StringToSingle(sp[0]), StringToSingle(sp[1]), StringToSingle(sp[2]));
}
private static string Vector3ToString(Vector3 v)
@@ -146,14 +136,14 @@ namespace WorldTuningTool SHADOW_RESOLUTION
}
- static IPlugin? Instance = null;
+ private static IPlugin? Instance = null;
- static Config getConfig()
+ private static Config getConfig()
{
return ConfigManager.GetConfig<Config>(Instance!);
}
- static void reorderConfig(Config config, List<Override> overrides)
+ private static void rebuildConfig(Config config, List<Override> overrides)
{
List<Override> selectedGlobals = config.Globals[selectedGlobal];
selectedGlobals.Clear();
@@ -167,7 +157,7 @@ namespace WorldTuningTool private const int SelectedNotSaved = 1;
private const int SetNotSaved = (1 << 1);
- static void saveConfig(Config config)
+ private static void saveConfig(Config config)
{
List<Override> tmpOverrides = config.Overrides[globalStage];
config.Overrides.Remove(globalStage);
@@ -249,10 +239,8 @@ namespace WorldTuningTool if (!superseded && param != null)
{
// If Global is selected, check if superseded by a currentStage override.
- superseded |= globalOverrides == null && stageOverrides != null &&
- overridesContainsParam(stageOverrides, param);
- // Any other selectedStage override is either inactive or could only be superseded by a
- // set or external override.
+ superseded |= globalOverrides == null && stageOverrides != null && overridesContainsParam(stageOverrides, param);
+ // Any other selectedStage override is either inactive or could only be superseded by a set or external override.
superseded |= selectedSet != "" && overridesContainsParam(config.Sets[selectedSet], param);
superseded |= overridesContainsParam(externalOverrides.Values, param);
}
@@ -483,7 +471,7 @@ namespace WorldTuningTool overrideForStage = false;
}
- public void OverrideValue(Vector4 v4, int i1)
+ public void SetOverrideValue(Vector4 v4, int i1)
{
if (queuedOverride)
{
@@ -818,6 +806,31 @@ namespace WorldTuningTool ImGui.PopStyleVar();
}
+ public string SetByLine(Config config, List<Override>? stageOverrides, List<Override>? globalOverrides, bool forSet, bool allowGlobal)
+ {
+ // Reverse order of selectedOverrideSuperseded().
+ if (overridesContainsParam(externalOverrides.Values, this))
+ {
+ return "Set by 'External'";
+ }
+ Assert(!forSet);
+ if (selectedSet != "" && overridesContainsParam(config.Sets[selectedSet], this))
+ {
+ return $"Set by '{selectedSet}'";
+ }
+ if ((allowGlobal || globalOverrides == null) && stageOverrides != null && overridesContainsParam(stageOverrides, this))
+ {
+ return $"Set by '{StageToString(currentStage)}'";
+ }
+ if (allowGlobal)
+ {
+ return "Set by \'Global\'";
+ }
+ // Superseded because inactive.
+ Assert(globalOverrides != null && selectedStage != currentStage);
+ return "";
+ }
+
public void Draw(float width, bool assumeOverride = false)
{
Draw(ref valueV, ref valueInt, width, assumeOverride);
@@ -854,11 +867,18 @@ namespace WorldTuningTool {
if (overrideForStage)
{
- ImGui.Text("Contained in Config");
+ Config config = getConfig();
+ List<Override>? globalOverrides = config.Overrides[globalStage];
+ List<Override>? stageOverrides = maybeGetStageOverrides(config);
+ ImGui.Text(SetByLine(config, stageOverrides, globalOverrides, false, true));
+ }
+ else if (overrideValue)
+ {
+ ImGui.Text("Set");
}
else
{
- ImGui.Text("Override");
+ ImGui.Text("Set override");
}
ImGui.EndTooltip();
}
@@ -977,13 +997,13 @@ namespace WorldTuningTool selectedOverrides.Add(ov);
if (selectedStage == globalStage)
{
- reorderConfig(config, selectedOverrides);
+ rebuildConfig(config, selectedOverrides);
}
configState |= SelectedNotSaved;
}
if (ImGui.BeginItemTooltip())
{
- ImGui.Text($"Add to '{Config.StageToString(selectedStage)}'");
+ ImGui.Text($"Add to '{StageToString(selectedStage)}'");
ImGui.EndTooltip();
}
}
@@ -1186,7 +1206,7 @@ namespace WorldTuningTool if (Param != null)
{
Param.OverrideOn(true);
- Param.OverrideValue(valueV, valueInt);
+ Param.SetOverrideValue(valueV, valueInt);
}
}
@@ -1203,8 +1223,7 @@ namespace WorldTuningTool public void Draw(bool forSet, List<Override>? currentOverrides, List<Override>? stageOverrides, List<Override>? globalOverrides, bool superseded, float width)
{
Assert(!superseded == isSet);
- bool fade = superseded;
- if (fade)
+ if (superseded)
{
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
}
@@ -1213,7 +1232,13 @@ namespace WorldTuningTool ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true);
}
ImGui.PushItemWidth(width * 0.475f);
- if (ImGui.BeginCombo("##Parameters", (Param != null) ? Param.Name : "", ImGuiComboFlags.HeightLarge))
+ bool beginCombo = ImGui.BeginCombo("##Parameters", (Param != null) ? Param.Name : "", ImGuiComboFlags.HeightLarge);
+ if (superseded)
+ {
+ ImGui.PopStyleVar();
+ }
+ Config config = getConfig();
+ if (beginCombo)
{
if (currentOverrides != null)
{
@@ -1268,7 +1293,6 @@ namespace WorldTuningTool }
else
{
- Config config = getConfig();
superseded = selectedOverrideSuperseded(config, globalOverrides, stageOverrides, Param);
if (!superseded)
{
@@ -1296,11 +1320,15 @@ namespace WorldTuningTool if (Param != null)
{
ImGui.SameLine();
+ if (superseded)
+ {
+ ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
+ }
if (Param.DrawValue(ref valueV, ref valueInt, width, false))
{
if (!superseded)
{
- Param.OverrideValue(valueV, valueInt);
+ Param.SetOverrideValue(valueV, valueInt);
}
}
(Vector4 v4, int i1) = Param.GetValue();
@@ -1315,11 +1343,11 @@ namespace WorldTuningTool valueInt = sValueInt;
if (!superseded)
{
- Param.OverrideValue(valueV, valueInt);
+ Param.SetOverrideValue(valueV, valueInt);
}
}
}
- if (fade)
+ if (superseded)
{
ImGui.PopStyleVar();
}
@@ -1343,47 +1371,15 @@ namespace WorldTuningTool else if (valueDiffers)
{
ImGui.SameLine();
- if (!superseded)
+ string byLine = "";
+ if (superseded)
{
- Param.DrawReferenceValue("Current", v4, i1);
- }
- else
- {
- if (forSet)
- {
- Assert(overridesContainsParam(externalOverrides.Values, Param));
- Param.DrawReferenceValue("Set by 'External'", v4, i1);
- }
- else
- {
- Config config = getConfig();
- // Reverse order of selectedOverrideSuperseded().
- if (overridesContainsParam(externalOverrides.Values, Param))
- {
- Param.DrawReferenceValue("Set by 'External'", v4, i1);
- }
- else if (selectedSet != "" && overridesContainsParam(config.Sets[selectedSet], Param))
- {
- Param.DrawReferenceValue($"Set by '{selectedSet}'", v4, i1);
- }
- else if (globalOverrides == null && stageOverrides != null &&
- overridesContainsParam(stageOverrides, Param))
- {
- Param.DrawReferenceValue($"Set by '{Config.StageToString(currentStage)}'", v4, i1);
- }
- else // Superseded because inactive.
- {
- Assert(globalOverrides != null && selectedStage != currentStage);
- Param.DrawReferenceValue("Current", v4, i1);
- }
- }
+ // Global is the lowest priority so "Set by 'Global'" never applies here.
+ byLine = Param.SetByLine(config, stageOverrides, globalOverrides, forSet, false);
}
+ Param.DrawReferenceValue((byLine == "") ? "Current" : byLine, v4, i1);
}
}
- else if (fade)
- {
- ImGui.PopStyleVar();
- }
}
}
@@ -1414,6 +1410,8 @@ namespace WorldTuningTool private static MtObject? sMhMain = null;
private static MtObject? sMhRender = null;
+ private static Lights lights = new Lights();
+
private static Parameter hqMode = newParameter<bool>("HQ Mode", 0xE9A3, ParameterType.BOOL);
private static Parameter[] lodParameters = {
@@ -1487,7 +1485,7 @@ namespace WorldTuningTool newParameter<float>("Capsule Light Dir XZY", 0xE548, ParameterType.VECTOR3),
newParameterView<float>("Capsule Light W Dir", 0xE560, ParameterType.VECTOR3),
newParameter<float>("Capsule Light Angle", 0xE5B0, ParameterType.FLOAT),
- newParameter<float>("Capsule AO Intensity", 0xE5B8, ParameterType.FLOAT)
+ newParameter<float>("Capsule AO Intensity", 0xE5B8, ParameterType.FLOAT, pStep(0.00025f))
};
private delegate void UpdateSSAOParams(nint stackOffset);
@@ -1595,7 +1593,7 @@ namespace WorldTuningTool private delegate void UpdateLightingParameters(nint stackOffset, nint lightingObjectInternal);
private Hook<UpdateLightingParameters>? updateLightingParams;
private Hook<UpdateLightingParameters>? updateLutBlend;
- private static WorldLUTs luts = new WorldLUTs();
+ private static LUT luts = new LUT();
private static Parameter[] lightingParameters = {
newParameter<int>("Light Tone Map Type", 0x16C, ParameterType.INT, pMinMaxStep(1, 6, 1)),
newParameter<bool>("Light Compute Luminance", 0x170, ParameterType.BOOL),
@@ -1636,8 +1634,6 @@ namespace WorldTuningTool private Hook<CreateBloomObject>? createBloomObject;
private Hook<CreateBloomObject2>? createBloomObject2;
private Hook<DestroyBloomObject>? destroyBloomObject;
- //private delegate void UpdateBloomParams(nint bloomObjectInternal, nint unknownPtr);
- //private Hook<UpdateBloomParams>? updateBloomParams;
private nint bloomObject = 0x0;
private static Parameter[] bloomParameters = {
// Disabling 'Draw' is a bad way to disable bloom. It breaks the filter on initial load which
@@ -1882,7 +1878,9 @@ namespace WorldTuningTool setShadowQuality.Invoke(MemoryUtil.Read<int>(sMhScene!.Instance + 0x5530) + 1);
}
+#if SHADER_FEATURES
private bool fullResSSLR = false;
+#endif
private Patch ssrRes1;
private Patch ssrRes2;
private Patch ssrRes3;
@@ -1993,89 +1991,6 @@ namespace WorldTuningTool private bool disableReducedRateAnimations = false;
private Patch zeroFrameSkip;
- private class Light
- {
- public nint Object;
- public int Type;
- public Parameter[] Parameters = {
- newParameter<int>("Group", 0x13C, ParameterType.INT, pMinMaxStep(1, 255, 1)), // 1 = World, (1 << 1) = Player/Palico, (1 << 2) = NPCs
- newFrameParameter<float>("Position", 0x5A0, ParameterType.VECTOR3, pStep(0.15f)),
- newFrameParameter<int>("Color", 0x140, ParameterType.COLOR),
- newFrameParameter<float>("Intensity", 0x8A8, ParameterType.FLOAT),
- newFrameParameter<float>("Radius", 0x6A0, ParameterType.FLOAT, pStep(0.25f)),
- newFrameParameter<float>("Effective Radius", 0x588, ParameterType.FLOAT, pStep(0.25f)),
- 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.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)),
- newFrameParameter<float>("Shadow Max Depth Bias", 0x584, ParameterType.FLOAT, pStep(0.00001f)),
- };
-
- public Light(nint lightObject, int type)
- {
- Object = lightObject;
- Type = type;
- foreach (Parameter param in Parameters)
- {
- param.Update(lightObject);
- }
- }
-
- public Light(nint lightObject, int type, Vector3 pos)
- {
- Object = lightObject;
- Type = type;
- foreach (Parameter param in Parameters)
- {
- param.OverrideOn(false);
- }
- Parameters[0].OverrideValue(default, 255);
- Parameters[1].OverrideValue(new Vector4(pos.X, pos.Y, pos.Z, 0.0f), 0);
- Parameters[3].OverrideValue(new Vector4(10.0f, 0.0f, 0.0f, 0.0f), 0);
- foreach (Parameter param in Parameters)
- {
- param.Update(lightObject);
- }
- }
- }
-
- // Point Light (2):
- // Create1: 0x141F875A0 ()
- // Create2: 0x141F87CD0 (nint)
- // Destroy: 0x141F87D90 (nint, int)
- //
- // Spot Light (3):
- // Create1: 0x141F8AE80 ()
- // Create2: 0x141F8B2D0 (nint)
- // Destroy: 0x141F8B390 (nint, int)
- //
- // Hemi Sphere Light (4):
- // Create1: 0x141F84840 ()
- // Create2: 0x141F84990 (nint)
- // Destroy: 0x141F84A40 (nint, int)
- //
- // Wrapper? (8):
- // Create1: 0x141F816C0 ()
- // Create2: 0x141F81800 ()
- // Destroy: 0x141F81940 (nint, int)
-
- private int requestLightType = 2;
- private NativeFunction<int, nint> createLight;
- //private bool interceptCreateLight = false;
- private List<Light> ourLights = new List<Light>();
- //private List<Light> sceneLights = new List<Light>();
- private NativeAction<nint, int, nint, int> addToScene;
- private NativeAction<nint> removeFromScene;
- //private delegate nint CreateLightObject(int type);
- //private Hook<CreateLightObject>? createLightObject;
- private delegate void DestroyLightObject(nint lightObject, int unknownInt);
- private Hook<DestroyLightObject>? destroyLightObject;
- private delegate void UpdateLights(nint lightObject);
- private Hook<UpdateLights>? updateLights;
-
public int AddOverride(string name, Vector4 v4, int i1)
{
foreach (Parameter param in allParameters)
@@ -2138,7 +2053,7 @@ namespace WorldTuningTool foreach (StageExt stage in Enum.GetValues(typeof(StageExt)))
{
if (stage == StageExt.Global) continue;
- Assert(Config.OrderedStages.Contains(stage));
+ Assert(OrderedStages.Contains(stage));
}
onAreaChange = Hook.Create<OnAreaChange>(0x141AC27D0, OnAreaChangeHook); // nint
@@ -2149,7 +2064,7 @@ namespace WorldTuningTool // Light Dir XZY is updated seperately at 0x1420397F0, we assume this function always happens later, though.
updateCapsuleAoParams = Hook.Create<UpdateCapsuleAOParams>(0x141B19E10, UpdateCapsuleAOParamsHook); // nint
- // These run during cutscenes.
+ // These run in a loop during cutscenes.
updateSSAOParams = Hook.Create<UpdateSSAOParams>(0x1416D8B10, UpdateSSAOParamsHook); // nint
updateSSLRParams = Hook.Create<UpdateSSLRParams>(0x1416DA3F0, UpdateSSLRParamsHook); // nint
updateLightingParams = Hook.Create<UpdateLightingParameters>(0x1416DAAB0, UpdateLightingParametersHook); // nint, nint
@@ -2161,7 +2076,6 @@ namespace WorldTuningTool createBloomObject = Hook.Create<CreateBloomObject>(0x1424CB3C0, CreateBloomObjectHook);
createBloomObject2 = Hook.Create<CreateBloomObject2>(0x1424CB5E0, CreateBloomObject2Hook); // nint
destroyBloomObject = Hook.Create<DestroyBloomObject>(0x1424CB750, DestroyBloomObjectHook); // nint, int
- //updateBloomParams = Hook.Create<UpdateBloomParams>(0x1424CD570, UpdateBloomParamsHook); // nint, nint
createDofObject = Hook.Create<CreateDofObject>(0x142421E80, CreateDofObjectHook);
createDofObject2 = Hook.Create<CreateDofObject2>(0x1424220A0, CreateDofObject2Hook); // nint
@@ -2181,12 +2095,7 @@ namespace WorldTuningTool createTAAObject2 = Hook.Create<CreateTAAObject2>(0x142391320, CreateTAAObject2Hook); // nint
destroyTAAObject = Hook.Create<DestroyTAAObject>(0x1423916E0, DestroyTAAObjectHook); // nint, int
- createLight = new NativeFunction<int, nint>(0x1418A3EF0);
- //createLightObject = Hook.Create<CreateLightObject>(0x1418A3EF0, CreateLightObjectHook);
- destroyLightObject = Hook.Create<DestroyLightObject>(0x141F87D90, DestroyLightObjectHook);
- addToScene = new NativeAction<nint, int, nint, int>(0x142219070);
- removeFromScene = new NativeAction<nint>(0x142228F10);
- updateLights = Hook.Create<UpdateLights>(0x141F88F30, UpdateLightsHook);
+ lights.Initialize();
nint addr = PatternScanner.FindFirst(Pattern.FromString("48 89 5C 24 10 48 89 74 24 18 48 89 7C 24 20 55 41 56 41 57 48 8B EC 48 83 EC 30 48 8B FA 48 8B D9 E8 AA B6 C1 FF 48 8B 47 10 48 8D 57 50"));
Assert(addr == 0x141AB2260); // nint, nint
@@ -2382,9 +2291,9 @@ namespace WorldTuningTool public void OnPreMain()
{
Config config = getConfig();
- Config.PatchConfig patches = config.Patches;
- fullResSSLR = patches.FullResolutionSSLR;
+ PatchConfig patches = config.Patches;
#if SHADER_FEATURES
+ fullResSSLR = patches.FullResolutionSSLR;
if (fullResSSLR)
{
ssrRes1.Enable();
@@ -2478,7 +2387,7 @@ namespace WorldTuningTool {
config.Overrides[globalStage].Add(ovG);
}
- foreach (StageExt area in Config.OrderedStages)
+ foreach (StageExt area in OrderedStages)
{
if (!config.Overrides.ContainsKey(area))
{
@@ -2873,20 +2782,6 @@ namespace WorldTuningTool return destroyBloomObject!.Original(bloomObjectInternal, unknownInt);
}
- /*
- private void UpdateBloomParamsHook(nint bloomObjectInternal, nint unknownPtr)
- {
- if (bloomObject == bloomObjectInternal)
- {
- foreach (Parameter param in bloomParameters)
- {
- param.Update(bloomObject);
- }
- }
- updateBloomParams!.Original(bloomObjectInternal, unknownPtr);
- }
- */
-
private nint CreateLightingObjectHook()
{
lightingObject = createLightingObject!.Original();
@@ -2968,80 +2863,6 @@ namespace WorldTuningTool staticShadowParams!.Original(shadowParamsStatic, shadowObjectInternal);
}
- /*
- private nint CreateLightObjectHook(int type)
- {
- nint lightObject = createLightObject!.Original(type);
- if (interceptCreateLight)
- {
- interceptCreateLight = false;
- }
- //else if (type == 2)
- else
- {
- sceneLights.Add(new Light(lightObject, type));
- }
- return lightObject;
- }
- */
-
- private void DestroyLightObjectHook(nint lightObject, int unknownInt)
- {
- /*
- for (int i = 0; i < sceneLights.Count; i++)
- {
- if (lightObject == sceneLights[i].Object)
- {
- sceneLights.RemoveAt(i);
- break;
- }
- }
- */
- for (int i = 0; i < ourLights.Count; i++)
- {
- if (lightObject == ourLights[i].Object)
- {
- ourLights.RemoveAt(i);
- break;
- }
- }
- destroyLightObject!.Original(lightObject, unknownInt);
- }
-
- private void UpdateLightsHook(nint lightObject)
- {
- Light? light = null;
- /*
- for (int i = 0; i < sceneLights.Count; i++)
- {
- if (lightObject == sceneLights[i].Object)
- {
- light = sceneLights[i];
- break;
- }
- }
- */
- if (light == null)
- {
- for (int i = 0; i < ourLights.Count; i++)
- {
- if (lightObject == ourLights[i].Object)
- {
- light = ourLights[i];
- break;
- }
- }
- }
- updateLights!.Original(lightObject);
- if (light != null)
- {
- foreach (Parameter param in light.Parameters)
- {
- param.Update(lightObject);
- }
- }
- }
-
private void HandleSetChange(string prevSet, List<Override> globalOverrides, List<Override>? stageOverrides)
{
Config config = getConfig();
@@ -3124,10 +2945,6 @@ namespace WorldTuningTool private void HandleAreaChange(StageExt stage)
{
Config config = getConfig();
- if (!config.Overrides.ContainsKey(stage))
- {
- return;
- }
List<Override> prevOverrides = config.Overrides[previousStage];
List<Override> globalOverrides = config.Overrides[globalStage];
BeginTransition();
@@ -3146,6 +2963,11 @@ namespace WorldTuningTool }
}
}
+ if (!config.Overrides.ContainsKey(stage))
+ {
+ Log.Error($"Unknown stage: {stage}");
+ stage = globalStage;
+ }
if (stage != globalStage)
{
List<Override> stageOverrides = config.Overrides[stage];
@@ -3182,13 +3004,13 @@ namespace WorldTuningTool float width = ImGui.GetWindowWidth();
width /= width / (600.0f * ImGui.GetIO().FontGlobalScale);
- ImGui.Text($"Current Stage: {Config.StageToString(currentStage)}");
+ ImGui.Text($"Current Stage: {StageToString(currentStage)}");
ImGui.PushItemWidth(width * 0.35f);
- if (ImGui.BeginCombo("##Stage", Config.StageToString(selectedStage), ImGuiComboFlags.HeightLarge))
+ if (ImGui.BeginCombo("##Stage", StageToString(selectedStage), ImGuiComboFlags.HeightLarge))
{
- foreach (StageExt area in Config.OrderedStages)
+ foreach (StageExt area in OrderedStages)
{
- string name = Config.StageToString(area);
+ string name = StageToString(area);
bool isSelected = selectedStage == area;
if (ImGui.Selectable(name, isSelected))
{
@@ -3326,7 +3148,7 @@ namespace WorldTuningTool {
if (selectedStage == globalStage)
{
- reorderConfig(config, selectedOverrides);
+ rebuildConfig(config, selectedOverrides);
}
configState |= SelectedNotSaved;
}
@@ -3530,8 +3352,9 @@ namespace WorldTuningTool if (ImGui.CollapsingHeader("Patches"))
{
- Config.PatchConfig patches = config.Patches;
+ PatchConfig patches = config.Patches;
+#if SHADER_FEATURES
if (ImGui.Checkbox("Full Resolution Screen Space Reflections (Requires Restart)", ref fullResSSLR))
{
patches.FullResolutionSSLR = fullResSSLR;
@@ -3543,6 +3366,7 @@ namespace WorldTuningTool ImGui.Text("Restart Required");
ImGui.EndTooltip();
}
+#endif
if (ImGui.Checkbox("Volume Rendering Full Resolution Blur Pass (Requires Area Change)", ref fullResVolumeBlur))
{
@@ -3560,7 +3384,7 @@ namespace WorldTuningTool }
if (ImGui.BeginItemTooltip())
{
- ImGui.Text("This can get rid of excessive aliasing when something is in front of a volumetric effect.\nMove to a different area for this to apply, it will stay applied after that.");
+ ImGui.Text("This can get rid of excessive aliasing when something is in front of a volumetric effect.\nMove to a different area for this to apply. It will stay applied after that.");
ImGui.EndTooltip();
}
@@ -3647,83 +3471,7 @@ namespace WorldTuningTool if (ImGui.CollapsingHeader("Lights"))
{
- /*
- ImGui.NextItemWidth(width * 0.25f);
- ImGui.InputInt("Type", ref requestLightType, 1);
- ImGui.SameLine();
- */
- if (ImGui.Button("New"))
- {
- //interceptCreateLight = true;
- nint lightObject = createLight.Invoke(requestLightType);
- Vector3 pos = default;
- Player? player = Player.MainPlayer;
- if (player != null)
- {
- pos = player.Position;
- pos.Y += 30.0f;
- }
- ourLights.Add(new Light(lightObject, requestLightType, pos));
- // mov byte ptr[rsp+20],00 unaccounted for, hopefully it never matters.
- addToScene.Invoke(MemoryUtil.Read<nint>(0x1451238C8), 0x16, lightObject, 0x0);
- }
- ImGui.Separator();
- ImGui.PushID("Ours");
- for (int i = 0; i < ourLights.Count; i++)
- {
- Light light = ourLights[i];
- ImGui.PushID(i);
- ImGui.Text($"Type: {light.Type}, Address: 0x{light.Object:X}");
- foreach (Parameter param in light.Parameters)
- {
- param.Draw(width, true);
- }
- /*
- if (ImGui.CollapsingHeader("Random Move"))
- {
- foreach (Parameter param in light.RandomMoveParameters)
- {
- param.Draw(width, true);
- }
- }
- */
- if (ImGui.Button("Remove"))
- {
- /*
- nint vTable = MemoryUtil.Read<nint>(lightObject);
- NativeAction<nint, int> freeLight = new NativeAction<nint, int>(MemoryUtil.Read<nint>(vTable));
- freeLight.Invoke(lightObject, 1);
- */
- // removeFromScene triggers destructor.
- removeFromScene.Invoke(light.Object);
- }
- ImGui.PopID();
- ImGui.Separator();
- }
- ImGui.PopID();
- ImGui.PushID("Scene");
- /*
- if (ImGui.CollapsingHeader("Scene Lights"))
- {
- for (int i = 0; i < sceneLights.Count; i++)
- {
- Light light = sceneLights[i];
- ImGui.PushID(i);
- ImGui.Text($"Type: {light.Type}, Address: 0x{light.Object:X}");
- foreach (Parameter param in light.Parameters)
- {
- param.Draw(width);
- }
- if (ImGui.Button("Remove"))
- {
- removeFromScene.Invoke(light.Object);
- }
- ImGui.PopID();
- ImGui.Separator();
- }
- }
- */
- ImGui.PopID();
+ lights.DrawUI(width);
}
bool expanded = ImGui.CollapsingHeader("Parameters");
@@ -3864,12 +3612,12 @@ namespace WorldTuningTool nint lutMap0 = MemoryUtil.Read<nint>(lightingObject + 0x1A8);
if (lutMap0 != 0x0)
{
- luts.DrawLUT(lutMap0, lightingObject, 0, width);
+ luts.DrawUI(lutMap0, lightingObject, 0, width);
}
nint lutMap1 = MemoryUtil.Read<nint>(lightingObject + 0x1B0);
if (lutMap1 != 0x0)
{
- luts.DrawLUT(lutMap1, lightingObject, 1, width);
+ luts.DrawUI(lutMap1, lightingObject, 1, width);
}
}
foreach (Parameter param in lightingParameters)
|