mirror of
https://github.com/cemu-project/DS4Windows.git
synced 2024-12-23 23:21:49 +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];
|
||||
}
|
||||
|
||||
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 getRainbow(int index)
|
||||
{
|
||||
@ -1949,6 +1963,7 @@ namespace DS4Windows
|
||||
// Cache properties instead of performing a string comparison every frame
|
||||
public bool[] distanceProfiles = new bool[5] { false, false, false, false, false };
|
||||
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 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();
|
||||
Node.AppendChild(xmlColor);
|
||||
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 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);
|
||||
@ -3084,6 +3100,9 @@ namespace DS4Windows
|
||||
try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/RumbleBoost"); Byte.TryParse(Item.InnerText, out rumble[device]); }
|
||||
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]); }
|
||||
catch { missingSetting = true; }
|
||||
|
||||
@ -4722,6 +4741,7 @@ namespace DS4Windows
|
||||
ledAsBattery[device] = false;
|
||||
flashType[device] = 0;
|
||||
rumble[device] = 100;
|
||||
rumbleAutostopTime[device] = 0;
|
||||
touchSensitivity[device] = 100;
|
||||
l2ModInfo[device].deadZone = r2ModInfo[device].deadZone = 0;
|
||||
lsModInfo[device].deadZone = rsModInfo[device].deadZone = 10;
|
||||
@ -4909,7 +4929,8 @@ namespace DS4Windows
|
||||
control.UnplugOutDev(device, tempDev);
|
||||
}
|
||||
|
||||
tempDev.setRumble(0, 0);
|
||||
tempDev.RumbleAutostopTime = rumbleAutostopTime[device];
|
||||
tempDev.setRumble(0, 0);
|
||||
});
|
||||
|
||||
Program.rootHub.touchPad[device]?.ResetTrackAccel(trackballFriction[device]);
|
||||
|
@ -910,9 +910,11 @@
|
||||
<StackPanel>
|
||||
<GroupBox Header="{lex:Loc Rumble}" MinHeight="50" Margin="4,4,4,0" Padding="0,4,0,4">
|
||||
<UniformGrid Rows="1" Columns="3">
|
||||
<UniformGrid Columns="2">
|
||||
<xctk:IntegerUpDown x:Name="RumbleBoostIUD" d:IsHidden="True" MinWidth="60" Value="{Binding RumbleBoost}" Minimum="0" Maximum="200" Increment="10" />
|
||||
<UniformGrid Columns="4" HorizontalAlignment="Left">
|
||||
<xctk:IntegerUpDown x:Name="RumbleBoostIUD" d:IsHidden="True" Value="{Binding RumbleBoost}" Minimum="0" Maximum="200" Increment="10" />
|
||||
<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>
|
||||
|
||||
<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;
|
||||
}
|
||||
|
||||
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;
|
||||
public bool HeavyRumbleActive
|
||||
{
|
||||
|
@ -329,6 +329,24 @@ namespace DS4Windows
|
||||
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
|
||||
{
|
||||
get { return currentHap.LightBarColor; }
|
||||
@ -1251,7 +1269,7 @@ namespace DS4Windows
|
||||
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
|
||||
if (rumbleAutostopTimer.ElapsedMilliseconds >= 2000L)
|
||||
if (rumbleAutostopTimer.ElapsedMilliseconds >= rumbleAutostopTime)
|
||||
setRumble(0, 0);
|
||||
}
|
||||
|
||||
@ -1445,10 +1463,14 @@ namespace DS4Windows
|
||||
testRumble.RumbleMotorStrengthLeftHeavySlow = leftHeavySlowMotor;
|
||||
testRumble.RumbleMotorsExplicitlyOff = rightLightFastMotor == 0 && leftHeavySlowMotor == 0;
|
||||
|
||||
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
|
||||
// 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)
|
||||
if (rumbleAutostopTime > 0)
|
||||
{
|
||||
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()
|
||||
|
24
DS4Windows/Translations/Strings.Designer.cs
generated
24
DS4Windows/Translations/Strings.Designer.cs
generated
@ -187,8 +187,7 @@ namespace DS4WinWPF.Translations {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Clear
|
||||
///.
|
||||
/// Looks up a localized string similar to Clear.
|
||||
/// </summary>
|
||||
public static string Clear {
|
||||
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>
|
||||
/// Looks up a localized string similar to Run At Startup.
|
||||
/// </summary>
|
||||
@ -584,8 +601,7 @@ namespace DS4WinWPF.Translations {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Scroll
|
||||
///.
|
||||
/// Looks up a localized string similar to Scroll.
|
||||
/// </summary>
|
||||
public static string TouchScroll {
|
||||
get {
|
||||
|
@ -306,4 +306,10 @@
|
||||
<data name="WarningsOnly" xml:space="preserve">
|
||||
<value>Warnings only</value>
|
||||
</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>
|
Loading…
Reference in New Issue
Block a user