diff --git a/DS4Control/ButtonMouse.cs b/DS4Control/ButtonMouse.cs deleted file mode 100644 index 1028c1f..0000000 --- a/DS4Control/ButtonMouse.cs +++ /dev/null @@ -1,182 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Runtime.InteropServices; -using DS4Library; -namespace DS4Control -{ - public class ButtonMouse : ITouchpadBehaviour - { - private int deviceNum; - private bool leftButton, middleButton, rightButton; - 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() - { - return "Button Mode"; - } - - public void touchesMoved(object sender, TouchpadEventArgs arg) - { - 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); - } - - private void synthesizeMouseButtons(bool justRelease) - { - bool previousLeftButton = leftButton, previousMiddleButton = middleButton, previousRightButton = rightButton; - if (justRelease) - { - leftButton = middleButton = rightButton = false; - } - else - { - leftButton = s.L1 || s.R1 || s.DpadLeft || s.Square; - middleButton = s.DpadUp || s.DpadDown || s.Triangle || s.Cross; - rightButton = s.DpadRight || s.Circle; - s.L1 = s.R1 = s.DpadLeft = s.Square = s.DpadUp = s.DpadDown = s.Triangle = s.Cross = s.DpadRight = s.Circle = false; - } - if (leftButton != previousLeftButton) - InputMethods.MouseEvent(leftButton ? InputMethods.MOUSEEVENTF_LEFTDOWN : InputMethods.MOUSEEVENTF_LEFTUP); - if (middleButton != previousMiddleButton) - InputMethods.MouseEvent(middleButton ? InputMethods.MOUSEEVENTF_MIDDLEDOWN : InputMethods.MOUSEEVENTF_MIDDLEUP); - if (rightButton != previousRightButton) - InputMethods.MouseEvent(rightButton ? InputMethods.MOUSEEVENTF_RIGHTDOWN : InputMethods.MOUSEEVENTF_RIGHTUP); - - } - - // touch area stuff - private bool leftDown, rightDown, upperDown; - private bool isLeft(Touch t) - { - return t.hwX < 1920 * 2 / 5; - } - - private bool isRight(Touch t) - { - return t.hwX >= 1920 * 3 / 5; - } - - public void touchButtonUp(object sender, TouchpadEventArgs arg) - { - if (upperDown) - { - mapTouchPad(DS4Controls.TouchUpper, true); - upperDown = false; - } - if (leftDown) - { - mapTouchPad(DS4Controls.TouchButton, true); - leftDown = false; - } - if (rightDown) - { - mapTouchPad(DS4Controls.TouchMulti, true); - rightDown = false; - } - dev.setRumble(0, 0); - } - - public void touchButtonDown(object sender, TouchpadEventArgs arg) - { - byte leftRumble, rightRumble; - if (arg.touches == null) //No touches, finger on upper portion of touchpad - { - mapTouchPad(DS4Controls.TouchUpper, false); - upperDown = true; - leftRumble = rightRumble = 127; - } - else if (arg.touches.Length == 1) - { - if (isLeft(arg.touches[0])) - { - mapTouchPad(DS4Controls.TouchButton, false); - leftDown = true; - leftRumble = 63; - rightRumble = 0; - } - else if (isRight(arg.touches[0])) - { - mapTouchPad(DS4Controls.TouchMulti, false); - rightDown = true; - leftRumble = 0; - rightRumble = 63; - } - else - { - leftRumble = rightRumble = 0; // Ignore ambiguous pushes. - } - } - else - { - buttonLock = !buttonLock; - leftRumble = rightRumble = (byte)(buttonLock ? 255 : 63); - } - dev.setRumble(rightRumble, leftRumble); // sustain while pressed - } - - bool mapTouchPad(DS4Controls padControl, bool release) - { - ushort key = Global.getCustomKey(padControl); - if (key == 0) - return false; - else - { - DS4KeyType keyType = Global.getCustomKeyType(padControl); - if (!release) - if (keyType.HasFlag(DS4KeyType.ScanCode)) - InputMethods.performSCKeyPress(key); - else InputMethods.performKeyPress(key); - else - if (!keyType.HasFlag(DS4KeyType.Repeat)) - if (keyType.HasFlag(DS4KeyType.ScanCode)) - InputMethods.performSCKeyRelease(key); - else InputMethods.performKeyRelease(key); - return true; - } - } - - public DS4State getDS4State() - { - return s; - } - - } -} - diff --git a/DS4Control/Control.cs b/DS4Control/Control.cs index 706b2fa..64d3d24 100644 --- a/DS4Control/Control.cs +++ b/DS4Control/Control.cs @@ -9,7 +9,8 @@ namespace DS4Control { X360Device x360Bus; DS4Device[] DS4Controllers = new DS4Device[4]; - TPadModeSwitcher[] modeSwitcher = new TPadModeSwitcher[4]; + //TPadModeSwitcher[] modeSwitcher = new TPadModeSwitcher[4]; + Mouse[] touchPad = new Mouse[4]; private bool running = false; private DS4State[] MappedState = new DS4State[4]; private DS4State[] CurrentState = new DS4State[4]; @@ -36,6 +37,7 @@ namespace DS4Control PreviousState[i] = new DS4State(); ExposedState[i] = new DS4StateExposed(CurrentState[i]); } + GiveMouses(); } private void WarnExclusiveModeFailure(DS4Device device) @@ -67,15 +69,19 @@ namespace DS4Control LogDebug("Found Controller: " + device.MacAddress + " (" + device.ConnectionType + ")"); WarnExclusiveModeFailure(device); DS4Controllers[ind] = device; + device.Removal -= DS4Devices.On_Removal; device.Removal += this.On_DS4Removal; - TPadModeSwitcher m_switcher = new TPadModeSwitcher(device, ind); - m_switcher.Debug += OnDebug; - modeSwitcher[ind] = m_switcher; + device.Removal += DS4Devices.On_Removal; + //TPadModeSwitcher m_switcher = new TPadModeSwitcher(device, ind); + //m_switcher.Debug += OnDebug; + //modeSwitcher[ind] = m_switcher; + touchPad[ind] = new Mouse(ind, device); 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); + //m_switcher.setMode(Global.getInitialMode(ind)); + TouchPadOn(ind, device); ind++; LogDebug("Controller: " + device.MacAddress + " is ready to use"); Log.LogToTray("Controller: " + device.MacAddress + " is ready to use"); @@ -100,15 +106,21 @@ namespace DS4Control { running = false; LogDebug("Stopping X360 Controllers"); + bool anyUnplugged = false; for (int i = 0; i < DS4Controllers.Length; i++) { if (DS4Controllers[i] != null) { + CurrentState[i].Battery = PreviousState[i].Battery = 0; // Reset for the next connection's initial status change. x360Bus.Unplug(i + 1); + anyUnplugged = true; DS4Controllers[i] = null; - modeSwitcher[i] = null; + //modeSwitcher[i] = null; + touchPad[i] = null; } } + if (anyUnplugged) + System.Threading.Thread.Sleep(XINPUT_UNPLUG_SETTLE_TIME); x360Bus.Stop(); LogDebug("Stopping DS4 Controllers"); DS4Devices.stopControllers(); @@ -119,16 +131,10 @@ namespace DS4Control } - 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 devices = DS4Devices.getDS4Controllers(); foreach (DS4Device device in devices) @@ -150,14 +156,18 @@ namespace DS4Control LogDebug("Found Controller: " + device.MacAddress + " (" + device.ConnectionType + ")"); WarnExclusiveModeFailure(device); DS4Controllers[Index] = device; + device.Removal -= DS4Devices.On_Removal; device.Removal += this.On_DS4Removal; - TPadModeSwitcher m_switcher = new TPadModeSwitcher(device, Index); - m_switcher.Debug += OnDebug; - modeSwitcher[Index] = m_switcher; + device.Removal += DS4Devices.On_Removal; + //TPadModeSwitcher m_switcher = new TPadModeSwitcher(device, Index); + //m_switcher.Debug += OnDebug; + //modeSwitcher[Index] = m_switcher; + touchPad[Index] = new Mouse(Index, device); device.LightBarColor = Global.loadColor(Index); device.Report += this.On_Report; x360Bus.Plugin(Index + 1); - m_switcher.setMode(Global.getTouchEnabled(Index) ? 1 : 0); + //m_switcher.setMode(Global.getInitialMode(Index)); + TouchPadOn(Index, device); LogDebug("Controller: " + device.MacAddress + " is ready to use"); Log.LogToTray("Controller: " + device.MacAddress + " is ready to use"); break; @@ -167,31 +177,80 @@ namespace DS4Control return true; } + public void TouchPadOn(int ind, DS4Device device) + { + ITouchpadBehaviour tPad = touchPad[ind]; + device.Touchpad.TouchButtonDown += tPad.touchButtonDown; + device.Touchpad.TouchButtonUp += tPad.touchButtonUp; + device.Touchpad.TouchesBegan += tPad.touchesBegan; + device.Touchpad.TouchesMoved += tPad.touchesMoved; + device.Touchpad.TouchesEnded += tPad.touchesEnded; + device.Touchpad.TouchUnchanged += tPad.touchUnchanged; + //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 string getDS4ControllerInfo(int index) { if (DS4Controllers[index] != null) { DS4Device d = DS4Controllers[index]; if (!d.IsAlive()) - return null; // awaiting the first battery charge indication + return "Connecting..."; // awaiting the first battery charge indication String battery; if (d.Charging) { if (d.Battery >= 100) - battery = "fully-charged"; + battery = "Charged"; else - battery = "charging at ~" + d.Battery + "%"; + battery = "Charging:" + d.Battery + "%"; } else { - battery = "draining at ~" + d.Battery + "%"; + battery = "Battery: " + d.Battery + "%"; } - return d.MacAddress + " (" + d.ConnectionType + "), Battery is " + battery + ", Touchpad in " + modeSwitcher[index].ToString(); + return d.MacAddress + " (" + d.ConnectionType + "), " + battery; + //return d.MacAddress + " (" + d.ConnectionType + "), Battery is " + battery + ", Touchpad in " + modeSwitcher[index].ToString(); } else - return null; + return String.Empty; } + public string getShortDS4ControllerInfo(int index) + { + if (DS4Controllers[index] != null) + { + DS4Device d = DS4Controllers[index]; + String battery; + if (!d.IsAlive()) + battery = "..."; + if (d.Charging) + { + if (d.Battery >= 100) + battery = "Full"; + else + battery = ">" + d.Battery + '%'; + } + else + { + battery = d.Battery + "%"; + } + return battery + ' ' + d.ConnectionType; + } + else + return "None"; + } + + /* public string[] getAvailableControllerModes(int index) + { + List modes = new List(); + if (DS4Controllers[index] != null) + foreach (ITouchpadBehaviour mode in modeSwitcher[index].getAvailableModes()) + modes.Add(mode.ToString()); + return modes.ToArray(); + } + public string getDS4ControllerMode(int index) { if (DS4Controllers[index] != null) @@ -203,8 +262,9 @@ namespace DS4Control } else return "couldn't find"; - } + } */ + private int XINPUT_UNPLUG_SETTLE_TIME = 250; // Inhibit races that occur with the asynchronous teardown of ScpVBus -> X360 driver instance. //Called when DS4 is disconnected or timed out protected virtual void On_DS4Removal(object sender, EventArgs e) { @@ -215,12 +275,14 @@ namespace DS4Control ind = i; if (ind != -1) { - justRemoved = true; + CurrentState[ind].Battery = PreviousState[ind].Battery = 0; // Reset for the next connection's initial status change. x360Bus.Unplug(ind + 1); LogDebug("Controller " + device.MacAddress + " was removed or lost connection"); Log.LogToTray("Controller " + device.MacAddress + " was removed or lost connection"); + System.Threading.Thread.Sleep(XINPUT_UNPLUG_SETTLE_TIME); DS4Controllers[ind] = null; - modeSwitcher[ind] = null; + //modeSwitcher[ind] = null; + touchPad[ind] = null; Global.ControllerStatusChanged(this); } } @@ -242,31 +304,26 @@ namespace DS4Control DS4State cState = CurrentState[ind]; device.getPreviousState(PreviousState[ind]); DS4State pState = PreviousState[ind]; + if (pState.Battery != cState.Battery) + Global.ControllerStatusChanged(this); - if (modeSwitcher[ind].getCurrentMode() is ButtonMouse) - { - ButtonMouse mode = (ButtonMouse)modeSwitcher[ind].getCurrentMode(); - // XXX so disgusting, need to virtualize this again - mode.getDS4State().Copy(cState); - } - else - { - device.getExposedState(ExposedState[ind], CurrentState[ind]); - cState = CurrentState[ind]; - } - + //bool wasButtonMouse = modeSwitcher[ind].getCurrentMode() is ButtonMouse; CheckForHotkeys(ind, cState, pState); + //if (wasButtonMouse && modeSwitcher[ind].getCurrentMode() is ButtonMouse) + { + //ButtonMouse mode = (ButtonMouse)modeSwitcher[ind].getCurrentMode(); + // XXX so disgusting, need to virtualize this again + // mode.getDS4State().CopyTo(cState); + } if (Global.getHasCustomKeysorButtons(ind)) { - Mapping.mapButtons(cState, pState, MappedState[ind]); + Mapping.MapCustom(ind, cState, 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 @@ -281,24 +338,49 @@ namespace DS4Control setRumble(Small, Big, ind); } } + + // Output any synthetic events. + Mapping.Commit(ind); + // Pull settings updates. + device.IdleTimeout = Global.getIdleDisconnectTimeout(ind); } } - + public void GiveMouses() + { + Mapping.GetMouses(ref touchPad); + } + bool touchreleased = true; protected virtual void CheckForHotkeys(int deviceID, DS4State cState, DS4State pState) { DS4Device d = DS4Controllers[deviceID]; if (cState.Touch1 && !pState.Share && !pState.Options) { if (cState.Share) - modeSwitcher[deviceID].previousMode(); + Global.setTouchSensitivity(deviceID, 0); else if (cState.Options) - modeSwitcher[deviceID].nextMode(); + Global.setTouchSensitivity(deviceID, 100); } + if (cState.Touch1 && pState.PS) + { + if (Global.getTouchSensitivity(deviceID) > 0 && touchreleased) + { + Global.setTouchSensitivity(deviceID, 0); + touchreleased = false; + } + else if (touchreleased) + { + Global.setTouchSensitivity(deviceID, 100); + touchreleased = false; + } + } + else + touchreleased = true; } public virtual void LogDebug(String Data) { + Console.WriteLine(System.DateTime.UtcNow.ToString("o") + "> " + Data); if (Debug != null) { DebugEventArgs args = new DebugEventArgs(Data); @@ -322,7 +404,10 @@ namespace DS4Control uint heavyBoosted = ((uint)heavyMotor * (uint)boost) / 100; if (heavyBoosted > 255) heavyBoosted = 255; - DS4Controllers[deviceNum].setRumble((byte)lightBoosted, (byte)heavyBoosted); + if (Global.getRumbleSwap(deviceNum)) + DS4Controllers[deviceNum].setRumble((byte)heavyBoosted, (byte)lightBoosted); + else + DS4Controllers[deviceNum].setRumble((byte)lightBoosted, (byte)heavyBoosted); } } } diff --git a/DS4Control/CursorOnlyMode.cs b/DS4Control/CursorOnlyMode.cs deleted file mode 100644 index 6e6bd50..0000000 --- a/DS4Control/CursorOnlyMode.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Runtime.InteropServices; -using DS4Library; -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() - { - return "Cursor Mode"; - } - - public void touchesMoved(object sender, TouchpadEventArgs arg) - { - cursor.touchesMoved(arg); - wheel.touchesMoved(arg); - } - - public void touchesBegan(object sender, TouchpadEventArgs arg) - { - cursor.touchesBegan(arg); - wheel.touchesBegan(arg); - } - - public void touchesEnded(object sender, TouchpadEventArgs arg) { } - - public void touchButtonUp(object sender, TouchpadEventArgs arg) { } - - public void touchButtonDown(object sender, TouchpadEventArgs arg) { } - - public void touchUnchanged(object sender, EventArgs unused) { } - } -} diff --git a/DS4Control/DS4Control.csproj b/DS4Control/DS4Control.csproj index d11ad68..46897b4 100644 --- a/DS4Control/DS4Control.csproj +++ b/DS4Control/DS4Control.csproj @@ -41,14 +41,9 @@ - - - - - diff --git a/DS4Control/DragMouse.cs b/DS4Control/DragMouse.cs deleted file mode 100644 index be9f97b..0000000 --- a/DS4Control/DragMouse.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Runtime.InteropServices; -using DS4Library; -using System.Threading; - -namespace DS4Control -{ - class DragMouse: Mouse - { - protected bool leftClick = false; - protected Timer timer; - private readonly MouseCursor cursor; - private readonly MouseWheel wheel; - - public DragMouse(int deviceID):base(deviceID) - { - timer = new System.Threading.Timer((a) => - { - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTUP); - leftClick = false; - }, null, - System.Threading.Timeout.Infinite, - System.Threading.Timeout.Infinite); - cursor = new MouseCursor(deviceNum); - wheel = new MouseWheel(deviceNum); - } - - public override string ToString() - { - return "Drag Mode"; - } - - public override void touchesBegan(object sender, TouchpadEventArgs arg) - { - base.touchesBegan(sender, arg); - if (leftClick) - timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); - } - - public override void touchesEnded(object sender, TouchpadEventArgs arg) - { - if (Global.getTapSensitivity(deviceNum) != 0) - { - DateTime test = arg.timeStamp; - if (test <= (pastTime + TimeSpan.FromMilliseconds((double)Global.getTapSensitivity(deviceNum) * 2)) && !arg.touchButtonPressed) - { - if (Math.Abs(firstTouch.hwX - arg.touches[0].hwX) < 10 && - Math.Abs(firstTouch.hwY - arg.touches[0].hwY) < 10) - { - if (leftClick) - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTUP); - - leftClick = true; - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTDOWN); - timer.Change(Global.getTapSensitivity(deviceNum) * 2, System.Threading.Timeout.Infinite); - } - } - else if (leftClick) - { - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTUP); - leftClick = false; - } - } - } - - public override void touchButtonUp(object sender, TouchpadEventArgs arg) - { - if (arg.touches == null) - { - //No touches, finger on upper portion of touchpad - mapTouchPad(DS4Controls.TouchUpper, true); - } - else if (arg.touches.Length > 1) - mapTouchPad(DS4Controls.TouchMulti, true); - else if (!rightClick && arg.touches.Length == 1 && !mapTouchPad(DS4Controls.TouchButton, true)) - { - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTUP); - leftClick = false; - } - } - - public override void touchButtonDown(object sender, TouchpadEventArgs arg) - { - if (arg.touches == null) - { - //No touches, finger on upper portion of touchpad - if (!mapTouchPad(DS4Controls.TouchUpper)) - InputMethods.performMiddleClick(); - } - else if (!Global.getLowerRCOff(deviceNum) && arg.touches[0].hwX > (1920 * 3) / 4 - && arg.touches[0].hwY > (960 * 3) / 4) - { - rightClick = true; - InputMethods.performRightClick(); - } - else if (arg.touches.Length > 1 && !mapTouchPad(DS4Controls.TouchMulti)) - { - rightClick = true; - InputMethods.performRightClick(); - } - else if (arg.touches.Length == 1 && !mapTouchPad(DS4Controls.TouchButton)) - { - rightClick = false; - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTDOWN); - leftClick = true; - } - } - } -} diff --git a/DS4Control/InputMethods.cs b/DS4Control/InputMethods.cs index e169490..956f90b 100644 --- a/DS4Control/InputMethods.cs +++ b/DS4Control/InputMethods.cs @@ -73,6 +73,21 @@ namespace DS4Control } } + public static void MouseEvent(uint mouseButton, int type) + { + lock (lockob) + { + sendInputs[0].Type = INPUT_MOUSE; + sendInputs[0].Data.Mouse.ExtraInfo = IntPtr.Zero; + sendInputs[0].Data.Mouse.Flags = mouseButton; + sendInputs[0].Data.Mouse.MouseData = (uint)type; + sendInputs[0].Data.Mouse.Time = 0; + sendInputs[0].Data.Mouse.X = 0; + sendInputs[0].Data.Mouse.Y = 0; + uint result = SendInput(1, sendInputs, Marshal.SizeOf(sendInputs[0])); + } + } + public static void performLeftClick() { lock (lockob) @@ -121,6 +136,21 @@ namespace DS4Control } } + public static void performFourthClick() + { + lock (lockob) + { + sendInputs[0].Type = INPUT_MOUSE; + sendInputs[0].Data.Mouse.ExtraInfo = IntPtr.Zero; + sendInputs[0].Data.Mouse.Flags = 0; + sendInputs[0].Data.Mouse.Flags |= MOUSEEVENTF_XBUTTONDOWN | MOUSEEVENTF_XBUTTONUP; + sendInputs[0].Data.Mouse.MouseData = 1; + sendInputs[0].Data.Mouse.Time = 0; + sendInputs[0].Data.Mouse.X = 0; + sendInputs[0].Data.Mouse.Y = 0; + uint result = SendInput(1, sendInputs, Marshal.SizeOf(sendInputs[0])); + } + } public static void performSCKeyPress(ushort key) { lock (lockob) @@ -244,7 +274,9 @@ namespace DS4Control MOUSEEVENTF_LEFTDOWN = 2, MOUSEEVENTF_LEFTUP = 4, MOUSEEVENTF_RIGHTDOWN = 8, MOUSEEVENTF_RIGHTUP = 16, MOUSEEVENTF_MIDDLEDOWN = 32, MOUSEEVENTF_MIDDLEUP = 64, + MOUSEEVENTF_XBUTTONDOWN = 128, MOUSEEVENTF_XBUTTONUP = 256, KEYEVENTF_KEYUP = 2, MOUSEEVENTF_WHEEL = 0x0800, MOUSEEVENTF_HWHEEL = 0x1000, + MOUSEEVENTF_MIDDLEWDOWN = 0x0020, MOUSEEVENTF_MIDDLEWUP = 0x0040, KEYEVENTF_SCANCODE = 0x0008, MAPVK_VK_TO_VSC = 0; [DllImport("user32.dll", SetLastError = true)] diff --git a/DS4Control/Mapping.cs b/DS4Control/Mapping.cs index ad310da..111ac19 100644 --- a/DS4Control/Mapping.cs +++ b/DS4Control/Mapping.cs @@ -5,45 +5,338 @@ using System.Text; using DS4Library; namespace DS4Control { - class Mapping + public class Mapping { - public static void mapButtons(DS4State cState, DS4State prevState, DS4State MappedState) + /* + * Represent the synthetic keyboard and mouse events. Maintain counts for each so we don't duplicate events. + */ + private class SyntheticState { - foreach (KeyValuePair customKey in Global.getCustomKeys()) + public struct MouseClick { - DS4KeyType keyType = Global.getCustomKeyType(customKey.Key); - bool PrevOn = getBoolMapping(customKey.Key, prevState); + public int leftCount, middleCount, rightCount, fourthCount, fifthCount, wUpCount, wDownCount; + } + public MouseClick previousClicks, currentClicks; + public struct KeyPress + { + public int vkCount, scanCodeCount, repeatCount; // repeat takes priority over non-, and scancode takes priority over non- + } + public class KeyPresses + { + public KeyPress previous, current; + } + public Dictionary keyPresses = new Dictionary(); + + public void SavePrevious(bool performClear) + { + previousClicks = currentClicks; + if (performClear) + currentClicks.leftCount = currentClicks.middleCount = currentClicks.rightCount = currentClicks.fourthCount = currentClicks.fifthCount = currentClicks.wUpCount = currentClicks.wDownCount = 0; + foreach (KeyPresses kp in keyPresses.Values) + { + kp.previous = kp.current; + if (performClear) + kp.current.repeatCount = kp.current.scanCodeCount = kp.current.vkCount = 0; + } + } + } + private static SyntheticState globalState = new SyntheticState(); + private static SyntheticState[] deviceState = { new SyntheticState(), new SyntheticState(), new SyntheticState(), new SyntheticState() }; + + // TODO When we disconnect, process a null/dead state to release any keys or buttons. + public static void Commit(int device) + { + SyntheticState state = deviceState[device]; + lock (globalState) + { + globalState.currentClicks.leftCount += state.currentClicks.leftCount - state.previousClicks.leftCount; + if (globalState.currentClicks.leftCount != 0 && globalState.previousClicks.leftCount == 0) + InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTDOWN); + else if (globalState.currentClicks.leftCount == 0 && globalState.previousClicks.leftCount != 0) + InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTUP); + + globalState.currentClicks.middleCount += state.currentClicks.middleCount - state.previousClicks.middleCount; + if (globalState.currentClicks.middleCount != 0 && globalState.previousClicks.middleCount == 0) + InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_MIDDLEDOWN); + else if (globalState.currentClicks.middleCount == 0 && globalState.previousClicks.middleCount != 0) + InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_MIDDLEUP); + + globalState.currentClicks.rightCount += state.currentClicks.rightCount - state.previousClicks.rightCount; + if (globalState.currentClicks.rightCount != 0 && globalState.previousClicks.rightCount == 0) + InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_RIGHTDOWN); + else if (globalState.currentClicks.rightCount == 0 && globalState.previousClicks.rightCount != 0) + InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_RIGHTUP); + + globalState.currentClicks.fourthCount += state.currentClicks.fourthCount - state.previousClicks.fourthCount; + if (globalState.currentClicks.fourthCount != 0 && globalState.previousClicks.fourthCount == 0) + InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_XBUTTONDOWN, 1); + else if (globalState.currentClicks.fourthCount == 0 && globalState.previousClicks.fourthCount != 0) + InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_XBUTTONUP, 1); + + globalState.currentClicks.fifthCount += state.currentClicks.fifthCount - state.previousClicks.fifthCount; + if (globalState.currentClicks.fifthCount != 0 && globalState.previousClicks.fifthCount == 0) + InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_XBUTTONDOWN, 2); + else if (globalState.currentClicks.fifthCount == 0 && globalState.previousClicks.fifthCount != 0) + InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_XBUTTONUP, 2); + + globalState.currentClicks.wUpCount += state.currentClicks.wUpCount - state.previousClicks.wUpCount; + if (globalState.currentClicks.wUpCount != 0 && globalState.previousClicks.wUpCount == 0) + InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_WHEEL, 100); + + globalState.currentClicks.wDownCount += state.currentClicks.wDownCount - state.previousClicks.wDownCount; + if (globalState.currentClicks.wDownCount != 0 && globalState.previousClicks.wDownCount == 0) + InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_WHEEL, -100); + + // Merge and synthesize all key presses/releases that are present in this device's mapping. + // TODO what about the rest? e.g. repeat keys really ought to be on some set schedule + foreach (KeyValuePair kvp in state.keyPresses) + { + SyntheticState.KeyPresses gkp; + if (globalState.keyPresses.TryGetValue(kvp.Key, out gkp)) + { + gkp.current.vkCount += kvp.Value.current.vkCount - kvp.Value.previous.vkCount; + gkp.current.scanCodeCount += kvp.Value.current.scanCodeCount - kvp.Value.previous.scanCodeCount; + gkp.current.repeatCount += kvp.Value.current.repeatCount - kvp.Value.previous.repeatCount; + } + else + { + gkp = new SyntheticState.KeyPresses(); + gkp.current = kvp.Value.current; + globalState.keyPresses[kvp.Key] = gkp; + } + + if (gkp.current.vkCount + gkp.current.scanCodeCount != 0 && gkp.previous.vkCount + gkp.previous.scanCodeCount == 0) + { + if (gkp.current.scanCodeCount != 0) + InputMethods.performSCKeyPress(kvp.Key); + else + InputMethods.performKeyPress(kvp.Key); + } + else if (gkp.current.repeatCount != 0 || // repeat or SC/VK transition + ((gkp.previous.scanCodeCount == 0) != (gkp.current.scanCodeCount == 0))) + { + if (gkp.previous.scanCodeCount != 0) // use the last type of VK/SC + InputMethods.performSCKeyRelease(kvp.Key); + else + InputMethods.performKeyRelease(kvp.Key); + + if (gkp.current.scanCodeCount != 0) + InputMethods.performSCKeyPress(kvp.Key); + else + InputMethods.performKeyPress(kvp.Key); + } + else if (gkp.current.vkCount + gkp.current.scanCodeCount == 0 && gkp.previous.vkCount + gkp.previous.scanCodeCount != 0) + { + if (gkp.previous.scanCodeCount != 0) // use the last type of VK/SC + InputMethods.performSCKeyRelease(kvp.Key); + else + InputMethods.performKeyRelease(kvp.Key); + } + } + globalState.SavePrevious(false); + } + state.SavePrevious(true); + } + public enum Click { None, Left, Middle, Right, Fourth, Fifth, WUP, WDOWN }; + public static void MapClick(int device, Click mouseClick) + { + switch (mouseClick) + { + case Click.Left: + deviceState[device].currentClicks.leftCount++; + break; + case Click.Middle: + deviceState[device].currentClicks.middleCount++; + break; + case Click.Right: + deviceState[device].currentClicks.rightCount++; + break; + case Click.Fourth: + deviceState[device].currentClicks.fourthCount++; + break; + case Click.Fifth: + deviceState[device].currentClicks.fifthCount++; + break; + case Click.WUP: + deviceState[device].currentClicks.wUpCount++; + break; + case Click.WDOWN: + deviceState[device].currentClicks.wDownCount++; + break; + } + } + + /** Map the touchpad button state to mouse or keyboard events. */ + public static void MapTouchpadButton(int device, DS4Controls what, Click mouseEventFallback, DS4State MappedState = null) + { + SyntheticState deviceState = Mapping.deviceState[device]; + ushort key = Global.getCustomKey(device, what); + if (key != 0) + { + + DS4KeyType keyType = Global.getCustomKeyType(device, what); + SyntheticState.KeyPresses kp; + if (!deviceState.keyPresses.TryGetValue(key, out kp)) + deviceState.keyPresses[key] = kp = new SyntheticState.KeyPresses(); + if (keyType.HasFlag(DS4KeyType.ScanCode)) + kp.current.scanCodeCount++; + else + kp.current.vkCount++; + if (keyType.HasFlag(DS4KeyType.Repeat)) + kp.current.repeatCount++; + } + else + { + X360Controls button = Global.getCustomButton(device, what); + switch (button) + { + case X360Controls.None: + switch (mouseEventFallback) + { + case Click.Left: + deviceState.currentClicks.leftCount++; + return; + case Click.Middle: + deviceState.currentClicks.middleCount++; + return; + case Click.Right: + deviceState.currentClicks.rightCount++; + return; + case Click.Fourth: + deviceState.currentClicks.fourthCount++; + return; + case Click.Fifth: + deviceState.currentClicks.fifthCount++; + return; + case Click.WUP: + deviceState.currentClicks.wUpCount++; + return; + case Click.WDOWN: + deviceState.currentClicks.wDownCount++; + return; + } + return; + case X360Controls.LeftMouse: + deviceState.currentClicks.leftCount++; + return; + case X360Controls.MiddleMouse: + deviceState.currentClicks.middleCount++; + return; + case X360Controls.RightMouse: + deviceState.currentClicks.rightCount++; + return; + case X360Controls.FourthMouse: + deviceState.currentClicks.fourthCount++; + return; + case X360Controls.FifthMouse: + deviceState.currentClicks.fifthCount++; + return; + case X360Controls.WUP: + deviceState.currentClicks.wUpCount++; + return; + case X360Controls.WDOWN: + deviceState.currentClicks.wDownCount++; + return; + + case X360Controls.A: + MappedState.Cross = true; + return; + case X360Controls.B: + MappedState.Circle = true; + return; + case X360Controls.X: + MappedState.Square = true; + return; + case X360Controls.Y: + MappedState.Triangle = true; + return; + case X360Controls.LB: + MappedState.L1 = true; + return; + case X360Controls.LS: + MappedState.L3 = true; + return; + case X360Controls.RB: + MappedState.R1 = true; + return; + case X360Controls.RS: + MappedState.R3 = true; + return; + case X360Controls.DpadUp: + MappedState.DpadUp = true; + return; + case X360Controls.DpadDown: + MappedState.DpadDown = true; + return; + case X360Controls.DpadLeft: + MappedState.DpadLeft = true; + return; + case X360Controls.DpadRight: + MappedState.DpadRight = true; + return; + case X360Controls.Guide: + MappedState.PS = true; + return; + case X360Controls.Back: + MappedState.Share = true; + return; + case X360Controls.Start: + MappedState.Options = true; + return; + case X360Controls.LT: + if (MappedState.L2 == 0) + MappedState.L2 = 255; + return; + case X360Controls.RT: + if (MappedState.R2 == 0) + MappedState.R2 = 255; + return; + + case X360Controls.Unbound: + return; + + default: + if (MappedState == null) + return; + break; + } + } + } + + /** Map DS4 Buttons/Axes to other DS4 Buttons/Axes (largely the same as Xinput ones) and to keyboard and mouse buttons. */ + public static void MapCustom(int device, DS4State cState, DS4State MappedState) + { + cState.CopyTo(MappedState); + SyntheticState deviceState = Mapping.deviceState[device]; + foreach (KeyValuePair customKey in Global.getCustomKeys(device)) + { + DS4KeyType keyType = Global.getCustomKeyType(device, customKey.Key); if (getBoolMapping(customKey.Key, cState)) { - resetToDefaultValue(customKey.Key, cState); - if (!PrevOn) - { - - if (keyType.HasFlag(DS4KeyType.ScanCode)) - InputMethods.performSCKeyPress(customKey.Value); - else InputMethods.performKeyPress(customKey.Value); - } - else if (keyType.HasFlag(DS4KeyType.Repeat)) - if (keyType.HasFlag(DS4KeyType.ScanCode)) - InputMethods.performSCKeyPress(customKey.Value); - else InputMethods.performKeyPress(customKey.Value); - } - else if (PrevOn) + resetToDefaultValue(customKey.Key, MappedState); + SyntheticState.KeyPresses kp; + if (!deviceState.keyPresses.TryGetValue(customKey.Value, out kp)) + deviceState.keyPresses[customKey.Value] = kp = new SyntheticState.KeyPresses(); if (keyType.HasFlag(DS4KeyType.ScanCode)) - InputMethods.performSCKeyRelease(customKey.Value); - else InputMethods.performKeyRelease(customKey.Value); + kp.current.scanCodeCount++; + else + kp.current.vkCount++; + if (keyType.HasFlag(DS4KeyType.Repeat)) + kp.current.repeatCount++; + } } - cState.Copy(MappedState); bool LX = false, LY = false, RX = false, RY = false; MappedState.LX = 127; MappedState.LY = 127; MappedState.RX = 127; MappedState.RY = 127; - foreach (KeyValuePair customButton in Global.getCustomButtons()) + Dictionary customButtons = Global.getCustomButtons(device); + foreach (KeyValuePair customButton in customButtons) + resetToDefaultValue(customButton.Key, MappedState); // erase default mappings for things that are remapped + foreach (KeyValuePair customButton in customButtons) { - bool LXChanged = MappedState.LX == 127; bool LYChanged = MappedState.LY == 127; bool RXChanged = MappedState.RX == 127; @@ -51,49 +344,64 @@ namespace DS4Control switch (customButton.Value) { case X360Controls.A: - MappedState.Cross = getBoolMapping(customButton.Key, cState); + if (!MappedState.Cross) + MappedState.Cross = getBoolMapping(customButton.Key, cState); break; case X360Controls.B: + if (!MappedState.Circle) MappedState.Circle = getBoolMapping(customButton.Key, cState); break; case X360Controls.X: + if (!MappedState.Square) MappedState.Square = getBoolMapping(customButton.Key, cState); break; case X360Controls.Y: + if (!MappedState.Triangle) MappedState.Triangle = getBoolMapping(customButton.Key, cState); break; case X360Controls.LB: + if (!MappedState.L1) MappedState.L1 = getBoolMapping(customButton.Key, cState); break; case X360Controls.LS: - MappedState.L3 = getBoolMapping(customButton.Key, cState); + if (!MappedState.L3) + MappedState.L3 = getBoolMapping(customButton.Key, cState); break; case X360Controls.RB: - MappedState.R1 = getBoolMapping(customButton.Key, cState); + if (!MappedState.R1) + MappedState.R1 = getBoolMapping(customButton.Key, cState); break; case X360Controls.RS: - MappedState.R3 = getBoolMapping(customButton.Key, cState); + if (!MappedState.R3) + MappedState.R3 = getBoolMapping(customButton.Key, cState); break; case X360Controls.DpadUp: - MappedState.DpadUp = getBoolMapping(customButton.Key, cState); + if (!MappedState.DpadUp) + MappedState.DpadUp = getBoolMapping(customButton.Key, cState); break; case X360Controls.DpadDown: - MappedState.DpadDown = getBoolMapping(customButton.Key, cState); + if (!MappedState.DpadDown) + MappedState.DpadDown = getBoolMapping(customButton.Key, cState); break; case X360Controls.DpadLeft: - MappedState.DpadLeft = getBoolMapping(customButton.Key, cState); + if (!MappedState.DpadLeft) + MappedState.DpadLeft = getBoolMapping(customButton.Key, cState); break; case X360Controls.DpadRight: - MappedState.DpadRight = getBoolMapping(customButton.Key, cState); + if (!MappedState.DpadRight) + MappedState.DpadRight = getBoolMapping(customButton.Key, cState); break; case X360Controls.Guide: - MappedState.PS = getBoolMapping(customButton.Key, cState); + if (!MappedState.PS) + MappedState.PS = getBoolMapping(customButton.Key, cState); break; case X360Controls.Back: - MappedState.Share = getBoolMapping(customButton.Key, cState); + if (!MappedState.Share) + MappedState.Share = getBoolMapping(customButton.Key, cState); break; case X360Controls.Start: - MappedState.Options = getBoolMapping(customButton.Key, cState); + if (!MappedState.Options) + MappedState.Options = getBoolMapping(customButton.Key, cState); break; case X360Controls.LXNeg: if (LXChanged) @@ -158,31 +466,32 @@ namespace DS4Control MappedState.R2 = getByteMapping(customButton.Key, cState); break; case X360Controls.LeftMouse: - bool PrevOn = getBoolMapping(customButton.Key, prevState); - bool CurOn = getBoolMapping(customButton.Key, cState); - if (!PrevOn && CurOn) - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTDOWN); - else if (PrevOn && !CurOn) - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTUP); + if (getBoolMapping(customButton.Key, cState)) + deviceState.currentClicks.leftCount++; break; case X360Controls.RightMouse: - PrevOn = getBoolMapping(customButton.Key, prevState); - CurOn = getBoolMapping(customButton.Key, cState); - if (!PrevOn && CurOn) - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_RIGHTDOWN); - else if (PrevOn && !CurOn) - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_RIGHTUP); + if (getBoolMapping(customButton.Key, cState)) + deviceState.currentClicks.rightCount++; break; case X360Controls.MiddleMouse: - PrevOn = getBoolMapping(customButton.Key, prevState); - CurOn = getBoolMapping(customButton.Key, cState); - if (!PrevOn && CurOn) - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_MIDDLEDOWN); - else if (PrevOn && !CurOn) - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_MIDDLEUP); + if (getBoolMapping(customButton.Key, cState)) + deviceState.currentClicks.middleCount++; break; - case X360Controls.Unbound: - resetToDefaultValue(customButton.Key, MappedState); + case X360Controls.FourthMouse: + if (getBoolMapping(customButton.Key, cState)) + deviceState.currentClicks.fourthCount++; + break; + case X360Controls.FifthMouse: + if (getBoolMapping(customButton.Key, cState)) + deviceState.currentClicks.fifthCount++; + break; + case X360Controls.WUP: + if (getBoolMapping(customButton.Key, cState)) + deviceState.currentClicks.wUpCount++; + break; + case X360Controls.WDOWN: + if (getBoolMapping(customButton.Key, cState)) + deviceState.currentClicks.wDownCount++; break; } } @@ -196,7 +505,11 @@ namespace DS4Control if (!RY) MappedState.RY = cState.RY; } - + static Mouse[] mouses; + public static void GetMouses(ref Mouse[] mouss) + { + mouses = mouss; + } public static bool compare(byte b1, byte b2) { if (Math.Abs(b1 - b2) > 10) @@ -205,8 +518,24 @@ namespace DS4Control } return true; } + + static bool[] touchArea = { true, true, true, true }; public static byte getByteMapping(DS4Controls control, DS4State cState) { + if (!cState.TouchButton) + for (int i = 0; i < 4; i++) + touchArea[i] = false; + if (!(touchArea[0] || touchArea[1] || touchArea[2] || touchArea[3])) + { + if (cState.Touch2) + touchArea[0] = true; + if (cState.TouchLeft && !cState.Touch2 && cState.Touch1) + touchArea[1] = true; + if (cState.TouchRight && !cState.Touch2 && cState.Touch1) + touchArea[2] = true; + if (!cState.Touch1) + touchArea[3] = true; + } switch (control) { case DS4Controls.Share: return (byte)(cState.Share ? 255 : 0); @@ -235,11 +564,39 @@ namespace DS4Control case DS4Controls.L2: return cState.L2; case DS4Controls.R2: return cState.R2; } + if (cState.TouchButton) + { + if (control == DS4Controls.TouchMulti) + if (!(touchArea[1] || touchArea[2] || touchArea[3])) + return (byte)(touchArea[0] ? 255 : 0); + if (control == DS4Controls.TouchLeft) + if (!(touchArea[0] || touchArea[2] || touchArea[3])) + return (byte)(touchArea[1] ? 255 : 0); + if (control == DS4Controls.TouchRight) + if (!(touchArea[0] || touchArea[1] || touchArea[3])) + return (byte)(touchArea[2] ? 255 : 0); + if (control == DS4Controls.TouchUpper) + if (!(touchArea[0] || touchArea[1] || touchArea[2])) + return (byte)(touchArea[3] ? 255 : 0); + } return 0; } - public static bool getBoolMapping(DS4Controls control, DS4State cState) { + if (!cState.TouchButton) + for (int i = 0; i < 4; i++) + touchArea[i] = false; + if (!(touchArea[0] || touchArea[1] || touchArea[2] || touchArea[3])) + { + if (cState.Touch2) + touchArea[0] = true; + if (cState.TouchLeft && !cState.Touch2 && cState.Touch1) + touchArea[1] = true; + if (cState.TouchRight && !cState.Touch2 && cState.Touch1) + touchArea[2] = true; + if (!cState.Touch1) + touchArea[3] = true; + } switch (control) { case DS4Controls.Share: return cState.Share; @@ -267,6 +624,22 @@ namespace DS4Control case DS4Controls.RYPos: return cState.RY > 200; case DS4Controls.L2: return cState.L2 > 100; case DS4Controls.R2: return cState.R2 > 100; + + } + if (cState.TouchButton) + { + if (control == DS4Controls.TouchMulti) + if (!(touchArea[1] || touchArea[2] || touchArea[3])) + return touchArea[0]; + if (control == DS4Controls.TouchLeft) + if (!(touchArea[0] || touchArea[2] || touchArea[3])) + return touchArea[1]; + if (control == DS4Controls.TouchRight) + if (!(touchArea[0] || touchArea[1] || touchArea[3])) + return touchArea[2]; + if (control == DS4Controls.TouchUpper) + if (!(touchArea[0] || touchArea[1] || touchArea[2])) + return touchArea[3]; } return false; } @@ -279,6 +652,20 @@ namespace DS4Control { trueVal = 255; } + if (!cState.TouchButton) + for (int i = 0; i < 4; i++) + touchArea[i] = false; + if (!(touchArea[0] || touchArea[1] || touchArea[2] || touchArea[3])) + { + if (cState.Touch2) + touchArea[0] = true; + if (cState.TouchLeft && !cState.Touch2 && cState.Touch1) + touchArea[1] = true; + if (cState.TouchRight && !cState.Touch2 && cState.Touch1) + touchArea[2] = true; + if (!cState.Touch1) + touchArea[3] = true; + } switch (control) { case DS4Controls.Share: return (byte)(cState.Share ? trueVal : falseVal); @@ -328,6 +715,21 @@ namespace DS4Control case DS4Controls.RYPos: return cState.RY; } } + if (cState.TouchButton) + { + if (control == DS4Controls.TouchMulti) + if (!(touchArea[1] || touchArea[2] || touchArea[3])) + return (byte)(touchArea[0] ? trueVal : falseVal); + if (control == DS4Controls.TouchLeft) + if (!(touchArea[0] || touchArea[2] || touchArea[3])) + return (byte)(touchArea[1] ? trueVal : falseVal); + if (control == DS4Controls.TouchRight) + if (!(touchArea[0] || touchArea[1] || touchArea[3])) + return (byte)(touchArea[2] ? trueVal : falseVal); + if (control == DS4Controls.TouchUpper) + if (!(touchArea[0] || touchArea[1] || touchArea[2])) + return (byte)(touchArea[3] ? trueVal : falseVal); + } return 0; } @@ -363,6 +765,10 @@ namespace DS4Control case DS4Controls.RYPos: cState.RY = 127; break; case DS4Controls.L2: cState.L2 = 0; break; case DS4Controls.R2: cState.R2 = 0; break; + //case DS4Controls.TouchButton: cState.TouchLeft = false; break; + //case DS4Controls.TouchMulti: cState.Touch2 = false; break; + //case DS4Controls.TouchRight: cState.TouchRight = false; break; + //case DS4Controls.TouchUpper: cState.TouchButton = false; break; } } diff --git a/DS4Control/Mouse.cs b/DS4Control/Mouse.cs index db9d9a0..bb33962 100644 --- a/DS4Control/Mouse.cs +++ b/DS4Control/Mouse.cs @@ -10,14 +10,16 @@ namespace DS4Control { protected DateTime pastTime; protected Touch firstTouch; + private DS4State s = new DS4State(); protected int deviceNum; + private DS4Device dev = null; private readonly MouseCursor cursor; private readonly MouseWheel wheel; - protected bool rightClick = false; - public Mouse(int deviceID) + public Mouse(int deviceID, DS4Device d) { deviceNum = deviceID; + dev = d; cursor = new MouseCursor(deviceNum); wheel = new MouseWheel(deviceNum); } @@ -27,11 +29,20 @@ namespace DS4Control return "Standard Mode"; } + protected virtual void MapClicks() + { + if (pushed != DS4Controls.None) + Mapping.MapTouchpadButton(deviceNum, pushed, clicked); + } + public virtual void touchesMoved(object sender, TouchpadEventArgs arg) { cursor.touchesMoved(arg); wheel.touchesMoved(arg); - //Log.LogToGui("moved to " + arg.touches[0].hwX + "," + arg.touches[0].hwY); + //MapClicks(); + dev.getCurrentState(s); + synthesizeMouseButtons(); + //Console.WriteLine(arg.timeStamp.ToString("O") + " " + "moved to " + arg.touches[0].hwX + "," + arg.touches[0].hwY); } public virtual void touchesBegan(object sender, TouchpadEventArgs arg) @@ -40,87 +51,124 @@ namespace DS4Control wheel.touchesBegan(arg); pastTime = arg.timeStamp; firstTouch = arg.touches[0]; - //Log.LogToGui("began at " + arg.touches[0].hwX + "," + arg.touches[0].hwY); + dev.getCurrentState(s); + synthesizeMouseButtons(); + //MapClicks(); + //Console.WriteLine(arg.timeStamp.ToString("O") + " " + "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); + //Console.WriteLine(arg.timeStamp.ToString("O") + " " + "ended at " + arg.touches[0].hwX + "," + arg.touches[0].hwY); if (Global.getTapSensitivity(deviceNum) != 0) { DateTime test = arg.timeStamp; if (test <= (pastTime + TimeSpan.FromMilliseconds((double)Global.getTapSensitivity(deviceNum) * 2)) && !arg.touchButtonPressed) { - if (Math.Abs(firstTouch.hwX - arg.touches[0].hwX) < 10 && - Math.Abs(firstTouch.hwY - arg.touches[0].hwY) < 10) - InputMethods.performLeftClick(); + if (Math.Abs(firstTouch.hwX - arg.touches[0].hwX) < 10 && Math.Abs(firstTouch.hwY - arg.touches[0].hwY) < 10) + Mapping.MapClick(deviceNum, Mapping.Click.Left); } } + dev.getCurrentState(s); + //if (buttonLock) + synthesizeMouseButtons(); + //MapClicks(); + } + + protected DS4Controls pushed = DS4Controls.None; + protected Mapping.Click clicked = Mapping.Click.None; + + // touch area stuff + public bool leftDown, rightDown, upperDown, multiDown, lowerRDown; + private bool isLeft(Touch t) + { + return t.hwX < 1920 * 2 / 5; + } + + private bool isRight(Touch t) + { + return t.hwX >= 1920 * 2 / 5; + } + + public virtual void touchUnchanged(object sender, EventArgs unused) + { + //MapClicks(); + dev.getCurrentState(s); + if (s.Touch1 || s.Touch2 || s.TouchButton) + synthesizeMouseButtons(); + } + + private DS4State remapped = new DS4State(); + private void synthesizeMouseButtons() + { + //Mapping.MapCustom(deviceNum, s, remapped); + if (leftDown) + Mapping.MapTouchpadButton(deviceNum, DS4Controls.TouchLeft, Mapping.Click.Left, remapped); + if (upperDown) + Mapping.MapTouchpadButton(deviceNum, DS4Controls.TouchUpper, Mapping.Click.Middle, remapped); + if (rightDown) + Mapping.MapTouchpadButton(deviceNum, DS4Controls.TouchRight, Mapping.Click.Left, remapped); + if (multiDown) + Mapping.MapTouchpadButton(deviceNum, DS4Controls.TouchMulti, Mapping.Click.Right, remapped); + if (lowerRDown) + Mapping.MapClick(deviceNum, Mapping.Click.Right); + s = remapped; + //remapped.CopyTo(s); } public virtual void touchButtonUp(object sender, TouchpadEventArgs arg) { - if (arg.touches == null) - { - //No touches, finger on upper portion of touchpad - mapTouchPad(DS4Controls.TouchUpper,true); - } - else if (arg.touches.Length > 1) - mapTouchPad(DS4Controls.TouchMulti, true); - else if (!rightClick && arg.touches.Length == 1 && !mapTouchPad(DS4Controls.TouchButton, true)) - { - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTUP); - } + pushed = DS4Controls.None; + upperDown = leftDown = rightDown = multiDown = false; + dev.setRumble(0, 0); + dev.getCurrentState(s); + if (s.Touch1 || s.Touch2) + synthesizeMouseButtons(); } public virtual void touchButtonDown(object sender, TouchpadEventArgs arg) { + //byte leftRumble, rightRumble; if (arg.touches == null) { //No touches, finger on upper portion of touchpad - if(!mapTouchPad(DS4Controls.TouchUpper)) - InputMethods.performMiddleClick(); + //leftRumble = rightRumble = 0; + upperDown = true; } - else if (!Global.getLowerRCOff(deviceNum) && arg.touches[0].hwX > (1920 * 3)/4 - && arg.touches[0].hwY > (960 * 3)/4) + else if (arg.touches.Length > 1 )//|| (Global.getLowerRCOn(deviceNum) && arg.touches[0].hwX > (1920 * 3) / 4 && arg.touches[0].hwY > (960 * 3) / 4)) { - rightClick = true; - InputMethods.performRightClick(); + //leftRumble = rightRumble = 150; + multiDown = true; } - else if (arg.touches.Length>1 && !mapTouchPad(DS4Controls.TouchMulti)) - { - rightClick = true; - InputMethods.performRightClick(); - } - else if (arg.touches.Length==1 && !mapTouchPad(DS4Controls.TouchButton)) - { - rightClick = false; - InputMethods.MouseEvent(InputMethods.MOUSEEVENTF_LEFTDOWN); - } - } - - public void touchUnchanged(object sender, EventArgs unused) { } - - protected bool mapTouchPad(DS4Controls padControl, bool release = false) - { - ushort key = Global.getCustomKey(padControl); - if (key == 0) - return false; else { - DS4KeyType keyType = Global.getCustomKeyType(padControl); - if (!release) - if (keyType.HasFlag(DS4KeyType.ScanCode)) - InputMethods.performSCKeyPress(key); - else InputMethods.performKeyPress(key); + if ((Global.getLowerRCOn(deviceNum) && arg.touches[0].hwX > (1920 * 3) / 4 && arg.touches[0].hwY > (960 * 3) / 4)) + Mapping.MapClick(deviceNum, Mapping.Click.Right); + if (isLeft(arg.touches[0])) + { + leftDown = true; + //leftRumble = 25; + //rightRumble = 0; + } + else if (isRight(arg.touches[0])) + { + rightDown = true; + //leftRumble = 0; + //rightRumble = 25; + } else - if (!keyType.HasFlag(DS4KeyType.Repeat)) - if (keyType.HasFlag(DS4KeyType.ScanCode)) - InputMethods.performSCKeyRelease(key); - else InputMethods.performKeyRelease(key); - return true; + { + //leftRumble = rightRumble = 0; // Ignore ambiguous pushes. + } } + //dev.setRumble(rightRumble, leftRumble); // sustain while pressed + dev.getCurrentState(s); + synthesizeMouseButtons(); } + public DS4State getDS4State() + { + return s; + } } } diff --git a/DS4Control/MouseCursor.cs b/DS4Control/MouseCursor.cs index 63835a9..be65875 100644 --- a/DS4Control/MouseCursor.cs +++ b/DS4Control/MouseCursor.cs @@ -48,35 +48,36 @@ namespace DS4Control // Often the DS4's internal jitter compensation kicks in and starts hiding changes, ironically creating jitter... deltaX = arg.touches[0].deltaX; deltaY = arg.touches[0].deltaY; - // allow only very fine, slow motions, when changing direction - if (deltaX < -1) + // allow only very fine, slow motions, when changing direction, even from neutral + // TODO maybe just consume it completely? + if (deltaX <= -1) { - if (horizontalDirection == Direction.Positive) + if (horizontalDirection != Direction.Negative) { deltaX = -1; horizontalRemainder = 0.0; } } - else if (deltaX > 1) + else if (deltaX >= 1) { - if (horizontalDirection == Direction.Negative) + if (horizontalDirection != Direction.Positive) { deltaX = 1; horizontalRemainder = 0.0; } } - if (deltaY < -1) + if (deltaY <= -1) { - if (verticalDirection == Direction.Positive) + if (verticalDirection != Direction.Negative) { deltaY = -1; verticalRemainder = 0.0; } } - else if (deltaY > 1) + else if (deltaY >= 1) { - if (verticalDirection == Direction.Negative) + if (verticalDirection != Direction.Positive) { deltaY = 1; verticalRemainder = 0.0; @@ -122,8 +123,8 @@ namespace DS4Control if (yAction != 0 || xAction != 0) InputMethods.MoveCursorBy(xAction, yAction); - horizontalDirection = xAction > 0.0 ? Direction.Positive : xAction < 0.0 ? Direction.Negative : Direction.Neutral; - verticalDirection = yAction > 0.0 ? Direction.Positive : yAction < 0.0 ? Direction.Negative : Direction.Neutral; + horizontalDirection = xMotion > 0.0 ? Direction.Positive : xMotion < 0.0 ? Direction.Negative : Direction.Neutral; + verticalDirection = yMotion > 0.0 ? Direction.Positive : yMotion < 0.0 ? Direction.Negative : Direction.Neutral; } } } diff --git a/DS4Control/ScpUtil.cs b/DS4Control/ScpUtil.cs index 21d3d73..dc007e7 100644 --- a/DS4Control/ScpUtil.cs +++ b/DS4Control/ScpUtil.cs @@ -9,10 +9,10 @@ using DS4Library; namespace DS4Control { [Flags] - public enum DS4KeyType : byte { None = 0, ScanCode = 1, Repeat = 2 }; //Increment by exponents of 2*, starting at 2^0 + public enum DS4KeyType : byte { None = 0, ScanCode = 1, Repeat = 2, Unbound = 4 }; //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 }; + public enum DS4Controls : byte { None, LXNeg, LXPos, LYNeg, LYPos, RXNeg, RXPos, RYNeg, RYPos, L1, L2, L3, R1, R2, R3, Square, Triangle, Circle, Cross, DpadUp, DpadRight, DpadDown, DpadLeft, PS, TouchLeft, TouchUpper, TouchMulti, TouchRight, Share, Options }; + public enum X360Controls : byte { None, 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, FourthMouse, FifthMouse, WUP, WDOWN, Unbound }; public class DebugEventArgs : EventArgs { @@ -91,78 +91,85 @@ namespace DS4Control public static DS4Color loadColor(int device) { DS4Color color = new DS4Color(); - color.red = m_Config.m_Leds[device][0]; - color.green = m_Config.m_Leds[device][1]; - color.blue = m_Config.m_Leds[device][2]; + color.red = m_Config.m_Leds[0]; + color.green = m_Config.m_Leds[1]; + color.blue = m_Config.m_Leds[2]; return color; } public static void saveColor(int device, byte red, byte green, byte blue) { - m_Config.m_Leds[device][0] = red; - m_Config.m_Leds[device][1] = green; - m_Config.m_Leds[device][2] = blue; + m_Config.m_Leds[0] = red; + m_Config.m_Leds[1] = green; + m_Config.m_Leds[2] = blue; } public static byte loadRumbleBoost(int device) { - return m_Config.m_Rumble[device]; + return m_Config.m_Rumble; } public static void saveRumbleBoost(int device, byte boost) { - m_Config.m_Rumble[device] = boost; + m_Config.m_Rumble = boost; } + public static bool getRumbleSwap(int device) + { + return m_Config.rumbleSwap; + } + public static void setRumbleSwap(int device, bool swap) + { + m_Config.rumbleSwap = swap; + } + public static bool getFlushHIDQueue(int device) { - return m_Config.flushHIDQueue[device]; + return m_Config.flushHIDQueue; } public static void setFlushHIDQueue(int device, bool setting) { - m_Config.flushHIDQueue[device] = setting; + m_Config.flushHIDQueue = setting; + } + + public static int getIdleDisconnectTimeout(int device) + { + return m_Config.idleDisconnectTimeout; + } + public static void setIdleDisconnectTimeout(int device, int seconds) + { + m_Config.idleDisconnectTimeout = seconds; } public static byte getTouchSensitivity(int device) { - return m_Config.touchSensitivity[device]; + return m_Config.touchSensitivity; } public static void setTouchSensitivity(int device, byte sen) { - m_Config.touchSensitivity[device] = sen; - } + m_Config.touchSensitivity = sen; + } public static void setFlashWhenLowBattery(int device, bool flash) { - m_Config.flashLedLowBattery[device] = flash; + m_Config.flashLedLowBattery = flash; } public static bool getFlashWhenLowBattery(int device) { - return m_Config.flashLedLowBattery[device]; + return m_Config.flashLedLowBattery; } public static void setLedAsBatteryIndicator(int device, bool ledAsBattery) { - m_Config.ledAsBattery[device] = ledAsBattery; + m_Config.ledAsBattery = ledAsBattery; } public static bool getLedAsBatteryIndicator(int device) { - return m_Config.ledAsBattery[device]; + return m_Config.ledAsBattery; } - - public static void setTouchEnabled(int device, bool touchEnabled) - { - m_Config.touchEnabled[device] = touchEnabled; - - } - public static bool getTouchEnabled(int device) - { - return m_Config.touchEnabled[device]; - - } - + public static void setUseExclusiveMode(bool exclusive) { m_Config.useExclusiveMode = exclusive; @@ -175,49 +182,56 @@ namespace DS4Control // New settings public static void saveLowColor(int device, byte red, byte green, byte blue) { - m_Config.m_LowLeds[device][0] = red; - m_Config.m_LowLeds[device][1] = green; - m_Config.m_LowLeds[device][2] = blue; + m_Config.m_LowLeds[0] = red; + m_Config.m_LowLeds[1] = green; + m_Config.m_LowLeds[2] = blue; } public static DS4Color loadLowColor(int device) { DS4Color color = new DS4Color(); - color.red = m_Config.m_LowLeds[device][0]; - color.green = m_Config.m_LowLeds[device][1]; - color.blue = m_Config.m_LowLeds[device][2]; + color.red = m_Config.m_LowLeds[0]; + color.green = m_Config.m_LowLeds[1]; + color.blue = m_Config.m_LowLeds[2]; return color; } public static void setTapSensitivity(int device, byte sen) { - m_Config.tapSensitivity[device] = sen; + m_Config.tapSensitivity = sen; } public static byte getTapSensitivity(int device) { - return m_Config.tapSensitivity[device]; + return m_Config.tapSensitivity; + } + public static bool getTap(int device) + { + if (m_Config.tapSensitivity == 0) + return false; + else + return true; } public static void setScrollSensitivity(int device, int sen) { - m_Config.scrollSensitivity[device] = sen; + m_Config.scrollSensitivity = sen; } public static int getScrollSensitivity(int device) { - return m_Config.scrollSensitivity[device]; + return m_Config.scrollSensitivity; } - public static void setLowerRCOff(int device, bool twoFingerRC) + public static void setLowerRCOn(int device, bool twoFingerRC) { - m_Config.lowerRCOff[device] = twoFingerRC; + m_Config.lowerRCOn = twoFingerRC; } - public static bool getLowerRCOff(int device) + public static bool getLowerRCOn(int device) { - return m_Config.lowerRCOff[device]; + return m_Config.lowerRCOn; } public static void setTouchpadJitterCompensation(int device, bool enabled) { - m_Config.touchpadJitterCompensation[device] = enabled; + m_Config.touchpadJitterCompensation = enabled; } public static bool getTouchpadJitterCompensation(int device) { - return m_Config.touchpadJitterCompensation[device]; + return m_Config.touchpadJitterCompensation; } public static void setStartMinimized(bool startMinimized) { @@ -246,68 +260,55 @@ namespace DS4Control public static double getLeftTriggerMiddle(int device) { - return m_Config.m_LeftTriggerMiddle[device]; + return m_Config.m_LeftTriggerMiddle; } public static void setLeftTriggerMiddle(int device, double value) { - m_Config.m_LeftTriggerMiddle[device] = value; + m_Config.m_LeftTriggerMiddle = value; } public static double getRightTriggerMiddle(int device) { - return m_Config.m_RightTriggerMiddle[device]; + return m_Config.m_RightTriggerMiddle; } public static void setRightTriggerMiddle(int device, double value) { - m_Config.m_RightTriggerMiddle[device] = value; + m_Config.m_RightTriggerMiddle = value; } - - public static void setCustomMap(int device, string customMap) + public static void setAProfile(int device, string filepath) { - m_Config.customMapPath[device] = customMap; + m_Config.profilePath[device] = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName + @"\Profiles\" + filepath + ".xml"; } - public static string getCustomMap(int device) + public static string getAProfile(int device) { - return m_Config.customMapPath[device]; + return m_Config.profilePath[device]; } - public static bool saveCustomMapping(string customMapPath, System.Windows.Forms.Control[] buttons) + public static X360Controls getCustomButton(int device, DS4Controls controlName) { - return m_Config.SaveCustomMapping(customMapPath, buttons); + return m_Config.GetCustomButton(device, controlName); } - public static bool loadCustomMapping(string customMapPath, System.Windows.Forms.Control[] buttons) + public static ushort getCustomKey(int device, DS4Controls controlName) { - return m_Config.LoadCustomMapping(customMapPath, buttons); + return m_Config.GetCustomKey(device, controlName); } - public static bool loadCustomMapping(int device) + public static DS4KeyType getCustomKeyType(int device, DS4Controls controlName) { - return m_Config.LoadCustomMapping(getCustomMap(device)); - } - public static X360Controls getCustomButton(DS4Controls controlName) - { - return m_Config.GetCustomButton(controlName); - } - public static ushort getCustomKey(DS4Controls controlName) - { - return m_Config.GetCustomKey(controlName); - } - public static DS4KeyType getCustomKeyType(DS4Controls controlName) - { - return m_Config.GetCustomKeyType(controlName); + return m_Config.GetCustomKeyType(device, controlName); } public static bool getHasCustomKeysorButtons(int device) { return m_Config.customMapButtons.Count > 0 || m_Config.customMapKeys.Count > 0; } - public static Dictionary getCustomButtons() + public static Dictionary getCustomButtons(int device) { return m_Config.customMapButtons; } - public static Dictionary getCustomKeys() + public static Dictionary getCustomKeys(int device) { return m_Config.customMapKeys; } - public static Dictionary getCustomKeyTypes() + public static Dictionary getCustomKeyTypes(int device) { return m_Config.customMapKeyTypes; } @@ -316,11 +317,24 @@ namespace DS4Control { m_Config.Load(); } + public static void LoadProfile(int device, System.Windows.Forms.Control[] buttons) + { + m_Config.LoadProfile(device, buttons); + } + public static void LoadProfile(int device) + { + m_Config.LoadProfile(device); + } public static void Save() { m_Config.Save(); } + public static void SaveProfile(string propath, System.Windows.Forms.Control[] buttons) + { + m_Config.SaveProfile(propath, buttons); + } + private static byte applyRatio(byte b1, byte b2, uint r) { uint ratio = r; @@ -347,204 +361,136 @@ namespace DS4Control public class BackingStore { protected String m_File = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName + @"\ScpControl.xml"; + protected String m_Profile = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName + @"\Profiles.xml"; protected XmlDocument m_Xdoc = new XmlDocument(); - public Boolean[] touchpadJitterCompensation = { true, true, true, true }; - public Boolean[] lowerRCOff = { false, false, false, false }; - public Boolean[] ledAsBattery = { false, false, false, false }; - public Boolean[] flashLedLowBattery = { false, false, false, false }; - public Boolean[] touchEnabled = { false, false, false, false }; - public double[] m_LeftTriggerMiddle = { 0.5, 0.5, 0.5, 0.5 }, m_RightTriggerMiddle = { 0.5, 0.5, 0.5, 0.5 }; - public String[] customMapPath = { String.Empty, String.Empty, String.Empty, String.Empty }; - public Byte[] m_Rumble = { 100, 100, 100, 100 }; - public Byte[] touchSensitivity = { 100, 100, 100, 100 }; - public Byte[] tapSensitivity = { 0, 0, 0, 0 }; - public int[] scrollSensitivity = { 0, 0, 0, 0 }; - public Byte[][] m_LowLeds = new Byte[][] - { - new Byte[] {0,0,0}, - new Byte[] {0,0,0}, - new Byte[] {0,0,0}, - new Byte[] {0,0,0} - }; - public Byte[][] m_Leds = new Byte[][] - { - new Byte[] {0,0,255}, - new Byte[] {255,0,0}, - new Byte[] {0,255,0}, - new Byte[] {255,0,255}, - }; - public bool[] flushHIDQueue = { true, true, true, true }; + public Boolean touchpadJitterCompensation = true; + public Boolean lowerRCOn; + public Boolean ledAsBattery = false; + public Boolean flashLedLowBattery = false; + public double m_LeftTriggerMiddle = 0.5, m_RightTriggerMiddle = 0.5; + public String customMapPath = String.Empty, buttonModeMapPath = String.Empty; + public String[] profilePath = { String.Empty, String.Empty, String.Empty, String.Empty }; + public Byte m_Rumble = 100; + public Boolean rumbleSwap = false; + public Byte touchSensitivity = 100; + public Byte tapSensitivity = 0; + public int scrollSensitivity = 0; + public Byte[] m_LowLeds = new Byte[] { 0, 0, 0 }; + public Byte[] m_Leds = new Byte[] {0,0,255}; + public bool flushHIDQueue = true; + public int idleDisconnectTimeout = 0; public Boolean useExclusiveMode = false; public Int32 formWidth = 782; public Int32 formHeight = 550; public Boolean startMinimized = false; - public Dictionary customMapKeyTypes = new Dictionary(); - public Dictionary customMapKeys = new Dictionary(); - public Dictionary customMapButtons = new Dictionary(); - public X360Controls GetCustomButton(DS4Controls controlName) + public Dictionary customMapKeyTypes = null; + public Dictionary customMapKeys = null; + public Dictionary customMapButtons = null; + public BackingStore() + { + //for (int i = 0; i < 4; i++) + { + //for (int j = (int)MapSelector.Standard; j <= (int)MapSelector.ButtonMode; j++) + { + customMapKeyTypes = new Dictionary(); + customMapKeys = new Dictionary(); + customMapButtons = new Dictionary(); + } + } + } + + public X360Controls GetCustomButton(int device, DS4Controls controlName) { if (customMapButtons.ContainsKey(controlName)) return customMapButtons[controlName]; - else return 0; + else return X360Controls.None; } - public UInt16 GetCustomKey(DS4Controls controlName) + public UInt16 GetCustomKey(int device, DS4Controls controlName) { if (customMapKeys.ContainsKey(controlName)) return customMapKeys[controlName]; else return 0; } - public DS4KeyType GetCustomKeyType(DS4Controls controlName) + public DS4KeyType GetCustomKeyType(int device, DS4Controls controlName) { if (customMapKeyTypes.ContainsKey(controlName)) return customMapKeyTypes[controlName]; else return 0; } - public Boolean LoadCustomMapping(String customMapPath) - { - Boolean Loaded = true; - customMapButtons.Clear(); - customMapKeys.Clear(); - customMapKeyTypes.Clear(); - try - { - if (customMapPath != string.Empty && File.Exists(customMapPath)) - { - m_Xdoc.Load(customMapPath); - DS4KeyType keyType; - UInt16 wvk; - XmlNode ParentItem = m_Xdoc.SelectSingleNode("/Control/Button"); - if (ParentItem != null) - foreach (XmlNode Item in ParentItem.ChildNodes) - customMapButtons.Add(getDS4ControlsByName(Item.Name), getX360ControlsByName(Item.InnerText)); - ParentItem = m_Xdoc.SelectSingleNode("/Control/Key"); - if (ParentItem != null) - foreach (XmlNode Item in ParentItem.ChildNodes) - if (UInt16.TryParse(Item.InnerText, out wvk)) - customMapKeys.Add(getDS4ControlsByName(Item.Name), wvk); - ParentItem = m_Xdoc.SelectSingleNode("/Control/KeyType"); - if (ParentItem != null) - foreach (XmlNode Item in ParentItem.ChildNodes) - if (Item != null) - { - keyType = DS4KeyType.None; - if (Item.InnerText.Contains(DS4KeyType.ScanCode.ToString())) - keyType |= DS4KeyType.ScanCode; - if (Item.InnerText.Contains(DS4KeyType.Repeat.ToString())) - keyType |= DS4KeyType.Repeat; - if (keyType != DS4KeyType.None) - customMapKeyTypes.Add(getDS4ControlsByName(Item.Name), keyType); - } - } - } - catch (Exception) - { - Loaded = false; - } - return Loaded; - } - public Boolean LoadCustomMapping(String customMapPath, System.Windows.Forms.Control[] buttons) - { - Boolean Loaded = true; - customMapButtons.Clear(); - customMapKeys.Clear(); - customMapKeyTypes.Clear(); - try - { - if (customMapPath != string.Empty && File.Exists(customMapPath)) - { - XmlNode Item; - m_Xdoc.Load(customMapPath); - DS4KeyType keyType; - UInt16 wvk; - foreach (var button in buttons) - try - { - Item = m_Xdoc.SelectSingleNode(String.Format("/Control/Key/{0}", button.Name)); - if (Item != null) - { - if (UInt16.TryParse(Item.InnerText, out wvk)) - { - customMapKeys.Add(getDS4ControlsByName(Item.Name), wvk); - button.Tag = wvk; - button.Text = ((System.Windows.Forms.Keys)wvk).ToString(); - - Item = m_Xdoc.SelectSingleNode(String.Format("/Control/KeyType/{0}", button.Name)); - if (Item != null) - { - keyType = DS4KeyType.None; - if (Item.InnerText.Contains(DS4KeyType.ScanCode.ToString())) - { - keyType |= DS4KeyType.ScanCode; - button.Font = new System.Drawing.Font(button.Font, System.Drawing.FontStyle.Bold); - } - if (Item.InnerText.Contains(DS4KeyType.Repeat.ToString())) - { - keyType |= DS4KeyType.Repeat; - button.ForeColor = System.Drawing.Color.Red; - } - if (keyType != DS4KeyType.None) - customMapKeyTypes.Add(getDS4ControlsByName(Item.Name), keyType); - } - } - } - else - { - Item = m_Xdoc.SelectSingleNode(String.Format("/Control/Button/{0}", button.Name)); - if (Item != null) - { - button.Tag = Item.InnerText; - button.Text = Item.InnerText; - customMapButtons.Add(getDS4ControlsByName(button.Name), getX360ControlsByName(Item.InnerText)); - } - } - } - catch - { - - } - } - } - catch - { - Loaded = false; - } - return Loaded; - } - public Boolean SaveCustomMapping(String customMapPath, System.Windows.Forms.Control[] buttons) + + public Boolean SaveProfile(String propath, System.Windows.Forms.Control[] buttons) { Boolean Saved = true; + //String folderName = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName; + //String pathString = System.IO.Path.Combine(folderName, "Profiles"); + //System.IO.Directory.CreateDirectory(pathString); + String path = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName + @"\Profiles\" + propath + ".xml"; try { XmlNode Node; + m_Xdoc.RemoveAll(); + Node = m_Xdoc.CreateXmlDeclaration("1.0", "utf-8", String.Empty); m_Xdoc.AppendChild(Node); - Node = m_Xdoc.CreateComment(String.Format(" Custom Control Mapping Data. {0} ", DateTime.Now)); + + Node = m_Xdoc.CreateComment(String.Format(" ScpControl Configuration Data. {0} ", DateTime.Now)); m_Xdoc.AppendChild(Node); + Node = m_Xdoc.CreateWhitespace("\r\n"); m_Xdoc.AppendChild(Node); - Node = m_Xdoc.CreateNode(XmlNodeType.Element, "Control", null); + + Node = m_Xdoc.CreateNode(XmlNodeType.Element, "ScpControl", null); + + XmlNode xmlFlushHIDQueue = m_Xdoc.CreateNode(XmlNodeType.Element, "flushHIDQueue", null); xmlFlushHIDQueue.InnerText = flushHIDQueue.ToString(); Node.AppendChild(xmlFlushHIDQueue); + XmlNode xmlIdleDisconnectTimeout = m_Xdoc.CreateNode(XmlNodeType.Element, "idleDisconnectTimeout", null); xmlIdleDisconnectTimeout.InnerText = idleDisconnectTimeout.ToString(); Node.AppendChild(xmlIdleDisconnectTimeout); + XmlNode xmlRed = m_Xdoc.CreateNode(XmlNodeType.Element, "Red", null); xmlRed.InnerText = m_Leds[0].ToString(); Node.AppendChild(xmlRed); + XmlNode xmlGreen = m_Xdoc.CreateNode(XmlNodeType.Element, "Green", null); xmlGreen.InnerText = m_Leds[1].ToString(); Node.AppendChild(xmlGreen); + XmlNode xmlBlue = m_Xdoc.CreateNode(XmlNodeType.Element, "Blue", null); xmlBlue.InnerText = m_Leds[2].ToString(); Node.AppendChild(xmlBlue); + XmlNode xmlRumbleBoost = m_Xdoc.CreateNode(XmlNodeType.Element, "RumbleBoost", null); xmlRumbleBoost.InnerText = m_Rumble.ToString(); Node.AppendChild(xmlRumbleBoost); + XmlNode xmlRumbleSwap = m_Xdoc.CreateNode(XmlNodeType.Element, "rumbleSwap", null); xmlRumbleSwap.InnerText = rumbleSwap.ToString(); Node.AppendChild(xmlRumbleSwap); + XmlNode xmlLedAsBatteryIndicator = m_Xdoc.CreateNode(XmlNodeType.Element, "ledAsBatteryIndicator", null); xmlLedAsBatteryIndicator.InnerText = ledAsBattery.ToString(); Node.AppendChild(xmlLedAsBatteryIndicator); + XmlNode xmlLowBatteryFlash = m_Xdoc.CreateNode(XmlNodeType.Element, "lowBatteryFlash", null); xmlLowBatteryFlash.InnerText = flashLedLowBattery.ToString(); Node.AppendChild(xmlLowBatteryFlash); + XmlNode xmlTouchSensitivity = m_Xdoc.CreateNode(XmlNodeType.Element, "touchSensitivity", null); xmlTouchSensitivity.InnerText = touchSensitivity.ToString(); Node.AppendChild(xmlTouchSensitivity); + XmlNode xmlLowRed = m_Xdoc.CreateNode(XmlNodeType.Element, "LowRed", null); xmlLowRed.InnerText = m_LowLeds[0].ToString(); Node.AppendChild(xmlLowRed); + XmlNode xmlLowGreen = m_Xdoc.CreateNode(XmlNodeType.Element, "LowGreen", null); xmlLowGreen.InnerText = m_LowLeds[1].ToString(); Node.AppendChild(xmlLowGreen); + XmlNode xmlLowBlue = m_Xdoc.CreateNode(XmlNodeType.Element, "LowBlue", null); xmlLowBlue.InnerText = m_LowLeds[2].ToString(); Node.AppendChild(xmlLowBlue); + XmlNode xmlTouchpadJitterCompensation = m_Xdoc.CreateNode(XmlNodeType.Element, "touchpadJitterCompensation", null); xmlTouchpadJitterCompensation.InnerText = touchpadJitterCompensation.ToString(); Node.AppendChild(xmlTouchpadJitterCompensation); + XmlNode xmlLowerRCOn = m_Xdoc.CreateNode(XmlNodeType.Element, "lowerRCOn", null); xmlLowerRCOn.InnerText = lowerRCOn.ToString(); Node.AppendChild(xmlLowerRCOn); + XmlNode xmlTapSensitivity = m_Xdoc.CreateNode(XmlNodeType.Element, "tapSensitivity", null); xmlTapSensitivity.InnerText = tapSensitivity.ToString(); Node.AppendChild(xmlTapSensitivity); + XmlNode xmlScrollSensitivity = m_Xdoc.CreateNode(XmlNodeType.Element, "scrollSensitivity", null); xmlScrollSensitivity.InnerText = scrollSensitivity.ToString(); Node.AppendChild(xmlScrollSensitivity); + XmlNode xmlLeftTriggerMiddle = m_Xdoc.CreateNode(XmlNodeType.Element, "LeftTriggerMiddle", null); xmlLeftTriggerMiddle.InnerText = m_LeftTriggerMiddle.ToString(); Node.AppendChild(xmlLeftTriggerMiddle); + XmlNode xmlRightTriggerMiddle = m_Xdoc.CreateNode(XmlNodeType.Element, "RightTriggerMiddle", null); xmlRightTriggerMiddle.InnerText = m_RightTriggerMiddle.ToString(); Node.AppendChild(xmlRightTriggerMiddle); + + // m_Xdoc.AppendChild(Node); + XmlNode NodeControl = m_Xdoc.CreateNode(XmlNodeType.Element, "Control", null); XmlNode Key = m_Xdoc.CreateNode(XmlNodeType.Element, "Key", null); XmlNode KeyType = m_Xdoc.CreateNode(XmlNodeType.Element, "KeyType", null); XmlNode Button = m_Xdoc.CreateNode(XmlNodeType.Element, "Button", null); foreach (var button in buttons) - try + // try { // Save even if string (for xbox controller buttons) if (button.Tag != null) { XmlNode buttonNode; string keyType = String.Empty; - if (button.ForeColor == System.Drawing.Color.Red) - keyType += DS4KeyType.Repeat; - if (button.Font.Bold) - keyType += DS4KeyType.ScanCode; + if (button.Tag is String && (String)button.Tag == "Unbound") + { + keyType += DS4KeyType.Unbound; + } + { + if (button.ForeColor == System.Drawing.Color.Red) + keyType += DS4KeyType.Repeat; + if (button.Font.Bold) + keyType += DS4KeyType.ScanCode; + } if (keyType != String.Empty) { buttonNode = m_Xdoc.CreateNode(XmlNodeType.Element, button.Name, null); @@ -558,26 +504,26 @@ namespace DS4Control else Button.AppendChild(buttonNode); } } - catch - { - Saved = false; - } - m_Xdoc.AppendChild(Node); + //catch + // { + // NodeControl.InnerText = ""; + //} + Node.AppendChild(NodeControl); if (Button.HasChildNodes) - Node.AppendChild(Button); + NodeControl.AppendChild(Button); if (Key.HasChildNodes) - Node.AppendChild(Key); + NodeControl.AppendChild(Key); if (KeyType.HasChildNodes) - Node.AppendChild(KeyType); - m_Xdoc.Save(customMapPath); - } - catch (Exception) - { - Saved = false; + NodeControl.AppendChild(KeyType); + m_Xdoc.AppendChild(Node); + if (NodeControl.HasChildNodes) + Node.AppendChild(NodeControl); + m_Xdoc.Save(path); } + catch { Saved = false; } + return Saved; } - private DS4Controls getDS4ControlsByName(string key) { switch (key) @@ -599,20 +545,22 @@ namespace DS4Control case "bnSquare": return DS4Controls.Square; case "bnPS": return DS4Controls.PS; - case "bnLX": return DS4Controls.LXNeg; - case "bnLY": return DS4Controls.LYNeg; - case "bnRX": return DS4Controls.RXNeg; - case "bnRY": return DS4Controls.RYNeg; - case "bnLX2": return DS4Controls.LXPos; - case "bnLY2": return DS4Controls.LYPos; - case "bnRX2": return DS4Controls.RXPos; - case "bnRY2": return DS4Controls.RYPos; + case "bnLSLeft": return DS4Controls.LXNeg; + case "bnLSUp": return DS4Controls.LYNeg; + case "bnRSLeft": return DS4Controls.RXNeg; + case "bnRSUp": return DS4Controls.RYNeg; + + case "bnLSRight": return DS4Controls.LXPos; + case "bnLSDown": return DS4Controls.LYPos; + case "bnRSRight": return DS4Controls.RXPos; + case "bnRSDown": return DS4Controls.RYPos; case "bnL2": return DS4Controls.L2; case "bnR2": return DS4Controls.R2; - case "bnTouchpad": return DS4Controls.TouchButton; + case "bnTouchLeft": return DS4Controls.TouchLeft; case "bnTouchMulti": return DS4Controls.TouchMulti; case "bnTouchUpper": return DS4Controls.TouchUpper; + case "bnTouchRight": return DS4Controls.TouchRight; } return 0; } @@ -648,81 +596,232 @@ namespace DS4Control case "Right Y-Axis+": return X360Controls.RYPos; case "Left Trigger": return X360Controls.LT; case "Right Trigger": return X360Controls.RT; - case "Click": return X360Controls.LeftMouse; - case "Right Click": return X360Controls.RightMouse; - case "Middle Click": return X360Controls.MiddleMouse; - case "(Unbound)": return X360Controls.Unbound; + + case "Left Mouse Button": return X360Controls.LeftMouse; + case "Right Mouse Button": return X360Controls.RightMouse; + case "Middle Mouse Button": return X360Controls.MiddleMouse; + case "4th Mouse Button": return X360Controls.FourthMouse; + case "5th Mouse Button": return X360Controls.FifthMouse; + case "Mouse Wheel Up": return X360Controls.WUP; + case "Mouse Wheel Down": return X360Controls.WDOWN; + case "Unbound": return X360Controls.Unbound; } return X360Controls.Unbound; } - public Boolean Load() + public Boolean LoadProfile(int device, System.Windows.Forms.Control[] buttons) { Boolean Loaded = true; + Dictionary customMapKeyTypes = new Dictionary(); + Dictionary customMapKeys = new Dictionary(); + Dictionary customMapButtons = new Dictionary(); Boolean missingSetting = false; try { - if (File.Exists(m_File)) + if (File.Exists(profilePath[device])) { XmlNode Item; - m_Xdoc.Load(m_File); + m_Xdoc.Load(profilePath[device]); + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/flushHIDQueue"); Boolean.TryParse(Item.InnerText, out flushHIDQueue); } + catch { missingSetting = true; } - for (int i = 0; i < 4; i++) - { - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/flushHIDQueue"); Boolean.TryParse(Item.InnerText, out flushHIDQueue[i]); } - catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/idleDisconnectTimeout"); Int32.TryParse(Item.InnerText, out idleDisconnectTimeout); } + catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/Red"); Byte.TryParse(Item.InnerText, out m_Leds[i][0]); } - catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Red"); Byte.TryParse(Item.InnerText, out m_Leds[0]); } + catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/Green"); Byte.TryParse(Item.InnerText, out m_Leds[i][1]); } - catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Green"); Byte.TryParse(Item.InnerText, out m_Leds[1]); } + catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/Blue"); Byte.TryParse(Item.InnerText, out m_Leds[i][2]); } - catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Blue"); Byte.TryParse(Item.InnerText, out m_Leds[2]); } + catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/RumbleBoost"); Byte.TryParse(Item.InnerText, out m_Rumble[i]); } - catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/RumbleBoost"); Byte.TryParse(Item.InnerText, out m_Rumble); } + catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/ledAsBatteryIndicator"); Boolean.TryParse(Item.InnerText, out ledAsBattery[i]); } - catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/rumbleSwap"); Boolean.TryParse(Item.InnerText, out rumbleSwap); } + catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/lowBatteryFlash"); Boolean.TryParse(Item.InnerText, out flashLedLowBattery[i]); } - catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/ledAsBatteryIndicator"); Boolean.TryParse(Item.InnerText, out ledAsBattery); } + catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/touchSensitivity"); Byte.TryParse(Item.InnerText, out touchSensitivity[i]); } - catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/lowBatteryFlash"); Boolean.TryParse(Item.InnerText, out flashLedLowBattery); } + catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/touchEnabled"); Boolean.TryParse(Item.InnerText, out touchEnabled[i]); } - catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/touchSensitivity"); Byte.TryParse(Item.InnerText, out touchSensitivity); } + catch { missingSetting = true; } + + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/LowRed"); Byte.TryParse(Item.InnerText, out m_LowLeds[0]); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/LowGreen"); Byte.TryParse(Item.InnerText, out m_LowLeds[1]); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/LowBlue"); Byte.TryParse(Item.InnerText, out m_LowLeds[2]); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/touchpadJitterCompensation"); Boolean.TryParse(Item.InnerText, out touchpadJitterCompensation); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/lowerRCOn"); Boolean.TryParse(Item.InnerText, out lowerRCOn); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/tapSensitivity"); Byte.TryParse(Item.InnerText, out tapSensitivity); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/scrollSensitivity"); Int32.TryParse(Item.InnerText, out scrollSensitivity); } + catch { missingSetting = true; } + // XXX This sucks, let's do better at removing old values that are no longer valid.... + if (scrollSensitivity > 10) + scrollSensitivity = 5; + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/LeftTriggerMiddle"); Double.TryParse(Item.InnerText, out m_LeftTriggerMiddle); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/RightTriggerMiddle"); Double.TryParse(Item.InnerText, out m_RightTriggerMiddle); } + catch { missingSetting = true; } + + DS4KeyType keyType; + UInt16 wvk; + foreach (var button in buttons) + try + { + //bool foundBinding = false; + Item = m_Xdoc.SelectSingleNode(String.Format("/ScpControl/Control/KeyType/{0}", button.Name)); + if (Item != null) + { + //foundBinding = true; + keyType = DS4KeyType.None; + if (Item.InnerText.Contains(DS4KeyType.Unbound.ToString())) + { + keyType = DS4KeyType.Unbound; + button.Tag = "Unbound"; + button.Text = "Unbound"; + } + else + { + if (Item.InnerText.Contains(DS4KeyType.ScanCode.ToString())) + { + keyType |= DS4KeyType.ScanCode; + button.Font = new System.Drawing.Font(button.Font, System.Drawing.FontStyle.Bold); + } + if (Item.InnerText.Contains(DS4KeyType.Repeat.ToString())) + { + keyType |= DS4KeyType.Repeat; + button.ForeColor = System.Drawing.Color.Red; + } + } + if (keyType != DS4KeyType.None) + customMapKeyTypes.Add(getDS4ControlsByName(Item.Name), keyType); + } + + Item = m_Xdoc.SelectSingleNode(String.Format("/ScpControl/Control/Key/{0}", button.Name)); + if (Item != null) + { + if (UInt16.TryParse(Item.InnerText, out wvk)) + { + //foundBinding = true; + customMapKeys.Add(getDS4ControlsByName(Item.Name), wvk); + button.Tag = wvk; + button.Text = ((System.Windows.Forms.Keys)wvk).ToString(); + } + } + else + { + Item = m_Xdoc.SelectSingleNode(String.Format("/ScpControl/Control/Button/{0}", button.Name)); + if (Item != null) + { + //foundBinding = true; + button.Tag = Item.InnerText; + button.Text = Item.InnerText; + customMapButtons.Add(getDS4ControlsByName(button.Name), getX360ControlsByName(Item.InnerText)); + } + } + } + catch + { + + } + } + } + catch { Loaded = false; } + + if (Loaded) + { + this.customMapButtons = customMapButtons; + this.customMapKeys = customMapKeys; + this.customMapKeyTypes = customMapKeyTypes; + } + // Only add missing settings if the actual load was graceful + if (missingSetting && Loaded) + SaveProfile(profilePath[device], buttons); + + return Loaded; + } + public Boolean LoadProfile(int device) + { + Boolean Loaded = true; + Dictionary customMapKeyTypes = new Dictionary(); + Dictionary customMapKeys = new Dictionary(); + Dictionary customMapButtons = new Dictionary(); + Boolean missingSetting = false; + + try + { + if (File.Exists(profilePath[device])) + { + XmlNode Item; + + m_Xdoc.Load(profilePath[device]); + + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/flushHIDQueue"); Boolean.TryParse(Item.InnerText, out flushHIDQueue); } + catch { missingSetting = true; } + + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/idleDisconnectTimeout"); Int32.TryParse(Item.InnerText, out idleDisconnectTimeout); } + catch { missingSetting = true; } + + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Red"); Byte.TryParse(Item.InnerText, out m_Leds[0]); } + catch { missingSetting = true; } + + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Green"); Byte.TryParse(Item.InnerText, out m_Leds[1]); } + catch { missingSetting = true; } + + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Blue"); Byte.TryParse(Item.InnerText, out m_Leds[2]); } + catch { missingSetting = true; } + + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/RumbleBoost"); Byte.TryParse(Item.InnerText, out m_Rumble); } + catch { missingSetting = true; } + + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/rumbleSwap"); Boolean.TryParse(Item.InnerText, out rumbleSwap); } + catch { missingSetting = true; } + + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/ledAsBatteryIndicator"); Boolean.TryParse(Item.InnerText, out ledAsBattery); } + catch { missingSetting = true; } + + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/lowBatteryFlash"); Boolean.TryParse(Item.InnerText, out flashLedLowBattery); } + catch { missingSetting = true; } + + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/touchSensitivity"); Byte.TryParse(Item.InnerText, out touchSensitivity); } + catch { missingSetting = true; } + + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/LowRed"); Byte.TryParse(Item.InnerText, out m_LowLeds[0]); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/LowGreen"); Byte.TryParse(Item.InnerText, out m_LowLeds[1]); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/LowBlue"); Byte.TryParse(Item.InnerText, out m_LowLeds[2]); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/touchpadJitterCompensation"); Boolean.TryParse(Item.InnerText, out touchpadJitterCompensation); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/lowerRCOn"); Boolean.TryParse(Item.InnerText, out lowerRCOn); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/tapSensitivity"); Byte.TryParse(Item.InnerText, out tapSensitivity); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/scrollSensitivity"); Int32.TryParse(Item.InnerText, out scrollSensitivity); } + catch { missingSetting = true; } + // XXX This sucks, let's do better at removing old values that are no longer valid.... + if (scrollSensitivity > 10) + scrollSensitivity = 5; + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/LeftTriggerMiddle"); Double.TryParse(Item.InnerText, out m_LeftTriggerMiddle); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/ScpControl/RightTriggerMiddle"); Double.TryParse(Item.InnerText, out m_RightTriggerMiddle); } + catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/LowRed"); Byte.TryParse(Item.InnerText, out m_LowLeds[i][0]); } - catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/LowGreen"); Byte.TryParse(Item.InnerText, out m_LowLeds[i][1]); } - catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/LowBlue"); Byte.TryParse(Item.InnerText, out m_LowLeds[i][2]); } - catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/touchpadJitterCompensation"); Boolean.TryParse(Item.InnerText, out touchpadJitterCompensation[i]); } - catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/lowerRCOff"); Boolean.TryParse(Item.InnerText, out lowerRCOff[i]); } - catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/tapSensitivity"); Byte.TryParse(Item.InnerText, out tapSensitivity[i]); } - catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/scrollSensitivity"); Int32.TryParse(Item.InnerText, out scrollSensitivity[i]); } - catch { missingSetting = true; } - // XXX This sucks, let's do better at removing old values that are no longer valid.... - if (scrollSensitivity[i] > 10) - scrollSensitivity[i] = 5; - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/customMapPath"); customMapPath[i] = Item.InnerText; } - catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/LeftTriggerMiddle"); Double.TryParse(Item.InnerText, out m_LeftTriggerMiddle[i]); } - catch { missingSetting = true; } - try { Item = m_Xdoc.SelectSingleNode("/ScpControl/Controller" + (i + 1) + "/RightTriggerMiddle"); Double.TryParse(Item.InnerText, out m_RightTriggerMiddle[i]); } - catch { missingSetting = true; } - } try { Item = m_Xdoc.SelectSingleNode("/ScpControl/useExclusiveMode"); Boolean.TryParse(Item.InnerText, out useExclusiveMode); } catch { missingSetting = true; } @@ -732,74 +831,121 @@ namespace DS4Control catch { missingSetting = true; } try { Item = m_Xdoc.SelectSingleNode("/ScpControl/formHeight"); Int32.TryParse(Item.InnerText, out formHeight); } catch { missingSetting = true; } + DS4KeyType keyType; + UInt16 wvk; + XmlNode ParentItem = m_Xdoc.SelectSingleNode("/ScpControl/Control/Button"); + if (ParentItem != null) + foreach (XmlNode item in ParentItem.ChildNodes) + customMapButtons.Add(getDS4ControlsByName(item.Name), getX360ControlsByName(item.InnerText)); + ParentItem = m_Xdoc.SelectSingleNode("/ScpControl/Control/Key"); + if (ParentItem != null) + foreach (XmlNode item in ParentItem.ChildNodes) + if (UInt16.TryParse(item.InnerText, out wvk)) + customMapKeys.Add(getDS4ControlsByName(item.Name), wvk); + ParentItem = m_Xdoc.SelectSingleNode("/ScpControl/Control/KeyType"); + if (ParentItem != null) + foreach (XmlNode item in ParentItem.ChildNodes) + if (item != null) + { + keyType = DS4KeyType.None; + if (item.InnerText.Contains(DS4KeyType.ScanCode.ToString())) + keyType |= DS4KeyType.ScanCode; + if (item.InnerText.Contains(DS4KeyType.Repeat.ToString())) + keyType |= DS4KeyType.Repeat; + if (item.InnerText.Contains(DS4KeyType.Unbound.ToString())) + keyType |= DS4KeyType.Unbound; + if (keyType != DS4KeyType.None) + customMapKeyTypes.Add(getDS4ControlsByName(item.Name), keyType); + } } } catch { Loaded = false; } + if (Loaded) + { + this.customMapButtons = customMapButtons; + this.customMapKeys = customMapKeys; + this.customMapKeyTypes = customMapKeyTypes; + } // Only add missing settings if the actual load was graceful if (missingSetting && Loaded) - Save(); + SaveProfile(profilePath[device], null); return Loaded; } - public Boolean Save() + + public bool Load() + { + Boolean Loaded = true; + Boolean missingSetting = false; + + try + { + if (File.Exists(m_Profile)) + { + XmlNode Item; + + m_Xdoc.Load(m_Profile); + + + try { Item = m_Xdoc.SelectSingleNode("/Profile/useExclusiveMode"); Boolean.TryParse(Item.InnerText, out useExclusiveMode); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/Profile/startMinimized"); Boolean.TryParse(Item.InnerText, out startMinimized); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/Profile/formWidth"); Int32.TryParse(Item.InnerText, out formWidth); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/Profile/formHeight"); Int32.TryParse(Item.InnerText, out formHeight); } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/Profile/Controller1"); profilePath[0] = Item.InnerText; } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/Profile/Controller2"); profilePath[1] = Item.InnerText; } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/Profile/Controller3"); profilePath[2] = Item.InnerText; } + catch { missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/Profile/Controller4"); profilePath[3] = Item.InnerText; } + catch { missingSetting = true; } + } + } + catch { } + if (missingSetting) + Save(); + return Loaded; + } + public bool Save() { Boolean Saved = true; try { - XmlNode Node, Entry; + XmlNode Node; m_Xdoc.RemoveAll(); Node = m_Xdoc.CreateXmlDeclaration("1.0", "utf-8", String.Empty); m_Xdoc.AppendChild(Node); - Node = m_Xdoc.CreateComment(String.Format(" ScpControl Configuration Data. {0} ", DateTime.Now)); + Node = m_Xdoc.CreateComment(String.Format(" Profile Configuration Data. {0} ", DateTime.Now)); m_Xdoc.AppendChild(Node); Node = m_Xdoc.CreateWhitespace("\r\n"); m_Xdoc.AppendChild(Node); - Node = m_Xdoc.CreateNode(XmlNodeType.Element, "ScpControl", null); + Node = m_Xdoc.CreateNode(XmlNodeType.Element, "Profile", null); + XmlNode xmlUseExclNode = m_Xdoc.CreateNode(XmlNodeType.Element, "useExclusiveMode", null); xmlUseExclNode.InnerText = useExclusiveMode.ToString(); Node.AppendChild(xmlUseExclNode); XmlNode xmlStartMinimized = m_Xdoc.CreateNode(XmlNodeType.Element, "startMinimized", null); xmlStartMinimized.InnerText = startMinimized.ToString(); Node.AppendChild(xmlStartMinimized); XmlNode xmlFormWidth = m_Xdoc.CreateNode(XmlNodeType.Element, "formWidth", null); xmlFormWidth.InnerText = formWidth.ToString(); Node.AppendChild(xmlFormWidth); XmlNode xmlFormHeight = m_Xdoc.CreateNode(XmlNodeType.Element, "formHeight", null); xmlFormHeight.InnerText = formHeight.ToString(); Node.AppendChild(xmlFormHeight); + + XmlNode xmlController1 = m_Xdoc.CreateNode(XmlNodeType.Element, "Controller1", null); xmlController1.InnerText = profilePath[0]; Node.AppendChild(xmlController1); + XmlNode xmlController2 = m_Xdoc.CreateNode(XmlNodeType.Element, "Controller2", null); xmlController2.InnerText = profilePath[1]; Node.AppendChild(xmlController2); + XmlNode xmlController3 = m_Xdoc.CreateNode(XmlNodeType.Element, "Controller3", null); xmlController3.InnerText = profilePath[2]; Node.AppendChild(xmlController3); + XmlNode xmlController4 = m_Xdoc.CreateNode(XmlNodeType.Element, "Controller4", null); xmlController4.InnerText = profilePath[3]; Node.AppendChild(xmlController4); - XmlNode cNode1 = m_Xdoc.CreateNode(XmlNodeType.Element, "Controller1", null); Node.AppendChild(cNode1); - XmlNode cNode2 = m_Xdoc.CreateNode(XmlNodeType.Element, "Controller2", null); Node.AppendChild(cNode2); - XmlNode cNode3 = m_Xdoc.CreateNode(XmlNodeType.Element, "Controller3", null); Node.AppendChild(cNode3); - XmlNode cNode4 = m_Xdoc.CreateNode(XmlNodeType.Element, "Controller4", null); Node.AppendChild(cNode4); - - XmlNode[] cNodes = { cNode1, cNode2, cNode3, cNode4 }; - - for (int i = 0; i < 4; i++) - { - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "flushHIDQueue", null); Entry.InnerText = flushHIDQueue[i].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "Red", null); Entry.InnerText = m_Leds[i][0].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "Green", null); Entry.InnerText = m_Leds[i][1].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "Blue", null); Entry.InnerText = m_Leds[i][2].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "RumbleBoost", null); Entry.InnerText = m_Rumble[i].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "ledAsBatteryIndicator", null); Entry.InnerText = ledAsBattery[i].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "lowBatteryFlash", null); Entry.InnerText = flashLedLowBattery[i].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "touchSensitivity", null); Entry.InnerText = touchSensitivity[i].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "touchEnabled", null); Entry.InnerText = touchEnabled[i].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "LowRed", null); Entry.InnerText = m_LowLeds[i][0].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "LowGreen", null); Entry.InnerText = m_LowLeds[i][1].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "LowBlue", null); Entry.InnerText = m_LowLeds[i][2].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "touchpadJitterCompensation", null); Entry.InnerText = touchpadJitterCompensation[i].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "lowerRCOff", null); Entry.InnerText = lowerRCOff[i].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "tapSensitivity", null); Entry.InnerText = tapSensitivity[i].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "scrollSensitivity", null); Entry.InnerText = scrollSensitivity[i].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "customMapPath", null); Entry.InnerText = customMapPath[i]; cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "LeftTriggerMiddle", null); Entry.InnerText = m_LeftTriggerMiddle[i].ToString(); cNodes[i].AppendChild(Entry); - Entry = m_Xdoc.CreateNode(XmlNodeType.Element, "RightTriggerMiddle", null); Entry.InnerText = m_RightTriggerMiddle[i].ToString(); cNodes[i].AppendChild(Entry); - } m_Xdoc.AppendChild(Node); - m_Xdoc.Save(m_File); + m_Xdoc.Save(m_Profile); } catch { Saved = false; } diff --git a/DS4Control/TPadModeSwitcher.cs b/DS4Control/TPadModeSwitcher.cs index 6a0d6f0..51d2dcc 100644 --- a/DS4Control/TPadModeSwitcher.cs +++ b/DS4Control/TPadModeSwitcher.cs @@ -14,11 +14,11 @@ namespace DS4Control public TPadModeSwitcher(DS4Device device, int deviceID) { this.device = device; - modes.Add(TouchpadDisabled.singleton); - modes.Add(new Mouse(deviceID)); - modes.Add(new ButtonMouse(deviceID, device)); - modes.Add(new MouseCursorOnly(deviceID)); - modes.Add(new DragMouse(deviceID)); + //modes.Add(TouchpadDisabled.singleton); + modes.Add(new Mouse(deviceID, device)); + //modes.Add(new ButtonMouse(deviceID, device)); + //modes.Add(new MouseCursorOnly(deviceID)); + //modes.Add(new DragMouse(deviceID)); } public void switchMode(int ind) @@ -35,7 +35,7 @@ namespace DS4Control public void setMode(int ind) { - ITouchpadBehaviour tmode = modes.ElementAt(ind); + ITouchpadBehaviour tmode = modes.ElementAt(ind % modes.Count); device.Touchpad.TouchButtonDown += tmode.touchButtonDown; device.Touchpad.TouchButtonUp += tmode.touchButtonUp; device.Touchpad.TouchesBegan += tmode.touchesBegan; @@ -75,9 +75,14 @@ namespace DS4Control Debug(this, new DebugEventArgs(data)); } - public ITouchpadBehaviour getCurrentMode() + /*public ITouchpadBehaviour getCurrentMode() { return modes.ElementAt(currentTypeInd); + }*/ + + public ITouchpadBehaviour[] getAvailableModes() + { + return modes.ToArray(); } public int getCurrentModeInt() diff --git a/DS4Control/TouchpadDisabled.cs b/DS4Control/TouchpadDisabled.cs deleted file mode 100644 index 0e560c7..0000000 --- a/DS4Control/TouchpadDisabled.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using DS4Library; - -namespace DS4Control -{ - class TouchpadDisabled : ITouchpadBehaviour - { - public override string ToString() - { - return "Disabled"; - } - - public static readonly TouchpadDisabled singleton = new TouchpadDisabled(); - - public void touchesMoved(object sender, TouchpadEventArgs arg) { } - - public void touchesBegan(object sender, TouchpadEventArgs arg) { } - - public void touchesEnded(object sender, TouchpadEventArgs arg) { } - - public void touchButtonUp(object sender, TouchpadEventArgs arg) { } - - public void touchButtonDown(object sender, TouchpadEventArgs arg) { } - - public void touchUnchanged(object sender, EventArgs unused) { } - } -} diff --git a/DS4Library/DS4Device.cs b/DS4Library/DS4Device.cs index fd886c0..bd5c297 100644 --- a/DS4Library/DS4Device.cs +++ b/DS4Library/DS4Device.cs @@ -67,6 +67,7 @@ namespace DS4Library private byte ledFlashOn, ledFlashOff; private Thread ds4Input, ds4Output; private int battery; + private DateTime lastActive = DateTime.UtcNow; private bool charging; public event EventHandler Report = null; public event EventHandler Removal = null; @@ -78,6 +79,7 @@ namespace DS4Library public string MacAddress { get { return Mac; } } public ConnectionType ConnectionType { get { return conType; } } + public int IdleTimeout { get; set; } // behavior only active when > 0 public int Battery { get { return battery; } } public bool Charging { get { return charging; } } @@ -148,7 +150,6 @@ namespace DS4Library public DS4Device(HidDevice hidDevice) { hDevice = hidDevice; - hDevice.MonitorDeviceEvents = true; conType = HidConnectionType(hDevice); Mac = hDevice.readSerial(); if (conType == ConnectionType.USB) @@ -172,7 +173,7 @@ namespace DS4Library if (ds4Input == null) { Console.WriteLine(MacAddress.ToString() + " " + System.DateTime.UtcNow.ToString("o") + "> start"); - sendOutputReport(true); // request the particular kind of input report we want + sendOutputReport(true); // initialize the output report ds4Output = new Thread(performDs4Output); ds4Output.Name = "DS4 Output thread: " + Mac; ds4Output.Start(); @@ -233,12 +234,26 @@ namespace DS4Library { lock (outputReport) { - while (writeOutput()) + int lastError = 0; + while (true) { - 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. + if (writeOutput()) + { + lastError = 0; + 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); + } else - Monitor.Wait(outputReport); + { + int thisError = Marshal.GetLastWin32Error(); + if (lastError != thisError) + { + Console.WriteLine(MacAddress.ToString() + " " + System.DateTime.UtcNow.ToString("o") + "> encountered write failure: " + thisError); + lastError = thisError; + } + } } } } @@ -251,29 +266,51 @@ namespace DS4Library private byte priorInputReport30 = 0xff; private void performDs4Input() { + System.Timers.Timer readTimeout = new System.Timers.Timer(); // Await 30 seconds for the initial packet, then 3 seconds thereafter. + readTimeout.Elapsed += delegate { HidDevice.CancelIO(); }; while (true) { + if (readTimeout.Interval != 3000.0) + { + if (readTimeout.Interval != 30000.0) + readTimeout.Interval = 30000.0; + else + readTimeout.Interval = 3000.0; + } + readTimeout.Enabled = true; if (conType != ConnectionType.USB) - if (hDevice.ReadFile(btInputReport) == HidDevice.ReadStatus.Success) + { + HidDevice.ReadStatus res = hDevice.ReadFile(btInputReport); + readTimeout.Enabled = false; + if (res == HidDevice.ReadStatus.Success) { Array.Copy(btInputReport, 2, inputReport, 0, inputReport.Length); } else { - Console.WriteLine(MacAddress.ToString() + " " + System.DateTime.UtcNow.ToString("o") + "> disconnect"); + Console.WriteLine(MacAddress.ToString() + " " + System.DateTime.UtcNow.ToString("o") + "> disconnect due to read failure: " + Marshal.GetLastWin32Error()); sendOutputReport(true); // Kick Windows into noticing the disconnection. StopOutputUpdate(); - if (!IsDisconnecting && Removal != null) + IsDisconnecting = true; + if (Removal != null) Removal(this, EventArgs.Empty); - return; - + return; + } - else if (hDevice.ReadFile(inputReport) != HidDevice.ReadStatus.Success) + } + else { - StopOutputUpdate(); - if (!IsDisconnecting && Removal != null) - Removal(this, EventArgs.Empty); - return; + HidDevice.ReadStatus res = hDevice.ReadFile(inputReport); + readTimeout.Enabled = false; + if (res != HidDevice.ReadStatus.Success) + { + Console.WriteLine(MacAddress.ToString() + " " + System.DateTime.UtcNow.ToString("o") + "> disconnect due to read failure: " + Marshal.GetLastWin32Error()); + StopOutputUpdate(); + IsDisconnecting = true; + if (Removal != null) + Removal(this, EventArgs.Empty); + return; + } } if (ConnectionType == ConnectionType.BT && btInputReport[0] != 0x11) { @@ -282,8 +319,6 @@ namespace DS4Library } 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]; @@ -355,7 +390,9 @@ namespace DS4Library 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 + cState.TouchLeft = (inputReport[1 + DS4Touchpad.TOUCHPAD_DATA_OFFSET + touchOffset] + ((inputReport[2 + DS4Touchpad.TOUCHPAD_DATA_OFFSET + touchOffset] & 0xF) * 255) >= 1920 * 2 / 5) ? false : true; + cState.TouchRight = (inputReport[1 + DS4Touchpad.TOUCHPAD_DATA_OFFSET + touchOffset] + ((inputReport[2 + DS4Touchpad.TOUCHPAD_DATA_OFFSET + touchOffset] & 0xF) * 255) < 1920 * 2 / 5) ? false : true; + // Even when idling there is still a touch packet indicating no touch 1 or 2 touchpad.handleTouchpad(inputReport, cState, touchOffset); } @@ -368,9 +405,26 @@ namespace DS4Library Console.WriteLine(); } */ - if (conType == ConnectionType.BT && (!pState.PS || !pState.Options) && cState.PS && cState.Options) + if (conType == ConnectionType.BT) { - if (DisconnectBT()) + bool shouldDisconnect = false; + if ((!pState.PS || !pState.Options) && cState.PS && cState.Options) + { + shouldDisconnect = true; + } + else if (IdleTimeout > 0) + { + if (!isNonSixaxisIdle()) + { + lastActive = utcNow; + } + else + { + DateTime timeout = lastActive + TimeSpan.FromSeconds(IdleTimeout); + shouldDisconnect = utcNow >= timeout; + } + } + if (shouldDisconnect && DisconnectBT()) return; // all done } // XXX fix initialization ordering so the null checks all go away @@ -378,9 +432,7 @@ namespace DS4Library Report(this, EventArgs.Empty); sendOutputReport(false); - if (pState == null) - pState = new DS4State(); - cState.Copy(pState); + cState.CopyTo(pState); } } @@ -420,7 +472,8 @@ namespace DS4Library outputReportBuffer.CopyTo(outputReport, 0); try { - writeOutput(); + if (!writeOutput()) + Console.WriteLine(MacAddress.ToString() + " " + System.DateTime.UtcNow.ToString("o") + "> encountered synchronous write failure: " + Marshal.GetLastWin32Error()); } catch { @@ -445,7 +498,7 @@ namespace DS4Library { if (Mac != null) { - Console.WriteLine("Trying to disonnect BT device"); + Console.WriteLine("Trying to disconnect BT device " + Mac); IntPtr btHandle = IntPtr.Zero; int IOCTL_BTH_DISCONNECT_DEVICE = 0x41000c; @@ -517,19 +570,40 @@ namespace DS4Library public void getExposedState(DS4StateExposed expState, DS4State state) { - cState.Copy(state); + cState.CopyTo(state); expState.Accel = accel; expState.Gyro = gyro; } public void getCurrentState(DS4State state) { - cState.Copy(state); + cState.CopyTo(state); } public void getPreviousState(DS4State state) { - pState.Copy(state); + pState.CopyTo(state); + } + + private bool isNonSixaxisIdle() + { + 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; + // TODO calibrate to get an accurate jitter and center-play range and centered position + const int slop = 64; + if (cState.LX <= 127 - slop || cState.LX >= 128 + slop || cState.LY <= 127 - slop || cState.LY >= 128 + slop) + return false; + if (cState.RX <= 127 - slop || cState.RX >= 128 + slop || cState.RY <= 127 - slop || cState.RY >= 128 + slop) + return false; + if (cState.Touch1 || cState.Touch2 || cState.TouchButton) + return false; + return true; } private DS4HapticState[] hapticState = new DS4HapticState[1]; diff --git a/DS4Library/DS4State.cs b/DS4Library/DS4State.cs index fe19030..c6b128f 100644 --- a/DS4Library/DS4State.cs +++ b/DS4Library/DS4State.cs @@ -11,7 +11,7 @@ namespace DS4Library 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 bool Share, Options, PS, Touch1, Touch2, TouchButton, TouchRight, TouchLeft; public byte Touch1Identifier, Touch2Identifier; public byte LX, RX, LY, RY, L2, R2; public byte FrameCounter; // 0, 1, 2...62, 63, 0.... @@ -23,7 +23,7 @@ namespace DS4Library Square = Triangle = Circle = Cross = false; DpadUp = DpadDown = DpadLeft = DpadRight = false; L1 = L3 = R1 = R3 = false; - Share = Options = PS = Touch1 = Touch2 = TouchButton = false; + Share = Options = PS = Touch1 = Touch2 = TouchButton = TouchRight = TouchLeft = false; LX = RX = LY = RY = 127; L2 = R2 = 0; FrameCounter = 255; // only actually has 6 bits, so this is a null indicator @@ -52,6 +52,8 @@ namespace DS4Library Options = state.Options; PS = state.PS; Touch1 = state.Touch1; + TouchRight = state.TouchRight; + TouchLeft = state.TouchLeft; Touch1Identifier = state.Touch1Identifier; Touch2 = state.Touch2; Touch2Identifier = state.Touch2Identifier; @@ -70,7 +72,7 @@ namespace DS4Library return new DS4State(this); } - public void Copy(DS4State state) + public void CopyTo(DS4State state) { state.ReportTimeStamp = ReportTimeStamp; state.Square = Square; @@ -94,6 +96,8 @@ namespace DS4Library state.Touch1Identifier = Touch1Identifier; state.Touch2 = Touch2; state.Touch2Identifier = Touch2Identifier; + state.TouchLeft = TouchLeft; + state.TouchRight = TouchRight; state.TouchButton = TouchButton; state.TouchPacketCounter = TouchPacketCounter; state.LX = LX; diff --git a/DS4Library/DS4Touchpad.cs b/DS4Library/DS4Touchpad.cs index cbd3e51..e485566 100644 --- a/DS4Library/DS4Touchpad.cs +++ b/DS4Library/DS4Touchpad.cs @@ -87,7 +87,6 @@ namespace DS4Library TouchUnchanged(this, EventArgs.Empty); return; } - 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); diff --git a/DS4Tool/CustomMapping.Designer.cs b/DS4Tool/CustomMapping.Designer.cs deleted file mode 100644 index cfec556..0000000 --- a/DS4Tool/CustomMapping.Designer.cs +++ /dev/null @@ -1,775 +0,0 @@ -namespace ScpServer -{ - partial class CustomMapping - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.pictureBox = new System.Windows.Forms.PictureBox(); - this.btnLoad = new System.Windows.Forms.Button(); - this.btnSave = new System.Windows.Forms.Button(); - this.cbRepeat = new System.Windows.Forms.CheckBox(); - this.cbScanCode = new System.Windows.Forms.CheckBox(); - this.bnCross = new System.Windows.Forms.Button(); - this.bnCircle = new System.Windows.Forms.Button(); - this.bnSquare = new System.Windows.Forms.Button(); - this.bnTriangle = new System.Windows.Forms.Button(); - this.bnR1 = new System.Windows.Forms.Button(); - this.bnR2 = new System.Windows.Forms.Button(); - this.bnL1 = new System.Windows.Forms.Button(); - this.bnL2 = new System.Windows.Forms.Button(); - this.bnUp = new System.Windows.Forms.Button(); - this.bnDown = new System.Windows.Forms.Button(); - this.bnRight = new System.Windows.Forms.Button(); - this.bnLeft = new System.Windows.Forms.Button(); - this.bnOptions = new System.Windows.Forms.Button(); - this.bnShare = new System.Windows.Forms.Button(); - this.bnTouchpad = new System.Windows.Forms.Button(); - this.bnPS = new System.Windows.Forms.Button(); - this.bnTouchUpper = new System.Windows.Forms.Button(); - this.bnTouchMulti = new System.Windows.Forms.Button(); - this.bnLY = new System.Windows.Forms.Button(); - this.lbControls = new System.Windows.Forms.ListBox(); - this.bnLY2 = new System.Windows.Forms.Button(); - this.bnRY = new System.Windows.Forms.Button(); - this.bnRY2 = new System.Windows.Forms.Button(); - this.bnLX = new System.Windows.Forms.Button(); - this.bnLX2 = new System.Windows.Forms.Button(); - this.bnRX = new System.Windows.Forms.Button(); - 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(); - this.lbMode = new System.Windows.Forms.Label(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit(); - this.SuspendLayout(); - // - // pictureBox - // - this.pictureBox.Anchor = System.Windows.Forms.AnchorStyles.None; - this.pictureBox.Enabled = false; - this.pictureBox.Image = global::ScpServer.Properties.Resources._1; - this.pictureBox.Location = new System.Drawing.Point(16, 67); - this.pictureBox.Name = "pictureBox"; - this.pictureBox.Size = new System.Drawing.Size(396, 214); - this.pictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; - this.pictureBox.TabIndex = 0; - this.pictureBox.TabStop = false; - // - // btnLoad - // - this.btnLoad.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnLoad.Location = new System.Drawing.Point(530, 12); - this.btnLoad.Name = "btnLoad"; - this.btnLoad.Size = new System.Drawing.Size(65, 21); - this.btnLoad.TabIndex = 24; - this.btnLoad.Text = "Load"; - this.btnLoad.UseVisualStyleBackColor = true; - this.btnLoad.Click += new System.EventHandler(this.btnLoad_Click); - // - // btnSave - // - this.btnSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnSave.Location = new System.Drawing.Point(601, 12); - this.btnSave.Name = "btnSave"; - this.btnSave.Size = new System.Drawing.Size(65, 21); - this.btnSave.TabIndex = 25; - this.btnSave.Text = "Save"; - this.btnSave.UseVisualStyleBackColor = true; - this.btnSave.Click += new System.EventHandler(this.btnSave_Click); - // - // cbRepeat - // - this.cbRepeat.Anchor = System.Windows.Forms.AnchorStyles.Top; - this.cbRepeat.AutoSize = true; - this.cbRepeat.ForeColor = System.Drawing.SystemColors.ControlText; - this.cbRepeat.Location = new System.Drawing.Point(19, 12); - this.cbRepeat.Name = "cbRepeat"; - this.cbRepeat.Size = new System.Drawing.Size(61, 17); - this.cbRepeat.TabIndex = 26; - this.cbRepeat.Text = "Repeat"; - this.cbRepeat.UseVisualStyleBackColor = true; - this.cbRepeat.CheckedChanged += new System.EventHandler(this.cbRepeat_CheckedChanged); - // - // cbScanCode - // - this.cbScanCode.Anchor = System.Windows.Forms.AnchorStyles.Top; - this.cbScanCode.AutoSize = true; - this.cbScanCode.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.cbScanCode.Location = new System.Drawing.Point(103, 12); - this.cbScanCode.Name = "cbScanCode"; - this.cbScanCode.Size = new System.Drawing.Size(79, 17); - this.cbScanCode.TabIndex = 50; - this.cbScanCode.Text = "Scan Code"; - this.cbScanCode.UseVisualStyleBackColor = true; - this.cbScanCode.CheckedChanged += new System.EventHandler(this.cbScanCode_CheckedChanged); - // - // bnCross - // - this.bnCross.BackColor = System.Drawing.Color.Transparent; - this.bnCross.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnCross.Cursor = System.Windows.Forms.Cursors.Default; - this.bnCross.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnCross.FlatAppearance.BorderSize = 0; - this.bnCross.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnCross.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnCross.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnCross.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnCross.Location = new System.Drawing.Point(323, 190); - this.bnCross.Name = "bnCross"; - this.bnCross.Size = new System.Drawing.Size(23, 23); - this.bnCross.TabIndex = 53; - this.bnCross.Text = "A Button"; - this.bnCross.UseVisualStyleBackColor = false; - // - // bnCircle - // - this.bnCircle.BackColor = System.Drawing.Color.Transparent; - this.bnCircle.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnCircle.Cursor = System.Windows.Forms.Cursors.Default; - this.bnCircle.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnCircle.FlatAppearance.BorderSize = 0; - this.bnCircle.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnCircle.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnCircle.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnCircle.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnCircle.Location = new System.Drawing.Point(350, 166); - this.bnCircle.Name = "bnCircle"; - this.bnCircle.Size = new System.Drawing.Size(23, 23); - this.bnCircle.TabIndex = 53; - this.bnCircle.Text = "B Button"; - this.bnCircle.UseVisualStyleBackColor = false; - // - // bnSquare - // - this.bnSquare.BackColor = System.Drawing.Color.Transparent; - this.bnSquare.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnSquare.Cursor = System.Windows.Forms.Cursors.Default; - this.bnSquare.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnSquare.FlatAppearance.BorderSize = 0; - this.bnSquare.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnSquare.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnSquare.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnSquare.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnSquare.Location = new System.Drawing.Point(294, 166); - this.bnSquare.Name = "bnSquare"; - this.bnSquare.Size = new System.Drawing.Size(23, 23); - this.bnSquare.TabIndex = 53; - this.bnSquare.Text = "X Button"; - this.bnSquare.UseVisualStyleBackColor = false; - // - // bnTriangle - // - this.bnTriangle.BackColor = System.Drawing.Color.Transparent; - this.bnTriangle.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnTriangle.Cursor = System.Windows.Forms.Cursors.Default; - this.bnTriangle.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnTriangle.FlatAppearance.BorderSize = 0; - this.bnTriangle.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnTriangle.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnTriangle.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnTriangle.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnTriangle.Location = new System.Drawing.Point(322, 140); - this.bnTriangle.Name = "bnTriangle"; - this.bnTriangle.Size = new System.Drawing.Size(23, 23); - this.bnTriangle.TabIndex = 53; - this.bnTriangle.Text = "Y Button"; - this.bnTriangle.UseVisualStyleBackColor = false; - // - // bnR1 - // - this.bnR1.BackColor = System.Drawing.Color.Transparent; - this.bnR1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnR1.Cursor = System.Windows.Forms.Cursors.Default; - this.bnR1.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnR1.FlatAppearance.BorderSize = 0; - this.bnR1.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnR1.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnR1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnR1.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnR1.Location = new System.Drawing.Point(310, 90); - this.bnR1.Name = "bnR1"; - this.bnR1.Size = new System.Drawing.Size(43, 15); - this.bnR1.TabIndex = 53; - this.bnR1.Text = "Right Bumper"; - this.bnR1.UseVisualStyleBackColor = false; - // - // bnR2 - // - this.bnR2.BackColor = System.Drawing.Color.Transparent; - this.bnR2.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnR2.Cursor = System.Windows.Forms.Cursors.Default; - this.bnR2.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnR2.FlatAppearance.BorderSize = 0; - this.bnR2.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnR2.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnR2.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnR2.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnR2.Location = new System.Drawing.Point(309, 65); - this.bnR2.Name = "bnR2"; - this.bnR2.Size = new System.Drawing.Size(43, 20); - this.bnR2.TabIndex = 53; - this.bnR2.Text = "Right Trigger"; - this.bnR2.UseVisualStyleBackColor = false; - // - // bnL1 - // - this.bnL1.BackColor = System.Drawing.Color.Transparent; - this.bnL1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnL1.Cursor = System.Windows.Forms.Cursors.Default; - this.bnL1.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnL1.FlatAppearance.BorderSize = 0; - this.bnL1.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnL1.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnL1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnL1.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnL1.Location = new System.Drawing.Point(73, 88); - this.bnL1.Name = "bnL1"; - this.bnL1.Size = new System.Drawing.Size(43, 15); - this.bnL1.TabIndex = 53; - this.bnL1.Text = "Left Bumper"; - this.bnL1.UseVisualStyleBackColor = false; - // - // bnL2 - // - this.bnL2.BackColor = System.Drawing.Color.Transparent; - this.bnL2.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnL2.Cursor = System.Windows.Forms.Cursors.Default; - this.bnL2.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnL2.FlatAppearance.BorderSize = 0; - this.bnL2.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnL2.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnL2.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnL2.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnL2.Location = new System.Drawing.Point(76, 66); - this.bnL2.Name = "bnL2"; - this.bnL2.Size = new System.Drawing.Size(43, 20); - this.bnL2.TabIndex = 53; - this.bnL2.Text = "Left Trigger"; - this.bnL2.UseVisualStyleBackColor = false; - // - // bnUp - // - this.bnUp.BackColor = System.Drawing.Color.Transparent; - this.bnUp.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnUp.Cursor = System.Windows.Forms.Cursors.Default; - this.bnUp.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnUp.FlatAppearance.BorderSize = 0; - this.bnUp.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnUp.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnUp.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnUp.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnUp.Location = new System.Drawing.Point(84, 142); - this.bnUp.Name = "bnUp"; - this.bnUp.Size = new System.Drawing.Size(19, 22); - this.bnUp.TabIndex = 53; - this.bnUp.Text = "Up Button"; - this.bnUp.UseVisualStyleBackColor = false; - // - // bnDown - // - this.bnDown.BackColor = System.Drawing.Color.Transparent; - this.bnDown.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnDown.Cursor = System.Windows.Forms.Cursors.Default; - this.bnDown.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnDown.FlatAppearance.BorderSize = 0; - this.bnDown.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnDown.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnDown.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - 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, 29); - this.bnDown.TabIndex = 53; - this.bnDown.Text = "Down Button"; - this.bnDown.UseVisualStyleBackColor = false; - // - // bnRight - // - this.bnRight.BackColor = System.Drawing.Color.Transparent; - this.bnRight.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnRight.Cursor = System.Windows.Forms.Cursors.Default; - this.bnRight.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnRight.FlatAppearance.BorderSize = 0; - this.bnRight.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnRight.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnRight.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - 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(27, 22); - this.bnRight.TabIndex = 53; - this.bnRight.Text = "Right Button"; - this.bnRight.UseVisualStyleBackColor = false; - // - // bnLeft - // - this.bnLeft.BackColor = System.Drawing.Color.Transparent; - this.bnLeft.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnLeft.Cursor = System.Windows.Forms.Cursors.Default; - this.bnLeft.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnLeft.FlatAppearance.BorderSize = 0; - this.bnLeft.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnLeft.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnLeft.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - 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, 23); - this.bnLeft.TabIndex = 53; - this.bnLeft.Text = "Left Button"; - this.bnLeft.UseVisualStyleBackColor = false; - // - // bnOptions - // - this.bnOptions.BackColor = System.Drawing.Color.Transparent; - this.bnOptions.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnOptions.Cursor = System.Windows.Forms.Cursors.Default; - this.bnOptions.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnOptions.FlatAppearance.BorderSize = 0; - this.bnOptions.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - 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(286, 121); - this.bnOptions.Name = "bnOptions"; - this.bnOptions.Size = new System.Drawing.Size(19, 30); - this.bnOptions.TabIndex = 53; - this.bnOptions.Text = "Start"; - this.bnOptions.UseVisualStyleBackColor = false; - // - // bnShare - // - this.bnShare.BackColor = System.Drawing.Color.Transparent; - this.bnShare.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnShare.Cursor = System.Windows.Forms.Cursors.Default; - this.bnShare.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnShare.FlatAppearance.BorderSize = 0; - this.bnShare.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - 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, 124); - this.bnShare.Name = "bnShare"; - this.bnShare.Size = new System.Drawing.Size(14, 29); - this.bnShare.TabIndex = 53; - this.bnShare.Text = "Back"; - this.bnShare.UseVisualStyleBackColor = false; - // - // bnTouchpad - // - this.bnTouchpad.BackColor = System.Drawing.Color.Transparent; - this.bnTouchpad.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnTouchpad.Cursor = System.Windows.Forms.Cursors.Default; - this.bnTouchpad.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnTouchpad.FlatAppearance.BorderSize = 0; - this.bnTouchpad.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - 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, 135); - this.bnTouchpad.Name = "bnTouchpad"; - this.bnTouchpad.Size = new System.Drawing.Size(64, 52); - this.bnTouchpad.TabIndex = 53; - this.bnTouchpad.Text = "Click"; - this.bnTouchpad.UseVisualStyleBackColor = false; - // - // bnPS - // - this.bnPS.BackColor = System.Drawing.Color.Transparent; - this.bnPS.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnPS.Cursor = System.Windows.Forms.Cursors.Default; - this.bnPS.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnPS.FlatAppearance.BorderSize = 0; - this.bnPS.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnPS.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnPS.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnPS.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnPS.Location = new System.Drawing.Point(205, 208); - this.bnPS.Name = "bnPS"; - this.bnPS.Size = new System.Drawing.Size(18, 18); - this.bnPS.TabIndex = 53; - this.bnPS.Text = "Guide"; - this.bnPS.UseVisualStyleBackColor = false; - // - // bnTouchUpper - // - this.bnTouchUpper.BackColor = System.Drawing.Color.Transparent; - this.bnTouchUpper.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnTouchUpper.Cursor = System.Windows.Forms.Cursors.Default; - this.bnTouchUpper.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnTouchUpper.FlatAppearance.BorderSize = 0; - this.bnTouchUpper.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnTouchUpper.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnTouchUpper.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - 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(129, 32); - this.bnTouchUpper.TabIndex = 53; - this.bnTouchUpper.Text = "Middle Click"; - this.bnTouchUpper.UseVisualStyleBackColor = false; - // - // bnTouchMulti - // - this.bnTouchMulti.BackColor = System.Drawing.Color.Transparent; - this.bnTouchMulti.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnTouchMulti.Cursor = System.Windows.Forms.Cursors.Default; - this.bnTouchMulti.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnTouchMulti.FlatAppearance.BorderSize = 0; - this.bnTouchMulti.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - 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, 135); - this.bnTouchMulti.Name = "bnTouchMulti"; - this.bnTouchMulti.Size = new System.Drawing.Size(64, 52); - this.bnTouchMulti.TabIndex = 53; - this.bnTouchMulti.Text = "Right Click"; - this.bnTouchMulti.UseVisualStyleBackColor = false; - // - // bnLY - // - this.bnLY.BackColor = System.Drawing.Color.Transparent; - this.bnLY.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnLY.Cursor = System.Windows.Forms.Cursors.Default; - this.bnLY.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnLY.FlatAppearance.BorderSize = 0; - this.bnLY.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnLY.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnLY.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnLY.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnLY.Location = new System.Drawing.Point(144, 213); - this.bnLY.Name = "bnLY"; - this.bnLY.Size = new System.Drawing.Size(21, 10); - this.bnLY.TabIndex = 53; - this.bnLY.Text = "Left Y-Axis-"; - this.bnLY.UseVisualStyleBackColor = false; - // - // lbControls - // - this.lbControls.FormattingEnabled = true; - this.lbControls.Items.AddRange(new object[] { - ""}); - 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; - // - // bnLY2 - // - this.bnLY2.BackColor = System.Drawing.Color.Transparent; - this.bnLY2.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnLY2.Cursor = System.Windows.Forms.Cursors.Default; - this.bnLY2.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnLY2.FlatAppearance.BorderSize = 0; - this.bnLY2.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnLY2.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnLY2.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnLY2.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnLY2.Location = new System.Drawing.Point(144, 241); - this.bnLY2.Name = "bnLY2"; - this.bnLY2.Size = new System.Drawing.Size(21, 10); - this.bnLY2.TabIndex = 53; - this.bnLY2.Text = "Left Y-Axis+"; - this.bnLY2.UseVisualStyleBackColor = false; - // - // bnRY - // - this.bnRY.BackColor = System.Drawing.Color.Transparent; - this.bnRY.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnRY.Cursor = System.Windows.Forms.Cursors.Default; - this.bnRY.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnRY.FlatAppearance.BorderSize = 0; - this.bnRY.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnRY.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnRY.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnRY.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnRY.Location = new System.Drawing.Point(265, 213); - this.bnRY.Name = "bnRY"; - this.bnRY.Size = new System.Drawing.Size(21, 10); - this.bnRY.TabIndex = 53; - this.bnRY.Text = "Right Y-Axis-"; - this.bnRY.UseVisualStyleBackColor = false; - // - // bnRY2 - // - this.bnRY2.BackColor = System.Drawing.Color.Transparent; - this.bnRY2.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnRY2.Cursor = System.Windows.Forms.Cursors.Default; - this.bnRY2.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnRY2.FlatAppearance.BorderSize = 0; - this.bnRY2.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnRY2.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnRY2.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnRY2.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnRY2.Location = new System.Drawing.Point(265, 241); - this.bnRY2.Name = "bnRY2"; - this.bnRY2.Size = new System.Drawing.Size(21, 10); - this.bnRY2.TabIndex = 53; - this.bnRY2.Text = "Right Y-Axis+"; - this.bnRY2.UseVisualStyleBackColor = false; - // - // bnLX - // - this.bnLX.BackColor = System.Drawing.Color.Transparent; - this.bnLX.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnLX.Cursor = System.Windows.Forms.Cursors.Default; - this.bnLX.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnLX.FlatAppearance.BorderSize = 0; - this.bnLX.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnLX.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnLX.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnLX.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnLX.Location = new System.Drawing.Point(131, 222); - this.bnLX.Name = "bnLX"; - this.bnLX.Size = new System.Drawing.Size(10, 20); - this.bnLX.TabIndex = 53; - this.bnLX.Text = "Left X-Axis-"; - this.bnLX.UseVisualStyleBackColor = false; - // - // bnLX2 - // - this.bnLX2.BackColor = System.Drawing.Color.Transparent; - this.bnLX2.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnLX2.Cursor = System.Windows.Forms.Cursors.Default; - this.bnLX2.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnLX2.FlatAppearance.BorderSize = 0; - this.bnLX2.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnLX2.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnLX2.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnLX2.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnLX2.Location = new System.Drawing.Point(167, 222); - this.bnLX2.Name = "bnLX2"; - this.bnLX2.Size = new System.Drawing.Size(10, 20); - this.bnLX2.TabIndex = 53; - this.bnLX2.Text = "Left X-Axis+"; - this.bnLX2.UseVisualStyleBackColor = false; - // - // bnRX - // - this.bnRX.BackColor = System.Drawing.Color.Transparent; - this.bnRX.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnRX.Cursor = System.Windows.Forms.Cursors.Default; - this.bnRX.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnRX.FlatAppearance.BorderSize = 0; - this.bnRX.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnRX.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnRX.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnRX.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnRX.Location = new System.Drawing.Point(253, 222); - this.bnRX.Name = "bnRX"; - this.bnRX.Size = new System.Drawing.Size(10, 20); - this.bnRX.TabIndex = 53; - this.bnRX.Text = "Right X-Axis-"; - this.bnRX.UseVisualStyleBackColor = false; - // - // bnRX2 - // - this.bnRX2.BackColor = System.Drawing.Color.Transparent; - this.bnRX2.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnRX2.Cursor = System.Windows.Forms.Cursors.Default; - this.bnRX2.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnRX2.FlatAppearance.BorderSize = 0; - this.bnRX2.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnRX2.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnRX2.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnRX2.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnRX2.Location = new System.Drawing.Point(289, 222); - this.bnRX2.Name = "bnRX2"; - this.bnRX2.Size = new System.Drawing.Size(10, 20); - this.bnRX2.TabIndex = 53; - this.bnRX2.Text = "Right X-Axis+"; - this.bnRX2.UseVisualStyleBackColor = false; - // - // bnL3 - // - this.bnL3.BackColor = System.Drawing.Color.Transparent; - this.bnL3.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnL3.Cursor = System.Windows.Forms.Cursors.Default; - this.bnL3.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnL3.FlatAppearance.BorderSize = 0; - this.bnL3.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnL3.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnL3.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnL3.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnL3.Location = new System.Drawing.Point(147, 223); - this.bnL3.Name = "bnL3"; - this.bnL3.Size = new System.Drawing.Size(16, 17); - this.bnL3.TabIndex = 53; - this.bnL3.Text = "Left Stick"; - this.bnL3.UseVisualStyleBackColor = false; - // - // bnR3 - // - this.bnR3.BackColor = System.Drawing.Color.Transparent; - this.bnR3.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.bnR3.Cursor = System.Windows.Forms.Cursors.Default; - this.bnR3.FlatAppearance.BorderColor = System.Drawing.Color.Red; - this.bnR3.FlatAppearance.BorderSize = 0; - this.bnR3.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.Control; - this.bnR3.FlatAppearance.MouseOverBackColor = System.Drawing.SystemColors.Control; - this.bnR3.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.bnR3.ForeColor = System.Drawing.SystemColors.WindowText; - this.bnR3.Location = new System.Drawing.Point(267, 224); - this.bnR3.Name = "bnR3"; - this.bnR3.Size = new System.Drawing.Size(16, 17); - this.bnR3.TabIndex = 53; - this.bnR3.Text = "Right Stick"; - this.bnR3.UseVisualStyleBackColor = false; - // - // TouchTip - // - this.TouchTip.AutoSize = true; - this.TouchTip.Location = new System.Drawing.Point(141, 34); - this.TouchTip.MaximumSize = new System.Drawing.Size(151, 52); - this.TouchTip.MinimumSize = new System.Drawing.Size(151, 52); - this.TouchTip.Name = "TouchTip"; - this.TouchTip.Size = new System.Drawing.Size(151, 52); - this.TouchTip.TabIndex = 55; - this.TouchTip.Text = "Touchpad (Standard Mode):\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; - // - // lbMode - // - this.lbMode.AutoSize = true; - this.lbMode.Location = new System.Drawing.Point(418, 51); - this.lbMode.Name = "lbMode"; - this.lbMode.Size = new System.Drawing.Size(51, 13); - this.lbMode.TabIndex = 56; - this.lbMode.Text = "Controller"; - this.lbMode.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.TouchTip); - this.Controls.Add(this.ReapTip); - this.Controls.Add(this.pictureBox); - this.Controls.Add(this.lbMode); - this.Controls.Add(this.lbControls); - this.Controls.Add(this.cbScanCode); - this.Controls.Add(this.cbRepeat); - this.Controls.Add(this.btnSave); - this.Controls.Add(this.btnLoad); - this.Controls.Add(this.bnL2); - this.Controls.Add(this.bnR2); - this.Controls.Add(this.bnL1); - this.Controls.Add(this.bnR1); - this.Controls.Add(this.bnLeft); - this.Controls.Add(this.bnRY2); - this.Controls.Add(this.bnRY); - this.Controls.Add(this.bnLY2); - this.Controls.Add(this.bnRX2); - this.Controls.Add(this.bnLX2); - this.Controls.Add(this.bnRX); - this.Controls.Add(this.bnLX); - this.Controls.Add(this.bnLY); - this.Controls.Add(this.bnRight); - this.Controls.Add(this.bnDown); - this.Controls.Add(this.bnR3); - this.Controls.Add(this.bnL3); - this.Controls.Add(this.bnPS); - this.Controls.Add(this.bnShare); - this.Controls.Add(this.bnTouchUpper); - this.Controls.Add(this.bnTouchMulti); - this.Controls.Add(this.bnTouchpad); - this.Controls.Add(this.bnOptions); - this.Controls.Add(this.bnUp); - this.Controls.Add(this.bnTriangle); - this.Controls.Add(this.bnSquare); - this.Controls.Add(this.bnCircle); - this.Controls.Add(this.bnCross); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.MaximizeBox = false; - this.MaximumSize = new System.Drawing.Size(700, 349); - this.MinimumSize = new System.Drawing.Size(700, 349); - this.Name = "CustomMapping"; - this.Text = "Custom Mapping"; - ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.PictureBox pictureBox; - private System.Windows.Forms.CheckBox cbRepeat; - private System.Windows.Forms.Button btnLoad; - private System.Windows.Forms.Button btnSave; - private System.Windows.Forms.CheckBox cbScanCode; - private System.Windows.Forms.Button bnCross; - private System.Windows.Forms.Button bnCircle; - private System.Windows.Forms.Button bnSquare; - private System.Windows.Forms.Button bnTriangle; - private System.Windows.Forms.Button bnR1; - private System.Windows.Forms.Button bnR2; - private System.Windows.Forms.Button bnL1; - private System.Windows.Forms.Button bnL2; - private System.Windows.Forms.Button bnUp; - private System.Windows.Forms.Button bnDown; - private System.Windows.Forms.Button bnRight; - private System.Windows.Forms.Button bnLeft; - private System.Windows.Forms.Button bnOptions; - private System.Windows.Forms.Button bnShare; - private System.Windows.Forms.Button bnTouchpad; - private System.Windows.Forms.Button bnPS; - private System.Windows.Forms.Button bnTouchUpper; - private System.Windows.Forms.Button bnTouchMulti; - private System.Windows.Forms.Button bnLY; - private System.Windows.Forms.ListBox lbControls; - private System.Windows.Forms.Button bnLY2; - private System.Windows.Forms.Button bnRY; - private System.Windows.Forms.Button bnRY2; - private System.Windows.Forms.Button bnLX; - private System.Windows.Forms.Button bnLX2; - private System.Windows.Forms.Button bnRX; - 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; - private System.Windows.Forms.Label lbMode; - } -} \ No newline at end of file diff --git a/DS4Tool/CustomMapping.cs b/DS4Tool/CustomMapping.cs deleted file mode 100644 index 2d6497b..0000000 --- a/DS4Tool/CustomMapping.cs +++ /dev/null @@ -1,389 +0,0 @@ -using DS4Control; -using DS4Library; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Linq; -using System.Text; -using System.Windows.Forms; - -namespace ScpServer -{ - public partial class CustomMapping : Form - { - private int device; - private bool handleNextKeyPress = false; - private bool ReapTipShown = false; - private List comboBoxes = new List(); - private List