diff --git a/pom.xml b/pom.xml
index 8a9a7c0..5a1aa59 100644
--- a/pom.xml
+++ b/pom.xml
@@ -138,9 +138,14 @@
1eb4087
- com.github.Maschell
+ com.github.QuarkTheAwesome
purejavahidapi
- cbf0588
+ 3591b7e
+
+
+ org.hid4java
+ hid4java
+ 0.4.0
diff --git a/src/net/ash/HIDToVPADNetworkClient/Main.java b/src/net/ash/HIDToVPADNetworkClient/Main.java
index 5b5cf7c..45cad29 100644
--- a/src/net/ash/HIDToVPADNetworkClient/Main.java
+++ b/src/net/ash/HIDToVPADNetworkClient/Main.java
@@ -37,8 +37,8 @@ public final class Main {
public static void main(String[] args) {
Settings.loadSettings();
try {
- new Thread(ActiveControllerManager.getInstance()).start();
- new Thread(NetworkManager.getInstance()).start();
+ new Thread(ActiveControllerManager.getInstance(), "ActiveControllerManager").start();
+ new Thread(NetworkManager.getInstance(), "NetworkManager").start();
} catch (Exception e) {
e.printStackTrace();
fatal();
diff --git a/src/net/ash/HIDToVPADNetworkClient/controller/Controller.java b/src/net/ash/HIDToVPADNetworkClient/controller/Controller.java
index 4792971..af5d1e5 100644
--- a/src/net/ash/HIDToVPADNetworkClient/controller/Controller.java
+++ b/src/net/ash/HIDToVPADNetworkClient/controller/Controller.java
@@ -21,6 +21,8 @@
*******************************************************************************/
package net.ash.HIDToVPADNetworkClient.controller;
+import java.util.Arrays;
+
import lombok.Getter;
import lombok.Synchronized;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
@@ -41,6 +43,8 @@ public abstract class Controller implements Runnable {
@Getter private final String identifier;
private byte[] latestData = null;
+ protected int MAX_PACKET_LENGTH = 64;
+
boolean shutdown = false;
boolean shutdownDone = false;
private final Object dataLock = new Object();
@@ -54,7 +58,7 @@ public abstract class Controller implements Runnable {
this.type = type;
this.identifier = identifier;
if (!initController(identifier)) {
- throw new ControllerInitializationFailedException();
+ throw new ControllerInitializationFailedException("Initialization failed");
}
}
@@ -62,14 +66,18 @@ public abstract class Controller implements Runnable {
public void run() {
boolean shutdownState = shutdown;
while (!shutdownState) {
- Utilities.sleep(Settings.DETECT_CONTROLLER_INTERVAL);
while (isActive()) {
byte[] newData = pollLatestData();
if (newData != null && newData.length != 0) {
+ if (newData.length > MAX_PACKET_LENGTH) {
+ newData = Arrays.copyOfRange(newData, 0, MAX_PACKET_LENGTH);
+ }
+ // System.out.println("data:" + Utilities.ByteArrayToString(newData));
setLatestData(newData);
}
doSleepAfterPollingData();
}
+ Utilities.sleep(Settings.DETECT_CONTROLLER_ACTIVE_INTERVAL);
synchronized (shutdownLock) {
shutdownState = shutdown;
}
@@ -202,7 +210,7 @@ public abstract class Controller implements Runnable {
}
public enum ControllerType {
- PureJAVAHid, LINUX, XINPUT13, XINPUT14
+ HIDController, LINUX, XINPUT13, XINPUT14
}
public abstract String getInfoText();
diff --git a/src/net/ash/HIDToVPADNetworkClient/controller/DS4NewController.java b/src/net/ash/HIDToVPADNetworkClient/controller/DS4NewController.java
index 22b1f8c..e4aa4c4 100644
--- a/src/net/ash/HIDToVPADNetworkClient/controller/DS4NewController.java
+++ b/src/net/ash/HIDToVPADNetworkClient/controller/DS4NewController.java
@@ -5,26 +5,27 @@ import java.util.Arrays;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
import net.ash.HIDToVPADNetworkClient.util.Settings;
-public class DS4NewController extends PureJavaHidController {
+public class DS4NewController extends HidController {
public static final short DS4_NEW_CONTROLLER_VID = 0x54C;
public static final short DS4_NEW_CONTROLLER_PID = 0x09CC;
public DS4NewController(String identifier) throws ControllerInitializationFailedException {
super(identifier);
if (Settings.isMacOSX()) {
- this.PACKET_LENGTH = 7;
+ this.MAX_PACKET_LENGTH = 7;
} else {
- this.PACKET_LENGTH = 6;
+ this.MAX_PACKET_LENGTH = 6;
}
}
@Override
public byte[] pollLatestData() {
- if (Settings.isMacOSX()) { // for some reason the controller has one extra byte at the beginning under OSX
- return Arrays.copyOfRange(currentData, 1, 7);
+ byte[] currentData = super.pollLatestData();
+ if (Settings.isMacOSX() && currentData != null && currentData.length > 6) { // for some reason the controller has one extra byte at the beginning under
+ // OSX
+ currentData = Arrays.copyOfRange(currentData, 1, 7);
}
-
- return currentData.clone();
+ return currentData;
}
@Override
diff --git a/src/net/ash/HIDToVPADNetworkClient/controller/PureJavaHidController.java b/src/net/ash/HIDToVPADNetworkClient/controller/HidController.java
similarity index 67%
rename from src/net/ash/HIDToVPADNetworkClient/controller/PureJavaHidController.java
rename to src/net/ash/HIDToVPADNetworkClient/controller/HidController.java
index 57c2523..c753d18 100644
--- a/src/net/ash/HIDToVPADNetworkClient/controller/PureJavaHidController.java
+++ b/src/net/ash/HIDToVPADNetworkClient/controller/HidController.java
@@ -22,63 +22,54 @@
package net.ash.HIDToVPADNetworkClient.controller;
import java.io.IOException;
-import java.util.Arrays;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
-import lombok.Synchronized;
import lombok.extern.java.Log;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
-import net.ash.HIDToVPADNetworkClient.util.PureJavaHidApiManager;
-import purejavahidapi.HidDevice;
-import purejavahidapi.InputReportListener;
+import net.ash.HIDToVPADNetworkClient.hid.HidDevice;
+import net.ash.HIDToVPADNetworkClient.hid.HidManager;
@Log
-public class PureJavaHidController extends Controller implements InputReportListener {
- private final Object dataLock = new Object();
- protected byte[] currentData = new byte[1];
-
- protected int PACKET_LENGTH = 64;
-
+public class HidController extends Controller {
@Getter @Setter(AccessLevel.PRIVATE) private HidDevice hidDevice;
public static Controller getInstance(String deviceIdentifier) throws IOException, ControllerInitializationFailedException {
- HidDevice device = PureJavaHidApiManager.getDeviceByPath(deviceIdentifier);
+
+ HidDevice device = HidManager.getDeviceByPath(deviceIdentifier);
short vid = 0;
short pid = 0;
if (device != null) {
- vid = device.getHidDeviceInfo().getVendorId();
- pid = device.getHidDeviceInfo().getProductId();
- device.close();
+ vid = device.getVendorId();
+ pid = device.getProductId();
}
// We use a special version to optimize the data for the switch pro controller
if (vid == SwitchProController.SWITCH_PRO_CONTROLLER_VID && pid == SwitchProController.SWITCH_PRO_CONTROLLER_PID) {
-
return new SwitchProController(deviceIdentifier);
} else if (vid == DS4NewController.DS4_NEW_CONTROLLER_VID && pid == DS4NewController.DS4_NEW_CONTROLLER_PID) {
return new DS4NewController(deviceIdentifier);
} else {
- return new PureJavaHidController(deviceIdentifier);
+ return new HidController(deviceIdentifier);
}
}
- public PureJavaHidController(String identifier) throws ControllerInitializationFailedException {
- super(ControllerType.PureJAVAHid, identifier);
+ public HidController(String identifier) throws ControllerInitializationFailedException {
+ super(ControllerType.HIDController, identifier);
}
@Override
public boolean initController(String identifier) {
- HidDevice device;
try {
- device = PureJavaHidApiManager.getDeviceByPath(identifier);
- if (device == null) {
+ HidDevice device = HidManager.getDeviceByPath(identifier);
+
+ if (device == null || !device.open()) {
return false;
}
+ log.info("HidDevice opened!");
- device.setInputReportListener(this);
setHidDevice(device);
return true;
@@ -89,9 +80,9 @@ public class PureJavaHidController extends Controller implements InputReportList
}
@Override
- @Synchronized("dataLock")
public byte[] pollLatestData() {
- return currentData.clone();
+ byte[] result = hidDevice.getLatestData();
+ return result;
}
@Override
@@ -105,34 +96,21 @@ public class PureJavaHidController extends Controller implements InputReportList
throw e;
}
}
-
}
@Override
public short getVID() {
- return getHidDevice().getHidDeviceInfo().getVendorId();
+ return getHidDevice().getVendorId();
}
@Override
public short getPID() {
- return getHidDevice().getHidDeviceInfo().getProductId();
- }
-
- @Override
- @Synchronized("dataLock")
- public void onInputReport(HidDevice source, byte reportID, byte[] reportData, int reportLength) {
- if (isActive()) {
- int length = PACKET_LENGTH;
- if (reportLength < length) {
- length = reportLength;
- }
- currentData = Arrays.copyOfRange(reportData, 0, length);
- }
+ return getHidDevice().getProductId();
}
@Override
public String getInfoText() {
- // TODO:
+ // TODO: own class for joycons
if (getVID() == 0x57e) {
if (getPID() == 0x2006) {
return "Joy-Con (L) on " + getIdentifier();
diff --git a/src/net/ash/HIDToVPADNetworkClient/controller/SwitchProController.java b/src/net/ash/HIDToVPADNetworkClient/controller/SwitchProController.java
index d1a6842..bc606b7 100644
--- a/src/net/ash/HIDToVPADNetworkClient/controller/SwitchProController.java
+++ b/src/net/ash/HIDToVPADNetworkClient/controller/SwitchProController.java
@@ -23,18 +23,19 @@ package net.ash.HIDToVPADNetworkClient.controller;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
-public class SwitchProController extends PureJavaHidController {
+public class SwitchProController extends HidController {
public static final short SWITCH_PRO_CONTROLLER_VID = 0x57e;
public static final short SWITCH_PRO_CONTROLLER_PID = 0x2009;
public SwitchProController(String identifier) throws ControllerInitializationFailedException {
super(identifier);
// truncate package to 11;
- this.PACKET_LENGTH = 11;
+ this.MAX_PACKET_LENGTH = 11;
}
@Override
public byte[] pollLatestData() {
+ byte[] currentData = super.pollLatestData();
if (currentData == null || currentData.length < 10) {
return new byte[0];
}
@@ -43,7 +44,7 @@ public class SwitchProController extends PureJavaHidController {
currentData[5] = 0;
currentData[7] = 0;
currentData[9] = 0;
- return currentData.clone();
+ return currentData;
}
@Override
diff --git a/src/net/ash/HIDToVPADNetworkClient/exeption/ControllerInitializationFailedException.java b/src/net/ash/HIDToVPADNetworkClient/exeption/ControllerInitializationFailedException.java
index bc09711..15ebd7d 100644
--- a/src/net/ash/HIDToVPADNetworkClient/exeption/ControllerInitializationFailedException.java
+++ b/src/net/ash/HIDToVPADNetworkClient/exeption/ControllerInitializationFailedException.java
@@ -23,6 +23,10 @@ package net.ash.HIDToVPADNetworkClient.exeption;
public class ControllerInitializationFailedException extends Exception {
+ public ControllerInitializationFailedException(String string) {
+ super(string);
+ }
+
/**
*
*/
diff --git a/src/net/ash/HIDToVPADNetworkClient/gui/GuiInputControls.java b/src/net/ash/HIDToVPADNetworkClient/gui/GuiInputControls.java
index e8b2067..dccbfdc 100644
--- a/src/net/ash/HIDToVPADNetworkClient/gui/GuiInputControls.java
+++ b/src/net/ash/HIDToVPADNetworkClient/gui/GuiInputControls.java
@@ -61,11 +61,7 @@ public final class GuiInputControls extends JPanel {
connectButton.setAlignmentX(Component.CENTER_ALIGNMENT);
final JCheckBox cbautoScanForController = new JCheckBox();
- if (Settings.isMacOSX()) {
- cbautoScanForController.setEnabled(false);
- } else {
- cbautoScanForController.setSelected(Settings.SCAN_AUTOMATICALLY_FOR_CONTROLLERS);
- }
+ cbautoScanForController.setSelected(Settings.SCAN_AUTOMATICALLY_FOR_CONTROLLERS);
cbautoScanForController.addActionListener(new ActionListener() {
diff --git a/src/net/ash/HIDToVPADNetworkClient/hid/HidDevice.java b/src/net/ash/HIDToVPADNetworkClient/hid/HidDevice.java
new file mode 100644
index 0000000..15391de
--- /dev/null
+++ b/src/net/ash/HIDToVPADNetworkClient/hid/HidDevice.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *******************************************************************************/
+package net.ash.HIDToVPADNetworkClient.hid;
+
+public interface HidDevice {
+
+ short getVendorId();
+
+ short getProductId();
+
+ void close();
+
+ byte[] getLatestData();
+
+ short getUsage();
+
+ String getPath();
+
+ boolean open();
+
+}
diff --git a/src/net/ash/HIDToVPADNetworkClient/hid/HidManager.java b/src/net/ash/HIDToVPADNetworkClient/hid/HidManager.java
new file mode 100644
index 0000000..92adccc
--- /dev/null
+++ b/src/net/ash/HIDToVPADNetworkClient/hid/HidManager.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *******************************************************************************/
+package net.ash.HIDToVPADNetworkClient.hid;
+
+import java.io.IOException;
+import java.util.List;
+
+import net.ash.HIDToVPADNetworkClient.hid.hid4java.Hid4JavaHidManagerBackend;
+import net.ash.HIDToVPADNetworkClient.hid.purejavahid.PureJavaHidManagerBackend;
+import net.ash.HIDToVPADNetworkClient.util.Settings;
+
+public class HidManager {
+ private final static HidManagerBackend backend;
+
+ public static List getAttachedController() {
+ return backend.getAttachedController();
+ }
+
+ public static HidDevice getDeviceByPath(String path) throws IOException {
+ return backend.getDeviceByPath(path);
+ }
+
+ static {
+ if (Settings.isMacOSX()) {
+ backend = new Hid4JavaHidManagerBackend();
+ } else if (Settings.isWindows()) {
+ backend = new PureJavaHidManagerBackend();
+ } else if (Settings.isLinux()) {
+ backend = new Hid4JavaHidManagerBackend();
+ } else
+ backend = null;
+ }
+}
diff --git a/src/net/ash/HIDToVPADNetworkClient/util/PureJavaHidApiManager.java b/src/net/ash/HIDToVPADNetworkClient/hid/HidManagerBackend.java
similarity index 59%
rename from src/net/ash/HIDToVPADNetworkClient/util/PureJavaHidApiManager.java
rename to src/net/ash/HIDToVPADNetworkClient/hid/HidManagerBackend.java
index 78fad0e..e1cef57 100644
--- a/src/net/ash/HIDToVPADNetworkClient/util/PureJavaHidApiManager.java
+++ b/src/net/ash/HIDToVPADNetworkClient/hid/HidManagerBackend.java
@@ -19,22 +19,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
-package net.ash.HIDToVPADNetworkClient.util;
+package net.ash.HIDToVPADNetworkClient.hid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import net.ash.HIDToVPADNetworkClient.manager.ControllerManager;
-import purejavahidapi.HidDevice;
-import purejavahidapi.HidDeviceInfo;
-import purejavahidapi.PureJavaHidApi;
-
-public final class PureJavaHidApiManager {
-
- private PureJavaHidApiManager() {
- }
+import net.ash.HIDToVPADNetworkClient.util.Settings;
+public abstract class HidManagerBackend {
/**
* Searches the corresponding HIDDevice for the given path
*
@@ -43,25 +36,12 @@ public final class PureJavaHidApiManager {
* @return It the device is found, it will be returned. Otherwise null is returned.
* @throws IOException
*/
- public static HidDevice getDeviceByPath(String path) throws IOException {
- HidDeviceInfo deviceinfo = ControllerManager.getDeviceInfoByPath(path);
- if (deviceinfo != null) {
- HidDevice result = PureJavaHidApi.openDevice(deviceinfo);
- if (result != null) {
- return result;
- }
- }
- /*
- * List devList = PureJavaHidApi.enumerateDevices(); HidDevice result = null; for (HidDeviceInfo info : devList) { String real_path =
- * info.getPath(); if (real_path.equals(path)) { return PureJavaHidApi.openDevice(info); } }
- */
- return null;
- }
+ public abstract HidDevice getDeviceByPath(String path) throws IOException;
- public static List getAttachedController() {
- List connectedGamepads = new ArrayList();
+ public List getAttachedController() {
+ List connectedGamepads = new ArrayList();
- for (HidDeviceInfo info : PureJavaHidApi.enumerateDevices()) {
+ for (HidDevice info : enumerateDevices()) {
if (isGamepad(info)) {
// Skip Xbox controller under windows. We should use XInput instead.
if (isXboxController(info) && Settings.isWindows()) {
@@ -73,24 +53,26 @@ public final class PureJavaHidApiManager {
return connectedGamepads;
}
- public static boolean isGamepad(HidDeviceInfo info) {
+ public static boolean isGamepad(HidDevice info) {
if (info == null) return false;
- short usagePage = info.getUsagePage();
- return (usagePage == 0x05 || usagePage == 0x01 || usagePage == 0x04 || isNintendoController(info) || isPlaystationController(info));
+ short usage = info.getUsage();
+ return (usage == 0x05 || usage == 0x04 || isNintendoController(info) || isPlaystationController(info));
}
- private static boolean isPlaystationController(HidDeviceInfo info) {
+ private static boolean isPlaystationController(HidDevice info) {
if (info == null) return false;
return (info.getVendorId() == 0x054c);
}
- private static boolean isNintendoController(HidDeviceInfo info) {
+ private static boolean isNintendoController(HidDevice info) {
if (info == null) return false;
return (info.getVendorId() == 0x57e);
}
- private static boolean isXboxController(HidDeviceInfo info) {
+ private static boolean isXboxController(HidDevice info) {
if (info == null) return false;
return (info.getVendorId() == 0x045e) && ((info.getProductId() == 0x02ff) || (info.getProductId() == 0x02a1));
}
+
+ public abstract List enumerateDevices();
}
diff --git a/src/net/ash/HIDToVPADNetworkClient/hid/hid4java/Hid4JavaHidDevice.java b/src/net/ash/HIDToVPADNetworkClient/hid/hid4java/Hid4JavaHidDevice.java
new file mode 100644
index 0000000..9d9c661
--- /dev/null
+++ b/src/net/ash/HIDToVPADNetworkClient/hid/hid4java/Hid4JavaHidDevice.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *******************************************************************************/
+package net.ash.HIDToVPADNetworkClient.hid.hid4java;
+
+import java.util.Arrays;
+
+import net.ash.HIDToVPADNetworkClient.hid.HidDevice;
+
+class Hid4JavaHidDevice implements HidDevice {
+ private org.hid4java.HidDevice myDevice;
+
+ private final byte[] data = new byte[64];
+
+ public Hid4JavaHidDevice(org.hid4java.HidDevice device) {
+ this.myDevice = device;
+ }
+
+ @Override
+ public boolean open() {
+ return myDevice.open();
+ }
+
+ @Override
+ public void close() {
+ myDevice.close();
+ }
+
+ @Override
+ public short getVendorId() {
+ return myDevice.getVendorId();
+ }
+
+ @Override
+ public short getProductId() {
+ return myDevice.getProductId();
+ }
+
+ @Override
+ public byte[] getLatestData() {
+ int length = myDevice.read(data);
+ if (length <= 0) return new byte[0];
+ return Arrays.copyOf(data, length);
+ }
+
+ @Override
+ public String getPath() {
+ return myDevice.getPath();
+ }
+
+ @Override
+ public String toString() {
+ return "Hid4JavaHidDevice [myDevice=" + myDevice + ", data=" + Arrays.toString(data) + "]";
+ }
+
+ @Override
+ public short getUsage() {
+ return (short) myDevice.getUsage();
+ }
+}
diff --git a/src/net/ash/HIDToVPADNetworkClient/hid/hid4java/Hid4JavaHidManagerBackend.java b/src/net/ash/HIDToVPADNetworkClient/hid/hid4java/Hid4JavaHidManagerBackend.java
new file mode 100644
index 0000000..d1dd1fe
--- /dev/null
+++ b/src/net/ash/HIDToVPADNetworkClient/hid/hid4java/Hid4JavaHidManagerBackend.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *******************************************************************************/
+package net.ash.HIDToVPADNetworkClient.hid.hid4java;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hid4java.HidManager;
+import org.hid4java.HidServices;
+
+import net.ash.HIDToVPADNetworkClient.hid.HidDevice;
+import net.ash.HIDToVPADNetworkClient.hid.HidManagerBackend;
+
+public class Hid4JavaHidManagerBackend extends HidManagerBackend {
+
+ @Override
+ public HidDevice getDeviceByPath(String path) throws IOException {
+ HidDevice result = null;
+ HidServices services = HidManager.getHidServices();
+ if (services == null) return result;
+
+ for (org.hid4java.HidDevice device : services.getAttachedHidDevices()) {
+ if (device.getPath().equals(path)) {
+ result = new Hid4JavaHidDevice(device);
+ break;
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public List enumerateDevices() {
+ List result = new ArrayList();
+ for (org.hid4java.HidDevice info : HidManager.getHidServices().getAttachedHidDevices()) {
+ result.add(new Hid4JavaHidDevice(info));
+ }
+ return result;
+ }
+
+}
diff --git a/src/net/ash/HIDToVPADNetworkClient/hid/purejavahid/PureJavaHidDevice.java b/src/net/ash/HIDToVPADNetworkClient/hid/purejavahid/PureJavaHidDevice.java
new file mode 100644
index 0000000..c7b28a6
--- /dev/null
+++ b/src/net/ash/HIDToVPADNetworkClient/hid/purejavahid/PureJavaHidDevice.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *******************************************************************************/
+package net.ash.HIDToVPADNetworkClient.hid.purejavahid;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import lombok.Synchronized;
+import net.ash.HIDToVPADNetworkClient.hid.HidDevice;
+import purejavahidapi.HidDeviceInfo;
+import purejavahidapi.InputReportListener;
+
+class PureJavaHidDevice implements HidDevice, InputReportListener {
+ private purejavahidapi.HidDevice myDevice = null;
+ private final purejavahidapi.HidDeviceInfo myDeviceInfo;
+
+ private final Object dataLock = new Object();
+ protected byte[] currentData = new byte[1];
+
+ public PureJavaHidDevice(HidDeviceInfo info) {
+ this.myDeviceInfo = info;
+ }
+
+ @Override
+ @Synchronized("dataLock")
+ public void onInputReport(purejavahidapi.HidDevice source, byte reportID, byte[] reportData, int reportLength) {
+ currentData = Arrays.copyOfRange(reportData, 0, reportLength);
+ }
+
+ @Override
+ public short getVendorId() {
+ return myDeviceInfo.getVendorId();
+ }
+
+ @Override
+ public short getProductId() {
+ return myDeviceInfo.getProductId();
+ }
+
+ @Override
+ public boolean open() {
+ boolean result = true;
+ try {
+ myDevice = purejavahidapi.PureJavaHidApi.openDevice(myDeviceInfo);
+ myDevice.setInputReportListener(this);
+ } catch (IOException e) {
+ result = false;
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ @Override
+ public void close() {
+ myDevice.close();
+ }
+
+ @Override
+ @Synchronized("dataLock")
+ public byte[] getLatestData() {
+ return currentData.clone();
+ }
+
+ @Override
+ public short getUsage() {
+ return myDeviceInfo.getUsagePage();
+ }
+
+ @Override
+ public String getPath() {
+ return myDeviceInfo.getPath();
+ }
+}
diff --git a/src/net/ash/HIDToVPADNetworkClient/hid/purejavahid/PureJavaHidManagerBackend.java b/src/net/ash/HIDToVPADNetworkClient/hid/purejavahid/PureJavaHidManagerBackend.java
new file mode 100644
index 0000000..32e4989
--- /dev/null
+++ b/src/net/ash/HIDToVPADNetworkClient/hid/purejavahid/PureJavaHidManagerBackend.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *******************************************************************************/
+package net.ash.HIDToVPADNetworkClient.hid.purejavahid;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.ash.HIDToVPADNetworkClient.hid.HidDevice;
+import net.ash.HIDToVPADNetworkClient.hid.HidManagerBackend;
+import purejavahidapi.PureJavaHidApi;
+
+public class PureJavaHidManagerBackend extends HidManagerBackend {
+
+ @Override
+ public List enumerateDevices() {
+ List result = new ArrayList();
+ for (purejavahidapi.HidDeviceInfo info : PureJavaHidApi.enumerateDevices()) {
+ result.add(new PureJavaHidDevice(info));
+ }
+ return result;
+ }
+
+ @Override
+ public HidDevice getDeviceByPath(String path) throws IOException {
+ List devList = PureJavaHidApi.enumerateDevices();
+ HidDevice result = null;
+ for (purejavahidapi.HidDeviceInfo info : devList) {
+ String real_path = info.getPath();
+ if (real_path.equals(path)) {
+ return new PureJavaHidDevice(info);
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/src/net/ash/HIDToVPADNetworkClient/manager/ActiveControllerManager.java b/src/net/ash/HIDToVPADNetworkClient/manager/ActiveControllerManager.java
index 85acf31..e57cd4a 100644
--- a/src/net/ash/HIDToVPADNetworkClient/manager/ActiveControllerManager.java
+++ b/src/net/ash/HIDToVPADNetworkClient/manager/ActiveControllerManager.java
@@ -61,7 +61,7 @@ public final class ActiveControllerManager implements Runnable {
Utilities.sleep(Settings.DETECT_CONTROLLER_INTERVAL);
}
}
- }).start();
+ }, "DetectControllerThread").start();
new Thread(new Runnable() {
@Override
@@ -71,7 +71,7 @@ public final class ActiveControllerManager implements Runnable {
Utilities.sleep(Settings.HANDLE_INPUTS_INTERVAL);
}
}
- }).start();
+ }, "HandleControllerInputThread").start();
}
public void updateControllerStates() {
diff --git a/src/net/ash/HIDToVPADNetworkClient/manager/ControllerManager.java b/src/net/ash/HIDToVPADNetworkClient/manager/ControllerManager.java
index eb28953..246f963 100644
--- a/src/net/ash/HIDToVPADNetworkClient/manager/ControllerManager.java
+++ b/src/net/ash/HIDToVPADNetworkClient/manager/ControllerManager.java
@@ -38,22 +38,21 @@ import lombok.Synchronized;
import lombok.extern.java.Log;
import net.ash.HIDToVPADNetworkClient.controller.Controller;
import net.ash.HIDToVPADNetworkClient.controller.Controller.ControllerType;
+import net.ash.HIDToVPADNetworkClient.controller.HidController;
import net.ash.HIDToVPADNetworkClient.controller.LinuxDevInputController;
-import net.ash.HIDToVPADNetworkClient.controller.PureJavaHidController;
import net.ash.HIDToVPADNetworkClient.controller.XInput13Controller;
import net.ash.HIDToVPADNetworkClient.controller.XInput14Controller;
import net.ash.HIDToVPADNetworkClient.controller.XInputController;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
+import net.ash.HIDToVPADNetworkClient.hid.HidDevice;
+import net.ash.HIDToVPADNetworkClient.hid.HidManager;
import net.ash.HIDToVPADNetworkClient.util.MessageBox;
import net.ash.HIDToVPADNetworkClient.util.MessageBoxManager;
-import net.ash.HIDToVPADNetworkClient.util.PureJavaHidApiManager;
import net.ash.HIDToVPADNetworkClient.util.Settings;
-import purejavahidapi.HidDeviceInfo;
@Log
public final class ControllerManager {
private static final Map attachedControllers = new HashMap();
- private static final Map connectedDevicesInfo = new HashMap();
private static boolean threwUnsatisfiedLinkError = false;
@@ -71,7 +70,7 @@ public final class ControllerManager {
if (Settings.isLinux()) {
connectedDevices.putAll(detectLinuxControllers());
} else if (Settings.isWindows()) {
- connectedDevices.putAll(detectWindowsControllers());
+ connectedDevices.putAll(detectXInputControllers());
}
connectedDevices.putAll(detectHIDDevices());
@@ -80,7 +79,6 @@ public final class ControllerManager {
List toRemove = new ArrayList();
synchronized (attachedControllers) {
for (String s : attachedControllers.keySet()) {
- System.out.println(s);
if (!connectedDevices.containsKey(s)) {
toRemove.add(s);
}
@@ -91,6 +89,7 @@ public final class ControllerManager {
synchronized (attachedControllers) {
attachedControllers.get(remove).destroyAll();
attachedControllers.remove(remove);
+ log.info("Device removed: " + toRemove);
}
}
@@ -104,11 +103,11 @@ public final class ControllerManager {
if (!contains) {
Controller c = null;
switch (entry.getValue()) {
- case PureJAVAHid:
+ case HIDController:
try {
- c = PureJavaHidController.getInstance(deviceIdentifier);
+ c = HidController.getInstance(deviceIdentifier);
} catch (ControllerInitializationFailedException e) {
- // e.printStackTrace();
+ log.info(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
@@ -117,14 +116,14 @@ public final class ControllerManager {
try {
c = new LinuxDevInputController(deviceIdentifier);
} catch (ControllerInitializationFailedException e) {
- // e.printStackTrace();
+ log.info(e.getMessage());
}
break;
case XINPUT14:
try {
c = new XInput14Controller(deviceIdentifier);
} catch (ControllerInitializationFailedException e) {
- // e.printStackTrace();
+ log.info(e.getMessage());
}
break;
case XINPUT13:
@@ -141,10 +140,11 @@ public final class ControllerManager {
if (Settings.AUTO_ACTIVATE_CONTROLLER) {
c.setActive(true);
}
- new Thread(c).start();
+ new Thread(c, "Controller Thread " + deviceIdentifier).start();
synchronized (attachedControllers) {
attachedControllers.put(deviceIdentifier, c);
}
+ log.info("Device added: " + deviceIdentifier);
}
}
}
@@ -157,19 +157,15 @@ public final class ControllerManager {
private static Map detectHIDDevices() {
Map connectedDevices = new HashMap();
- System.out.println("detectHIDDevices");
- for (HidDeviceInfo info : PureJavaHidApiManager.getAttachedController()) {
+ for (HidDevice info : HidManager.getAttachedController()) {
String path = info.getPath();
- connectedDevices.put(path, ControllerType.PureJAVAHid);
- synchronized (connectedDevicesInfo) {
- connectedDevicesInfo.put(path, info);
- }
+ connectedDevices.put(path, ControllerType.HIDController);
}
return connectedDevices;
}
- private static Map detectWindowsControllers() {
+ private static Map detectXInputControllers() {
Map result = new HashMap();
ControllerType type = ControllerType.XINPUT13;
@@ -245,10 +241,4 @@ public final class ControllerManager {
c.setActive(false);
}
}
-
- @Synchronized("connectedDevicesInfo")
- public static HidDeviceInfo getDeviceInfoByPath(String path) {
- return connectedDevicesInfo.get(path);
- }
-
}
diff --git a/src/net/ash/HIDToVPADNetworkClient/network/NetworkManager.java b/src/net/ash/HIDToVPADNetworkClient/network/NetworkManager.java
index 595d674..a26c0c8 100644
--- a/src/net/ash/HIDToVPADNetworkClient/network/NetworkManager.java
+++ b/src/net/ash/HIDToVPADNetworkClient/network/NetworkManager.java
@@ -157,17 +157,17 @@ public final class NetworkManager implements Runnable {
}
}
- // TODO: PONG from WiiU? Hey Quark ;)
private void sendPing(PingCommand command) {
if (sendTCP(Protocol.getRawPingDataToSend(command))) {
- log.info("PING");
byte pong;
try {
pong = tcpClient.recvByte();
- if (pong != Protocol.TCP_CMD_PONG) {
+ if (pong == Protocol.TCP_CMD_PONG) {
+ log.info("Ping...Pong!");
+ } else {
+ log.info("Got no valid response to a Ping. Disconnecting.");
disconnect();
}
- log.info("got PONG!");
} catch (IOException e) {
log.info("Failed to get PONG. Disconnecting.");
tcpClient.checkShouldRetry();
diff --git a/src/net/ash/HIDToVPADNetworkClient/util/MessageBoxManager.java b/src/net/ash/HIDToVPADNetworkClient/util/MessageBoxManager.java
index b430582..8fa7026 100644
--- a/src/net/ash/HIDToVPADNetworkClient/util/MessageBoxManager.java
+++ b/src/net/ash/HIDToVPADNetworkClient/util/MessageBoxManager.java
@@ -73,7 +73,7 @@ public final class MessageBoxManager implements Runnable {
public static void addMessageBoxListener(MessageBoxListener msglistener) {
if (!threadStarted) {
- new Thread(instance).start();
+ new Thread(instance, "MessageBoxManager").start();
threadStarted = true;
}
newList.add(msglistener);
diff --git a/src/net/ash/HIDToVPADNetworkClient/util/Settings.java b/src/net/ash/HIDToVPADNetworkClient/util/Settings.java
index f1a0b58..fec12c0 100644
--- a/src/net/ash/HIDToVPADNetworkClient/util/Settings.java
+++ b/src/net/ash/HIDToVPADNetworkClient/util/Settings.java
@@ -44,7 +44,9 @@ public final class Settings {
public static final int PING_INTERVAL = 1000;
public static final int PROCESS_CMD_INTERVAL = 10;
- public static boolean SCAN_AUTOMATICALLY_FOR_CONTROLLERS = !isMacOSX(); // It doesn't work on OSX
+ public static final int DETECT_CONTROLLER_ACTIVE_INTERVAL = 100;
+
+ public static boolean SCAN_AUTOMATICALLY_FOR_CONTROLLERS = true;
public static boolean DEBUG_UDP_OUTPUT = false;
public static boolean SEND_DATA_ONLY_ON_CHANGE = false;