public DS4Controller(DS4Device underlyingDevice) { UnderlyingController = underlyingDevice; _running = true; _monitorThread = new Thread(MonitorThread); _monitorThread.Start(); }
//returns DS4 controllers that were found and are running public static IEnumerable<DS4Device> getDS4Controllers() { lock (Devices) { DS4Device[] controllers = new DS4Device[Devices.Count]; Devices.Values.CopyTo(controllers, 0); return controllers; } }
// Called when devices is diconnected, timed out or has input reading failure public static void On_Removal(object sender, EventArgs e) { lock (Devices) { DS4Device device = (DS4Device)sender; if (device != null) { device.HidDevice.CloseDevice(); Devices.Remove(device.HidDevice.DevicePath); DevicePaths.Remove(device.HidDevice.DevicePath); deviceSerials.Remove(device.MacAddress); //purgeHiddenExclusiveDevices(); } } }
public static void RemoveDevice(DS4Device device) { if (device is null) { return; } lock (Devices) { device.HidDevice.CloseDevice(); Devices.Remove(device.HidDevice.DevicePath); DevicePaths.Remove(device.HidDevice.DevicePath); DeviceSerials.Remove(device.MacAddress); } }
public void TouchPadOn(int ind, DS4Device device) { ITouchpadBehaviour tPad = touchPad[ind]; device.Touchpad.TouchButtonDown += tPad.touchButtonDown; device.Touchpad.TouchButtonUp += tPad.touchButtonUp; device.Touchpad.TouchesBegan += tPad.touchesBegan; device.Touchpad.TouchesMoved += tPad.touchesMoved; device.Touchpad.TouchesEnded += tPad.touchesEnded; device.Touchpad.TouchUnchanged += tPad.touchUnchanged; //device.Touchpad.PreTouchProcess += delegate { touchPad[ind].populatePriorButtonStates(); }; device.Touchpad.PreTouchProcess += (sender, args) => { touchPad[ind].populatePriorButtonStates(); }; device.SixAxis.SixAccelMoved += tPad.sixaxisMoved; //LogDebug("Touchpad mode for " + device.MacAddress + " is now " + tmode.ToString()); //Log.LogToTray("Touchpad mode for " + device.MacAddress + " is now " + tmode.ToString()); }
private static void EvalHid(HidDevice hDevice) { if (IgnoreDevice(hDevice)) { return; } if (!hDevice.IsOpen) { OpenDevice(hDevice); } if (!hDevice.IsOpen) { return; } string serial = hDevice.ReadSerial(); if (DS4Device.IsValidSerial(serial)) { if (DeviceSerials.Contains(serial)) { OnSerialExists(hDevice); } else { try { VidPidInfo metainfo = KnownDevices.Single(x => x.Vid == hDevice.Attributes.VendorId && x.Pid == hDevice.Attributes.ProductId); if (metainfo != null) { OnAddSerial(hDevice, metainfo, serial); } } catch { // Single() may throw an exception } } } }
public static void UpdateSerial(object sender, EventArgs e) { lock (Devices) { DS4Device device = (DS4Device)sender; if (device != null) { string serial = device.getMacAddress(); if (Devices.ContainsKey(serial)) { Devices.Remove(serial); device.updateSerial(); serial = device.getMacAddress(); Devices.Add(serial, device); } } } }
public string getDS4MacAddress(int index) { DS4Device d = DS4Controllers[index]; if (d != null) { if (!d.IsAlive()) { return(Properties.Resources.Connecting); } return(d.getMacAddress()); } else { return(string.Empty); } }
protected void On_SerialChange(object sender, EventArgs e) { DS4Device device = (DS4Device)sender; int ind = -1; for (int i = 0, arlength = DS4_CONTROLLER_COUNT; ind == -1 && i < arlength; i++) { DS4Device tempDev = DS4Controllers[i]; if (tempDev != null && device == tempDev) { ind = i; } } if (ind >= 0) { OnDeviceSerialChange(this, ind, device.getMacAddress()); } }
public static void updateLightBar(DS4Device device, int deviceNum) { DS4Color color; if (!defaultLight && !forcelight[deviceNum]) { if (getUseCustomLed(deviceNum)) { if (getLedAsBatteryIndicator(deviceNum)) { ref DS4Color fullColor = ref getCustomColor(deviceNum); ref DS4Color lowColor = ref getLowColor(deviceNum); color = getTransitionedColor(ref lowColor, ref fullColor, device.getBattery()); } else { color = getCustomColor(deviceNum); } }
public static void stopControllers() { lock (Devices) { IEnumerable <DS4Device> devices = getDS4Controllers(); //foreach (DS4Device device in devices) for (int i = 0, devCount = devices.Count(); i < devCount; i++) { DS4Device device = devices.ElementAt(i); device.StopUpdate(); //device.runRemoval(); device.HidDevice.CloseDevice(); } Devices.Clear(); DevicePaths.Clear(); DisabledDevices.Clear(); } }
public static void UpdateLightBar(DS4Device device, int deviceNum) { DS4Color color; if (!DefaultLight && !ForceLight[deviceNum]) { if (GetUseCustomLed(deviceNum)) { if (GetLedAsBatteryIndicator(deviceNum)) { ref DS4Color fullColor = ref GetCustomColor(deviceNum); ref DS4Color lowColor = ref GetLowColor(deviceNum); color = LerpDS4Color(ref lowColor, ref fullColor, device.Battery); } else { color = GetCustomColor(deviceNum); } }
//enumerates ds4 controllers in the system public static void findControllers() { lock (Devices) { int[] pid = { 0x5C4 }; IEnumerable <HidDevice> hDevices = HidDevices.Enumerate(0x054C, pid); // Sort Bluetooth first in case USB is also connected on the same controller. hDevices = hDevices.OrderBy <HidDevice, ConnectionType>((HidDevice d) => { return(DS4Device.HidConnectionType(d)); }); foreach (HidDevice hDevice in hDevices) { if (DevicePaths.Contains(hDevice.DevicePath)) { continue; // BT/USB endpoint already open once } if (!hDevice.IsOpen) { hDevice.OpenDevice(isExclusiveMode); // TODO in exclusive mode, try to hold both open when both are connected if (isExclusiveMode && !hDevice.IsOpen) { hDevice.OpenDevice(false); } } if (hDevice.IsOpen) { if (Devices.ContainsKey(hDevice.readSerial())) { continue; // happens when the BT endpoint already is open and the USB is plugged into the same host } else { DS4Device ds4Device = new DS4Device(hDevice); ds4Device.Removal += On_Removal; Devices.Add(ds4Device.MacAddress, ds4Device); DevicePaths.Add(hDevice.DevicePath); ds4Device.StartUpdate(); } } } } }
public string getDS4MacAddress(int index) { if (DS4Controllers[index] != null) { DS4Device d = DS4Controllers[index]; if (!d.IsAlive()) //return "Connecting..."; // awaiting the first battery charge indication { var TimeoutThread = new System.Threading.Thread(() => TimeoutConnection(d)); TimeoutThread.IsBackground = true; TimeoutThread.Name = "TimeoutFor" + d.MacAddress.ToString(); TimeoutThread.Start(); return(Properties.Resources.Connecting); } return(d.MacAddress); } else { return(String.Empty); } }
private void CheckLauchProfileOption(int ind, DS4Device device) { string programPath = LaunchProgram[ind]; if (programPath != string.Empty) { System.Diagnostics.Process[] localAll = System.Diagnostics.Process.GetProcesses(); bool procFound = false; for (int procInd = 0, procsLen = localAll.Length; !procFound && procInd < procsLen; procInd++) { try { string temp = localAll[procInd].MainModule.FileName; if (temp == programPath) { procFound = true; } } // Ignore any process for which this information // is not exposed catch { } } if (!procFound) { Task processTask = new Task(() => { Thread.Sleep(5000); System.Diagnostics.Process tempProcess = new System.Diagnostics.Process(); tempProcess.StartInfo.FileName = programPath; tempProcess.StartInfo.WorkingDirectory = new FileInfo(programPath).Directory.ToString(); //tempProcess.StartInfo.UseShellExecute = false; try { tempProcess.Start(); } catch { } }); processTask.Start(); } } }
public string getDS4ControllerInfo(int index) { if (DS4Controllers[index] != null) { DS4Device d = DS4Controllers[index]; if (!d.IsAlive()) //return "Connecting..."; // awaiting the first battery charge indication { var TimeoutThread = new System.Threading.Thread(() => TimeoutConnection(d)); TimeoutThread.IsBackground = true; TimeoutThread.Name = "TimeoutFor" + d.MacAddress.ToString(); TimeoutThread.Start(); return(Properties.Resources.Connecting); } String battery; if (d.Charging) { if (d.Battery >= 100) { battery = Properties.Resources.Charged; } else { battery = Properties.Resources.Charging.Replace("*number*", d.Battery.ToString()); } } else { battery = Properties.Resources.Battery.Replace("*number*", d.Battery.ToString()); } return(d.MacAddress + " (" + d.ConnectionType + "), " + battery); //return d.MacAddress + " (" + d.ConnectionType + "), Battery is " + battery + ", Touchpad in " + modeSwitcher[index].ToString(); } else { return(String.Empty); } }
//enumerates ds4 controllers in the system public static void findControllers() { lock (Devices) { int[] pid = { 0x5C4 }; IEnumerable<HidDevice> hDevices = HidDevices.Enumerate(0x054C, pid); // Sort Bluetooth first in case USB is also connected on the same controller. hDevices = hDevices.OrderBy<HidDevice, ConnectionType>((HidDevice d) => { return DS4Device.HidConnectionType(d); }); foreach (HidDevice hDevice in hDevices) { if (DevicePaths.Contains(hDevice.DevicePath)) continue; // BT/USB endpoint already open once if (!hDevice.IsOpen) { hDevice.OpenDevice(isExclusiveMode); // TODO in exclusive mode, try to hold both open when both are connected if (isExclusiveMode && !hDevice.IsOpen) hDevice.OpenDevice(false); } if (hDevice.IsOpen) { if (Devices.ContainsKey(hDevice.readSerial())) continue; // happens when the BT endpoint already is open and the USB is plugged into the same host else { DS4Device ds4Device = new DS4Device(hDevice); ds4Device.Removal += On_Removal; Devices.Add(ds4Device.MacAddress, ds4Device); DevicePaths.Add(hDevice.DevicePath); ds4Device.StartUpdate(); } } } } }
public static void updateLightBar(DS4Device device, int deviceNum) { DS4Color color = new DS4Color(); bool useForceLight = forcelight[deviceNum]; LightbarSettingInfo lightbarSettingInfo = getLightbarSettingsInfo(deviceNum); LightbarDS4WinInfo lightModeInfo = lightbarSettingInfo.ds4winSettings; bool useLightRoutine = lightbarSettingInfo.mode == LightbarMode.DS4Win; //bool useLightRoutine = false; if (!defaultLight && !useForceLight && useLightRoutine) { if (lightModeInfo.useCustomLed) { if (lightModeInfo.ledAsBattery) { ref DS4Color fullColor = ref lightModeInfo.m_CustomLed; // ref getCustomColor(deviceNum); ref DS4Color lowColor = ref lightModeInfo.m_LowLed; //ref getLowColor(deviceNum); color = getTransitionedColor(ref lowColor, ref fullColor, device.getBattery()); } else { color = lightModeInfo.m_CustomLed; //getCustomColor(deviceNum); } }
public static void UpdateSerial(object sender, EventArgs e) { lock (Devices) { DS4Device device = (DS4Device)sender; if (device != null) { string devPath = device.HidDevice.DevicePath; string serial = device.getMacAddress(); if (Devices.ContainsKey(devPath)) { deviceSerials.Remove(serial); device.updateSerial(); serial = device.getMacAddress(); if (DS4Device.isValidSerial(serial)) { deviceSerials.Add(serial); } device.refreshCalibration(); } } } }
public string getDS4ControllerInfo(int index) { DS4Device d = DS4Controllers[index]; if (d != null) { if (!d.IsAlive()) { return(Properties.Resources.Connecting); } string battery; if (d.isCharging()) { if (d.getBattery() >= 100) { battery = Properties.Resources.Charged; } else { battery = Properties.Resources.Charging.Replace("*number*", d.getBattery().ToString()); } } else { battery = Properties.Resources.Battery.Replace("*number*", d.getBattery().ToString()); } return(d.getMacAddress() + " (" + d.getConnectionType() + "), " + battery); //return d.MacAddress + " (" + d.ConnectionType + "), Battery is " + battery + ", Touchpad in " + modeSwitcher[index].ToString(); } else { return(string.Empty); } }
// Called every time a new input report has arrived protected virtual void On_Report(object sender, EventArgs e) { DS4Device device = (DS4Device)sender; int ind = -1; for (int i = 0, arlength = DS4_CONTROLLER_COUNT; ind == -1 && i < arlength; i++) { DS4Device tempDev = DS4Controllers[i]; if (tempDev != null && device == tempDev) { ind = i; } } if (ind != -1) { if (getFlushHIDQueue(ind)) { device.FlushHID(); } string devError = tempStrings[ind] = device.error; if (!string.IsNullOrEmpty(devError)) { device.getUiContext()?.Post(new SendOrPostCallback(delegate(object state) { LogDebug(devError); }), null); } if (inWarnMonitor[ind]) { int flashWhenLateAt = getFlashWhenLateAt(); if (!lag[ind] && device.Latency >= flashWhenLateAt) { lag[ind] = true; device.getUiContext()?.Post(new SendOrPostCallback(delegate(object state) { LagFlashWarning(ind, true); }), null); } else if (lag[ind] && device.Latency < flashWhenLateAt) { lag[ind] = false; device.getUiContext()?.Post(new SendOrPostCallback(delegate(object state) { LagFlashWarning(ind, false); }), null); } } else { if (DateTime.UtcNow - device.firstActive > TimeSpan.FromSeconds(5)) { inWarnMonitor[ind] = true; } } device.getCurrentState(CurrentState[ind]); DS4State cState = CurrentState[ind]; DS4State pState = device.getPreviousStateRef(); //device.getPreviousState(PreviousState[ind]); //DS4State pState = PreviousState[ind]; if (!device.firstReport && device.IsAlive()) { device.firstReport = true; device.getUiContext()?.Post(new SendOrPostCallback(delegate(object state) { OnDeviceStatusChanged(this, ind); }), null); } else if (pState.Battery != cState.Battery || device.oldCharging != device.isCharging()) { byte tempBattery = currentBattery[ind] = cState.Battery; bool tempCharging = charging[ind] = device.isCharging(); device.getUiContext()?.Post(new SendOrPostCallback(delegate(object state) { OnBatteryStatusChange(this, ind, tempBattery, tempCharging); }), null); } if (getEnableTouchToggle(ind)) { CheckForTouchToggle(ind, cState, pState); } cState = Mapping.SetCurveAndDeadzone(ind, cState); if (!recordingMacro && (!string.IsNullOrEmpty(tempprofilename[ind]) || containsCustomAction(ind) || containsCustomExtras(ind) || getProfileActionCount(ind) > 0)) { Mapping.MapCustom(ind, cState, MappedState[ind], ExposedState[ind], touchPad[ind], this); cState = MappedState[ind]; } if (!useDInputOnly[ind]) { x360Bus.Parse(cState, processingData[ind].Report, ind); // We push the translated Xinput state, and simultaneously we // pull back any possible rumble data coming from Xinput consumers. if (x360Bus.Report(processingData[ind].Report, processingData[ind].Rumble)) { byte Big = processingData[ind].Rumble[3]; byte Small = processingData[ind].Rumble[4]; if (processingData[ind].Rumble[1] == 0x08) { setRumble(Big, Small, ind); } } } if (_udpServer != null) { _udpServer.NewReportIncoming(GetPadDetailForIdx(ind), CurrentState[ind]); } // Output any synthetic events. Mapping.Commit(ind); // Update the GUI/whatever. DS4LightBar.updateLightBar(device, ind, cState, ExposedState[ind], touchPad[ind]); } }
//Called when DS4 is disconnected or timed out protected virtual void On_DS4Removal(object sender, EventArgs e) { DS4Device device = (DS4Device)sender; int ind = -1; for (int i = 0, arlength = DS4Controllers.Length; ind == -1 && i < arlength; i++) { if (DS4Controllers[i] != null && device.getMacAddress() == DS4Controllers[i].getMacAddress()) { ind = i; } } if (ind != -1) { bool removingStatus = false; lock (device.removeLocker) { if (!device.IsRemoving) { removingStatus = true; device.IsRemoving = true; } } if (removingStatus) { CurrentState[ind].Battery = PreviousState[ind].Battery = 0; // Reset for the next connection's initial status change. if (!useDInputOnly[ind]) { bool unplugResult = x360Bus.Unplug(ind); int xinputIndex = x360Bus.FirstController + ind; if (unplugResult) { LogDebug("X360 Controller # " + xinputIndex + " unplugged"); } else { LogDebug("X360 Controller # " + xinputIndex + " failed to unplug"); } } string removed = Properties.Resources.ControllerWasRemoved.Replace("*Mac address*", (ind + 1).ToString()); if (device.getBattery() <= 20 && device.getConnectionType() == ConnectionType.BT && !device.isCharging()) { removed += ". " + Properties.Resources.ChargeController; } LogDebug(removed); Log.LogToTray(removed); /*Stopwatch sw = new Stopwatch(); * sw.Start(); * while (sw.ElapsedMilliseconds < XINPUT_UNPLUG_SETTLE_TIME) * { * // Use SpinWait to keep control of current thread. Using Sleep could potentially * // cause other events to get run out of order * System.Threading.Thread.SpinWait(500); * } * sw.Stop(); */ device.IsRemoved = true; device.Synced = false; DS4Controllers[ind] = null; touchPad[ind] = null; lag[ind] = false; inWarnMonitor[ind] = false; useDInputOnly[ind] = true; System.Threading.Thread.Sleep(XINPUT_UNPLUG_SETTLE_TIME); OnControllerRemoved(this, ind); } } }
// Trigger sensitivity public void ControllerThread() { while (true) { if (Controller != null) { if (Controller.IsDisconnecting) { Controller = null; IsConnected = false; ControllerDisconnected(); continue; } Thread.Sleep(5); continue; } DS4Devices.findControllers(); var Controllers = DS4Devices.getDS4Controllers(); if (Controllers.Count() > 0) { Controller = Controllers.First(); IsConnected = true; if (Controller != null) { try { ControllerConnected(); } catch { } Controller.Touchpad.TouchesMoved += Touchpad_TouchesMoved; } } Thread.Sleep(5); } }
private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { controllerThread.Abort(); stateThread.Abort(); // Disconnect controller and abort thread if (Controller != null) { Controller.pushHapticState(new DS4HapticState() { LightBarExplicitlyOff = true, RumbleMotorsExplicitlyOff = true }); LightBarOff(); Controller.StopUpdate(); if (Controller.ConnectionType == ConnectionType.BT) Controller.DisconnectBT(); Controller = null; } } disposedValue = true; } }
public bool HotPlug(SynchronizationContext uiContext) { if (running) { DS4Devices.findControllers(); IEnumerable <DS4Device> devices = DS4Devices.getDS4Controllers(); //foreach (DS4Device device in devices) for (int i = 0, devlen = devices.Count(); i < devlen; i++) { DS4Device device = devices.ElementAt(i); if (device.isDisconnectingStatus()) { continue; } if (((Func <bool>) delegate { for (Int32 Index = 0, arlength = DS4Controllers.Length; Index < arlength; Index++) { if (DS4Controllers[Index] != null && DS4Controllers[Index].getMacAddress() == device.getMacAddress()) { return(true); } } return(false); })()) { continue; } for (Int32 Index = 0, arlength = DS4Controllers.Length; Index < arlength; Index++) { if (DS4Controllers[Index] == null) { LogDebug(Properties.Resources.FoundController + device.getMacAddress() + " (" + device.getConnectionType() + ")"); Task task = new Task(() => { Thread.Sleep(5); WarnExclusiveModeFailure(device); }); task.Start(); DS4Controllers[Index] = device; device.setUiContext(uiContext); device.Removal += this.On_DS4Removal; device.Removal += DS4Devices.On_Removal; device.SyncChange += this.On_SyncChange; device.SyncChange += DS4Devices.UpdateSerial; device.SerialChange += this.On_SerialChange; touchPad[Index] = new Mouse(Index, device); device.LightBarColor = getMainColor(Index); device.Report += this.On_Report; if (!getDInputOnly(Index) && device.isSynced()) { int xinputIndex = x360Bus.FirstController + Index; LogDebug("Plugging in X360 Controller #" + xinputIndex); bool xinputResult = x360Bus.Plugin(Index); if (xinputResult) { LogDebug("X360 Controller # " + xinputIndex + " connected"); useDInputOnly[Index] = false; } else { LogDebug("X360 Controller # " + xinputIndex + " failed. Using DInput only mode"); useDInputOnly[Index] = true; } } TouchPadOn(Index, device); CheckProfileOptions(Index, device); device.StartUpdate(); //string filename = Path.GetFileName(ProfilePath[Index]); if (File.Exists(appdatapath + "\\Profiles\\" + ProfilePath[Index] + ".xml")) { string prolog = Properties.Resources.UsingProfile.Replace("*number*", (Index + 1).ToString()).Replace("*Profile name*", ProfilePath[Index]); LogDebug(prolog); Log.LogToTray(prolog); } else { string prolog = Properties.Resources.NotUsingProfile.Replace("*number*", (Index + 1).ToString()); LogDebug(prolog); Log.LogToTray(prolog); } break; } } } } return(true); }
// Enumerates ds4 controllers in the system public static void findControllers() { lock (Devices) { int[] pid = { 0xBA0, 0x5C4, 0x09CC }; IEnumerable <HidDevice> hDevices = HidDevices.Enumerate(0x054C, pid); // Sort Bluetooth first in case USB is also connected on the same controller. hDevices = hDevices.OrderBy <HidDevice, ConnectionType>((HidDevice d) => { return(DS4Device.HidConnectionType(d)); }); List <HidDevice> tempList = hDevices.ToList(); purgeHiddenExclusiveDevices(); tempList.AddRange(DisabledDevices); int devCount = tempList.Count(); string devicePlural = "device" + (devCount == 0 || devCount > 1 ? "s" : ""); //Log.LogToGui("Found " + devCount + " possible " + devicePlural + ". Examining " + devicePlural + ".", false); for (int i = 0; i < devCount; i++) //foreach (HidDevice hDevice in hDevices) { HidDevice hDevice = tempList[i]; if (DevicePaths.Contains(hDevice.DevicePath)) { continue; // BT/USB endpoint already open once } if (!hDevice.IsOpen) { hDevice.OpenDevice(isExclusiveMode); if (!hDevice.IsOpen && isExclusiveMode) { try { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); bool elevated = principal.IsInRole(WindowsBuiltInRole.Administrator); if (!elevated) { // Launches an elevated child process to re-enable device string exeName = Process.GetCurrentProcess().MainModule.FileName; ProcessStartInfo startInfo = new ProcessStartInfo(exeName); startInfo.Verb = "runas"; startInfo.Arguments = "re-enabledevice " + devicePathToInstanceId(hDevice.DevicePath); Process child = Process.Start(startInfo); if (!child.WaitForExit(5000)) { child.Kill(); } else if (child.ExitCode == 0) { hDevice.OpenDevice(isExclusiveMode); } } else { reEnableDevice(devicePathToInstanceId(hDevice.DevicePath)); hDevice.OpenDevice(isExclusiveMode); } } catch (Exception) { } } // TODO in exclusive mode, try to hold both open when both are connected if (isExclusiveMode && !hDevice.IsOpen) { hDevice.OpenDevice(false); } } if (hDevice.IsOpen) { string serial = hDevice.readSerial(); bool validSerial = !serial.Equals(DS4Device.blankSerial); if (Devices.ContainsKey(serial)) { // happens when the BT endpoint already is open and the USB is plugged into the same host if (isExclusiveMode && hDevice.IsExclusive && !DisabledDevices.Contains(hDevice)) { // Grab reference to exclusively opened HidDevice so device // stays hidden to other processes DisabledDevices.Add(hDevice); //DevicePaths.Add(hDevice.DevicePath); } continue; } else { DS4Device ds4Device = new DS4Device(hDevice); //ds4Device.Removal += On_Removal; Devices.Add(ds4Device.MacAddress, ds4Device); DevicePaths.Add(hDevice.DevicePath); LoadLinkedProfile(i, ds4Device.MacAddress); } } } } }
public bool Start(object tempui, bool showlog = true) { if (x360Bus.Open() && x360Bus.Start()) { if (showlog) { LogDebug(Properties.Resources.Starting); } LogDebug("Connection to Scp Virtual Bus established"); DS4Devices.isExclusiveMode = getUseExclusiveMode(); if (showlog) { LogDebug(Properties.Resources.SearchingController); LogDebug(DS4Devices.isExclusiveMode ? Properties.Resources.UsingExclusive : Properties.Resources.UsingShared); } try { DS4Devices.findControllers(); IEnumerable <DS4Device> devices = DS4Devices.getDS4Controllers(); //int ind = 0; DS4LightBar.defaultLight = false; //foreach (DS4Device device in devices) for (int i = 0, devCount = devices.Count(); i < devCount; i++) { DS4Device device = devices.ElementAt(i); if (showlog) { LogDebug(Properties.Resources.FoundController + device.getMacAddress() + " (" + device.getConnectionType() + ")"); } Task task = new Task(() => { Thread.Sleep(5); WarnExclusiveModeFailure(device); }); task.Start(); DS4Controllers[i] = device; device.setUiContext(tempui as SynchronizationContext); device.Removal += this.On_DS4Removal; device.Removal += DS4Devices.On_Removal; device.SyncChange += this.On_SyncChange; device.SyncChange += DS4Devices.UpdateSerial; device.SerialChange += this.On_SerialChange; touchPad[i] = new Mouse(i, device); device.LightBarColor = getMainColor(i); if (!getDInputOnly(i) && device.isSynced()) { int xinputIndex = x360Bus.FirstController + i; LogDebug("Plugging in X360 Controller #" + xinputIndex); bool xinputResult = x360Bus.Plugin(i); if (xinputResult) { LogDebug("X360 Controller # " + xinputIndex + " connected"); useDInputOnly[i] = false; } else { LogDebug("X360 Controller # " + xinputIndex + " failed. Using DInput only mode"); useDInputOnly[i] = true; } } device.Report += this.On_Report; TouchPadOn(i, device); CheckProfileOptions(i, device, true); device.StartUpdate(); //string filename = ProfilePath[ind]; //ind++; if (showlog) { if (File.Exists(appdatapath + "\\Profiles\\" + ProfilePath[i] + ".xml")) { string prolog = Properties.Resources.UsingProfile.Replace("*number*", (i + 1).ToString()).Replace("*Profile name*", ProfilePath[i]); LogDebug(prolog); Log.LogToTray(prolog); } else { string prolog = Properties.Resources.NotUsingProfile.Replace("*number*", (i + 1).ToString()); LogDebug(prolog); Log.LogToTray(prolog); } } if (i >= 4) // out of Xinput devices! { break; } } } catch (Exception e) { LogDebug(e.Message); Log.LogToTray(e.Message); } running = true; if (_udpServer != null) { var UDP_SERVER_PORT = 26760; try { _udpServer.Start(UDP_SERVER_PORT); LogDebug("UDP server listening on port " + UDP_SERVER_PORT); } catch (System.Net.Sockets.SocketException ex) { var errMsg = String.Format("Couldn't start UDP server on port {0}, outside applications won't be able to access pad data ({1})", UDP_SERVER_PORT, ex.SocketErrorCode); LogDebug(errMsg, true); Log.LogToTray(errMsg, true, true); } } } else { string logMessage = "Could not connect to Scp Virtual Bus Driver. Please check the status of the System device in Device Manager"; LogDebug(logMessage); Log.LogToTray(logMessage); } runHotPlug = true; return(true); }
public bool Stop(bool showlog = true) { if (running) { running = false; runHotPlug = false; if (showlog) { LogDebug(Properties.Resources.StoppingX360); } bool anyUnplugged = false; for (int i = 0, arlength = DS4Controllers.Length; i < arlength; i++) { DS4Device tempDevice = DS4Controllers[i]; if (tempDevice != null) { if (DCBTatStop && !tempDevice.isCharging()) { if (tempDevice.getConnectionType() == ConnectionType.BT) { tempDevice.StopUpdate(); tempDevice.DisconnectBT(true); } else if (tempDevice.getConnectionType() == ConnectionType.SONYWA) { tempDevice.StopUpdate(); tempDevice.DisconnectDongle(true); } } else { DS4LightBar.forcelight[i] = false; DS4LightBar.forcedFlash[i] = 0; DS4LightBar.defaultLight = true; DS4LightBar.updateLightBar(DS4Controllers[i], i, CurrentState[i], ExposedState[i], touchPad[i]); tempDevice.IsRemoved = true; Thread.Sleep(50); } CurrentState[i].Battery = PreviousState[i].Battery = 0; // Reset for the next connection's initial status change. x360Bus.Unplug(i); useDInputOnly[i] = true; anyUnplugged = true; DS4Controllers[i] = null; touchPad[i] = null; lag[i] = false; inWarnMonitor[i] = false; } } if (anyUnplugged) { Thread.Sleep(XINPUT_UNPLUG_SETTLE_TIME); } x360Bus.UnplugAll(); x360Bus.Stop(); if (showlog) { LogDebug(Properties.Resources.StoppingDS4); } DS4Devices.stopControllers(); if (_udpServer != null) { _udpServer.Stop(); } if (showlog) { LogDebug(Properties.Resources.StoppedDS4Windows); } } runHotPlug = false; return(true); }
// Called when devices is diconnected, timed out or has input reading failure public static void On_Removal(object sender, EventArgs e) { DS4Device device = (DS4Device)sender; RemoveDevice(device); }
// Enumerates ds4 controllers in the system public static void findControllers() { lock (Devices) { IEnumerable <HidDevice> hDevices = HidDevices.EnumerateDS4(knownDevices); hDevices = hDevices.Where(dev => IsRealDS4(dev)).Select(dev => dev); //hDevices = from dev in hDevices where IsRealDS4(dev) select dev; // Sort Bluetooth first in case USB is also connected on the same controller. hDevices = hDevices.OrderBy <HidDevice, ConnectionType>((HidDevice d) => { return(DS4Device.HidConnectionType(d)); }); List <HidDevice> tempList = hDevices.ToList(); purgeHiddenExclusiveDevices(); tempList.AddRange(DisabledDevices); int devCount = tempList.Count(); string devicePlural = "device" + (devCount == 0 || devCount > 1 ? "s" : ""); //Log.LogToGui("Found " + devCount + " possible " + devicePlural + ". Examining " + devicePlural + ".", false); for (int i = 0; i < devCount; i++) //foreach (HidDevice hDevice in hDevices) { HidDevice hDevice = tempList[i]; if (hDevice.Description == "HID-compliant vendor-defined device") { continue; // ignore the Nacon Revolution Pro programming interface } else if (DevicePaths.Contains(hDevice.DevicePath)) { continue; // BT/USB endpoint already open once } VidPidInfo metainfo = knownDevices.Single(x => x.vid == hDevice.Attributes.VendorId && x.pid == hDevice.Attributes.ProductId); if (!hDevice.IsOpen) { hDevice.OpenDevice(isExclusiveMode); if (!hDevice.IsOpen && isExclusiveMode) { try { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); bool elevated = principal.IsInRole(WindowsBuiltInRole.Administrator); if (!elevated) { // Launches an elevated child process to re-enable device string exeName = Process.GetCurrentProcess().MainModule.FileName; ProcessStartInfo startInfo = new ProcessStartInfo(exeName); startInfo.Verb = "runas"; startInfo.Arguments = "re-enabledevice " + devicePathToInstanceId(hDevice.DevicePath); Process child = Process.Start(startInfo); if (!child.WaitForExit(30000)) { child.Kill(); } else if (child.ExitCode == 0) { hDevice.OpenDevice(isExclusiveMode); } } else { reEnableDevice(devicePathToInstanceId(hDevice.DevicePath)); hDevice.OpenDevice(isExclusiveMode); } } catch (Exception) { } } // TODO in exclusive mode, try to hold both open when both are connected if (isExclusiveMode && !hDevice.IsOpen) { hDevice.OpenDevice(false); } } if (hDevice.IsOpen) { string serial = hDevice.readSerial(); bool validSerial = !serial.Equals(DS4Device.blankSerial); if (validSerial && deviceSerials.Contains(serial)) { // happens when the BT endpoint already is open and the USB is plugged into the same host if (isExclusiveMode && hDevice.IsExclusive && !DisabledDevices.Contains(hDevice)) { // Grab reference to exclusively opened HidDevice so device // stays hidden to other processes DisabledDevices.Add(hDevice); //DevicePaths.Add(hDevice.DevicePath); } continue; } else { DS4Device ds4Device = new DS4Device(hDevice, metainfo.name); //ds4Device.Removal += On_Removal; if (!ds4Device.ExitOutputThread) { Devices.Add(hDevice.DevicePath, ds4Device); DevicePaths.Add(hDevice.DevicePath); deviceSerials.Add(serial); } } } } } }
//enumerates ds4 controllers in the system public static void findControllers() { lock (Devices) { int[] pid = { 0xBA0, 0x5C4, 0x09CC }; IEnumerable <HidDevice> hDevices = HidDevices.Enumerate(0x054C, pid); // Sort Bluetooth first in case USB is also connected on the same controller. hDevices = hDevices.OrderBy <HidDevice, ConnectionType>((HidDevice d) => { return(DS4Device.HidConnectionType(d)); }); foreach (HidDevice hDevice in hDevices) { if (DevicePaths.Contains(hDevice.DevicePath)) { continue; // BT/USB endpoint already open once } if (!hDevice.IsOpen) { hDevice.OpenDevice(isExclusiveMode); if (!hDevice.IsOpen && isExclusiveMode) { try { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); bool elevated = principal.IsInRole(WindowsBuiltInRole.Administrator); if (!elevated) { // Launches an elevated child process to re-enable device string exeName = Process.GetCurrentProcess().MainModule.FileName; ProcessStartInfo startInfo = new ProcessStartInfo(exeName); startInfo.Verb = "runas"; startInfo.Arguments = "re-enabledevice " + devicePathToInstanceId(hDevice.DevicePath); Process child = Process.Start(startInfo); if (!child.WaitForExit(5000)) { child.Kill(); } else if (child.ExitCode == 0) { hDevice.OpenDevice(isExclusiveMode); } } else { reEnableDevice(devicePathToInstanceId(hDevice.DevicePath)); hDevice.OpenDevice(isExclusiveMode); } } catch (Exception) { } } // TODO in exclusive mode, try to hold both open when both are connected if (isExclusiveMode && !hDevice.IsOpen) { hDevice.OpenDevice(false); } } if (hDevice.IsOpen) { if (Devices.ContainsKey(hDevice.readSerial())) { continue; // happens when the BT endpoint already is open and the USB is plugged into the same host } else { DS4Device ds4Device = new DS4Device(hDevice); ds4Device.Removal += On_Removal; Devices.Add(ds4Device.MacAddress, ds4Device); DevicePaths.Add(hDevice.DevicePath); ds4Device.StartUpdate(); } } } } }
//Called every time the new input report has arrived protected virtual void On_Report(object sender, EventArgs e) { DS4Device device = (DS4Device)sender; int ind = -1; for (int i = 0; i < DS4Controllers.Length; i++) { if (device == DS4Controllers[i]) { ind = i; } } if (ind != -1) { if (FlushHIDQueue[ind]) { device.FlushHID(); } if (!string.IsNullOrEmpty(device.error)) { LogDebug(device.error); } if (DateTime.UtcNow - device.firstActive > TimeSpan.FromSeconds(5)) { if (device.Latency >= FlashWhenLateAt && !lag[ind]) { LagFlashWarning(ind, true); } else if (device.Latency < FlashWhenLateAt && lag[ind]) { LagFlashWarning(ind, false); } } device.getExposedState(ExposedState[ind], CurrentState[ind]); DS4State cState = CurrentState[ind]; device.getPreviousState(PreviousState[ind]); DS4State pState = PreviousState[ind]; if (pState.Battery != cState.Battery) { ControllerStatusChanged(this); } CheckForHotkeys(ind, cState, pState); if (eastertime) { EasterTime(ind); } GetInputkeys(ind); if (LSCurve[ind] != 0 || RSCurve[ind] != 0 || LSDeadzone[ind] != 0 || RSDeadzone[ind] != 0 || L2Deadzone[ind] != 0 || R2Deadzone[ind] != 0 || LSSens[ind] != 0 || RSSens[ind] != 0 || L2Sens[ind] != 0 || R2Sens[ind] != 0) //if a curve or deadzone is in place { cState = Mapping.SetCurveAndDeadzone(ind, cState); } if (!recordingMacro && (!string.IsNullOrEmpty(tempprofilename[ind]) || HasCustomAction(ind) || HasCustomExtras(ind) || ProfileActions[ind].Count > 0)) { Mapping.MapCustom(ind, cState, MappedState[ind], ExposedState[ind], touchPad[ind], this); cState = MappedState[ind]; } //if (HasCustomExtras(ind)) // DoExtras(ind); // Update the GUI/whatever. DS4LightBar.updateLightBar(device, ind, cState, ExposedState[ind], touchPad[ind]); x360Bus.Parse(cState, processingData[ind].Report, ind); // We push the translated Xinput state, and simultaneously we // pull back any possible rumble data coming from Xinput consumers. if (x360Bus.Report(processingData[ind].Report, processingData[ind].Rumble)) { Byte Big = (Byte)(processingData[ind].Rumble[3]); Byte Small = (Byte)(processingData[ind].Rumble[4]); if (processingData[ind].Rumble[1] == 0x08) { setRumble(Big, Small, ind); } } // Output any synthetic events. Mapping.Commit(ind); // Pull settings updates. device.IdleTimeout = IdleDisconnectTimeout[ind]; } }
public static void updateLightBar(DS4Device device, int deviceNum) { DS4Color color; if (!defaultLight && !forcelight[deviceNum]) { if (getUseCustomLed(deviceNum)) { if (getLedAsBatteryIndicator(deviceNum)) { DS4Color fullColor = getCustomColor(deviceNum); DS4Color lowColor = getLowColor(deviceNum); color = getTransitionedColor(lowColor, fullColor, device.getBattery()); } else { color = getCustomColor(deviceNum); } } else { double rainbow = getRainbow(deviceNum); if (rainbow > 0) { // Display rainbow DateTime now = DateTime.UtcNow; if (now >= oldnow[deviceNum] + TimeSpan.FromMilliseconds(10)) //update by the millisecond that way it's a smooth transtion { oldnow[deviceNum] = now; if (device.isCharging()) { counters[deviceNum] -= 1.5 * 3 / rainbow; } else { counters[deviceNum] += 1.5 * 3 / rainbow; } } if (counters[deviceNum] < 0) { counters[deviceNum] = 180000; } else if (counters[deviceNum] > 180000) { counters[deviceNum] = 0; } if (getLedAsBatteryIndicator(deviceNum)) { color = HuetoRGB((float)counters[deviceNum] % 360, (byte)(device.getBattery() * 2.55)); } else { color = HuetoRGB((float)counters[deviceNum] % 360, 255); } } else if (getLedAsBatteryIndicator(deviceNum)) { DS4Color fullColor = getMainColor(deviceNum); DS4Color lowColor = getLowColor(deviceNum); color = getTransitionedColor(lowColor, fullColor, device.getBattery()); } else { color = getMainColor(deviceNum); } } if (device.getBattery() <= getFlashAt(deviceNum) && !defaultLight && !device.isCharging()) { DS4Color flashColor = getFlashColor(deviceNum); if (!(flashColor.red == 0 && flashColor.green == 0 && flashColor.blue == 0)) { color = flashColor; } if (getFlashType(deviceNum) == 1) { double ratio = 0.0; if (!fadewatches[deviceNum].IsRunning) { bool temp = fadedirection[deviceNum]; fadedirection[deviceNum] = !temp; fadewatches[deviceNum].Restart(); ratio = temp ? 100.0 : 0.0; } else { long elapsed = fadewatches[deviceNum].ElapsedMilliseconds; if (fadedirection[deviceNum]) { if (elapsed < PULSE_FLASH_DURATION) { elapsed = elapsed / 40; ratio = 100.0 * (elapsed / PULSE_FLASH_SEGMENTS); } else { ratio = 100.0; fadewatches[deviceNum].Stop(); } } else { if (elapsed < PULSE_FLASH_DURATION) { elapsed = elapsed / 40; ratio = (0 - 100.0) * (elapsed / PULSE_FLASH_SEGMENTS) + 100.0; } else { ratio = 0.0; fadewatches[deviceNum].Stop(); } } } color = getTransitionedColor(color, new DS4Color(0, 0, 0), ratio); } } int idleDisconnectTimeout = getIdleDisconnectTimeout(deviceNum); if (idleDisconnectTimeout > 0 && getLedAsBatteryIndicator(deviceNum) && (!device.isCharging() || device.getBattery() >= 100)) { //Fade lightbar by idle time TimeSpan timeratio = new TimeSpan(DateTime.UtcNow.Ticks - device.lastActive.Ticks); double botratio = timeratio.TotalMilliseconds; double topratio = TimeSpan.FromSeconds(idleDisconnectTimeout).TotalMilliseconds; double ratio = 100.0 * (botratio / topratio), elapsed = ratio; if (ratio >= 50.0 && ratio < 100.0) { color = getTransitionedColor(color, new DS4Color(0, 0, 0), (uint)(-100.0 * (elapsed = 0.02 * (ratio - 50.0)) * (elapsed - 2.0))); } else if (ratio >= 100.0) { color = getTransitionedColor(color, new DS4Color(0, 0, 0), 100.0); } } if (device.isCharging() && device.getBattery() < 100) { switch (getChargingType(deviceNum)) { case 1: { double ratio = 0.0; if (!fadewatches[deviceNum].IsRunning) { bool temp = fadedirection[deviceNum]; fadedirection[deviceNum] = !temp; fadewatches[deviceNum].Restart(); ratio = temp ? 100.0 : 0.0; } else { long elapsed = fadewatches[deviceNum].ElapsedMilliseconds; if (fadedirection[deviceNum]) { if (elapsed < PULSE_CHARGING_DURATION) { elapsed = elapsed / 40; ratio = 100.0 * (elapsed / PULSE_CHARGING_SEGMENTS); } else { ratio = 100.0; fadewatches[deviceNum].Stop(); } } else { if (elapsed < PULSE_CHARGING_DURATION) { elapsed = elapsed / 40; ratio = (0 - 100.0) * (elapsed / PULSE_CHARGING_SEGMENTS) + 100.0; } else { ratio = 0.0; fadewatches[deviceNum].Stop(); } } } color = getTransitionedColor(color, new DS4Color(0, 0, 0), ratio); break; } case 2: { counters[deviceNum] += 0.167; color = HuetoRGB((float)counters[deviceNum] % 360, 255); break; } case 3: { color = getChargingColor(deviceNum); break; } default: break; } } } else if (forcelight[deviceNum]) { color = forcedColor[deviceNum]; } else if (shuttingdown) { color = new DS4Color(0, 0, 0); } else { if (device.getConnectionType() == ConnectionType.BT) { color = new DS4Color(32, 64, 64); } else { color = new DS4Color(0, 0, 0); } } bool distanceprofile = DistanceProfiles[deviceNum] || tempprofileDistance[deviceNum]; //distanceprofile = (ProfilePath[deviceNum].ToLower().Contains("distance") || tempprofilename[deviceNum].ToLower().Contains("distance")); if (distanceprofile && !defaultLight) { // Thing I did for Distance float rumble = device.getLeftHeavySlowRumble() / 2.55f; byte max = Max(color.red, Max(color.green, color.blue)); if (device.getLeftHeavySlowRumble() > 100) { color = getTransitionedColor(new DS4Color(max, max, 0), new DS4Color(255, 0, 0), rumble); } else { color = getTransitionedColor(color, getTransitionedColor(new DS4Color(max, max, 0), new DS4Color(255, 0, 0), 39.6078f), device.getLeftHeavySlowRumble()); } } DS4HapticState haptics = new DS4HapticState { LightBarColor = color }; if (haptics.IsLightBarSet()) { if (forcelight[deviceNum] && forcedFlash[deviceNum] > 0) { haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = (byte)(25 - forcedFlash[deviceNum]); haptics.LightBarExplicitlyOff = true; } else if (device.getBattery() <= getFlashAt(deviceNum) && getFlashType(deviceNum) == 0 && !defaultLight && !device.isCharging()) { int level = device.getBattery() / 10; if (level >= 10) { level = 0; // all values of ~0% or >~100% are rendered the same } haptics.LightBarFlashDurationOn = BatteryIndicatorDurations[level, 0]; haptics.LightBarFlashDurationOff = BatteryIndicatorDurations[level, 1]; } else if (distanceprofile && device.getLeftHeavySlowRumble() > 155) //also part of Distance { haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = (byte)((-device.getLeftHeavySlowRumble() + 265)); haptics.LightBarExplicitlyOff = true; } else { //haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = 1; haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = 0; haptics.LightBarExplicitlyOff = true; } } else { haptics.LightBarExplicitlyOff = true; } byte tempLightBarOnDuration = device.getLightBarOnDuration(); if (tempLightBarOnDuration != haptics.LightBarFlashDurationOn && tempLightBarOnDuration != 1 && haptics.LightBarFlashDurationOn == 0) { haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = 1; } device.pushHapticState(ref haptics); }
public static void updateLightBar(DS4Device device, int deviceNum, DS4State cState, DS4StateExposed eState, Mouse tp) { DS4Color color; if (!defualtLight && !forcelight[deviceNum]) { if (UseCustomLed[deviceNum]) { if (LedAsBatteryIndicator[deviceNum]) { DS4Color fullColor = CustomColor[deviceNum]; DS4Color lowColor = LowColor[deviceNum]; color = getTransitionedColor(lowColor, fullColor, device.Battery); } else { color = CustomColor[deviceNum]; } } else { if (Rainbow[deviceNum] > 0) { // Display rainbow DateTime now = DateTime.UtcNow; if (now >= oldnow + TimeSpan.FromMilliseconds(10)) //update by the millisecond that way it's a smooth transtion { oldnow = now; if (device.Charging) { counters[deviceNum] -= 1.5 * 3 / Rainbow[deviceNum]; } else { counters[deviceNum] += 1.5 * 3 / Rainbow[deviceNum]; } } if (counters[deviceNum] < 0) { counters[deviceNum] = 180000; } if (counters[deviceNum] > 180000) { counters[deviceNum] = 0; } if (LedAsBatteryIndicator[deviceNum]) { color = HuetoRGB((float)counters[deviceNum] % 360, (byte)(2.55 * device.Battery)); } else { color = HuetoRGB((float)counters[deviceNum] % 360, 255); } } else if (LedAsBatteryIndicator[deviceNum]) { //if (device.Charging == false || device.Battery >= 100) // when charged, don't show the charging animation { DS4Color fullColor = MainColor[deviceNum]; DS4Color lowColor = LowColor[deviceNum]; color = getTransitionedColor(lowColor, fullColor, (uint)device.Battery); } } else { color = MainColor[deviceNum]; } } if (device.Battery <= FlashAt[deviceNum] && !defualtLight && !device.Charging) { if (!(FlashColor[deviceNum].red == 0 && FlashColor[deviceNum].green == 0 && FlashColor[deviceNum].blue == 0)) { color = FlashColor[deviceNum]; } if (FlashType[deviceNum] == 1) { if (fadetimer[deviceNum] <= 0) { fadedirection[deviceNum] = true; } else if (fadetimer[deviceNum] >= 100) { fadedirection[deviceNum] = false; } if (fadedirection[deviceNum]) { fadetimer[deviceNum] += 1; } else { fadetimer[deviceNum] -= 1; } color = getTransitionedColor(color, new DS4Color(0, 0, 0), fadetimer[deviceNum]); } } if (IdleDisconnectTimeout[deviceNum] > 0 && LedAsBatteryIndicator[deviceNum] && (!device.Charging || device.Battery >= 100)) {//Fade lightbar by idle time TimeSpan timeratio = new TimeSpan(DateTime.UtcNow.Ticks - device.lastActive.Ticks); double botratio = timeratio.TotalMilliseconds; double topratio = TimeSpan.FromSeconds(IdleDisconnectTimeout[deviceNum]).TotalMilliseconds; double ratio = ((botratio / topratio) * 100); if (ratio >= 50 && ratio <= 100) { color = getTransitionedColor(color, new DS4Color(0, 0, 0), (uint)((ratio - 50) * 2)); } else if (ratio >= 100) { color = getTransitionedColor(color, new DS4Color(0, 0, 0), 100); } } if (device.Charging && device.Battery < 100) { switch (ChargingType[deviceNum]) { case 1: if (fadetimer[deviceNum] <= 0) { fadedirection[deviceNum] = true; } else if (fadetimer[deviceNum] >= 105) { fadedirection[deviceNum] = false; } if (fadedirection[deviceNum]) { fadetimer[deviceNum] += .1; } else { fadetimer[deviceNum] -= .1; } color = getTransitionedColor(color, new DS4Color(0, 0, 0), fadetimer[deviceNum]); break; case 2: counters[deviceNum] += .167; color = HuetoRGB((float)counters[deviceNum] % 360, 255); break; case 3: color = ChargingColor[deviceNum]; break; default: break; } } } else if (forcelight[deviceNum]) { color = forcedColor[deviceNum]; } else if (shuttingdown) { color = new DS4Color(0, 0, 0); } else { if (device.ConnectionType == ConnectionType.BT) { color = new DS4Color(32, 64, 64); } else { color = new DS4Color(0, 0, 0); } } bool distanceprofile = (ProfilePath[deviceNum].ToLower().Contains("distance") || tempprofilename[deviceNum].ToLower().Contains("distance")); if (distanceprofile && !defualtLight) { //Thing I did for Distance float rumble = device.LeftHeavySlowRumble / 2.55f; byte max = Max(color.red, Max(color.green, color.blue)); if (device.LeftHeavySlowRumble > 100) { color = getTransitionedColor(new DS4Color(max, max, 0), new DS4Color(255, 0, 0), rumble); } else { color = getTransitionedColor(color, getTransitionedColor(new DS4Color(max, max, 0), new DS4Color(255, 0, 0), 39.6078f), device.LeftHeavySlowRumble); } } DS4HapticState haptics = new DS4HapticState { LightBarColor = color }; if (haptics.IsLightBarSet()) { if (forcelight[deviceNum] && forcedFlash[deviceNum] > 0) { haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = (byte)(25 - forcedFlash[deviceNum]); haptics.LightBarExplicitlyOff = true; } else if (device.Battery <= FlashAt[deviceNum] && FlashType[deviceNum] == 0 && !defualtLight && !device.Charging) { int level = device.Battery / 10; //if (level >= 10) //level = 0; // all values of ~0% or >~100% are rendered the same haptics.LightBarFlashDurationOn = BatteryIndicatorDurations[level, 0]; haptics.LightBarFlashDurationOff = BatteryIndicatorDurations[level, 1]; } else if (distanceprofile && device.LeftHeavySlowRumble > 155) //also part of Distance { haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = (byte)((-device.LeftHeavySlowRumble + 265)); haptics.LightBarExplicitlyOff = true; } else { //haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = 1; haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = 0; haptics.LightBarExplicitlyOff = true; } } else { haptics.LightBarExplicitlyOff = true; } if (device.LightBarOnDuration != haptics.LightBarFlashDurationOn && device.LightBarOnDuration != 1 && haptics.LightBarFlashDurationOn == 0) { haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = 1; } if (device.LightBarOnDuration == 1) //helps better reset the color { System.Threading.Thread.Sleep(5); } device.pushHapticState(haptics); }
public bool Start(object tempui, bool showlog = true) { if (x360Bus.Open() && x360Bus.Start()) { if (showlog) { LogDebug(Properties.Resources.Starting); } LogDebug("Connection to Scp Virtual Bus established"); DS4Devices.isExclusiveMode = getUseExclusiveMode(); if (showlog) { LogDebug(Properties.Resources.SearchingController); LogDebug(DS4Devices.isExclusiveMode ? Properties.Resources.UsingExclusive : Properties.Resources.UsingShared); } try { DS4Devices.findControllers(); IEnumerable <DS4Device> devices = DS4Devices.getDS4Controllers(); //int ind = 0; DS4LightBar.defaultLight = false; //foreach (DS4Device device in devices) for (int i = 0, devCount = devices.Count(); i < devCount; i++) { DS4Device device = devices.ElementAt(i); if (showlog) { LogDebug(Properties.Resources.FoundController + device.getMacAddress() + " (" + device.getConnectionType() + ")"); } Task task = new Task(() => { Thread.Sleep(5); WarnExclusiveModeFailure(device); }); task.Start(); DS4Controllers[i] = device; device.setUiContext(tempui as SynchronizationContext); device.Removal += this.On_DS4Removal; device.Removal += DS4Devices.On_Removal; device.SyncChange += this.On_SyncChange; device.SyncChange += DS4Devices.UpdateSerial; device.SerialChange += this.On_SerialChange; if (device.isValidSerial() && containsLinkedProfile(device.getMacAddress())) { ProfilePath[i] = getLinkedProfile(device.getMacAddress()); } else { ProfilePath[i] = OlderProfilePath[i]; } LoadProfile(i, false, this, false, false); touchPad[i] = new Mouse(i, device); device.LightBarColor = getMainColor(i); if (!getDInputOnly(i) && device.isSynced()) { int xinputIndex = x360Bus.FirstController + i; LogDebug("Plugging in X360 Controller #" + xinputIndex); bool xinputResult = x360Bus.Plugin(i); if (xinputResult) { useDInputOnly[i] = false; LogDebug("X360 Controller # " + xinputIndex + " connected"); } else { useDInputOnly[i] = true; LogDebug("X360 Controller # " + xinputIndex + " failed. Using DInput only mode"); } } int tempIdx = i; device.Report += (sender, e) => { this.On_Report(sender, e, tempIdx); }; TouchPadOn(i, device); CheckProfileOptions(i, device, true); device.StartUpdate(); //string filename = ProfilePath[ind]; //ind++; if (showlog) { if (File.Exists(appdatapath + "\\Profiles\\" + ProfilePath[i] + ".xml")) { string prolog = Properties.Resources.UsingProfile.Replace("*number*", (i + 1).ToString()).Replace("*Profile name*", ProfilePath[i]); LogDebug(prolog); Log.LogToTray(prolog); } else { string prolog = Properties.Resources.NotUsingProfile.Replace("*number*", (i + 1).ToString()); LogDebug(prolog); Log.LogToTray(prolog); } } if (i >= 4) // out of Xinput devices! { break; } } } catch (Exception e) { LogDebug(e.Message); Log.LogToTray(e.Message); } running = true; } else { string logMessage = "Could not connect to Scp Virtual Bus Driver. Please check the status of the System device in Device Manager"; LogDebug(logMessage); Log.LogToTray(logMessage); } runHotPlug = true; return(true); }