Add multiple controller support

This commit is contained in:
Cameron Gutman 2015-02-01 04:37:35 -05:00
parent 9988330613
commit 51343a171d
5 changed files with 130 additions and 27 deletions

View File

@ -348,6 +348,20 @@ public class NvConnection {
inputStream.sendMouseButtonUp(mouseButton);
}
public void sendControllerInput(final short controllerNumber,
final short buttonFlags,
final byte leftTrigger, final byte rightTrigger,
final short leftStickX, final short leftStickY,
final short rightStickX, final short rightStickY)
{
if (inputStream == null)
return;
inputStream.sendControllerInput(controllerNumber, buttonFlags, leftTrigger,
rightTrigger, leftStickX, leftStickY,
rightStickX, rightStickY);
}
public void sendControllerInput(final short buttonFlags,
final byte leftTrigger, final byte rightTrigger,
final short leftStickX, final short leftStickY,

View File

@ -11,8 +11,9 @@ public class ControllerBatchingBlock {
private short leftStickY;
private short rightStickX;
private short rightStickY;
private short controllerNumber;
public ControllerBatchingBlock(ControllerPacket initialPacket) {
public ControllerBatchingBlock(MultiControllerPacket initialPacket) {
this.buttonFlags = initialPacket.buttonFlags;
this.leftTrigger = initialPacket.leftTrigger;
this.rightTrigger = initialPacket.rightTrigger;
@ -54,8 +55,9 @@ public class ControllerBatchingBlock {
// We have several restrictions that will cause batching to break up the controller packets.
// 1) Button flags must be the same for all packets in the batch
// 2) The movement direction of all axes must remain the same or be neutral
public boolean submitNewPacket(ControllerPacket packet) {
public boolean submitNewPacket(MultiControllerPacket packet) {
if (buttonFlags != packet.buttonFlags ||
controllerNumber != packet.controllerNumber ||
!checkDirs(leftTrigger, packet.leftTrigger, 0) ||
!checkDirs(rightTrigger, packet.rightTrigger, 1) ||
!checkDirs(leftStickX, packet.leftStickX, 2) ||
@ -66,6 +68,7 @@ public class ControllerBatchingBlock {
return false;
}
this.controllerNumber = packet.controllerNumber;
this.leftTrigger = packet.leftTrigger;
this.rightTrigger = packet.rightTrigger;
this.leftStickX = packet.leftStickX;
@ -75,7 +78,8 @@ public class ControllerBatchingBlock {
return true;
}
public void reinitializePacket(ControllerPacket packet) {
public void reinitializePacket(MultiControllerPacket packet) {
packet.controllerNumber = controllerNumber;
packet.buttonFlags = buttonFlags;
packet.leftTrigger = leftTrigger;
packet.rightTrigger = rightTrigger;

View File

@ -3,7 +3,7 @@ package com.limelight.nvstream.input;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class ControllerPacket extends InputPacket {
public class ControllerPacket extends MultiControllerPacket {
public static final byte[] HEADER =
{
0x0A,
@ -46,26 +46,12 @@ public class ControllerPacket extends InputPacket {
public static final short PACKET_LENGTH = PAYLOAD_LENGTH +
InputPacket.HEADER_LENGTH;
// Set this flag if you want ControllerPacket to handle scaling for you
// You MUST properly handle deadzones to use this flag
//
// Note: This flag does nothing right now. It causes some controllers
// to behave badly.
public static boolean enableAxisScaling = false;
short buttonFlags;
byte leftTrigger;
byte rightTrigger;
short leftStickX;
short leftStickY;
short rightStickX;
short rightStickY;
public ControllerPacket(short buttonFlags, byte leftTrigger, byte rightTrigger,
short leftStickX, short leftStickY,
short rightStickX, short rightStickY)
{
super(PACKET_TYPE);
super((short) 0, buttonFlags, leftTrigger, rightTrigger, leftStickX,
leftStickY, rightStickX, rightStickY);
this.buttonFlags = buttonFlags;
this.leftTrigger = leftTrigger;

View File

@ -129,8 +129,8 @@ public class ControllerStream {
} while (totalDeltaX != 0 && totalDeltaY != 0);
}
// Try to batch axis changes on controller packets too
else if (!inputQueue.isEmpty() && packet instanceof ControllerPacket) {
ControllerPacket initialControllerPacket = (ControllerPacket) packet;
else if (!inputQueue.isEmpty() && packet instanceof MultiControllerPacket) {
MultiControllerPacket initialControllerPacket = (MultiControllerPacket) packet;
ControllerBatchingBlock batchingBlock = null;
synchronized (inputQueue) {
@ -138,13 +138,13 @@ public class ControllerStream {
while (i.hasNext()) {
InputPacket queuedPacket = i.next();
if (queuedPacket instanceof ControllerPacket) {
if (queuedPacket instanceof MultiControllerPacket) {
// Only initialize the batching block if we got here
if (batchingBlock == null) {
batchingBlock = new ControllerBatchingBlock(initialControllerPacket);
}
if (batchingBlock.submitNewPacket((ControllerPacket) queuedPacket))
if (batchingBlock.submitNewPacket((MultiControllerPacket) queuedPacket))
{
// Batching was successful, so remove this packet
i.remove();
@ -263,9 +263,35 @@ public class ControllerStream {
public void sendControllerInput(short buttonFlags, byte leftTrigger, byte rightTrigger,
short leftStickX, short leftStickY, short rightStickX, short rightStickY)
{
queuePacket(new ControllerPacket(buttonFlags, leftTrigger,
rightTrigger, leftStickX, leftStickY,
rightStickX, rightStickY));
if (context.serverGeneration == ConnectionContext.SERVER_GENERATION_3) {
// Use legacy controller packets for generation 3
queuePacket(new ControllerPacket(buttonFlags, leftTrigger,
rightTrigger, leftStickX, leftStickY,
rightStickX, rightStickY));
}
else {
// Use multi-controller packets for generation 4 and above
queuePacket(new MultiControllerPacket((short) 0, buttonFlags, leftTrigger,
rightTrigger, leftStickX, leftStickY,
rightStickX, rightStickY));
}
}
public void sendControllerInput(short controllerNumber, short buttonFlags, byte leftTrigger, byte rightTrigger,
short leftStickX, short leftStickY, short rightStickX, short rightStickY)
{
if (context.serverGeneration == ConnectionContext.SERVER_GENERATION_3) {
// Use legacy controller packets for generation 3
queuePacket(new ControllerPacket(buttonFlags, leftTrigger,
rightTrigger, leftStickX, leftStickY,
rightStickX, rightStickY));
}
else {
// Use multi-controller packets for generation 4 and above
queuePacket(new MultiControllerPacket(controllerNumber, buttonFlags, leftTrigger,
rightTrigger, leftStickX, leftStickY,
rightStickX, rightStickY));
}
}
public void sendMouseButtonDown(byte mouseButton)

View File

@ -0,0 +1,73 @@
package com.limelight.nvstream.input;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class MultiControllerPacket extends InputPacket {
public static final byte[] TAIL =
{
(byte)0x9C,
0x00,
0x00,
0x00,
0x55,
0x00
};
public static final int PACKET_TYPE = 0x1e;
public static final short PAYLOAD_LENGTH = 30;
public static final short PACKET_LENGTH = PAYLOAD_LENGTH +
InputPacket.HEADER_LENGTH;
short controllerNumber;
short buttonFlags;
byte leftTrigger;
byte rightTrigger;
short leftStickX;
short leftStickY;
short rightStickX;
short rightStickY;
public MultiControllerPacket(short controllerNumber, short buttonFlags, byte leftTrigger, byte rightTrigger,
short leftStickX, short leftStickY,
short rightStickX, short rightStickY)
{
super(PACKET_TYPE);
this.controllerNumber = controllerNumber;
this.buttonFlags = buttonFlags;
this.leftTrigger = leftTrigger;
this.rightTrigger = rightTrigger;
this.leftStickX = leftStickX;
this.leftStickY = leftStickY;
this.rightStickX = rightStickX;
this.rightStickY = rightStickY;
}
@Override
public void toWirePayload(ByteBuffer bb) {
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.putInt(0xd);
bb.putShort((short) 0x1a);
bb.putShort(controllerNumber);
bb.putShort((short) 0x07);
bb.putShort((short) 0x14);
bb.putShort(buttonFlags);
bb.put(leftTrigger);
bb.put(rightTrigger);
bb.putShort(leftStickX);
bb.putShort(leftStickY);
bb.putShort(rightStickX);
bb.putShort(rightStickY);
bb.put(TAIL);
}
@Override
public int getPacketLength() {
return PACKET_LENGTH;
}
}