mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-20 19:42:45 +00:00
Add multiple controller support
This commit is contained in:
parent
9988330613
commit
51343a171d
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,10 +263,36 @@ public class ControllerStream {
|
||||
public void sendControllerInput(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((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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user