Changed HID backend to purejavahid

moved some magic values to the settings class
This commit is contained in:
Maschell 2017-03-16 19:33:50 +01:00
parent a479bb14ee
commit e0a392442d
19 changed files with 294 additions and 154 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "purejavahidapi"]
path = purejavahidapi
url = https://github.com/nyholku/purejavahidapi

12
pom.xml
View File

@ -21,13 +21,9 @@
<id>jitpack.io</id> <!-- JitPack allows github repo to be used as a maven repo --> <id>jitpack.io</id> <!-- JitPack allows github repo to be used as a maven repo -->
<url>https://jitpack.io</url> <!-- For documentation: http://jitpack.io/ --> <url>https://jitpack.io</url> <!-- For documentation: http://jitpack.io/ -->
</repository> </repository>
</repositories> </repositories>
<dependencies> <dependencies>
<dependency>
<groupId>org.hid4java</groupId>
<artifactId>hid4java</artifactId>
<version>0.4.0</version>
</dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
@ -39,5 +35,11 @@
<artifactId>jxinput</artifactId> <artifactId>jxinput</artifactId>
<version>1eb4087</version> <!-- JXInput 0.7 --> <version>1eb4087</version> <!-- JXInput 0.7 -->
</dependency> </dependency>
<dependency>
<groupId>purejavahidapi</groupId>
<artifactId>purejavahidapi</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -23,19 +23,17 @@ package net.ash.HIDToVPADNetworkClient;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import org.hid4java.HidManager;
import net.ash.HIDToVPADNetworkClient.gui.GuiMain; import net.ash.HIDToVPADNetworkClient.gui.GuiMain;
import net.ash.HIDToVPADNetworkClient.manager.ActiveControllerManager; import net.ash.HIDToVPADNetworkClient.manager.ActiveControllerManager;
import net.ash.HIDToVPADNetworkClient.network.NetworkManager; import net.ash.HIDToVPADNetworkClient.network.NetworkManager;
/* Ash's todo list /* Ash's todo list
* TODO finish Hid4JavaController * TODO finish HidController
* TODO locale * TODO locale
*/ */
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Hello World!"); System.out.println("Hello World!");
try { try {
new Thread(ActiveControllerManager.getInstance()).start(); new Thread(ActiveControllerManager.getInstance()).start();
@ -43,15 +41,14 @@ public class Main {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
fatal(); fatal();
} }
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { public void run() {
GuiMain.createGUI(); GuiMain.createGUI();
} }
}); });
} }
public static void fatal() { public static void fatal() {
System.err.println("HID To VPAD Network Client encountered an irrecoverable error."); System.err.println("HID To VPAD Network Client encountered an irrecoverable error.");
System.err.println("Exiting..."); System.err.println("Exiting...");
@ -59,7 +56,6 @@ public class Main {
} }
public static void initiateShutdown() { public static void initiateShutdown() {
HidManager.getHidServices().shutdown();
System.exit(0); System.exit(0);
} }
} }

View File

