diff --git a/DS4Windows/DS4Control/Mapping.cs b/DS4Windows/DS4Control/Mapping.cs
index 32e561a..4b052de 100644
--- a/DS4Windows/DS4Control/Mapping.cs
+++ b/DS4Windows/DS4Control/Mapping.cs
@@ -3804,18 +3804,13 @@ namespace DS4Windows
private const int C_WHEEL_ANGLE_PRECISION_DECIMALS = (C_WHEEL_ANGLE_PRECISION == 1 ? 0 : C_WHEEL_ANGLE_PRECISION/10);
// "In-game" calibration process:
- // TODO: Launching a calibration process should probably be a special action which allows multiple key bindings to launch a specific task.
- // - Place controller at "steering wheel center" position and press DS4 Option button to start the calibration (Profile should have "SASteeringWheelEmulationAxis" option set to LXPos, LYPos, RXPos or RYPos value).
- // - Hold the controller still for a while and wait until red lightbar turns to blinking yellow (center point calibrated)
- // - Turn the controller at 90 degree left or right position and hold still for few seconds and wait until lightbar turns to blinking light blue (two points calibrated)
- // - Turn the controller at 90 degree position on the opposite side (but do it by going through 0 degree center position. Don't go through 180deg mark). Wait until lighbar turns to green (three points calibrated)
- // - Now you can check the calibratio by turning the wheel and see when the green lightbar starts to blink (it should blink at those three calibrated positions).
- // - Press DS4 Options button to accept the calibration (result is saved to ControllerConfigs.xml xml file in AppData folder).
+ // - Place controller at "steering wheel center" position and press "Calibrate SA steering wheel" special action button to start the calibration
+ // - Hold the controller still for a while at center point and press "X"
+ // - Turn the controller at 90 degree left or right position and hold still for few seconds and press "X"
+ // - Turn the controller at 90 degree position on the opposite side and press "X"
+ // - Now you can check the calibratio by turning the wheel and see when the green lightbar starts to blink (it should blink at those three calibrated positions)
+ // - Press "Calibrate SA steering wheel" special action key to accept the calibration (result is saved to ControllerConfigs.xml xml file)
//
- // 0 = None of the anchors calibrated yet. Hold controller still at "wheel center position" and wait until lightbar turns from constant red to flashing yellow color
- // 1 = one anchor calibrated (The first calibration point should always be the center position)
- // 2 = two anchors calibrated (center and 90Right or 90Left depending on which way user turn the wheel after the first center calibration point)
- // 3 = all three anchor points calibrated (center, 90Right, 90Left). Good to go. User can check calibration by turning the wheel and checking when the green lightbar blinks. If happy then pressing Options btn accepts the calibration.
private static readonly DS4Color calibrationColor_0 = new DS4Color { red = 0xA0, green = 0x00, blue = 0x00 };
private static readonly DS4Color calibrationColor_1 = new DS4Color { red = 0xFF, green = 0xFF, blue = 0x00 };
private static readonly DS4Color calibrationColor_2 = new DS4Color { red = 0x00, green = 0x50, blue = 0x50 };
@@ -3851,7 +3846,6 @@ namespace DS4Windows
}
// Calculate and return the angle of the controller as -180...0...+180 value.
- // TODO: Support >360 degree turn range by adding "lap counter" when wheel is rotated full rounds left or right.At the moment this logic supports only 360 degree turn range.
private static Int32 CalculateControllerAngle(int gyroAccelX, int gyroAccelZ, DS4Device controller)
{
Int32 result;
@@ -3908,6 +3902,7 @@ namespace DS4Windows
return result;
}
+ // Calibrate sixaxis steering wheel emulation. Use DS4Windows configuration screen to start a calibration or press a special action key (if defined)
private static void SAWheelEmulationCalibration(int device, DS4StateExposed exposedState, ControlService ctrl, DS4State currentDeviceState, DS4Device controller)
{
int gyroAccelX, gyroAccelZ;
@@ -3916,8 +3911,7 @@ namespace DS4Windows
gyroAccelX = exposedState.getAccelX();
gyroAccelZ = exposedState.getAccelZ();
- // "SASteeringWheelEmulaationCalibration" action key combination is used to run "in-game" calibration process (user can define the action key combination in DS4Windows GUI).
- // State 0=Normal mode (ie. calibration process is not running), 1=Activating calibration, 2=Calibration process running, 3=Completing calibration
+ // State 0=Normal mode (ie. calibration process is not running), 1=Activating calibration, 2=Calibration process running, 3=Completing calibration, 4=Cancelling calibration
if (controller.WheelRecalibrateActiveState == 1)
{
AppLogger.LogToGui($"Controller {ctrl.x360Bus.FirstController + device} activated re-calibration of SA steering wheel emulation", false);
@@ -3925,21 +3919,22 @@ namespace DS4Windows
controller.WheelRecalibrateActiveState = 2;
controller.wheelPrevPhysicalAngle = 0;
+ controller.wheelPrevFullAngle = 0;
controller.wheelFullTurnCount = 0;
// Clear existing calibration value and use current position as "center" point.
// This initial center value may be off-center because of shaking the controller while button was pressed. The value will be overriden with correct value once controller is stabilized and hold still few secs at the center point
controller.wheelCenterPoint.X = gyroAccelX;
controller.wheelCenterPoint.Y = gyroAccelZ;
- controller.wheel90DegPointRight.X = gyroAccelX + 25;
- controller.wheel90DegPointLeft.X = gyroAccelX - 25;
+ controller.wheel90DegPointRight.X = gyroAccelX + 20;
+ controller.wheel90DegPointLeft.X = gyroAccelX - 20;
// Clear bitmask for calibration points. All three calibration points need to be set before re-calibration process is valid
controller.wheelCalibratedAxisBitmask = DS4Device.WheelCalibrationPoint.None;
- controller.wheelPrevRecalibrateTime = DateTime.Now;
+ controller.wheelPrevRecalibrateTime = new DateTime(2500, 1, 1);
}
- else if (controller.WheelRecalibrateActiveState == 3 /*&& currentDeviceState.Options && ((TimeSpan)(DateTime.Now - controller.wheelPrevRecalibrateTime)).TotalSeconds > 3 */)
+ else if (controller.WheelRecalibrateActiveState == 3)
{
AppLogger.LogToGui($"Controller {ctrl.x360Bus.FirstController + device} completed the calibration of SA steering wheel emulation. center=({controller.wheelCenterPoint.X}, {controller.wheelCenterPoint.Y}) 90L=({controller.wheel90DegPointLeft.X}, {controller.wheel90DegPointLeft.Y}) 90R=({controller.wheel90DegPointRight.X}, {controller.wheel90DegPointRight.Y})", false);
@@ -3949,36 +3944,34 @@ namespace DS4Windows
else
controller.wheelCenterPoint.X = controller.wheelCenterPoint.Y = 0;
- // Reset lightbar back to normal color
- // TODO: hmmm... Sometimes color is not reset back to normal "main color". Investigate why following code logic doesn't always restore it.
- DS4LightBar.forcelight[device] = false;
- DS4LightBar.forcedFlash[device] = 0;
- DS4LightBar.updateLightBar(controller, device);
-
- controller.LightBarColor = Global.getMainColor(device);
- DS4LightBar.updateLightBar(controller, device);
+ controller.WheelRecalibrateActiveState = 0;
+ controller.wheelPrevRecalibrateTime = DateTime.Now;
+ }
+ else if (controller.WheelRecalibrateActiveState == 4)
+ {
+ AppLogger.LogToGui($"Controller {ctrl.x360Bus.FirstController + device} cancelled the calibration of SA steering wheel emulation.", false);
controller.WheelRecalibrateActiveState = 0;
-
controller.wheelPrevRecalibrateTime = DateTime.Now;
}
if (controller.WheelRecalibrateActiveState > 0)
{
- // Auto calibrate 90deg left/right positions (these values may change over time because gyro/accel sensor values are not "precise mathematics", so user can trigger calibration even in mid-game sessions by pressing DS4 Options btn),
- // but make sure controller is stable enough to avoid misaligments because of hard shaking (check velocity of gyro axis)
- if (Math.Abs(currentDeviceState.Motion.angVelPitch) < 0.5 && Math.Abs(currentDeviceState.Motion.angVelYaw) < 0.5 && Math.Abs(currentDeviceState.Motion.angVelRoll) < 0.5)
+ // Cross "X" key pressed. Set calibration point when the key is released and controller hold steady for a few seconds
+ if(currentDeviceState.Cross == true) controller.wheelPrevRecalibrateTime = DateTime.Now;
+
+ // Make sure controller is hold steady (velocity of gyro axis) to avoid misaligments and set calibration few secs after the "X" key was released
+ if (Math.Abs(currentDeviceState.Motion.angVelPitch) < 0.5 && Math.Abs(currentDeviceState.Motion.angVelYaw) < 0.5 && Math.Abs(currentDeviceState.Motion.angVelRoll) < 0.5
+ && ((TimeSpan)(DateTime.Now - controller.wheelPrevRecalibrateTime)).TotalSeconds > 1)
{
+ controller.wheelPrevRecalibrateTime = new DateTime(2500, 1, 1);
+
if (controller.wheelCalibratedAxisBitmask == DS4Device.WheelCalibrationPoint.None)
{
- // Wait few secs after re-calibration button was pressed. Hold controller still at center position and don't shake it too much until red lightbar turns to yellow.
- if (((TimeSpan)(DateTime.Now - controller.wheelPrevRecalibrateTime)).TotalSeconds >= 3)
- {
- controller.wheelCenterPoint.X = gyroAccelX;
- controller.wheelCenterPoint.Y = gyroAccelZ;
+ controller.wheelCenterPoint.X = gyroAccelX;
+ controller.wheelCenterPoint.Y = gyroAccelZ;
- controller.wheelCalibratedAxisBitmask |= DS4Device.WheelCalibrationPoint.Center;
- }
+ controller.wheelCalibratedAxisBitmask |= DS4Device.WheelCalibrationPoint.Center;
}
else if (controller.wheel90DegPointRight.X < gyroAccelX)
{
@@ -4001,8 +3994,7 @@ namespace DS4Windows
}
// Show lightbar color feedback how the calibration process is proceeding.
- // red / yellow / blue / green = No calibration anchors/one anchor/two anchors/three anchors calibrated (center, 90DegLeft, 90DegRight)
- // Blinking led = Controller is tilted at the current calibration point (or calibration routine just set a new anchor point)
+ // red / yellow / blue / green = No calibration anchors/one anchor/two anchors/all three anchors calibrated when color turns to green (center, 90DegLeft, 90DegRight).
int bitsSet = CountNumOfSetBits((int)controller.wheelCalibratedAxisBitmask);
if (bitsSet >= 3) DS4LightBar.forcedColor[device] = calibrationColor_3;
else if (bitsSet == 2) DS4LightBar.forcedColor[device] = calibrationColor_2;
@@ -4010,20 +4002,28 @@ namespace DS4Windows
else DS4LightBar.forcedColor[device] = calibrationColor_0;
result = CalculateControllerAngle(gyroAccelX, gyroAccelZ, controller);
- if (bitsSet >= 1 && (
- Math.Abs(result) <= 1 * C_WHEEL_ANGLE_PRECISION
- || (Math.Abs(result) >= 88 * C_WHEEL_ANGLE_PRECISION && Math.Abs(result) <= 92 * C_WHEEL_ANGLE_PRECISION)
- || Math.Abs(result) >= 178 * C_WHEEL_ANGLE_PRECISION
- ))
+
+ // Force lightbar flashing when controller is currently at calibration point (user can verify the calibration before accepting it by looking at flashing lightbar)
+ if( ((controller.wheelCalibratedAxisBitmask & DS4Device.WheelCalibrationPoint.Center) != 0 && Math.Abs(result) <= 1 * C_WHEEL_ANGLE_PRECISION)
+ || ((controller.wheelCalibratedAxisBitmask & DS4Device.WheelCalibrationPoint.Left90) != 0 && result <= -89 * C_WHEEL_ANGLE_PRECISION && result >= -91 * C_WHEEL_ANGLE_PRECISION)
+ || ((controller.wheelCalibratedAxisBitmask & DS4Device.WheelCalibrationPoint.Right90) != 0 && result >= 89 * C_WHEEL_ANGLE_PRECISION && result <= 91 * C_WHEEL_ANGLE_PRECISION)
+ || ((controller.wheelCalibratedAxisBitmask & DS4Device.WheelCalibrationPoint.Left90) != 0 && Math.Abs(result) >= 179 * C_WHEEL_ANGLE_PRECISION) )
DS4LightBar.forcedFlash[device] = 2;
else
DS4LightBar.forcedFlash[device] = 0;
DS4LightBar.forcelight[device] = true;
- //DS4LightBar.updateLightBar(controller, device);
LogToGuiSACalibrationDebugMsg($"Calibration values ({gyroAccelX}, {gyroAccelZ}) angle={result / (1.0 * C_WHEEL_ANGLE_PRECISION)}\n");
}
+ else
+ {
+ // Re-calibration completed or cancelled. Set lightbar color back to normal color
+ DS4LightBar.forcedFlash[device] = 0;
+ DS4LightBar.forcedColor[device] = Global.getMainColor(device);
+ DS4LightBar.forcelight[device] = false;
+ DS4LightBar.updateLightBar(controller, device);
+ }
}
protected static Int32 Scale360degreeGyroAxis(int device, DS4StateExposed exposedState, ControlService ctrl)
@@ -4036,13 +4036,12 @@ namespace DS4Windows
int gyroAccelX, gyroAccelZ;
int result;
- //controller = Program.rootHub.DS4Controllers[device];
controller = ctrl.DS4Controllers[device];
if (controller == null) return 0;
currentDeviceState = controller.getCurrentStateRef();
- // If user has pressed "SASteeringWheelEmulationCalibration" special action key combination then run "in-game" calibration process
+ // If calibration is active then do the calibration process instead of the normal "angle calculation"
if (controller.WheelRecalibrateActiveState > 0)
{
SAWheelEmulationCalibration(device, exposedState, ctrl, currentDeviceState, controller);
@@ -4081,47 +4080,68 @@ namespace DS4Windows
controller.wheelPrevRecalibrateTime = DateTime.Now;
}
- result = CalculateControllerAngle(gyroAccelX, gyroAccelZ, controller);
-
- if (controller.wheelPrevPhysicalAngle < 0 && result > 0)
- {
- // If wrapped around from -180 to +180 side then SA steering wheel keeps on turning "left" (ie. beyond 360 degrees)
- if ((result - controller.wheelPrevPhysicalAngle) > 180 * C_WHEEL_ANGLE_PRECISION)
- controller.wheelFullTurnCount--;
- }
- else if (controller.wheelPrevPhysicalAngle > 0 && result < 0)
- {
- // If wrapped around from +180 to -180 side then SA steering wheel keeps on turning "right" (ie. beyond 360 degrees)
- if ((controller.wheelPrevPhysicalAngle - result) > 180 * C_WHEEL_ANGLE_PRECISION)
- controller.wheelFullTurnCount++;
- }
- controller.wheelPrevPhysicalAngle = result;
-
- if (controller.wheelFullTurnCount != 0)
- {
- if (controller.wheelFullTurnCount > 0)
- result = (controller.wheelFullTurnCount * 180 * C_WHEEL_ANGLE_PRECISION) + ((controller.wheelFullTurnCount * 180 * C_WHEEL_ANGLE_PRECISION) + result);
- else
- result = (controller.wheelFullTurnCount * 180 * C_WHEEL_ANGLE_PRECISION) - ((controller.wheelFullTurnCount * -180 * C_WHEEL_ANGLE_PRECISION) - result);
- }
-
- // TODO: How to prevent "too many laps" problem or reset it (DS4Win doesn't know when a game is running so it keeps counting laps)?
int maxRangeRight = Global.getSASteeringWheelEmulationRange(device) / 2 * C_WHEEL_ANGLE_PRECISION;
int maxRangeLeft = -maxRangeRight;
- if (maxRangeRight != (360 / 2 * C_WHEEL_ANGLE_PRECISION) )
- result = Mapping.ClampInt(maxRangeLeft, result, maxRangeRight);
+ result = CalculateControllerAngle(gyroAccelX, gyroAccelZ, controller);
- // Keep outputting debug data 30secs after the latest re-calibration event (user can check these values from the log screen of DS4Windows GUI)
- //if (((TimeSpan)(DateTime.Now - prevRecalibrateTime)).TotalSeconds < 30)
- // LogToGuiSACalibrationDebugMsg($"DEBUG gyro=({gyroAccelX}, {gyroAccelZ}) angle={result / (1.0 * C_WHEEL_ANGLE_PRECISION)}");
+ // If wrapped around from +180 to -180 side (or vice versa) then SA steering wheel keeps on turning beyond 360 degrees (if range is >360)
+ int wheelFullTurnCount = controller.wheelFullTurnCount;
+ if (controller.wheelPrevPhysicalAngle < 0 && result > 0)
+ {
+ if ((result - controller.wheelPrevPhysicalAngle) > 180 * C_WHEEL_ANGLE_PRECISION)
+ if (maxRangeRight > 360 * C_WHEEL_ANGLE_PRECISION)
+ wheelFullTurnCount--;
+ else
+ result = maxRangeLeft;
+ }
+ else if (controller.wheelPrevPhysicalAngle > 0 && result < 0)
+ {
+ if ((controller.wheelPrevPhysicalAngle - result) > 180 * C_WHEEL_ANGLE_PRECISION)
+ if (maxRangeRight > 360 * C_WHEEL_ANGLE_PRECISION)
+ wheelFullTurnCount++;
+ else
+ result = maxRangeRight;
+ }
+ controller.wheelPrevPhysicalAngle = result;
- //LogToGuiSACalibrationDebugMsg($"DEBUG gyro=({gyroAccelX}, {gyroAccelZ}) angle={result / (1.0 * C_WHEEL_ANGLE_PRECISION)} fullTurns={controller.wheelFullTurnCount}", false);
+ if (wheelFullTurnCount != 0)
+ {
+ if (wheelFullTurnCount > 0)
+ result = (wheelFullTurnCount * 180 * C_WHEEL_ANGLE_PRECISION) + ((wheelFullTurnCount * 180 * C_WHEEL_ANGLE_PRECISION) + result);
+ else
+ result = (wheelFullTurnCount * 180 * C_WHEEL_ANGLE_PRECISION) - ((wheelFullTurnCount * -180 * C_WHEEL_ANGLE_PRECISION) - result);
+ }
- // Scale input to a raw x360 thumbstick output scale
- //return (((result - (-180 * C_WHEEL_ANGLE_PRECISION)) * (32767 - (-32768))) / (180 * C_WHEEL_ANGLE_PRECISION - (-180 * C_WHEEL_ANGLE_PRECISION))) + (-32768);
- return (( (result - maxRangeLeft) * (32767 - (-32768))) / (maxRangeRight - maxRangeLeft)) + (-32768);
+ // If the new angle is more than 180 degrees further away then this is probably bogus value (controller shaking too much and gyro and velocity sensors went crazy).
+ // Accept the new angle only when the new angle is within a "stability threshold", otherwise use the previous full angle value.
+ if (Math.Abs(result - controller.wheelPrevFullAngle) <= 180 * C_WHEEL_ANGLE_PRECISION)
+ {
+ controller.wheelPrevFullAngle = result;
+ controller.wheelFullTurnCount = wheelFullTurnCount;
+ }
+ else
+ {
+ result = controller.wheelPrevFullAngle;
+ }
+
+ result = Mapping.ClampInt(maxRangeLeft, result, maxRangeRight);
+
+ //LogToGuiSACalibrationDebugMsg($"DEBUG gyro=({gyroAccelX}, {gyroAccelZ}) gyroPitchRollYaw=({currentDeviceState.Motion.gyroPitch}, {currentDeviceState.Motion.gyroRoll}, {currentDeviceState.Motion.gyroYaw}) gyroPitchRollYaw=({currentDeviceState.Motion.angVelPitch}, {currentDeviceState.Motion.angVelRoll}, {currentDeviceState.Motion.angVelYaw}) angle={result / (1.0 * C_WHEEL_ANGLE_PRECISION)} fullTurns={controller.wheelFullTurnCount}", false);
+
+ // Scale input to a raw x360 16bit output scale, except if output axis of steering wheel emulation is L2+R2 trigger axis.
+ // L2+R2 triggers use independent 8bit values, so use -255..0..+255 scaled values (therefore L2+R2 Trigger axis supports only 360 turn range)
+ if (Global.getSASteeringWheelEmulationAxis(device) != DS4Controls.L2)
+ {
+ return (((result - maxRangeLeft) * (32767 - (-32768))) / (maxRangeRight - maxRangeLeft)) + (-32768);
+ }
+ else
+ {
+ result = Convert.ToInt32(Math.Round(result / (1.0 * C_WHEEL_ANGLE_PRECISION)));
+ if (result < 0) result = -181 - result;
+ return (((result - (-180)) * (255 - (-255))) / (180 - (-180))) + (-255);
+ }
}
}
// END: SixAxis steering wheel emulation logic
diff --git a/DS4Windows/DS4Control/X360Device.cs b/DS4Windows/DS4Control/X360Device.cs
index 7ef8123..a19fc51 100644
--- a/DS4Windows/DS4Control/X360Device.cs
+++ b/DS4Windows/DS4Control/X360Device.cs
@@ -140,16 +140,27 @@ namespace DS4Windows
if (state.PS) Output[11] |= (Byte)(1 << 2); // Guide
- Output[12] = state.L2; // Left Trigger
- Output[13] = state.R2; // Right Trigger
+ DS4Controls steeringWheelMappedAxis = Global.getSASteeringWheelEmulationAxis(device);
+
+ if (steeringWheelMappedAxis == DS4Controls.L2)
+ {
+ Output[12] = Output[13] = 0;
+ if (state.SASteeringWheelEmulationUnit >= 0)
+ Output[12] = (Byte)state.SASteeringWheelEmulationUnit;
+ else
+ Output[13] = (Byte)state.SASteeringWheelEmulationUnit;
+ }
+ else
+ {
+ Output[12] = state.L2; // Left Trigger
+ Output[13] = state.R2; // Right Trigger
+ }
Int32 ThumbLX;
Int32 ThumbLY;
Int32 ThumbRX;
Int32 ThumbRY;
- DS4Controls steeringWheelMappedAxis = Global.getSASteeringWheelEmulationAxis(device);
-
if (steeringWheelMappedAxis == DS4Controls.LXPos) ThumbLX = state.SASteeringWheelEmulationUnit;
else ThumbLX = Scale(state.LX, false);
diff --git a/DS4Windows/DS4Forms/Options.Designer.cs b/DS4Windows/DS4Forms/Options.Designer.cs
index cd9742a..7bc6cfb 100644
--- a/DS4Windows/DS4Forms/Options.Designer.cs
+++ b/DS4Windows/DS4Forms/Options.Designer.cs
@@ -188,6 +188,11 @@
this.lbGyroXP = new System.Windows.Forms.Label();
this.bnGyroXN = new System.Windows.Forms.Button();
this.lbGyroXN = new System.Windows.Forms.Label();
+ this.lblSteeringWheelEmulationAxis = new System.Windows.Forms.Label();
+ this.cBSteeringWheelEmulationAxis = new System.Windows.Forms.ComboBox();
+ this.lblSteeringWheelEmulationRange = new System.Windows.Forms.Label();
+ this.cBSteeringWheelEmulationRange = new System.Windows.Forms.ComboBox();
+ this.btnSteeringWheelEmulationCalibrate = new System.Windows.Forms.Button();
this.tCControls = new System.Windows.Forms.TabControl();
this.tPControls = new System.Windows.Forms.TabPage();
this.lBControls = new System.Windows.Forms.ListBox();
@@ -315,6 +320,8 @@
this.rBSAControls = new System.Windows.Forms.RadioButton();
this.rBSAMouse = new System.Windows.Forms.RadioButton();
this.pnlSAMouse = new System.Windows.Forms.Panel();
+ this.label26 = new System.Windows.Forms.Label();
+ this.triggerCondAndCombo = new System.Windows.Forms.ComboBox();
this.cBGyroMouseXAxis = new System.Windows.Forms.ComboBox();
this.label16 = new System.Windows.Forms.Label();
this.lbGyroSmooth = new System.Windows.Forms.Label();
@@ -386,8 +393,6 @@
this.optionsTouchInvStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.shareTouchInvStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.psTouchInvStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.triggerCondAndCombo = new System.Windows.Forms.ComboBox();
- this.label26 = new System.Windows.Forms.Label();
this.advColorDialog = new DS4Windows.AdvancedColorDialog();
((System.ComponentModel.ISupportInitialize)(this.nUDRainbow)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.tBBlueBar)).BeginInit();
@@ -1856,6 +1861,11 @@
this.fLPTiltControls.Controls.Add(this.lbGyroXP);
this.fLPTiltControls.Controls.Add(this.bnGyroXN);
this.fLPTiltControls.Controls.Add(this.lbGyroXN);
+ this.fLPTiltControls.Controls.Add(this.lblSteeringWheelEmulationAxis);
+ this.fLPTiltControls.Controls.Add(this.cBSteeringWheelEmulationAxis);
+ this.fLPTiltControls.Controls.Add(this.lblSteeringWheelEmulationRange);
+ this.fLPTiltControls.Controls.Add(this.cBSteeringWheelEmulationRange);
+ this.fLPTiltControls.Controls.Add(this.btnSteeringWheelEmulationCalibrate);
resources.ApplyResources(this.fLPTiltControls, "fLPTiltControls");
this.fLPTiltControls.Name = "fLPTiltControls";
//
@@ -1911,6 +1921,56 @@
resources.ApplyResources(this.lbGyroXN, "lbGyroXN");
this.lbGyroXN.Name = "lbGyroXN";
//
+ // lblSteeringWheelEmulationAxis
+ //
+ resources.ApplyResources(this.lblSteeringWheelEmulationAxis, "lblSteeringWheelEmulationAxis");
+ this.lblSteeringWheelEmulationAxis.Name = "lblSteeringWheelEmulationAxis";
+ //
+ // cBSteeringWheelEmulationAxis
+ //
+ this.cBSteeringWheelEmulationAxis.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cBSteeringWheelEmulationAxis.FormattingEnabled = true;
+ this.cBSteeringWheelEmulationAxis.Items.AddRange(new object[] {
+ resources.GetString("cBSteeringWheelEmulationAxis.Items"),
+ resources.GetString("cBSteeringWheelEmulationAxis.Items1"),
+ resources.GetString("cBSteeringWheelEmulationAxis.Items2"),
+ resources.GetString("cBSteeringWheelEmulationAxis.Items3"),
+ resources.GetString("cBSteeringWheelEmulationAxis.Items4"),
+ resources.GetString("cBSteeringWheelEmulationAxis.Items5")});
+ resources.ApplyResources(this.cBSteeringWheelEmulationAxis, "cBSteeringWheelEmulationAxis");
+ this.cBSteeringWheelEmulationAxis.Name = "cBSteeringWheelEmulationAxis";
+ this.cBSteeringWheelEmulationAxis.SelectedIndexChanged += new System.EventHandler(this.cBSteeringWheelEmulationAxis_SelectedIndexChanged);
+ //
+ // lblSteeringWheelEmulationRange
+ //
+ resources.ApplyResources(this.lblSteeringWheelEmulationRange, "lblSteeringWheelEmulationRange");
+ this.lblSteeringWheelEmulationRange.Name = "lblSteeringWheelEmulationRange";
+ //
+ // cBSteeringWheelEmulationRange
+ //
+ this.cBSteeringWheelEmulationRange.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cBSteeringWheelEmulationRange.FormattingEnabled = true;
+ this.cBSteeringWheelEmulationRange.Items.AddRange(new object[] {
+ resources.GetString("cBSteeringWheelEmulationRange.Items"),
+ resources.GetString("cBSteeringWheelEmulationRange.Items1"),
+ resources.GetString("cBSteeringWheelEmulationRange.Items2"),
+ resources.GetString("cBSteeringWheelEmulationRange.Items3"),
+ resources.GetString("cBSteeringWheelEmulationRange.Items4"),
+ resources.GetString("cBSteeringWheelEmulationRange.Items5"),
+ resources.GetString("cBSteeringWheelEmulationRange.Items6"),
+ resources.GetString("cBSteeringWheelEmulationRange.Items7"),
+ resources.GetString("cBSteeringWheelEmulationRange.Items8")});
+ resources.ApplyResources(this.cBSteeringWheelEmulationRange, "cBSteeringWheelEmulationRange");
+ this.cBSteeringWheelEmulationRange.Name = "cBSteeringWheelEmulationRange";
+ this.cBSteeringWheelEmulationRange.SelectedIndexChanged += new System.EventHandler(this.cBSteeringWheelEmulationRange_SelectedIndexChanged);
+ //
+ // btnSteeringWheelEmulationCalibrate
+ //
+ resources.ApplyResources(this.btnSteeringWheelEmulationCalibrate, "btnSteeringWheelEmulationCalibrate");
+ this.btnSteeringWheelEmulationCalibrate.Name = "btnSteeringWheelEmulationCalibrate";
+ this.btnSteeringWheelEmulationCalibrate.UseVisualStyleBackColor = true;
+ this.btnSteeringWheelEmulationCalibrate.Click += new System.EventHandler(this.btnSteeringWheelEmulationCalibrate_Click);
+ //
// tCControls
//
this.tCControls.Controls.Add(this.tPControls);
@@ -3362,8 +3422,8 @@
this.gBGyro.BackColor = System.Drawing.SystemColors.Control;
this.gBGyro.Controls.Add(this.rBSAControls);
this.gBGyro.Controls.Add(this.rBSAMouse);
- this.gBGyro.Controls.Add(this.pnlSAMouse);
this.gBGyro.Controls.Add(this.fLPTiltControls);
+ this.gBGyro.Controls.Add(this.pnlSAMouse);
resources.ApplyResources(this.gBGyro, "gBGyro");
this.gBGyro.Name = "gBGyro";
this.gBGyro.TabStop = false;
@@ -3408,6 +3468,21 @@
resources.ApplyResources(this.pnlSAMouse, "pnlSAMouse");
this.pnlSAMouse.Name = "pnlSAMouse";
//
+ // label26
+ //
+ resources.ApplyResources(this.label26, "label26");
+ this.label26.Name = "label26";
+ //
+ // triggerCondAndCombo
+ //
+ this.triggerCondAndCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.triggerCondAndCombo.FormattingEnabled = true;
+ this.triggerCondAndCombo.Items.AddRange(new object[] {
+ resources.GetString("triggerCondAndCombo.Items"),
+ resources.GetString("triggerCondAndCombo.Items1")});
+ resources.ApplyResources(this.triggerCondAndCombo, "triggerCondAndCombo");
+ this.triggerCondAndCombo.Name = "triggerCondAndCombo";
+ //
// cBGyroMouseXAxis
//
this.cBGyroMouseXAxis.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
@@ -4110,21 +4185,6 @@
resources.ApplyResources(this.psTouchInvStripMenuItem, "psTouchInvStripMenuItem");
this.psTouchInvStripMenuItem.CheckedChanged += new System.EventHandler(this.TouchDisableInvert_CheckedChanged);
//
- // triggerCondAndCombo
- //
- this.triggerCondAndCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
- this.triggerCondAndCombo.FormattingEnabled = true;
- this.triggerCondAndCombo.Items.AddRange(new object[] {
- resources.GetString("triggerCondAndCombo.Items"),
- resources.GetString("triggerCondAndCombo.Items1")});
- resources.ApplyResources(this.triggerCondAndCombo, "triggerCondAndCombo");
- this.triggerCondAndCombo.Name = "triggerCondAndCombo";
- //
- // label26
- //
- resources.ApplyResources(this.label26, "label26");
- this.label26.Name = "label26";
- //
// Options
//
resources.ApplyResources(this, "$this");
@@ -4192,6 +4252,7 @@
this.pnlLSTrack.ResumeLayout(false);
this.pnlRSTrack.ResumeLayout(false);
this.fLPTiltControls.ResumeLayout(false);
+ this.fLPTiltControls.PerformLayout();
this.tCControls.ResumeLayout(false);
this.tPControls.ResumeLayout(false);
this.pnlController.ResumeLayout(false);
@@ -4614,5 +4675,10 @@
private System.Windows.Forms.CheckBox trackballCk;
private System.Windows.Forms.Label label26;
private System.Windows.Forms.ComboBox triggerCondAndCombo;
+ private System.Windows.Forms.Label lblSteeringWheelEmulationAxis;
+ private System.Windows.Forms.ComboBox cBSteeringWheelEmulationAxis;
+ private System.Windows.Forms.Label lblSteeringWheelEmulationRange;
+ private System.Windows.Forms.ComboBox cBSteeringWheelEmulationRange;
+ private System.Windows.Forms.Button btnSteeringWheelEmulationCalibrate;
}
}
\ No newline at end of file
diff --git a/DS4Windows/DS4Forms/Options.cs b/DS4Windows/DS4Forms/Options.cs
index bad6866..b10b94c 100644
--- a/DS4Windows/DS4Forms/Options.cs
+++ b/DS4Windows/DS4Forms/Options.cs
@@ -718,6 +718,20 @@ namespace DS4Windows
nUDGyroSmoothWeight.Value = (decimal)(GyroSmoothingWeight[device]);
cBGyroMouseXAxis.SelectedIndex = GyroMouseHorizontalAxis[device];
triggerCondAndCombo.SelectedIndex = SATriggerCond[device] ? 0 : 1;
+
+ switch (getSASteeringWheelEmulationAxis(device))
+ {
+ case DS4Controls.None: cBSteeringWheelEmulationAxis.SelectedIndex = 0; break;
+ case DS4Controls.LXPos: cBSteeringWheelEmulationAxis.SelectedIndex = 1; break;
+ case DS4Controls.LYPos: cBSteeringWheelEmulationAxis.SelectedIndex = 2; break;
+ case DS4Controls.RXPos: cBSteeringWheelEmulationAxis.SelectedIndex = 3; break;
+ case DS4Controls.RYPos: cBSteeringWheelEmulationAxis.SelectedIndex = 4; break;
+ case DS4Controls.L2:
+ case DS4Controls.R2: cBSteeringWheelEmulationAxis.SelectedIndex = 5; break;
+ }
+
+ int idxSASteeringWheelEmulationRange = cBSteeringWheelEmulationRange.Items.IndexOf(getSASteeringWheelEmulationRange(device).ToString());
+ if (idxSASteeringWheelEmulationRange >= 0) cBSteeringWheelEmulationRange.SelectedIndex = idxSASteeringWheelEmulationRange;
}
else
{
@@ -836,6 +850,8 @@ namespace DS4Windows
nUDGyroSmoothWeight.Value = 0.5m;
cBGyroMouseXAxis.SelectedIndex = 0;
triggerCondAndCombo.SelectedIndex = 0;
+ cBSteeringWheelEmulationAxis.SelectedIndex = 0;
+ cBSteeringWheelEmulationRange.SelectedIndex = cBSteeringWheelEmulationRange.Items.IndexOf("360");
Set();
}
@@ -2992,6 +3008,85 @@ namespace DS4Windows
}
}
+ private void cBSteeringWheelEmulationRange_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (loading == false)
+ {
+ SASteeringWheelEmulationRange[device] = Convert.ToInt32(cBSteeringWheelEmulationRange.Items[cBSteeringWheelEmulationRange.SelectedIndex].ToString());
+ }
+ }
+
+ private void cBSteeringWheelEmulationAxis_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (loading == false)
+ {
+ switch (cBSteeringWheelEmulationAxis.SelectedIndex)
+ {
+ case 0: SASteeringWheelEmulationAxis[device] = DS4Controls.None; break; // Gyro SA steering wheel emulation disabled
+ case 1: SASteeringWheelEmulationAxis[device] = DS4Controls.LXPos; break; // Left stick X axis
+ case 2: SASteeringWheelEmulationAxis[device] = DS4Controls.LYPos; break; // Left stick Y axis
+ case 3: SASteeringWheelEmulationAxis[device] = DS4Controls.RXPos; break; // Right stick X axis
+ case 4: SASteeringWheelEmulationAxis[device] = DS4Controls.RYPos; break; // Right stick Y axis
+ case 5: SASteeringWheelEmulationAxis[device] = DS4Controls.L2; break; // Left+Right trigger axis (max range -255..0 as left trigger and 0..+255 as right trigger)
+ }
+ }
+ }
+
+ private void btnSteeringWheelEmulationCalibrate_Click(object sender, EventArgs e)
+ {
+ if(cBSteeringWheelEmulationAxis.SelectedIndex > 0)
+ {
+ DS4Device d;
+ int tempDeviceNum = (int)nUDSixaxis.Value - 1;
+
+ d = Program.rootHub.DS4Controllers[tempDeviceNum];
+ if (d != null)
+ {
+ Point origWheelCenterPoint = new Point(d.wheelCenterPoint.X, d.wheelCenterPoint.Y);
+ Point origWheel90DegPointLeft = new Point(d.wheel90DegPointLeft.X, d.wheel90DegPointLeft.Y);
+ Point origWheel90DegPointRight = new Point(d.wheel90DegPointRight.X, d.wheel90DegPointRight.Y);
+
+ d.WheelRecalibrateActiveState = 1;
+
+ DialogResult msgBoxResult = MessageBox.Show($"{Properties.Resources.SASteeringWheelEmulationCalibrate}.\n\n" +
+ $"{Properties.Resources.SASteeringWheelEmulationCalibrateInstruction1}.\n" +
+ $"{Properties.Resources.SASteeringWheelEmulationCalibrateInstruction2}.\n" +
+ $"{Properties.Resources.SASteeringWheelEmulationCalibrateInstruction3}.\n\n" +
+ $"{Properties.Resources.SASteeringWheelEmulationCalibrateInstruction}.\n",
+ Properties.Resources.SASteeringWheelEmulationCalibrate,
+ MessageBoxButtons.OKCancel,
+ MessageBoxIcon.Information,
+ MessageBoxDefaultButton.Button1,
+ 0,
+ false);
+
+ if (msgBoxResult == DialogResult.OK)
+ {
+ // Accept new calibration values (State 3 is "Complete calibration" state)
+ d.WheelRecalibrateActiveState = 3;
+ }
+ else
+ {
+ // Cancel calibration and reset back to original calibration values
+ d.WheelRecalibrateActiveState = 4;
+
+ d.wheelFullTurnCount = 0;
+ d.wheelCenterPoint = origWheelCenterPoint;
+ d.wheel90DegPointLeft = origWheel90DegPointLeft;
+ d.wheel90DegPointRight = origWheel90DegPointRight;
+ }
+ }
+ else
+ {
+ MessageBox.Show($"{Properties.Resources.SASteeringWheelEmulationCalibrateNoControllerError}.");
+ }
+ }
+ else
+ {
+ MessageBox.Show($"{Properties.Resources.SASteeringWheelEmulationCalibrateNoneAxisError}.");
+ }
+ }
+
private void trackFrictionNUD_ValueChanged(object sender, EventArgs e)
{
if (loading == false)
diff --git a/DS4Windows/DS4Forms/Options.resx b/DS4Windows/DS4Forms/Options.resx
index dc50f18..4a5c38d 100644
--- a/DS4Windows/DS4Forms/Options.resx
+++ b/DS4Windows/DS4Forms/Options.resx
@@ -4057,11 +4057,191 @@ with profile
7
+
+ True
+
+
+ NoControl
+
+
+ 3, 116
+
+
+ 0, 5, 0, 0
+
+
+ 98, 18
+
+
+ 290
+
+
+ Steering wheel axis
+
+
+ lblSteeringWheelEmulationAxis
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ fLPTiltControls
+
+
+ 8
+
+
+ None
+
+
+ Left X-Axis
+
+
+ Left Y-Axis
+
+
+ Right X-Axis
+
+
+ Right Y-Axis
+
+
+ Trigger L+R Axis
+
+
+ 107, 119
+
+
+ 110, 21
+
+
+ 291
+
+
+ cBSteeringWheelEmulationAxis
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ fLPTiltControls
+
+
+ 9
+
+
+ True
+
+
+ NoControl
+
+
+ 3, 143
+
+
+ 0, 5, 0, 0
+
+
+ 107, 18
+
+
+ 292
+
+
+ Steering wheel range
+
+
+ lblSteeringWheelEmulationRange
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ fLPTiltControls
+
+
+ 10
+
+
+ 90
+
+
+ 180
+
+
+ 270
+
+
+ 360
+
+
+ 450
+
+
+ 720
+
+
+ 900
+
+
+ 1080
+
+
+ 1440
+
+
+ 116, 146
+
+
+ 60, 21
+
+
+ 293
+
+
+ cBSteeringWheelEmulationRange
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ fLPTiltControls
+
+
+ 11
+
+
+ NoControl
+
+
+ 182, 146
+
+
+ 75, 23
+
+
+ 294
+
+
+ Calibrate...
+
+
+ btnSteeringWheelEmulationCalibrate
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ fLPTiltControls
+
+
+ 12
+
4, 43
- 271, 167
+ 271, 170
254
@@ -4076,7 +4256,7 @@ with profile
gBGyro
- 3
+ 2
True
@@ -8297,7 +8477,7 @@ with profile
gBGyro
- 2
+ 3
3, 253
@@ -8971,9 +9151,6 @@ with profile
1011, 481
-
- NoControl
-
4, 4, 4, 4
@@ -9392,7 +9569,7 @@ with profile
advColorDialog
- DS4Windows.AdvancedColorDialog, DS4Windows, Version=1.5.8.0, Culture=neutral, PublicKeyToken=null
+ DS4Windows.AdvancedColorDialog, DS4Windows, Version=1.5.17.0, Culture=neutral, PublicKeyToken=null
Options
diff --git a/DS4Windows/DS4Library/DS4Device.cs b/DS4Windows/DS4Library/DS4Device.cs
index 1dc2991..283e582 100644
--- a/DS4Windows/DS4Library/DS4Device.cs
+++ b/DS4Windows/DS4Library/DS4Device.cs
@@ -158,6 +158,7 @@ namespace DS4Windows
}
public Int32 wheelPrevPhysicalAngle = 0;
+ public Int32 wheelPrevFullAngle = 0;
public Int32 wheelFullTurnCount = 0;
public Point wheelCenterPoint;
diff --git a/DS4Windows/Properties/Resources.Designer.cs b/DS4Windows/Properties/Resources.Designer.cs
index 2145fc9..1d7eb76 100644
--- a/DS4Windows/Properties/Resources.Designer.cs
+++ b/DS4Windows/Properties/Resources.Designer.cs
@@ -1636,6 +1636,60 @@ namespace DS4Windows.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to All calibraton points are set when lightbar color turns to green. While turning the controller the lightbar color flashes when the controller is at calibration point. Accept calibration with OK button.
+ ///
+ internal static string SASteeringWheelEmulationCalibrateInstruction {
+ get {
+ return ResourceManager.GetString("SASteeringWheelEmulationCalibrateInstruction", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to (1) Center the controller, hold it steady and press "X".
+ ///
+ internal static string SASteeringWheelEmulationCalibrateInstruction1 {
+ get {
+ return ResourceManager.GetString("SASteeringWheelEmulationCalibrateInstruction1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to (2) Turn to 90° left (or right) position and press "X".
+ ///
+ internal static string SASteeringWheelEmulationCalibrateInstruction2 {
+ get {
+ return ResourceManager.GetString("SASteeringWheelEmulationCalibrateInstruction2", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to (3) Turn to 90° right (or left) position and press "X".
+ ///
+ internal static string SASteeringWheelEmulationCalibrateInstruction3 {
+ get {
+ return ResourceManager.GetString("SASteeringWheelEmulationCalibrateInstruction3", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot calibrate gyro (sixaxis) steering wheel emulation values without a controller. Connect a controller via bluetooth or usb.
+ ///
+ internal static string SASteeringWheelEmulationCalibrateNoControllerError {
+ get {
+ return ResourceManager.GetString("SASteeringWheelEmulationCalibrateNoControllerError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Gyro steering wheel emulation axis option is set to NONE (emulation is not used). Please select an axis option before calibrating the sixaxis gyro steering wheel emulation.
+ ///
+ internal static string SASteeringWheelEmulationCalibrateNoneAxisError {
+ get {
+ return ResourceManager.GetString("SASteeringWheelEmulationCalibrateNoneAxisError", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
diff --git a/DS4Windows/Properties/Resources.resx b/DS4Windows/Properties/Resources.resx
index dbc3d2c..af66c79 100644
--- a/DS4Windows/Properties/Resources.resx
+++ b/DS4Windows/Properties/Resources.resx
@@ -640,6 +640,24 @@
Calibration of sixaxis wheel emulation
+
+ (1) Center the controller, hold it steady and press "X"
+
+
+ (2) Turn to 90° left (or right) position and press "X"
+
+
+ (3) Turn to 90° right (or left) position and press "X"
+
+
+ All calibraton points are set when lightbar color turns to green. While turning the controller the lightbar color flashes when the controller is at calibration point. Accept calibration with OK button
+
+
+ Cannot calibrate gyro (sixaxis) steering wheel emulation values without a controller. Connect a controller via bluetooth or usb
+
+
+ Gyro steering wheel emulation axis option is set to NONE (emulation is not used). Please select an axis option before calibrating the sixaxis gyro steering wheel emulation
+
Click for advanced Sixaxis reading