diff --git a/src/com/limelight/Limelight.java b/src/com/limelight/Limelight.java index 4b943f3..f92d259 100644 --- a/src/com/limelight/Limelight.java +++ b/src/com/limelight/Limelight.java @@ -36,6 +36,8 @@ public class Limelight implements NvConnectionListener { PlatformBinding.getAudioRenderer(), PlatformBinding.getVideoDecoderRenderer()); + ControllerListener.startSendingInput(conn); + } private static void startControllerListener() { diff --git a/src/com/limelight/gui/SettingsFrame.java b/src/com/limelight/gui/SettingsFrame.java index 75c8a60..ce28a33 100644 --- a/src/com/limelight/gui/SettingsFrame.java +++ b/src/com/limelight/gui/SettingsFrame.java @@ -5,6 +5,8 @@ import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import javax.swing.Box; import javax.swing.BoxLayout; @@ -20,10 +22,14 @@ import com.limelight.input.ControllerComponent; import com.limelight.input.Gamepad; import com.limelight.input.GamepadHandler; import com.limelight.input.GamepadSettings; +import com.limelight.settings.GamepadSettingsManager; public class SettingsFrame extends JFrame { private static final long serialVersionUID = 1L; + private boolean configChanged = false; + private GamepadSettings config; + public SettingsFrame() { super("Limelight Settings"); this.setSize(800, 500); @@ -50,11 +56,10 @@ public class SettingsFrame extends JFrame { componentBox.add(Box.createHorizontalStrut(10)); componentBox.add(components[i].getLabel()); componentBox.add(Box.createHorizontalGlue()); - componentBox.add(components[i].getTextField()); + componentBox.add(components[i].getMapButton()); componentBox.add(Box.createHorizontalStrut(10)); - components[i].getTextField().setColumns(10); - components[i].getTextField().setMaximumSize(new Dimension(50, 30)); - components[i].getTextField().addActionListener(createListener()); + components[i].getMapButton().setMaximumSize(new Dimension(50, 30)); + components[i].getMapButton().addActionListener(createListener()); if (i > components.length / 2) { rightColumn.add(componentBox); if (i < components.length - 1) { @@ -80,6 +85,16 @@ public class SettingsFrame extends JFrame { c.add(mainPanel); + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + super.windowClosing(e); + if (configChanged) { + updateConfigs(); + } + } + }); + Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); this.setLocation(dim.width/2-this.getSize().width/2, dim.height/2-this.getSize().height/2); this.setVisible(true); @@ -92,7 +107,7 @@ public class SettingsFrame extends JFrame { //#allthejank ControllerComponent contComp = ControllerComponent.valueOf(((JTextField)e.getSource()).getName()); - contComp.getTextField().setText("Select Input"); + contComp.getMapButton().setText("Select Input"); Gamepad listenPad = GamepadHandler.getGamepads().get(0); listenPad.poll(); @@ -100,14 +115,21 @@ public class SettingsFrame extends JFrame { Event event = new Event(); queue.getNextEvent(event); Component comp = event.getComponent(); - contComp.getTextField().setText(comp.getName()); + contComp.getMapButton().setText(comp.getName()); - GamepadSettings config = listenPad.getConfiguration(); + config = listenPad.getConfiguration(); + if (config == null) { + config = new GamepadSettings(); + } config.insertSetting(contComp, comp); + configChanged = true; } }; } + private void updateConfigs() { + GamepadSettingsManager.writeSettings(config); + } } diff --git a/src/com/limelight/input/ControllerComponent.java b/src/com/limelight/input/ControllerComponent.java index 2a3515b..8b2ff4d 100644 --- a/src/com/limelight/input/ControllerComponent.java +++ b/src/com/limelight/input/ControllerComponent.java @@ -1,9 +1,11 @@ package com.limelight.input; -import javax.swing.JLabel; -import javax.swing.JTextField; +import java.io.Serializable; -public enum ControllerComponent { +import javax.swing.JButton; +import javax.swing.JLabel; + +public enum ControllerComponent implements Serializable { BTN_A("Button 1 (A)", false), BTN_X("Button 2 (X)", false), BTN_Y("Button 3 (Y)", false), BTN_B("Button 4 (B)", false), DPAD_UP("D-pad Up", false), DPAD_DOWN("D-pad Down", false), DPAD_LEFT("D-pad Left", false), DPAD_RIGHT("D-pad Right", false), LS_X("Left Stick X", true), LS_Y("Left Stick X", true), RS_X("Right Stick X", true), RS_Y("Left Stick Y", true), @@ -12,14 +14,13 @@ public enum ControllerComponent { BTN_START("Start Button", false), BTN_BACK("Back Button", false), BTN_SPECIAL("Special Button", false); private JLabel label; - private JTextField textBox; + private JButton mapButton; private boolean analog; private ControllerComponent(String name, boolean analog) { this.label = new JLabel(name); - this.textBox = new JTextField(); - this.textBox.setEditable(false); - this.textBox.setName(this.name()); + this.mapButton = new JButton(); + this.mapButton.setName(this.name()); this.analog = analog; } @@ -27,8 +28,8 @@ public enum ControllerComponent { return label; } - public JTextField getTextField() { - return textBox; + public JButton getMapButton() { + return mapButton; } public boolean isAnalog() { diff --git a/src/com/limelight/input/ControllerListener.java b/src/com/limelight/input/ControllerListener.java index 53c85d8..2bfa30f 100644 --- a/src/com/limelight/input/ControllerListener.java +++ b/src/com/limelight/input/ControllerListener.java @@ -18,6 +18,7 @@ public class ControllerListener { */ public static boolean startUp() { if (listenerThread == null || !listenerThread.isAlive()) { + System.out.println("Controller Listener thread starting up"); listenerThread = new Thread() { @Override public void run() { @@ -36,13 +37,14 @@ public class ControllerListener { Class defEnv = ControllerEnvironment.getDefaultEnvironment().getClass(); construct = defEnv.getDeclaredConstructor(); construct.setAccessible(true); + + ControllerEnvironment defaultEnv = null; + //TODO: allow "rescanning" to work again + defaultEnv = (ControllerEnvironment)construct.newInstance(); + while(!isInterrupted()) { - ControllerEnvironment defaultEnv = null; - - defaultEnv = (ControllerEnvironment)construct.newInstance(); - Controller[] ca = defaultEnv.getControllers(); LinkedList gamepads = new LinkedList(); @@ -60,9 +62,7 @@ public class ControllerListener { } GamepadHandler.addGamepads(gamepads); - if (conn != null) { - GamepadHandler.setConnection(conn); - } + GamepadHandler.setConnection(conn); try { Thread.sleep(1000); @@ -83,12 +83,19 @@ public class ControllerListener { public static void stopListening() { if (listenerThread != null && listenerThread.isAlive()) { + System.out.println("Stopping Controller Listener thread"); listenerThread.interrupt(); } } public static void startSendingInput(NvConnection connection) { + System.out.println("Starting to send controller input"); conn = connection; } + + public static void stopSendingInput() { + System.out.println("Stopping sending controller input"); + conn = null; + } } diff --git a/src/com/limelight/input/Gamepad.java b/src/com/limelight/input/Gamepad.java index 6496674..84f5539 100644 --- a/src/com/limelight/input/Gamepad.java +++ b/src/com/limelight/input/Gamepad.java @@ -104,11 +104,13 @@ public class Gamepad { } private void handleComponent(Component comp, float value) { - ControllerComponent contComp = config.getControllerComponent(comp); - if (contComp.isAnalog()) { - handleAnalog(contComp, value); - } else { - handleButtons(contComp, value); + if (config != null) { + ControllerComponent contComp = config.getControllerComponent(comp); + if (contComp.isAnalog()) { + handleAnalog(contComp, value); + } else { + handleButtons(contComp, value); + } } } @@ -147,14 +149,14 @@ public class Gamepad { break; } } - + private void handleButtons(ControllerComponent contComp, float value) { boolean press = false; if (value > 0.5F) { press = true; } - + switch (contComp) { case BTN_A: toggle(ControllerPacket.A_FLAG, press); diff --git a/src/com/limelight/input/GamepadHandler.java b/src/com/limelight/input/GamepadHandler.java index e6f919b..6ec440d 100644 --- a/src/com/limelight/input/GamepadHandler.java +++ b/src/com/limelight/input/GamepadHandler.java @@ -6,6 +6,7 @@ import java.util.LinkedList; import java.util.List; import com.limelight.nvstream.NvConnection; +import com.limelight.settings.GamepadSettingsManager; import net.java.games.input.Controller; @@ -18,9 +19,11 @@ public class GamepadHandler { gamepads.clear(); + + GamepadSettings settings = GamepadSettingsManager.getSettings(); for (Controller pad : pads) { - gamepads.add(new Gamepad(pad, null)); //TODO: need to create/get the settings for this controller + gamepads.add(new Gamepad(pad, settings)); } } @@ -34,6 +37,7 @@ public class GamepadHandler { public static void startUp() { if (handler == null || !handler.isAlive()) { + System.out.println("Gamepad Handler thread starting up"); handler = new Thread(new Runnable() { @Override public void run() { @@ -42,6 +46,7 @@ public class GamepadHandler { if (!gamepad.poll()) { break; } + gamepad.handleEvents(conn); } try { @@ -56,6 +61,7 @@ public class GamepadHandler { public static void stopHandler() { if (handler != null && handler.isAlive()) { + System.out.println("Stopping Gamepad Handler thread"); handler.interrupt(); conn = null; } diff --git a/src/com/limelight/input/GamepadSettings.java b/src/com/limelight/input/GamepadSettings.java index fe8de61..0649d80 100644 --- a/src/com/limelight/input/GamepadSettings.java +++ b/src/com/limelight/input/GamepadSettings.java @@ -1,10 +1,13 @@ package com.limelight.input; +import java.io.Serializable; import java.util.HashMap; import net.java.games.input.Component; -public class GamepadSettings { +public class GamepadSettings implements Serializable { + private static final long serialVersionUID = -185035113915743149L; + private HashMap mapping; private HashMap inverseMapping; diff --git a/src/com/limelight/settings/GamepadSettingsManager.java b/src/com/limelight/settings/GamepadSettingsManager.java new file mode 100644 index 0000000..475cbc0 --- /dev/null +++ b/src/com/limelight/settings/GamepadSettingsManager.java @@ -0,0 +1,83 @@ +package com.limelight.settings; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import com.limelight.input.GamepadSettings; + +public class GamepadSettingsManager { + private static GamepadSettings cachedSettings; + + + public static GamepadSettings getSettings() { + if (cachedSettings == null) { + File gamepadFile = SettingsManager.getInstance().getGamepadFile(); + ObjectInputStream ois = null; + + try { + ois = new ObjectInputStream(new FileInputStream(gamepadFile)); + GamepadSettings savedSettings = (GamepadSettings)ois.readObject(); + cachedSettings = savedSettings; + + } catch (ClassNotFoundException e) { + System.out.println("Saved file is not of the correct type. It might have been modified externally."); + + } catch (FileNotFoundException e) { + System.out.println("Could not find gamepad settings file"); + e.printStackTrace(); + + } catch (IOException e) { + System.out.println("Could not read gamepad settings file"); + e.printStackTrace(); + + } finally { + if (ois != null) { + try { + ois.close(); + + } catch (IOException e) { + System.out.println("Could not close gamepad settings file"); + e.printStackTrace(); + } + } + } + } + return cachedSettings; + } + + public static void writeSettings(GamepadSettings settings) { + cachedSettings = settings; + + File gamepadFile = SettingsManager.getInstance().getGamepadFile(); + ObjectOutputStream ous = null; + + try { + ous = new ObjectOutputStream(new FileOutputStream(gamepadFile)); + ous.writeObject(settings); + + } catch (FileNotFoundException e) { + System.out.println("Could not find gamepad settings file"); + e.printStackTrace(); + + } catch (IOException e) { + System.out.println("Could not write gamepad settings file"); + e.printStackTrace(); + + } finally { + if (ous != null) { + try { + ous.close(); + } catch (IOException e) { + System.out.println("Unable to close gamepad settings file"); + e.printStackTrace(); + } + } + } + } + +} diff --git a/src/com/limelight/settings/SettingsManager.java b/src/com/limelight/settings/SettingsManager.java new file mode 100644 index 0000000..39ac08a --- /dev/null +++ b/src/com/limelight/settings/SettingsManager.java @@ -0,0 +1,65 @@ +package com.limelight.settings; + +import java.io.File; +import java.io.IOException; + +public class SettingsManager { + + public static String SETTINGS_DIR = System.getProperty("user.home") + File.separator + "Limelight"; + + //directory to hold limelight settings + private File settingsDir; + + private File settingsFile; + private File gamepadFile; + + private static SettingsManager manager; + + private SettingsManager() { + settingsFile = new File(SETTINGS_DIR + "settings"); + gamepadFile = new File(SETTINGS_DIR + "gamepad"); + settingsDir = new File(SETTINGS_DIR); + } + + public static SettingsManager getInstance() { + if (manager == null) { + manager = new SettingsManager(); + } + return manager; + } + + public File getGamepadFile() { + if (!settingsDir.exists()) { + settingsFile.mkdirs(); + } + + if (!gamepadFile.exists()) { + try { + gamepadFile.createNewFile(); + } catch (IOException e) { + System.out.println("Unable to create gamepad file"); + return null; + } + } + + return gamepadFile; + } + + public File getSettingsFile() { + if (!settingsDir.exists()) { + settingsFile.mkdirs(); + } + + if (!settingsFile.exists()) { + try { + settingsFile.createNewFile(); + } catch (IOException e) { + System.out.println("Unable to create setting file"); + return null; + } + } + + return settingsFile; + } + +}