diff --git a/DS4Windows/DS4Control/DS4LightBar.cs b/DS4Windows/DS4Control/DS4LightBar.cs index d06b91c..0a146c6 100644 --- a/DS4Windows/DS4Control/DS4LightBar.cs +++ b/DS4Windows/DS4Control/DS4LightBar.cs @@ -304,7 +304,8 @@ namespace DS4Windows if (tempLightBarOnDuration != haptics.LightBarFlashDurationOn && tempLightBarOnDuration != 1 && haptics.LightBarFlashDurationOn == 0) haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = 1; - device.pushHapticState(ref haptics); + device.SetHapticState(ref haptics); + //device.pushHapticState(ref haptics); } public static bool defaultLight = false, shuttingdown = false; diff --git a/DS4Windows/DS4Control/Mapping.cs b/DS4Windows/DS4Control/Mapping.cs index 3673ab1..84ce6d8 100644 --- a/DS4Windows/DS4Control/Mapping.cs +++ b/DS4Windows/DS4Control/Mapping.cs @@ -1846,6 +1846,9 @@ namespace DS4Windows } } } + + string prolog = Properties.Resources.UsingProfile.Replace("*number*", (device + 1).ToString()).Replace("*Profile name*", action.details); + AppLogger.LogToGui(prolog, false); LoadTempProfile(device, action.details, true, ctrl); return; } @@ -2233,6 +2236,8 @@ namespace DS4Windows } untriggeraction[device] = null; + string prolog = Properties.Resources.UsingProfile.Replace("*number*", (device + 1).ToString()).Replace("*Profile name*", ProfilePath[device]); + AppLogger.LogToGui(prolog, false); LoadProfile(device, false, ctrl); } } diff --git a/DS4Windows/DS4Forms/DS4Form.cs b/DS4Windows/DS4Forms/DS4Form.cs index 7ad27d3..b48dcbb 100644 --- a/DS4Windows/DS4Forms/DS4Form.cs +++ b/DS4Windows/DS4Forms/DS4Form.cs @@ -6,7 +6,6 @@ using System.Reflection; using System.Collections.Generic; using System.Net; using System.Drawing; -using Microsoft.Win32; using System.Diagnostics; using System.Xml; using System.Text; @@ -18,6 +17,7 @@ using TaskRunner = System.Threading.Tasks.Task; using NonFormTimer = System.Timers.Timer; using static DS4Windows.Global; using System.Security; +using System.Management; namespace DS4Windows { @@ -37,8 +37,8 @@ namespace DS4Windows private ToolStripMenuItem[] shortcuts; private ToolStripMenuItem[] disconnectShortcuts; protected CheckBox[] linkedProfileCB; - NonFormTimer hotkeysTimer = new NonFormTimer(); - NonFormTimer autoProfilesTimer = new NonFormTimer(); + NonFormTimer hotkeysTimer = null;// new NonFormTimer(); + NonFormTimer autoProfilesTimer = null;// new NonFormTimer(); string tempProfileProgram = string.Empty; double dpix, dpiy; List profilenames = new List(); @@ -56,7 +56,7 @@ namespace DS4Windows bool runningBat; private bool changingService; private IntPtr regHandle = new IntPtr(); - private static DS4Form instance; + private ManagementEventWatcher managementEvWatcher; Dictionary hoverTextDict = new Dictionary(); // 0 index is used for application version text. 1 - 4 indices are used for controller status string[] notifyText = new string[5] @@ -66,7 +66,7 @@ namespace DS4Windows private const string UPDATER_VERSION = "1.3.0"; private const int WM_QUERYENDSESSION = 0x11; private const int WM_CLOSE = 0x10; - internal string updaterExe = Environment.Is64BitProcess ? "DS4Updater_x64.exe" : "DS4Updater_x86.exe"; + internal string updaterExe = Environment.Is64BitProcess ? "DS4Updater.exe" : "DS4Updater_x86.exe"; [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); @@ -126,7 +126,13 @@ namespace DS4Windows linkedProfileCB = new CheckBox[4] { linkCB1, linkCB2, linkCB3, linkCB4 }; - SystemEvents.PowerModeChanged += OnPowerChange; + WqlEventQuery q = new WqlEventQuery(); + ManagementScope scope = new ManagementScope("root\\CIMV2"); + q.EventClassName = "Win32_PowerManagementEvent"; + managementEvWatcher = new ManagementEventWatcher(scope, q); + managementEvWatcher.EventArrived += PowerEventArrive; + managementEvWatcher.Start(); + tSOptions.Visible = false; TaskRunner.Run(() => CheckDrivers()); @@ -243,16 +249,10 @@ namespace DS4Windows */ //tabProfiles.Controls.Add(opt); - //autoProfilesTimer.Elapsed += CheckAutoProfiles; - autoProfilesTimer.Interval = 1000; - autoProfilesTimer.AutoReset = false; - FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location); string version = fvi.FileVersion; LogDebug(DateTime.Now, "DS4Windows version " + version, false); - LoadP(); - Global.BatteryStatusChange += BatteryStatusUpdate; Global.ControllerRemoved += ControllerRemovedChange; Global.DeviceStatusChange += DeviceStatusChanged; @@ -264,17 +264,9 @@ namespace DS4Windows Enable_Controls(3, false); btnStartStop.Text = Properties.Resources.StartText; - //hotkeysTimer.Elapsed += Hotkeys; - hotkeysTimer.AutoReset = false; - if (SwipeProfiles) - { - ChangeHotkeysStatus(true); - //hotkeysTimer.Start(); - } - startToolStripMenuItem.Text = btnStartStop.Text; cBoxNotifications.SelectedIndex = Notifications; - cBSwipeProfiles.Checked = SwipeProfiles; + //cBSwipeProfiles.Checked = SwipeProfiles; int checkwhen = CheckWhen; cBUpdate.Checked = checkwhen > 0; if (checkwhen > 23) @@ -378,7 +370,6 @@ namespace DS4Windows } } - instance = this; this.Resize += Form_Resize; this.LocationChanged += TrackLocationChanged; if (!(StartMinimized || mini)) @@ -414,6 +405,33 @@ namespace DS4Windows this.BeginInvoke((System.Action)(() => BtnStartStop_Clicked())); }); } + + Thread timerThread = new Thread(() => + { + hotkeysTimer = new NonFormTimer(); + //hotkeysTimer.Elapsed += Hotkeys; + hotkeysTimer.AutoReset = false; + if (SwipeProfiles) + { + ChangeHotkeysStatus(true); + //hotkeysTimer.Start(); + } + + autoProfilesTimer = new NonFormTimer(); + //autoProfilesTimer.Elapsed += CheckAutoProfiles; + autoProfilesTimer.Interval = 1000; + autoProfilesTimer.AutoReset = false; + + LoadP(); + + this.BeginInvoke((System.Action)(() => + { + cBSwipeProfiles.Checked = SwipeProfiles; + })); + }); + timerThread.IsBackground = true; + timerThread.Priority = ThreadPriority.Lowest; + timerThread.Start(); } private void populateHoverTextDict() @@ -529,33 +547,37 @@ namespace DS4Windows return text.ToString(); } - private static void OnPowerChange(object s, PowerModeChangedEventArgs e) + private void PowerEventArrive(object sender, EventArrivedEventArgs e) { - switch (e.Mode) + short evType = Convert.ToInt16(e.NewEvent.GetPropertyValue("EventType")); + switch (evType) { - case PowerModes.Resume: + case 7: { - if (instance.btnStartStop.Text == Properties.Resources.StartText && instance.wasrunning) + if (btnStartStop.Text == Properties.Resources.StartText && wasrunning) { DS4LightBar.shuttingdown = false; - instance.wasrunning = false; + wasrunning = false; Program.rootHub.suspending = false; - instance.BtnStartStop_Clicked(); + this.Invoke((System.Action)(() => BtnStartStop_Clicked())); } + break; } - case PowerModes.Suspend: + case 4: { - if (instance.btnStartStop.Text == Properties.Resources.StopText) + if (btnStartStop.Text == Properties.Resources.StopText) { DS4LightBar.shuttingdown = true; Program.rootHub.suspending = true; - instance.BtnStartStop_Clicked(); - instance.wasrunning = true; + this.Invoke((System.Action)(() => BtnStartStop_Clicked())); + wasrunning = true; } + break; } - default: break; + default: + break; } } @@ -1794,7 +1816,6 @@ Properties.Resources.DS4Update, MessageBoxButtons.YesNo, MessageBoxIcon.Question private void StartWindowsCheckBox_CheckedChanged(object sender, EventArgs e) { bool isChecked = StartWindowsCheckBox.Checked; - RegistryKey KeyLoc = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true); if (isChecked && !File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\DS4Windows.lnk")) { appShortcutToStartup(); @@ -1804,8 +1825,6 @@ Properties.Resources.DS4Update, MessageBoxButtons.YesNo, MessageBoxIcon.Question File.Delete(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\DS4Windows.lnk"); } - KeyLoc.DeleteValue("DS4Tool", false); - if (isChecked) { runStartupPanel.Visible = true; diff --git a/DS4Windows/DS4Library/DS4Device.cs b/DS4Windows/DS4Library/DS4Device.cs index 283e582..9cb7fa6 100644 --- a/DS4Windows/DS4Library/DS4Device.cs +++ b/DS4Windows/DS4Library/DS4Device.cs @@ -140,10 +140,6 @@ namespace DS4Windows private byte[] outReportBuffer, outputReport; private readonly DS4Touchpad touchpad = null; private readonly DS4SixAxis sixAxis = null; - private byte rightLightFastRumble; - private byte leftHeavySlowRumble; - private DS4Color ligtBarColor; - private byte ledFlashOn, ledFlashOff; private Thread ds4Input, ds4Output; private int battery; private DS4Audio audio = null; @@ -306,73 +302,44 @@ namespace DS4Windows public byte RightLightFastRumble { - get { return rightLightFastRumble; } + get { return currentHap.RumbleMotorStrengthRightLightFast; } set { - if (rightLightFastRumble != value) - rightLightFastRumble = value; + if (currentHap.RumbleMotorStrengthRightLightFast != value) + currentHap.RumbleMotorStrengthRightLightFast = value; } } public byte LeftHeavySlowRumble { - get { return leftHeavySlowRumble; } + get { return currentHap.RumbleMotorStrengthLeftHeavySlow; } set { - if (leftHeavySlowRumble != value) - leftHeavySlowRumble = value; + if (currentHap.RumbleMotorStrengthLeftHeavySlow != value) + currentHap.RumbleMotorStrengthLeftHeavySlow = value; } } public byte getLeftHeavySlowRumble() { - return leftHeavySlowRumble; + return currentHap.RumbleMotorStrengthLeftHeavySlow; } public DS4Color LightBarColor { - get { return ligtBarColor; } + get { return currentHap.LightBarColor; } set { - if (ligtBarColor.red != value.red || ligtBarColor.green != value.green || ligtBarColor.blue != value.blue) + if (currentHap.LightBarColor.red != value.red || currentHap.LightBarColor.green != value.green || currentHap.LightBarColor.blue != value.blue) { - ligtBarColor = value; - } - } - } - - public byte LightBarOnDuration - { - get { return ledFlashOn; } - set - { - if (ledFlashOn != value) - { - ledFlashOn = value; + currentHap.LightBarColor = value; } } } public byte getLightBarOnDuration() { - return ledFlashOn; - } - - public byte LightBarOffDuration - { - get { return ledFlashOff; } - set - { - if (ledFlashOff != value) - { - ledFlashOff = value; - } - } - } - - public byte getLightBarOffDuration() - { - return ledFlashOff; + return currentHap.LightBarFlashDurationOn; } // Specify the poll rate interval used for the DS4 hardware when @@ -561,7 +528,7 @@ namespace DS4Windows if (conType == ConnectionType.BT) { ds4Output = new Thread(performDs4Output); - ds4Output.Priority = ThreadPriority.AboveNormal; + ds4Output.Priority = ThreadPriority.Normal; ds4Output.Name = "DS4 Output thread: " + Mac; ds4Output.IsBackground = true; ds4Output.Start(); @@ -575,7 +542,7 @@ namespace DS4Windows else { ds4Output = new Thread(OutReportCopy); - ds4Output.Priority = ThreadPriority.AboveNormal; + ds4Output.Priority = ThreadPriority.Normal; ds4Output.Name = "DS4 Arr Copy thread: " + Mac; ds4Output.IsBackground = true; ds4Output.Start(); @@ -647,6 +614,7 @@ namespace DS4Windows } private byte outputPendCount = 0; + private readonly Stopwatch standbySw = new Stopwatch(); private unsafe void performDs4Output() { try @@ -689,7 +657,15 @@ namespace DS4Windows byteR[i] = byteB[i]; } //outReportBuffer.CopyTo(outputReport, 0); - outputPendCount--; + if (outputPendCount > 1) + outputPendCount--; + else if (outputPendCount == 1) + { + outputPendCount--; + standbySw.Restart(); + } + else + standbySw.Restart(); } currentRumble = true; @@ -774,6 +750,7 @@ namespace DS4Windows int crcpos = BT_INPUT_REPORT_CRC32_POS; int crcoffset = 0; long latencySum = 0; + standbySw.Start(); while (!exitInputThread) { @@ -893,7 +870,7 @@ namespace DS4Windows } utcNow = DateTime.UtcNow; // timestamp with UTC in case system time zone changes - resetHapticState(); + cState.PacketCounter = pState.PacketCounter + 1; cState.ReportTimeStamp = utcNow; cState.LX = inputReport[1]; @@ -1162,8 +1139,9 @@ namespace DS4Windows private unsafe void sendOutputReport(bool synchronous, bool force = false) { - setTestRumble(); - setHapticState(); + MergeStates(); + //setTestRumble(); + //setHapticState(); bool quitOutputThread = false; bool usingBT = conType == ConnectionType.BT; @@ -1178,13 +1156,13 @@ namespace DS4Windows outReportBuffer[1] = (byte)(0x80 | btPollRate); // input report rate // enable rumble (0x01), lightbar (0x02), flash (0x04) outReportBuffer[3] = 0xf7; - outReportBuffer[6] = rightLightFastRumble; // fast motor - outReportBuffer[7] = leftHeavySlowRumble; // slow motor - outReportBuffer[8] = ligtBarColor.red; // red - outReportBuffer[9] = ligtBarColor.green; // green - outReportBuffer[10] = ligtBarColor.blue; // blue - outReportBuffer[11] = ledFlashOn; // flash on duration - outReportBuffer[12] = ledFlashOff; // flash off duration + outReportBuffer[6] = currentHap.RumbleMotorStrengthRightLightFast; // fast motor + outReportBuffer[7] = currentHap.RumbleMotorStrengthLeftHeavySlow; // slow motor + outReportBuffer[8] = currentHap.LightBarColor.red; // red + outReportBuffer[9] = currentHap.LightBarColor.green; // green + outReportBuffer[10] = currentHap.LightBarColor.blue; // blue + outReportBuffer[11] = currentHap.LightBarFlashDurationOn; // flash on duration + outReportBuffer[12] = currentHap.LightBarFlashDurationOff; // flash off duration fixed (byte* byteR = outputReport, byteB = outReportBuffer) { @@ -1197,13 +1175,13 @@ namespace DS4Windows outReportBuffer[0] = 0x05; // enable rumble (0x01), lightbar (0x02), flash (0x04) outReportBuffer[1] = 0xf7; - outReportBuffer[4] = rightLightFastRumble; // fast motor - outReportBuffer[5] = leftHeavySlowRumble; // slow motor - outReportBuffer[6] = ligtBarColor.red; // red - outReportBuffer[7] = ligtBarColor.green; // green - outReportBuffer[8] = ligtBarColor.blue; // blue - outReportBuffer[9] = ledFlashOn; // flash on duration - outReportBuffer[10] = ledFlashOff; // flash off duration + outReportBuffer[4] = currentHap.RumbleMotorStrengthRightLightFast; // fast motor + outReportBuffer[5] = currentHap.RumbleMotorStrengthLeftHeavySlow; // slow motor + outReportBuffer[6] = currentHap.LightBarColor.red; // red + outReportBuffer[7] = currentHap.LightBarColor.green; // green + outReportBuffer[8] = currentHap.LightBarColor.blue; // blue + outReportBuffer[9] = currentHap.LightBarFlashDurationOn; // flash on duration + outReportBuffer[10] = currentHap.LightBarFlashDurationOff; // flash off duration fixed (byte* byteR = outputReport, byteB = outReportBuffer) { @@ -1223,10 +1201,24 @@ namespace DS4Windows if (synchronous) { - outputPendCount = 3; - - if (change) + output = output || standbySw.ElapsedMilliseconds >= 4000L; + if (output || change) { + if (change) + { + outputPendCount = 3; + standbySw.Reset(); + } + else if (outputPendCount > 1) + outputPendCount--; + else if (outputPendCount == 1) + { + outputPendCount--; + standbySw.Restart(); + } + else + standbySw.Restart(); + if (usingBT) { Monitor.Enter(outputReport); @@ -1258,11 +1250,13 @@ namespace DS4Windows //for (int i = 0, arlen = outputReport.Length; !change && i < arlen; i++) // change = outputReport[i] != outReportBuffer[i]; + output = output || standbySw.ElapsedMilliseconds >= 4000L; if (output || change) { if (change) { outputPendCount = 3; + standbySw.Reset(); } Monitor.Pulse(outReportBuffer); @@ -1398,13 +1392,15 @@ namespace DS4Windows testRumble.RumbleMotorsExplicitlyOff = rightLightFastMotor == 0 && leftHeavySlowMotor == 0; } - private void setTestRumble() + private void MergeStates() { if (testRumble.IsRumbleSet()) { - pushHapticState(ref testRumble); if (testRumble.RumbleMotorsExplicitlyOff) testRumble.RumbleMotorsExplicitlyOff = false; + + currentHap.RumbleMotorStrengthLeftHeavySlow = testRumble.RumbleMotorStrengthLeftHeavySlow; + currentHap.RumbleMotorStrengthRightLightFast = testRumble.RumbleMotorStrengthRightLightFast; } } @@ -1459,60 +1455,10 @@ namespace DS4Windows return true; } - private DS4HapticState[] hapticState = new DS4HapticState[1]; - private int hapticStackIndex = 0; - private void resetHapticState() + private DS4HapticState currentHap = new DS4HapticState(); + public void SetHapticState(ref DS4HapticState hs) { - hapticStackIndex = 0; - } - - delegate void HapticItem(ref DS4HapticState haptic); - - // Use the "most recently set" haptic state for each of light bar/motor. - private void setHapticState() - { - byte lightBarFlashDurationOn = ledFlashOn, lightBarFlashDurationOff = ledFlashOff; - byte rumbleMotorStrengthLeftHeavySlow = leftHeavySlowRumble, - rumbleMotorStrengthRightLightFast = rightLightFastRumble; - int hapticLen = hapticState.Length; - for (int i=0; i < hapticLen; i++) - { - if (i == hapticStackIndex) - break; // rest haven't been used this time - - ((HapticItem)((ref DS4HapticState haptic) => { - if (haptic.IsLightBarSet()) - { - ligtBarColor = haptic.LightBarColor; - lightBarFlashDurationOn = haptic.LightBarFlashDurationOn; - lightBarFlashDurationOff = haptic.LightBarFlashDurationOff; - } - - if (haptic.IsRumbleSet()) - { - rumbleMotorStrengthLeftHeavySlow = haptic.RumbleMotorStrengthLeftHeavySlow; - rumbleMotorStrengthRightLightFast = haptic.RumbleMotorStrengthRightLightFast; - } - }))(ref hapticState[i]); - } - - ledFlashOn = lightBarFlashDurationOn; - ledFlashOff = lightBarFlashDurationOff; - leftHeavySlowRumble = rumbleMotorStrengthLeftHeavySlow; - rightLightFastRumble = rumbleMotorStrengthRightLightFast; - } - - public void pushHapticState(ref DS4HapticState hs) - { - int hapsLen = hapticState.Length; - if (hapticStackIndex == hapsLen) - { - DS4HapticState[] newHaptics = new DS4HapticState[hapsLen + 1]; - Array.Copy(hapticState, newHaptics, hapsLen); - hapticState = newHaptics; - } - - hapticState[hapticStackIndex++] = hs; + currentHap = hs; } override diff --git a/DS4Windows/DS4Windows.csproj b/DS4Windows/DS4Windows.csproj index 1de9306..1b02371 100644 --- a/DS4Windows/DS4Windows.csproj +++ b/DS4Windows/DS4Windows.csproj @@ -123,6 +123,7 @@ + diff --git a/DS4Windows/Properties/AssemblyInfo.cs b/DS4Windows/Properties/AssemblyInfo.cs index d2ffedb..20c5e1b 100644 --- a/DS4Windows/Properties/AssemblyInfo.cs +++ b/DS4Windows/Properties/AssemblyInfo.cs @@ -33,7 +33,7 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.6.2")] -[assembly: AssemblyFileVersion("1.6.2")] +[assembly: AssemblyVersion("1.6.6")] +[assembly: AssemblyFileVersion("1.6.6")] [assembly: NeutralResourcesLanguage("en")] diff --git a/DS4Windows/Properties/Resources.Designer.cs b/DS4Windows/Properties/Resources.Designer.cs index 1d7eb76..d468473 100644 --- a/DS4Windows/Properties/Resources.Designer.cs +++ b/DS4Windows/Properties/Resources.Designer.cs @@ -1419,7 +1419,7 @@ namespace DS4Windows.Properties { } /// - /// Looks up a localized string similar to Please Download the Updater now, and place it in the programs folder, then check for update again. + /// Looks up a localized string similar to Please Download the Updater now, place it in the programs folder and rename to DS4Updater.exe if on x86, then check for update again. /// public static string PleaseDownloadUpdater { get { diff --git a/DS4Windows/Properties/Resources.resx b/DS4Windows/Properties/Resources.resx index af66c79..e284d89 100644 --- a/DS4Windows/Properties/Resources.resx +++ b/DS4Windows/Properties/Resources.resx @@ -545,7 +545,7 @@ ..\Resources\Pairmode.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - Please Download the Updater now, and place it in the programs folder, then check for update again + Please Download the Updater now, place it in the programs folder and rename to DS4Updater.exe if on x86, then check for update again Please import or make a profile diff --git a/DS4Windows/newest.txt b/DS4Windows/newest.txt index fdd3be6..ec70f75 100644 --- a/DS4Windows/newest.txt +++ b/DS4Windows/newest.txt @@ -1 +1 @@ -1.6.2 +1.6.6