mirror of
https://github.com/cemu-project/DS4Windows.git
synced 2024-11-22 17:29:18 +01:00
User configurable (profile) max time in seconds for a rumble effect. The rumble watchdog timer used to be fixed 2 secs, but now it is possible to disable this watchdog timer (0 secs value) or set the max time in profile editor.
This commit is contained in:
parent
b74b37463c
commit
77e713e7b9
@ -980,6 +980,20 @@ namespace DS4Windows
|
|||||||
return m_Config.rumble[index];
|
return m_Config.rumble[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setRumbleAutostopTime(int index, int value)
|
||||||
|
{
|
||||||
|
m_Config.rumbleAutostopTime[index] = value;
|
||||||
|
|
||||||
|
DS4Device tempDev = Program.rootHub.DS4Controllers[index];
|
||||||
|
if (tempDev != null && tempDev.isSynced())
|
||||||
|
tempDev.RumbleAutostopTime = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getRumbleAutostopTime(int index)
|
||||||
|
{
|
||||||
|
return m_Config.rumbleAutostopTime[index];
|
||||||
|
}
|
||||||
|
|
||||||
public static double[] Rainbow => m_Config.rainbow;
|
public static double[] Rainbow => m_Config.rainbow;
|
||||||
public static double getRainbow(int index)
|
public static double getRainbow(int index)
|
||||||
{
|
{
|
||||||
@ -1949,6 +1963,7 @@ namespace DS4Windows
|
|||||||
// Cache properties instead of performing a string comparison every frame
|
// Cache properties instead of performing a string comparison every frame
|
||||||
public bool[] distanceProfiles = new bool[5] { false, false, false, false, false };
|
public bool[] distanceProfiles = new bool[5] { false, false, false, false, false };
|
||||||
public Byte[] rumble = new Byte[5] { 100, 100, 100, 100, 100 };
|
public Byte[] rumble = new Byte[5] { 100, 100, 100, 100, 100 };
|
||||||
|
public int[] rumbleAutostopTime = new int[5] { 0, 0, 0, 0, 0 }; // Value in milliseconds (0=autustop timer disabled)
|
||||||
public Byte[] touchSensitivity = new Byte[5] { 100, 100, 100, 100, 100 };
|
public Byte[] touchSensitivity = new Byte[5] { 100, 100, 100, 100, 100 };
|
||||||
public StickDeadZoneInfo[] lsModInfo = new StickDeadZoneInfo[5]
|
public StickDeadZoneInfo[] lsModInfo = new StickDeadZoneInfo[5]
|
||||||
{
|
{
|
||||||
@ -2438,6 +2453,7 @@ namespace DS4Windows
|
|||||||
xmlColor.InnerText = m_Leds[device].red.ToString() + "," + m_Leds[device].green.ToString() + "," + m_Leds[device].blue.ToString();
|
xmlColor.InnerText = m_Leds[device].red.ToString() + "," + m_Leds[device].green.ToString() + "," + m_Leds[device].blue.ToString();
|
||||||
Node.AppendChild(xmlColor);
|
Node.AppendChild(xmlColor);
|
||||||
XmlNode xmlRumbleBoost = m_Xdoc.CreateNode(XmlNodeType.Element, "RumbleBoost", null); xmlRumbleBoost.InnerText = rumble[device].ToString(); Node.AppendChild(xmlRumbleBoost);
|
XmlNode xmlRumbleBoost = m_Xdoc.CreateNode(XmlNodeType.Element, "RumbleBoost", null); xmlRumbleBoost.InnerText = rumble[device].ToString(); Node.AppendChild(xmlRumbleBoost);
|
||||||
|
XmlNode xmlRumbleAutostopTime = m_Xdoc.CreateNode(XmlNodeType.Element, "RumbleAutostopTime", null); xmlRumbleAutostopTime.InnerText = rumbleAutostopTime[device].ToString(); Node.AppendChild(xmlRumbleAutostopTime);
|
||||||
XmlNode xmlLedAsBatteryIndicator = m_Xdoc.CreateNode(XmlNodeType.Element, "ledAsBatteryIndicator", null); xmlLedAsBatteryIndicator.InnerText = ledAsBattery[device].ToString(); Node.AppendChild(xmlLedAsBatteryIndicator);
|
XmlNode xmlLedAsBatteryIndicator = m_Xdoc.CreateNode(XmlNodeType.Element, "ledAsBatteryIndicator", null); xmlLedAsBatteryIndicator.InnerText = ledAsBattery[device].ToString(); Node.AppendChild(xmlLedAsBatteryIndicator);
|
||||||
XmlNode xmlLowBatteryFlash = m_Xdoc.CreateNode(XmlNodeType.Element, "FlashType", null); xmlLowBatteryFlash.InnerText = flashType[device].ToString(); Node.AppendChild(xmlLowBatteryFlash);
|
XmlNode xmlLowBatteryFlash = m_Xdoc.CreateNode(XmlNodeType.Element, "FlashType", null); xmlLowBatteryFlash.InnerText = flashType[device].ToString(); Node.AppendChild(xmlLowBatteryFlash);
|
||||||
XmlNode xmlFlashBatterAt = m_Xdoc.CreateNode(XmlNodeType.Element, "flashBatteryAt", null); xmlFlashBatterAt.InnerText = flashAt[device].ToString(); Node.AppendChild(xmlFlashBatterAt);
|
XmlNode xmlFlashBatterAt = m_Xdoc.CreateNode(XmlNodeType.Element, "flashBatteryAt", null); xmlFlashBatterAt.InnerText = flashAt[device].ToString(); Node.AppendChild(xmlFlashBatterAt);
|
||||||
@ -3084,6 +3100,9 @@ namespace DS4Windows
|
|||||||
try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/RumbleBoost"); Byte.TryParse(Item.InnerText, out rumble[device]); }
|
try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/RumbleBoost"); Byte.TryParse(Item.InnerText, out rumble[device]); }
|
||||||
catch { missingSetting = true; }
|
catch { missingSetting = true; }
|
||||||
|
|
||||||
|
try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/RumbleAutostopTime"); Int32.TryParse(Item.InnerText, out rumbleAutostopTime[device]); }
|
||||||
|
catch { missingSetting = true; }
|
||||||
|
|
||||||
try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/ledAsBatteryIndicator"); Boolean.TryParse(Item.InnerText, out ledAsBattery[device]); }
|
try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/ledAsBatteryIndicator"); Boolean.TryParse(Item.InnerText, out ledAsBattery[device]); }
|
||||||
catch { missingSetting = true; }
|
catch { missingSetting = true; }
|
||||||
|
|
||||||
@ -4722,6 +4741,7 @@ namespace DS4Windows
|
|||||||
ledAsBattery[device] = false;
|
ledAsBattery[device] = false;
|
||||||
flashType[device] = 0;
|
flashType[device] = 0;
|
||||||
rumble[device] = 100;
|
rumble[device] = 100;
|
||||||
|
rumbleAutostopTime[device] = 0;
|
||||||
touchSensitivity[device] = 100;
|
touchSensitivity[device] = 100;
|
||||||
l2ModInfo[device].deadZone = r2ModInfo[device].deadZone = 0;
|
l2ModInfo[device].deadZone = r2ModInfo[device].deadZone = 0;
|
||||||
lsModInfo[device].deadZone = rsModInfo[device].deadZone = 10;
|
lsModInfo[device].deadZone = rsModInfo[device].deadZone = 10;
|
||||||
@ -4909,6 +4929,7 @@ namespace DS4Windows
|
|||||||
control.UnplugOutDev(device, tempDev);
|
control.UnplugOutDev(device, tempDev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tempDev.RumbleAutostopTime = rumbleAutostopTime[device];
|
||||||
tempDev.setRumble(0, 0);
|
tempDev.setRumble(0, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -910,9 +910,11 @@
|
|||||||
<StackPanel>
|
<StackPanel>
|
||||||
<GroupBox Header="{lex:Loc Rumble}" MinHeight="50" Margin="4,4,4,0" Padding="0,4,0,4">
|
<GroupBox Header="{lex:Loc Rumble}" MinHeight="50" Margin="4,4,4,0" Padding="0,4,0,4">
|
||||||
<UniformGrid Rows="1" Columns="3">
|
<UniformGrid Rows="1" Columns="3">
|
||||||
<UniformGrid Columns="2">
|
<UniformGrid Columns="4" HorizontalAlignment="Left">
|
||||||
<xctk:IntegerUpDown x:Name="RumbleBoostIUD" d:IsHidden="True" MinWidth="60" Value="{Binding RumbleBoost}" Minimum="0" Maximum="200" Increment="10" />
|
<xctk:IntegerUpDown x:Name="RumbleBoostIUD" d:IsHidden="True" Value="{Binding RumbleBoost}" Minimum="0" Maximum="200" Increment="10" />
|
||||||
<Label Content="%" />
|
<Label Content="%" />
|
||||||
|
<xctk:IntegerUpDown x:Name="RumbleAutostopTimeIUD" d:IsHidden="True" Value="{Binding RumbleAutostopTime}" Minimum="0" Maximum="3600" Increment="1" ToolTip="{lex:Loc RumbleMaxSecsTip}"/>
|
||||||
|
<Label Content="{lex:Loc RumbleMaxSecs}" />
|
||||||
</UniformGrid>
|
</UniformGrid>
|
||||||
|
|
||||||
<Button x:Name="heavyRumbleTestBtn" Content="Test Heavy" Margin="10,0,0,0" Click="HeavyRumbleTestBtn_Click" />
|
<Button x:Name="heavyRumbleTestBtn" Content="Test Heavy" Margin="10,0,0,0" Click="HeavyRumbleTestBtn_Click" />
|
||||||
|
@ -342,6 +342,13 @@ namespace DS4WinWPF.DS4Forms.ViewModels
|
|||||||
set => Global.RumbleBoost[device] = (byte)value;
|
set => Global.RumbleBoost[device] = (byte)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int RumbleAutostopTime
|
||||||
|
{
|
||||||
|
// RumbleAutostopTime value is in milliseconds in XML config file, but GUI uses just seconds
|
||||||
|
get => Global.getRumbleAutostopTime(device) / 1000;
|
||||||
|
set => Global.setRumbleAutostopTime(device, value * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
private bool heavyRumbleActive;
|
private bool heavyRumbleActive;
|
||||||
public bool HeavyRumbleActive
|
public bool HeavyRumbleActive
|
||||||
{
|
{
|
||||||
|
@ -329,6 +329,24 @@ namespace DS4Windows
|
|||||||
return currentHap.RumbleMotorStrengthLeftHeavySlow;
|
return currentHap.RumbleMotorStrengthLeftHeavySlow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int rumbleAutostopTime = 0;
|
||||||
|
public int RumbleAutostopTime
|
||||||
|
{
|
||||||
|
get { return rumbleAutostopTime; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// Value in milliseconds
|
||||||
|
rumbleAutostopTime = value;
|
||||||
|
|
||||||
|
// If autostop timer is disabled (value 0) then stop existing autostop timer otherwise restart it
|
||||||
|
if (value <= 0)
|
||||||
|
rumbleAutostopTimer.Reset();
|
||||||
|
else
|
||||||
|
rumbleAutostopTimer.Restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public DS4Color LightBarColor
|
public DS4Color LightBarColor
|
||||||
{
|
{
|
||||||
get { return currentHap.LightBarColor; }
|
get { return currentHap.LightBarColor; }
|
||||||
@ -1251,7 +1269,7 @@ namespace DS4Windows
|
|||||||
if (rumbleAutostopTimer.IsRunning)
|
if (rumbleAutostopTimer.IsRunning)
|
||||||
{
|
{
|
||||||
// Workaround to a bug in ViGem driver. Force stop potentially stuck rumble motor on the next output report if there haven't been new rumble events within X seconds
|
// Workaround to a bug in ViGem driver. Force stop potentially stuck rumble motor on the next output report if there haven't been new rumble events within X seconds
|
||||||
if (rumbleAutostopTimer.ElapsedMilliseconds >= 2000L)
|
if (rumbleAutostopTimer.ElapsedMilliseconds >= rumbleAutostopTime)
|
||||||
setRumble(0, 0);
|
setRumble(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1445,10 +1463,14 @@ namespace DS4Windows
|
|||||||
testRumble.RumbleMotorStrengthLeftHeavySlow = leftHeavySlowMotor;
|
testRumble.RumbleMotorStrengthLeftHeavySlow = leftHeavySlowMotor;
|
||||||
testRumble.RumbleMotorsExplicitlyOff = rightLightFastMotor == 0 && leftHeavySlowMotor == 0;
|
testRumble.RumbleMotorsExplicitlyOff = rightLightFastMotor == 0 && leftHeavySlowMotor == 0;
|
||||||
|
|
||||||
if (testRumble.RumbleMotorsExplicitlyOff)
|
// If rumble autostop timer (msecs) is enabled for this device then restart autostop timer everytime rumble is modified (or stop the timer if rumble is set to zero)
|
||||||
rumbleAutostopTimer.Reset(); // Stop an autostop timer because ViGem driver sent properly a zero rumble notification
|
if (rumbleAutostopTime > 0)
|
||||||
else
|
{
|
||||||
rumbleAutostopTimer.Restart(); // Start an autostop timer to stop potentially stuck rumble motor because of lost rumble notification events from ViGem driver
|
if (testRumble.RumbleMotorsExplicitlyOff)
|
||||||
|
rumbleAutostopTimer.Reset(); // Stop an autostop timer because ViGem driver sent properly a zero rumble notification
|
||||||
|
else
|
||||||
|
rumbleAutostopTimer.Restart(); // Start an autostop timer to stop potentially stuck rumble motor because of lost rumble notification events from ViGem driver
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MergeStates()
|
private void MergeStates()
|
||||||
|
24
DS4Windows/Translations/Strings.Designer.cs
generated
24
DS4Windows/Translations/Strings.Designer.cs
generated
@ -187,8 +187,7 @@ namespace DS4WinWPF.Translations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Clear
|
/// Looks up a localized string similar to Clear.
|
||||||
///.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Clear {
|
public static string Clear {
|
||||||
get {
|
get {
|
||||||
@ -502,6 +501,24 @@ namespace DS4WinWPF.Translations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to sec.
|
||||||
|
/// </summary>
|
||||||
|
public static string RumbleMaxSecs {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("RumbleMaxSecs", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Auto stop rumble in secs (0=auto stop disabled).
|
||||||
|
/// </summary>
|
||||||
|
public static string RumbleMaxSecsTip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("RumbleMaxSecsTip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Run At Startup.
|
/// Looks up a localized string similar to Run At Startup.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -584,8 +601,7 @@ namespace DS4WinWPF.Translations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Scroll
|
/// Looks up a localized string similar to Scroll.
|
||||||
///.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string TouchScroll {
|
public static string TouchScroll {
|
||||||
get {
|
get {
|
||||||
|
@ -306,4 +306,10 @@
|
|||||||
<data name="WarningsOnly" xml:space="preserve">
|
<data name="WarningsOnly" xml:space="preserve">
|
||||||
<value>Warnings only</value>
|
<value>Warnings only</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="RumbleMaxSecs" xml:space="preserve">
|
||||||
|
<value>sec</value>
|
||||||
|
</data>
|
||||||
|
<data name="RumbleMaxSecsTip" xml:space="preserve">
|
||||||
|
<value>Auto stop rumble in secs (0=auto stop disabled)</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
Loading…
Reference in New Issue
Block a user