@ -25,6 +25,7 @@ import lombok.Getter;
import lombok.Synchronized; import lombok.Synchronized;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException; import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
import net.ash.HIDToVPADNetworkClient.manager.ControllerManager; import net.ash.HIDToVPADNetworkClient.manager.ControllerManager;
import net.ash.HIDToVPADNetworkClient.util.Settings;
import net.ash.HIDToVPADNetworkClient.util.Utilities; import net.ash.HIDToVPADNetworkClient.util.Utilities;
/** /**
@ -43,6 +44,9 @@ public abstract class Controller implements Runnable{
boolean shutdownDone = false; boolean shutdownDone = false;
private Object dataLock = new Object(); private Object dataLock = new Object();
private Object shutdownLock = new Object(); private Object shutdownLock = new Object();
private Object rumbleLock = new Object();
private boolean rumble = false;
public Controller(ControllerType type, String identifier) throws ControllerInitializationFailedException{ public Controller(ControllerType type, String identifier) throws ControllerInitializationFailedException{
this.type = type; this.type = type;
@ -56,7 +60,7 @@ public abstract class Controller implements Runnable{
public void run() { public void run() {
boolean shutdownState = shutdown; boolean shutdownState = shutdown;
while(!shutdownState){ while(!shutdownState){
Utilities.sleep(1000); Utilities.sleep(Settings.DETECT_CONTROLLER_INTERVAL);
while(isActive()) { while(isActive()) {
byte[] newData = pollLatestData(); byte[] newData = pollLatestData();
if(newData != null){ if(newData != null){
@ -74,7 +78,7 @@ public abstract class Controller implements Runnable{
} }
protected void doSleepAfterPollingData() { protected void doSleepAfterPollingData() {
Utilities.sleep(10); Utilities.sleep(Settings.SLEEP_AFER_POLLING);
} }
@Synchronized("dataLock") @Synchronized("dataLock")
@ -189,7 +193,24 @@ public abstract class Controller implements Runnable{
return true; return true;
} }
public enum ControllerType { @Synchronized("rumbleLock")
HID4JAVA, LINUX, XINPUT13,XINPUT14 public boolean isRumble() {
return rumble;
} }
@Synchronized("rumbleLock")
public void startRumble() {
this.rumble = true;
}
@Synchronized("rumbleLock")
public void stopRumble() {
this.rumble = false;
}
public enum ControllerType {
PureJAVAHid, LINUX, XINPUT13,XINPUT14
}
public abstract String getInfoText();
} }

View File

@ -1,80 +0,0 @@
/*******************************************************************************
* 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.controller;
import java.util.Arrays;
import org.hid4java.HidDevice;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
import net.ash.HIDToVPADNetworkClient.util.HID4JavaManager;
import net.ash.HIDToVPADNetworkClient.util.Utilities;
public class Hid4JavaController extends Controller {
public Hid4JavaController(String identifier) throws ControllerInitializationFailedException {
super(ControllerType.HID4JAVA, identifier);
}
private static final int PACKET_LENGTH = 128;
@Getter @Setter(AccessLevel.PRIVATE)
private HidDevice hidDevice;
@Override
public boolean initController(String identifier) {
HidDevice device = HID4JavaManager.getDeviceByPath(identifier);
//device.setNonBlocking(true); //TODO: What does this do? This is done no in a extra Thread so it shouldn't matter.
device.open();
Utilities.sleep(20); //What a bit until is opened.
if (device == null | !device.isOpen()) return false;
setHidDevice(device);
//System.out.println("ctrl: " + device.isOpen() + " " + device.getLastErrorMessage());
return true;
}
@Override
public byte[] pollLatestData() {
byte[] data = new byte[PACKET_LENGTH];
int length = getHidDevice().read(data);
if(length <= 0) return null;
//if(length > data.length) System.out.println("WTF?");
return Arrays.copyOf(data, length);
}
@Override
public void destroyDriver() {
getHidDevice().close();
}
@Override
public short getVID() {
return getHidDevice().getVendorId();
}
@Override
public short getPID() {
return getHidDevice().getProductId();
}
}

View File

@ -144,4 +144,9 @@ public class LinuxDevInputController extends Controller implements Runnable{
return "[" + super.toString() + ";VID," + Integer.toHexString((int)getVID() & 0xFFFF) + ";PID," + Integer.toHexString((int)getPID() & 0xFFFF) + ";run," + isActive() + ((controller == null) ? ";uninitialised]" : ";initialised]"); return "[" + super.toString() + ";VID," + Integer.toHexString((int)getVID() & 0xFFFF) + ";PID," + Integer.toHexString((int)getPID() & 0xFFFF) + ";run," + isActive() + ((controller == null) ? ";uninitialised]" : ";initialised]");
} }
@Override
public String getInfoText() {
return "Linux controller on " + getIdentifier();
}
} }

View File

@ -0,0 +1,122 @@
/*******************************************************************************
* 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.controller;
import java.io.IOException;
import java.util.Arrays;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.Synchronized;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
import net.ash.HIDToVPADNetworkClient.util.PureJavaHidApiManager;
import purejavahidapi.HidDevice;
import purejavahidapi.InputReportListener;
public class PureJavaHidController extends Controller implements InputReportListener {
public static Controller getInstance(String deviceIdentifier) throws IOException, ControllerInitializationFailedException {
HidDevice device = PureJavaHidApiManager.getDeviceByPath(deviceIdentifier);
//We use a special version to optimize the data for the switch pro controller
if(device.getHidDeviceInfo().getVendorId() == SwitchProController.SWITCH_PRO_CONTROLLER_VID &&
device.getHidDeviceInfo().getProductId() == SwitchProController.SWITCH_PRO_CONTROLLER_PID){
return new SwitchProController(deviceIdentifier);
}else{
return new PureJavaHidController(deviceIdentifier);
}
}
public PureJavaHidController(String identifier) throws ControllerInitializationFailedException {
super(ControllerType.PureJAVAHid, identifier);
}
private Object dataLock = new Object();
protected byte[] currentData = new byte[1];
protected int PACKET_LENGTH = 64;
@Getter @Setter(AccessLevel.PRIVATE)
private HidDevice hidDevice;
@Override
public boolean initController(String identifier) {
HidDevice device;
try {
device = PureJavaHidApiManager.getDeviceByPath(identifier);
device.setInputReportListener(this);
setHidDevice(device);
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
@Override
@Synchronized("dataLock")
public byte[] pollLatestData() {
return currentData.clone();
}
@Override
public void destroyDriver() {
getHidDevice().close();
}
@Override
public short getVID() {
return getHidDevice().getHidDeviceInfo().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);
}
}
@Override
public String getInfoText() {
//TODO:
if(getVID() == 0x57e){
if(getPID() == 0x2006){
return "Joy-Con (L) on " + getIdentifier();
}else if(getPID() == 0x2007){
return "Joy-Con (R) on " + getIdentifier();
}
}
return "USB HID on " + getIdentifier();
}
}

View File

@ -0,0 +1,30 @@
package net.ash.HIDToVPADNetworkClient.controller;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
public class SwitchProController extends PureJavaHidController {
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;
}
@Override
public byte[] pollLatestData() {
//remove unused data (because only changed data will be sent)
currentData[3] = 0;
currentData[5] = 0;
currentData[7] = 0;
currentData[9] = 0;
return currentData.clone();
}
@Override
public String getInfoText(){
return "Switch Pro Controller on " + getIdentifier();
}
}

View File

@ -27,4 +27,9 @@ public class XInput13Controller extends XInputController {
public XInput13Controller(String identifier) throws ControllerInitializationFailedException { public XInput13Controller(String identifier) throws ControllerInitializationFailedException {
super(ControllerType.XINPUT13, identifier); super(ControllerType.XINPUT13, identifier);
} }
@Override
public String getInfoText(){
return "XInput 1.3 on " + getIdentifier();
}
} }

View File

@ -27,4 +27,9 @@ public class XInput14Controller extends XInputController {
public XInput14Controller(String identifier) throws ControllerInitializationFailedException { public XInput14Controller(String identifier) throws ControllerInitializationFailedException {
super(ControllerType.XINPUT14, identifier); super(ControllerType.XINPUT14, identifier);
} }
@Override
public String getInfoText(){
return "XInput 1.4 on " + getIdentifier();
}
} }

View File

@ -52,7 +52,7 @@ public class XInputController extends Controller {
try { try {
device = XInputDevice.getDeviceFor(pad); device = XInputDevice.getDeviceFor(pad);
} catch (XInputNotLoadedException e) { } catch (XInputNotLoadedException e) {
//Log? //TODO: Log?
} }
if(device == null) return false; if(device == null) return false;
setDevice(device); setDevice(device);
@ -103,8 +103,8 @@ public class XInputController extends Controller {
axesDataShoulderButtons |= axes.rtRaw << 0; axesDataShoulderButtons |= axes.rtRaw << 0;
buttonState |= axesDataShoulderButtons << 16; buttonState |= axesDataShoulderButtons << 16;
data.putInt(axesData).putInt(buttonState); data.putInt(axesData).putInt(buttonState);
return(data.array()); return(data.array());
} }
return null; return null;
@ -125,4 +125,9 @@ public class XInputController extends Controller {
public short getPID() { public short getPID() {
return 0x1337; return 0x1337;
} }
@Override
public String getInfoText(){
return "XInput on " + getIdentifier();
}
} }

View File

@ -65,18 +65,7 @@ public class GuiControllerListItem extends JPanel implements ActionListener {
} }
private String getFlavorText() { private String getFlavorText() {
switch (controller.getType()) { //TODO: String.format with value from Settings. return controller.getInfoText();
case XINPUT13:
return "XInput 1.3 on " + controller.getIdentifier();
case XINPUT14:
return "XInput 1.4 on " + controller.getIdentifier();
case HID4JAVA:
return "USB HID on " + controller.getIdentifier();
case LINUX:
return "Linux controller on " + controller.getIdentifier();
default:
return controller.toString();
}
} }
@Override @Override

View File

@ -27,12 +27,14 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import lombok.extern.java.Log;
import net.ash.HIDToVPADNetworkClient.controller.Controller; import net.ash.HIDToVPADNetworkClient.controller.Controller;
import net.ash.HIDToVPADNetworkClient.network.NetworkHIDDevice; import net.ash.HIDToVPADNetworkClient.network.NetworkHIDDevice;
import net.ash.HIDToVPADNetworkClient.network.NetworkManager; import net.ash.HIDToVPADNetworkClient.network.NetworkManager;
import net.ash.HIDToVPADNetworkClient.util.Settings; import net.ash.HIDToVPADNetworkClient.util.Settings;
import net.ash.HIDToVPADNetworkClient.util.Utilities; import net.ash.HIDToVPADNetworkClient.util.Utilities;
@Log
public class ActiveControllerManager implements Runnable{ public class ActiveControllerManager implements Runnable{
private static ActiveControllerManager instance = new ActiveControllerManager(); private static ActiveControllerManager instance = new ActiveControllerManager();
@ -66,8 +68,7 @@ public class ActiveControllerManager implements Runnable{
} }
}).start(); }).start();
} }
private Map<Controller,NetworkHIDDevice> activeControllers = new HashMap<>(); private Map<Controller,NetworkHIDDevice> activeControllers = new HashMap<>();
public void updateControllerStates() { public void updateControllerStates() {
List<Controller> currentControllers = ControllerManager.getActiveControllers(); List<Controller> currentControllers = ControllerManager.getActiveControllers();
@ -79,7 +80,7 @@ public class ActiveControllerManager implements Runnable{
for(Controller c: currentControllers){ for(Controller c: currentControllers){
if(!activeControllers.containsKey(c)){ if(!activeControllers.containsKey(c)){
System.out.println("Added " + c); //TODO: real logging log.info("Added " + c);
toAdd.add(c); toAdd.add(c);
} }
} }
@ -87,7 +88,7 @@ public class ActiveControllerManager implements Runnable{
//removing all old //removing all old
for(Controller c : activeControllers.keySet()){ for(Controller c : activeControllers.keySet()){
if(!currentControllers.contains(c)){ if(!currentControllers.contains(c)){
System.out.println("Removed " + c); //TODO: real logging log.info("Removed " + c);
toRemove.add(c); toRemove.add(c);
} }
} }
@ -138,4 +139,18 @@ public class ActiveControllerManager implements Runnable{
} }
} }
} }
/**
*
* @param HIDhandle
* @return returns the controller for the given handle. returns null if the controller with the given handle is not found.
*/
public Controller getControllerByHIDHandle(int HIDhandle) {
for(Entry<Controller, NetworkHIDDevice> entry: activeControllers.entrySet()){
if(entry.getValue().getHidHandle() == HIDhandle){
return entry.getKey();
}
}
return null;
}
} }

