summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xConfig.cs95
-rwxr-xr-xPlugin.cs2349
-rwxr-xr-xScripts/generate_diffs.sh2
3 files changed, 2387 insertions, 59 deletions
diff --git a/Config.cs b/Config.cs
index bbb785b..356c746 100755
--- a/Config.cs
+++ b/Config.cs
@@ -1,4 +1,5 @@
using SharpPluginLoader.Core.Configuration;
+using SharpPluginLoader.Core;
namespace WorldTuningTool
{
@@ -6,5 +7,99 @@ namespace WorldTuningTool
{
public String Name => "WorldTuningTool";
public String Version => "1.0";
+
+ public static string StageToString(Stage stage)
+ {
+ switch (stage)
+ {
+ case Stage.InfinityOfNothingHandler:
+ return "Global";
+ case Stage.AncientForest:
+ return "Ancient Forest";
+ case Stage.WildspireWaste:
+ return "Wildspire Waste";
+ case Stage.CoralHighlands:
+ return "Coral Highlands";
+ case Stage.RottenVale:
+ return "Rotten Vale";
+ case Stage.ElderRecess:
+ return "Elder Recess";
+ case Stage.GreatRavine:
+ return "Great Ravine";
+ case Stage.GreatRavineStory:
+ return "Great Ravine Story";
+ case Stage.HoarfrostReach:
+ return "Hoarfrost Reach";
+ case Stage.GuidingLands:
+ return "Guiding Lands";
+ case Stage.InfinityOfNothing:
+ return "Infinity Of Nothing";
+ case Stage.SpecialArena:
+ return "Special Arena";
+ case Stage.ChallengeArena:
+ return "Challenge Arena";
+ case Stage.Astera:
+ return "Astera";
+ case Stage.AsteraHub:
+ return "Astera Hub";
+ case Stage.ResearchBase:
+ return "Research Base";
+ case Stage.Seliana:
+ return "Seliana";
+ case Stage.SelianaHub:
+ return "Seliana Hub";
+ case Stage.Everstream:
+ return "Everstream";
+ case Stage.ConfluenceOfFates:
+ return "Confluence Of Fates";
+ case Stage.CharacterCreation:
+ return "Character Creation";
+ case Stage.DebugMap:
+ return "Debug Map";
+ case Stage.ElDorado:
+ return "El Dorado";
+ case Stage.SelianaSupplyCache:
+ return "Seliana Supply Cache";
+ case Stage.OriginIsleNergigante:
+ return "Origin Isle Nergigante";
+ case Stage.OriginIsleSharaIshvalda:
+ return "Origin Isle Shara Ishvalda";
+ case Stage.SecludedValley:
+ return "Secluded Valley";
+ case Stage.AlatreonStage:
+ return "Alatreon Stage";
+ case Stage.CastleSchrade:
+ return "Castle Schrade";
+ case Stage.LivingQuarters:
+ return "Living Quarters";
+ case Stage.PrivateQuarters:
+ return "Private Quarters";
+ case Stage.PrivateSuite:
+ return "Private Suite";
+ case Stage.TrainingCamp:
+ return "Training Camp";
+ case Stage.ChamberOfFive:
+ return "Chamber Of Five";
+ case Stage.SelianaRoom:
+ return "Seliana Room";
+ }
+ return "Global (null)";
+ }
+
+ /*
+ public class StageExt
+ {
+ Stage s {
+ get
+ {
+ }
+ set
+ {
+ }
+ };
+ }
+ */
+
+ public Dictionary<Stage, List<Plugin.Override>> Overrides { get; set; } = new Dictionary<Stage, List<Plugin.Override>>();
}
}
diff --git a/Plugin.cs b/Plugin.cs
index c647785..da94bb8 100755
--- a/Plugin.cs
+++ b/Plugin.cs
@@ -1,10 +1,25 @@
-using System.Reflection;
+//#define ENABLE_ASSERTS
+
+using System.Numerics;
+using System.Reflection;
+using System.Diagnostics;
using System.Runtime.Loader;
using System.Runtime.InteropServices;
using ImGuiNET;
using SharpPluginLoader.Core;
+using SharpPluginLoader.Core.Configuration;
using SharpPluginLoader.Core.Memory;
+using SharpPluginLoader.Core.Entities;
+
+// @TODO:
+// - Inter-op.
+// - Motion blur for freeze.
+// - Binds.
+// - Lights.
+// - Try to understand shadow distance vs backforward distance vs bias.
+// - Shadow distance retuning.
+// - Descriptions.
namespace WorldTuningTool
{
@@ -13,55 +28,2292 @@ namespace WorldTuningTool
public string Name => "World Tuning Tool";
public string Author => "Akon City Software";
- // @TODO:
- // - Port FXAA object.
- // - Port some stuff as is.
- // - OnAreaChange.
- // - Shadow distance retuning.
- // - Work out obvious simplifications.
- // - sMhRenderer vs common parameter address.
- // - Overrides system.
- // - Pass on LODs.
- // - Verbose descriptions.
- // - Re-implement shadow res override for hoarfrost.
- // - Exact float flag for hex input?
+ private static void Assert(bool condition)
+ {
+#if ENABLE_ASSERTS
+ Trace.Assert(condition);
+#endif
+ }
+
+ private static byte ByteFlag(bool f) { return f ? (byte)0x1 : (byte)0x0; }
+
+ private static Vector4 ColorVectorFromInt(int c)
+ {
+ return new Vector4(
+ ((c )&0xFF)/255.0f,
+ ((c>>8 )&0xFF)/255.0f,
+ ((c>>16)&0xFF)/255.0f,
+ ((c>>24)&0xFF)/255.0f);
+ }
+
+ private static int ColorVectorToInt(Vector4 v)
+ {
+ return ((int)MathF.Round(v.X*255.0f) |
+ ((int)MathF.Round(v.Y*255.0f) << 8) |
+ ((int)MathF.Round(v.Z*255.0f) << 16) |
+ ((int)MathF.Round(v.W*255.0f) << 24));
+ }
+
+ public enum ParameterType
+ {
+ BOOL,
+ BYTE,
+ FLAG,
+ INT,
+ HEX,
+ COLOR,
+ FLOAT,
+ VECTOR3,
+ VECTOR4
+ }
- private bool dofDisabled = false;
- private Patch jmpOverDof;
+ private const float defaultParamWidth = 0.215f;
- public void SetDofForceOff(bool off)
+ public abstract class Parameter
{
- if (off && !dofDisabled)
+ public string Name;
+ private string hiddenName;
+ public ParameterType Type;
+ public bool PerFrame;
+
+ private nint offset;
+ private nint lastAddr = 0x0;
+ private bool overrideValue = false;
+ private bool overrideForStage = false;
+ private bool overrideWasOn = false;
+
+ protected float stepf, minf, maxf;
+ protected int step, min, max;
+ protected int mask;
+
+ private Vector4 valueV = default;
+ private int valueInt = 0;
+ private Vector4 oValueV;
+ private int oValueInt;
+
+ private bool pendingUpdate = true;
+ private bool queuedOverride = false;
+ private bool queuedValue = false;
+ private Vector4 qValueV;
+ private int qValueInt;
+
+ private bool bValue = false;
+ private Vector4 bValueV;
+ private int bValueInt;
+
+ public Parameter(string name, nint offset, ParameterType type, bool perFrame)
+ {
+ Name = name;
+ hiddenName = "##" + Name;
+ this.offset = offset;
+ Type = type;
+ PerFrame = perFrame;
+ }
+
+ public bool PendingUpdate()
+ {
+ return pendingUpdate;
+ }
+
+ public (Vector4, int) GetValue()
+ {
+ return (valueV, valueInt);
+ }
+
+ public int GetMask()
+ {
+ return mask;
+ }
+
+ private void writeCurrentValue()
+ {
+ if (lastAddr == 0x0) return;
+ switch (Type)
+ {
+ case ParameterType.BOOL:
+ case ParameterType.BYTE:
+ MemoryUtil.GetRef<byte>(lastAddr + offset) = (byte)valueInt;
+ break;
+ case ParameterType.FLAG:
+ if (valueInt == 0)
+ {
+ MemoryUtil.GetRef<int>(lastAddr + offset) &= ~mask;
+ }
+ else
+ {
+ MemoryUtil.GetRef<int>(lastAddr + offset) |= mask;
+ }
+ break;
+ case ParameterType.INT:
+ case ParameterType.HEX:
+ case ParameterType.COLOR:
+ MemoryUtil.GetRef<int>(lastAddr + offset) = valueInt;
+ break;
+ case ParameterType.FLOAT:
+ MemoryUtil.GetRef<float>(lastAddr + offset) = valueV.X;
+ break;
+ case ParameterType.VECTOR3:
+ MemoryUtil.GetRef<Vector3>(lastAddr + offset) = new Vector3(valueV.X, valueV.Y, valueV.Z);
+ break;
+ case ParameterType.VECTOR4:
+ MemoryUtil.GetRef<Vector4>(lastAddr + offset) = valueV;
+ break;
+ }
+ }
+
+ public void OverrideOn(bool forStage)
{
- jmpOverDof.Enable();
+ if (pendingUpdate)
+ {
+ if (queuedOverride)
+ {
+ Assert(!overrideWasOn && forStage);
+ overrideWasOn = true;
+ }
+ else
+ {
+ queuedOverride = true;
+ }
+ }
+ else
+ {
+ if (overrideValue)
+ {
+ Assert(!overrideWasOn && forStage);
+ overrideWasOn = true;
+ }
+ else
+ {
+ oValueV = valueV;
+ oValueInt = valueInt;
+ if (!PerFrame)
+ {
+ writeCurrentValue();
+ }
+ overrideValue = true;
+ }
+ }
+ overrideForStage = forStage;
}
- else if (!off && dofDisabled)
+
+ public void OverrideOff()
{
- jmpOverDof.Disable();
+ if (queuedOverride)
+ {
+ if (overrideWasOn)
+ {
+ Assert(overrideForStage);
+ overrideWasOn = false;
+ }
+ else
+ {
+ queuedOverride = false;
+ }
+ }
+ else
+ {
+ Assert(overrideValue);
+ if (overrideWasOn)
+ {
+ Assert(overrideForStage);
+ overrideWasOn = false;
+ }
+ else
+ {
+ valueV = oValueV;
+ valueInt = oValueInt;
+ bValue = false;
+ if (!PerFrame)
+ {
+ writeCurrentValue();
+ }
+ overrideValue = false;
+ }
+ }
+ overrideForStage = false;
}
- dofDisabled = off;
+
+ public void OverrideValue(Vector4 v, int i)
+ {
+ if (queuedOverride)
+ {
+ qValueV = v;
+ qValueInt = i;
+ queuedValue = true;
+ }
+ else
+ {
+ valueV = v;
+ valueInt = i;
+ if (!PerFrame)
+ {
+ writeCurrentValue();
+ }
+ }
+ }
+
+ public void Update(nint baseObject)
+ {
+ lastAddr = baseObject;
+
+ if (baseObject == 0x0)
+ {
+ pendingUpdate = true;
+ return;
+ }
+
+ // Trying to track changes to the original value is a
+ // "best effort" approach because it can't work if the in-game
+ // value and the override value are the same.
+ switch (Type)
+ {
+ case ParameterType.BOOL:
+ case ParameterType.BYTE:
+ {
+ ref byte b1 = ref MemoryUtil.GetRef<byte>(baseObject + offset);
+ if (b1 != (byte)valueInt && b1 != (byte)oValueInt)
+ {
+ oValueInt = (byte)b1;
+ }
+ if (overrideValue)
+ {
+ b1 = (byte)valueInt;
+ }
+ else
+ {
+ valueInt = b1;
+ }
+ break;
+ }
+ case ParameterType.FLAG:
+ {
+ ref int i1 = ref MemoryUtil.GetRef<int>(baseObject + offset);
+ int f1 = i1 & mask;
+ if (f1 != valueInt && f1 != oValueInt)
+ {
+ oValueInt = f1;
+ }
+ if (overrideValue)
+ {
+ if (f1 == 0)
+ {
+ i1 &= ~mask;
+ }
+ else
+ {
+ i1 |= mask;
+ }
+ }
+ else
+ {
+ valueInt = f1;
+ }
+ break;
+ }
+ case ParameterType.INT:
+ case ParameterType.HEX:
+ case ParameterType.COLOR:
+ {
+ ref int i1 = ref MemoryUtil.GetRef<int>(baseObject + offset);
+ if (i1 != valueInt && i1 != oValueInt)
+ {
+ oValueInt = i1;
+ }
+ if (overrideValue)
+ {
+ i1 = valueInt;
+ }
+ else
+ {
+ valueInt = i1;
+ }
+ break;
+ }
+ case ParameterType.FLOAT:
+ {
+ ref float f1 = ref MemoryUtil.GetRef<float>(baseObject + offset);
+ if (f1 != valueV.X && f1 != oValueV.X)
+ {
+ oValueV.X = f1;
+ }
+ if (overrideValue)
+ {
+ f1 = valueV.X;
+ }
+ else
+ {
+ valueV.X = f1;
+ }
+ break;
+ }
+ case ParameterType.VECTOR3:
+ {
+ ref Vector3 v3 = ref MemoryUtil.GetRef<Vector3>(baseObject + offset);
+ Vector3 valueV3 = new Vector3(valueV.X, valueV.Y, valueV.Z);
+ if (v3 != valueV3 && v3 != valueV3)
+ {
+ oValueV.X = v3.X;
+ oValueV.Y = v3.Y;
+ oValueV.Z = v3.Z;
+ }
+ if (overrideValue)
+ {
+ v3 = valueV3;
+ }
+ else
+ {
+ valueV.X = v3.X;
+ valueV.Y = v3.Y;
+ valueV.Z = v3.Z;
+ }
+ break;
+ }
+ case ParameterType.VECTOR4:
+ {
+ ref Vector4 v4 = ref MemoryUtil.GetRef<Vector4>(baseObject + offset);
+ if (v4 != valueV && v4 != oValueV)
+ {
+ oValueV = v4;
+ }
+ if (overrideValue)
+ {
+ v4 = valueV;
+ }
+ else
+ {
+ valueV = v4;
+ }
+ break;
+ }
+ }
+
+ if (pendingUpdate)
+ {
+ pendingUpdate = false;
+ if (queuedOverride)
+ {
+ Assert(!overrideValue);
+ OverrideOn(overrideForStage);
+ if (queuedValue)
+ {
+ valueV = qValueV;
+ valueInt = qValueInt;
+ if (!PerFrame)
+ {
+ writeCurrentValue();
+ }
+ queuedValue = false;
+ }
+ queuedOverride = false;
+ }
+ }
+ }
+
+ public bool DrawValue(ref Vector4 v4, ref int i1, float width, bool drawLabel)
+ {
+ bool valueChanged = false;
+ string label = drawLabel ? Name : hiddenName;
+ switch (Type)
+ {
+ case ParameterType.BOOL:
+ {
+ bool b = i1 == 0x1;
+ if (ImGui.Checkbox(label, ref b))
+ {
+ i1 = ByteFlag(b);
+ valueChanged = true;
+ }
+ break;
+ }
+ case ParameterType.BYTE:
+ {
+ ImGui.SetNextItemWidth(width * defaultParamWidth);
+ ImGuiInputTextFlags flags = ImGuiInputTextFlags.EnterReturnsTrue;
+ if (ImGui.InputInt(label, ref i1, step, 0, flags))
+ {
+ i1 = Math.Clamp(i1, min, max);
+ valueChanged = true;
+ }
+ break;
+ }
+ case ParameterType.INT:
+ case ParameterType.HEX:
+ {
+ ImGui.SetNextItemWidth(width * defaultParamWidth);
+ ImGuiInputTextFlags flags = ImGuiInputTextFlags.EnterReturnsTrue;
+ if (Type == ParameterType.HEX)
+ {
+ flags |= ImGuiInputTextFlags.CharsHexadecimal;
+ }
+ if (ImGui.InputInt(label, ref i1, step, 0, flags))
+ {
+ if (max > min)
+ {
+ i1 = Math.Clamp(i1, min, max);
+ }
+ valueChanged = true;
+ }
+ break;
+ }
+ case ParameterType.FLAG:
+ {
+ bool b = i1 == mask;
+ if (ImGui.Checkbox(label, ref b))
+ {
+ i1 = b ? mask : 0;
+ valueChanged = true;
+ }
+ break;
+ }
+ case ParameterType.COLOR:
+ {
+ ImGui.SetNextItemWidth(width * defaultParamWidth * 3.0f);
+ Vector4 colorV = ColorVectorFromInt(i1);
+ if (ImGui.ColorEdit4(label, ref colorV))
+ {
+ i1 = ColorVectorToInt(colorV);
+ valueChanged = true;
+ }
+ break;
+ }
+ case ParameterType.FLOAT:
+ {
+ ImGui.SetNextItemWidth(width * defaultParamWidth);
+ float f1 = v4.X;
+ if (ImGui.DragFloat(label, ref f1, stepf, minf, maxf, "%.5f", ImGuiSliderFlags.NoRoundToFormat))
+ {
+ //if (ImGui.IsItemDeactivatedAfterEdit())
+ //{
+ v4.X = f1;
+ valueChanged = true;
+ //}
+ }
+ break;
+ }
+ case ParameterType.VECTOR3:
+ {
+ ImGui.SetNextItemWidth(width * defaultParamWidth * 3.0f);
+ Vector3 v3 = new Vector3(v4.X, v4.Y, v4.Z);
+ if (ImGui.DragFloat3(label, ref v3, stepf, minf, maxf, "%.4f", ImGuiSliderFlags.NoRoundToFormat))
+ {
+ v4.X = v3.X;
+ v4.Y = v3.Y;
+ v4.Z = v3.Z;
+ valueChanged = true;
+ }
+ break;
+ }
+ case ParameterType.VECTOR4:
+ {
+ ImGui.SetNextItemWidth(width * defaultParamWidth * 4.0f);
+ if (ImGui.DragFloat4(label, ref v4, stepf, minf, maxf, "%.4f", ImGuiSliderFlags.NoRoundToFormat))
+ {
+ valueChanged = true;
+ }
+ break;
+ }
+ }
+ return valueChanged;
+ }
+
+ public void Draw(float width, bool assumeOverride = false)
+ {
+ Draw(ref valueV, ref valueInt, width, assumeOverride);
+ }
+
+ public void Draw(ref Vector4 v4, ref int i1, float width, bool assumeOverride)
+ {
+ ImGui.PushID(Name);
+ if (!assumeOverride)
+ {
+ if (overrideForStage)
+ {
+ ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true);
+ ImGui.PushItemFlag(ImGuiItemFlags.MixedValue, true);
+ }
+ bool toggleOverride = overrideValue;
+ if (ImGui.Checkbox("##Override", ref toggleOverride))
+ {
+ if (toggleOverride)
+ {
+ OverrideOn(false);
+ }
+ else
+ {
+ OverrideOff();
+ }
+ }
+ if (ImGui.BeginItemTooltip())
+ {
+ if (overrideForStage)
+ {
+ ImGui.Text("Overridden by Config");
+ }
+ else
+ {
+ ImGui.Text("Override Value");
+ }
+ ImGui.EndTooltip();
+ }
+ if (overrideForStage)
+ {
+ ImGui.PopItemFlag();
+ ImGui.PopItemFlag();
+ }
+ ImGui.SameLine();
+ }
+ if (!overrideValue)
+ {
+ ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true);
+ }
+ if (DrawValue(ref valueV, ref valueInt, width, !bValue) && !PerFrame)
+ {
+ writeCurrentValue();
+ }
+ if (!assumeOverride && overrideValue && !pendingUpdate)
+ {
+ ImGui.SameLine();
+ if (!bValue)
+ {
+ if (ImGui.Button("B >"))
+ {
+ bValueV = oValueV;
+ bValueInt = oValueInt;
+ bValue = true;
+ }
+ }
+ else
+ {
+ if (ImGui.Button("A/B"))
+ {
+ (bValueV, valueV) = (valueV, bValueV);
+ (bValueInt, valueInt) = (valueInt, bValueInt);
+ if (!PerFrame)
+ {
+ writeCurrentValue();
+ }
+ }
+ ImGui.SameLine();
+ DrawValue(ref bValueV, ref bValueInt, width, true);
+ ImGui.SameLine();
+ if (ImGui.Button("< B"))
+ {
+ bValue = false;
+ }
+ }
+ ImGui.SameLine();
+ ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.7f);
+ switch (Type)
+ {
+ case ParameterType.BOOL:
+ {
+ ImGui.Text($"(Original: {oValueInt == 0x1})");
+ break;
+ }
+ case ParameterType.BYTE:
+ {
+ ImGui.Text($"(Original: {oValueInt})");
+ break;
+ }
+ case ParameterType.FLAG:
+ {
+ ImGui.Text($"(Original: {oValueInt != 0})");
+ break;
+ }
+ case ParameterType.INT:
+ case ParameterType.HEX:
+ case ParameterType.COLOR:
+ {
+ if (Type == ParameterType.INT)
+ {
+ ImGui.Text($"(Original: {oValueInt})");
+ }
+ else
+ {
+ ImGui.Text($"(Original: {oValueInt:X})");
+ }
+ break;
+ }
+ case ParameterType.FLOAT:
+ {
+ ImGui.Text($"(Original: {oValueV.X:0.00000})");
+ break;
+ }
+ case ParameterType.VECTOR3:
+ {
+ ImGui.Text($"(Original: {oValueV.X:0.0000}, {oValueV.Y:0.0000}, {oValueV.Z:0.0000})");
+ break;
+ }
+ case ParameterType.VECTOR4:
+ {
+ ImGui.Text($"(Original: {oValueV.X:0.0000}, {oValueV.Y:0.0000}, {oValueV.Z:0.0000}, {oValueV.W:0.00000})");
+ break;
+ }
+ }
+ //ImGui.SameLine();
+ //ImGui.Text($"(Address: {lastAddr:X})");
+ ImGui.PopStyleVar();
+ }
+ if (!overrideValue)
+ {
+ ImGui.PopItemFlag();
+ }
+ ImGui.PopID();
+ }
+ }
+
+ public class Parameter<T> : Parameter where T : unmanaged
+ {
+ public Parameter(string name, nint offset, ParameterType type, bool perFrame, T? step = null, T min = default, T max = default) : base(name, offset, type, perFrame)
+ {
+ if (typeof(T) == typeof(float))
+ {
+ this.stepf = step != null ? Convert.ToSingle(step) : 0.01f;
+ this.minf = Convert.ToSingle(min);
+ this.maxf = Convert.ToSingle(max);
+ }
+ else if (typeof(T) == typeof(int) || typeof(T) == typeof(byte))
+ {
+ this.step = step != null ? Convert.ToInt32(step) : 0;
+ mask = this.step;
+ this.min = Convert.ToInt32(min);
+ this.max = Convert.ToInt32(max);
+ if (typeof(T) == typeof(byte) && this.min == 0 && this.max == 0)
+ {
+ this.min = 0x0;
+ this.max = 0xFF;
+ }
+ }
+ }
+ }
+
+ private static bool overridesContainsParam(List<Override> overrides, Parameter param)
+ {
+ foreach (Override ov in overrides)
+ {
+ if (ov.Param == param)
+ {
+ return true;
+ }
+ }
+ return false;
}
- public bool GetDofDisabled()
+ private static void unsetIfOverridesContainsParam(List<Override> overrides, Parameter param)
{
- return dofDisabled;
+ foreach (Override ov in overrides)
+ {
+ if (ov.Param == param)
+ {
+ ov.Unset();
+ break;
+ }
+ }
+ }
+
+ private static void setIfOverridesContainsParam(List<Override> overrides, Parameter param)
+ {
+ foreach (Override ov in overrides)
+ {
+ if (ov.Param == param)
+ {
+ ov.Set();
+ break;
+ }
+ }
+ }
+
+ private static Parameter? getParameterByName(string name)
+ {
+ foreach (Parameter param in allParameters)
+ {
+ if (param.Name == name)
+ {
+ return param;
+ }
+ }
+ return null;
+ }
+
+ public class Override
+ {
+ public Parameter? Param = null;
+ public string Name
+ {
+ get
+ {
+ return Param != null ? Param.Name : "";
+ }
+ set
+ {
+ Param = getParameterByName(value);
+ }
+ }
+ public string Value
+ {
+ get
+ {
+ if (Param != null)
+ {
+ switch (Param.Type)
+ {
+ case ParameterType.BOOL:
+ return (valueInt == 0x1).ToString();
+ case ParameterType.BYTE:
+ return valueInt.ToString();
+ case ParameterType.FLAG:
+ return (valueInt != 0).ToString();
+ case ParameterType.INT:
+ return valueInt.ToString();
+ case ParameterType.HEX:
+ case ParameterType.COLOR:
+ return valueInt.ToString("X8");
+ case ParameterType.FLOAT:
+ return valueV.X.ToString();
+ case ParameterType.VECTOR3:
+ {
+ Vector3 valueV3 = new Vector3(valueV.X, valueV.Y, valueV.Z);
+ return valueV3.ToString();
+ }
+ case ParameterType.VECTOR4:
+ return valueV.ToString();
+ }
+ }
+ return "";
+ }
+ set
+ {
+ if (Param == null) return;
+ try
+ {
+ switch (Param.Type)
+ {
+ case ParameterType.BOOL:
+ valueInt = ByteFlag(Convert.ToBoolean(value));
+ break;
+ case ParameterType.BYTE:
+ valueInt = Convert.ToInt32(value);
+ break;
+ case ParameterType.FLAG:
+ valueInt = Convert.ToBoolean(value) ? Param.GetMask() : 0;
+ break;
+ case ParameterType.INT:
+ valueInt = Convert.ToInt32(value);
+ break;
+ case ParameterType.HEX:
+ case ParameterType.COLOR:
+ valueInt = Convert.ToInt32(value, 16);
+ break;
+ case ParameterType.FLOAT:
+ valueV.X = Convert.ToSingle(value);
+ break;
+ case ParameterType.VECTOR3:
+ break;
+ case ParameterType.VECTOR4:
+ break;
+ }
+ }
+ catch (FormatException)
+ {
+ }
+ catch (OverflowException)
+ {
+ }
+ }
+ }
+ private Vector4 valueV = default;
+ private int valueInt = 0;
+ private bool isSet = false;
+
+ public void Set()
+ {
+ Assert(!isSet);
+ isSet = true;
+ if (Param != null)
+ {
+ Param.OverrideOn(true);
+ Param.OverrideValue(valueV, valueInt);
+ }
+ }
+
+ public void Unset()
+ {
+ Assert(isSet);
+ isSet = false;
+ if (Param != null)
+ {
+ Param.OverrideOff();
+ }
+ }
+
+ public void Draw(List<Override> currentOverrides, List<Override>? globalOverrides, float width)
+ {
+ ImGui.PushItemWidth(width * 0.35f);
+ if (ImGui.BeginCombo("##Parameters", Param != null ? Param.Name : ""))
+ {
+ foreach (Parameter param in allParameters)
+ {
+ if (overridesContainsParam(currentOverrides, param))
+ {
+ continue;
+ }
+ bool isSelected = Param == param;
+ if (ImGui.Selectable(param.Name, isSelected))
+ {
+ bool wasSet = isSet;
+ if (wasSet)
+ {
+ Unset();
+ if (globalOverrides != null)
+ {
+ if (Param != null)
+ {
+ setIfOverridesContainsParam(globalOverrides, Param);
+ }
+ unsetIfOverridesContainsParam(globalOverrides, param);
+ }
+ }
+ Param = param;
+ (valueV, valueInt) = Param.GetValue();
+ if (wasSet) Set();
+ }
+ if (isSelected) ImGui.SetItemDefaultFocus();
+ }
+ ImGui.EndCombo();
+ }
+ ImGui.PopItemWidth();
+ if (Param != null)
+ {
+ ImGui.SameLine();
+ if (Param.DrawValue(ref valueV, ref valueInt, width, false) && isSet)
+ {
+ Param.OverrideValue(valueV, valueInt);
+ }
+ if (isSet && !Param.PendingUpdate() && (valueV, valueInt) != Param.GetValue())
+ {
+ ImGui.SameLine();
+ if (ImGui.Button("Set"))
+ {
+ Param.OverrideValue(valueV, valueInt);
+ }
+ }
+ }
+ }
}
+ private delegate void OnAreaChange(nint unknownPtr);
+ private Hook<OnAreaChange>? onAreaChange;
+
+ private static readonly MtObject sMain = SingletonManager.GetSingleton("sMhMain")!;
+ private static readonly MtObject sMhRender = SingletonManager.GetSingleton("sMhRender")!;
+
+ private static readonly MtObject sMhScene = SingletonManager.GetSingleton("sMhScene")!;
+ private delegate void UpdateSSAOParams(nint sceneObjectInternal, nint stackOffset);
+ private Hook<UpdateSSAOParams>? updateSSAOParams;
+ private static Parameter[] ssaoParameters = {
+ new Parameter<float>("SSAO Depth Bias", 0xB4B0, ParameterType.FLOAT, false),
+ new Parameter<float>("SSAO Sloped Depth Bias", 0xB4B4, ParameterType.FLOAT, false),
+ new Parameter<float>("SSAO Max Depth Bias", 0xB4B8, ParameterType.FLOAT, false),
+ new Parameter<float>("SSAO Dispersion", 0xB4BC, ParameterType.FLOAT, false),
+ new Parameter<float>("SSAO Effect", 0xB430, ParameterType.FLOAT, false),
+ new Parameter<float>("SSAO Effect GI", 0xB434, ParameterType.FLOAT, false),
+ new Parameter<float>("SSAO Depth Difference", 0xB4C0, ParameterType.FLOAT, false),
+ new Parameter<float>("SSAO Samples Per Pixel", 0xB4C4, ParameterType.FLOAT, false),
+ new Parameter<int>("SSAO Max Sample Num", 0xB4C8, ParameterType.INT, false),
+ new Parameter<int>("SSAO Max Sample Num (HQ)", 0xB4D0, ParameterType.INT, false),
+ new Parameter<float>("SSAO Radius", 0xB4D4, ParameterType.FLOAT, false),
+ new Parameter<float>("SSAO Bias", 0xB4D8, ParameterType.FLOAT, false),
+ new Parameter<float>("SSAO Intensity", 0xB4E0, ParameterType.FLOAT, false),
+ new Parameter<byte>("SSAO Use HiZ", 0xB4E5, ParameterType.BOOL, false),
+ new Parameter<float>("SSAO Edge Atten Rate", 0xB4DC, ParameterType.FLOAT, false)
+ };
+ private delegate void UpdateSSLRParams(nint stackOffset);
+ private Hook<UpdateSSLRParams>? updateSSLRParams;
+ private static Parameter[] sslrParameters = {
+ new Parameter<int>("SSLR Loop Count", 0xE628, ParameterType.INT, false),
+ new Parameter<float>("SSLR Loop Count Factor for CBR", 0xE62C, ParameterType.FLOAT, false),
+ new Parameter<float>("SSLR Eliminate Depth", 0xE630, ParameterType.FLOAT, false),
+ new Parameter<float>("SSLR Accurate Threshold", 0xE644, ParameterType.FLOAT, false),
+ new Parameter<float>("SSLR Accurate Threshold (HQ)", 0xE64C, ParameterType.FLOAT, false),
+ new Parameter<float>("SSLR Dither Radius", 0xE634, ParameterType.FLOAT, false),
+ new Parameter<float>("SSLR Importance Bias", 0xE638, ParameterType.FLOAT, false),
+ new Parameter<float>("SSLR Mip Scale", 0xE63C, ParameterType.FLOAT, false),
+ new Parameter<float>("SSLR Mip Bias", 0xE640, ParameterType.FLOAT, false),
+ new Parameter<byte>("SSLR Dither Resolve", 0xB43F, ParameterType.BOOL, false),
+ new Parameter<float>("SSLR Edge Atten Rate", 0xB428, ParameterType.FLOAT, false),
+ new Parameter<int>("SSLR Mip 0 Count Threshold", 0xB438, ParameterType.INT, false, 1),
+ new Parameter<float>("SSLR Depth Eliminate Rate", 0xB42C, ParameterType.FLOAT, false),
+ new Parameter<byte>("SSLR Use Mipmap", 0xE650, ParameterType.BOOL, false),
+ new Parameter<byte>("SSLR GBuffer Jitter", 0xB440, ParameterType.BOOL, false),
+ };
+ private static Parameter[] sceneParameters = {
+ new Parameter<byte>("HQ Mode", 0xE9A3, ParameterType.BOOL, false),
+ new Parameter<float>("Shadow Cascade 2Way Bias (HQ)", 0x58, ParameterType.FLOAT, false),
+ new Parameter<int>("Primary Shadow Sample Num", 0xE5C4, ParameterType.INT, false),
+ new Parameter<int>("Primary Shadow Sample Num (HQ)", 0xE5CC, ParameterType.INT, false),
+ new Parameter<byte>("Primary Shadow HQ", 0xE5C0, ParameterType.BOOL, false),
+ new Parameter<byte>("Primary Shadow HQ (HQ)", 0xE5C2, ParameterType.BOOL, false),
+ new Parameter<float>("LOD Bias 1", 0x21C, ParameterType.FLOAT, false),
+ new Parameter<float>("LOD Bias 2", 0x220, ParameterType.FLOAT, false),
+ new Parameter<float>("LOD Caster Bias", 0x1E4, ParameterType.FLOAT, false),
+ new Parameter<float>("LOD Length Bias", 0x1F4, ParameterType.FLOAT, false),
+ new Parameter<float>("LOD Length Bias (HQ)", 0x1FC, ParameterType.FLOAT, false),
+ new Parameter<float>("LOD Pixel Size Bias", 0x200, ParameterType.FLOAT, false),
+ new Parameter<float>("LOD Pixel Size Bias (HQ)", 0x208, ParameterType.FLOAT, false),
+ new Parameter<int>("LOD Limit", 0xE898, ParameterType.INT, false, 1),
+ new Parameter<float>("LOD Passthrough Culling Rate", 0x1F0, ParameterType.FLOAT, false),
+ new Parameter<float>("Far Culling Fade Length Max", 0x20C, ParameterType.FLOAT, false),
+ new Parameter<float>("Far Culling Fade Pixel Max", 0x210, ParameterType.FLOAT, false),
+ new Parameter<float>("Speed Tree LOD Billboard Fade Range", 0x214, ParameterType.FLOAT, false),
+ new Parameter<float>("LOD Culling Length Bias", 0x224, ParameterType.FLOAT, false),
+ new Parameter<float>("LOD Culling Pixel Bias", 0x228, ParameterType.FLOAT, false),
+ new Parameter<byte>("Is Calc LOD Bias Use Boundary", 0x218, ParameterType.BOOL, false),
+ new Parameter<byte>("Material Draw SS Normal", 0x5626, ParameterType.BOOL, false),
+ new Parameter<float>("Material Height Factor", 0x5628, ParameterType.FLOAT, false),
+ new Parameter<int>("Model Detail", 0x190, ParameterType.INT, false, 1),
+ new Parameter<byte>("Passthrough Active", 0xE9A0, ParameterType.BOOL, false),
+ new Parameter<byte>("Passthrough Culling Active", 0xE9A2, ParameterType.BOOL, false),
+ new Parameter<float>("Passthrough Near", 0xE940, ParameterType.FLOAT, false),
+ new Parameter<float>("Passthrough Far", 0xE944, ParameterType.FLOAT, false),
+ new Parameter<float>("Passthrough Near Alpha", 0xE948, ParameterType.FLOAT, false),
+ new Parameter<float>("Passthrough Far Alpha", 0xE94C, ParameterType.FLOAT, false),
+ new Parameter<float>("Passthrough Correct", 0xE950, ParameterType.FLOAT, false),
+ new Parameter<float>("LOD Length Platform Bias[2]", 0x22C + (4 * 2), ParameterType.FLOAT, false),
+ new Parameter<float>("LOD Pixel Size Platform Bias[2]", 0x244 + (4 * 2), ParameterType.FLOAT, false),
+ new Parameter<byte>("Contact Shadows Enabled", 0xB4EC, ParameterType.BOOL, false),
+ new Parameter<byte>("Force Disable Contact Shadows", 0xB4ED, ParameterType.BOOL, false),
+ new Parameter<byte>("Facial Contact Shadows Enabled", 0xB4EE, ParameterType.BOOL, false),
+ new Parameter<byte>("Contact Shadows Enable Noise", 0xB500, ParameterType.BOOL, false),
+ new Parameter<byte>("Facial Contact Shadows Enable Noise", 0xB501, ParameterType.BOOL, false),
+ new Parameter<float>("Contact Shadow Intensity", 0xB4F0, ParameterType.FLOAT, false),
+ new Parameter<float>("Contact Shadow Length", 0xB4F4, ParameterType.FLOAT, false),
+ new Parameter<float>("Contact Shadow Accept Maximum Length", 0xB4F8, ParameterType.FLOAT, false),
+ new Parameter<float>("Contact Shadow Accept Minimum Length", 0xB4FC, ParameterType.FLOAT, false),
+ new Parameter<byte>("Capsule AO Enabled", 0xB502, ParameterType.BOOL, false),
+ new Parameter<byte>("Force Disable Capsule AO", 0xB503, ParameterType.BOOL, false),
+ new Parameter<float>("Capsule AO Distance Fall Coef", 0xE5B4, ParameterType.FLOAT, false),
+ new Parameter<int>("Capsule AO Light Channel Mask", 0xE5BC, ParameterType.INT, false),
+ //new Parameter<float>("Capsule AO Null Parent Matrix", 0xE570, ParameterType.FLOAT, false),
+ new Parameter<float>("Capsule Light Dir XZY", 0xE548, ParameterType.VECTOR3, false),
+ new Parameter<float>("Capsule Light W Dir", 0xE560, ParameterType.FLOAT, false),
+ new Parameter<float>("Capsule Light Angle", 0xE5B0, ParameterType.FLOAT, false),
+ new Parameter<float>("Capsule AO Intensity", 0xE5B8, ParameterType.FLOAT, false),
+ new Parameter<byte>("Accurate Cascade 1 Shadow", 0x44F, ParameterType.BOOL, false),
+ new Parameter<byte>("Broad Area Shadow Enable", 0x5534, ParameterType.BOOL, false),
+ new Parameter<float>("Broad Area Shadow Center", 0x5540, ParameterType.FLOAT, false),
+ //new Parameter<float>("Broad Area Shadow Range", 0x5560, ParameterType.FLOAT, false),
+ new Parameter<float>("Broad Area Shadow Dir", 0x5550, ParameterType.VECTOR4, false),
+ //new Parameter<float>("Broad Area Shadow Depth Bias", 0x5570, ParameterType.FLOAT, false),
+ //new Parameter<float>("Broad Area Shadow Sloped Depth Bias", 0x5574, ParameterType.FLOAT, false),
+ //new Parameter<float>("Broad Area Shadow Max Depth Bias", 0x5578, ParameterType.FLOAT, false),
+ new Parameter<float>("Broad Area Shadow Max LOD Level", 0x5524, ParameterType.FLOAT, false),
+ new Parameter<float>("Broad Area Shadow Culling Size", 0x5528, ParameterType.FLOAT, false),
+ new Parameter<float>("Checkerboard Alpha Unroll Near", 0xE964, ParameterType.FLOAT, false),
+ new Parameter<float>("Checkerboard Alpha Unroll Far", 0xE968, ParameterType.FLOAT, false),
+ new Parameter<float>("Checkerboard History Blend Rate", 0xE96C, ParameterType.FLOAT, false),
+ new Parameter<byte>("Checkerboard Sanitize Color", 0xE972, ParameterType.BOOL, false),
+ new Parameter<byte>("Checkerboard Blend Dither", 0xE973, ParameterType.BOOL, false),
+ new Parameter<float>("Checkerboard BBox Strength", 0xE974, ParameterType.FLOAT, false),
+ new Parameter<float>("Checkerboard Dither Passthru Weight", 0xE978, ParameterType.FLOAT, false),
+ new Parameter<float>("Checkerboard Dither Filtered Weight", 0xE97C, ParameterType.FLOAT, false),
+ new Parameter<byte>("Checkerboard Continous History Reset", 0xE971, ParameterType.BOOL, false),
+ new Parameter<float>("Snow Field 4 Global LOD Param", 0x5718, ParameterType.FLOAT, false)
+ };
+
+ private delegate nint CreateFXAAObject();
+ private delegate nint CreateFXAAObject2(nint unknownPtr);
+ private delegate nint DestroyFXAAObject(nint fxaaObjectInternal, int unknownInt);
+ private Hook<CreateFXAAObject>? createFXAAObject;
+ private Hook<CreateFXAAObject2>? createFXAAObject2;
+ private Hook<DestroyFXAAObject>? destroyFXAAObject;
+ private nint fxaaObject = 0x0;
+ private static Parameter[] fxaaParameters = {
+ new Parameter<float>("FXAA Subpix", 0x178, ParameterType.FLOAT, false, null, 0.0f, 1.0f),
+ new Parameter<float>("FXAA Edge Threshold", 0x17C, ParameterType.FLOAT, false, 0.001f, 0.0f, 1.0f),
+ new Parameter<float>("FXAA Edge Threshold Min", 0x180, ParameterType.FLOAT, false, 0.001f, 0.0f, 1.0f)
+ };
+
+ private delegate nint CreateDofObject();
+ private delegate nint CreateDofObject2(nint unknownPtr);
+ private delegate nint DestroyDofObject(nint dofObjectInternal, int unknownInt);
+ private Hook<CreateDofObject>? createDofObject;
+ private Hook<CreateDofObject2>? createDofObject2;
+ private Hook<DestroyDofObject>? destroyDofObject;
+ private delegate void UpdateDofParams(nint unknownPtr);
+ private Hook<UpdateDofParams>? updateDofParams;
+ private nint dofObject = 0x0;
+ private static Parameter[] dofParameters = {
+ new Parameter<byte>("Enabled", 0x1DD, ParameterType.BOOL, false),
+ new Parameter<byte>("New Version", 0x1DC, ParameterType.BOOL, false),
+ new Parameter<float>("F Number", 0x1A0, ParameterType.FLOAT, true, 0.001f),
+ new Parameter<float>("Sensor Size", 0x1A4, ParameterType.FLOAT, true, 0.001f),
+ new Parameter<float>("Focus Distance", 0x1A8, ParameterType.FLOAT, true, 0.2f),
+ new Parameter<float>("Near Coef", 0x1CC, ParameterType.FLOAT, false, 0.001f),
+ new Parameter<float>("Far Coef", 0x1C8, ParameterType.FLOAT, false, 0.001f),
+ new Parameter<byte>("Near Enable", 0x1DE, ParameterType.BOOL, false),
+ new Parameter<byte>("Far Enable", 0x1DF, ParameterType.BOOL, false),
+ new Parameter<byte>("Debug Draw", 0x1E0, ParameterType.BOOL, false),
+ new Parameter<float>("Radius", 0x1D0, ParameterType.FLOAT, false, 0.001f),
+ new Parameter<float>("Depth Scale Foreground", 0x1D4, ParameterType.FLOAT, false, 0.0001f),
+ new Parameter<float>("Aspect", 0x1D8, ParameterType.FLOAT, false, 0.001f),
+ new Parameter<byte>("Vignetting Enabled", 0x200, ParameterType.BOOL, true),
+ new Parameter<byte>("Vignetting Ellipse", 0x201, ParameterType.BOOL, true),
+ new Parameter<float>("Vignetting Ellipticity", 0x204, ParameterType.FLOAT, true),
+ new Parameter<float>("Vignetting Offset", 0x1F8, ParameterType.FLOAT, true),
+ new Parameter<float>("Vignetting Pow", 0x1FC, ParameterType.FLOAT, true),
+ new Parameter<int>("Vignetting Color", 0x208, ParameterType.COLOR, true)
+ };
+
+ private delegate nint CreateMotionBlurObject();
+ private delegate nint CreateMotionBlurObject2(nint unknownPtr);
+ private delegate nint DestroyMotionBlurObject(nint motionBlurObjectInternal, int unknownInt);
+ private Hook<CreateMotionBlurObject>? createMotionBlurObject;
+ private Hook<CreateMotionBlurObject2>? createMotionBlurObject2;
+ private Hook<DestroyMotionBlurObject>? destroyMotionBlurObject;
+ private delegate void UpdateMotionBlurParams(nint unknownPtr, nint unknownPtr2);
+ private Hook<UpdateMotionBlurParams>? updateMotionBlurParams;
+ private nint motionBlurObject = 0x0;
+ private static Parameter[] motionBlurParameters = {
+ new Parameter<int>("Type", 0x168, ParameterType.INT, false, 1),
+ new Parameter<int>("Sample Num", 0x180, ParameterType.INT, false, 1),
+ new Parameter<float>("Shutter Speed", 0x184, ParameterType.FLOAT, true),
+ new Parameter<float>("Fur Shutter Speed", 0x188, ParameterType.FLOAT, false),
+ new Parameter<float>("Blur Threshold", 0x18C, ParameterType.FLOAT, false)
+ };
+
+ private delegate nint CreateBloomObject();
+ private delegate nint CreateBloomObject2(nint unknownPtr);
+ private delegate nint DestroyBloomObject(nint bloomObjectInternal, int unknownInt);
+ private Hook<CreateBloomObject>? createBloomObject;
+ private Hook<CreateBloomObject2>? createBloomObject2;
+ private Hook<DestroyBloomObject>? destroyBloomObject;
+ private nint bloomObject = 0x0;
+ private static Parameter[] bloomParameters = {
+ new Parameter<byte>("Enabled", 0x48, ParameterType.BOOL, false),
+ new Parameter<float>("Threshold", 0x204, ParameterType.FLOAT, false),
+ new Parameter<float>("Renormalize", 0x208, ParameterType.FLOAT, false),
+ new Parameter<float>("Dispersion for CBR", 0x210, ParameterType.FLOAT, false),
+ new Parameter<byte>("is SRGB Gamut", 0x214, ParameterType.BOOL, false),
+ new Parameter<byte>("Enable Optimize", 0x215, ParameterType.BOOL, false),
+ new Parameter<int>("Color", 0x200, ParameterType.COLOR, false),
+ new Parameter<float>("Dirt Color", 0x230, ParameterType.FLOAT, false),
+ new Parameter<byte>("Flip Dirt Intensity", 0x240, ParameterType.BOOL, false),
+ new Parameter<int>("Downsample Count", 0x168, ParameterType.INT, false),
+ new Parameter<int>("Reduction Resolution", 0x16C, ParameterType.INT, false),
+ new Parameter<byte>("Compute Luminance", 0x241, ParameterType.BOOL, false)
+ };
+
+ private delegate nint CreateLightingObject();
+ private delegate nint DestroyLightingObject(nint lightingObjectInternal, int unknownInt);
+ private Hook<CreateLightingObject>? createLightingObject;
+ private Hook<DestroyLightingObject>? destroyLightingObject;
+ private nint lightingObject = 0x0;
/*
+ Compute Luminance (bool) +0x170
+ Luminance Version (int) +0x168
+ LUT Blend (bool) +0x1C8
+ Vfx LUT Blend (bool) +0x1D0
+ Input Color Linear to PQ (bool) +0x1A1
+ Output Color PQ to Linear (bool) +0x1A0
+ */
+ private static Parameter[] lightingParameters = {
+ new Parameter<int>("Tone Map Type", 0x16C, ParameterType.INT, false, 1, 1, 7),
+ new Parameter<float>("Shoulder Strength", 0x168, ParameterType.FLOAT, false),
+ new Parameter<float>("Linear Strength", 0x178, ParameterType.FLOAT, false),
+ new Parameter<float>("Linear Angle", 0x17C, ParameterType.FLOAT, false),
+ new Parameter<float>("Toe Strength", 0x180, ParameterType.FLOAT, false),
+ new Parameter<float>("Toe Num", 0x184, ParameterType.FLOAT, false),
+ new Parameter<float>("White Point", 0x18C, ParameterType.FLOAT, false),
+ new Parameter<byte>("Enable Color Grading", 0x1D8, ParameterType.BOOL, false),
+ new Parameter<float>("Dispersion", 0x19C, ParameterType.FLOAT, false),
+ new Parameter<float>("Edge Sharpness", 0x198, ParameterType.FLOAT, false),
+ new Parameter<byte>("Downsample Volume", 0x210, ParameterType.BOOL, false)
+ };
+
+ private delegate void UpdateShadowParams(nint shadowObjectInternal, nint stackOffset);
+ private Hook<UpdateShadowParams>? updateShadowParams;
+ private Hook<UpdateShadowParams>? staticShadowParams;
+ private static Parameter[] shadowParameters1 = {
+ };
+ private static Parameter[] shadowParameters2 = {
+ new Parameter<float>("Color", 0xE0, ParameterType.FLOAT, true),
+ new Parameter<float>("Intensity", 0xF4, ParameterType.FLOAT, true),
+ new Parameter<float>("Min Roughness", 0xFC, ParameterType.FLOAT, true),
+ new Parameter<float>("Dir", 0x110, ParameterType.VECTOR4, true),
+ new Parameter<byte>("Group", 0x14, ParameterType.BYTE, true),
+ new Parameter<byte>("Priority", 0x1A, ParameterType.BYTE, true),
+ new Parameter<byte>("Primary", 0x1D, ParameterType.BOOL, true),
+ new Parameter<byte>("Shadow Cast", 0x23, ParameterType.BOOL, true),
+ new Parameter<float>("Near Clip Distance", 0x28, ParameterType.FLOAT, true),
+ new Parameter<float>("Shadow Sloped Depth Bias", 0x40, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<int>("Shadow Map Size", 0x30, ParameterType.INT, true),
+ new Parameter<float>("Shadow Depth Bias", 0x38, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<float>("Shadow Max Depth Bias", 0x48, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<byte>("Do Volumetric", 0x1F, ParameterType.BOOL, true),
+ new Parameter<byte>("Draw Mode", 0x21, ParameterType.BYTE, true),
+ new Parameter<float>("Shadow Distance", 0x6C, ParameterType.FLOAT, true, 5.0f),
+ new Parameter<float>("Shadow Backforward Distance", 0x7C, ParameterType.FLOAT, true, 5.0f),
+ new Parameter<float>("Shadow Distribution", 0x74, ParameterType.FLOAT, true, 0.001f),
+ new Parameter<byte>("Manual Split", 0x4D, ParameterType.BOOL, true),
+ new Parameter<byte>("Individual Shadow Bias", 0x81, ParameterType.BOOL, true),
+ new Parameter<float>("Manual Split Distance[0]", 0x54, ParameterType.FLOAT, true),
+ new Parameter<float>("Cascade Depth Bias[0]", 0x88, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<float>("Cascade Sloped Depth Bias[0]", 0xA0, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<float>("Cascade Max Depth Bias[0]", 0xB8, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<float>("Manual Split Distance[1]", 0x5C, ParameterType.FLOAT, true),
+ new Parameter<float>("Cascade Depth Bias[1]", 0x90, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<float>("Cascade Sloped Depth Bias[1]", 0xA8, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<float>("Cascade Max Depth Bias[1]", 0xC0, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<float>("Manual Split Distance[2]", 0x64, ParameterType.FLOAT, true),
+ new Parameter<float>("Cascade Depth Bias[2]", 0x98, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<float>("Cascade Sloped Depth Bias[2]", 0xB0, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<float>("Cascade Max Depth Bias[2]", 0xC8, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<float>("Projection Scale", 0x134, ParameterType.FLOAT, true),
+ new Parameter<float>("Projection Offset Speed", 0x144, ParameterType.FLOAT, true),
+ new Parameter<float>("Projection Up", 0x160, ParameterType.VECTOR3, true),
+ new Parameter<byte>("Shadow Cascade Mode", 0x174, ParameterType.BYTE, true, 1, 0, 3),
+ new Parameter<float>("Shadow Cascade 2Way Bias", 0x17C, ParameterType.FLOAT, true),
+ new Parameter<float>("Shadow Culling Length[0]", 0x184, ParameterType.FLOAT, true),
+ new Parameter<float>("Shadow Culling Length[1]", 0x18C, ParameterType.FLOAT, true),
+ new Parameter<float>("Shadow Culling Length[2]", 0x194, ParameterType.FLOAT, true),
+ new Parameter<float>("Broad Area Shadow Range", 0x1B0, ParameterType.FLOAT, true, 0.0001f),
+ new Parameter<float>("Broad Area Shadow Depth Bias", 0x1C4, ParameterType.FLOAT, true, 0.0001f),
+ new Parameter<float>("Broad Area Shadow Sloped Depth Bias", 0x1CC, ParameterType.FLOAT, true, 0.0001f),
+ new Parameter<float>("Broad Area Shadow Max Depth Bias", 0x1D4, ParameterType.FLOAT, true, 0.0001f),
+ new Parameter<int>("Primary Shadow Sample Num", 0x1DC, ParameterType.INT, true),
+ new Parameter<float>("Primary Shadow Radius", 0x1EC, ParameterType.FLOAT, true, 0.0001f),
+ new Parameter<float>("Fov", 0x1F4, ParameterType.FLOAT, true, 0.0001f),
+ new Parameter<byte>("Is Fixed Fov Mode", 0x1F9, ParameterType.BOOL, true),
+ new Parameter<float>("Discretization Angle", 0x200, ParameterType.FLOAT, true, 0.0001f),
+ new Parameter<byte>("Is Discretization Fov Mode", 0x205, ParameterType.BOOL, true)
+ };
+
+ private static Parameter[] allParameters = sceneParameters
+ .Concat(ssaoParameters)
+ .Concat(sslrParameters)
+ .Concat(fxaaParameters)
+ .Concat(dofParameters)
+ .Concat(motionBlurParameters)
+ .Concat(bloomParameters)
+ .Concat(lightingParameters)
+ .Concat(shadowParameters2).ToArray();
+
+ private bool tripleShadowResolution = false;
+ private NativeAction<int> setShadowQuality;
+ private Patch shadowRes1_3x;
+ private Patch shadowRes1_1;
+ private Patch shadowRes1_2;
+ private Patch shadowRes1_3;
+ private Patch shadowRes2;
+ private Patch shadowRes3;
+ private Patch shadowRes4_Limit;
+
+ private void tripleShadowResEnable()
+ {
+ shadowRes1_3x.Enable();
+ shadowRes1_1.Enable();
+ shadowRes1_2.Enable();
+ shadowRes1_3.Enable();
+ shadowRes2.Enable();
+ shadowRes3.Enable();
+ //shadowRes4_Limit.Enable();
+ }
+
+ private void tripleShadowResDisable()
+ {
+ shadowRes1_3x.Disable();
+ shadowRes1_1.Disable();
+ shadowRes1_2.Disable();
+ shadowRes1_3.Disable();
+ shadowRes2.Disable();
+ shadowRes3.Disable();
+ //shadowRes4_Limit.Disable();
+ }
+
+ private bool disableVolumeDownsample = false;
+ private Patch volumeSars1;
+ private Patch volumeSars2;
+ private Patch volumeSars3;
+ private Patch volumeSars4;
+ private Patch volumeSars5;
+ private Patch volumeSars6;
+ private Patch volumeSars7;
+ private Patch volumeSars8;
+ private Patch volumeSars9;
+
+ private void disableVolumeDownsampleEnable()
+ {
+ volumeSars1.Enable();
+ volumeSars2.Enable();
+ volumeSars3.Enable();
+ volumeSars4.Enable();
+ volumeSars5.Enable();
+ volumeSars6.Enable();
+ volumeSars7.Enable();
+ volumeSars8.Enable();
+ volumeSars9.Enable();
+ }
+
+ private void disableVolumeDownsampleDisable()
+ {
+ volumeSars1.Disable();
+ volumeSars2.Disable();
+ volumeSars3.Disable();
+ volumeSars4.Disable();
+ volumeSars5.Disable();
+ volumeSars6.Disable();
+ volumeSars7.Disable();
+ volumeSars8.Disable();
+ volumeSars9.Disable();
+ }
+
+ private bool higherVolumeQuality = false;
+ private Patch value2ForVolumeQuality;
+
+ private bool disableLODLimits = false;
+ private Patch defaultViewModeLODLimit;
+ private Patch defaultViewModeLODLimit_1;
+ private Patch defaultViewModeLODLimit_2;
+
+ private void disableLODLimitsEnable()
+ {
+ defaultViewModeLODLimit.Enable();
+ defaultViewModeLODLimit_1.Enable();
+ defaultViewModeLODLimit_2.Enable();
+ }
+
+ private void disableLODLimitsDisable()
+ {
+ defaultViewModeLODLimit.Disable();
+ defaultViewModeLODLimit_1.Disable();
+ defaultViewModeLODLimit_2.Disable();
+ }
+
+ private bool largerFoliageSwayRange = false;
+ private Patch addressHigherValueForFoliageSway;
+
+ private bool disableReducedRateAnimations = false;
+ private Patch zeroFrameSkip;
+
+ private class Light
+ {
+ public nint Object;
+ public Parameter[] Parameters = {
+ new Parameter<byte>("Group", 0x13C, ParameterType.BYTE, false, 1),
+ new Parameter<float>("Position", 0x5A0, ParameterType.VECTOR3, true, 0.1f),
+ new Parameter<float>("Intensity", 0x8A8, ParameterType.FLOAT, true, 0.1f),
+ new Parameter<float>("Radius", 0x6A0, ParameterType.FLOAT, true, 0.1f),
+ new Parameter<float>("Depth Bias", 0x57C, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<float>("Sloped Depth Bias", 0x580, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<float>("Max Depth Bias", 0x584, ParameterType.FLOAT, true, 0.00001f),
+ new Parameter<int>("Color", 0x140, ParameterType.COLOR, true),
+ new Parameter<float>("Cone", 0x5F0, ParameterType.FLOAT, true, 0.1f),
+ new Parameter<float>("Spread", 0x5F4, ParameterType.FLOAT, true, 0.1f),
+ new Parameter<int>("Shadow Cast", 0x138, ParameterType.FLAG, false, (1 << 23)),
+ new Parameter<byte>("Draw Mode", 0x48, ParameterType.BYTE, false, 1),
+ new Parameter<byte>("Target Mode", 0x5F8, ParameterType.BOOL, true),
+ new Parameter<byte>("Do Volumetric", 0x590, ParameterType.BOOL, true),
+ new Parameter<byte>("Use Umbra", 0x591, ParameterType.BOOL, true),
+ new Parameter<byte>("Enable Camera LOD", 0x592, ParameterType.BOOL, true)
+ };
+
+ public Light(nint lightObject, Vector3 pos)
+ {
+ Object = lightObject;
+ foreach (Parameter param in Parameters)
+ {
+ param.OverrideOn(false);
+ }
+ Parameters[0].OverrideValue(default, 3);
+ Parameters[1].OverrideValue(new Vector4(pos.X, pos.Y, pos.Z, 0.0f), 0);
+ Parameters[2].OverrideValue(new Vector4(10.0f, 0.0f, 0.0f, 0.0f), 0);
+ foreach (Parameter param in Parameters)
+ {
+ param.Update(lightObject);
+ }
+ }
+ }
+
+ private int requestLightType = 2;
+ private NativeFunction<int, nint> createLight;
+ private List<Light> ourLights = new List<Light>();
+ private NativeAction<nint, int, nint, int> addToScene;
+ private NativeAction<nint> removeFromScene;
+ private delegate void UpdateLights(nint lightObject);
+ private Hook<UpdateLights>? updateLights;
+
public PluginData Initialize()
{
- PluginData data = new PluginData();
- data.ExportedFunctions.Add(("SetDofForceOff", SetDofForceOff));
- data.ExportedFunctions.Add(("GetDofDisabled", GetDofDisabled));
- return data;
+ onAreaChange = Hook.Create<OnAreaChange>(0x141AC27D0, OnAreaChangeHook); // nint
+
+ // These run during cutscenes.
+ updateSSAOParams = Hook.Create<UpdateSSAOParams>(0x1416D8B10, UpdateSSAOParamsHook); // nint, nint
+ updateSSLRParams = Hook.Create<UpdateSSLRParams>(0x1416DA3F0, UpdateSSLRParamsHook); // nint
+
+ createFXAAObject = Hook.Create<CreateFXAAObject>(0x142393560, CreateFXAAObjectHook);
+ createFXAAObject2 = Hook.Create<CreateFXAAObject2>(0x142393680, CreateFXAAObject2Hook); // nint
+ destroyFXAAObject = Hook.Create<DestroyFXAAObject>(0x142393740, DestroyFXAAObjectHook); // nint, int
+
+ createDofObject = Hook.Create<CreateDofObject>(0x142421E80, CreateDofObjectHook);
+ createDofObject2 = Hook.Create<CreateDofObject2>(0x1424220A0, CreateDofObject2Hook); // nint
+ destroyDofObject = Hook.Create<DestroyDofObject>(0x142422290, DestroyDofObjectHook); // nint, int
+ updateDofParams = Hook.Create<UpdateDofParams>(0x1412BA6A0, UpdateDofParamsHook); // nint
+
+ createMotionBlurObject = Hook.Create<CreateMotionBlurObject>(0x1424C95E0, CreateMotionBlurObjectHook);
+ createMotionBlurObject2 = Hook.Create<CreateMotionBlurObject2>(0x1424C9740, CreateMotionBlurObject2Hook); // nint
+ destroyMotionBlurObject = Hook.Create<DestroyMotionBlurObject>(0x1424C97E0, DestroyMotionBlurObjectHook); // nint, int
+ updateMotionBlurParams = Hook.Create<UpdateMotionBlurParams>(0x1424CADF0, UpdateMotionBlurParamsHook); // nint, nint
+
+ createBloomObject = Hook.Create<CreateBloomObject>(0x1424CB3C0, CreateBloomObjectHook);
+ createBloomObject2 = Hook.Create<CreateBloomObject2>(0x1424CB5E0, CreateBloomObject2Hook); // nint
+ destroyBloomObject = Hook.Create<DestroyBloomObject>(0x1424CB750, DestroyBloomObjectHook); // nint, int
+
+ createLightingObject = Hook.Create<CreateLightingObject>(0x1424CDE20, CreateLightingObjectHook);
+ destroyLightingObject = Hook.Create<DestroyLightingObject>(0x1424CE380, DestroyLightingObjectHook); // nint, int
+
+ 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"));
+#if ADDR_ASSERTS
+ Assert(addr == 0x141AB2260); // nint, nint
+#endif
+ updateShadowParams = Hook.Create<UpdateShadowParams>(addr, UpdateShadowParamsHook);
+ staticShadowParams = Hook.Create<UpdateShadowParams>(0x1416D94F0, StaticShadowParamsHook); // nint, nint
+
+ setShadowQuality = new NativeAction<int>(0x14043FF80);
+
+ 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 ?? ?? ?? ??"));
+#if ADDR_ASSERTS
+ Assert(addr == 0x14043FF80);
+ Assert(MemoryUtil.Read<float>(0x142E4FE5C) == 3.0f);
+#endif
+ shadowRes1_3x = new Patch(addr + 0x8, [0xD0, 0xFE, 0xA0, 0x02]); // 3.0.
+ 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.
+
+ // shadowRes2/3 control the detail of the infrequently updated fallback shadows.
+ 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"));
+#if ADDR_ASSERTS
+ Assert(addr == 0x142287A50);
+#endif
+ shadowRes2 = new Patch(addr + 0x3F, [
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC3,
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC3,
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC3, // High.
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0xC3, // Mid.
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xC3 // Low.
+ ]);
+
+ addr = PatternScanner.FindFirst(Pattern.FromString("89 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"));
+#if ADDR_ASSERTS
+ Assert(addr == 0x142287AD0);
+#endif
+ shadowRes3 = new Patch(addr + 0x34, [
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC3,
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC3,
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC3,
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0xC3,
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xC3
+ ]);
+
+ addr = PatternScanner.FindFirst(Pattern.FromString("89 91 00 55 00 00 83 FA 05 77 41 48 63 C2 4C 8D 05 ?? ?? ?? ?? 41 8B 94 80 84 8B 28 02 49 03 D0 FF E2 B8 00 08 00 00"));
+#if ADDR_ASSERTS
+ Assert(addr == 0x142288B00);
+#endif
+ // This value controls the shadow map texture resolution. 16384x16384 is likely the limit for many drivers
+ // and any value higher would crash. Keeping this at the default value (unpatched) *should* work unless the
+ // game does something unpredictable. At 3x Shadow Resolution + High, the shadow map will be 8448x8448.
+ shadowRes4_Limit = new Patch(addr + 0x29, [ // N/64 = 255, fractional values closer to 256 not tested.
+ 0xB8, 0x40, 0x15, 0x00, 0x00, 0xEB, 0x21 // This case is used for Low, Medium and High in-game.
+ ]);
+
+ volumeSars1 = new Patch((nint)0x1424D0159, [0x90, 0x90]);
+ volumeSars2 = new Patch((nint)0x1424D01A0, [0x90, 0x90]);
+ volumeSars3 = new Patch((nint)0x1424D01C6, [0x90, 0x90]);
+ volumeSars4 = new Patch((nint)0x1424D0219, [0x90, 0x90]);
+ volumeSars5 = new Patch((nint)0x1424D0242, [0x90, 0x90]);
+ volumeSars6 = new Patch((nint)0x1424D029D, [0x90, 0x90]);
+ volumeSars7 = new Patch((nint)0x1424D02C6, [0x90, 0x90]);
+ volumeSars8 = new Patch((nint)0x1424D0321, [0x90, 0x90]);
+ volumeSars9 = new Patch((nint)0x1424D034A, [0x90, 0x90]);
+
+ value2ForVolumeQuality = new Patch((nint)0x142389652, [0xB8, 0x02, 0x00, 0x00, 0x00, 0x90]);
+
+ // Gameplay.
+ addr = PatternScanner.FindFirst(Pattern.FromString("80 BB 34 EC 00 00 00 88 8B 31 EC 00 00 C6 83 30 EC 00 00 00 74 1C C6 83 34 EC 00 00 00 48 8B 0D 68 4B 4F 03 80 B9 58 02 00 00 00 75 05 E8 5A F5 01 00 48 8B CB E8 E2 05 00 00 83 BB DC EB 00 00 06 74 0A C7 83 DC EB 00 00 06 00 00 00"));
+#if ADDR_ASSERTS
+ ssert(addr == 0x141B1A0B4);
+#endif
+ defaultViewModeLODLimit = new Patch(addr + 0x40, [0x07, 0x74, 0x0A, 0xC7, 0x83, 0xDC, 0xEB, 0x00, 0x00, 0x07]);
+
+ // In room.
+ addr = PatternScanner.FindFirst(Pattern.FromString("8B 9F CC 00 00 00 81 FB F9 01 00 00 74 0C 8B CB E8 95 3F 65 01 83 F8 05 75 11 48 8B 0D 61 C8 F6 04 BA 02 00 00 00 E8 DF 2D 8C 01 48 8B 0D A0 C7 F6 04 8B D3"));
+#if ADDR_ASSERTS
+ Assert(addr == 0x140257AE6);
+#endif
+ defaultViewModeLODLimit_1 = new Patch(addr + 0x22, [0x07]);
+
+ // Forging/Changing Equipment.
+ addr = PatternScanner.FindFirst(Pattern.FromString("BA 02 00 00 00 E8 6E C0 80 00 48 8B 74 24 38 48 8B 57 28 48 8D 4F 30 E8 4C 79 B4 FE 48 8B 0D 0D FF A6 03 BA 04 00 00 00 E8 8B 64 3C 00 48 8B 05 D4 01 A7 03 80 B8 FD 46 01 00 00"));
+#if ADDR_ASSERTS
+ Assert(addr == 0x141754438);
+#endif
+ defaultViewModeLODLimit_2 = new Patch(addr + 0x24, [0x07]);
+
+ addr = PatternScanner.FindFirst(Pattern.FromString("74 4D 33 C0 48 81 C1 00 02 00 00 F3 0F 10 11 0F 2F CA 72 0C FF C0 48 83 C1 04 83 F8 03 72 EC C3"));
+#if ADDR_ASSERTS
+ Assert(addr == 0x1426D89CA);
+#endif
+ addressHigherValueForFoliageSway = new Patch(addr + 0x7, [0x04]);
+
+ // Found using mFrameSkipNum annotation from MHW-DTI-Dumps.
+ zeroFrameSkip = new Patch((nint)0x142246948, [0x31, 0xC0, 0x90, 0x90, 0x90, 0x90]);
+
+ // The game will crash when trying to switch to the FULL_RES path for SSR. It's likley because
+ // it tries to access resources (shader, buffer, texture, etc.) that are not loaded.
+ // Ex: MonsterHunterWorld.exe+228C4A7 - mov rdi,[rdi+00000120] # Attempted read.
+ // MonsterHunterWorld.exe+259329B - lea rcx,[rdi+00000120] # Zero.
+ // The code that zero's these addresses looks like a shell of where they would be loaded. So my assumption
+ // is that it's compiled out and that this method of increasing the SSR resolution will not work.
+ // Though, it may still be possible by finagling the parameters of the half res case.
+ /*
+ // Attempt to forcefully enable FULL_RES path for SSR.
+ ssrRes1 = new Patch((nint)0x14228894D, [0x0F, 0x85, 0xB9, 0xAA, 0x30, 0x00]);
+ ssrRes1_1 = new Patch((nint)0x14259340C, [0xC6, 0x81, 0x28, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]);
+ ssrRes2 = new Patch((nint)0x14228897D, [0x0F, 0x85, 0x99, 0xAA, 0x30, 0x00]);
+ ssrRes2_1 = new Patch((nint)0x14259341C, [0xC6, 0x81, 0x30, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]);
+ ssrRes3 = new Patch((nint)0x1422889AD, [0x0F, 0x85, 0x79, 0xAA, 0x30, 0x00]);
+ ssrRes3_1 = new Patch((nint)0x14259342C, [0xC6, 0x81, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]);
+ ssrRes4 = new Patch((nint)0x14259268C, [0x41, 0xC7, 0x86, 0x28, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xC7, 0x86, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xC7, 0x86, 0x30, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xC7, 0x86, 0x34, 0x02, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x41, 0xC7, 0x86, 0x38, 0x02, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x41, 0xC6, 0x86, 0x3C, 0x02, 0x00, 0x00, 0x01]);
+ */
+ // None of these work either.
+ /*
+ // Don't scale resolution by SSR Factor.
+ ssrRes10 = new Patch((nint)0x142592DEF, [0x90, 0x90, 0x90, 0x90]);
+ ssrRes11 = new Patch((nint)0x142592E00, [0x90, 0x90, 0x90, 0x90]);
+
+ // Make SSR Factor 1.0.
+ ssrRes12 = new Patch((nint)0x1425926B8 + 0x7, [0x00, 0x00, 0x80, 0x3F]);
+ */
+ /* Double width and height (3rd and 4th parameter).
+ initSSRHook = Hook.Create<initSSR>(0x1425924D5, InitSSRHook); // nint, nint, int, int
+ increaseSSRMipSize1 = new Patch((nint)0x142592EBA + 0x2, [0x2]);
+ increaseSSRMipSize2 = new Patch((nint)0x142592ED0 + 0x2, [0x2]);
+ */
+
+ createLight = new NativeFunction<int, nint>(0x1418A3EF0);
+ addToScene = new NativeAction<nint, int, nint, int>(0x142219070);
+ removeFromScene = new NativeAction<nint>(0x142228F10);
+ updateLights = Hook.Create<UpdateLights>(0x141F88F30, UpdateLightsHook);
+
+ return new PluginData();
}
- */
- public void OnPreMain()
+ public void OnLoad()
{
- unchecked
+ Config config = ConfigManager.GetConfig<Config>(this);
+ foreach (Stage area in Enum.GetValues(typeof(Stage)))
{
- jmpOverDof = new Patch((nint)0x1424233C6, [0xEB]); // je -> jmp.
+ if (!config.Overrides.ContainsKey(area))
+ {
+ config.Overrides.Add(area, new List<Override>());
+ }
+ }
+ List<Override> globalOverrides = config.Overrides[Stage.InfinityOfNothingHandler];
+ foreach (Override ovG in globalOverrides)
+ {
+ ovG.Set();
+ }
+ ConfigManager.SaveConfig<Config>(this);
+ }
+
+ public void OnUpdate(float deltaTime)
+ {
+ if (fxaaObject != 0x0)
+ {
+ foreach (Parameter param in fxaaParameters)
+ {
+ if (!param.PerFrame)
+ {
+ param.Update(fxaaObject);
+ }
+ }
+ }
+ if (dofObject != 0x0)
+ {
+ foreach (Parameter param in dofParameters)
+ {
+ if (!param.PerFrame)
+ {
+ param.Update(dofObject);
+ }
+ }
+ }
+ if (motionBlurObject != 0x0)
+ {
+ foreach (Parameter param in motionBlurParameters)
+ {
+ if (!param.PerFrame)
+ {
+ param.Update(motionBlurObject);
+ }
+ }
+ }
+ if (bloomObject != 0x0)
+ {
+ foreach (Parameter param in bloomParameters)
+ {
+ if (!param.PerFrame)
+ {
+ param.Update(bloomObject);
+ }
+ }
+ }
+ if (lightingObject != 0x0)
+ {
+ foreach (Parameter param in lightingParameters)
+ {
+ if (!param.PerFrame)
+ {
+ param.Update(lightingObject);
+ }
+ }
+ }
+ if (sMhScene.Instance != 0x0)
+ {
+ foreach (Parameter param in ssaoParameters)
+ {
+ if (!param.PerFrame)
+ {
+ param.Update(sMhScene.Instance);
+ }
+ }
+ foreach (Parameter param in sslrParameters)
+ {
+ if (!param.PerFrame)
+ {
+ param.Update(sMhScene.Instance);
+ }
+ }
+ foreach (Parameter param in sceneParameters)
+ {
+ if (!param.PerFrame)
+ {
+ param.Update(sMhScene.Instance);
+ }
+ }
+ }
+ }
+
+ private void UpdateSSAOParamsHook(nint sceneObjectInternal, nint stackOffset)
+ {
+ updateSSAOParams!.Original(sceneObjectInternal, stackOffset);
+ foreach (Parameter param in ssaoParameters)
+ {
+ param.Update(sMhScene.Instance);
+ }
+ }
+
+ private void UpdateSSLRParamsHook(nint stackOffset)
+ {
+ updateSSLRParams!.Original(stackOffset);
+ foreach (Parameter param in sslrParameters)
+ {
+ param.Update(sMhScene.Instance);
+ }
+ }
+
+ private nint CreateFXAAObjectHook()
+ {
+ fxaaObject = createFXAAObject!.Original();
+ foreach (Parameter param in fxaaParameters)
+ {
+ param.Update(fxaaObject);
+ }
+ return fxaaObject;
+ }
+
+ private nint CreateFXAAObject2Hook(nint unknownPtr)
+ {
+ fxaaObject = createFXAAObject2!.Original(unknownPtr);
+ foreach (Parameter param in fxaaParameters)
+ {
+ param.Update(fxaaObject);
+ }
+ return fxaaObject;
+ }
+
+ private nint DestroyFXAAObjectHook(nint fxaaObjectInternal, int unknownInt)
+ {
+ Assert(unknownInt == 1);
+ if (fxaaObject == fxaaObjectInternal)
+ {
+ fxaaObject = 0x0;
+ foreach (Parameter param in fxaaParameters)
+ {
+ param.Update(fxaaObject);
+ }
+ }
+ return destroyFXAAObject!.Original(fxaaObjectInternal, unknownInt);
+ }
+
+ private nint CreateDofObjectHook()
+ {
+ dofObject = createDofObject!.Original();
+ foreach (Parameter param in dofParameters)
+ {
+ param.Update(dofObject);
+ }
+ return dofObject;
+ }
+
+ private nint CreateDofObject2Hook(nint unknownPtr)
+ {
+ dofObject = createDofObject2!.Original(unknownPtr);
+ foreach (Parameter param in dofParameters)
+ {
+ param.Update(dofObject);
+ }
+ return dofObject;
+ }
+
+ private nint DestroyDofObjectHook(nint dofObjectInternal, int unknownInt)
+ {
+ Assert(unknownInt == 1);
+ if (dofObject == dofObjectInternal)
+ {
+ dofObject = 0x0;
+ foreach (Parameter param in dofParameters)
+ {
+ param.Update(dofObject);
+ }
+ }
+ return destroyDofObject!.Original(dofObjectInternal, unknownInt);
+ }
+
+ private void UpdateDofParamsHook(nint unknownPtr)
+ {
+ updateDofParams!.Original(unknownPtr);
+ foreach (Parameter param in dofParameters)
+ {
+ if (param.PerFrame)
+ {
+ param.Update(dofObject);
+ }
+ }
+ }
+
+ private nint CreateMotionBlurObjectHook()
+ {
+ motionBlurObject = createMotionBlurObject!.Original();
+ foreach (Parameter param in motionBlurParameters)
+ {
+ param.Update(motionBlurObject);
+ }
+ return motionBlurObject;
+ }
+
+ private nint CreateMotionBlurObject2Hook(nint unknownPtr)
+ {
+ motionBlurObject = createMotionBlurObject2!.Original(unknownPtr);
+ foreach (Parameter param in motionBlurParameters)
+ {
+ param.Update(motionBlurObject);
+ }
+ return motionBlurObject;
+ }
+
+ private nint DestroyMotionBlurObjectHook(nint motionBlurObjectInternal, int unknownInt)
+ {
+ Assert(unknownInt == 1);
+ if (motionBlurObject == motionBlurObjectInternal)
+ {
+ motionBlurObject = 0x0;
+ foreach (Parameter param in motionBlurParameters)
+ {
+ param.Update(motionBlurObject);
+ }
+ }
+ return destroyMotionBlurObject!.Original(motionBlurObjectInternal, unknownInt);
+ }
+
+ private void UpdateMotionBlurParamsHook(nint unknownPtr, nint unknownPtr2)
+ {
+ foreach (Parameter param in motionBlurParameters)
+ {
+ if (param.PerFrame)
+ {
+ param.Update(motionBlurObject);
+ }
+ }
+ updateMotionBlurParams!.Original(unknownPtr, unknownPtr2);
+ }
+
+ private nint CreateBloomObjectHook()
+ {
+ bloomObject = createBloomObject!.Original();
+ foreach (Parameter param in bloomParameters)
+ {
+ param.Update(bloomObject);
+ }
+ return bloomObject;
+ }
+
+ private nint CreateBloomObject2Hook(nint unknownPtr)
+ {
+ bloomObject = createBloomObject2!.Original(unknownPtr);
+ foreach (Parameter param in bloomParameters)
+ {
+ param.Update(bloomObject);
+ }
+ return bloomObject;
+ }
+
+ private nint DestroyBloomObjectHook(nint bloomObjectInternal, int unknownInt)
+ {
+ Assert(unknownInt == 1);
+ if (bloomObject == bloomObjectInternal)
+ {
+ bloomObject = 0x0;
+ foreach (Parameter param in bloomParameters)
+ {
+ param.Update(bloomObject);
+ }
+ }
+ return destroyBloomObject!.Original(bloomObjectInternal, unknownInt);
+ }
+
+ private nint CreateLightingObjectHook()
+ {
+ lightingObject = createLightingObject!.Original();
+ foreach (Parameter param in lightingParameters)
+ {
+ param.Update(lightingObject);
+ }
+ return lightingObject;
+ }
+
+ private nint DestroyLightingObjectHook(nint lightingObjectInternal, int unknownInt)
+ {
+ Assert(unknownInt == 1);
+ if (lightingObject == lightingObjectInternal)
+ {
+ lightingObject = 0x0;
+ foreach (Parameter param in lightingParameters)
+ {
+ param.Update(lightingObject);
+ }
+ }
+ return destroyLightingObject!.Original(lightingObjectInternal, unknownInt);
+ }
+
+ private void UpdateShadowParamsHook(nint shadowObjectInternal, nint stackOffset)
+ {
+ ref nint rax = ref MemoryUtil.GetRef<nint>(stackOffset + 0x170);
+ nint shadowCascadeMode = rax >> 32;
+ bool firstPass = shadowCascadeMode == 3;
+
+ if (firstPass)
+ {
+ }
+ else
+ {
+ foreach (Parameter param in shadowParameters2)
+ {
+ param.Update(stackOffset);
+ }
+ }
+
+ updateShadowParams!.Original(shadowObjectInternal, stackOffset);
+ }
+
+ private void StaticShadowParamsHook(nint shadowObjectStatic, nint shadowObjectInternal)
+ {
+ if (shadowObjectInternal == 0x0)
+ {
+ foreach (Parameter param in shadowParameters1)
+ {
+ param.Update(shadowObjectStatic);
+ }
+ }
+ staticShadowParams!.Original(shadowObjectStatic, shadowObjectInternal);
+ }
+
+ private Stage previousStage = Stage.InfinityOfNothingHandler;
+ private Stage selectedStage = Stage.InfinityOfNothingHandler;
+ private static bool stageIsGlobal(Stage stage)
+ {
+ return stage == Stage.InfinityOfNothingHandler;
+ }
+
+ private void OnAreaChangeHook(nint unknownPtr)
+ {
+ onAreaChange!.Original(unknownPtr);
+ Stage stage = Area.CurrentStage;
+ if (stage == 0x0)
+ {
+ stage = Stage.InfinityOfNothingHandler;
+ }
+ if (stage == previousStage) return;
+ Config config = ConfigManager.GetConfig<Config>(this);
+ List<Override> prevOverrides = config.Overrides[previousStage];
+ previousStage = stage;
+ List<Override>? globalOverrides = null;
+ if (!stageIsGlobal(stage))
+ {
+ globalOverrides = config.Overrides[Stage.InfinityOfNothingHandler];
+ }
+ foreach (Override ovP in prevOverrides)
+ {
+ ovP.Unset();
+ if (globalOverrides != null && ovP.Param != null)
+ {
+ setIfOverridesContainsParam(globalOverrides, ovP.Param);
+ }
+ }
+ if (globalOverrides != null) // Stage isn't global.
+ {
+ List<Override> stageOverrides = config.Overrides[stage];
+ foreach (Override ovS in stageOverrides)
+ {
+ if (ovS.Param != null)
+ {
+ unsetIfOverridesContainsParam(globalOverrides, ovS.Param);
+ }
+ ovS.Set();
+ }
+ }
+ }
+
+ private void UpdateLightsHook(nint lightObject)
+ {
+ Light? ourLight = null;
+ for (int i = 0; i < ourLights.Count; i++)
+ {
+ if (lightObject == ourLights[i].Object)
+ {
+ ourLight = ourLights[i];
+ break;
+ }
+ }
+ updateLights!.Original(lightObject);
+ if (ourLight != null)
+ {
+ foreach (Parameter param in ourLight.Parameters)
+ {
+ param.Update(lightObject);
+ }
+ }
+ }
+
+ public void OnImGuiRender()
+ {
+ float width = ImGui.GetWindowWidth();
+ width /= (width / 600.0f);
+
+ if (ImGui.CollapsingHeader("Lights"))
+ {
+ ImGui.PushItemWidth(width * 0.25f);
+ ImGui.InputInt("Type", ref requestLightType, 1);
+ ImGui.SameLine();
+ if (ImGui.Button("New"))
+ {
+ nint lightObject = createLight.Invoke(requestLightType);
+ Vector3 pos = default;
+ Player? player = Player.MainPlayer;
+ if (player != null)
+ {
+ pos = player.Position;
+ pos.Y += 20.0f;
+ }
+ ourLights.Add(new Light(lightObject, pos));
+ // mov byte ptr[rsp+20],00 unaccounted for, hopefully it doesn't matter.
+ addToScene.Invoke(MemoryUtil.Read<nint>(0x1451238C8), 0x16, lightObject, 0x0);
+ }
+ ImGui.PopItemWidth();
+ ImGui.Separator();
+ for (int i = 0; i < ourLights.Count; i++)
+ {
+ Light light = ourLights[i];
+ ImGui.PushID(i);
+ ImGui.Text($"Address: {light.Object:X}");
+ foreach (Parameter param in light.Parameters)
+ {
+ 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);
+ ourLights.RemoveAt(i);
+ i--;
+ }
+ ImGui.PopID();
+ ImGui.Separator();
+ }
+ }
+
+ /*
+ if (ImGui.TextLink($"Current Stage: {Config.StageToString(Area.CurrentStage)}"))
+ {
+ if (Area.CurrentStage == 0)
+ {
+ selectedStage = Stage.InfinityOfNothingHandler;
+ }
+ else
+ {
+ selectedStage = Area.CurrentStage;
+ }
+ }
+ */
+ ImGui.Text($"Current Stage: {Config.StageToString(Area.CurrentStage)}");
+
+ ImGui.PushItemWidth(width * 0.35f);
+ if (ImGui.BeginCombo("##Stage", Config.StageToString(selectedStage)))
+ {
+ foreach (Stage area in Enum.GetValues(typeof(Stage)))
+ {
+ string name = Config.StageToString(area);
+ bool isSelected = selectedStage == area;
+ if (ImGui.Selectable(name, isSelected))
+ {
+ selectedStage = area;
+ }
+ if (isSelected) ImGui.SetItemDefaultFocus();
+ }
+ ImGui.EndCombo();
+ }
+ ImGui.SameLine();
+ if (ImGui.Button("Current"))
+ {
+ if (Area.CurrentStage != 0x0)
+ {
+ selectedStage = Area.CurrentStage;
+ }
+ else
+ {
+ selectedStage = Stage.InfinityOfNothingHandler;
+ }
+ }
+ ImGui.SameLine();
+ if (ImGui.Button("Global"))
+ {
+ selectedStage = Stage.InfinityOfNothingHandler;
+ }
+ Config config = ConfigManager.GetConfig<Config>(this);
+ List<Override> stageOverrides = config.Overrides[selectedStage];
+ List<Override>? globalOverrides = null;
+ if (!stageIsGlobal(selectedStage))
+ {
+ globalOverrides = config.Overrides[Stage.InfinityOfNothingHandler];
+ }
+ if (ImGui.Button("Add override"))
+ {
+ Override ov = new Override();
+ if (Area.CurrentStage == selectedStage || stageIsGlobal(selectedStage))
+ {
+ ov.Set();
+ }
+ stageOverrides.Add(ov);
+ }
+ ImGui.PopItemWidth();
+ for (int i = 0; i < stageOverrides.Count; i++)
+ {
+ Override ovS = stageOverrides[i];
+ ImGui.PushID(i);
+ bool requestRemove = ImGui.Button("X");
+ ImGui.SameLine();
+ bool requestUp = ImGui.Button("▲");
+ ImGui.SameLine();
+ bool requestDown = ImGui.Button("▼");
+ ImGui.SameLine();
+ if (requestDown && i < stageOverrides.Count - 1)
+ {
+ (stageOverrides[i], stageOverrides[i + 1]) = (stageOverrides[i + 1], stageOverrides[i]);
+ }
+ ovS.Draw(stageOverrides, globalOverrides, width);
+ if (requestUp && i > 0)
+ {
+ (stageOverrides[i], stageOverrides[i - 1]) = (stageOverrides[i - 1], stageOverrides[i]);
+ }
+ if (requestRemove)
+ {
+ ovS.Unset();
+ if (globalOverrides != null && ovS.Param != null)
+ {
+ setIfOverridesContainsParam(globalOverrides, ovS.Param);
+ }
+ stageOverrides.RemoveAt(i);
+ i--;
+ }
+ ImGui.PopID();
+ }
+ if (ImGui.Button("Save"))
+ {
+ ConfigManager.SaveConfig<Config>(this);
+ }
+
+ if (ImGui.CollapsingHeader("Patches"))
+ {
+ if (ImGui.Checkbox("3x Shadow Resolution", ref tripleShadowResolution))
+ {
+ if (tripleShadowResolution)
+ {
+ tripleShadowResEnable();
+ }
+ else
+ {
+ tripleShadowResDisable();
+ }
+ setShadowQuality.Invoke(MemoryUtil.Read<int>(sMhScene.Instance + 0x5530) + 1);
+ }
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text("In-Game Settings:\n - High: 1.0 -> 3.0\n - Mid: 0.7 -> 2.1\n - Low: 0.5 -> 1.5");
+ ImGui.EndTooltip();
+ }
+
+ if (ImGui.Checkbox("Volume Rendering Full Resolution Blur Pass (Requires Area Change)", ref disableVolumeDownsample))
+ {
+ if (disableVolumeDownsample)
+ {
+ disableVolumeDownsampleEnable();
+ }
+ else
+ {
+ disableVolumeDownsampleDisable();
+ }
+ }
+ 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 one time for this to apply, it will stay applied after that.");
+ ImGui.EndTooltip();
+ }
+
+ if (ImGui.Checkbox("Higher Than \"Highest\" Volume Rendering Quality", ref higherVolumeQuality))
+ {
+ if (higherVolumeQuality)
+ {
+ value2ForVolumeQuality.Enable();
+ }
+ else
+ {
+ value2ForVolumeQuality.Disable();
+ }
+ }
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text("*Extremely Resource Intensive* Only noticeable effect is likely in areas that had visible breakup with Volume Rendering Quality: Highest.\nThis takes mostly the same path as Highest.");
+ ImGui.EndTooltip();
+ }
+
+ if (ImGui.Checkbox("Disable Player/Palico/NPC LOD Limit in Gameplay", ref disableLODLimits))
+ {
+ if (disableLODLimits)
+ {
+ disableLODLimitsEnable();
+ }
+ else
+ {
+ disableLODLimitsDisable();
+ }
+ }
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text("This will make the default (gameplay) LOD limits equivalent to View Mode. Disabling the limit on:\n - Player Models & Shadows\n - Palico Models & Shadows\n - NPC Models & Shadows\n - Simple NPC Models & Shadows\nAlso equivalent to the settings applied in your room with the addition of disabled Simple NPC limits.");
+ ImGui.EndTooltip();
+ }
+
+ if (ImGui.Checkbox("Larger Foliage Sway Range", ref largerFoliageSwayRange))
+ {
+ if (largerFoliageSwayRange)
+ {
+ addressHigherValueForFoliageSway.Enable();
+ }
+ else
+ {
+ addressHigherValueForFoliageSway.Disable();
+ }
+ }
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text("Increase the distance at which Foliage Sway is still applied to lower priority plants.");
+ ImGui.EndTooltip();
+ }
+
+ if (ImGui.Checkbox("Disable Reduced Rate Animations", ref disableReducedRateAnimations))
+ {
+ if (disableReducedRateAnimations)
+ {
+ zeroFrameSkip.Enable();
+ }
+ else
+ {
+ zeroFrameSkip.Disable();
+ }
+ }
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text("Ignore the frame skip set on an animal's animation when are far from the camera.");
+ ImGui.EndTooltip();
+ }
+ }
+
+ if (ImGui.CollapsingHeader("Parameters"))
+ {
+ if (ImGui.CollapsingHeader("FXAA Parameters"))
+ {
+ ImGui.PushID("FXAA");
+ ImGui.Text($"Address: {fxaaObject:X}");
+ if (fxaaObject != 0x0)
+ {
+ foreach (Parameter param in fxaaParameters)
+ {
+ param.Draw(width);
+ }
+ }
+ ImGui.PopID();
+ }
+
+ if (ImGui.CollapsingHeader("Depth of Field Parameters"))
+ {
+ ImGui.PushID("DepthOfField");
+ ImGui.Text($"Address: {dofObject:X}");
+ if (dofObject != 0x0)
+ {
+ foreach (Parameter param in dofParameters)
+ {
+ param.Draw(width);
+ }
+ }
+ ImGui.PopID();
+ }
+
+ if (ImGui.CollapsingHeader("Motion Blur Parameters"))
+ {
+ ImGui.PushID("MotionBlur");
+ ImGui.Text($"Address: {motionBlurObject:X}");
+ if (motionBlurObject != 0x0)
+ {
+ foreach (Parameter param in motionBlurParameters)
+ {
+ param.Draw(width);
+ }
+ }
+ }
+
+ if (ImGui.CollapsingHeader("Bloom Parameters"))
+ {
+ ImGui.PushID("Bloom");
+ ImGui.Text($"Address: {bloomObject:X}");
+ if (bloomObject != 0x0)
+ {
+ foreach (Parameter param in bloomParameters)
+ {
+ param.Draw(width);
+ }
+ }
+ }
+
+ if (ImGui.CollapsingHeader("Lighting Parameters"))
+ {
+ ImGui.PushID("Lighting");
+ ImGui.Text($"Address: {lightingObject:X}");
+ if (lightingObject != 0x0)
+ {
+ foreach (Parameter param in lightingParameters)
+ {
+ param.Draw(width);
+ }
+ }
+ ImGui.PopID();
+ }
+
+ if (ImGui.CollapsingHeader("Shadow Parameters"))
+ {
+ ImGui.PushID("Shadows");
+ // MonsterHunterWorld.exe+1AB99E0 - mov rax,[MonsterHunterWorld.exe+500E180]
+ nint shadowAddr = MemoryUtil.Read<nint>(0x14500E180);
+ nint shadowObject = MemoryUtil.Read<nint>(shadowAddr + 0x4B0);
+ shadowAddr += 0x5B0;
+ ImGui.Text($"Address: {shadowAddr:X}, Object: {shadowObject:X}");
+ /*
+ if (ImGui.CollapsingHeader("Pass 1"))
+ {
+ ImGui.PushID("Pass1");
+ foreach (Parameter param in shadowParameters1)
+ {
+ param.Draw(width);
+ }
+ ImGui.PopID();
+ }
+ if (ImGui.CollapsingHeader("Pass 2"))
+ {
+ ImGui.PushID("Pass2");
+ */
+ foreach (Parameter param in shadowParameters2)
+ {
+ param.Draw(width);
+ }
+ /*
+ ImGui.PopID();
+ }
+ */
+ ImGui.PopID();
+ }
+
+ if (ImGui.CollapsingHeader("SSAO Parameters"))
+ {
+ ImGui.PushID("SSAO");
+ ImGui.Text($"Address: {sMhScene.Instance:X}");
+ foreach (Parameter param in ssaoParameters)
+ {
+ param.Draw(width);
+ }
+ ImGui.PopID();
+ }
+
+ if (ImGui.CollapsingHeader("SSLR Parameters"))
+ {
+ ImGui.PushID("SSLR");
+ ImGui.Text($"Address: {sMhScene.Instance:X}");
+ foreach (Parameter param in sslrParameters)
+ {
+ param.Draw(width);
+ }
+ ImGui.PopID();
+ }
+
+ if (ImGui.CollapsingHeader("Scene Parameters"))
+ {
+ ImGui.PushID("Scene");
+ ImGui.Text($"Address: {sMhScene.Instance:X}");
+ foreach (Parameter param in sceneParameters)
+ {
+ param.Draw(width);
+ }
+ ImGui.PopID();
+ }
+ }
+
+ if (ImGui.CollapsingHeader("DEBUG"))
+ {
+ ImGui.PushItemWidth(width * 0.15f);
+ ImGui.Text($"FPS: {MemoryUtil.GetRef<float>(sMain.Instance + 0x68)}");
+ ImGui.Text($"Delta Time: {MemoryUtil.GetRef<float>(sMain.Instance + 0x94)}");
+ // Locations taken from MHW-DTI-Dumps/wip_dump_15_20_00.h.
+ ImGui.InputFloat("Simulation FPS", ref MemoryUtil.GetRef<float>(sMain.Instance + 0x58));
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text("This does not apply to jiggle physics.");
+ ImGui.EndTooltip();
+ }
+ ImGui.InputFloat("Max FPS", ref MemoryUtil.GetRef<float>(sMain.Instance + 0x5C));
+ ImGui.PopItemWidth();
}
}
@@ -143,34 +2395,13 @@ namespace WorldTuningTool
Log.Info("Face shader replaced.");
}
}
- /*
- else if (hash == "d7e47ffe-82572c64-795c4698-341e5b91")
- {
- if (replaceShaderFromFile(info, $"{shaderPath}/sslr_mips.shdr")) {
- info->Replacement.Type = ShaderSourceType.BINARY;
- Log.Info("SSLR mips shader replaced.");
- }
- }
- */
- }
-
- public void OnLoad()
- {
- }
-
- public void OnImGuiRender()
- {
- if (ImGui.Checkbox("Disable Depth of Field", ref dofDisabled))
- {
- if (dofDisabled)
- {
- jmpOverDof.Enable();
- }
- else
- {
- jmpOverDof.Disable();
- }
- }
+ //else if (hash == "d7e47ffe-82572c64-795c4698-341e5b91")
+ //{
+ // if (replaceShaderFromFile(info, $"{shaderPath}/sslr_mips.shdr")) {
+ // info->Replacement.Type = ShaderSourceType.BINARY;
+ // Log.Info("SSLR mips shader replaced.");
+ // }
+ //}
}
}
}
diff --git a/Scripts/generate_diffs.sh b/Scripts/generate_diffs.sh
index d7e0d70..fa95217 100755
--- a/Scripts/generate_diffs.sh
+++ b/Scripts/generate_diffs.sh
@@ -3,6 +3,8 @@
# https://github.com/bo3b/3Dmigoto
# Disassemble: cmd_Decompiler.exe -d shader.dxbc (saved from RenderDoc).
# Assemble: cmd_Decompiler.exe -a shader.asm (edited)
+#
+# Compile: dxc.exe shader.hlsl -T [v|p|c]s_5_0
#wine cmd_Decompiler.exe -d ../Shaders/Original/*.dxbc
#wine cmd_Decompiler.exe -d ../Shaders/*.shdr