summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-11-09 12:13:27 -0500
committerAndrew Opalach <andrew@akon.city> 2025-11-09 12:13:27 -0500
commit3b4ffba9f594aeba929cdc14820a03ed3131aadc (patch)
treefd6039ec2359c61821d296c2c6c362a65baf2814
parentb3803ef3628be8f91d612283780775fb0500f71f (diff)
downloadNewCamera-3b4ffba9f594aeba929cdc14820a03ed3131aadc.tar.gz
NewCamera-3b4ffba9f594aeba929cdc14820a03ed3131aadc.tar.bz2
NewCamera-3b4ffba9f594aeba929cdc14820a03ed3131aadc.zip
Fix input handling with 2+ controllers connected
- Also disable Start/Select, RB/LB, and stick direction input in free camera. - Update config defaults. Signed-off-by: Andrew Opalach <andrew@akon.city>
-rwxr-xr-xConfig.cs10
-rwxr-xr-xPlugin.cs158
2 files changed, 97 insertions, 71 deletions
diff --git a/Config.cs b/Config.cs
index 4ff79e1..ad3caa6 100755
--- a/Config.cs
+++ b/Config.cs
@@ -7,10 +7,10 @@ namespace MHWNewCamera
{
public struct Settings
{
- public const float DEFAULT_SPEED = 3.00f;
- public const float DEFAULT_ZOOM_SPEED = 1.0f;
+ public const float DEFAULT_SPEED = 4.5f;
+ public const float DEFAULT_ZOOM_SPEED = 0.02f;
public const float DEFAULT_SPEED_MODIFIER = 0.25f;
- public const float DEFAULT_SENSITIVITY = 1.95f;
+ public const float DEFAULT_SENSITIVITY = 0.04f;
public const double DEFAULT_PITCH_LIMIT = -1.0;
public const double MAX_PITCH_LIMIT = 89.95;
public const int DEFAULT_DEADZONE = 4750;
@@ -111,8 +111,8 @@ namespace MHWNewCamera
public bool ApplyLodFactors { get; set; } = false;
public float LodFactor1 { get; set; } = 0.0f;
public float LodFactor2 { get; set; } = 0.0f;
- public float FoliageLodFactor { get; set; } = 1.0f;
- public float TerrainLodFactor { get; set; } = 32.0f;
+ public float FoliageLodFactor { get; set; } = 64.0f;
+ public float TerrainLodFactor { get; set; } = 64.0f;
public bool LargerFoliageSwayRange { get; set; } = false;
}
}
diff --git a/Plugin.cs b/Plugin.cs
index bfffa53..2d80ce2 100755
--- a/Plugin.cs
+++ b/Plugin.cs
@@ -17,18 +17,19 @@ using System.Diagnostics;
#endif
// @TODO:
+// - Special case freecam for cutscenes and canteen animations.
+// - Glass objects in research base and on the botanical research center table still fade.
+// - Contact shadow resolution.
// - Thoroughly test "Disable Mod".
// - Improve AOB scans.
// - How to change closer shadow "fade" range.
// - Reduce the pop-in caused by updating shadow blobs.
// - Snow LOD pop-in.
-// - Contact shadow resolution.
-// - White vase thing in research base still fades when close.
+// - Stop animation rate lowering at distance.
// - Display equiped armor in the debug UI.
// - Manully set freecam viewport index.
// - Override in-game viewmode.
// - +right and +forward to move character.
-// - Special case freecam for cutscenes and canteen animations.
// Steam proton launch command:
// env DOTNET_ROOT="" WINEDLLOVERRIDES="msvcrt,dinput8=n,b" %command%
@@ -99,10 +100,19 @@ namespace MHWNewCamera
private bool comboButton1Down = false;
private uint lastPadDown = 0;
+ private uint? prevPadDown = null;
private bool buttonWasDown(Button button)
{
return (lastPadDown & (uint)button) == (uint)button;
}
+ private bool buttonWasPressed(Button button)
+ {
+ return (lastPadDown & (uint)button) == (uint)button && (prevPadDown & (uint)button) != (uint)button;
+ }
+ private bool buttonWasReleased(Button button)
+ {
+ return (lastPadDown & (uint)button) != (uint)button && (prevPadDown & (uint)button) == (uint)button;
+ }
private double cameraFov = DEFAULT_FOV;
private float cameraForward = 0.0f;
@@ -269,6 +279,7 @@ namespace MHWNewCamera
private static readonly MtObject sMhSteamController = SingletonManager.GetSingleton("sMhSteamController")!;
private nint controllerAddr() => sMhSteamController.Instance;
+ private nint primaryPad = 0x0;
private static readonly MtObject sOtomo = SingletonManager.GetSingleton("sOtomo")!;
@@ -622,9 +633,13 @@ namespace MHWNewCamera
#if HOOK_ORDER_ASSERTS
Trace.Assert(hookOrder == 0 || hookOrder == 3);
hookOrder = 0;
- frameTick++;
+ if (frameTick == int.MaxValue) frameTick = 0;
+ else frameTick++;
+ debugLog($"OnUpdate() @ {frameTick}");
#endif
+ primaryPad = 0x0;
+
// Consider that pCamera could become an invalid pointer.
checkPlayerChange();
}
@@ -1117,19 +1132,31 @@ namespace MHWNewCamera
// I haven't thought about or tested enough to know if it should be a performance consideration.
private void WritePadInputHook(nint unknownPtr, nint unknownPtr2, nint unknownPtr3)
{
- if (disableMod)
+ // Assumes the primary pad always comes first.
+ if (primaryPad == 0x0)
+ {
+ primaryPad = unknownPtr2;
+ }
+
+ if (disableMod || unknownPtr2 != primaryPad)
{
writePadInputHook!.Original(unknownPtr, unknownPtr2, unknownPtr3);
return;
}
- uint PadDown = 0, PadTrg = 0, PadRel = 0, PadChg = 0;
- if ((enableCombo && freeCameraCombo != null && disableComboButton1) && comboButton1Down)
+ Button b1 = 0u, b2 = 0u;
+ // PadOld = 0x19C
+ uint PadDown = 0u, PadTrg = 0u, PadRel = 0u, PadChg = 0u;
+ if (enableCombo && freeCameraCombo != null)
{
- PadDown = MemoryUtil.Read<uint>(controllerAddr() + 0x198);
- uint b1 = (uint)freeCameraCombo[0];
- PadDown |= b1;
- MemoryUtil.WriteBytes(controllerAddr() + 0x198, BitConverter.GetBytes(PadDown));
+ b1 = freeCameraCombo[0];
+ b2 = freeCameraCombo[1];
+ if (disableComboButton1 && comboButton1Down)
+ {
+ PadDown = MemoryUtil.Read<uint>(controllerAddr() + 0x198);
+ PadDown |= (uint)b1;
+ MemoryUtil.WriteBytes(controllerAddr() + 0x198, BitConverter.GetBytes(PadDown));
+ }
}
writePadInputHook!.Original(unknownPtr, unknownPtr2, unknownPtr3);
@@ -1138,8 +1165,6 @@ namespace MHWNewCamera
if (enableCombo && freeCameraCombo != null)
{
- Button b1 = freeCameraCombo[0];
- Button b2 = freeCameraCombo[1];
if (disableComboButton1)
{
if (!readInputsPostHook)
@@ -1148,11 +1173,12 @@ namespace MHWNewCamera
PadTrg = MemoryUtil.Read<uint>(controllerAddr() + 0x1A0);
PadRel = MemoryUtil.Read<uint>(controllerAddr() + 0x1A4);
PadChg = MemoryUtil.Read<uint>(controllerAddr() + 0x1A8);
+ prevPadDown = prevPadDown == null ? PadDown : lastPadDown;
lastPadDown = PadDown;
readInputsPostHook = true;
}
uint b1u = (uint)b1;
- if (comboButton1Down || enableFreeCamera || !Input.IsDown(b2))
+ if (comboButton1Down || enableFreeCamera || !buttonWasDown(b2))
{
if ((PadDown & b1u) == b1u)
{
@@ -1175,46 +1201,87 @@ namespace MHWNewCamera
MemoryUtil.WriteBytes(controllerAddr() + 0x1A8, BitConverter.GetBytes(PadChg));
}
}
- if ((comboButton1Down || (!disableComboButton1 && Input.IsDown(b1))) && Input.IsPressed(b2))
- {
- enableFreeCamera = !enableFreeCamera;
- }
+ }
+
+ if (!readInputsPostHook)
+ {
+ PadDown = MemoryUtil.Read<uint>(controllerAddr() + 0x198);
+ prevPadDown = prevPadDown == null ? PadDown : lastPadDown;
+ lastPadDown = PadDown;
+ }
+
+ if ((comboButton1Down || (!disableComboButton1 && buttonWasDown(b1))) && buttonWasPressed(b2))
+ {
+ enableFreeCamera = !enableFreeCamera;
}
if (enableFreeCamera)
{
- if (!unlockMovementHeld && Input.IsPressed(Button.L2))
+ if (!unlockInputToggled)
+ {
+ if (!readInputsPostHook)
+ {
+ PadTrg = MemoryUtil.Read<uint>(controllerAddr() + 0x1A0);
+ PadRel = MemoryUtil.Read<uint>(controllerAddr() + 0x1A4);
+ PadChg = MemoryUtil.Read<uint>(controllerAddr() + 0x1A8);
+ readInputsPostHook = true;
+ }
+ uint FaceButtonMask = (uint)Button.Cross | (uint)Button.Circle | (uint)Button.Square | (uint)Button.Triangle;
+ uint DPadMask = (uint)Button.Up | (uint)Button.Down | (uint)Button.Left | (uint)Button.Right;
+ uint StartSelectMask = (uint)Button.Options | (uint)Button.Share;
+ uint BumperMask = (uint)Button.L1 | (uint)Button.R1;
+ uint StickMask = (uint)Button.LsUp | (uint)Button.LsDown | (uint)Button.LsLeft | (uint)Button.LsRight |
+ (uint)Button.RsUp | (uint)Button.RsDown | (uint)Button.RsLeft | (uint)Button.RsRight;
+ uint Mask = FaceButtonMask | DPadMask | StartSelectMask | BumperMask | StickMask;
+ if (enableCombo && freeCameraCombo != null)
+ {
+ Mask &= ~((uint)b1 | (uint)b2);
+ }
+ PadDown &= ~Mask;
+ PadTrg &= ~Mask;
+ PadRel &= ~Mask;
+ PadChg &= ~Mask;
+ MemoryUtil.WriteBytes(controllerAddr() + 0x198, BitConverter.GetBytes(PadDown));
+ MemoryUtil.WriteBytes(controllerAddr() + 0x1A0, BitConverter.GetBytes(PadTrg));
+ MemoryUtil.WriteBytes(controllerAddr() + 0x1A0, BitConverter.GetBytes(PadRel));
+ MemoryUtil.WriteBytes(controllerAddr() + 0x1A8, BitConverter.GetBytes(PadChg));
+ // Left and right trigger.
+ MemoryUtil.WriteBytes(controllerAddr() + 0x1C0, BitConverter.GetBytes(0));
+ MemoryUtil.WriteBytes(controllerAddr() + 0x1C1, BitConverter.GetBytes(0));
+ }
+
+ if (!unlockMovementHeld && buttonWasPressed(Button.L2))
{
unlockMovementHeld = true;
}
- else if (unlockMovementHeld && Input.IsReleased(Button.L2))
+ else if (unlockMovementHeld && buttonWasReleased(Button.L2))
{
unlockMovementHeld = false;
unlockMovementPause = false;
}
if (unlockMovementHeld)
{
- if (Input.IsPressed(Button.L1))
+ if (buttonWasPressed(Button.L1))
{
unlockMovementToggled = !unlockMovementToggled;
}
// Temporarily disable for zoom mode.
- if (Input.IsDown(Button.R2))
+ if (buttonWasDown(Button.R2))
{
unlockMovementPause = true;
}
- else if (Input.IsReleased(Button.R2))
+ else if (buttonWasReleased(Button.R2))
{
unlockMovementPause = false;
}
}
- if (Input.IsDown(Button.L2) && Input.IsPressed(Button.R1))
+ if (buttonWasDown(Button.L2) && buttonWasPressed(Button.R1))
{
unlockInputToggled = !unlockInputToggled;
}
- if (Input.IsDown(Button.R2) && Input.IsPressed(Button.R1))
+ if (buttonWasDown(Button.R2) && buttonWasPressed(Button.R1))
{
if (uiToggled)
{
@@ -1226,47 +1293,6 @@ namespace MHWNewCamera
}
uiToggled = !uiToggled;
}
-
- if (!readInputsPostHook)
- {
- PadDown = MemoryUtil.Read<uint>(controllerAddr() + 0x198);
- lastPadDown = PadDown;
- }
-
- if (!unlockInputToggled)
- {
- if (!readInputsPostHook)
- {
- PadTrg = MemoryUtil.Read<uint>(controllerAddr() + 0x1A0);
- PadRel = MemoryUtil.Read<uint>(controllerAddr() + 0x1A4);
- PadChg = MemoryUtil.Read<uint>(controllerAddr() + 0x1A8);
- readInputsPostHook = true;
- }
- uint FaceButtonMask = (uint)Button.Cross | (uint)Button.Circle | (uint)Button.Square | (uint)Button.Triangle;
- uint DPadMask = (uint)Button.Up | (uint)Button.Down | (uint)Button.Left | (uint)Button.Right;
- if (enableCombo && freeCameraCombo != null)
- {
- uint b1 = (uint)freeCameraCombo[0];
- uint b2 = (uint)freeCameraCombo[1];
- FaceButtonMask &= ~(b1 | b2);
- DPadMask &= ~(b1 | b2);
- }
- PadDown &= ~DPadMask;
- PadDown &= ~FaceButtonMask;
- //PadDown &= ~((uint)Button.R1 | (uint)Button.L1);
- PadTrg &= ~DPadMask;
- PadTrg &= ~FaceButtonMask;
- //PadTrg &= ~((uint)Button.R1 | (uint)Button.L1);
- PadChg &= ~DPadMask;
- PadChg &= ~FaceButtonMask;
- //PadChg &= ~((uint)Button.R1 | (uint)Button.L1);
- MemoryUtil.WriteBytes(controllerAddr() + 0x198, BitConverter.GetBytes(PadDown));
- MemoryUtil.WriteBytes(controllerAddr() + 0x1A0, BitConverter.GetBytes(PadTrg));
- MemoryUtil.WriteBytes(controllerAddr() + 0x1A8, BitConverter.GetBytes(PadChg));
- // Left and right trigger.
- MemoryUtil.WriteBytes(controllerAddr() + 0x1C0, BitConverter.GetBytes(0));
- MemoryUtil.WriteBytes(controllerAddr() + 0x1C1, BitConverter.GetBytes(0));
- }
}
}