View File

@ -23,15 +23,13 @@ package net.ash.HIDToVPADNetworkClient.manager;
import java.io.File; import java.io.File;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.hid4java.HidDevice;
import org.hid4java.HidManager;
import com.ivan.xinput.XInputDevice; import com.ivan.xinput.XInputDevice;
import com.ivan.xinput.XInputDevice14; import com.ivan.xinput.XInputDevice14;
import com.ivan.xinput.exceptions.XInputNotLoadedException; import com.ivan.xinput.exceptions.XInputNotLoadedException;
@ -39,12 +37,14 @@ import com.ivan.xinput.exceptions.XInputNotLoadedException;
import lombok.Synchronized; import lombok.Synchronized;
import net.ash.HIDToVPADNetworkClient.controller.Controller; import net.ash.HIDToVPADNetworkClient.controller.Controller;
import net.ash.HIDToVPADNetworkClient.controller.Controller.ControllerType; import net.ash.HIDToVPADNetworkClient.controller.Controller.ControllerType;
import net.ash.HIDToVPADNetworkClient.controller.Hid4JavaController; import net.ash.HIDToVPADNetworkClient.controller.PureJavaHidController;
import net.ash.HIDToVPADNetworkClient.controller.LinuxDevInputController; import net.ash.HIDToVPADNetworkClient.controller.LinuxDevInputController;
import net.ash.HIDToVPADNetworkClient.controller.XInput13Controller; import net.ash.HIDToVPADNetworkClient.controller.XInput13Controller;
import net.ash.HIDToVPADNetworkClient.controller.XInput14Controller; import net.ash.HIDToVPADNetworkClient.controller.XInput14Controller;
import net.ash.HIDToVPADNetworkClient.controller.XInputController; import net.ash.HIDToVPADNetworkClient.controller.XInputController;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException; import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
import purejavahidapi.HidDeviceInfo;
import purejavahidapi.PureJavaHidApi;
public class ControllerManager{ public class ControllerManager{
private static Map<String,Controller> attachedControllers = new HashMap<>(); private static Map<String,Controller> attachedControllers = new HashMap<>();
@ -64,12 +64,8 @@ public class ControllerManager{
} else if (os.contains("Windows")) { } else if (os.contains("Windows")) {
connectedDevices.putAll(detectWindowsControllers()); connectedDevices.putAll(detectWindowsControllers());
} }
/*TODO: Enable HID4Java again. Currently it's disabled because connectedDevices.putAll(detectHIDDevices());
* We can either use the WiiU directly OR have XInput anyway.
* Adding an option menu for enabling it?
*/
//connectedDevices.putAll(detectHIDDevices());
//Remove detached devices //Remove detached devices
List<String> toRemove = new ArrayList<>(); List<String> toRemove = new ArrayList<>();
@ -89,11 +85,13 @@ public class ControllerManager{
if(!attachedControllers.containsKey(deviceIdentifier)){ if(!attachedControllers.containsKey(deviceIdentifier)){
Controller c = null; Controller c = null;
switch(entry.getValue()){ switch(entry.getValue()){
case HID4JAVA: case PureJAVAHid:
try { try {
c= new Hid4JavaController(deviceIdentifier); c= PureJavaHidController.getInstance(deviceIdentifier);
} catch (ControllerInitializationFailedException e) { } catch (ControllerInitializationFailedException e) {
//e.printStackTrace(); //e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} }
break; break;
case LINUX: case LINUX:
@ -142,11 +140,13 @@ public class ControllerManager{
private static Map<String, ControllerType> detectHIDDevices() { private static Map<String, ControllerType> detectHIDDevices() {
Map<String,ControllerType> connectedDevices = new HashMap<>(); Map<String,ControllerType> connectedDevices = new HashMap<>();
for (HidDevice device : HidManager.getHidServices().getAttachedHidDevices()) {
if(device.getUsage() == 0x05 || device.getUsage() == 0x04){ for (HidDeviceInfo info : PureJavaHidApi.enumerateDevices()) {
connectedDevices.put(device.getPath(),ControllerType.HID4JAVA); if(info.getUsagePage() == 0x05 || info.getUsagePage() == 0x04 || (info.getVendorId() == 0x57e)){
connectedDevices.put(info.getPath(),ControllerType.PureJAVAHid);
} }
} }
return connectedDevices; return connectedDevices;
} }

View File

@ -96,4 +96,26 @@ public class NetworkHIDDevice {
clearCommands(); clearCommands();
return commands; return commands;
} }
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + hidHandle;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NetworkHIDDevice other = (NetworkHIDDevice) obj;
if (hidHandle != other.hidHandle)
return false;
return true;
}
} }

View File

@ -25,17 +25,15 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.omg.Messaging.SyncScopeHelper;
import lombok.Getter; import lombok.Getter;
import lombok.Synchronized; import lombok.Synchronized;
import lombok.extern.java.Log; import lombok.extern.java.Log;
import net.ash.HIDToVPADNetworkClient.manager.ControllerManager;
import net.ash.HIDToVPADNetworkClient.network.commands.AttachCommand; import net.ash.HIDToVPADNetworkClient.network.commands.AttachCommand;
import net.ash.HIDToVPADNetworkClient.network.commands.DetachCommand; import net.ash.HIDToVPADNetworkClient.network.commands.DetachCommand;
import net.ash.HIDToVPADNetworkClient.network.commands.DeviceCommand; import net.ash.HIDToVPADNetworkClient.network.commands.DeviceCommand;
import net.ash.HIDToVPADNetworkClient.network.commands.PingCommand; import net.ash.HIDToVPADNetworkClient.network.commands.PingCommand;
import net.ash.HIDToVPADNetworkClient.network.commands.ReadCommand; import net.ash.HIDToVPADNetworkClient.network.commands.ReadCommand;
import net.ash.HIDToVPADNetworkClient.util.Settings;
import net.ash.HIDToVPADNetworkClient.util.Utilities; import net.ash.HIDToVPADNetworkClient.util.Utilities;
@Log @Log
@ -83,8 +81,8 @@ public class NetworkManager implements Runnable{
int i = 0; int i = 0;
while(true){ while(true){
proccessCommands(); proccessCommands();
Utilities.sleep(10);//TODO: move magic value to Settings Utilities.sleep(Settings.PROCESS_CMD_INTERVAL);
if(i++ > 1000/10){//TODO: move magic value to Settings if(i++ > Settings.PING_INTERVAL/Settings.PROCESS_CMD_INTERVAL){
ping(); ping();
i = 0; i = 0;
} }
@ -154,7 +152,7 @@ public class NetworkManager implements Runnable{
result = true; result = true;
} }
}else{ }else{
Utilities.sleep(500); //TODO: move magic value to Settings Utilities.sleep(Settings.SENDING_CMD_SLEEP_IF_NOT_CONNECTED); //TODO: move magic value to Settings
} }
//Add the command again on errors //Add the command again on errors

View File

@ -27,7 +27,6 @@ import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.concurrent.SynchronousQueue;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;

View File

@ -21,31 +21,30 @@
*******************************************************************************/ *******************************************************************************/
package net.ash.HIDToVPADNetworkClient.util; package net.ash.HIDToVPADNetworkClient.util;
import org.hid4java.HidDevice; import java.io.IOException;
import org.hid4java.HidManager; import java.util.List;
import org.hid4java.HidServices;
public class HID4JavaManager { import purejavahidapi.HidDevice;
import purejavahidapi.HidDeviceInfo;
import purejavahidapi.PureJavaHidApi;
public class PureJavaHidApiManager {
private HID4JavaManager(){} private PureJavaHidApiManager(){}
/** /**
* Searches the corresponding HIDDevice for the given path * Searches the corresponding HIDDevice for the given path
* @param path Path of the HIDDevice * @param path Path of the HIDDevice
* @return It the device is found, it will be returned. Otherwise null is returned. * @return It the device is found, it will be returned. Otherwise null is returned.
* @throws IOException
*/ */
public static HidDevice getDeviceByPath(String path){ public static HidDevice getDeviceByPath(String path) throws IOException{
HidDevice result = null; List<HidDeviceInfo> devList = PureJavaHidApi.enumerateDevices();
for (HidDeviceInfo info : devList) {
HidServices services = HidManager.getHidServices(); if(info.getPath().equals(path)){
if(services == null) return result; return PureJavaHidApi.openDevice(info);
for (HidDevice device : services.getAttachedHidDevices()) {
if (device.getPath().equals(path)) {
result = device;
break;
} }
} }
return result; return null;
} }
} }

View File

@ -25,6 +25,10 @@ public class Settings {
public static final int DETECT_CONTROLLER_INTERVAL = 1000; public static final int DETECT_CONTROLLER_INTERVAL = 1000;
public static final int HANDLE_INPUTS_INTERVAL = 15; public static final int HANDLE_INPUTS_INTERVAL = 15;
public static final int MAXIMUM_TRIES_FOR_RECONNECTING = 10; public static final int MAXIMUM_TRIES_FOR_RECONNECTING = 10;
public static final int SLEEP_AFER_POLLING = 10;
public static final int SENDING_CMD_SLEEP_IF_NOT_CONNECTED = 500;
public static final int PING_INTERVAL = 1000;
public static final int PROCESS_CMD_INTERVAL = 10;
private Settings(){} private Settings(){}