mirror of
https://github.com/cemu-project/DS4Windows.git
synced 2024-11-25 18:46:58 +01:00
Merged Electrobrains DS4Windows, Hectic's options, imporved custom mapping
This commit is contained in:
parent
df43fd0d74
commit
768fdd0260
@ -13,10 +13,14 @@ namespace DS4Control
|
||||
private DS4State s = new DS4State();
|
||||
private bool buttonLock; // Toggled with a two-finger touchpad push, we accept and absorb button input without any fingers on a touchpad, helping with drag-and-drop.
|
||||
private DS4Device dev = null;
|
||||
private readonly MouseCursor cursor;
|
||||
private readonly MouseWheel wheel;
|
||||
public ButtonMouse(int deviceID, DS4Device d)
|
||||
{
|
||||
deviceNum = deviceID;
|
||||
dev = d;
|
||||
cursor = new MouseCursor(deviceNum);
|
||||
wheel = new MouseWheel(deviceNum);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -26,56 +30,36 @@ namespace DS4Control
|
||||
|
||||
public void touchesMoved(object sender, TouchpadEventArgs arg)
|
||||
{
|
||||
if (arg.touches.Length == 1)
|
||||
{
|
||||
double sensitivity = Global.getTouchSensitivity(deviceNum) / 100.0;
|
||||
int mouseDeltaX = (int)(sensitivity * (arg.touches[0].deltaX));
|
||||
int mouseDeltaY = (int)(sensitivity * (arg.touches[0].deltaY));
|
||||
InputMethods.MoveCursorBy(mouseDeltaX, mouseDeltaY);
|
||||
}
|
||||
else if (arg.touches.Length == 2)
|
||||
{
|
||||
Touch lastT0 = arg.touches[0].previousTouch;
|
||||
Touch lastT1 = arg.touches[1].previousTouch;
|
||||
Touch T0 = arg.touches[0];
|
||||
Touch T1 = arg.touches[1];
|
||||
|
||||
//mouse wheel 120 == 1 wheel click according to Windows API
|
||||
int lastMidX = (lastT0.hwX + lastT1.hwX) / 2, lastMidY = (lastT0.hwY + lastT1.hwY) / 2,
|
||||
currentMidX = (T0.hwX + T1.hwX) / 2, currentMidY = (T0.hwY + T1.hwY) / 2; // XXX Will controller swap touch IDs?
|
||||
double coefficient = Global.getScrollSensitivity(deviceNum);
|
||||
// Adjust for touch distance: "standard" distance is 960 pixels, i.e. half the width. Scroll farther if fingers are farther apart, and vice versa, in linear proportion.
|
||||
double touchXDistance = T1.hwX - T0.hwX, touchYDistance = T1.hwY - T0.hwY, touchDistance = Math.Sqrt(touchXDistance * touchXDistance + touchYDistance * touchYDistance);
|
||||
coefficient *= touchDistance / 960.0;
|
||||
InputMethods.MouseWheel((int)(coefficient * (lastMidY - currentMidY)), (int)(coefficient * (currentMidX - lastMidX)));
|
||||
}
|
||||
synthesizeMouseButtons(false);
|
||||
}
|
||||
|
||||
public void untouched()
|
||||
{
|
||||
if (buttonLock)
|
||||
synthesizeMouseButtons(false);
|
||||
else
|
||||
cursor.touchesMoved(arg);
|
||||
wheel.touchesMoved(arg);
|
||||
dev.getCurrentState(s);
|
||||
synthesizeMouseButtons(false);
|
||||
}
|
||||
|
||||
public void touchUnchanged(object sender, EventArgs unused)
|
||||
{
|
||||
dev.getCurrentState(s);
|
||||
if (buttonLock || s.Touch1 || s.Touch2)
|
||||
synthesizeMouseButtons(false);
|
||||
}
|
||||
|
||||
public void touchesBegan(object sender, TouchpadEventArgs arg)
|
||||
{
|
||||
cursor.touchesBegan(arg);
|
||||
wheel.touchesBegan(arg);
|
||||
dev.getCurrentState(s);
|
||||
synthesizeMouseButtons(false);
|
||||
}
|
||||
|
||||
public void touchesEnded(object sender, TouchpadEventArgs arg)
|
||||
{
|
||||
dev.getCurrentState(s);
|
||||
if (!buttonLock)
|
||||
synthesizeMouseButtons(true);
|
||||
else
|
||||
dev.getCurrentState(s);
|
||||
}
|
||||
|
||||
private void synthesizeMouseButtons(bool justRelease)
|
||||
{
|
||||
dev.getCurrentState(s);
|
||||
bool previousLeftButton = leftButton, previousMiddleButton = middleButton, previousRightButton = rightButton;
|
||||
if (justRelease)
|
||||
{
|
||||
@ -113,17 +97,20 @@ namespace DS4Control
|
||||
{
|
||||
if (upperDown)
|
||||
{
|
||||
mapTouchPad(DS4Controls.TouchUpper, true);
|
||||
if (!mapTouchPad(DS4Controls.TouchUpper, true))
|
||||
InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_MIDDLEUP);
|
||||
upperDown = false;
|
||||
}
|
||||
if (leftDown)
|
||||
{
|
||||
mapTouchPad(DS4Controls.TouchButton, true);
|
||||
if (!mapTouchPad(DS4Controls.TouchButton, true))
|
||||
InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTUP);
|
||||
leftDown = false;
|
||||
}
|
||||
if (rightDown)
|
||||
{
|
||||
mapTouchPad(DS4Controls.TouchMulti, true);
|
||||
if (!mapTouchPad(DS4Controls.TouchMulti, true))
|
||||
InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_RIGHTUP);
|
||||
rightDown = false;
|
||||
}
|
||||
dev.setRumble(0, 0);
|
||||
@ -134,7 +121,8 @@ namespace DS4Control
|
||||
byte leftRumble, rightRumble;
|
||||
if (arg.touches == null) //No touches, finger on upper portion of touchpad
|
||||
{
|
||||
mapTouchPad(DS4Controls.TouchUpper, false);
|
||||
if (!mapTouchPad(DS4Controls.TouchUpper, false))
|
||||
InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_MIDDLEDOWN);
|
||||
upperDown = true;
|
||||
leftRumble = rightRumble = 127;
|
||||
}
|
||||
@ -142,23 +130,23 @@ namespace DS4Control
|
||||
{
|
||||
if (isLeft(arg.touches[0]))
|
||||
{
|
||||
mapTouchPad(DS4Controls.TouchButton, false);
|
||||
if (!mapTouchPad(DS4Controls.TouchButton, false))
|
||||
InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTDOWN);
|
||||
leftDown = true;
|
||||
leftRumble = 63;
|
||||
rightRumble = 0;
|
||||
}
|
||||
else if (isRight(arg.touches[0]))
|
||||
{
|
||||
mapTouchPad(DS4Controls.TouchMulti, false);
|
||||
if (!mapTouchPad(DS4Controls.TouchMulti, false))
|
||||
InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_RIGHTDOWN);
|
||||
rightDown = true;
|
||||
leftRumble = 0;
|
||||
rightRumble = 63;
|
||||
}
|
||||
else
|
||||
{
|
||||
mapTouchPad(DS4Controls.TouchUpper, false); // ambiguous = same as upper
|
||||
upperDown = true;
|
||||
leftRumble = rightRumble = 127;
|
||||
leftRumble = rightRumble = 0; // Ignore ambiguous pushes.
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -5,7 +5,7 @@ using System.Text;
|
||||
using DS4Library;
|
||||
namespace DS4Control
|
||||
{
|
||||
public class Control: IDisposable
|
||||
public class Control
|
||||
{
|
||||
X360Device x360Bus;
|
||||
DS4Device[] DS4Controllers = new DS4Device[4];
|
||||
@ -38,6 +38,17 @@ namespace DS4Control
|
||||
}
|
||||
}
|
||||
|
||||
private void WarnExclusiveModeFailure(DS4Device device)
|
||||
{
|
||||
if (DS4Devices.isExclusiveMode && !device.IsExclusive)
|
||||
{
|
||||
String message = "Warning: Could not open DS4 " + device.MacAddress + " exclusively. " +
|
||||
"You must quit other applications like Steam, Uplay before activating the 'Hide DS4 Controller' option.";
|
||||
LogDebug(message);
|
||||
Log.LogToTray(message);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (x360Bus.Open() && x360Bus.Start())
|
||||
@ -53,33 +64,29 @@ namespace DS4Control
|
||||
int ind = 0;
|
||||
foreach (DS4Device device in devices)
|
||||
{
|
||||
LogDebug("Found Controller: " + device.MacAddress);
|
||||
if (device.MacAddress == "00:00:00:00:00:00")
|
||||
{
|
||||
LogDebug("WARNING: If you are seing all zeroes as controller ID");
|
||||
LogDebug("You might be running not fully supported BT dongle");
|
||||
LogDebug("Only some basic functionality is enabled");
|
||||
}
|
||||
LogDebug("Found Controller: " + device.MacAddress + " (" + device.ConnectionType + ")");
|
||||
WarnExclusiveModeFailure(device);
|
||||
DS4Controllers[ind] = device;
|
||||
device.Removal += this.On_DS4Removal;
|
||||
TPadModeSwitcher m_switcher = new TPadModeSwitcher(device, ind);
|
||||
m_switcher.Debug += OnDebug;
|
||||
m_switcher.setMode(Global.getTouchEnabled(ind) ? 1 : 0);
|
||||
modeSwitcher[ind] = m_switcher;
|
||||
DS4Color color = Global.loadColor(ind);
|
||||
device.LightBarColor = color;
|
||||
x360Bus.Plugin(ind + 1);
|
||||
device.Report += this.On_Report;
|
||||
m_switcher.setMode(Global.getTouchEnabled(ind) ? 1 : 0);
|
||||
ind++;
|
||||
LogDebug("Controller: " + device.MacAddress + " is ready to use");
|
||||
Log.LogToTray("Controller: " + device.MacAddress + " is ready to use");
|
||||
if (ind >= 4)
|
||||
if (ind >= 4) // out of Xinput devices!
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogDebug(e.Message);
|
||||
Log.LogToTray(e.Message);
|
||||
}
|
||||
running = true;
|
||||
|
||||
@ -106,19 +113,28 @@ namespace DS4Control
|
||||
LogDebug("Stopping DS4 Controllers");
|
||||
DS4Devices.stopControllers();
|
||||
LogDebug("Stopped DS4 Tool");
|
||||
Global.ControllerStatusChanged(this);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private volatile bool justRemoved; // inhibits HotPlug temporarily when a device is being torn down
|
||||
public bool HotPlug()
|
||||
{
|
||||
if (running)
|
||||
{
|
||||
if (justRemoved)
|
||||
{
|
||||
justRemoved = false;
|
||||
System.Threading.Thread.Sleep(200);
|
||||
}
|
||||
DS4Devices.findControllers();
|
||||
IEnumerable<DS4Device> devices = DS4Devices.getDS4Controllers();
|
||||
foreach (DS4Device device in devices)
|
||||
{
|
||||
if (device.IsDisconnecting)
|
||||
continue;
|
||||
if (((Func<bool>)delegate
|
||||
{
|
||||
for (Int32 Index = 0; Index < DS4Controllers.Length; Index++)
|
||||
@ -131,15 +147,19 @@ namespace DS4Control
|
||||
for (Int32 Index = 0; Index < DS4Controllers.Length; Index++)
|
||||
if (DS4Controllers[Index] == null)
|
||||
{
|
||||
LogDebug("Found Controller: " + device.MacAddress + " (" + device.ConnectionType + ")");
|
||||
WarnExclusiveModeFailure(device);
|
||||
DS4Controllers[Index] = device;
|
||||
device.Removal += this.On_DS4Removal;
|
||||
TPadModeSwitcher m_switcher = new TPadModeSwitcher(device, Index);
|
||||
m_switcher.Debug += OnDebug;
|
||||
modeSwitcher[Index] = m_switcher;
|
||||
m_switcher.setMode(Global.getTouchEnabled(Index) ? 1 : 0);
|
||||
device.LightBarColor = Global.loadColor(Index);
|
||||
device.Report += this.On_Report;
|
||||
x360Bus.Plugin(Index + 1);
|
||||
m_switcher.setMode(Global.getTouchEnabled(Index) ? 1 : 0);
|
||||
LogDebug("Controller: " + device.MacAddress + " is ready to use");
|
||||
Log.LogToTray("Controller: " + device.MacAddress + " is ready to use");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -152,7 +172,21 @@ namespace DS4Control
|
||||
if (DS4Controllers[index] != null)
|
||||
{
|
||||
DS4Device d = DS4Controllers[index];
|
||||
return d.MacAddress + ", Battery = " + d.Battery + "%," + " Touchpad = " + modeSwitcher[index].ToString() + " (" + d.ConnectionType + ")";
|
||||
if (!d.IsAlive())
|
||||
return null; // awaiting the first battery charge indication
|
||||
String battery;
|
||||
if (d.Charging)
|
||||
{
|
||||
if (d.Battery >= 100)
|
||||
battery = "fully-charged";
|
||||
else
|
||||
battery = "charging at ~" + d.Battery + "%";
|
||||
}
|
||||
else
|
||||
{
|
||||
battery = "draining at ~" + d.Battery + "%";
|
||||
}
|
||||
return d.MacAddress + " (" + d.ConnectionType + "), Battery is " + battery + ", Touchpad in " + modeSwitcher[index].ToString();
|
||||
}
|
||||
else
|
||||
return null;
|
||||
@ -168,11 +202,13 @@ namespace DS4Control
|
||||
ind = i;
|
||||
if (ind != -1)
|
||||
{
|
||||
justRemoved = true;
|
||||
x360Bus.Unplug(ind + 1);
|
||||
LogDebug("Controller " + device.MacAddress + " was removed or lost connection");
|
||||
Log.LogToTray("Controller " + device.MacAddress + " was removed or lost connection");
|
||||
DS4Controllers[ind] = null;
|
||||
modeSwitcher[ind] = null;
|
||||
Global.ControllerStatusChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,36 +225,39 @@ namespace DS4Control
|
||||
|
||||
if (ind!=-1)
|
||||
{
|
||||
DS4State cState;
|
||||
device.getExposedState(ExposedState[ind], CurrentState[ind]);
|
||||
DS4State cState = CurrentState[ind];
|
||||
device.getPreviousState(PreviousState[ind]);
|
||||
DS4State pState = PreviousState[ind];
|
||||
|
||||
if (modeSwitcher[ind].getCurrentMode() is ButtonMouse)
|
||||
{
|
||||
device.getExposedState(ExposedState[ind], CurrentState[ind]);
|
||||
cState = CurrentState[ind];
|
||||
ButtonMouse mode = (ButtonMouse)modeSwitcher[ind].getCurrentMode();
|
||||
if (!cState.Touch1 && !cState.Touch2 && !cState.TouchButton)
|
||||
mode.untouched();
|
||||
cState = mode.getDS4State();
|
||||
// XXX so disgusting, need to virtualize this again
|
||||
mode.getDS4State().Copy(cState);
|
||||
}
|
||||
else
|
||||
{
|
||||
device.getExposedState(ExposedState[ind], CurrentState[ind]);
|
||||
cState = CurrentState[ind];
|
||||
}
|
||||
device.getPreviousState(PreviousState[ind]);
|
||||
DS4State pState = PreviousState[ind];
|
||||
|
||||
|
||||
CheckForHotkeys(ind, cState, pState);
|
||||
|
||||
DS4LightBar.updateBatteryStatus(cState.Battery, device, ind);
|
||||
|
||||
if (Global.getHasCustomKeysorButtons(ind))
|
||||
{
|
||||
Mapping.mapButtons(cState, pState, MappedState[ind]);
|
||||
cState = MappedState[ind];
|
||||
}
|
||||
|
||||
// Update the GUI/whatever.
|
||||
DS4LightBar.updateLightBar(device, ind);
|
||||
if (pState.Battery != cState.Battery)
|
||||
Global.ControllerStatusChanged(this);
|
||||
|
||||
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]);
|
||||
@ -272,16 +311,5 @@ namespace DS4Control
|
||||
heavyBoosted = 255;
|
||||
DS4Controllers[deviceNum].setRumble((byte)lightBoosted, (byte)heavyBoosted);
|
||||
}
|
||||
|
||||
public DS4Device getDS4Controller(int deviceNum)
|
||||
{
|
||||
return DS4Controllers[deviceNum];
|
||||
}
|
||||
|
||||
//CA1001 TypesThatOwnDisposableFieldsShouldBeDisposable
|
||||
public void Dispose()
|
||||
{
|
||||
x360Bus.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,14 @@ namespace DS4Control
|
||||
public class MouseCursorOnly : ITouchpadBehaviour
|
||||
{
|
||||
private int deviceNum;
|
||||
private readonly MouseCursor cursor;
|
||||
private readonly MouseWheel wheel;
|
||||
|
||||
public MouseCursorOnly(int deviceID)
|
||||
{
|
||||
deviceNum = deviceID;
|
||||
cursor = new MouseCursor(deviceNum);
|
||||
wheel = new MouseWheel(deviceNum);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -21,16 +26,15 @@ namespace DS4Control
|
||||
|
||||
public void touchesMoved(object sender, TouchpadEventArgs arg)
|
||||
{
|
||||
if (arg.touches.Length == 1)
|
||||
{
|
||||
double sensitivity = Global.getTouchSensitivity(deviceNum) / 100.0;
|
||||
int mouseDeltaX = (int)(sensitivity * (arg.touches[0].deltaX));
|
||||
int mouseDeltaY = (int)(sensitivity * (arg.touches[0].deltaY));
|
||||
InputMethods.MoveCursorBy(mouseDeltaX, mouseDeltaY);
|
||||
}
|
||||
cursor.touchesMoved(arg);
|
||||
wheel.touchesMoved(arg);
|
||||
}
|
||||
|
||||
public void touchesBegan(object sender, TouchpadEventArgs arg) { }
|
||||
public void touchesBegan(object sender, TouchpadEventArgs arg)
|
||||
{
|
||||
cursor.touchesBegan(arg);
|
||||
wheel.touchesBegan(arg);
|
||||
}
|
||||
|
||||
public void touchesEnded(object sender, TouchpadEventArgs arg) { }
|
||||
|
||||
@ -38,6 +42,6 @@ namespace DS4Control
|
||||
|
||||
public void touchButtonDown(object sender, TouchpadEventArgs arg) { }
|
||||
|
||||
public void untouched(object sender, TouchpadEventArgs nullUnused) { }
|
||||
public void touchUnchanged(object sender, EventArgs unused) { }
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,8 @@
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="CursorOnlyMode.cs" />
|
||||
<Compile Include="DragMouse.cs" />
|
||||
<Compile Include="MouseCursor.cs" />
|
||||
<Compile Include="MouseWheel.cs" />
|
||||
<Compile Include="TouchpadDisabled.cs" />
|
||||
<Compile Include="TPadModeSwitcher.cs" />
|
||||
<Compile Include="DS4LightBar.cs" />
|
||||
|
@ -9,7 +9,7 @@ namespace DS4Control
|
||||
{
|
||||
private readonly static byte[/* Light On duration */, /* Light Off duration */] BatteryIndicatorDurations =
|
||||
{
|
||||
{ 255, 255 }, // 0 doesn't happen
|
||||
{ 0, 0 }, // 0 is for "charging" OR anything sufficiently-"charged"
|
||||
{ 28, 252 },
|
||||
{ 56, 224 },
|
||||
{ 84, 196 },
|
||||
@ -18,46 +18,77 @@ namespace DS4Control
|
||||
{ 168, 112 },
|
||||
{ 196, 84 },
|
||||
{ 224, 56}, // on 80% of the time at 80, etc.
|
||||
{ 252, 28 }, // on 90% of the time at 90
|
||||
{ 0, 0 } // no flash at 100
|
||||
{ 252, 28 } // on 90% of the time at 90
|
||||
};
|
||||
static double[] counters = new double[4];
|
||||
|
||||
public static void updateBatteryStatus(int battery, DS4Device device, int deviceNum)
|
||||
public static void updateLightBar(DS4Device device, int deviceNum)
|
||||
{
|
||||
DS4Color color;
|
||||
if (Global.getLedAsBatteryIndicator(deviceNum))
|
||||
{
|
||||
byte[] fullColor = {
|
||||
Global.loadColor(deviceNum).red,
|
||||
Global.loadColor(deviceNum).green,
|
||||
Global.loadColor(deviceNum).blue
|
||||
if (device.Charging == false || device.Battery >= 100) // when charged, don't show the charging animation
|
||||
{
|
||||
DS4Color fullColor = new DS4Color
|
||||
{
|
||||
red = Global.loadColor(deviceNum).red,
|
||||
green = Global.loadColor(deviceNum).green,
|
||||
blue = Global.loadColor(deviceNum).blue
|
||||
};
|
||||
|
||||
// New Setting
|
||||
DS4Color color = Global.loadLowColor(deviceNum);
|
||||
byte[] lowColor = { color.red, color.green, color.blue };
|
||||
|
||||
uint ratio = (uint)battery;
|
||||
color = Global.getTransitionedColor(lowColor, fullColor, ratio);
|
||||
device.LightBarColor = color;
|
||||
|
||||
color = Global.loadLowColor(deviceNum);
|
||||
DS4Color lowColor = new DS4Color
|
||||
{
|
||||
red = color.red,
|
||||
green = color.green,
|
||||
blue = color.blue
|
||||
};
|
||||
|
||||
color = Global.getTransitionedColor(lowColor, fullColor, (uint)device.Battery);
|
||||
}
|
||||
else // Display rainbow when charging.
|
||||
{
|
||||
counters[deviceNum]++;
|
||||
double theta = Math.PI * 2.0 * counters[deviceNum] / 1800.0;
|
||||
const double brightness = Math.PI; // small brightness numbers (far from max 128.0) mean less light steps and slower output reports; also, the lower the brightness the faster you can charge
|
||||
color = new DS4Color
|
||||
{
|
||||
red = (byte)(brightness * Math.Sin(theta) + brightness - 0.5),
|
||||
green = (byte)(brightness * Math.Sin(theta + (Math.PI * 2.0) / 3.0) + brightness - 0.5),
|
||||
blue = (byte)(brightness * Math.Sin(theta + 2.0 * (Math.PI * 2.0) / 3.0) + brightness - 0.5)
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DS4Color color = Global.loadColor(deviceNum);
|
||||
device.LightBarColor = color;
|
||||
color = Global.loadColor(deviceNum);
|
||||
}
|
||||
|
||||
DS4HapticState haptics = new DS4HapticState
|
||||
{
|
||||
LightBarColor = color
|
||||
};
|
||||
if (haptics.IsLightBarSet())
|
||||
{
|
||||
if (Global.getFlashWhenLowBattery(deviceNum))
|
||||
{
|
||||
device.LightBarOnDuration = BatteryIndicatorDurations[battery / 10, 0];
|
||||
device.LightBarOffDuration = BatteryIndicatorDurations[battery / 10, 1];
|
||||
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
|
||||
{
|
||||
device.LightBarOffDuration = device.LightBarOnDuration = 0;
|
||||
haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
haptics.LightBarExplicitlyOff = true;
|
||||
}
|
||||
device.pushHapticState(haptics);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,12 @@ using System.Threading;
|
||||
|
||||
namespace DS4Control
|
||||
{
|
||||
class DragMouse: Mouse, IDisposable
|
||||
class DragMouse: Mouse
|
||||
{
|
||||
protected bool leftClick = false;
|
||||
protected Timer timer;
|
||||
private readonly MouseCursor cursor;
|
||||
private readonly MouseWheel wheel;
|
||||
|
||||
public DragMouse(int deviceID):base(deviceID)
|
||||
{
|
||||
@ -22,6 +24,8 @@ namespace DS4Control
|
||||
}, null,
|
||||
System.Threading.Timeout.Infinite,
|
||||
System.Threading.Timeout.Infinite);
|
||||
cursor = new MouseCursor(deviceNum);
|
||||
wheel = new MouseWheel(deviceNum);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -29,44 +33,9 @@ namespace DS4Control
|
||||
return "Drag Mode";
|
||||
}
|
||||
|
||||
public override void touchesMoved(object sender, TouchpadEventArgs arg)
|
||||
{
|
||||
if (arg.touches.Length == 1)
|
||||
{
|
||||
double sensitivity = Global.getTouchSensitivity(deviceNum) / 100.0;
|
||||
int mouseDeltaX = (int)(sensitivity * (arg.touches[0].deltaX));
|
||||
int mouseDeltaY = (int)(sensitivity * (arg.touches[0].deltaY));
|
||||
InputMethods.MoveCursorBy(mouseDeltaX, mouseDeltaY);
|
||||
}
|
||||
else if (arg.touches.Length == 2 && !leftClick)
|
||||
{
|
||||
Touch lastT0 = arg.touches[0].previousTouch;
|
||||
Touch lastT1 = arg.touches[1].previousTouch;
|
||||
Touch T0 = arg.touches[0];
|
||||
Touch T1 = arg.touches[1];
|
||||
|
||||
//mouse wheel 120 == 1 wheel click according to Windows API
|
||||
int lastMidX = (lastT0.hwX + lastT1.hwX) / 2, lastMidY = (lastT0.hwY + lastT1.hwY) / 2,
|
||||
currentMidX = (T0.hwX + T1.hwX) / 2, currentMidY = (T0.hwY + T1.hwY) / 2; // XXX Will controller swap touch IDs?
|
||||
double coefficient = Global.getScrollSensitivity(deviceNum);
|
||||
// Adjust for touch distance: "standard" distance is 960 pixels, i.e. half the width. Scroll farther if fingers are farther apart, and vice versa, in linear proportion.
|
||||
double touchXDistance = T1.hwX - T0.hwX, touchYDistance = T1.hwY - T0.hwY, touchDistance = Math.Sqrt(touchXDistance * touchXDistance + touchYDistance * touchYDistance);
|
||||
coefficient *= touchDistance / 960.0;
|
||||
InputMethods.MouseWheel((int)(coefficient * (lastMidY - currentMidY)), (int)(coefficient * (currentMidX - lastMidX)));
|
||||
}
|
||||
else
|
||||
{
|
||||
double sensitivity = Global.getTouchSensitivity(deviceNum) / 100.0;
|
||||
int mouseDeltaX = (int)(sensitivity * (arg.touches[1].deltaX));
|
||||
int mouseDeltaY = (int)(sensitivity * (arg.touches[1].deltaY));
|
||||
InputMethods.MoveCursorBy(mouseDeltaX, mouseDeltaY);
|
||||
}
|
||||
}
|
||||
|
||||
public override void touchesBegan(object sender, TouchpadEventArgs arg)
|
||||
{
|
||||
pastTime = arg.timeStamp;
|
||||
firstTouch = arg.touches[0];
|
||||
base.touchesBegan(sender, arg);
|
||||
if (leftClick)
|
||||
timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
|
||||
}
|
||||
@ -139,11 +108,5 @@ namespace DS4Control
|
||||
leftClick = true;
|
||||
}
|
||||
}
|
||||
|
||||
//CA1001 TypesThatOwnDisposableFieldsShouldBeDisposable
|
||||
public void Dispose()
|
||||
{
|
||||
timer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,5 +12,6 @@ namespace DS4Control
|
||||
void touchButtonUp(object sender, TouchpadEventArgs arg);
|
||||
void touchButtonDown(object sender, TouchpadEventArgs arg);
|
||||
void touchesEnded(object sender, TouchpadEventArgs arg);
|
||||
void touchUnchanged(object sender, EventArgs unused);
|
||||
}
|
||||
}
|
||||
|
@ -40,8 +40,6 @@ namespace DS4Control
|
||||
MappedState.LY = 127;
|
||||
MappedState.RX = 127;
|
||||
MappedState.RY = 127;
|
||||
int MouseDeltaX = 0;
|
||||
int MouseDeltaY = 0;
|
||||
|
||||
foreach (KeyValuePair<DS4Controls, X360Controls> customButton in Global.getCustomButtons())
|
||||
{
|
||||
@ -183,34 +181,6 @@ namespace DS4Control
|
||||
else if (PrevOn && !CurOn)
|
||||
InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_MIDDLEUP);
|
||||
break;
|
||||
case X360Controls.MouseUp:
|
||||
if (MouseDeltaY == 0)
|
||||
{
|
||||
MouseDeltaY = calculateRelativeMouseDelta(customButton.Key, cState, prevState);
|
||||
MouseDeltaY = -Math.Abs(MouseDeltaY);
|
||||
}
|
||||
break;
|
||||
case X360Controls.MouseDown:
|
||||
if (MouseDeltaY == 0)
|
||||
{
|
||||
MouseDeltaY = calculateRelativeMouseDelta(customButton.Key, cState, prevState);
|
||||
MouseDeltaY = Math.Abs(MouseDeltaY);
|
||||
}
|
||||
break;
|
||||
case X360Controls.MouseLeft:
|
||||
if (MouseDeltaX == 0)
|
||||
{
|
||||
MouseDeltaX = calculateRelativeMouseDelta(customButton.Key, cState, prevState);
|
||||
MouseDeltaX = -Math.Abs(MouseDeltaX);
|
||||
}
|
||||
break;
|
||||
case X360Controls.MouseRight:
|
||||
if (MouseDeltaX == 0)
|
||||
{
|
||||
MouseDeltaX = calculateRelativeMouseDelta(customButton.Key, cState, prevState);
|
||||
MouseDeltaX = Math.Abs(MouseDeltaX);
|
||||
}
|
||||
break;
|
||||
case X360Controls.Unbound:
|
||||
resetToDefaultValue(customButton.Key, MappedState);
|
||||
break;
|
||||
@ -225,54 +195,6 @@ namespace DS4Control
|
||||
MappedState.RX = cState.RX;
|
||||
if (!RY)
|
||||
MappedState.RY = cState.RY;
|
||||
InputMethods.MoveCursorBy(MouseDeltaX, MouseDeltaY);
|
||||
}
|
||||
|
||||
private static int calculateRelativeMouseDelta(DS4Controls control, DS4State cState, DS4State pState)
|
||||
{
|
||||
int axisVal = -1;
|
||||
int DEAD_ZONE = 10;
|
||||
float SPEED_MULTIPLIER = 0.000004f;
|
||||
bool positive = false;
|
||||
float deltaTime = cState.ReportTimeStamp.Ticks - pState.ReportTimeStamp.Ticks;
|
||||
switch (control)
|
||||
{
|
||||
case DS4Controls.LXNeg:
|
||||
axisVal = cState.LX;
|
||||
break;
|
||||
case DS4Controls.LXPos:
|
||||
positive = true;
|
||||
axisVal = cState.LX;
|
||||
break;
|
||||
case DS4Controls.RXNeg:
|
||||
axisVal = cState.RX;
|
||||
break;
|
||||
case DS4Controls.RXPos:
|
||||
positive = true;
|
||||
axisVal = cState.RX;
|
||||
break;
|
||||
case DS4Controls.LYNeg:
|
||||
axisVal = cState.LY;
|
||||
break;
|
||||
case DS4Controls.LYPos:
|
||||
positive = true;
|
||||
axisVal = cState.LY;
|
||||
break;
|
||||
case DS4Controls.RYNeg:
|
||||
axisVal = cState.RY;
|
||||
break;
|
||||
case DS4Controls.RYPos:
|
||||
positive = true;
|
||||
axisVal = cState.RY;
|
||||
break;
|
||||
}
|
||||
axisVal = axisVal - 127;
|
||||
int delta = 0;
|
||||
if ( (!positive && axisVal < -DEAD_ZONE ) || (positive && axisVal > DEAD_ZONE))
|
||||
{
|
||||
delta = (int)(float) (axisVal * SPEED_MULTIPLIER * deltaTime);
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
|
||||
public static bool compare(byte b1, byte b2)
|
||||
|
@ -11,11 +11,15 @@ namespace DS4Control
|
||||
protected DateTime pastTime;
|
||||
protected Touch firstTouch;
|
||||
protected int deviceNum;
|
||||
private readonly MouseCursor cursor;
|
||||
private readonly MouseWheel wheel;
|
||||
protected bool rightClick = false;
|
||||
|
||||
public Mouse(int deviceID)
|
||||
{
|
||||
deviceNum = deviceID;
|
||||
cursor = new MouseCursor(deviceNum);
|
||||
wheel = new MouseWheel(deviceNum);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -25,39 +29,23 @@ namespace DS4Control
|
||||
|
||||
public virtual void touchesMoved(object sender, TouchpadEventArgs arg)
|
||||
{
|
||||
if (arg.touches.Length == 1)
|
||||
{
|
||||
double sensitivity = Global.getTouchSensitivity(deviceNum) / 100.0;
|
||||
int mouseDeltaX = (int)(sensitivity * (arg.touches[0].deltaX));
|
||||
int mouseDeltaY = (int)(sensitivity * (arg.touches[0].deltaY));
|
||||
InputMethods.MoveCursorBy(mouseDeltaX, mouseDeltaY);
|
||||
}
|
||||
else if (arg.touches.Length == 2)
|
||||
{
|
||||
Touch lastT0 = arg.touches[0].previousTouch;
|
||||
Touch lastT1 = arg.touches[1].previousTouch;
|
||||
Touch T0 = arg.touches[0];
|
||||
Touch T1 = arg.touches[1];
|
||||
|
||||
//mouse wheel 120 == 1 wheel click according to Windows API
|
||||
int lastMidX = (lastT0.hwX + lastT1.hwX) / 2, lastMidY = (lastT0.hwY + lastT1.hwY) / 2,
|
||||
currentMidX = (T0.hwX + T1.hwX) / 2, currentMidY = (T0.hwY + T1.hwY) / 2; // XXX Will controller swap touch IDs?
|
||||
double coefficient = Global.getScrollSensitivity(deviceNum);
|
||||
// Adjust for touch distance: "standard" distance is 960 pixels, i.e. half the width. Scroll farther if fingers are farther apart, and vice versa, in linear proportion.
|
||||
double touchXDistance = T1.hwX - T0.hwX, touchYDistance = T1.hwY - T0.hwY, touchDistance = Math.Sqrt(touchXDistance * touchXDistance + touchYDistance * touchYDistance);
|
||||
coefficient *= touchDistance / 960.0;
|
||||
InputMethods.MouseWheel((int)(coefficient * (lastMidY - currentMidY)), (int)(coefficient * (currentMidX - lastMidX)));
|
||||
}
|
||||
cursor.touchesMoved(arg);
|
||||
wheel.touchesMoved(arg);
|
||||
//Log.LogToGui("moved to " + arg.touches[0].hwX + "," + arg.touches[0].hwY);
|
||||
}
|
||||
|
||||
public virtual void touchesBegan(object sender, TouchpadEventArgs arg)
|
||||
{
|
||||
cursor.touchesBegan(arg);
|
||||
wheel.touchesBegan(arg);
|
||||
pastTime = arg.timeStamp;
|
||||
firstTouch = arg.touches[0];
|
||||
//Log.LogToGui("began at " + arg.touches[0].hwX + "," + arg.touches[0].hwY);
|
||||
}
|
||||
|
||||
public virtual void touchesEnded(object sender, TouchpadEventArgs arg)
|
||||
{
|
||||
//Log.LogToGui("ended at " + arg.touches[0].hwX + "," + arg.touches[0].hwY);
|
||||
if (Global.getTapSensitivity(deviceNum) != 0)
|
||||
{
|
||||
DateTime test = arg.timeStamp;
|
||||
@ -111,6 +99,8 @@ namespace DS4Control
|
||||
}
|
||||
}
|
||||
|
||||
public void touchUnchanged(object sender, EventArgs unused) { }
|
||||
|
||||
protected bool mapTouchPad(DS4Controls padControl, bool release = false)
|
||||
{
|
||||
ushort key = Global.getCustomKey(padControl);
|
||||
|
@ -12,8 +12,7 @@ namespace DS4Control
|
||||
public enum DS4KeyType : byte { None = 0, ScanCode = 1, Repeat = 2 }; //Increment by exponents of 2*, starting at 2^0
|
||||
public enum Ds3PadId : byte { None = 0xFF, One = 0x00, Two = 0x01, Three = 0x02, Four = 0x03, All = 0x04 };
|
||||
public enum DS4Controls : byte { LXNeg, LXPos, LYNeg, LYPos, RXNeg, RXPos, RYNeg, RYPos, L1, L2, L3, R1, R2, R3, Square, Triangle, Circle, Cross, DpadUp, DpadRight, DpadDown, DpadLeft, PS, TouchButton, TouchUpper, TouchMulti, Share, Options };
|
||||
public enum X360Controls : byte { LXNeg, LXPos, LYNeg, LYPos, RXNeg, RXPos, RYNeg, RYPos, LB, LT, LS, RB, RT, RS, X, Y, B, A, DpadUp, DpadRight, DpadDown, DpadLeft, Guide, Back, Start, LeftMouse, RightMouse, MiddleMouse, Unbound,
|
||||
MouseLeft, MouseRight, MouseDown, MouseUp};
|
||||
public enum X360Controls : byte { LXNeg, LXPos, LYNeg, LYPos, RXNeg, RXPos, RYNeg, RYPos, LB, LT, LS, RB, RT, RS, X, Y, B, A, DpadUp, DpadRight, DpadDown, DpadLeft, Guide, Back, Start, LeftMouse, RightMouse, MiddleMouse, Unbound };
|
||||
|
||||
public class DebugEventArgs : EventArgs
|
||||
{
|
||||
@ -82,6 +81,13 @@ namespace DS4Control
|
||||
protected static BackingStore m_Config = new BackingStore();
|
||||
protected static Int32 m_IdleTimeout = 600000;
|
||||
|
||||
public static event EventHandler<EventArgs> ControllerStatusChange; // called when a controller is added/removed/battery or touchpad mode changes/etc.
|
||||
public static void ControllerStatusChanged(object sender)
|
||||
{
|
||||
if (ControllerStatusChange != null)
|
||||
ControllerStatusChange(sender, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public static DS4Color loadColor(int device)
|
||||
{
|
||||
DS4Color color = new DS4Color();
|
||||
@ -327,22 +333,12 @@ namespace DS4Control
|
||||
byte bdif = (byte)(bmax - bmin);
|
||||
return (byte)(bmin + (bdif * ratio / 100));
|
||||
}
|
||||
public static DS4Color getTransitionedColor(byte[] c1, byte[] c2, uint ratio)
|
||||
{
|
||||
DS4Color color = new DS4Color();
|
||||
color.red = 255;
|
||||
color.green = 255;
|
||||
color.blue = 255;
|
||||
uint r = ratio % 101;
|
||||
if (c1.Length != 3 || c2.Length != 3 || ratio < 0)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
color.red = applyRatio(c1[0], c2[0], ratio);
|
||||
color.green = applyRatio(c1[1], c2[1], ratio);
|
||||
color.blue = applyRatio(c1[2], c2[2], ratio);
|
||||
|
||||
return color;
|
||||
public static DS4Color getTransitionedColor(DS4Color c1, DS4Color c2, uint ratio)
|
||||
{;
|
||||
c1.red = applyRatio(c1.red, c2.red, ratio);
|
||||
c1.green = applyRatio(c1.green, c2.green, ratio);
|
||||
c1.blue = applyRatio(c1.blue, c2.blue, ratio);
|
||||
return c1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -655,10 +651,6 @@ namespace DS4Control
|
||||
case "Click": return X360Controls.LeftMouse;
|
||||
case "Right Click": return X360Controls.RightMouse;
|
||||
case "Middle Click": return X360Controls.MiddleMouse;
|
||||
case "Mouse Up": return X360Controls.MouseUp;
|
||||
case "Mouse Down": return X360Controls.MouseDown;
|
||||
case "Mouse Left": return X360Controls.MouseLeft;
|
||||
case "Mouse Right": return X360Controls.MouseRight;
|
||||
case "(Unbound)": return X360Controls.Unbound;
|
||||
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ namespace DS4Control
|
||||
device.Touchpad.TouchesBegan -= currentMode.touchesBegan;
|
||||
device.Touchpad.TouchesMoved -= currentMode.touchesMoved;
|
||||
device.Touchpad.TouchesEnded -= currentMode.touchesEnded;
|
||||
device.Touchpad.TouchUnchanged -= currentMode.touchUnchanged;
|
||||
setMode(ind);
|
||||
}
|
||||
|
||||
@ -40,9 +41,11 @@ namespace DS4Control
|
||||
device.Touchpad.TouchesBegan += tmode.touchesBegan;
|
||||
device.Touchpad.TouchesMoved += tmode.touchesMoved;
|
||||
device.Touchpad.TouchesEnded += tmode.touchesEnded;
|
||||
device.Touchpad.TouchUnchanged += tmode.touchUnchanged;
|
||||
currentTypeInd = ind;
|
||||
LogDebug("Touchpad mode for " + device.MacAddress + " is now " + tmode.ToString());
|
||||
Log.LogToTray("Touchpad mode for " + device.MacAddress + " is now " + tmode.ToString());
|
||||
Global.ControllerStatusChanged(this);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
@ -25,6 +25,6 @@ namespace DS4Control
|
||||
|
||||
public void touchButtonDown(object sender, TouchpadEventArgs arg) { }
|
||||
|
||||
public void untouched(object sender, TouchpadEventArgs nullUnused) { }
|
||||
public void touchUnchanged(object sender, EventArgs unused) { }
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,28 @@ namespace DS4Library
|
||||
public byte blue;
|
||||
}
|
||||
|
||||
public enum ConnectionType : byte { USB, BT };
|
||||
public enum ConnectionType : byte { BT, USB }; // Prioritize Bluetooth when both are connected.
|
||||
|
||||
/**
|
||||
* The haptics engine uses a stack of these states representing the light bar and rumble motor settings.
|
||||
* It (will) handle composing them and the details of output report management.
|
||||
*/
|
||||
public struct DS4HapticState
|
||||
{
|
||||
public DS4Color LightBarColor;
|
||||
public bool LightBarExplicitlyOff;
|
||||
public byte LightBarFlashDurationOn, LightBarFlashDurationOff;
|
||||
public byte RumbleMotorStrengthLeftHeavySlow, RumbleMotorStrengthRightLightFast;
|
||||
public bool RumbleMotorsExplicitlyOff;
|
||||
public bool IsLightBarSet()
|
||||
{
|
||||
return LightBarExplicitlyOff || LightBarColor.red != 0 || LightBarColor.green != 0 || LightBarColor.blue != 0;
|
||||
}
|
||||
public bool IsRumbleSet()
|
||||
{
|
||||
return RumbleMotorsExplicitlyOff || RumbleMotorStrengthLeftHeavySlow != 0 || RumbleMotorStrengthRightLightFast != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class DS4Device
|
||||
{
|
||||
@ -36,31 +57,30 @@ namespace DS4Library
|
||||
private ConnectionType conType;
|
||||
private byte[] accel = new byte[6];
|
||||
private byte[] gyro = new byte[6];
|
||||
private byte[] inputReport = new byte[64];
|
||||
private byte[] inputReport;
|
||||
private byte[] btInputReport = null;
|
||||
private byte[] outputReport = null;
|
||||
private byte[] outputReportBuffer, outputReport;
|
||||
private readonly DS4Touchpad touchpad = null;
|
||||
private byte rightLightFastRumble;
|
||||
private byte leftHeavySlowRumble;
|
||||
private DS4Color ligtBarColor;
|
||||
private byte ledFlashOn, ledFlashOff;
|
||||
private bool isDirty = false;
|
||||
private Thread updaterThread = null;
|
||||
private Thread ds4Input, ds4Output;
|
||||
private int battery;
|
||||
private int idleTimeout = 1200;
|
||||
private DateTime lastActive = DateTime.Now;
|
||||
private bool charging;
|
||||
public event EventHandler<EventArgs> Report = null;
|
||||
public event EventHandler<EventArgs> Removal = null;
|
||||
|
||||
public int IdleTimeout { get { return idleTimeout; }
|
||||
set { idleTimeout = value; } }
|
||||
public HidDevice HidDevice { get { return hDevice; } }
|
||||
public bool IsExclusive { get { return HidDevice.IsExclusive; } }
|
||||
public bool IsDisconnecting { get; private set; }
|
||||
|
||||
public string MacAddress { get { return Mac; } }
|
||||
|
||||
public ConnectionType ConnectionType { get { return conType; } }
|
||||
|
||||
public int Battery { get { return battery; } }
|
||||
public bool Charging { get { return charging; } }
|
||||
|
||||
public byte RightLightFastRumble
|
||||
{
|
||||
@ -69,7 +89,6 @@ namespace DS4Library
|
||||
{
|
||||
if (value == rightLightFastRumble) return;
|
||||
rightLightFastRumble = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,7 +99,6 @@ namespace DS4Library
|
||||
{
|
||||
if (value == leftHeavySlowRumble) return;
|
||||
leftHeavySlowRumble = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +110,6 @@ namespace DS4Library
|
||||
if (ligtBarColor.red != value.red || ligtBarColor.green != value.green || ligtBarColor.blue != value.blue)
|
||||
{
|
||||
ligtBarColor = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,7 +122,6 @@ namespace DS4Library
|
||||
if (ledFlashOn != value)
|
||||
{
|
||||
ledFlashOn = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,41 +134,51 @@ namespace DS4Library
|
||||
if (ledFlashOff != value)
|
||||
{
|
||||
ledFlashOff = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DS4Touchpad Touchpad { get { return touchpad; } }
|
||||
|
||||
public static ConnectionType HidConnectionType(HidDevice hidDevice)
|
||||
{
|
||||
return hidDevice.Capabilities.InputReportByteLength == 64 ? ConnectionType.USB : ConnectionType.BT;
|
||||
}
|
||||
|
||||
public DS4Device(HidDevice hidDevice)
|
||||
{
|
||||
hDevice = hidDevice;
|
||||
hDevice.MonitorDeviceEvents = true;
|
||||
conType = hDevice.Capabilities.InputReportByteLength == 64 ? ConnectionType.USB : ConnectionType.BT;
|
||||
conType = HidConnectionType(hDevice);
|
||||
Mac = hDevice.readSerial();
|
||||
if (conType == ConnectionType.USB)
|
||||
{
|
||||
inputReport = new byte[64];
|
||||
outputReport = new byte[hDevice.Capabilities.OutputReportByteLength];
|
||||
outputReportBuffer = new byte[hDevice.Capabilities.OutputReportByteLength];
|
||||
}
|
||||
else
|
||||
{
|
||||
btInputReport = new byte[BT_INPUT_REPORT_LENGTH];
|
||||
inputReport = new byte[btInputReport.Length - 2];
|
||||
outputReport = new byte[BT_OUTPUT_REPORT_LENGTH];
|
||||
outputReportBuffer = new byte[BT_OUTPUT_REPORT_LENGTH];
|
||||
}
|
||||
touchpad = new DS4Touchpad();
|
||||
isDirty = true;
|
||||
sendOutputReport();
|
||||
}
|
||||
|
||||
public void StartUpdate()
|
||||
{
|
||||
if (updaterThread == null)
|
||||
if (ds4Input == null)
|
||||
{
|
||||
updaterThread = new Thread(updateCurrentState);
|
||||
updaterThread.Name = "DS4 Update thread :" + Mac;
|
||||
Console.WriteLine(updaterThread.Name + " has started");
|
||||
updaterThread.Start();
|
||||
Console.WriteLine(MacAddress.ToString() + " " + System.DateTime.UtcNow.ToString("o") + "> start");
|
||||
sendOutputReport(true); // request the particular kind of input report we want
|
||||
ds4Output = new Thread(performDs4Output);
|
||||
ds4Output.Name = "DS4 Output thread: " + Mac;
|
||||
ds4Output.Start();
|
||||
ds4Input = new Thread(performDs4Input);
|
||||
ds4Input.Name = "DS4 Input thread: " + Mac;
|
||||
ds4Input.Start();
|
||||
}
|
||||
else
|
||||
Console.WriteLine("Thread already running for DS4: " + Mac);
|
||||
@ -160,12 +186,29 @@ namespace DS4Library
|
||||
|
||||
public void StopUpdate()
|
||||
{
|
||||
if (updaterThread.ThreadState != System.Threading.ThreadState.Stopped || updaterThread.ThreadState != System.Threading.ThreadState.Aborted)
|
||||
if (ds4Input.ThreadState != System.Threading.ThreadState.Stopped || ds4Input.ThreadState != System.Threading.ThreadState.Aborted)
|
||||
{
|
||||
try
|
||||
{
|
||||
updaterThread.Abort();
|
||||
updaterThread = null;
|
||||
ds4Input.Abort();
|
||||
ds4Input.Join();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
}
|
||||
}
|
||||
StopOutputUpdate();
|
||||
}
|
||||
|
||||
private void StopOutputUpdate()
|
||||
{
|
||||
if (ds4Output.ThreadState != System.Threading.ThreadState.Stopped || ds4Output.ThreadState != System.Threading.ThreadState.Aborted)
|
||||
{
|
||||
try
|
||||
{
|
||||
ds4Output.Abort();
|
||||
ds4Output.Join();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -174,28 +217,61 @@ namespace DS4Library
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCurrentState()
|
||||
private bool writeOutput()
|
||||
{
|
||||
if (conType == ConnectionType.BT)
|
||||
{
|
||||
return hDevice.WriteOutputReportViaControl(outputReport);
|
||||
}
|
||||
else
|
||||
{
|
||||
return hDevice.WriteOutputReportViaInterrupt(outputReport, 8);
|
||||
}
|
||||
}
|
||||
|
||||
private void performDs4Output()
|
||||
{
|
||||
lock (outputReport)
|
||||
{
|
||||
while (writeOutput())
|
||||
{
|
||||
if (testRumble.IsRumbleSet()) // repeat test rumbles periodically; rumble has auto-shut-off in the DS4 firmware
|
||||
Monitor.Wait(outputReport, 10000); // DS4 firmware stops it after 5 seconds, so let the motors rest for that long, too.
|
||||
else
|
||||
Monitor.Wait(outputReport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Is the device alive and receiving valid sensor input reports? */
|
||||
public bool IsAlive()
|
||||
{
|
||||
return priorInputReport30 != 0xff;
|
||||
}
|
||||
private byte priorInputReport30 = 0xff;
|
||||
private void performDs4Input()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (conType != ConnectionType.USB)
|
||||
if (hDevice.ReadFile(btInputReport) == HidDevice.ReadStatus.Success)
|
||||
{
|
||||
Array.Copy(btInputReport, 2, inputReport, 0, 64);
|
||||
Array.Copy(btInputReport, 2, inputReport, 0, inputReport.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
isDirty = true;
|
||||
sendOutputReport(); // not sure why but without this Windows
|
||||
//will not mark timed out controller as disonnected
|
||||
if (Removal != null)
|
||||
Console.WriteLine(MacAddress.ToString() + " " + System.DateTime.UtcNow.ToString("o") + "> disconnect");
|
||||
sendOutputReport(true); // Kick Windows into noticing the disconnection.
|
||||
StopOutputUpdate();
|
||||
if (!IsDisconnecting && Removal != null)
|
||||
Removal(this, EventArgs.Empty);
|
||||
return;
|
||||
|
||||
}
|
||||
else if (hDevice.ReadFile(inputReport) != HidDevice.ReadStatus.Success)
|
||||
{
|
||||
if (Removal != null)
|
||||
StopOutputUpdate();
|
||||
if (!IsDisconnecting && Removal != null)
|
||||
Removal(this, EventArgs.Empty);
|
||||
return;
|
||||
}
|
||||
@ -204,11 +280,11 @@ namespace DS4Library
|
||||
//Received incorrect report, skip it
|
||||
continue;
|
||||
}
|
||||
|
||||
lock (cState)
|
||||
{
|
||||
DateTime utcNow = System.DateTime.UtcNow; // timestamp with UTC in case system time zone changes
|
||||
resetHapticState();
|
||||
if (cState == null)
|
||||
cState = new DS4State();
|
||||
cState.ReportTimeStamp = utcNow;
|
||||
cState.LX = inputReport[1];
|
||||
cState.LY = inputReport[2];
|
||||
cState.RX = inputReport[3];
|
||||
@ -256,95 +332,110 @@ namespace DS4Library
|
||||
|
||||
cState.PS = ((byte)inputReport[7] & (1 << 0)) != 0;
|
||||
cState.TouchButton = (inputReport[7] & (1 << 2 - 1)) != 0;
|
||||
cState.FrameCounter = (byte)(inputReport[7] >> 2);
|
||||
|
||||
// Store Gyro and Accel values
|
||||
Array.Copy(inputReport, 14, accel, 0, 6);
|
||||
Array.Copy(inputReport, 20, gyro, 0, 6);
|
||||
|
||||
int charge = 0;
|
||||
if (conType == ConnectionType.USB)
|
||||
charging = (inputReport[30] & 0x10) != 0;
|
||||
battery = (inputReport[30] & 0x0f) * 10;
|
||||
cState.Battery = (byte)battery;
|
||||
if (inputReport[30] != priorInputReport30)
|
||||
{
|
||||
charge = (inputReport[30] - 16) * 10;
|
||||
if (charge > 100)
|
||||
charge = 100;
|
||||
priorInputReport30 = inputReport[30];
|
||||
Console.WriteLine(MacAddress.ToString() + " " + System.DateTime.UtcNow.ToString("o") + "> power subsystem octet: 0x" + inputReport[30].ToString("x02"));
|
||||
}
|
||||
else
|
||||
|
||||
// XXX DS4State mapping needs fixup, turn touches into an array[4] of structs. And include the touchpad details there instead.
|
||||
for (int touches = inputReport[-1 + DS4Touchpad.TOUCHPAD_DATA_OFFSET - 1], touchOffset = 0; touches > 0; touches--, touchOffset += 9)
|
||||
{
|
||||
charge = (inputReport[30] + 1) * 10;
|
||||
if (charge > 100)
|
||||
charge = 100;
|
||||
cState.TouchPacketCounter = inputReport[-1 + DS4Touchpad.TOUCHPAD_DATA_OFFSET + touchOffset];
|
||||
cState.Touch1 = (inputReport[0 + DS4Touchpad.TOUCHPAD_DATA_OFFSET + touchOffset] >> 7) != 0 ? false : true; // >= 1 touch detected
|
||||
cState.Touch1Identifier = (byte)(inputReport[0 + DS4Touchpad.TOUCHPAD_DATA_OFFSET + touchOffset] & 0x7f);
|
||||
cState.Touch2 = (inputReport[4 + DS4Touchpad.TOUCHPAD_DATA_OFFSET + touchOffset] >> 7) != 0 ? false : true; // 2 touches detected
|
||||
cState.Touch2Identifier = (byte)(inputReport[4 + DS4Touchpad.TOUCHPAD_DATA_OFFSET + touchOffset] & 0x7f);
|
||||
// Even when idling there is still a touch packet indicating no touch 1 or 2
|
||||
touchpad.handleTouchpad(inputReport, cState, touchOffset);
|
||||
}
|
||||
|
||||
cState.Battery = charge;
|
||||
battery = charge;
|
||||
|
||||
cState.Touch1 = (inputReport[0 + DS4Touchpad.TOUCHPAD_DATA_OFFSET] >> 7) != 0 ? false : true; // >= 1 touch detected
|
||||
cState.Touch2 = (inputReport[4 + DS4Touchpad.TOUCHPAD_DATA_OFFSET] >> 7) != 0 ? false : true; // 2 touches detected
|
||||
|
||||
cState.ReportTimeStamp = DateTime.UtcNow;
|
||||
}
|
||||
if (ConnectionType == ConnectionType.BT && !isIdle(cState))
|
||||
/* Debug output of incoming HID data:
|
||||
if (cState.L2 == 0xff && cState.R2 == 0xff)
|
||||
{
|
||||
lastActive = DateTime.Now;
|
||||
}
|
||||
if (ConnectionType == ConnectionType.BT && lastActive + TimeSpan.FromSeconds(idleTimeout) < DateTime.Now)
|
||||
Console.Write(MacAddress.ToString() + " " + System.DateTime.UtcNow.ToString("o") + ">");
|
||||
for (int i = 0; i < inputReport.Length; i++)
|
||||
Console.Write(" " + inputReport[i].ToString("x2"));
|
||||
Console.WriteLine();
|
||||
} */
|
||||
|
||||
if (conType == ConnectionType.BT && (!pState.PS || !pState.Options) && cState.PS && cState.Options)
|
||||
{
|
||||
DisconnectBT();
|
||||
}
|
||||
|
||||
touchpad.handleTouchpad(inputReport, cState);
|
||||
|
||||
sendOutputReport();
|
||||
|
||||
if ((!pState.PS || !pState.Options) && cState.PS && cState.Options)
|
||||
{
|
||||
DisconnectBT();
|
||||
if (DisconnectBT())
|
||||
return; // all done
|
||||
}
|
||||
// XXX fix initialization ordering so the null checks all go away
|
||||
if (Report != null)
|
||||
Report(this, EventArgs.Empty);
|
||||
lock (pState)
|
||||
{
|
||||
sendOutputReport(false);
|
||||
|
||||
if (pState == null)
|
||||
pState = new DS4State();
|
||||
cState.Copy(pState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendOutputReport()
|
||||
{
|
||||
if (isDirty)
|
||||
private void sendOutputReport(bool synchronous)
|
||||
{
|
||||
setTestRumble();
|
||||
setHapticState();
|
||||
if (conType == ConnectionType.BT)
|
||||
{
|
||||
outputReport[0] = 0x11;
|
||||
outputReport[1] = 128;
|
||||
outputReport[3] = 0xff;
|
||||
outputReport[6] = rightLightFastRumble; //fast motor
|
||||
outputReport[7] = leftHeavySlowRumble; //slow motor
|
||||
outputReport[8] = LightBarColor.red; //red
|
||||
outputReport[9] = LightBarColor.green; //green
|
||||
outputReport[10] = LightBarColor.blue; //blue
|
||||
outputReport[11] = ledFlashOn; //flash on duration
|
||||
outputReport[12] = ledFlashOff; //flash off duration
|
||||
|
||||
if (hDevice.WriteOutputReportViaControl(outputReport))
|
||||
isDirty = false;
|
||||
outputReportBuffer[0] = 0x11;
|
||||
outputReportBuffer[1] = 0x80;
|
||||
outputReportBuffer[3] = 0xff;
|
||||
outputReportBuffer[6] = rightLightFastRumble; //fast motor
|
||||
outputReportBuffer[7] = leftHeavySlowRumble; //slow motor
|
||||
outputReportBuffer[8] = LightBarColor.red; //red
|
||||
outputReportBuffer[9] = LightBarColor.green; //green
|
||||
outputReportBuffer[10] = LightBarColor.blue; //blue
|
||||
outputReportBuffer[11] = ledFlashOn; //flash on duration
|
||||
outputReportBuffer[12] = ledFlashOff; //flash off duration
|
||||
}
|
||||
else
|
||||
{
|
||||
outputReport[0] = 0x5;
|
||||
outputReport[1] = 0xFF;
|
||||
outputReport[4] = rightLightFastRumble; //fast motor
|
||||
outputReport[5] = leftHeavySlowRumble; //slow motor
|
||||
outputReport[6] = LightBarColor.red; //red
|
||||
outputReport[7] = LightBarColor.green; //green
|
||||
outputReport[8] = LightBarColor.blue; //blue
|
||||
outputReport[9] = ledFlashOn; //flash on duration
|
||||
outputReport[10] = ledFlashOff; //flash off duration
|
||||
if (hDevice.WriteOutputReportViaInterrupt(outputReport))
|
||||
outputReportBuffer[0] = 0x05;
|
||||
outputReportBuffer[1] = 0xff;
|
||||
outputReportBuffer[4] = rightLightFastRumble; //fast motor
|
||||
outputReportBuffer[5] = leftHeavySlowRumble; //slow motor
|
||||
outputReportBuffer[6] = LightBarColor.red; //red
|
||||
outputReportBuffer[7] = LightBarColor.green; //green
|
||||
outputReportBuffer[8] = LightBarColor.blue; //blue
|
||||
outputReportBuffer[9] = ledFlashOn; //flash on duration
|
||||
outputReportBuffer[10] = ledFlashOff; //flash off duration
|
||||
}
|
||||
lock (outputReport)
|
||||
{
|
||||
isDirty = false;
|
||||
if (synchronous)
|
||||
{
|
||||
outputReportBuffer.CopyTo(outputReport, 0);
|
||||
try
|
||||
{
|
||||
writeOutput();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If it's dead already, don't worry about it.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool output = false;
|
||||
for (int i = 0; !output && i < outputReport.Length; i++)
|
||||
output = outputReport[i] != outputReportBuffer[i];
|
||||
if (output)
|
||||
{
|
||||
outputReportBuffer.CopyTo(outputReport, 0);
|
||||
Monitor.Pulse(outputReport);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -367,7 +458,6 @@ namespace DS4Library
|
||||
}
|
||||
long lbtAddr = BitConverter.ToInt64(btAddr, 0);
|
||||
|
||||
|
||||
NativeMethods.BLUETOOTH_FIND_RADIO_PARAMS p = new NativeMethods.BLUETOOTH_FIND_RADIO_PARAMS();
|
||||
p.dwSize = Marshal.SizeOf(typeof(NativeMethods.BLUETOOTH_FIND_RADIO_PARAMS));
|
||||
IntPtr searchHandle = NativeMethods.BluetoothFindFirstRadio(ref p, ref btHandle);
|
||||
@ -383,53 +473,47 @@ namespace DS4Library
|
||||
|
||||
}
|
||||
NativeMethods.BluetoothFindRadioClose(searchHandle);
|
||||
Console.WriteLine("Disconnect successul: " + success);
|
||||
Console.WriteLine("Disconnect successful: " + success);
|
||||
success = true; // XXX return value indicates failure, but it still works?
|
||||
if(success)
|
||||
{
|
||||
IsDisconnecting = true;
|
||||
StopOutputUpdate();
|
||||
if (Removal != null)
|
||||
Removal(this, EventArgs.Empty);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setLightbarColor(byte red, byte green, byte blue)
|
||||
{
|
||||
if (red != ligtBarColor.red || green != ligtBarColor.green || blue != ligtBarColor.blue)
|
||||
{
|
||||
isDirty = true;
|
||||
ligtBarColor.red = red;
|
||||
ligtBarColor.green = green;
|
||||
ligtBarColor.blue = blue;
|
||||
}
|
||||
}
|
||||
|
||||
public void setLightbarDuration(byte onDuration, byte offDuration)
|
||||
{
|
||||
LightBarOffDuration = offDuration;
|
||||
LightBarOnDuration = onDuration;
|
||||
}
|
||||
|
||||
private DS4HapticState testRumble = new DS4HapticState();
|
||||
public void setRumble(byte rightLightFastMotor, byte leftHeavySlowMotor)
|
||||
{
|
||||
RightLightFastRumble = rightLightFastMotor;
|
||||
LeftHeavySlowRumble = leftHeavySlowMotor;
|
||||
testRumble.RumbleMotorStrengthRightLightFast = rightLightFastMotor;
|
||||
testRumble.RumbleMotorStrengthLeftHeavySlow = leftHeavySlowMotor;
|
||||
testRumble.RumbleMotorsExplicitlyOff = rightLightFastMotor == 0 && leftHeavySlowMotor == 0;
|
||||
}
|
||||
|
||||
private void setTestRumble()
|
||||
{
|
||||
if (testRumble.IsRumbleSet())
|
||||
{
|
||||
pushHapticState(testRumble);
|
||||
if (testRumble.RumbleMotorsExplicitlyOff)
|
||||
testRumble.RumbleMotorsExplicitlyOff = false;
|
||||
}
|
||||
}
|
||||
|
||||
public DS4State getCurrentState()
|
||||
{
|
||||
lock (cState)
|
||||
{
|
||||
return cState.Clone();
|
||||
}
|
||||
}
|
||||
|
||||
public DS4State getPreviousState()
|
||||
{
|
||||
lock (pState)
|
||||
{
|
||||
return pState.Clone();
|
||||
}
|
||||
}
|
||||
|
||||
public void getExposedState(DS4StateExposed expState, DS4State state)
|
||||
{
|
||||
@ -439,38 +523,61 @@ namespace DS4Library
|
||||
}
|
||||
|
||||
public void getCurrentState(DS4State state)
|
||||
{
|
||||
lock (cState)
|
||||
{
|
||||
cState.Copy(state);
|
||||
}
|
||||
}
|
||||
|
||||
public void getPreviousState(DS4State state)
|
||||
{
|
||||
lock (pState)
|
||||
{
|
||||
pState.Copy(state);
|
||||
}
|
||||
|
||||
private DS4HapticState[] hapticState = new DS4HapticState[1];
|
||||
private int hapticStackIndex = 0;
|
||||
private void resetHapticState()
|
||||
{
|
||||
hapticStackIndex = 0;
|
||||
}
|
||||
|
||||
private bool isIdle(DS4State cState)
|
||||
// Use the "most recently set" haptic state for each of light bar/motor.
|
||||
private void setHapticState()
|
||||
{
|
||||
if (cState.Square || cState.Cross || cState.Circle || cState.Triangle)
|
||||
return false;
|
||||
if (cState.DpadUp || cState.DpadLeft || cState.DpadDown || cState.DpadRight)
|
||||
return false;
|
||||
if (cState.L3 || cState.R3 || cState.L1 || cState.R1 || cState.Share || cState.Options)
|
||||
return false;
|
||||
if (cState.L2 != 0 || cState.R2 != 0)
|
||||
return false;
|
||||
if (Math.Abs(cState.LX - 127) > 10 || (Math.Abs(cState.LY - 127) > 10 ))
|
||||
return false;
|
||||
if (Math.Abs(cState.RX - 127) > 10 || (Math.Abs(cState.RY - 127) > 10))
|
||||
return false;
|
||||
if (cState.Touch1 || cState.Touch2 || cState.TouchButton)
|
||||
return false;
|
||||
return true;
|
||||
int i = 0;
|
||||
DS4Color lightBarColor = LightBarColor;
|
||||
byte lightBarFlashDurationOn = LightBarOnDuration, lightBarFlashDurationOff = LightBarOffDuration;
|
||||
byte rumbleMotorStrengthLeftHeavySlow = LeftHeavySlowRumble, rumbleMotorStrengthRightLightFast = rightLightFastRumble;
|
||||
foreach (DS4HapticState haptic in hapticState)
|
||||
{
|
||||
if (i++ == hapticStackIndex)
|
||||
break; // rest haven't been used this time
|
||||
if (haptic.IsLightBarSet())
|
||||
{
|
||||
lightBarColor = haptic.LightBarColor;
|
||||
lightBarFlashDurationOn = haptic.LightBarFlashDurationOn;
|
||||
lightBarFlashDurationOff = haptic.LightBarFlashDurationOff;
|
||||
}
|
||||
if (haptic.IsRumbleSet())
|
||||
{
|
||||
rumbleMotorStrengthLeftHeavySlow = haptic.RumbleMotorStrengthLeftHeavySlow;
|
||||
rumbleMotorStrengthRightLightFast = haptic.RumbleMotorStrengthRightLightFast;
|
||||
}
|
||||
}
|
||||
LightBarColor = lightBarColor;
|
||||
LightBarOnDuration = lightBarFlashDurationOn;
|
||||
LightBarOffDuration = lightBarFlashDurationOff;
|
||||
LeftHeavySlowRumble = rumbleMotorStrengthLeftHeavySlow;
|
||||
RightLightFastRumble = rumbleMotorStrengthRightLightFast;
|
||||
}
|
||||
|
||||
public void pushHapticState(DS4HapticState hs)
|
||||
{
|
||||
if (hapticStackIndex == hapticState.Length)
|
||||
{
|
||||
DS4HapticState[] newHaptics = new DS4HapticState[hapticState.Length + 1];
|
||||
Array.Copy(hapticState, newHaptics, hapticState.Length);
|
||||
hapticState = newHaptics;
|
||||
}
|
||||
hapticState[hapticStackIndex++] = hs;
|
||||
}
|
||||
|
||||
override
|
||||
|
@ -8,6 +8,7 @@ namespace DS4Library
|
||||
public class DS4Devices
|
||||
{
|
||||
private static Dictionary<string, DS4Device> Devices = new Dictionary<string, DS4Device>();
|
||||
private static HashSet<String> DevicePaths = new HashSet<String>();
|
||||
public static bool isExclusiveMode = false;
|
||||
|
||||
//enumerates ds4 controllers in the system
|
||||
@ -17,30 +18,33 @@ namespace DS4Library
|
||||
{
|
||||
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)
|
||||
{
|
||||
byte[] buffer = new byte[38];
|
||||
buffer[0] = 0x2;
|
||||
hDevice.readFeatureData(buffer);
|
||||
if (Devices.ContainsKey(hDevice.readSerial()))
|
||||
continue;
|
||||
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.StartUpdate();
|
||||
ds4Device.Removal += On_Removal;
|
||||
Devices.Add(ds4Device.MacAddress, ds4Device);
|
||||
DevicePaths.Add(hDevice.DevicePath);
|
||||
ds4Device.StartUpdate();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("ERROR: Can't open DS4 Controller. Try quitting other applications like Steam, Uplay, etc.)");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -49,6 +53,8 @@ namespace DS4Library
|
||||
//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)
|
||||
{
|
||||
lock (Devices)
|
||||
{
|
||||
DS4Device device = null;
|
||||
try
|
||||
@ -58,14 +64,22 @@ namespace DS4Library
|
||||
catch (ArgumentNullException) { }
|
||||
return device;
|
||||
}
|
||||
}
|
||||
|
||||
//returns DS4 controllers that were found and are running
|
||||
public static IEnumerable<DS4Device> getDS4Controllers()
|
||||
{
|
||||
return Devices.Values;
|
||||
lock (Devices)
|
||||
{
|
||||
DS4Device[] controllers = new DS4Device[Devices.Count];
|
||||
Devices.Values.CopyTo(controllers, 0);
|
||||
return controllers;
|
||||
}
|
||||
}
|
||||
|
||||
public static void stopControllers()
|
||||
{
|
||||
lock (Devices)
|
||||
{
|
||||
IEnumerable<DS4Device> devices = getDS4Controllers();
|
||||
foreach (DS4Device device in devices)
|
||||
@ -74,6 +88,8 @@ namespace DS4Library
|
||||
device.HidDevice.CloseDevice();
|
||||
}
|
||||
Devices.Clear();
|
||||
DevicePaths.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
//called when devices is diconnected, timed out or has input reading failure
|
||||
@ -84,6 +100,7 @@ namespace DS4Library
|
||||
DS4Device device = (DS4Device)sender;
|
||||
device.HidDevice.CloseDevice();
|
||||
Devices.Remove(device.MacAddress);
|
||||
DevicePaths.Remove(device.HidDevice.DevicePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,27 +7,33 @@ namespace DS4Library
|
||||
{
|
||||
public class DS4State
|
||||
{
|
||||
public DateTime ReportTimeStamp;
|
||||
public bool Square, Triangle, Circle, Cross;
|
||||
public bool DpadUp, DpadDown, DpadLeft, DpadRight;
|
||||
public bool L1, L3, R1, R3;
|
||||
public bool Share, Options, PS, Touch1, Touch2, TouchButton;
|
||||
public byte Touch1Identifier, Touch2Identifier;
|
||||
public byte LX, RX, LY, RY, L2, R2;
|
||||
public int Battery;
|
||||
public DateTime ReportTimeStamp;
|
||||
public byte FrameCounter; // 0, 1, 2...62, 63, 0....
|
||||
public byte TouchPacketCounter; // we break these out automatically
|
||||
public byte Battery; // 0 for charging, 10/20/30/40/50/60/70/80/90/100 for percentage of full
|
||||
|
||||
public DS4State()
|
||||
{
|
||||
ReportTimeStamp = DateTime.UtcNow;
|
||||
Square = Triangle = Circle = Cross = false;
|
||||
DpadUp = DpadDown = DpadLeft = DpadRight = false;
|
||||
L1 = L3 = R1 = R3 = false;
|
||||
Share = Options = PS = Touch1 = Touch2 = TouchButton = false;
|
||||
LX = RX = LY = RY = 127;
|
||||
L2 = R2 = 0;
|
||||
FrameCounter = 255; // only actually has 6 bits, so this is a null indicator
|
||||
TouchPacketCounter = 255; // 8 bits, no great junk value
|
||||
Battery = 0;
|
||||
}
|
||||
|
||||
public DS4State(DS4State state)
|
||||
{
|
||||
ReportTimeStamp = state.ReportTimeStamp;
|
||||
Square = state.Square;
|
||||
Triangle = state.Triangle;
|
||||
Circle = state.Circle;
|
||||
@ -46,14 +52,17 @@ namespace DS4Library
|
||||
Options = state.Options;
|
||||
PS = state.PS;
|
||||
Touch1 = state.Touch1;
|
||||
Touch1Identifier = state.Touch1Identifier;
|
||||
Touch2 = state.Touch2;
|
||||
Touch2Identifier = state.Touch2Identifier;
|
||||
TouchButton = state.TouchButton;
|
||||
TouchPacketCounter = state.TouchPacketCounter;
|
||||
LX = state.LX;
|
||||
RX = state.RX;
|
||||
LY = state.LY;
|
||||
RY = state.RY;
|
||||
FrameCounter = state.FrameCounter;
|
||||
Battery = state.Battery;
|
||||
ReportTimeStamp = state.ReportTimeStamp;
|
||||
}
|
||||
|
||||
public DS4State Clone()
|
||||
@ -63,6 +72,7 @@ namespace DS4Library
|
||||
|
||||
public void Copy(DS4State state)
|
||||
{
|
||||
state.ReportTimeStamp = ReportTimeStamp;
|
||||
state.Square = Square;
|
||||
state.Triangle = Triangle;
|
||||
state.Circle = Circle;
|
||||
@ -81,14 +91,17 @@ namespace DS4Library
|
||||
state.Options = Options;
|
||||
state.PS = PS;
|
||||
state.Touch1 = Touch1;
|
||||
state.Touch1Identifier = Touch1Identifier;
|
||||
state.Touch2 = Touch2;
|
||||
state.Touch2Identifier = Touch2Identifier;
|
||||
state.TouchButton = TouchButton;
|
||||
state.TouchPacketCounter = TouchPacketCounter;
|
||||
state.LX = LX;
|
||||
state.RX = RX;
|
||||
state.LY = LY;
|
||||
state.RY = RY;
|
||||
state.FrameCounter = FrameCounter;
|
||||
state.Battery = Battery;
|
||||
state.ReportTimeStamp = ReportTimeStamp;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -53,21 +53,21 @@ namespace DS4Library
|
||||
|
||||
/// <summary> Pitch upward/backward </summary>
|
||||
/// <remarks> Add double the previous result to this delta and divide by three.</remarks>
|
||||
public int AccelX { get { return (UInt16)(accel[0] << 8) | accel[1]; } }
|
||||
public int AccelX { get { return (Int16)((UInt16)(accel[0] << 8) | accel[1]); } }
|
||||
/// <summary> Yaw leftward/counter-clockwise/turn to port or larboard side </summary>
|
||||
/// <remarks> Add double the previous result to this delta and divide by three.</remarks>
|
||||
public int AccelY { get { return (UInt16)(accel[2] << 8) | accel[3]; } }
|
||||
public int AccelY { get { return (Int16)((UInt16)(accel[2] << 8) | accel[3]); } }
|
||||
/// <summary> roll left/L side of controller down/starboard raising up </summary>
|
||||
/// <remarks> Add double the previous result to this delta and divide by three.</remarks>
|
||||
public int AccelZ { get { return (UInt16)(accel[4] << 8) | accel[5]; } }
|
||||
public int AccelZ { get { return (Int16)((UInt16)(accel[4] << 8) | accel[5]); } }
|
||||
/// <summary> R side of controller upward </summary>
|
||||
/// <remarks> Add double the previous result to this delta and divide by three.</remarks>
|
||||
public int GyroX { get { return (UInt16)(gyro[0] << 8) | gyro[1]; } }
|
||||
public int GyroX { get { return (Int16)((UInt16)(gyro[0] << 8) | gyro[1]); } }
|
||||
/// <summary> touchpad and button face side of controller upward </summary>
|
||||
/// <remarks> Add double the previous result to this delta and divide by three.</remarks>
|
||||
public int GyroY { get { return (UInt16)(gyro[2] << 8) | gyro[3]; } }
|
||||
public int GyroY { get { return (Int16)((UInt16)(gyro[2] << 8) | gyro[3]); } }
|
||||
/// <summary> Audio/expansion ports upward and light bar/shoulders/bumpers/USB port downward </summary>
|
||||
/// <remarks> Add double the previous result to this delta and divide by three.</remarks>
|
||||
public int GyroZ { get { return (UInt16)(gyro[4] << 8) | gyro[5]; } }
|
||||
public int GyroZ { get { return (Int16)((UInt16)(gyro[4] << 8) | gyro[5]); } }
|
||||
}
|
||||
}
|
||||
|
@ -8,11 +8,10 @@ namespace DS4Library
|
||||
public class TouchpadEventArgs : EventArgs
|
||||
{
|
||||
public readonly Touch[] touches = null;
|
||||
public readonly System.DateTime timeStamp;
|
||||
public readonly bool touchButtonPressed;
|
||||
public readonly DateTime timeStamp;
|
||||
public TouchpadEventArgs(DateTime timeStamp, bool tButtonDown, Touch t0, Touch t1 = null)
|
||||
public TouchpadEventArgs(System.DateTime utcTimestamp, bool tButtonDown, Touch t0, Touch t1 = null)
|
||||
{
|
||||
this.timeStamp = timeStamp;
|
||||
if (t1 != null)
|
||||
{
|
||||
touches = new Touch[2];
|
||||
@ -25,6 +24,7 @@ namespace DS4Library
|
||||
touches[0] = t0;
|
||||
}
|
||||
touchButtonPressed = tButtonDown;
|
||||
this.timeStamp = utcTimestamp;
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,128 +49,161 @@ namespace DS4Library
|
||||
|
||||
public class DS4Touchpad
|
||||
{
|
||||
public event EventHandler<TouchpadEventArgs> TouchesBegan = null;
|
||||
public event EventHandler<TouchpadEventArgs> TouchesMoved = null;
|
||||
public event EventHandler<TouchpadEventArgs> TouchesEnded = null;
|
||||
public event EventHandler<TouchpadEventArgs> TouchButtonDown = null;
|
||||
public event EventHandler<TouchpadEventArgs> TouchButtonUp = null;
|
||||
public readonly static int TOUCHPAD_DATA_OFFSET = 35;
|
||||
internal static int lastTouchPadX, lastTouchPadY,
|
||||
lastTouchPadX2, lastTouchPadY2; // tracks 0, 1 or 2 touches; we maintain touch 1 and 2 separately
|
||||
internal static bool lastTouchPadIsDown;
|
||||
internal static bool lastIsActive;
|
||||
internal static bool lastIsActive2;
|
||||
internal static byte lastTouchID, lastTouchID2;
|
||||
public event EventHandler<TouchpadEventArgs> TouchesBegan = null; // finger one or two landed (or both, or one then two, or two then one; any touches[] count increase)
|
||||
public event EventHandler<TouchpadEventArgs> TouchesMoved = null; // deltaX/deltaY are set because one or both fingers were already down on a prior sensor reading
|
||||
public event EventHandler<TouchpadEventArgs> TouchesEnded = null; // all fingers lifted
|
||||
public event EventHandler<TouchpadEventArgs> TouchButtonDown = null; // touchpad pushed down until the button clicks
|
||||
public event EventHandler<TouchpadEventArgs> TouchButtonUp = null; // touchpad button released
|
||||
public event EventHandler<EventArgs> TouchUnchanged = null; // no status change for the touchpad itself... but other sensors may have changed, or you may just want to do some processing
|
||||
|
||||
public void handleTouchpad(byte[] data, DS4State sensors)
|
||||
public readonly static int TOUCHPAD_DATA_OFFSET = 35;
|
||||
internal int lastTouchPadX1, lastTouchPadY1,
|
||||
lastTouchPadX2, lastTouchPadY2; // tracks 0, 1 or 2 touches; we maintain touch 1 and 2 separately
|
||||
internal bool lastTouchPadIsDown;
|
||||
internal bool lastIsActive1, lastIsActive2;
|
||||
internal byte lastTouchID1, lastTouchID2;
|
||||
internal byte[] previousPacket = new byte[8];
|
||||
|
||||
// We check everything other than the not bothering with not-very-useful TouchPacketCounter.
|
||||
private bool PacketChanged(byte[] data, int touchPacketOffset)
|
||||
{
|
||||
bool changed = false;
|
||||
for (int i = 0; i < previousPacket.Length; i++)
|
||||
{
|
||||
byte oldValue = previousPacket[i];
|
||||
previousPacket[i] = data[i + TOUCHPAD_DATA_OFFSET + touchPacketOffset];
|
||||
if (previousPacket[i] != oldValue)
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
public void handleTouchpad(byte[] data, DS4State sensors, int touchPacketOffset = 0)
|
||||
{
|
||||
bool touchPadIsDown = sensors.TouchButton;
|
||||
byte touchID = (byte)(data[0 + TOUCHPAD_DATA_OFFSET] & 0x7F);
|
||||
byte touchID2 = (byte)(data[4 + TOUCHPAD_DATA_OFFSET] & 0x7F);
|
||||
int currentX = data[1 + TOUCHPAD_DATA_OFFSET] + ((data[2 + TOUCHPAD_DATA_OFFSET] & 0xF) * 255);
|
||||
int currentY = ((data[2 + TOUCHPAD_DATA_OFFSET] & 0xF0) >> 4) + (data[3 + TOUCHPAD_DATA_OFFSET] * 16);
|
||||
int currentX2 = data[5 + TOUCHPAD_DATA_OFFSET] + ((data[6 + TOUCHPAD_DATA_OFFSET] & 0xF) * 255);
|
||||
int currentY2 = ((data[6 + TOUCHPAD_DATA_OFFSET] & 0xF0) >> 4) + (data[7 + TOUCHPAD_DATA_OFFSET] * 16);
|
||||
if (!PacketChanged(data, touchPacketOffset) && touchPadIsDown == lastTouchPadIsDown)
|
||||
{
|
||||
if (TouchUnchanged != null)
|
||||
TouchUnchanged(this, EventArgs.Empty);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sensors.Touch1)
|
||||
byte touchID1 = (byte)(data[0 + TOUCHPAD_DATA_OFFSET + touchPacketOffset] & 0x7F);
|
||||
byte touchID2 = (byte)(data[4 + TOUCHPAD_DATA_OFFSET + touchPacketOffset] & 0x7F);
|
||||
int currentX1 = data[1 + TOUCHPAD_DATA_OFFSET + touchPacketOffset] + ((data[2 + TOUCHPAD_DATA_OFFSET + touchPacketOffset] & 0xF) * 255);
|
||||
int currentY1 = ((data[2 + TOUCHPAD_DATA_OFFSET + touchPacketOffset] & 0xF0) >> 4) + (data[3 + TOUCHPAD_DATA_OFFSET + touchPacketOffset] * 16);
|
||||
int currentX2 = data[5 + TOUCHPAD_DATA_OFFSET + touchPacketOffset] + ((data[6 + TOUCHPAD_DATA_OFFSET + touchPacketOffset] & 0xF) * 255);
|
||||
int currentY2 = ((data[6 + TOUCHPAD_DATA_OFFSET + touchPacketOffset] & 0xF0) >> 4) + (data[7 + TOUCHPAD_DATA_OFFSET + touchPacketOffset] * 16);
|
||||
|
||||
TouchpadEventArgs args;
|
||||
if (sensors.Touch1 || sensors.Touch2)
|
||||
{
|
||||
if (!lastTouchPadIsDown && touchPadIsDown && TouchButtonDown != null)
|
||||
if ((sensors.Touch1 && !lastIsActive1) || (sensors.Touch2 && !lastIsActive2))
|
||||
{
|
||||
TouchpadEventArgs args = null;
|
||||
Touch t0 = new Touch(currentX, currentY, touchID);
|
||||
if (sensors.Touch2)
|
||||
if (TouchesBegan != null)
|
||||
{
|
||||
Touch t1 = new Touch(currentX2, currentY2, touchID2);
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, t0, t1);
|
||||
if (sensors.Touch1 && sensors.Touch2)
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, new Touch(currentX1, currentY1, touchID1), new Touch(currentX2, currentY2, touchID2));
|
||||
else if (sensors.Touch1)
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, new Touch(currentX1, currentY1, touchID1));
|
||||
else
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, new Touch(currentX2, currentY2, touchID2));
|
||||
|
||||
TouchesBegan(this, args);
|
||||
}
|
||||
}
|
||||
else if (sensors.Touch1 == lastIsActive1 && sensors.Touch2 == lastIsActive2 && TouchesMoved != null)
|
||||
{
|
||||
Touch tPrev, t0, t1;
|
||||
|
||||
if (sensors.Touch1 && sensors.Touch2)
|
||||
{
|
||||
tPrev = new Touch(lastTouchPadX1, lastTouchPadY1, lastTouchID1);
|
||||
t0 = new Touch(currentX1, currentY1, touchID1, tPrev);
|
||||
tPrev = new Touch(lastTouchPadX2, lastTouchPadY2, lastTouchID2);
|
||||
t1 = new Touch(currentX2, currentY2, touchID2, tPrev);
|
||||
}
|
||||
else if (sensors.Touch1)
|
||||
{
|
||||
tPrev = new Touch(lastTouchPadX1, lastTouchPadY1, lastTouchID1);
|
||||
t0 = new Touch(currentX1, currentY1, touchID1, tPrev);
|
||||
t1 = null;
|
||||
}
|
||||
else
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, t0);
|
||||
{
|
||||
tPrev = new Touch(lastTouchPadX2, lastTouchPadY2, lastTouchID2);
|
||||
t0 = new Touch(currentX2, currentY2, touchID2, tPrev);
|
||||
t1 = null;
|
||||
}
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, t0, t1);
|
||||
|
||||
TouchesMoved(this, args);
|
||||
}
|
||||
|
||||
if (!lastTouchPadIsDown && touchPadIsDown && TouchButtonDown != null)
|
||||
{
|
||||
if (sensors.Touch1 && sensors.Touch2)
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, new Touch(currentX1, currentY1, touchID1), new Touch(currentX2, currentY2, touchID2));
|
||||
else if (sensors.Touch1)
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, new Touch(currentX1, currentY1, touchID1));
|
||||
else
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, new Touch(currentX2, currentY2, touchID2));
|
||||
|
||||
TouchButtonDown(this, args);
|
||||
}
|
||||
else if (lastTouchPadIsDown && !touchPadIsDown && TouchButtonUp != null)
|
||||
{
|
||||
TouchpadEventArgs args = null;
|
||||
Touch t0 = new Touch(currentX, currentY, touchID);
|
||||
if (sensors.Touch2)
|
||||
{
|
||||
Touch t1 = new Touch(currentX2, currentY2, touchID2);
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, t0, t1);
|
||||
}
|
||||
if (sensors.Touch1 && sensors.Touch2)
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, new Touch(currentX1, currentY1, touchID1), new Touch(currentX2, currentY2, touchID2));
|
||||
else if (sensors.Touch1)
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, new Touch(currentX1, currentY1, touchID1));
|
||||
else
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, t0);
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, new Touch(currentX2, currentY2, touchID2));
|
||||
|
||||
TouchButtonUp(this, args);
|
||||
}
|
||||
|
||||
if (!lastIsActive || (sensors.Touch2 && !lastIsActive2))
|
||||
if (sensors.Touch1)
|
||||
{
|
||||
TouchpadEventArgs args = null;
|
||||
Touch t0 = new Touch(currentX, currentY, touchID);
|
||||
if (sensors.Touch2 && !lastIsActive2)
|
||||
lastTouchPadX1 = currentX1;
|
||||
lastTouchPadY1 = currentY1;
|
||||
}
|
||||
if (sensors.Touch2)
|
||||
{
|
||||
Touch t1 = new Touch(currentX2, currentY2, touchID2);
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, t0, t1);
|
||||
}
|
||||
else
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, t0);
|
||||
if (TouchesBegan != null)
|
||||
TouchesBegan(this, args);
|
||||
}
|
||||
else if (lastIsActive)
|
||||
{
|
||||
if (TouchesMoved != null)
|
||||
{
|
||||
TouchpadEventArgs args = null;
|
||||
|
||||
Touch t0Prev = new Touch(lastTouchPadX, lastTouchPadY, lastTouchID);
|
||||
Touch t0 = new Touch(currentX, currentY, touchID, t0Prev);
|
||||
if (sensors.Touch1 && sensors.Touch2)
|
||||
{
|
||||
Touch t1Prev = new Touch(lastTouchPadX2, lastTouchPadY2, lastTouchID2);
|
||||
Touch t1 = new Touch(currentX2, currentY2, touchID2, t1Prev);
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, t0, t1);
|
||||
}
|
||||
else
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, t0);
|
||||
TouchesMoved(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
lastTouchPadX = currentX;
|
||||
lastTouchPadY = currentY;
|
||||
lastTouchPadX2 = currentX2;
|
||||
lastTouchPadY2 = currentY2;
|
||||
}
|
||||
lastTouchPadIsDown = touchPadIsDown;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lastIsActive)
|
||||
{
|
||||
TouchpadEventArgs args = null;
|
||||
Touch t0 = new Touch(currentX, currentY, touchID);
|
||||
if (lastIsActive2)
|
||||
{
|
||||
Touch t1 = new Touch(currentX2, currentY2, touchID2);
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, t0, t1);
|
||||
}
|
||||
else
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, t0);
|
||||
if (TouchesEnded != null)
|
||||
TouchesEnded(this, args);
|
||||
}
|
||||
|
||||
if (touchPadIsDown && !lastTouchPadIsDown && TouchButtonDown != null)
|
||||
if (touchPadIsDown && !lastTouchPadIsDown)
|
||||
{
|
||||
if (TouchButtonDown != null)
|
||||
TouchButtonDown(this, new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, null, null));
|
||||
}
|
||||
else if (!touchPadIsDown && lastTouchPadIsDown && TouchButtonUp != null)
|
||||
else if (!touchPadIsDown && lastTouchPadIsDown)
|
||||
{
|
||||
if (TouchButtonUp != null)
|
||||
TouchButtonUp(this, new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, null, null));
|
||||
}
|
||||
|
||||
if ((lastIsActive1 || lastIsActive2) && TouchesEnded != null)
|
||||
{
|
||||
if (lastIsActive1 && lastIsActive2)
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, new Touch(lastTouchPadX1, lastTouchPadY1, touchID1), new Touch(lastTouchPadX2, lastTouchPadY2, touchID2));
|
||||
else if (lastIsActive1)
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, new Touch(lastTouchPadX1, lastTouchPadY1, touchID1));
|
||||
else
|
||||
args = new TouchpadEventArgs(sensors.ReportTimeStamp, sensors.TouchButton, new Touch(lastTouchPadX2, lastTouchPadY2, touchID2));
|
||||
|
||||
TouchesEnded(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
lastIsActive = sensors.Touch1;
|
||||
lastIsActive1 = sensors.Touch1;
|
||||
lastIsActive2 = sensors.Touch2;
|
||||
lastTouchID = touchID;
|
||||
lastTouchID1 = touchID1;
|
||||
lastTouchID2 = touchID2;
|
||||
lastTouchPadIsDown = touchPadIsDown;
|
||||
}
|
||||
|
6
DS4Service/DS4Service.Designer.cs
generated
6
DS4Service/DS4Service.Designer.cs
generated
@ -13,13 +13,9 @@
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
if (components != null)
|
||||
components.Dispose();
|
||||
//CA2213 Disposable fields should be disposed
|
||||
if (rootHub != null)
|
||||
rootHub.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
15
DS4Tool/AboutBox.Designer.cs
generated
15
DS4Tool/AboutBox.Designer.cs
generated
@ -35,7 +35,7 @@
|
||||
//
|
||||
// OkButton
|
||||
//
|
||||
this.OkButton.Location = new System.Drawing.Point(113, 202);
|
||||
this.OkButton.Location = new System.Drawing.Point(260, 118);
|
||||
this.OkButton.Name = "OkButton";
|
||||
this.OkButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.OkButton.TabIndex = 0;
|
||||
@ -52,28 +52,27 @@
|
||||
this.textBox1.Multiline = true;
|
||||
this.textBox1.Name = "textBox1";
|
||||
this.textBox1.ReadOnly = true;
|
||||
this.textBox1.Size = new System.Drawing.Size(260, 155);
|
||||
this.textBox1.Size = new System.Drawing.Size(260, 61);
|
||||
this.textBox1.TabIndex = 1;
|
||||
this.textBox1.Text = "DS4 Tool 1.3 RC3\r\n\r\nCreated By:\r\nArtur Dzmitryieu(InhexSTER)\r\nelectrobrains\r\nHect" +
|
||||
"icSeptic\r\nJays2Kings\r\n\r\nBased on DS3 Scp Server from\r\nScarlet.Crush";
|
||||
this.textBox1.Text = "DS4Windows is Open Source software!\r\n\r\nInsert link to GPL here (at some point.)";
|
||||
this.textBox1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// linkLabel1
|
||||
//
|
||||
this.linkLabel1.AutoSize = true;
|
||||
this.linkLabel1.Location = new System.Drawing.Point(59, 175);
|
||||
this.linkLabel1.Location = new System.Drawing.Point(9, 86);
|
||||
this.linkLabel1.Name = "linkLabel1";
|
||||
this.linkLabel1.Size = new System.Drawing.Size(183, 13);
|
||||
this.linkLabel1.Size = new System.Drawing.Size(324, 13);
|
||||
this.linkLabel1.TabIndex = 2;
|
||||
this.linkLabel1.TabStop = true;
|
||||
this.linkLabel1.Text = "https://code.google.com/p/ds4-tool/";
|
||||
this.linkLabel1.Text = "https://code.google.com/r/brianfundakowskifeldman-ds4windows/";
|
||||
this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
|
||||
//
|
||||
// AboutBox
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(284, 230);
|
||||
this.ClientSize = new System.Drawing.Size(347, 153);
|
||||
this.Controls.Add(this.linkLabel1);
|
||||
this.Controls.Add(this.textBox1);
|
||||
this.Controls.Add(this.OkButton);
|
||||
|
@ -28,7 +28,7 @@ namespace ScpServer
|
||||
|
||||
private void AboutBox_Load(object sender, EventArgs e)
|
||||
{
|
||||
linkLabel1.Links.Add(0,35,"https://code.google.com/p/ds4-tool/");
|
||||
linkLabel1.Links.Add(0, linkLabel1.Text.Length, "https://code.google.com/r/brianfundakowskifeldman-ds4windows/");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
55
DS4Tool/CustomMapping.Designer.cs
generated
55
DS4Tool/CustomMapping.Designer.cs
generated
@ -62,6 +62,8 @@
|
||||
this.bnRX2 = new System.Windows.Forms.Button();
|
||||
this.bnL3 = new System.Windows.Forms.Button();
|
||||
this.bnR3 = new System.Windows.Forms.Button();
|
||||
this.TouchTip = new System.Windows.Forms.Label();
|
||||
this.ReapTip = new System.Windows.Forms.Label();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
@ -300,7 +302,7 @@
|
||||
this.bnDown.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
this.bnDown.Location = new System.Drawing.Point(85, 184);
|
||||
this.bnDown.Name = "bnDown";
|
||||
this.bnDown.Size = new System.Drawing.Size(19, 22);
|
||||
this.bnDown.Size = new System.Drawing.Size(19, 29);
|
||||
this.bnDown.TabIndex = 53;
|
||||
this.bnDown.Text = "Down Button";
|
||||
this.bnDown.UseVisualStyleBackColor = false;
|
||||
@ -318,7 +320,7 @@
|
||||
this.bnRight.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
this.bnRight.Location = new System.Drawing.Point(106, 164);
|
||||
this.bnRight.Name = "bnRight";
|
||||
this.bnRight.Size = new System.Drawing.Size(21, 18);
|
||||
this.bnRight.Size = new System.Drawing.Size(27, 22);
|
||||
this.bnRight.TabIndex = 53;
|
||||
this.bnRight.Text = "Right Button";
|
||||
this.bnRight.UseVisualStyleBackColor = false;
|
||||
@ -336,7 +338,7 @@
|
||||
this.bnLeft.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
this.bnLeft.Location = new System.Drawing.Point(57, 163);
|
||||
this.bnLeft.Name = "bnLeft";
|
||||
this.bnLeft.Size = new System.Drawing.Size(26, 20);
|
||||
this.bnLeft.Size = new System.Drawing.Size(26, 23);
|
||||
this.bnLeft.TabIndex = 53;
|
||||
this.bnLeft.Text = "Left Button";
|
||||
this.bnLeft.UseVisualStyleBackColor = false;
|
||||
@ -352,9 +354,9 @@
|
||||
this.bnOptions.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control;
|
||||
this.bnOptions.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.bnOptions.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
this.bnOptions.Location = new System.Drawing.Point(283, 125);
|
||||
this.bnOptions.Location = new System.Drawing.Point(286, 121);
|
||||
this.bnOptions.Name = "bnOptions";
|
||||
this.bnOptions.Size = new System.Drawing.Size(13, 22);
|
||||
this.bnOptions.Size = new System.Drawing.Size(19, 30);
|
||||
this.bnOptions.TabIndex = 53;
|
||||
this.bnOptions.Text = "Start";
|
||||
this.bnOptions.UseVisualStyleBackColor = false;
|
||||
@ -370,9 +372,9 @@
|
||||
this.bnShare.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control;
|
||||
this.bnShare.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.bnShare.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
this.bnShare.Location = new System.Drawing.Point(131, 127);
|
||||
this.bnShare.Location = new System.Drawing.Point(131, 124);
|
||||
this.bnShare.Name = "bnShare";
|
||||
this.bnShare.Size = new System.Drawing.Size(12, 23);
|
||||
this.bnShare.Size = new System.Drawing.Size(14, 29);
|
||||
this.bnShare.TabIndex = 53;
|
||||
this.bnShare.Text = "Back";
|
||||
this.bnShare.UseVisualStyleBackColor = false;
|
||||
@ -388,9 +390,9 @@
|
||||
this.bnTouchpad.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control;
|
||||
this.bnTouchpad.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.bnTouchpad.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
this.bnTouchpad.Location = new System.Drawing.Point(151, 131);
|
||||
this.bnTouchpad.Location = new System.Drawing.Point(151, 161);
|
||||
this.bnTouchpad.Name = "bnTouchpad";
|
||||
this.bnTouchpad.Size = new System.Drawing.Size(64, 56);
|
||||
this.bnTouchpad.Size = new System.Drawing.Size(128, 26);
|
||||
this.bnTouchpad.TabIndex = 53;
|
||||
this.bnTouchpad.Text = "Click";
|
||||
this.bnTouchpad.UseVisualStyleBackColor = false;
|
||||
@ -426,7 +428,7 @@
|
||||
this.bnTouchUpper.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
this.bnTouchUpper.Location = new System.Drawing.Point(150, 104);
|
||||
this.bnTouchUpper.Name = "bnTouchUpper";
|
||||
this.bnTouchUpper.Size = new System.Drawing.Size(125, 26);
|
||||
this.bnTouchUpper.Size = new System.Drawing.Size(129, 32);
|
||||
this.bnTouchUpper.TabIndex = 53;
|
||||
this.bnTouchUpper.Text = "Middle Click";
|
||||
this.bnTouchUpper.UseVisualStyleBackColor = false;
|
||||
@ -442,9 +444,9 @@
|
||||
this.bnTouchMulti.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control;
|
||||
this.bnTouchMulti.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.bnTouchMulti.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
this.bnTouchMulti.Location = new System.Drawing.Point(215, 131);
|
||||
this.bnTouchMulti.Location = new System.Drawing.Point(151, 135);
|
||||
this.bnTouchMulti.Name = "bnTouchMulti";
|
||||
this.bnTouchMulti.Size = new System.Drawing.Size(64, 56);
|
||||
this.bnTouchMulti.Size = new System.Drawing.Size(128, 26);
|
||||
this.bnTouchMulti.TabIndex = 53;
|
||||
this.bnTouchMulti.Text = "Right Click";
|
||||
this.bnTouchMulti.UseVisualStyleBackColor = false;
|
||||
@ -471,12 +473,11 @@
|
||||
//
|
||||
this.lbControls.FormattingEnabled = true;
|
||||
this.lbControls.Items.AddRange(new object[] {
|
||||
"<Press a button, then a key to assign>"});
|
||||
"<Click a button, then a key/item to assign>"});
|
||||
this.lbControls.Location = new System.Drawing.Point(418, 67);
|
||||
this.lbControls.Name = "lbControls";
|
||||
this.lbControls.Size = new System.Drawing.Size(248, 212);
|
||||
this.lbControls.TabIndex = 54;
|
||||
this.lbControls.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);
|
||||
//
|
||||
// bnLY2
|
||||
//
|
||||
@ -640,12 +641,36 @@
|
||||
this.bnR3.Text = "Right Stick";
|
||||
this.bnR3.UseVisualStyleBackColor = false;
|
||||
//
|
||||
// TouchTip
|
||||
//
|
||||
this.TouchTip.AutoSize = true;
|
||||
this.TouchTip.Location = new System.Drawing.Point(164, 34);
|
||||
this.TouchTip.Name = "TouchTip";
|
||||
this.TouchTip.Size = new System.Drawing.Size(109, 52);
|
||||
this.TouchTip.TabIndex = 55;
|
||||
this.TouchTip.Text = "Touchpad:\r\nTop: Upper Pad \r\nMiddle: Multi-Touch \r\nBottom: Single Touch";
|
||||
this.TouchTip.TextAlign = System.Drawing.ContentAlignment.TopCenter;
|
||||
this.TouchTip.Visible = false;
|
||||
//
|
||||
// ReapTip
|
||||
//
|
||||
this.ReapTip.AutoSize = true;
|
||||
this.ReapTip.Location = new System.Drawing.Point(134, 59);
|
||||
this.ReapTip.Name = "ReapTip";
|
||||
this.ReapTip.Size = new System.Drawing.Size(169, 26);
|
||||
this.ReapTip.TabIndex = 55;
|
||||
this.ReapTip.Text = "Double Tap a key to toggle repeat\r\n(Excludes TouchPad)";
|
||||
this.ReapTip.TextAlign = System.Drawing.ContentAlignment.TopCenter;
|
||||
this.ReapTip.Visible = false;
|
||||
//
|
||||
// CustomMapping
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(244)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
|
||||
this.ClientSize = new System.Drawing.Size(684, 310);
|
||||
this.Controls.Add(this.ReapTip);
|
||||
this.Controls.Add(this.TouchTip);
|
||||
this.Controls.Add(this.pictureBox);
|
||||
this.Controls.Add(this.lbControls);
|
||||
this.Controls.Add(this.cbScanCode);
|
||||
@ -728,5 +753,7 @@
|
||||
private System.Windows.Forms.Button bnRX2;
|
||||
private System.Windows.Forms.Button bnL3;
|
||||
private System.Windows.Forms.Button bnR3;
|
||||
private System.Windows.Forms.Label TouchTip;
|
||||
private System.Windows.Forms.Label ReapTip;
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ namespace ScpServer
|
||||
{
|
||||
private int device;
|
||||
private bool handleNextKeyPress = false;
|
||||
private bool MouseMoveAdded = false;
|
||||
private bool ReapTipShown = false;
|
||||
private List<ComboBox> comboBoxes = new List<ComboBox>();
|
||||
private List<Button> buttons = new List<Button>();
|
||||
private Dictionary<string, string> defaults = new Dictionary<string, string>();
|
||||
@ -46,11 +46,10 @@ namespace ScpServer
|
||||
// Add events here (easier for modification/addition)
|
||||
((Button)control).Enter += new System.EventHandler(this.EnterCommand);
|
||||
((Button)control).KeyDown += new System.Windows.Forms.KeyEventHandler(this.KeyDownCommand);
|
||||
((Button)control).Enter += new System.EventHandler(this.TopofListChanged);
|
||||
((Button)control).KeyDown += new System.Windows.Forms.KeyEventHandler(this.TopofListChanged);
|
||||
//((Button)control).Enter += new System.EventHandler(this.TopofListChanged);
|
||||
//((Button)control).KeyDown += new System.Windows.Forms.KeyEventHandler(this.TopofListChanged);
|
||||
((Button)control).KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.KeyPressCommand);
|
||||
((Button)control).PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.PreviewKeyDownCommand);
|
||||
//lbControls.Items.Add(((Button)control).Text);
|
||||
lbControls.SelectedIndexChanged += new System.EventHandler(this.SelectedIndexChangedCommand);
|
||||
}
|
||||
}
|
||||
@ -64,7 +63,9 @@ namespace ScpServer
|
||||
{
|
||||
if (sender is Button)
|
||||
{
|
||||
ReapTip.Visible = false;
|
||||
lbControls.SetSelected(0, true);
|
||||
//
|
||||
for (int i = 1; i < lbControls.Items.Count; i++)
|
||||
if (lbControls.Items[i].ToString().Contains(" (default)"))
|
||||
{
|
||||
@ -160,6 +161,8 @@ namespace ScpServer
|
||||
lbControls.Items.Insert(1, temp);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (((Button)sender).Name.Contains("bnLX") || ((Button)sender).Name.Contains("bnLY") || ((Button)sender).Name.Contains("bnRX") || ((Button)sender).Name.Contains("bnRY"))
|
||||
{
|
||||
lbControls.Items.Insert(2, "Mouse Right");
|
||||
@ -167,8 +170,20 @@ namespace ScpServer
|
||||
lbControls.Items.Insert(2, "Mouse Down");
|
||||
lbControls.Items.Insert(2, "Mouse Up");
|
||||
}
|
||||
break;
|
||||
|
||||
if (((Button)sender).Name.Contains("Touch"))
|
||||
TouchTip.Visible = true;
|
||||
else
|
||||
{
|
||||
if (ReapTipShown == false)
|
||||
{
|
||||
ReapTip.Visible = true;
|
||||
ReapTipShown = true;
|
||||
}
|
||||
TouchTip.Visible = false;
|
||||
}
|
||||
if (((Button)sender).Text != "Save" && ((Button)sender).Text != "Load")
|
||||
lbControls.Items[0] = ((Button)sender).Text;
|
||||
}
|
||||
|
||||
private void PreviewKeyDownCommand(object sender, PreviewKeyDownEventArgs e)
|
||||
@ -238,8 +253,8 @@ namespace ScpServer
|
||||
}
|
||||
private void SelectedIndexChangedCommand(object sender, EventArgs e)
|
||||
{
|
||||
if (lastSelectedBn != null)
|
||||
if (lbControls.SelectedIndex > 0)
|
||||
{
|
||||
if (lastSelectedBn.Text != lbControls.Items[lbControls.SelectedIndex].ToString())
|
||||
{
|
||||
if (lbControls.Items[lbControls.SelectedIndex].ToString().Contains(" (default)"))
|
||||
@ -252,7 +267,6 @@ namespace ScpServer
|
||||
lastSelectedBn.Tag = lbControls.Items[lbControls.SelectedIndex].ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
private void cbRepeat_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!lastSelectedBn.Name.Contains("Touch") && (lastSelectedBn.Tag is int || lastSelectedBn.Tag is UInt16))
|
||||
@ -322,10 +336,6 @@ namespace ScpServer
|
||||
}
|
||||
}
|
||||
|
||||
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -11,8 +11,7 @@
|
||||
<AssemblyName>DS4Tool</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>C:\Users\Jonathan\Documents\Projects\DS4Builds\</PublishUrl>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
@ -22,11 +21,10 @@
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<AutorunEnabled>true</AutorunEnabled>
|
||||
<ApplicationRevision>1</ApplicationRevision>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
@ -55,18 +53,6 @@
|
||||
<PropertyGroup>
|
||||
<StartupObject>ScpServer.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ManifestCertificateThumbprint>82841E533FB15D122F1D1941E6264C09CDDD60F1</ManifestCertificateThumbprint>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ManifestKeyFile>DS4Tool_TemporaryKey.pfx</ManifestKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<GenerateManifests>true</GenerateManifests>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignManifests>true</SignManifests>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
@ -87,7 +73,6 @@
|
||||
<DependentUpon>AboutBox.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="AdvancedColorDialog.cs" />
|
||||
<Compile Include="AdvancedComboBox.cs" />
|
||||
<Compile Include="CustomMapping.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@ -108,12 +93,6 @@
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ReadInputForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ReadInputForm.Designer.cs">
|
||||
<DependentUpon>ReadInputForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ScpForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@ -143,13 +122,9 @@
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="ReadInputForm.resx">
|
||||
<DependentUpon>ReadInputForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="ScpForm.resx">
|
||||
<DependentUpon>ScpForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<None Include="DS4Tool_TemporaryKey.pfx" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
@ -194,16 +169,12 @@
|
||||
<None Include="Resources\28.png" />
|
||||
<None Include="Resources\29.png" />
|
||||
<Content Include="Resources\3.png" />
|
||||
<None Include="Resources\30.png" />
|
||||
<None Include="Resources\31.png" />
|
||||
<Content Include="Resources\4.png" />
|
||||
<Content Include="Resources\5.png" />
|
||||
<Content Include="Resources\6.png" />
|
||||
<Content Include="Resources\7.png" />
|
||||
<Content Include="Resources\8.png" />
|
||||
<Content Include="Resources\9.png" />
|
||||
<None Include="Resources\DS4 More Red %28small%29.png" />
|
||||
<None Include="Resources\DS4 Control Shadows %28small%29.png" />
|
||||
<Content Include="Resources\DS4.ico" />
|
||||
<Content Include="Resources\Scp_All.ico" />
|
||||
</ItemGroup>
|
||||
|
@ -118,86 +118,65 @@
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="_10" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\10.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_1" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Stop" xml:space="preserve">
|
||||
<value>Stop</value>
|
||||
<comment>To be localized.</comment>
|
||||
</data>
|
||||
<data name="_15" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\15.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_9" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\9.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_13" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\13.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="DS4" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\DS4.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Start" xml:space="preserve">
|
||||
<value>Start</value>
|
||||
<comment>To be localized.</comment>
|
||||
</data>
|
||||
<data name="_19" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\19.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="Stop" xml:space="preserve">
|
||||
<value>Stop</value>
|
||||
<comment>To be localized.</comment>
|
||||
</data>
|
||||
<data name="_4" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\4.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="_1" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_10" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\10.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_11" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\11.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="_12" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\12.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_2" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="_13" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\13.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_14" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\14.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_5" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\5.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="_15" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\15.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_22" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\22.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_7" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\7.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_12" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\12.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="_17" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\17.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_18" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\18.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_19" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\19.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_2" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_20" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\20.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_21" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\21.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_17" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\17.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="_22" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\22.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_23" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\23.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_3" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\3.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_8" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\8.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_6" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\6.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="DS4" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\DS4.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_24" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
@ -216,4 +195,25 @@
|
||||
<data name="_29" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\29.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_3" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\3.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_4" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\4.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_5" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\5.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_6" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\6.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_7" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\7.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_8" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\8.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_9" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\9.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
Binary file not shown.
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 48 KiB |
Binary file not shown.
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 52 KiB |
13
DS4Tool/ScpForm.Designer.cs
generated
13
DS4Tool/ScpForm.Designer.cs
generated
@ -13,13 +13,9 @@
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
if (components != null)
|
||||
components.Dispose();
|
||||
//CA2213 Disposable fields should be disposed
|
||||
if (rootHub != null)
|
||||
rootHub.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
@ -93,7 +89,8 @@
|
||||
//
|
||||
// tmrUpdate
|
||||
//
|
||||
this.tmrUpdate.Tick += new System.EventHandler(this.tmrUpdate_Tick);
|
||||
this.tmrUpdate.Interval = 1;
|
||||
this.tmrUpdate.Tick += new System.EventHandler(this.ControllerStatusChange);
|
||||
//
|
||||
// pnlButton
|
||||
//
|
||||
@ -330,7 +327,7 @@
|
||||
this.Controls.Add(this.pnlStatus);
|
||||
this.MinimumSize = new System.Drawing.Size(750, 192);
|
||||
this.Name = "ScpForm";
|
||||
this.Text = "DS4 to XInput Mapper 1.3 RC4 - J2K Build";
|
||||
this.Text = "DS4Windows 1.0 Alpha (2014-03-28.1)";
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form_Close);
|
||||
this.Load += new System.EventHandler(this.Form_Load);
|
||||
this.Resize += new System.EventHandler(this.Form_Resize);
|
||||
@ -348,6 +345,7 @@
|
||||
private System.Windows.Forms.ListView lvDebug;
|
||||
private System.Windows.Forms.ColumnHeader chTime;
|
||||
private System.Windows.Forms.ColumnHeader chData;
|
||||
private System.Windows.Forms.Timer tmrUpdate;
|
||||
private System.Windows.Forms.Panel pnlButton;
|
||||
private System.Windows.Forms.Button btnStop;
|
||||
private System.Windows.Forms.Button btnStartStop;
|
||||
@ -367,7 +365,6 @@
|
||||
private System.Windows.Forms.Label lbLastMessage;
|
||||
private System.Windows.Forms.LinkLabel lnkControllers;
|
||||
private System.Windows.Forms.Button AboutButton;
|
||||
private System.Windows.Forms.Timer tmrUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ namespace ScpServer
|
||||
protected void ShowNotification(object sender, DebugEventArgs args)
|
||||
{
|
||||
notifyIcon1.BalloonTipText = args.Data;
|
||||
notifyIcon1.BalloonTipTitle = "DS4 Tool";
|
||||
notifyIcon1.BalloonTipTitle = "DS4Windows";
|
||||
notifyIcon1.ShowBalloonTip(1);
|
||||
}
|
||||
|
||||
@ -45,15 +45,13 @@ namespace ScpServer
|
||||
{
|
||||
notifyIcon1.Visible = true;
|
||||
this.Hide();
|
||||
//hide in taskbar
|
||||
this.ShowInTaskbar = false;
|
||||
}
|
||||
else if (FormWindowState.Normal == this.WindowState)
|
||||
{
|
||||
notifyIcon1.Visible = false;
|
||||
//show in taskbar
|
||||
this.Show();
|
||||
this.ShowInTaskbar = true;
|
||||
|
||||
}
|
||||
//Added last message alternative
|
||||
if (this.Height > 220)
|
||||
@ -83,13 +81,11 @@ namespace ScpServer
|
||||
rootHub.Debug += On_Debug;
|
||||
Log.GuiLog += On_Debug;
|
||||
Log.TrayIconLog += ShowNotification;
|
||||
tmrUpdate.Enabled = true;
|
||||
// tmrUpdate.Enabled = true; TODO remove tmrUpdate and leave tick()
|
||||
Global.Load();
|
||||
hideDS4CheckBox.CheckedChanged -= hideDS4CheckBox_CheckedChanged;
|
||||
hideDS4CheckBox.Checked = Global.getUseExclusiveMode();
|
||||
hideDS4CheckBox.CheckedChanged += hideDS4CheckBox_CheckedChanged;
|
||||
if (btnStartStop.Enabled)
|
||||
btnStartStop_Click(sender, e);
|
||||
|
||||
// New settings
|
||||
this.Width = Global.getFormWidth();
|
||||
@ -104,8 +100,10 @@ namespace ScpServer
|
||||
Form_Resize(sender, e);
|
||||
}
|
||||
Global.loadCustomMapping(0);
|
||||
|
||||
|
||||
Global.ControllerStatusChange += ControllerStatusChange;
|
||||
ControllerStatusChanged();
|
||||
if (btnStartStop.Enabled)
|
||||
btnStartStop_Clicked();
|
||||
}
|
||||
protected void Form_Close(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
@ -116,6 +114,10 @@ namespace ScpServer
|
||||
}
|
||||
|
||||
protected void btnStartStop_Click(object sender, EventArgs e)
|
||||
{
|
||||
btnStartStop_Clicked();
|
||||
}
|
||||
protected void btnStartStop_Clicked()
|
||||
{
|
||||
if (btnStartStop.Text == Properties.Resources.Start
|
||||
&& rootHub.Start())
|
||||
@ -156,17 +158,23 @@ namespace ScpServer
|
||||
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
protected void tmrUpdate_Tick(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
delegate void ControllerStatusChangedDelegate(object sender, EventArgs e);
|
||||
protected void ControllerStatusChange(object sender, EventArgs e)
|
||||
{
|
||||
if (InvokeRequired)
|
||||
Invoke(new ControllerStatusChangedDelegate(ControllerStatusChange), new object[] { sender, e });
|
||||
else
|
||||
ControllerStatusChanged();
|
||||
}
|
||||
protected void ControllerStatusChanged()
|
||||
{
|
||||
// If controllers are detected, but not checked, automatically check #1
|
||||
bool checkFirst = true;
|
||||
bool optionsEnabled = false;
|
||||
for (Int32 Index = 0; Index < Pad.Length; Index++)
|
||||
{
|
||||
string contollerInfo = rootHub.getDS4ControllerInfo(Index);
|
||||
|
||||
Pad[Index].Text = contollerInfo;
|
||||
Pad[Index].Text = rootHub.getDS4ControllerInfo(Index);
|
||||
if (Pad[Index].Text != null && Pad[Index].Text != "")
|
||||
{
|
||||
Pad[Index].Enabled = true;
|
||||
@ -237,8 +245,8 @@ namespace ScpServer
|
||||
module.Dispose();
|
||||
|
||||
Global.setUseExclusiveMode(hideDS4CheckBox.Checked);
|
||||
btnStartStop_Click(sender, e);
|
||||
btnStartStop_Click(sender, e);
|
||||
btnStartStop_Clicked();
|
||||
btnStartStop_Clicked();
|
||||
Global.Save();
|
||||
}
|
||||
private void startMinimizedCheckBox_CheckedChanged(object sender, EventArgs e)
|
||||
|
@ -62,6 +62,7 @@ namespace HidLibrary
|
||||
public SafeFileHandle safeReadHandle { get; private set; }
|
||||
public FileStream fileStream { get; private set; }
|
||||
public bool IsOpen { get; private set; }
|
||||
public bool IsExclusive { get; private set; }
|
||||
public bool IsConnected { get { return HidDevices.IsConnected(_devicePath); } }
|
||||
public bool IsTimedOut { get { return idleTicks > 5; } }
|
||||
public string Description { get { return _description; } }
|
||||
@ -93,7 +94,7 @@ namespace HidLibrary
|
||||
if (IsOpen) return;
|
||||
try
|
||||
{
|
||||
if (safeReadHandle == null)
|
||||
if (safeReadHandle == null || safeReadHandle.IsInvalid)
|
||||
safeReadHandle = OpenHandle(_devicePath, isExclusive);
|
||||
}
|
||||
catch (Exception exception)
|
||||
@ -103,6 +104,7 @@ namespace HidLibrary
|
||||
}
|
||||
|
||||
IsOpen = !safeReadHandle.IsInvalid;
|
||||
IsExclusive = isExclusive;
|
||||
}
|
||||
|
||||
public void CloseDevice()
|
||||
@ -327,15 +329,7 @@ namespace HidLibrary
|
||||
}
|
||||
}
|
||||
|
||||
public bool WriteFile(byte[] buffer)
|
||||
{
|
||||
uint bytesWritten = 0;
|
||||
if ( NativeMethods.WriteFile(safeReadHandle.DangerousGetHandle(), buffer, (uint)buffer.Length, out bytesWritten, IntPtr.Zero) && bytesWritten > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
public bool WriteOutputReportViaInterrupt(byte[] outputBuffer)
|
||||
public bool WriteOutputReportViaInterrupt(byte[] outputBuffer, int timeout)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -409,8 +403,6 @@ namespace HidLibrary
|
||||
byte[] buffer = new byte[126];
|
||||
NativeMethods.HidD_GetSerialNumberString(safeReadHandle.DangerousGetHandle(), buffer, (ulong)buffer.Length);
|
||||
string MACAddr = System.Text.Encoding.Unicode.GetString(buffer).Replace("\0", string.Empty).ToUpper();
|
||||
if (MACAddr == null || MACAddr == String.Empty)
|
||||
MACAddr = "000000000000";
|
||||
MACAddr = String.Format("{0}{1}:{2}{3}:{4}{5}:{6}{7}:{8}{9}:{10}{11}",
|
||||
MACAddr[0], MACAddr[1], MACAddr[2], MACAddr[3], MACAddr[4],
|
||||
MACAddr[5], MACAddr[6], MACAddr[7], MACAddr[8],
|
||||
|
@ -66,7 +66,7 @@ namespace HidLibrary
|
||||
static internal extern uint WaitForSingleObject(IntPtr hHandle, int dwMilliseconds);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
static internal extern bool WriteFile(IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, IntPtr lpOverlapped);
|
||||
static internal extern bool WriteFile(IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, [In] ref System.Threading.NativeOverlapped lpOverlapped);
|
||||
|
||||
internal const int DBT_DEVICEARRIVAL = 0x8000;
|
||||
internal const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
|
||||
|
Loading…
Reference in New Issue
Block a user