diff --git a/GestureLock/GestureLock.csproj b/GestureLock/GestureLock.csproj new file mode 100644 index 0000000..ae47bce --- /dev/null +++ b/GestureLock/GestureLock.csproj @@ -0,0 +1,40 @@ + + + + + net472 + enable + latest + false + + + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\0Harmony.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\MelonLoader.dll + + + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\SteamVR.dll + + + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\UIExpansionKit.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.InputLegacyModule.dll + + + + + + + + + diff --git a/GestureLock/GestureLock.sln b/GestureLock/GestureLock.sln new file mode 100644 index 0000000..65fa197 --- /dev/null +++ b/GestureLock/GestureLock.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32630.192 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GestureLock", "GestureLock.csproj", "{B318B038-DA12-4960-A35E-613BE26B7965}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B318B038-DA12-4960-A35E-613BE26B7965}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B318B038-DA12-4960-A35E-613BE26B7965}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B318B038-DA12-4960-A35E-613BE26B7965}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B318B038-DA12-4960-A35E-613BE26B7965}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0ABE9CFE-D4F5-4B5B-9D1A-5D0B1DA7E2CD} + EndGlobalSection +EndGlobal diff --git a/GestureLock/Main.cs b/GestureLock/Main.cs new file mode 100644 index 0000000..ffc7af4 --- /dev/null +++ b/GestureLock/Main.cs @@ -0,0 +1,140 @@ +using ABI_RC.Core.UI; +using ABI_RC.Core.Savior; +using HarmonyLib; +using MelonLoader; +using UnityEngine; +using Valve.VR; + +namespace GestureLock; + +public class GestureLock : MelonMod +{ + private static MelonPreferences_Category m_catagoryGestureLock; + private static MelonPreferences_Entry m_entryGestureLock; + private static MelonPreferences_Entry m_entryGestureBind; + private static MelonPreferences_Entry m_entryGestureHand; + + private enum BindHand + { + LeftHand, + RightHand + } + private enum BindingOptions + { + ButtonATouch, + ButtonBTouch, + StickTouch, + TriggerTouch + } + + public override void OnApplicationStart() + { + m_catagoryGestureLock = MelonPreferences.CreateCategory(nameof(GestureLock)); + m_entryGestureLock = m_catagoryGestureLock.CreateEntry("Enabled", true, description: "Double-touch VR binding."); + m_entryGestureHand = m_catagoryGestureLock.CreateEntry("VR Hand", BindHand.LeftHand); + m_entryGestureBind = m_catagoryGestureLock.CreateEntry("VR Binding", BindingOptions.StickTouch); + + m_catagoryGestureLock.SaveToFile(false); + m_entryGestureLock.OnValueChangedUntyped += UpdateSettings; + m_entryGestureHand.OnValueChangedUntyped += UpdateSettings; + m_entryGestureBind.OnValueChangedUntyped += UpdateSettings; + + UpdateSettings(); + } + private static void UpdateSettings() + { + HarmonyPatches.enabled = m_entryGestureLock.Value; + HarmonyPatches.bind = m_entryGestureBind.Value; + HarmonyPatches.hand = (SteamVR_Input_Sources)m_entryGestureHand.Value+1; + } + + [HarmonyPatch] + private class HarmonyPatches + { + public static bool enabled = m_entryGestureLock.Value; + public static BindingOptions bind = m_entryGestureBind.Value; + public static SteamVR_Input_Sources hand = SteamVR_Input_Sources.LeftHand; + + private static bool isLocked = false; + private static float oldGestureLeft = 0; + private static float oldGestureRight = 0; + + private static bool toggleLock = false; + private static float touchDoubleTimer = 0f; + private static bool touchArmed = false; + + private static void CheckTouch(bool input) + { + if (input) + { + if (touchArmed && touchDoubleTimer < 0.25f) + { + touchArmed = false; + toggleLock = true; + touchDoubleTimer = 1f; + } + else + { + touchDoubleTimer = 0f; + } + touchArmed = false; + } + else + { + touchArmed = true; + } + } + + //Read VR Buttons + [HarmonyPostfix] + [HarmonyPatch(typeof(InputModuleSteamVR), "UpdateInput")] + private static void AfterUpdateInput(ref SteamVR_Action_Boolean ___steamVrButtonATouch, ref SteamVR_Action_Boolean ___steamVrButtonBTouch, ref SteamVR_Action_Boolean ___steamVrStickTouch, ref SteamVR_Action_Boolean ___steamVrTriggerTouch) + { + if (!MetaPort.Instance.isUsingVr || !enabled) return; + + touchDoubleTimer += Time.deltaTime; + toggleLock = false; + + switch (bind) + { + case BindingOptions.ButtonATouch: + CheckTouch(___steamVrButtonATouch.GetState(hand)); + return; + case BindingOptions.ButtonBTouch: + CheckTouch(___steamVrButtonBTouch.GetState(hand)); + return; + case BindingOptions.StickTouch: + CheckTouch(___steamVrStickTouch.GetState(hand)); + return; + case BindingOptions.TriggerTouch: + CheckTouch(___steamVrTriggerTouch.GetState(hand)); + return; + default: break; + } + } + + //Apply GestureLock + [HarmonyPostfix] + [HarmonyPatch(typeof(CVRInputManager), "Update")] + private static void AfterUpdate(ref float ___gestureLeftRaw, ref float ___gestureLeft, ref float ___gestureRightRaw, ref float ___gestureRight) + { + if (!MetaPort.Instance.isUsingVr || !enabled) return; + + if (toggleLock) + { + isLocked = !isLocked; + oldGestureLeft = ___gestureLeft; + oldGestureRight = ___gestureRight; + MelonLogger.Msg("Gestures " + (isLocked ? "Locked" : "Unlocked")); + CohtmlHud.Instance.ViewDropTextImmediate("", "Gesture Lock ", "Gestures " + (isLocked ? "Locked" : "Unlocked")); + } + if (isLocked) + { + ___gestureLeftRaw = oldGestureLeft; + ___gestureLeft = oldGestureLeft; + ___gestureRightRaw = oldGestureRight; + ___gestureRight = oldGestureRight; + } + } + } +} diff --git a/GestureLock/Properties/AssemblyInfo.cs b/GestureLock/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..94de873 --- /dev/null +++ b/GestureLock/Properties/AssemblyInfo.cs @@ -0,0 +1,30 @@ +using MelonLoader; +using GestureLock.Properties; +using System.Reflection; + + +[assembly: AssemblyVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyTitle(nameof(GestureLock))] +[assembly: AssemblyCompany(AssemblyInfoParams.Author)] +[assembly: AssemblyProduct(nameof(GestureLock))] + +[assembly: MelonInfo( + typeof(GestureLock.GestureLock), + nameof(GestureLock), + AssemblyInfoParams.Version, + AssemblyInfoParams.Author, + downloadLink: "" +)] + +[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")] +[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)] +[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)] + +namespace GestureLock.Properties; +internal static class AssemblyInfoParams +{ + public const string Version = "1.0.0"; + public const string Author = "NotAKidoS"; +} \ No newline at end of file