Last active
October 21, 2020 03:55
-
-
Save Ryochan7/8fbbf5d43f7e687b0ffb04a26fd4fa59 to your computer and use it in GitHub Desktop.
Diff showing steps needed for Flick Stick to work in DS4Windows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/DS4Windows/DS4Control/Mapping.cs b/DS4Windows/DS4Control/Mapping.cs | |
index a0c6f43b..ddfa002a 100644 | |
--- a/DS4Windows/DS4Control/Mapping.cs | |
+++ b/DS4Windows/DS4Control/Mapping.cs | |
@@ -1996,6 +1996,45 @@ namespace DS4Windows | |
MappedState.SASteeringWheelEmulationUnit = Mapping.Scale360degreeGyroAxis(device, eState, ctrl); | |
} | |
+ DS4Device d = ctrl.DS4Controllers[device]; | |
+ DS4State crawState = d.getCurrentStateRef(); | |
+ DS4State pState = d.getPreviousStateRef(); | |
+ double angleChange = HandleFlickStickAngle(crawState, pState); | |
+ //angleChange = flickFilter.Filter(angleChange, cState.elapsedTime); | |
+ //Console.WriteLine(angleChange); | |
+ //if (angleChange != 0.0) | |
+ double lsangle = angleChange * 180.0 / Math.PI; | |
+ if (lsangle == 0.0) | |
+ { | |
+ flickAngleRemainder = 0.0; | |
+ } | |
+ else if (lsangle >= 0.0 && flickAngleRemainder >= 0.0) | |
+ { | |
+ lsangle += flickAngleRemainder; | |
+ } | |
+ | |
+ flickAngleRemainder = 0.0; | |
+ //Console.WriteLine(lsangle); | |
+ //if (angleChange != 0.0) | |
+ if (lsangle != 0.0) | |
+ //if (Math.Abs(lsangle) >= 0.5) | |
+ { | |
+ flickAngleRemainder = 0.0; | |
+ //flickAngleRemainder = lsangle - (int)lsangle; | |
+ //lsangle = (int)lsangle; | |
+ tempMouseDeltaX += lsangle * REAL_WORLD_CALIBRATION; | |
+ } | |
+ else | |
+ { | |
+ flickAngleRemainder = lsangle; | |
+ } | |
+ /*else | |
+ { | |
+ horizontalRemainder = 0.0; | |
+ verticalRemainder = 0.0; | |
+ } | |
+ */ | |
+ | |
ref byte gyroTempX = ref gyroStickX[device]; | |
if (gyroTempX != 128) | |
{ | |
@@ -2026,6 +2065,94 @@ namespace DS4Windows | |
} | |
} | |
+ private static OneEuroFilter flickFilter = new OneEuroFilter(0.4, 0.4); | |
+ private const double REAL_WORLD_CALIBRATION = 10; | |
+ private static double flickProgress = 0.0; | |
+ private static double flickSize = 0.0; | |
+ | |
+ private static double FlickThreshold = 0.9; | |
+ private static double FlickTime = 0.1; | |
+ | |
+ private static double flickAngleRemainder = 0.0; | |
+ | |
+ private static double HandleFlickStickAngle(DS4State cState, DS4State pState) | |
+ { | |
+ double result = 0.0; | |
+ | |
+ double lastXMax = pState.RX >= 128 ? 127.0 : -128.0; | |
+ double lastTestX = (pState.RX - 128) / lastXMax; | |
+ double lastYMax = pState.RY >= 128 ? 127.0 : -128.0; | |
+ double lastTestY = (pState.RY - 128) / lastYMax; | |
+ | |
+ double currentXMax = cState.RX >= 128 ? 127.0 : -128.0; | |
+ double currentTestX = (cState.RX - 128) / currentXMax; | |
+ double currentYMax = cState.RY >= 128 ? 127.0 : -128.0; | |
+ double currentTestY = (cState.RY - 128) / currentYMax; | |
+ | |
+ double lastLength = (lastTestX * lastTestX) + (lastTestY * lastTestY); | |
+ double length = (currentTestX * currentTestX) + (currentTestY * currentTestY); | |
+ double testLength = FlickThreshold * FlickThreshold; | |
+ | |
+ if (length >= testLength) | |
+ { | |
+ if (lastLength < testLength) | |
+ { | |
+ // Start new Flick | |
+ flickProgress = 0.0; // Reset Flick progress | |
+ flickSize = Math.Atan2((cState.RX - 128), -(cState.RY - 128)); | |
+ flickFilter.Filter(0.0, cState.elapsedTime); | |
+ } | |
+ else | |
+ { | |
+ // Turn camera | |
+ double stickAngle = Math.Atan2((cState.RX - 128), -(cState.RY - 128)); | |
+ double lastStickAngle = Math.Atan2((pState.RX - 128),-(pState.RY - 128)); | |
+ double angleChange = (stickAngle - lastStickAngle); | |
+ double rawAngleChange = angleChange; | |
+ angleChange = (angleChange+Math.PI) % (2*Math.PI); | |
+ if (angleChange < 0) | |
+ { | |
+ angleChange += 2 * Math.PI; | |
+ } | |
+ angleChange -= Math.PI; | |
+ //Console.WriteLine("ANGLE CHANGE: {0} {1} {2}", stickAngle, lastStickAngle, rawAngleChange); | |
+ //Console.WriteLine("{0} {1} | {2} {3}", cState.RX, pState.RX, cState.RY, pState.RY); | |
+ angleChange = flickFilter.Filter(angleChange, cState.elapsedTime); | |
+ result += angleChange; | |
+ } | |
+ } | |
+ else | |
+ { | |
+ // Cleanup | |
+ flickFilter.Filter(0.0, cState.elapsedTime); | |
+ result = 0.0; | |
+ } | |
+ | |
+ // Continue Flick motion | |
+ double lastFlickProgress = flickProgress; | |
+ if (lastFlickProgress < FlickTime) | |
+ { | |
+ flickProgress = Math.Min(flickProgress + cState.elapsedTime, FlickTime); | |
+ | |
+ double lastPerOne = lastFlickProgress / FlickTime; | |
+ double thisPerOne = flickProgress / FlickTime; | |
+ | |
+ double warpedLastPerOne = WarpEaseOut(lastPerOne); | |
+ double warpedThisPerone = WarpEaseOut(thisPerOne); | |
+ //Console.WriteLine("{0} {1}", warpedThisPerone, warpedLastPerOne); | |
+ | |
+ result += (warpedThisPerone - warpedLastPerOne) * flickSize; | |
+ } | |
+ | |
+ return result; | |
+ } | |
+ | |
+ private static double WarpEaseOut(double input) | |
+ { | |
+ double flipped = 1.0 - input; | |
+ return 1.0 - flipped * flipped; | |
+ } | |
+ | |
private static bool IfAxisIsNotModified(int device, bool shift, DS4Controls dc) | |
{ | |
return shift ? false : GetDS4Action(device, dc, false) == null; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment