diff --git a/limelight-pc/src/com/limelight/Limelight.java b/limelight-pc/src/com/limelight/Limelight.java index f7e2327..e139bcd 100644 --- a/limelight-pc/src/com/limelight/Limelight.java +++ b/limelight-pc/src/com/limelight/Limelight.java @@ -57,9 +57,9 @@ public class Limelight implements NvConnectionListener { */ try { //#allthejank - Constructor construct = null; + Constructor construct = null; - Class defEnv = ControllerEnvironment.getDefaultEnvironment().getClass(); + Class defEnv = ControllerEnvironment.getDefaultEnvironment().getClass(); construct = defEnv.getDeclaredConstructor(); construct.setAccessible(true); @@ -71,11 +71,20 @@ public class Limelight implements NvConnectionListener { Controller[] ca = defaultEnv.getControllers(); LinkedList gamepads = new LinkedList(); + + /* + * iterates through the controllers and adds gamepads and ps3 controller to the list + * NOTE: JInput does not consider a PS3 controller to be a gamepad (it thinks it's a "STICK") so we must use the + * name of it. + */ for(int i = 0; i < ca.length; i++){ if (ca[i].getType() == Controller.Type.GAMEPAD) { gamepads.add(ca[i]); + } else if (ca[i].getName().contains("PLAYSTATION")) { + gamepads.add(ca[i]); } } + GamepadHandler.addGamepads(gamepads, conn); diff --git a/limelight-pc/src/com/limelight/input/Gamepad.java b/limelight-pc/src/com/limelight/input/Gamepad.java new file mode 100644 index 0000000..62aec94 --- /dev/null +++ b/limelight-pc/src/com/limelight/input/Gamepad.java @@ -0,0 +1,128 @@ +package com.limelight.input; + +import com.limelight.nvstream.NvConnection; + +import net.java.games.input.Component; +import net.java.games.input.Controller; +import net.java.games.input.Event; +import net.java.games.input.EventQueue; + +public abstract class Gamepad { + protected Controller pad; + private NvConnection conn; + + protected short inputMap = 0x0000; + protected byte leftTrigger = 0x00; + protected byte rightTrigger = 0x00; + protected short rightStickX = 0x0000; + protected short rightStickY = 0x0000; + protected short leftStickX = 0x0000; + protected short leftStickY = 0x0000; + + public enum ControllerType { XBOX, PS3 }; + + + public static Gamepad createInstance(NvConnection conn, Controller pad, ControllerType type) { + switch (type) { + case XBOX: + return new XBox360Controller(conn, pad); + case PS3: + return new PS3Controller(conn, pad); + default: + return new XBox360Controller(conn, pad); + } + } + + public Gamepad(NvConnection conn, Controller pad) { + this.conn = conn; + this.pad = pad; + + for (Component comp : pad.getComponents()) { + initValue(comp); + } + + } + + private void initValue(Component comp) { + handleComponent(comp, comp.getPollData()); + } + + public boolean poll() { + return pad.poll(); + } + + public void sendControllerPacket() { + conn.sendControllerInput(inputMap, leftTrigger, rightTrigger, + leftStickX, leftStickY, rightStickX, rightStickY); + } + + public void handleEvents() { + EventQueue queue = pad.getEventQueue(); + Event event = new Event(); + + while(queue.getNextEvent(event)) { + + /* uncommented for debugging */ + //printInfo(pad, event); + + handleEvent(event); + + sendControllerPacket(); + } + + } + + /* + * used for debugging, normally unused. + */ + @SuppressWarnings("unused") + private void printInfo(Controller gamepad, Event event) { + Component comp = event.getComponent(); + + StringBuilder builder = new StringBuilder(gamepad.getName()); + + builder.append(" at "); + builder.append(event.getNanos()).append(": "); + builder.append(comp.getName()).append(" changed to "); + + + float value = event.getValue(); + if(comp.isAnalog()) { + builder.append(value); + } else { + if(value==1.0f) { + builder.append("On"); + } else { + builder.append("Off"); + } + } + + System.out.println(builder.toString()); + } + + private void handleEvent(Event event) { + Component comp = event.getComponent(); + float value = event.getValue(); + + handleComponent(comp, value); + } + + private void handleComponent(Component comp, float value) { + if (comp.isAnalog()) { + handleAnalog(comp, value); + } else { + handleButtons(comp, value); + } + } + + protected void toggle(short button, boolean press) { + if (press) { + inputMap |= button; + } else { + inputMap &= ~button; + } + } + + protected abstract void handleAnalog(Component comp, float value); + protected abstract void handleButtons(Component comp, float value); +} diff --git a/limelight-pc/src/com/limelight/input/GamepadHandler.java b/limelight-pc/src/com/limelight/input/GamepadHandler.java index 480ff85..fa6ff50 100644 --- a/limelight-pc/src/com/limelight/input/GamepadHandler.java +++ b/limelight-pc/src/com/limelight/input/GamepadHandler.java @@ -1,70 +1,53 @@ package com.limelight.input; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import com.limelight.input.Gamepad.ControllerType; import com.limelight.nvstream.NvConnection; -import com.limelight.nvstream.input.ControllerPacket; -import net.java.games.input.Component; import net.java.games.input.Controller; -import net.java.games.input.Event; -import net.java.games.input.EventQueue; public class GamepadHandler { - private NvConnection conn; - - private static LinkedList gamepads = new LinkedList(); + private static LinkedList gamepads = new LinkedList(); private static GamepadHandler singleton; - short inputMap = 0x0000; - private byte leftTrigger = 0x00; - private byte rightTrigger = 0x00; - private short rightStickX = 0x0000; - private short rightStickY = 0x0000; - private short leftStickX = 0x0000; - private short leftStickY = 0x0000; - - private GamepadHandler(NvConnection conn) { - this.conn = conn; - } - public static void addGamepads(List pads, NvConnection conn) { if (singleton == null) { - singleton = new GamepadHandler(conn); + singleton = new GamepadHandler(); singleton.startUp(); } gamepads.clear(); for (Controller pad : pads) { - gamepads.add(pad); + + gamepads.add(Gamepad.createInstance(conn, pad, getType(pad))); } } + private static ControllerType getType(Controller pad) { + if (pad.getType() == Controller.Type.GAMEPAD) { + return ControllerType.XBOX; + } + if (pad.getName().contains("PLAYSTATION")) { + return ControllerType.PS3; + } + return null; + } + private void startUp() { new Thread(new Runnable() { @Override public void run() { while (true) { - for (Controller gamepad : gamepads) { + for (Gamepad gamepad : gamepads) { if (!gamepad.poll()) { - gamepads.remove(GamepadHandler.this); + gamepads.remove(gamepad); break; } - EventQueue queue = gamepad.getEventQueue(); - Event event = new Event(); - - while(queue.getNextEvent(event)) { - - //printInfo(gamepda, event); - - handleEvent(event); - - sendControllerPacket(); - } + gamepad.handleEvents(); } try { Thread.sleep(20); @@ -74,104 +57,4 @@ public class GamepadHandler { }).start(); } - private void printInfo(Controller gamepad, Event event) { - StringBuffer buffer = new StringBuffer(gamepad.getName()); - buffer.append(" at "); - buffer.append(event.getNanos()).append(", "); - Component comp = event.getComponent(); - buffer.append(comp.getName()).append(" changed to "); - float value = event.getValue(); - if(comp.isAnalog()) { - buffer.append(value); - } else { - if(value==1.0f) { - buffer.append("On"); - } else { - buffer.append("Off"); - } - } - System.out.println(buffer.toString()); - System.out.println(comp.getIdentifier().toString()); - } - - - private void handleEvent(Event event) { - Component comp = event.getComponent(); - float value = event.getValue(); - - if (comp.isAnalog()) { - handleAnalog(comp, value); - } else { - handleButtons(comp, value); - } - } - - private void toggle(short button, boolean press) { - if (press) { - inputMap |= button; - } else { - inputMap &= ~button; - } - } - - private void handleButtons(Component comp, float value) { - Component.Identifier id = comp.getIdentifier(); - boolean press = value > 0.5F; - - if (id == Component.Identifier.Button._13) { - toggle(ControllerPacket.LEFT_FLAG, press); - } else if (id == Component.Identifier.Button._14) { - toggle(ControllerPacket.RIGHT_FLAG, press); - } else if (id == Component.Identifier.Button._11) { - toggle(ControllerPacket.UP_FLAG, press); - } else if (id == Component.Identifier.Button._12) { - toggle(ControllerPacket.DOWN_FLAG, press); - } else if (id == Component.Identifier.Button._0) { - toggle(ControllerPacket.A_FLAG, press); - } else if (id == Component.Identifier.Button._2) { - toggle(ControllerPacket.X_FLAG, press); - } else if (id == Component.Identifier.Button._3) { - toggle(ControllerPacket.Y_FLAG, press); - } else if (id == Component.Identifier.Button._1) { - toggle(ControllerPacket.B_FLAG, press); - } else if (id == Component.Identifier.Button._9) { - toggle(ControllerPacket.BACK_FLAG, press); - } else if (id == Component.Identifier.Button._8) { - toggle(ControllerPacket.PLAY_FLAG, press); - } else if (id == Component.Identifier.Button._7) { - toggle(ControllerPacket.RS_CLK_FLAG, press); - } else if (id == Component.Identifier.Button._6) { - toggle(ControllerPacket.LS_CLK_FLAG, press); - } else if (id == Component.Identifier.Button._4) { - toggle(ControllerPacket.LB_FLAG, press); - } else if (id == Component.Identifier.Button._5) { - toggle(ControllerPacket.RB_FLAG, press); - } else if (id == Component.Identifier.Button._10) { - toggle(ControllerPacket.SPECIAL_BUTTON_FLAG, press); - } - } - - private void handleAnalog(Component comp, float value) { - Component.Identifier id = comp.getIdentifier(); - - if (id == Component.Identifier.Axis.RX) { - rightStickX = (short)Math.round(value * 0x7FFF); - } else if (id == Component.Identifier.Axis.RY) { - rightStickY = (short)Math.round(-value * 0x7FFF); - } else if (id == Component.Identifier.Axis.X) { - leftStickX = (short)Math.round(value * 0x7FFF); - } else if (id == Component.Identifier.Axis.Y) { - leftStickY = (short)Math.round(-value * 0x7FFF); - } else if (id == Component.Identifier.Axis.Z) { - leftTrigger = (byte)Math.round((value + 1) / 2 * 0xFF); - } else if (id == Component.Identifier.Axis.RZ) { - rightTrigger = (byte)Math.round((value + 1) / 2 * 0xFF); - } - - } - - private void sendControllerPacket() { - conn.sendControllerInput(inputMap, leftTrigger, rightTrigger, - leftStickX, leftStickY, rightStickX, rightStickY); - } } diff --git a/limelight-pc/src/com/limelight/input/PS3Controller.java b/limelight-pc/src/com/limelight/input/PS3Controller.java new file mode 100644 index 0000000..a21ed3b --- /dev/null +++ b/limelight-pc/src/com/limelight/input/PS3Controller.java @@ -0,0 +1,71 @@ +package com.limelight.input; + +import com.limelight.nvstream.NvConnection; +import com.limelight.nvstream.input.ControllerPacket; + +import net.java.games.input.Component; +import net.java.games.input.Controller; + +public class PS3Controller extends Gamepad { + + public PS3Controller(NvConnection conn, Controller pad) { + super(conn, pad); + } + + @Override + protected void handleAnalog(Component comp, float value) { + Component.Identifier id = comp.getIdentifier(); + + if (id == Component.Identifier.Axis.Z) { + rightStickX = (short)Math.round(value * 0x7FFF); + } else if (id == Component.Identifier.Axis.RZ) { + rightStickY = (short)Math.round(-value * 0x7FFF); + } else if (id == Component.Identifier.Axis.X) { + leftStickX = (short)Math.round(value * 0x7FFF); + } else if (id == Component.Identifier.Axis.Y) { + leftStickY = (short)Math.round(-value * 0x7FFF); + } + } + + @Override + protected void handleButtons(Component comp, float value) { + Component.Identifier id = comp.getIdentifier(); + boolean press = value > 0.5F; + + if (id == Component.Identifier.Button._7) { + toggle(ControllerPacket.LEFT_FLAG, press); + } else if (id == Component.Identifier.Button._5) { + toggle(ControllerPacket.RIGHT_FLAG, press); + } else if (id == Component.Identifier.Button._4) { + toggle(ControllerPacket.UP_FLAG, press); + } else if (id == Component.Identifier.Button._6) { + toggle(ControllerPacket.DOWN_FLAG, press); + } else if (id == Component.Identifier.Button._14) { + toggle(ControllerPacket.A_FLAG, press); + } else if (id == Component.Identifier.Button._15) { + toggle(ControllerPacket.X_FLAG, press); + } else if (id == Component.Identifier.Button._12) { + toggle(ControllerPacket.Y_FLAG, press); + } else if (id == Component.Identifier.Button._13) { + toggle(ControllerPacket.B_FLAG, press); + } else if (id == Component.Identifier.Button._0) { + toggle(ControllerPacket.BACK_FLAG, press); + } else if (id == Component.Identifier.Button._3) { + toggle(ControllerPacket.PLAY_FLAG, press); + } else if (id == Component.Identifier.Button._2) { + toggle(ControllerPacket.RS_CLK_FLAG, press); + } else if (id == Component.Identifier.Button._1) { + toggle(ControllerPacket.LS_CLK_FLAG, press); + } else if (id == Component.Identifier.Button._10) { + toggle(ControllerPacket.LB_FLAG, press); + } else if (id == Component.Identifier.Button._11) { + toggle(ControllerPacket.RB_FLAG, press); + } else if (id == Component.Identifier.Button._16) { + toggle(ControllerPacket.SPECIAL_BUTTON_FLAG, press); + } else if (id == Component.Identifier.Button._8) { + leftTrigger = (byte)Math.round((press ? 1 : 0) * 0xFF); + } else if (id == Component.Identifier.Button._9) { + rightTrigger = (byte)Math.round((press ? 1 : 0) * 0xFF); + } + } +} diff --git a/limelight-pc/src/com/limelight/input/XBox360Controller.java b/limelight-pc/src/com/limelight/input/XBox360Controller.java new file mode 100644 index 0000000..a393297 --- /dev/null +++ b/limelight-pc/src/com/limelight/input/XBox360Controller.java @@ -0,0 +1,73 @@ +package com.limelight.input; + +import net.java.games.input.Component; +import net.java.games.input.Controller; + +import com.limelight.nvstream.NvConnection; +import com.limelight.nvstream.input.ControllerPacket; + +public class XBox360Controller extends Gamepad { + + public XBox360Controller(NvConnection conn, Controller pad) { + super(conn, pad); + } + + @Override + protected void handleButtons(Component comp, float value) { + Component.Identifier id = comp.getIdentifier(); + boolean press = value > 0.5F; + + if (id == Component.Identifier.Button._13) { + toggle(ControllerPacket.LEFT_FLAG, press); + } else if (id == Component.Identifier.Button._14) { + toggle(ControllerPacket.RIGHT_FLAG, press); + } else if (id == Component.Identifier.Button._11) { + toggle(ControllerPacket.UP_FLAG, press); + } else if (id == Component.Identifier.Button._12) { + toggle(ControllerPacket.DOWN_FLAG, press); + } else if (id == Component.Identifier.Button._0) { + toggle(ControllerPacket.A_FLAG, press); + } else if (id == Component.Identifier.Button._2) { + toggle(ControllerPacket.X_FLAG, press); + } else if (id == Component.Identifier.Button._3) { + toggle(ControllerPacket.Y_FLAG, press); + } else if (id == Component.Identifier.Button._1) { + toggle(ControllerPacket.B_FLAG, press); + } else if (id == Component.Identifier.Button._9) { + toggle(ControllerPacket.BACK_FLAG, press); + } else if (id == Component.Identifier.Button._8) { + toggle(ControllerPacket.PLAY_FLAG, press); + } else if (id == Component.Identifier.Button._7) { + toggle(ControllerPacket.RS_CLK_FLAG, press); + } else if (id == Component.Identifier.Button._6) { + toggle(ControllerPacket.LS_CLK_FLAG, press); + } else if (id == Component.Identifier.Button._4) { + toggle(ControllerPacket.LB_FLAG, press); + } else if (id == Component.Identifier.Button._5) { + toggle(ControllerPacket.RB_FLAG, press); + } else if (id == Component.Identifier.Button._10) { + toggle(ControllerPacket.SPECIAL_BUTTON_FLAG, press); + } + } + + @Override + protected void handleAnalog(Component comp, float value) { + Component.Identifier id = comp.getIdentifier(); + + if (id == Component.Identifier.Axis.RX) { + rightStickX = (short)Math.round(value * 0x7FFF); + } else if (id == Component.Identifier.Axis.RY) { + rightStickY = (short)Math.round(-value * 0x7FFF); + } else if (id == Component.Identifier.Axis.X) { + leftStickX = (short)Math.round(value * 0x7FFF); + } else if (id == Component.Identifier.Axis.Y) { + leftStickY = (short)Math.round(-value * 0x7FFF); + } else if (id == Component.Identifier.Axis.Z) { + leftTrigger = (byte)Math.round((value + 1) / 2 * 0xFF); + } else if (id == Component.Identifier.Axis.RZ) { + rightTrigger = (byte)Math.round((value + 1) / 2 * 0xFF); + } + + } + +}