diff --git a/src/com/limelight/gui/GamepadConfigFrame.java b/src/com/limelight/gui/GamepadConfigFrame.java index a61e669..085eb0b 100644 --- a/src/com/limelight/gui/GamepadConfigFrame.java +++ b/src/com/limelight/gui/GamepadConfigFrame.java @@ -34,6 +34,7 @@ import com.limelight.input.gamepad.Gamepad; import com.limelight.input.gamepad.GamepadHandler; import com.limelight.input.gamepad.GamepadMapping; import com.limelight.input.gamepad.GamepadMapping.Mapping; +import com.limelight.input.gamepad.SourceComponent; import com.limelight.settings.GamepadSettingsManager; /** @@ -244,10 +245,9 @@ public class GamepadConfigFrame extends JFrame { @Override public void run() { - Component newComponent = waitForNewMapping(pad); + SourceComponent newComponent = waitForNewMapping(pad); consumeEvents(pad); - if (newComponent != null) { Mapping oldConfig = config.get(newComponent); if (oldConfig != null) { @@ -256,7 +256,7 @@ public class GamepadConfigFrame extends JFrame { config.insertMapping(mappingToMap, newComponent); - buttonPressed.setText(newComponent.getName()); + buttonPressed.setText(newComponent.getComponent().getName()); configChanged = true; } else { @@ -275,8 +275,8 @@ public class GamepadConfigFrame extends JFrame { /* * Waits until the user chooses what to map to the clicked component */ - private Component waitForNewMapping(Gamepad pad) { - Component newMapping = null; + private SourceComponent waitForNewMapping(Gamepad pad) { + SourceComponent newMapping = null; while (newMapping == null) { if (pad.poll()) { @@ -287,8 +287,13 @@ public class GamepadConfigFrame extends JFrame { if (!pad.poll()) { break; } - if (Math.abs(event.getValue()) > .75F) { - newMapping = event.getComponent(); + + if (event.getComponent().getIdentifier() == Component.Identifier.Axis.POV) { + newMapping = new SourceComponent(event.getComponent(), ""+event.getValue()); + break; + } + else if (!event.getComponent().isAnalog() || Math.abs(event.getValue()) > .75F) { + newMapping = new SourceComponent(event.getComponent(), ""); break; } } diff --git a/src/com/limelight/gui/StreamFrame.java b/src/com/limelight/gui/StreamFrame.java index 2b07913..3c6d178 100644 --- a/src/com/limelight/gui/StreamFrame.java +++ b/src/com/limelight/gui/StreamFrame.java @@ -30,8 +30,6 @@ import javax.swing.JProgressBar; import com.limelight.Limelight; import com.limelight.input.KeyboardHandler; import com.limelight.input.MouseHandler; -import com.limelight.input.gamepad.GamepadHandler; -import com.limelight.input.gamepad.GamepadListener; import com.limelight.nvstream.NvConnection; import com.limelight.nvstream.NvConnectionListener.Stage; import com.limelight.nvstream.StreamConfiguration; diff --git a/src/com/limelight/input/gamepad/Gamepad.java b/src/com/limelight/input/gamepad/Gamepad.java index 60f0ead..58dc732 100644 --- a/src/com/limelight/input/gamepad/Gamepad.java +++ b/src/com/limelight/input/gamepad/Gamepad.java @@ -5,6 +5,7 @@ import com.limelight.nvstream.NvConnection; import com.limelight.nvstream.input.ControllerPacket; import net.java.games.input.Component; +import net.java.games.input.Component.Identifier; import net.java.games.input.Controller; import net.java.games.input.Event; import net.java.games.input.EventQueue; @@ -97,8 +98,7 @@ public class Gamepad { * Prints out the specified event information for the given gamepad * used for debugging, normally unused. */ - @SuppressWarnings("unused") - private void printInfo(Controller gamepad, Event event) { + public static void printInfo(Controller gamepad, Event event) { Component comp = event.getComponent(); StringBuilder builder = new StringBuilder(gamepad.getName()); @@ -108,9 +108,40 @@ public class Gamepad { builder.append(comp.getName()).append(" changed to "); - float value = event.getValue(); + float value = event.getValue(); if(comp.isAnalog()) { builder.append(value); + } else if (comp.getIdentifier() == Identifier.Axis.POV) { + if (value == Component.POV.DOWN) { + builder.append("Down"); + } + else if (value == Component.POV.UP) { + builder.append("Up"); + } + else if (value == Component.POV.LEFT) { + builder.append("Left"); + } + else if (value == Component.POV.RIGHT) { + builder.append("Right"); + } + else if (value == Component.POV.CENTER) { + builder.append("Center"); + } + else if (value == Component.POV.DOWN_LEFT) { + builder.append("Down-left"); + } + else if (value == Component.POV.DOWN_RIGHT) { + builder.append("Down-right"); + } + else if (value == Component.POV.UP_LEFT) { + builder.append("Up-left"); + } + else if (value == Component.POV.UP_RIGHT) { + builder.append("Up-right"); + } + else { + builder.append("Unknown"); + } } else { if(value==1.0f) { builder.append("On"); @@ -140,6 +171,9 @@ public class Gamepad { if (mapping != null) { if (mapping.contComp.isAnalog()) { handleAnalog(mapping.contComp, sanitizeValue(mapping, value)); + } else if (comp.getIdentifier() == Component.Identifier.Axis.POV) { + // The values are directional constants so they cannot be sanitized + handlePOV(value); } else { handleButtons(mapping.contComp, sanitizeValue(mapping, value)); } @@ -171,6 +205,47 @@ public class Gamepad { } } + /* + * Handles POV component input + */ + private void handlePOV(float value) { + if (value == Component.POV.UP || + value == Component.POV.UP_LEFT || + value == Component.POV.UP_RIGHT) { + toggle(ControllerPacket.UP_FLAG, true); + } + else { + toggle(ControllerPacket.UP_FLAG, false); + } + + if (value == Component.POV.DOWN || + value == Component.POV.DOWN_LEFT || + value == Component.POV.DOWN_RIGHT) { + toggle(ControllerPacket.DOWN_FLAG, true); + } + else { + toggle(ControllerPacket.DOWN_FLAG, false); + } + + if (value == Component.POV.LEFT || + value == Component.POV.DOWN_LEFT || + value == Component.POV.UP_LEFT) { + toggle(ControllerPacket.LEFT_FLAG, true); + } + else { + toggle(ControllerPacket.LEFT_FLAG, false); + } + + if (value == Component.POV.RIGHT || + value == Component.POV.UP_RIGHT || + value == Component.POV.DOWN_RIGHT) { + toggle(ControllerPacket.RIGHT_FLAG, true); + } + else { + toggle(ControllerPacket.RIGHT_FLAG, false); + } + } + /* * Handles analog component input */ diff --git a/src/com/limelight/input/gamepad/GamepadMapping.java b/src/com/limelight/input/gamepad/GamepadMapping.java index 1ece52e..1525b2a 100644 --- a/src/com/limelight/input/gamepad/GamepadMapping.java +++ b/src/com/limelight/input/gamepad/GamepadMapping.java @@ -28,8 +28,12 @@ public class GamepadMapping implements Serializable { * @param toMap a Mapping that will be mapped to the specified gamepad component * @param comp the gamepad component to map to. */ - public void insertMapping(Mapping toMap, Component comp) { - mapping.put(comp.getIdentifier().getName(), toMap); + public void insertMapping(Mapping toMap, SourceComponent comp) { + // This is the base mapping for components with multiple "buttons" + mapping.put(comp.getComponentId(), toMap); + + // This is the more-specific mapping for the specific buttons + mapping.put(comp.getFullUniqueId(), toMap); } /** @@ -41,12 +45,31 @@ public class GamepadMapping implements Serializable { return mapping.get(comp.getIdentifier().getName()); } + /** + * Gets the mapping for the specified source component + * @param comp the source component to get a mapping for + * @return a mapping for the requested component + */ + public Mapping get(SourceComponent comp) { + return mapping.get(comp.getFullUniqueId()); + } + /** * Removes the mapping to the specified component * @param comp the component to no longer be mapped. */ - public void remove(Component comp) { - mapping.remove(comp.getIdentifier().getName()); + public void remove(SourceComponent comp) { + // Remove the most specific mapping + mapping.remove(comp.getFullUniqueId()); + + for (Entry entry : mapping.entrySet()) { + if (entry.getKey().startsWith(comp.getComponentId())) { + return; + } + } + + // Remove the common mapping if no more specific mappings remain + mapping.remove(comp.getComponentId()); } /** diff --git a/src/com/limelight/input/gamepad/SourceComponent.java b/src/com/limelight/input/gamepad/SourceComponent.java new file mode 100644 index 0000000..0474eca --- /dev/null +++ b/src/com/limelight/input/gamepad/SourceComponent.java @@ -0,0 +1,29 @@ +package com.limelight.input.gamepad; + +import net.java.games.input.Component; + +public class SourceComponent { + private Component component; + private String id; + + public SourceComponent(Component component, String id) { + this.component = component; + this.id = id; + } + + public Component getComponent() { + return component; + } + + public String getId() { + return id; + } + + public String getFullUniqueId() { + return getComponentId() + " " + getId(); + } + + public String getComponentId() { + return component.getIdentifier().getName(); + } +}