diff --git a/pom.xml b/pom.xml
index 2d630d7..c8fb408 100644
--- a/pom.xml
+++ b/pom.xml
@@ -140,7 +140,7 @@
com.github.QuarkTheAwesome
purejavahidapi
- 3591b7e
+ f877704
org.hid4java
diff --git a/src/net/ash/HIDToVPADNetworkClient/controller/Controller.java b/src/net/ash/HIDToVPADNetworkClient/controller/Controller.java
index af5d1e5..e1dfb6f 100644
--- a/src/net/ash/HIDToVPADNetworkClient/controller/Controller.java
+++ b/src/net/ash/HIDToVPADNetworkClient/controller/Controller.java
@@ -170,7 +170,7 @@ public abstract class Controller implements Runnable {
@Override
public String toString() {
- return getType() + " " + getIdentifier();
+ return getType() + " " + getIdentifier().trim();
}
@Override
diff --git a/src/net/ash/HIDToVPADNetworkClient/controller/HidController.java b/src/net/ash/HIDToVPADNetworkClient/controller/HidController.java
index c753d18..36912fb 100644
--- a/src/net/ash/HIDToVPADNetworkClient/controller/HidController.java
+++ b/src/net/ash/HIDToVPADNetworkClient/controller/HidController.java
@@ -119,6 +119,7 @@ public class HidController extends Controller {
}
}
- return "USB HID on " + getIdentifier();
+ String name = getHidDevice().getProductString();
+ return ((name != null) ? name : "USB HID") + " on " + getIdentifier();
}
}
\ No newline at end of file
diff --git a/src/net/ash/HIDToVPADNetworkClient/gui/GuiInputControls.java b/src/net/ash/HIDToVPADNetworkClient/gui/GuiInputControls.java
index 570d2b5..e3f654e 100644
--- a/src/net/ash/HIDToVPADNetworkClient/gui/GuiInputControls.java
+++ b/src/net/ash/HIDToVPADNetworkClient/gui/GuiInputControls.java
@@ -30,7 +30,6 @@ import java.awt.event.ActionListener;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
-import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
@@ -60,19 +59,6 @@ public final class GuiInputControls extends JPanel {
final JButton connectButton = new JButton(CONNECT);
connectButton.setAlignmentX(Component.CENTER_ALIGNMENT);
- final JCheckBox cbautoScanForController = new JCheckBox();
- cbautoScanForController.setSelected(Settings.SCAN_AUTOMATICALLY_FOR_CONTROLLERS);
-
- cbautoScanForController.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- boolean selected = ((JCheckBox) e.getSource()).isSelected();
- Settings.SCAN_AUTOMATICALLY_FOR_CONTROLLERS = selected;
- cbautoScanForController.setSelected(selected);
- }
- });
-
final JButton scanButton = new JButton("Scan for Controllers");
scanButton.setAlignmentX(Component.CENTER_ALIGNMENT);
scanButton.addActionListener(new ActionListener() {
@@ -86,11 +72,19 @@ public final class GuiInputControls extends JPanel {
}
});
- JPanel scanWrap = new JPanel();
- scanWrap.setLayout(new BoxLayout(scanWrap, BoxLayout.X_AXIS));
- JLabel label = new JLabel("Auto Scan for Controllers: ");
- scanWrap.add(label);
- scanWrap.add(cbautoScanForController);
+ final JButton optionsButton = new JButton("Options");
+ optionsButton.setAlignmentX(Component.CENTER_ALIGNMENT);
+ optionsButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ GuiOptionsWindow.showWindow(GuiMain.getInstance());
+ }
+ });
+ }
+ });
ipTextBox = new JTextField();
ipTextBox.setColumns(15);
@@ -100,23 +94,6 @@ public final class GuiInputControls extends JPanel {
ipTextBoxWrap.add(ipTextBox);
ipTextBoxWrap.setMaximumSize(new Dimension(1000, 20));
- final JCheckBox cbautoActivateController = new JCheckBox();
- cbautoActivateController.setSelected(Settings.AUTO_ACTIVATE_CONTROLLER);
- cbautoActivateController.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- boolean selected = ((JCheckBox) e.getSource()).isSelected();
- Settings.AUTO_ACTIVATE_CONTROLLER = selected;
- cbautoActivateController.setSelected(selected);
- }
- });
-
- JPanel autoActivateWrap = new JPanel();
- autoActivateWrap.setLayout(new BoxLayout(autoActivateWrap, BoxLayout.X_AXIS));
- autoActivateWrap.add(new JLabel("Auto Activate Controller: "));
- autoActivateWrap.add(cbautoActivateController);
-
add(Box.createVerticalGlue());
add(ipTextBoxWrap);
@@ -126,9 +103,7 @@ public final class GuiInputControls extends JPanel {
add(Box.createRigidArea(new Dimension(1, 4)));
add(scanButton);
add(Box.createRigidArea(new Dimension(1, 4)));
- add(scanWrap);
- add(Box.createRigidArea(new Dimension(1, 4)));
- add(autoActivateWrap);
+ add(optionsButton);
add(Box.createVerticalGlue());
add(Box.createVerticalGlue());
diff --git a/src/net/ash/HIDToVPADNetworkClient/gui/GuiOptionsWindow.java b/src/net/ash/HIDToVPADNetworkClient/gui/GuiOptionsWindow.java
new file mode 100644
index 0000000..a3efaf6
--- /dev/null
+++ b/src/net/ash/HIDToVPADNetworkClient/gui/GuiOptionsWindow.java
@@ -0,0 +1,267 @@
+/*******************************************************************************
+ * 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.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.LayoutManager;
+import java.awt.Toolkit;
+import java.awt.datatransfer.StringSelection;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextArea;
+import javax.swing.border.EtchedBorder;
+
+import lombok.extern.java.Log;
+import net.ash.HIDToVPADNetworkClient.util.Settings;
+import net.ash.HIDToVPADNetworkClient.util.StatusReport;
+
+@Log
+public class GuiOptionsWindow extends JPanel {
+ private static final long serialVersionUID = 1L;
+ private static final GuiOptionsWindow instance = new GuiOptionsWindow();
+
+ private final List tabs = new ArrayList();
+
+ public static void showWindow() {
+ showWindow(null);
+ }
+
+ public static void showWindow(Component parent) {
+ instance.setOpaque(true);
+ for (Tab t : instance.tabs) {
+ t.updateTab();
+ }
+
+ JFrame window = new JFrame("Options");
+ window.setContentPane(instance);
+ window.pack();
+ window.setLocationRelativeTo(parent);
+ window.setVisible(true);
+ }
+
+ private GuiOptionsWindow() {
+ super(new GridLayout(1, 1));
+
+ log.info("Hello from the Options window!");
+
+ setPreferredSize(new Dimension(600, 200));
+
+ JTabbedPane tabPane = new JTabbedPane();
+ tabPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
+
+ Tab controllerTab = new ControllerTab();
+ tabs.add(controllerTab);
+ tabPane.addTab("Controllers", controllerTab);
+
+ Tab infoTab = new InfoTab();
+ tabs.add(infoTab);
+ tabPane.addTab("Info", infoTab);
+
+ add(tabPane);
+ }
+
+ private class ControllerTab extends Tab {
+ private static final long serialVersionUID = 1L;
+
+ private final ControllerFilteringList cFilterList;
+ private final JCheckBox cBoxScanForControllers;
+ private final JCheckBox cBoxAutoActivateControllers;
+
+ private ControllerTab() {
+ super(new GridLayout(1, 2));
+
+ cFilterList = new ControllerFilteringList();
+
+ for (Settings.ControllerFiltering.Type type : Settings.ControllerFiltering.Type.values()) {
+ if (!type.isSupportedOnPlatform()) continue;
+ ControllerFilteringListItem item = new ControllerFilteringListItem(type);
+ cFilterList.add(item);
+ }
+
+ add(cFilterList);
+
+ JPanel rightSideControls = new JPanel();
+ rightSideControls.setLayout(new BoxLayout(rightSideControls, BoxLayout.PAGE_AXIS));
+ rightSideControls.add(Box.createVerticalGlue());
+
+ cBoxScanForControllers = new JCheckBox("Automatically scan for controllers");
+ cBoxScanForControllers.setAlignmentX(Component.CENTER_ALIGNMENT);
+ cBoxScanForControllers.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Settings.SCAN_AUTOMATICALLY_FOR_CONTROLLERS = cBoxScanForControllers.isSelected();
+ }
+ });
+ rightSideControls.add(cBoxScanForControllers);
+
+ rightSideControls.add(Box.createVerticalStrut(2));
+
+ cBoxAutoActivateControllers = new JCheckBox("Automatically activate controllers");
+ cBoxAutoActivateControllers.setAlignmentX(Component.CENTER_ALIGNMENT);
+ cBoxAutoActivateControllers.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Settings.AUTO_ACTIVATE_CONTROLLER = cBoxAutoActivateControllers.isSelected();
+ }
+ });
+ rightSideControls.add(cBoxAutoActivateControllers);
+
+ rightSideControls.add(Box.createVerticalGlue());
+ add(rightSideControls);
+ }
+
+ @Override
+ public void updateTab() {
+ for (ControllerFilteringListItem c : cFilterList.items) {
+ c.updateItem();
+ }
+ cBoxScanForControllers.setSelected(Settings.SCAN_AUTOMATICALLY_FOR_CONTROLLERS);
+ cBoxAutoActivateControllers.setSelected(Settings.AUTO_ACTIVATE_CONTROLLER);
+ }
+
+ private class ControllerFilteringList extends JPanel {
+ private static final long serialVersionUID = 1L;
+
+ private List items = new ArrayList();
+ private JPanel innerPanel;
+
+ private ControllerFilteringList() {
+ super(new BorderLayout());
+ setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 0));
+
+ innerPanel = new JPanel();
+ innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.PAGE_AXIS));
+
+ JScrollPane innerPanelWrap = new JScrollPane(innerPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ innerPanelWrap.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
+ add(innerPanelWrap, BorderLayout.CENTER);
+
+ JLabel controllerFilterText = new JLabel("Controllers to show:");
+ controllerFilterText.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
+ add(controllerFilterText, BorderLayout.PAGE_START);
+ }
+
+ public Component add(ControllerFilteringListItem c) {
+ items.add(c);
+ return innerPanel.add(c);
+ }
+ }
+
+ private class ControllerFilteringListItem extends JPanel {
+ private static final long serialVersionUID = 1L;
+
+ private final JCheckBox cBox;
+ private final Settings.ControllerFiltering.Type type;
+
+ private ControllerFilteringListItem(Settings.ControllerFiltering.Type typeIn) {
+ super(new GridLayout(1, 1));
+ this.type = typeIn;
+
+ cBox = new JCheckBox(type.getName());
+ cBox.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+ cBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Settings.ControllerFiltering.setFilterState(type, cBox.isSelected());
+ }
+ });
+ add(cBox);
+ }
+
+ public void updateItem() {
+ cBox.setSelected(Settings.ControllerFiltering.getFilterState(type));
+ }
+
+ //I can't believe I didn't figure this out for GuiControllerList
+ @Override
+ public Dimension getMaximumSize() {
+ return new Dimension(Integer.MAX_VALUE, getPreferredSize().height);
+ }
+ }
+ }
+
+ private class InfoTab extends Tab {
+ private static final long serialVersionUID = 1L;
+
+ private final JTextArea infoText;
+ private final JScrollPane infoTextWrap;
+
+ private InfoTab() {
+ super();
+ setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
+ setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5));
+
+ infoText = new JTextArea();
+ infoText.setEditable(false);
+ infoTextWrap = new JScrollPane(infoText, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ infoTextWrap.setAlignmentX(Component.CENTER_ALIGNMENT);
+ add(infoTextWrap);
+
+ add(Box.createVerticalStrut(10));
+
+ JButton copyButton = new JButton("Copy");
+ copyButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ StringSelection data = new StringSelection(infoText.getText());
+ Toolkit.getDefaultToolkit().getSystemClipboard().setContents(data, data);
+ }
+ });
+ copyButton.setAlignmentX(Component.CENTER_ALIGNMENT);
+ add(copyButton);
+ }
+
+ @Override
+ public void updateTab() {
+ infoText.setCaretPosition(0);
+ infoText.setText(StatusReport.generateStatusReport());
+ infoText.setCaretPosition(0);
+ }
+ }
+
+ private abstract class Tab extends JPanel {
+ private static final long serialVersionUID = 1L;
+ public abstract void updateTab();
+ public Tab(LayoutManager l) {
+ super(l);
+ }
+ public Tab() {
+ super();
+ }
+ }
+}
diff --git a/src/net/ash/HIDToVPADNetworkClient/hid/HidDevice.java b/src/net/ash/HIDToVPADNetworkClient/hid/HidDevice.java
index 9d6fb38..2e33db2 100644
--- a/src/net/ash/HIDToVPADNetworkClient/hid/HidDevice.java
+++ b/src/net/ash/HIDToVPADNetworkClient/hid/HidDevice.java
@@ -57,11 +57,18 @@ public interface HidDevice {
byte[] getLatestData();
/**
- * Retuns the Usage of this HID-Device
+ * Retuns the Usage Page of this HID-Device
*
- * @return usage
+ * @return usage page
*/
- short getUsage();
+ short getUsagePage();
+
+ /**
+ * Retuns the Usage ID of this HID-Device
+ *
+ * @return usage id
+ */
+ short getUsageID();
/**
* Returns the path of this HidDevice
@@ -69,4 +76,11 @@ public interface HidDevice {
* @return path
*/
String getPath();
+
+ /**
+ * Returns the name of the HID device
+ *
+ * @return product string (name)
+ */
+ String getProductString();
}
diff --git a/src/net/ash/HIDToVPADNetworkClient/hid/HidManager.java b/src/net/ash/HIDToVPADNetworkClient/hid/HidManager.java
index 5ee6d49..f4bf2bb 100644
--- a/src/net/ash/HIDToVPADNetworkClient/hid/HidManager.java
+++ b/src/net/ash/HIDToVPADNetworkClient/hid/HidManager.java
@@ -37,28 +37,55 @@ public class HidManager {
public static HidDevice getDeviceByPath(String path) throws IOException {
return backend.getDeviceByPath(path);
}
-
+
public static List getAttachedControllers() {
List connectedGamepads = new ArrayList();
for (HidDevice info : backend.enumerateDevices()) {
if (isGamepad(info)) {
-
- // Skip Xbox controller under windows. We should use XInput instead.
- if (isXboxController(info) && Settings.isWindows()) {
- continue;
+ if (Settings.ControllerFiltering.getFilterState(Settings.ControllerFiltering.Type.HIDGAMEPAD)) {
+ // Skip Xbox controller under windows. We should use XInput instead.
+ if (isXboxController(info) && Settings.isWindows()) {
+ continue;
+ }
+ connectedGamepads.add(info);
}
+ } else if (isKeyboard(info)) {
+ if (Settings.ControllerFiltering.getFilterState(Settings.ControllerFiltering.Type.HIDKEYBOARD)) {
+ connectedGamepads.add(info);
+ }
+ } else if (isMouse(info)) {
+ if (Settings.ControllerFiltering.getFilterState(Settings.ControllerFiltering.Type.HIDMOUSE)) {
+ connectedGamepads.add(info);
+ }
+ } else if (Settings.ControllerFiltering.getFilterState(Settings.ControllerFiltering.Type.HIDOTHER)) {
connectedGamepads.add(info);
}
}
return connectedGamepads;
}
+
+ public static List getAllAttachedControllers() {
+ return backend.enumerateDevices();
+ }
public static boolean isGamepad(HidDevice info) {
if (info == null) return false;
- short usage = info.getUsage();
+ short usage = info.getUsageID();
return (usage == 0x05 || usage == 0x04 || isNintendoController(info) || isPlaystationController(info));
}
+
+ public static boolean isKeyboard(HidDevice info) {
+ if (info == null) return false;
+ short usage = info.getUsageID();
+ return (usage == 0x06);
+ }
+
+ public static boolean isMouse(HidDevice info) {
+ if (info == null) return false;
+ short usage = info.getUsageID();
+ return (usage == 0x02);
+ }
private static boolean isPlaystationController(HidDevice info) {
if (info == null) return false;
@@ -75,13 +102,17 @@ public class HidManager {
return (info.getVendorId() == (short) 0x045e) && ((info.getProductId() == (short) 0x02ff) || (info.getProductId() == (short) 0x02a1));
}
+ public static String getBackendType() {
+ return backend.getClass().getSimpleName();
+ }
+
static {
if (Settings.isMacOSX()) {
backend = new Hid4JavaHidManagerBackend();
} else if (Settings.isWindows()) {
backend = new PureJavaHidManagerBackend();
} else if (Settings.isLinux()) {
- backend = new Hid4JavaHidManagerBackend();
+ backend = new PureJavaHidManagerBackend();
} else {
backend = null;
}
diff --git a/src/net/ash/HIDToVPADNetworkClient/hid/hid4java/Hid4JavaHidDevice.java b/src/net/ash/HIDToVPADNetworkClient/hid/hid4java/Hid4JavaHidDevice.java
index ad6104f..362b3da 100644
--- a/src/net/ash/HIDToVPADNetworkClient/hid/hid4java/Hid4JavaHidDevice.java
+++ b/src/net/ash/HIDToVPADNetworkClient/hid/hid4java/Hid4JavaHidDevice.java
@@ -66,13 +66,23 @@ class Hid4JavaHidDevice implements HidDevice {
return myDevice.getPath();
}
+ @Override
+ public String getProductString() {
+ return myDevice.getProduct();
+ }
+
@Override
public String toString() {
- return "Hid4JavaHidDevice [vid= " + getVendorId() + ", pid= " + getProductId() + ", data=" + Arrays.toString(data) + "]";
+ return "Hid4JavaHidDevice [vid= " + getVendorId() + ", pid= " + getProductId() + ", usage= " + String.format("%04X:%04X", getUsagePage(), getUsageID()) + ", data=" + Arrays.toString(data) + "]";
}
@Override
- public short getUsage() {
+ public short getUsageID() {
return (short) myDevice.getUsage();
}
+
+ @Override
+ public short getUsagePage() {
+ return (short) myDevice.getUsagePage();
+ }
}
diff --git a/src/net/ash/HIDToVPADNetworkClient/hid/purejavahid/PureJavaHidDevice.java b/src/net/ash/HIDToVPADNetworkClient/hid/purejavahid/PureJavaHidDevice.java
index d4b822d..fe3435a 100644
--- a/src/net/ash/HIDToVPADNetworkClient/hid/purejavahid/PureJavaHidDevice.java
+++ b/src/net/ash/HIDToVPADNetworkClient/hid/purejavahid/PureJavaHidDevice.java
@@ -81,18 +81,28 @@ class PureJavaHidDevice implements HidDevice, InputReportListener {
}
@Override
- public short getUsage() {
+ public short getUsagePage() {
return myDeviceInfo.getUsagePage();
}
+
+ @Override
+ public short getUsageID() {
+ return myDeviceInfo.getUsageID();
+ }
@Override
public String getPath() {
return myDeviceInfo.getPath();
}
+ @Override
+ public String getProductString() {
+ return myDeviceInfo.getProductString();
+ }
+
@Override
public String toString() {
- return "PureJavaHidDevice [vid= " + String.format("%04X", getVendorId()) + ", pid= " + String.format("%04X", getProductId()) + ", path= " + getPath()
- + ", data=" + Arrays.toString(currentData) + "]";
+ return "PureJavaHidDevice [vid= " + String.format("%04X", getVendorId()) + ", pid= " + String.format("%04X", getProductId()) + ", path= " + getPath().trim()
+ + ", usage= " + String.format("%04X:%04X", getUsagePage(), getUsageID()) + ", data=" + Arrays.toString(currentData) + "]";
}
}
diff --git a/src/net/ash/HIDToVPADNetworkClient/util/Settings.java b/src/net/ash/HIDToVPADNetworkClient/util/Settings.java
index 74295fa..fe74dfd 100644
--- a/src/net/ash/HIDToVPADNetworkClient/util/Settings.java
+++ b/src/net/ash/HIDToVPADNetworkClient/util/Settings.java
@@ -26,6 +26,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.util.Arrays;
import java.util.Properties;
import lombok.Getter;
@@ -117,6 +118,13 @@ public final class Settings {
}
}
+ String filterStates = prop.getProperty("filterStates");
+ if (filterStates != null) {
+ ControllerFiltering.loadFilterStates(filterStates);
+ } else {
+ ControllerFiltering.setDefaultFilterStates();
+ }
+
log.info("Loaded config successfully!");
}
@@ -139,7 +147,8 @@ public final class Settings {
prop.setProperty("autoActivatingController", Boolean.toString(Settings.AUTO_ACTIVATE_CONTROLLER));
prop.setProperty("sendDataOnlyOnChanges", Boolean.toString(Settings.SEND_DATA_ONLY_ON_CHANGE));
prop.setProperty("scanAutomaticallyForControllers", Boolean.toString(Settings.SCAN_AUTOMATICALLY_FOR_CONTROLLERS));
-
+ prop.setProperty("filterStates", ControllerFiltering.getFilterStates());
+
try {
FileOutputStream outStream = new FileOutputStream(configFile);
prop.store(outStream, "HIDToVPADNetworkClient");
@@ -183,10 +192,65 @@ public final class Settings {
} else if (os.contains("Mac OS X")) {
return Platform.MAC_OS_X;
}
- return null;
+ return Platform.UNKNOWN;
}
public enum Platform {
- LINUX, WINDOWS, MAC_OS_X, UNKNOWN
+ LINUX (0x1), WINDOWS (0x2), MAC_OS_X (0x4), UNKNOWN (0x8);
+
+ private int mask;
+ private Platform(int mask) {
+ this.mask = mask;
+ }
+ }
+
+ //TODO rename this to something less nonsensical
+ public static class ControllerFiltering {
+ public static enum Type {
+ HIDGAMEPAD (0, "HID Gamepads", Platform.LINUX.mask | Platform.WINDOWS.mask | Platform.MAC_OS_X.mask),
+ HIDKEYBOARD (1, "HID Keyboards", Platform.LINUX.mask | Platform.MAC_OS_X.mask),
+ HIDMOUSE (2, "HID Mice", Platform.LINUX.mask | Platform.MAC_OS_X.mask),
+ HIDOTHER (3, "Other HIDs", Platform.LINUX.mask | Platform.WINDOWS.mask | Platform.MAC_OS_X.mask);
+
+ private int index;
+ @Getter private String name;
+ private int platforms;
+ private Type(int index, String name, int platforms) {
+ this.index = index;
+ this.name = name;
+ this.platforms = platforms;
+ }
+ public boolean isSupportedOnPlatform() {
+ return (platforms & getPlattform().mask) != 0;
+ }
+ }
+
+ private static boolean[] filterStates = new boolean[Type.values().length];
+ public static String getFilterStates() {
+ return Arrays.toString(filterStates);
+ }
+ public static void loadFilterStates(String newFilterStates) {
+ boolean[] newFilterStatesParsed = Utilities.stringToBoolArray(newFilterStates);
+ if (newFilterStatesParsed.length != filterStates.length) {
+ //TODO handle changes in filtering more gracefully
+ log.warning("Number of controller filters in config does not match reality, using defaults...");
+ setDefaultFilterStates();
+ } else {
+ filterStates = newFilterStatesParsed;
+ }
+ }
+
+ public static void setFilterState(Type filter, boolean state) {
+ filterStates[filter.index] = state;
+ }
+ public static boolean getFilterState(Type filter) {
+ return filterStates[filter.index] || !filter.isSupportedOnPlatform();
+ }
+ public static void setDefaultFilterStates() {
+ filterStates[Type.HIDGAMEPAD.index] = true;
+ filterStates[Type.HIDKEYBOARD.index] = false;
+ filterStates[Type.HIDMOUSE.index] = false;
+ filterStates[Type.HIDOTHER.index] = false;
+ }
}
}
diff --git a/src/net/ash/HIDToVPADNetworkClient/util/StatusReport.java b/src/net/ash/HIDToVPADNetworkClient/util/StatusReport.java
new file mode 100644
index 0000000..b6ab09f
--- /dev/null
+++ b/src/net/ash/HIDToVPADNetworkClient/util/StatusReport.java
@@ -0,0 +1,39 @@
+package net.ash.HIDToVPADNetworkClient.util;
+
+import net.ash.HIDToVPADNetworkClient.controller.Controller;
+import net.ash.HIDToVPADNetworkClient.hid.HidDevice;
+import net.ash.HIDToVPADNetworkClient.hid.HidManager;
+import net.ash.HIDToVPADNetworkClient.manager.ControllerManager;
+import net.ash.HIDToVPADNetworkClient.network.NetworkManager;
+
+public class StatusReport {
+ public static String generateStatusReport() {
+ String report = "HID to VPAD Network Client\n\nRunning on ";
+ report += Settings.getPlattform();
+
+ report += "\nHID Backend: ";
+ report += HidManager.getBackendType();
+
+ report += "\nCurrently ";
+ report += (NetworkManager.getInstance().isConnected()) ? "Connected.\n" : "Disconnected.\n";
+ report += (NetworkManager.getInstance().isReconnecting()) ? "" : "Not ";
+ report += "Reconnecting.";
+
+ report += "\n\nCurrently attached controllers:";
+ for (Controller c : ControllerManager.getAttachedControllers()) {
+ report += "\n";
+ report += c.toString();
+ }
+
+ report += "\n\nFiltering settings:\n";
+ report += Settings.ControllerFiltering.getFilterStates();
+
+ report += "\n\nAll HIDs:";
+ for (HidDevice d : HidManager.getAllAttachedControllers()) {
+ report += "\n";
+ report += d.toString();
+ }
+
+ return report;
+ }
+}
diff --git a/src/net/ash/HIDToVPADNetworkClient/util/Utilities.java b/src/net/ash/HIDToVPADNetworkClient/util/Utilities.java
index af5f9de..52693ed 100644
--- a/src/net/ash/HIDToVPADNetworkClient/util/Utilities.java
+++ b/src/net/ash/HIDToVPADNetworkClient/util/Utilities.java
@@ -76,4 +76,19 @@ public final class Utilities {
public static short signedShortToByte(short value) {
return signedShortToByte((int) value);
}
+
+ /**
+ * Arrays.toString(boolean[]) in reverse.
+ * https://stackoverflow.com/questions/456367/
+ * @param string
+ * @return array
+ */
+ public static boolean[] stringToBoolArray(String string) {
+ String[] strings = string.replace("[", "").replace("]", "").split(", ");
+ boolean result[] = new boolean[strings.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = Boolean.parseBoolean(strings[i]);
+ }
+ return result;
+ }
}