mirror of
https://github.com/Maschell/HIDtoVPADNetworkClient.git
synced 2024-11-22 05:59:16 +01:00
Changed HID backend to purejavahid
moved some magic values to the settings class
This commit is contained in:
parent
a479bb14ee
commit
e0a392442d
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "purejavahidapi"]
|
||||
path = purejavahidapi
|
||||
url = https://github.com/nyholku/purejavahidapi
|
12
pom.xml
12
pom.xml
@ -21,13 +21,9 @@
|
||||
<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/ -->
|
||||
</repository>
|
||||
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.hid4java</groupId>
|
||||
<artifactId>hid4java</artifactId>
|
||||
<version>0.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
@ -39,5 +35,11 @@
|
||||
<artifactId>jxinput</artifactId>
|
||||
<version>1eb4087</version> <!-- JXInput 0.7 -->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>purejavahidapi</groupId>
|
||||
<artifactId>purejavahidapi</artifactId>
|
||||
<version>0.0.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -23,19 +23,17 @@ package net.ash.HIDToVPADNetworkClient;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.hid4java.HidManager;
|
||||
|
||||
import net.ash.HIDToVPADNetworkClient.gui.GuiMain;
|
||||
import net.ash.HIDToVPADNetworkClient.manager.ActiveControllerManager;
|
||||
import net.ash.HIDToVPADNetworkClient.network.NetworkManager;
|
||||
|
||||
/* Ash's todo list
|
||||
* TODO finish Hid4JavaController
|
||||
* TODO finish HidController
|
||||
* TODO locale
|
||||
*/
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello World!");
|
||||
try {
|
||||
new Thread(ActiveControllerManager.getInstance()).start();
|
||||
@ -43,15 +41,14 @@ public class Main {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fatal();
|
||||
}
|
||||
|
||||
}
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
GuiMain.createGUI();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static void fatal() {
|
||||
System.err.println("HID To VPAD Network Client encountered an irrecoverable error.");
|
||||
System.err.println("Exiting...");
|
||||
@ -59,7 +56,6 @@ public class Main {
|
||||
}
|
||||
|
||||
public static void initiateShutdown() {
|
||||
HidManager.getHidServices().shutdown();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import lombok.Getter;
|
||||
import lombok.Synchronized;
|
||||
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
|
||||
import net.ash.HIDToVPADNetworkClient.manager.ControllerManager;
|
||||
import net.ash.HIDToVPADNetworkClient.util.Settings;
|
||||
import net.ash.HIDToVPADNetworkClient.util.Utilities;
|
||||
|
||||
/**
|
||||
@ -43,6 +44,9 @@ public abstract class Controller implements Runnable{
|
||||
boolean shutdownDone = false;
|
||||
private Object dataLock = new Object();
|
||||
private Object shutdownLock = new Object();
|
||||
|
||||
private Object rumbleLock = new Object();
|
||||
private boolean rumble = false;
|
||||
|
||||
public Controller(ControllerType type, String identifier) throws ControllerInitializationFailedException{
|
||||
this.type = type;
|
||||
@ -56,7 +60,7 @@ public abstract class Controller implements Runnable{
|
||||
public void run() {
|
||||
boolean shutdownState = shutdown;
|
||||
while(!shutdownState){
|
||||
Utilities.sleep(1000);
|
||||
Utilities.sleep(Settings.DETECT_CONTROLLER_INTERVAL);
|
||||
while(isActive()) {
|
||||
byte[] newData = pollLatestData();
|
||||
if(newData != null){
|
||||
@ -74,7 +78,7 @@ public abstract class Controller implements Runnable{
|
||||
}
|
||||
|
||||
protected void doSleepAfterPollingData() {
|
||||
Utilities.sleep(10);
|
||||
Utilities.sleep(Settings.SLEEP_AFER_POLLING);
|
||||
}
|
||||
|
||||
@Synchronized("dataLock")
|
||||
@ -189,7 +193,24 @@ public abstract class Controller implements Runnable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public enum ControllerType {
|
||||
HID4JAVA, LINUX, XINPUT13,XINPUT14
|
||||
@Synchronized("rumbleLock")
|
||||
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();
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfoText() {
|
||||
return "Linux controller on " + getIdentifier();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -27,4 +27,9 @@ public class XInput13Controller extends XInputController {
|
||||
public XInput13Controller(String identifier) throws ControllerInitializationFailedException {
|
||||
super(ControllerType.XINPUT13, identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfoText(){
|
||||
return "XInput 1.3 on " + getIdentifier();
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,9 @@ public class XInput14Controller extends XInputController {
|
||||
public XInput14Controller(String identifier) throws ControllerInitializationFailedException {
|
||||
super(ControllerType.XINPUT14, identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfoText(){
|
||||
return "XInput 1.4 on " + getIdentifier();
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public class XInputController extends Controller {
|
||||
try {
|
||||
device = XInputDevice.getDeviceFor(pad);
|
||||
} catch (XInputNotLoadedException e) {
|
||||
//Log?
|
||||
//TODO: Log?
|
||||
}
|
||||
if(device == null) return false;
|
||||
setDevice(device);
|
||||
@ -103,8 +103,8 @@ public class XInputController extends Controller {
|
||||
axesDataShoulderButtons |= axes.rtRaw << 0;
|
||||
|
||||
buttonState |= axesDataShoulderButtons << 16;
|
||||
data.putInt(axesData).putInt(buttonState);
|
||||
|
||||
data.putInt(axesData).putInt(buttonState);
|
||||
|
||||
return(data.array());
|
||||
}
|
||||
return null;
|
||||
@ -125,4 +125,9 @@ public class XInputController extends Controller {
|
||||
public short getPID() {
|
||||
return 0x1337;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfoText(){
|
||||
return "XInput on " + getIdentifier();
|
||||
}
|
||||
}
|
||||
|
@ -65,18 +65,7 @@ public class GuiControllerListItem extends JPanel implements ActionListener {
|
||||
}
|
||||
|
||||
private String getFlavorText() {
|
||||
switch (controller.getType()) { //TODO: String.format with value from Settings.
|
||||
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();
|
||||
}
|
||||
return controller.getInfoText();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -27,12 +27,14 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import lombok.extern.java.Log;
|
||||
import net.ash.HIDToVPADNetworkClient.controller.Controller;
|
||||
import net.ash.HIDToVPADNetworkClient.network.NetworkHIDDevice;
|
||||
import net.ash.HIDToVPADNetworkClient.network.NetworkManager;
|
||||
import net.ash.HIDToVPADNetworkClient.util.Settings;
|
||||
import net.ash.HIDToVPADNetworkClient.util.Utilities;
|
||||
|
||||
@Log
|
||||
public class ActiveControllerManager implements Runnable{
|
||||
private static ActiveControllerManager instance = new ActiveControllerManager();
|
||||
|
||||
@ -66,8 +68,7 @@ public class ActiveControllerManager implements Runnable{
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Map<Controller,NetworkHIDDevice> activeControllers = new HashMap<>();
|
||||
public void updateControllerStates() {
|
||||
List<Controller> currentControllers = ControllerManager.getActiveControllers();
|
||||
@ -79,7 +80,7 @@ public class ActiveControllerManager implements Runnable{
|
||||
|
||||
for(Controller c: currentControllers){
|
||||
if(!activeControllers.containsKey(c)){
|
||||
System.out.println("Added " + c); //TODO: real logging
|
||||
log.info("Added " + c);
|
||||
toAdd.add(c);
|
||||
}
|
||||
}
|
||||
@ -87,7 +88,7 @@ public class ActiveControllerManager implements Runnable{
|
||||
//removing all old
|
||||
for(Controller c : activeControllers.keySet()){
|
||||
if(!currentControllers.contains(c)){
|
||||
System.out.println("Removed " + c); //TODO: real logging
|
||||
log.info("Removed " + 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;
|
||||
}
|
||||
}
|
||||
|
@ -23,15 +23,13 @@ package net.ash.HIDToVPADNetworkClient.manager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.hid4java.HidDevice;
|
||||
import org.hid4java.HidManager;
|
||||
|
||||
import com.ivan.xinput.XInputDevice;
|
||||
import com.ivan.xinput.XInputDevice14;
|
||||
import com.ivan.xinput.exceptions.XInputNotLoadedException;
|
||||
@ -39,12 +37,14 @@ import com.ivan.xinput.exceptions.XInputNotLoadedException;
|
||||
import lombok.Synchronized;
|
||||
import net.ash.HIDToVPADNetworkClient.controller.Controller;
|
||||
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.XInput13Controller;
|
||||
import net.ash.HIDToVPADNetworkClient.controller.XInput14Controller;
|
||||
import net.ash.HIDToVPADNetworkClient.controller.XInputController;
|
||||
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
|
||||
import purejavahidapi.HidDeviceInfo;
|
||||
import purejavahidapi.PureJavaHidApi;
|
||||
|
||||
public class ControllerManager{
|
||||
private static Map<String,Controller> attachedControllers = new HashMap<>();
|
||||
@ -64,12 +64,8 @@ public class ControllerManager{
|
||||
} else if (os.contains("Windows")) {
|
||||
connectedDevices.putAll(detectWindowsControllers());
|
||||
}
|
||||
|
||||
/*TODO: Enable HID4Java again. Currently it's disabled because
|
||||
* We can either use the WiiU directly OR have XInput anyway.
|
||||
* Adding an option menu for enabling it?
|
||||
*/
|
||||
//connectedDevices.putAll(detectHIDDevices());
|
||||
|
||||
connectedDevices.putAll(detectHIDDevices());
|
||||
|
||||
//Remove detached devices
|
||||
List<String> toRemove = new ArrayList<>();
|
||||
@ -89,11 +85,13 @@ public class ControllerManager{
|
||||
if(!attachedControllers.containsKey(deviceIdentifier)){
|
||||
Controller c = null;
|
||||
switch(entry.getValue()){
|
||||
case HID4JAVA:
|
||||
case PureJAVAHid:
|
||||
try {
|
||||
c= new Hid4JavaController(deviceIdentifier);
|
||||
c= PureJavaHidController.getInstance(deviceIdentifier);
|
||||
} catch (ControllerInitializationFailedException e) {
|
||||
//e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
case LINUX:
|
||||
@ -142,11 +140,13 @@ public class ControllerManager{
|
||||
|
||||
private static Map<String, ControllerType> detectHIDDevices() {
|
||||
Map<String,ControllerType> connectedDevices = new HashMap<>();
|
||||
for (HidDevice device : HidManager.getHidServices().getAttachedHidDevices()) {
|
||||
if(device.getUsage() == 0x05 || device.getUsage() == 0x04){
|
||||
connectedDevices.put(device.getPath(),ControllerType.HID4JAVA);
|
||||
|
||||
for (HidDeviceInfo info : PureJavaHidApi.enumerateDevices()) {
|
||||
if(info.getUsagePage() == 0x05 || info.getUsagePage() == 0x04 || (info.getVendorId() == 0x57e)){
|
||||
connectedDevices.put(info.getPath(),ControllerType.PureJAVAHid);
|
||||
}
|
||||
}
|
||||
|
||||
return connectedDevices;
|
||||
}
|
||||
|
||||
|
@ -96,4 +96,26 @@ public class NetworkHIDDevice {
|
||||
clearCommands();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -25,17 +25,15 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.omg.Messaging.SyncScopeHelper;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Synchronized;
|
||||
import lombok.extern.java.Log;
|
||||
import net.ash.HIDToVPADNetworkClient.manager.ControllerManager;
|
||||
import net.ash.HIDToVPADNetworkClient.network.commands.AttachCommand;
|
||||
import net.ash.HIDToVPADNetworkClient.network.commands.DetachCommand;
|
||||
import net.ash.HIDToVPADNetworkClient.network.commands.DeviceCommand;
|
||||
import net.ash.HIDToVPADNetworkClient.network.commands.PingCommand;
|
||||
import net.ash.HIDToVPADNetworkClient.network.commands.ReadCommand;
|
||||
import net.ash.HIDToVPADNetworkClient.util.Settings;
|
||||
import net.ash.HIDToVPADNetworkClient.util.Utilities;
|
||||
|
||||
@Log
|
||||
@ -83,8 +81,8 @@ public class NetworkManager implements Runnable{
|
||||
int i = 0;
|
||||
while(true){
|
||||
proccessCommands();
|
||||
Utilities.sleep(10);//TODO: move magic value to Settings
|
||||
if(i++ > 1000/10){//TODO: move magic value to Settings
|
||||
Utilities.sleep(Settings.PROCESS_CMD_INTERVAL);
|
||||
if(i++ > Settings.PING_INTERVAL/Settings.PROCESS_CMD_INTERVAL){
|
||||
ping();
|
||||
i = 0;
|
||||
}
|
||||
@ -154,7 +152,7 @@ public class NetworkManager implements Runnable{
|
||||
result = true;
|
||||
}
|
||||
}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
|
||||
|
@ -27,7 +27,6 @@ import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
|
@ -21,31 +21,30 @@
|
||||
*******************************************************************************/
|
||||
package net.ash.HIDToVPADNetworkClient.util;
|
||||
|
||||
import org.hid4java.HidDevice;
|
||||
import org.hid4java.HidManager;
|
||||
import org.hid4java.HidServices;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
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
|
||||
* @param path Path of the HIDDevice
|
||||
* @return It the device is found, it will be returned. Otherwise null is returned.
|
||||
* @throws IOException
|
||||
*/
|
||||
public static HidDevice getDeviceByPath(String path){
|
||||
HidDevice result = null;
|
||||
|
||||
HidServices services = HidManager.getHidServices();
|
||||
if(services == null) return result;
|
||||
|
||||
for (HidDevice device : services.getAttachedHidDevices()) {
|
||||
if (device.getPath().equals(path)) {
|
||||
result = device;
|
||||
break;
|
||||
public static HidDevice getDeviceByPath(String path) throws IOException{
|
||||
List<HidDeviceInfo> devList = PureJavaHidApi.enumerateDevices();
|
||||
for (HidDeviceInfo info : devList) {
|
||||
if(info.getPath().equals(path)){
|
||||
return PureJavaHidApi.openDevice(info);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
}
|
@ -25,6 +25,10 @@ public class Settings {
|
||||
public static final int DETECT_CONTROLLER_INTERVAL = 1000;
|
||||
public static final int HANDLE_INPUTS_INTERVAL = 15;
|
||||
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(){}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user