2014-03-28 02:50:40 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using HidLibrary;
|
|
|
|
|
namespace DS4Library
|
|
|
|
|
{
|
|
|
|
|
public class DS4Devices
|
|
|
|
|
{
|
|
|
|
|
private static Dictionary<string, DS4Device> Devices = new Dictionary<string, DS4Device>();
|
2014-03-29 06:29:08 +01:00
|
|
|
|
private static HashSet<String> DevicePaths = new HashSet<String>();
|
2014-03-28 02:50:40 +01:00
|
|
|
|
public static bool isExclusiveMode = false;
|
|
|
|
|
|
|
|
|
|
//enumerates ds4 controllers in the system
|
|
|
|
|
public static void findControllers()
|
|
|
|
|
{
|
|
|
|
|
lock (Devices)
|
|
|
|
|
{
|
|
|
|
|
int[] pid = { 0x5C4 };
|
|
|
|
|
IEnumerable<HidDevice> hDevices = HidDevices.Enumerate(0x054C, pid);
|
2014-03-29 06:29:08 +01:00
|
|
|
|
// Sort Bluetooth first in case USB is also connected on the same controller.
|
|
|
|
|
hDevices = hDevices.OrderBy<HidDevice, ConnectionType>((HidDevice d) => { return DS4Device.HidConnectionType(d); });
|
2014-03-28 02:50:40 +01:00
|
|
|
|
|
|
|
|
|
foreach (HidDevice hDevice in hDevices)
|
|
|
|
|
{
|
2014-03-29 06:29:08 +01:00
|
|
|
|
if (DevicePaths.Contains(hDevice.DevicePath))
|
|
|
|
|
continue; // BT/USB endpoint already open once
|
2014-03-28 02:50:40 +01:00
|
|
|
|
if (!hDevice.IsOpen)
|
2014-03-29 06:29:08 +01:00
|
|
|
|
{
|
2014-03-28 02:50:40 +01:00
|
|
|
|
hDevice.OpenDevice(isExclusiveMode);
|
2014-03-29 06:29:08 +01:00
|
|
|
|
// TODO in exclusive mode, try to hold both open when both are connected
|
|
|
|
|
if (isExclusiveMode && !hDevice.IsOpen)
|
|
|
|
|
hDevice.OpenDevice(false);
|
|
|
|
|
}
|
2014-03-28 02:50:40 +01:00
|
|
|
|
if (hDevice.IsOpen)
|
|
|
|
|
{
|
|
|
|
|
if (Devices.ContainsKey(hDevice.readSerial()))
|
2014-03-29 06:29:08 +01:00
|
|
|
|
continue; // happens when the BT endpoint already is open and the USB is plugged into the same host
|
2014-03-28 02:50:40 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DS4Device ds4Device = new DS4Device(hDevice);
|
|
|
|
|
ds4Device.Removal += On_Removal;
|
|
|
|
|
Devices.Add(ds4Device.MacAddress, ds4Device);
|
2014-03-29 06:29:08 +01:00
|
|
|
|
DevicePaths.Add(hDevice.DevicePath);
|
|
|
|
|
ds4Device.StartUpdate();
|
2014-03-28 02:50:40 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//allows to get DS4Device by specifying unique MAC address
|
|
|
|
|
//format for MAC address is XX:XX:XX:XX:XX:XX
|
|
|
|
|
public static DS4Device getDS4Controller(string mac)
|
2014-03-29 06:29:08 +01:00
|
|
|
|
{
|
|
|
|
|
lock (Devices)
|
2014-03-28 02:50:40 +01:00
|
|
|
|
{
|
2014-03-29 06:29:08 +01:00
|
|
|
|
DS4Device device = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Devices.TryGetValue(mac, out device);
|
|
|
|
|
}
|
|
|
|
|
catch (ArgumentNullException) { }
|
|
|
|
|
return device;
|
2014-03-28 02:50:40 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//returns DS4 controllers that were found and are running
|
|
|
|
|
public static IEnumerable<DS4Device> getDS4Controllers()
|
|
|
|
|
{
|
2014-03-29 06:29:08 +01:00
|
|
|
|
lock (Devices)
|
|
|
|
|
{
|
|
|
|
|
DS4Device[] controllers = new DS4Device[Devices.Count];
|
|
|
|
|
Devices.Values.CopyTo(controllers, 0);
|
|
|
|
|
return controllers;
|
|
|
|
|
}
|
2014-03-28 02:50:40 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void stopControllers()
|
2014-03-29 06:29:08 +01:00
|
|
|
|
{
|
|
|
|
|
lock (Devices)
|
2014-03-28 02:50:40 +01:00
|
|
|
|
{
|
2014-03-29 06:29:08 +01:00
|
|
|
|
IEnumerable<DS4Device> devices = getDS4Controllers();
|
|
|
|
|
foreach (DS4Device device in devices)
|
|
|
|
|
{
|
|
|
|
|
device.StopUpdate();
|
|
|
|
|
device.HidDevice.CloseDevice();
|
|
|
|
|
}
|
|
|
|
|
Devices.Clear();
|
|
|
|
|
DevicePaths.Clear();
|
2014-03-28 02:50:40 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//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;
|
|
|
|
|
device.HidDevice.CloseDevice();
|
|
|
|
|
Devices.Remove(device.MacAddress);
|
2014-03-29 06:29:08 +01:00
|
|
|
|
DevicePaths.Remove(device.HidDevice.DevicePath);
|
2014-03-28 02:50:40 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|