diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rwxr-xr-x | Plugin.cs | 238 |
2 files changed, 229 insertions, 10 deletions
@@ -5,3 +5,4 @@ Archive/ ModSlots/slots.txt ModSlots/venv/ Research/temp/ +Research/video/ @@ -46,6 +46,7 @@ using SharpPluginLoader.Core.Configuration; // - Open Poses Menu
// @TODO:
+// - Attempt to document all test cases I can think of.
// - Better hook for renderer params.
// - Centralize all bindings to get a better idea of how to structure custom binds.
// - Use GetRef<>.
@@ -180,6 +181,28 @@ namespace MHWNewCamera public bool gBufferJitter; // +0xB440
};
+ public struct DOFParameters {
+ public bool enabled; // +0x1DD
+ public bool newVersion; // +0x1DC
+ public float fNumber; // +0x1A0
+ public float sensorSize; // +0x1A4
+ public float focusDistance; // +0x1A8
+ public float nearCoef; // +0x1CC
+ public float farCoef; // +0x1C8
+ public bool nearEnable; // +0x1DE
+ public bool farEnable; // +0x1DF
+ public bool debugDraw; // +0x1E0
+ public float radius; // +0x1D0
+ public float depthScaleForeground; // +0x1D4
+ public float aspect; // +0x1D8
+ public bool vignettingEnabled; // +0x200
+ public bool vignettingEllipse; // +0x201
+ public float vignettingEllipticity; // +0x204
+ public float vignettingOffset; // +0x1F8
+ public float vignettingPow; // +0x1FC
+ public int vignettingColor; // +0x208
+ };
+
public enum ZoneState : int {
Unknown = 0,
Hub = 1,
@@ -201,6 +224,8 @@ namespace MHWNewCamera private static readonly MtObject sMain = SingletonManager.GetSingleton("sMhMain")!;
private static readonly MtObject sUmbra = SingletonManager.GetSingleton("sUmbra")!;
private bool freezeGame = false;
+ private bool decoupleDtFromGameTime = false;
+ private int advanceFrame = 0;
private float cameraSpeed;
private float cameraSpeedModifier;
@@ -349,6 +374,14 @@ namespace MHWNewCamera private delegate void MotionBlurDelegate(nint unknownPtr, nint unknownPtr2);
private Hook<MotionBlurDelegate>? motionBlurHook;
+ private bool dofDisabled = false;
+ private DOFParameters dofParams;
+ private bool fillOutDofParams = true;
+ private bool applyVignettingParams = false;
+ private bool fillOutVignettingParams = true;
+ private delegate void DofUpdateDelegate(nint unknownPtr);
+ private Hook<DofUpdateDelegate>? dofHook;
+
private delegate void CameraEffectDelegate(nint unknownPtr, nint unknownPtr2, nint unknownPtr3);
private Hook<CameraEffectDelegate>? cameraEffectHook;
@@ -383,7 +416,6 @@ namespace MHWNewCamera private bool uiToggled = false;
private Patch jmpOverUi;
- private bool dofDisabled = false;
private Patch jmpOverDof;
private bool disableCharacterFade = false;
@@ -829,6 +861,8 @@ namespace MHWNewCamera motionBlurHook = Hook.Create<MotionBlurDelegate>(0x1424CADF0, MotionBlurHook); // nint, nint
+ dofHook = Hook.Create<DofUpdateDelegate>(0x1412BA6A0, DofHook); // nint
+
cameraEffectHook = Hook.Create<CameraEffectDelegate>(0x141AB6AE0, CameraEffectHook); // nint, nint, nint
unchecked
@@ -1294,6 +1328,17 @@ namespace MHWNewCamera }
freeCameraFallback = true;
+ ref float gameSpeed = ref MemoryUtil.GetRef<float>(sMain.Instance + 0xA4);
+ if (freezeGame && gameSpeed != 0.0f)
+ {
+ gameSpeed = 0.0f;
+ }
+ else if (freezeGame && advanceFrame > 0)
+ {
+ gameSpeed = 1.0f;
+ advanceFrame--;
+ }
+
if (hideWeapon)
{
Player? player = Player.MainPlayer;
@@ -1488,7 +1533,7 @@ namespace MHWNewCamera private void updateFreeCamera(Camera camera)
{
float deltaTime;
- if (freezeGame)
+ if (decoupleDtFromGameTime)
{
deltaTime = 60.0f / MemoryUtil.Read<float>(sMain.Instance + 0x68);
}
@@ -2706,6 +2751,8 @@ namespace MHWNewCamera if (buttonWasPressed(Button.Circle))
{
+ dofParams.nearEnable = !dofParams.nearEnable;
+ /*
dofDisabled = !dofDisabled;
if (dofDisabled)
{
@@ -2715,6 +2762,7 @@ namespace MHWNewCamera {
jmpOverDof.Disable();
}
+ */
}
}
else if (freeCameraFromViewMode && !unlockInputForMenu && buttonWasPressed(Button.Circle))
@@ -2876,10 +2924,12 @@ namespace MHWNewCamera {
motionBlurWasDisabled = motionBlurDisabled;
motionBlurDisabled = true;
+ decoupleDtFromGameTime = true;
}
else
{
motionBlurDisabled = motionBlurWasDisabled;
+ decoupleDtFromGameTime = false;
}
MemoryUtil.WriteBytes(sMain.Instance + 0xA4, BitConverter.GetBytes(freezeGame ? 0.0f : 1.0f));
}
@@ -2904,6 +2954,100 @@ namespace MHWNewCamera motionBlurHook!.Original(unknownPtr, unknownPtr2);
}
+ private void DofHook(nint unknownPtr)
+ {
+ dofHook!.Original(unknownPtr);
+
+ if (disableMod)
+ {
+ return;
+ }
+
+#if HOOK_ORDER_ASSERTS
+ debugLog($"DofHook({unknownPtr:x}) @ {frameTick}");
+#endif
+
+ nint unknownObj = MemoryUtil.Read<nint>(unknownPtr + 0x230);
+ nint dofFilter = MemoryUtil.Read<nint>(unknownObj + 0x58);
+ if (dofFilter != 0x0)
+ {
+ ref byte dofEnabled = ref MemoryUtil.GetRef<byte>(dofFilter + 0x1DD);
+ ref byte newVersion = ref MemoryUtil.GetRef<byte>(dofFilter + 0x1DC);
+ ref float fNumber = ref MemoryUtil.GetRef<float>(dofFilter + 0x1A0);
+ ref float sensorSize = ref MemoryUtil.GetRef<float>(dofFilter + 0x1A4);
+ ref float focusDistance = ref MemoryUtil.GetRef<float>(dofFilter + 0x1A8);
+ ref float nearCoef = ref MemoryUtil.GetRef<float>(dofFilter + 0x1CC);
+ ref float farCoef = ref MemoryUtil.GetRef<float>(dofFilter + 0x1C8);
+ ref byte nearEnable = ref MemoryUtil.GetRef<byte>(dofFilter + 0x1DE);
+ ref byte farEnable = ref MemoryUtil.GetRef<byte>(dofFilter + 0x1DF);
+ ref byte debugDraw = ref MemoryUtil.GetRef<byte>(dofFilter + 0x1E0);
+ ref float radius = ref MemoryUtil.GetRef<float>(dofFilter + 0x1D0);
+ ref float depthScaleForeground = ref MemoryUtil.GetRef<float>(dofFilter + 0x1D4);
+ ref float aspect = ref MemoryUtil.GetRef<float>(dofFilter + 0x1D8);
+ ref byte vignettingEnabled = ref MemoryUtil.GetRef<byte>(dofFilter + 0x200);
+ ref byte vignettingEllipse = ref MemoryUtil.GetRef<byte>(dofFilter + 0x201);
+ ref float vignettingEllipticity = ref MemoryUtil.GetRef<float>(dofFilter + 0x204);
+ ref float vignettingOffset = ref MemoryUtil.GetRef<float>(dofFilter + 0x1F8);
+ ref float vignettingPow = ref MemoryUtil.GetRef<float>(dofFilter + 0x1FC);
+ ref int vignettingColor = ref MemoryUtil.GetRef<int>(dofFilter + 0x208);
+ if (fillOutDofParams)
+ {
+ dofParams.enabled = dofEnabled == 0x1;
+ dofParams.newVersion = newVersion == 0x1;
+ dofParams.fNumber = fNumber;
+ dofParams.sensorSize = sensorSize;
+ dofParams.focusDistance = focusDistance;
+ dofParams.nearCoef = nearCoef;
+ dofParams.farCoef = farCoef;
+ dofParams.nearEnable = nearEnable == 0x1;
+ dofParams.farEnable = farEnable == 0x1;
+ dofParams.debugDraw = debugDraw == 0x1;
+ dofParams.radius = radius;
+ dofParams.depthScaleForeground = depthScaleForeground;
+ dofParams.aspect = aspect;
+ fillOutDofParams = false;
+ }
+ if (fillOutVignettingParams)
+ {
+ dofParams.vignettingEnabled = vignettingEnabled == 0x1;
+ dofParams.vignettingEllipse = vignettingEllipse == 0x1;
+ dofParams.vignettingEllipticity = vignettingEllipticity;
+ dofParams.vignettingOffset = vignettingOffset;
+ dofParams.vignettingPow = vignettingPow;
+ dofParams.vignettingColor = vignettingColor;
+ fillOutVignettingParams = false;
+ }
+ /*
+ if ((dofEnabled == 0x0) != dofDisabled)
+ {
+ dofEnabled = byteFlag(!dofDisabled);
+ }
+ */
+ dofEnabled = byteFlag(dofParams.enabled);
+ newVersion = byteFlag(dofParams.newVersion);
+ fNumber = dofParams.fNumber;
+ sensorSize = dofParams.sensorSize;
+ focusDistance = dofParams.focusDistance;
+ nearCoef = dofParams.nearCoef;
+ farCoef = dofParams.farCoef;
+ nearEnable = byteFlag(dofParams.nearEnable);
+ farEnable = byteFlag(dofParams.farEnable);
+ debugDraw = byteFlag(dofParams.debugDraw);
+ radius = dofParams.radius;
+ depthScaleForeground = dofParams.depthScaleForeground;
+ aspect = dofParams.aspect;
+ if (applyVignettingParams)
+ {
+ vignettingEnabled = byteFlag(dofParams.vignettingEnabled);
+ vignettingEllipse = byteFlag(dofParams.vignettingEllipse);
+ vignettingEllipticity = dofParams.vignettingEllipticity;
+ vignettingOffset = dofParams.vignettingOffset;
+ vignettingPow = dofParams.vignettingPow;
+ vignettingColor = dofParams.vignettingColor;
+ }
+ }
+ }
+
private void UnderwaterCheckHook(nint unknownPtr)
{
underwaterCheckHook!.Original(unknownPtr);
@@ -3448,15 +3592,20 @@ namespace MHWNewCamera }
#if SHADER_FEATURES
+ private bool shadersLoadedOnce = false;
public unsafe void OnCreateShader(ShaderInfo *info)
{
+ if (shadersLoadedOnce)
+ {
+ return;
+ }
string hash = new string(info->DxbcHash);
if (hash == "2e4e18fd-6ea5eeae-2de3d65c-26ab36dd")
{
byte[] shaderData;
try
{
- shaderData = System.IO.File.ReadAllBytes("./volume_upsample.shdr");
+ shaderData = System.IO.File.ReadAllBytes("./volume_upsample_edit.shdr");
}
catch (Exception)
{
@@ -3465,13 +3614,14 @@ namespace MHWNewCamera info->NewSourceType = SourceType.BINARY;
info->NewSourceLength = shaderData.Length;
info->NewSource = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement<byte>(shaderData, 0);
+ Log.Info("Replaced volume upsample shader 1.");
}
else if (hash == "e2c8c13e-45bc99b2-4c3d7699-3d66188e")
{
byte[] shaderData;
try
{
- shaderData = System.IO.File.ReadAllBytes("./volume_upsample2.shdr");
+ shaderData = System.IO.File.ReadAllBytes("./volume_upsample2_edit.shdr");
}
catch (Exception)
{
@@ -3480,6 +3630,9 @@ namespace MHWNewCamera info->NewSourceType = SourceType.BINARY;
info->NewSourceLength = shaderData.Length;
info->NewSource = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement<byte>(shaderData, 0);
+ Log.Info("Replaced volume upsample shader 2.");
+ // This interestingly allows us to A/B using the volume rendering value 2 switch.
+ shadersLoadedOnce = true;
}
}
#endif
@@ -4640,17 +4793,31 @@ namespace MHWNewCamera }
ImGui.PushItemWidth(width * 0.125f);
- float gameSpeed = MemoryUtil.Read<float>(sMain.Instance + 0xA4);
+ ref float gameSpeed = ref MemoryUtil.GetRef<float>(sMain.Instance + 0xA4);
if (ImGui.DragFloat("Game Speed", ref gameSpeed, 0.005f, 0.0f, Single.MaxValue))
{
- MemoryUtil.WriteBytes(sMain.Instance + 0xA4, BitConverter.GetBytes(gameSpeed));
+ if (gameSpeed == 1.0f)
+ {
+ decoupleDtFromGameTime = false;
+ }
}
ImGui.SameLine();
if (ImGui.Button("Toggle Freeze Game"))
{
toggleFreezeGame();
}
+ ImGui.SameLine();
+ if (ImGui.Button("Advance Frame"))
+ {
+ advanceFrame++;
+ }
ImGui.PopItemWidth();
+ ImGui.Checkbox("Decouple Camera Speed from Game Speed", ref decoupleDtFromGameTime);
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text("Enable this to move in free camera at a normal speed when game speed is not 1.0.");
+ ImGui.EndTooltip();
+ }
if (ImGui.Checkbox("Override View Mode", ref overrideViewMode))
{
@@ -4973,13 +5140,58 @@ namespace MHWNewCamera ImGui.EndTooltip();
}
+ if (ImGui.CollapsingHeader("Depth of Field Parameters"))
+ {
+ ImGui.Checkbox("Enabled", ref dofParams.enabled);
+ ImGui.Checkbox("New Version", ref dofParams.newVersion);
+ ImGui.DragFloat("FNumber", ref dofParams.fNumber, 0.001f, 0.0f, 0.0f, "%.5f");
+ ImGui.DragFloat("Sensor Size", ref dofParams.sensorSize, 0.001f, 0.0f, 0.0f, "%.5f");
+ ImGui.DragFloat("Focus Distance", ref dofParams.focusDistance, 0.2f);
+ ImGui.DragFloat("Near Coef", ref dofParams.nearCoef, 0.001f, 0.0f, 0.0f, "%.5f");
+ ImGui.DragFloat("Far Coef", ref dofParams.farCoef, 0.001f, 0.0f, 0.0f, "%.5f");
+ ImGui.Checkbox("Near Enabled", ref dofParams.nearEnable);
+ ImGui.Checkbox("Far Enabled", ref dofParams.farEnable);
+ ImGui.Checkbox("Debug Draw", ref dofParams.debugDraw);
+ if (!dofParams.newVersion)
+ {
+ ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
+ }
+ ImGui.Text("New Version Parameters:");
+ ImGui.DragFloat("Radius", ref dofParams.radius, 0.001f, 0.0f, 0.0f, "%.6f");
+ ImGui.DragFloat("Depth Scale Foreground", ref dofParams.depthScaleForeground, 0.0001f, 0.0f, 0.0f, "%.6f");
+ ImGui.DragFloat("Aspect", ref dofParams.aspect, 0.001f, 0.0f, 0.0f, "%.6f");
+ if (!dofParams.newVersion)
+ {
+ ImGui.PopStyleVar();
+ }
+ if (ImGui.Button("Reset Per-frame Parameters"))
+ {
+ fillOutDofParams = true;
+ }
+ }
+
+ if (ImGui.CollapsingHeader("Vignetting Parameters"))
+ {
+ ImGui.Checkbox("Apply Adjustments", ref applyVignettingParams);
+ ImGui.Checkbox("Enabled", ref dofParams.vignettingEnabled);
+ ImGui.Checkbox("Ellipse", ref dofParams.vignettingEllipse);
+ ImGui.DragFloat("Ellipticity", ref dofParams.vignettingEllipticity, 0.05f);
+ ImGui.DragFloat("Offset", ref dofParams.vignettingOffset, 0.05f);
+ ImGui.DragFloat("Power", ref dofParams.vignettingPow, 0.05f);
+ ImGui.InputInt("Color", ref dofParams.vignettingColor, 0, 0, ImGuiInputTextFlags.CharsHexadecimal);
+ if (ImGui.Button("Reset Per-frame Parameters"))
+ {
+ fillOutVignettingParams = true;
+ }
+ }
+
if (ImGui.CollapsingHeader("Shadow Distance Parameters"))
{
ImGui.PushItemWidth(width * 0.2f);
ImGui.Text($"sUmbra: {sUmbra.Instance:x}");
nint obj = MemoryUtil.Read<nint>(sUmbra.Instance + 0x00149740);
ImGui.Text($"Object Address: {obj:x}");
- ImGui.Checkbox("Apply Adjust", ref applyShadowAdjust);
+ ImGui.Checkbox("Apply Adjustments", ref applyShadowAdjust);
ImGui.InputFloat("Shadow Backforward Distance", ref shadowBackforwardDistance);
if (ImGui.BeginItemTooltip())
{
@@ -5190,9 +5402,15 @@ namespace MHWNewCamera }
ImGui.Text("Graphics:");
- // Names and locations taken from MHW-DTI-Dumps/wip_dump_15_20_00.h.
- ImGui.Text($"Max Fps: {MemoryUtil.Read<float>(sMain.Instance + 0x5C)}");
- ImGui.Text($"Fps: {MemoryUtil.Read<float>(sMain.Instance + 0x68)}");
+ // 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.InputFloat("Fps", ref MemoryUtil.GetRef<float>(sMain.Instance + 0x68));
ImGui.Text($"Delta Time: {MemoryUtil.Read<float>(sMain.Instance + 0x94)}");
ImGui.Text($"prevFoliageLODBias: {prevFoliageLODBias}");
|