From 975be33ff83321265d7e4f5d9f6c44ed49b26cf6 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 1 Feb 2015 21:01:44 -0500 Subject: [PATCH] Add multiple controller support --- limelight-common/Input.h | 33 +++++++++-- limelight-common/InputStream.c | 100 +++++++++++++++++++++++---------- limelight-common/Limelight.h | 2 + 3 files changed, 101 insertions(+), 34 deletions(-) diff --git a/limelight-common/Input.h b/limelight-common/Input.h index 72a8f96..da36fe0 100644 --- a/limelight-common/Input.h +++ b/limelight-common/Input.h @@ -33,10 +33,10 @@ typedef struct _NV_MOUSE_BUTTON_PACKET { } NV_MOUSE_BUTTON_PACKET, *PNV_MOUSE_BUTTON_PACKET; #define PACKET_TYPE_CONTROLLER 0x18 -#define HEADER_A 0x0000000A -#define HEADER_B 0x1400 -#define TAIL_A 0x0000009C -#define TAIL_B 0x0055 +#define C_HEADER_A 0x0000000A +#define C_HEADER_B 0x1400 +#define C_TAIL_A 0x0000009C +#define C_TAIL_B 0x0055 typedef struct _NV_CONTROLLER_PACKET { NV_INPUT_HEADER header; int headerA; @@ -52,6 +52,31 @@ typedef struct _NV_CONTROLLER_PACKET { short tailB; } NV_CONTROLLER_PACKET, *PNV_CONTROLLER_PACKET; +#define PACKET_TYPE_MULTI_CONTROLLER 0x1E +#define MC_HEADER_A 0x0000000D +#define MC_HEADER_B 0x001A +#define MC_MID_A 0x0007 +#define MC_MID_B 0x0014 +#define MC_TAIL_A 0x0000009C +#define MC_TAIL_B 0x0055 +typedef struct _NV_MULTI_CONTROLLER_PACKET { + NV_INPUT_HEADER header; + int headerA; + short headerB; + short controllerNumber; + short midA; + short midB; + short buttonFlags; + char leftTrigger; + char rightTrigger; + short leftStickX; + short leftStickY; + short rightStickX; + short rightStickY; + int tailA; + short tailB; +} NV_MULTI_CONTROLLER_PACKET, *PNV_MULTI_CONTROLLER_PACKET; + #define PACKET_TYPE_SCROLL 0xA #define MAGIC_A 0x09 typedef struct _NV_SCROLL_PACKET { diff --git a/limelight-common/InputStream.c b/limelight-common/InputStream.c index dee03f1..008e535 100644 --- a/limelight-common/InputStream.c +++ b/limelight-common/InputStream.c @@ -26,6 +26,7 @@ typedef struct _PACKET_HOLDER { NV_MOUSE_MOVE_PACKET mouseMove; NV_MOUSE_BUTTON_PACKET mouseButton; NV_CONTROLLER_PACKET controller; + NV_MULTI_CONTROLLER_PACKET multiController; NV_SCROLL_PACKET scroll; } packet; } PACKET_HOLDER, *PPACKET_HOLDER; @@ -259,41 +260,80 @@ int LiSendKeyboardEvent(short keyCode, char keyAction, char modifiers) { return err; } +static int sendControllerEventInternal(short controllerNumber, short buttonFlags, char leftTrigger, char rightTrigger, + short leftStickX, short leftStickY, short rightStickX, short rightStickY) +{ + PPACKET_HOLDER holder; + int err; + + if (!initialized) { + return -2; + } + + holder = malloc(sizeof(*holder)); + if (holder == NULL) { + return -1; + } + + if (serverMajorVersion == 3) { + // Generation 3 servers don't support multiple controllers so we send + // the legacy packet + holder->packetLength = sizeof(NV_CONTROLLER_PACKET); + holder->packet.controller.header.packetType = htonl(PACKET_TYPE_CONTROLLER); + holder->packet.controller.headerA = C_HEADER_A; + holder->packet.controller.headerB = C_HEADER_B; + holder->packet.controller.buttonFlags = buttonFlags; + holder->packet.controller.leftTrigger = leftTrigger; + holder->packet.controller.rightTrigger = rightTrigger; + holder->packet.controller.leftStickX = leftStickX; + holder->packet.controller.leftStickY = leftStickY; + holder->packet.controller.rightStickX = rightStickX; + holder->packet.controller.rightStickY = rightStickY; + holder->packet.controller.tailA = C_TAIL_A; + holder->packet.controller.tailB = C_TAIL_B; + } + else { + // Generation 4+ servers support passing the controller number + holder->packetLength = sizeof(NV_MULTI_CONTROLLER_PACKET); + holder->packet.multiController.header.packetType = htonl(PACKET_TYPE_MULTI_CONTROLLER); + holder->packet.multiController.headerA = MC_HEADER_A; + holder->packet.multiController.headerB = MC_HEADER_B; + holder->packet.multiController.controllerNumber = controllerNumber; + holder->packet.multiController.midA = MC_MID_A; + holder->packet.multiController.midB = MC_MID_B; + holder->packet.multiController.buttonFlags = buttonFlags; + holder->packet.multiController.leftTrigger = leftTrigger; + holder->packet.multiController.rightTrigger = rightTrigger; + holder->packet.multiController.leftStickX = leftStickX; + holder->packet.multiController.leftStickY = leftStickY; + holder->packet.multiController.rightStickX = rightStickX; + holder->packet.multiController.rightStickY = rightStickY; + holder->packet.multiController.tailA = MC_TAIL_A; + holder->packet.multiController.tailB = MC_TAIL_B; + } + + err = LbqOfferQueueItem(&packetQueue, holder); + if (err != LBQ_SUCCESS) { + free(holder); + } + + return err; +} + /* Send a controller event to the streaming machine */ int LiSendControllerEvent(short buttonFlags, char leftTrigger, char rightTrigger, short leftStickX, short leftStickY, short rightStickX, short rightStickY) { - PPACKET_HOLDER holder; - int err; + return sendControllerEventInternal(0, buttonFlags, leftTrigger, rightTrigger, + leftStickX, leftStickY, rightStickX, rightStickY); +} - if (!initialized) { - return -2; - } - - holder = malloc(sizeof(*holder)); - if (holder == NULL) { - return -1; - } - - holder->packetLength = sizeof(NV_CONTROLLER_PACKET); - holder->packet.controller.header.packetType = htonl(PACKET_TYPE_CONTROLLER); - holder->packet.controller.headerA = HEADER_A; - holder->packet.controller.headerB = HEADER_B; - holder->packet.controller.buttonFlags = buttonFlags; - holder->packet.controller.leftTrigger = leftTrigger; - holder->packet.controller.rightTrigger = rightTrigger; - holder->packet.controller.leftStickX = leftStickX; - holder->packet.controller.leftStickY = leftStickY; - holder->packet.controller.rightStickX = rightStickX; - holder->packet.controller.rightStickY = rightStickY; - holder->packet.controller.tailA = TAIL_A; - holder->packet.controller.tailB = TAIL_B; - err = LbqOfferQueueItem(&packetQueue, holder); - if (err != LBQ_SUCCESS) { - free(holder); - } - - return err; +/* Send a controller event to the streaming machine */ +int LiSendMultiControllerEvent(short controllerNumber, short buttonFlags, char leftTrigger, char rightTrigger, + short leftStickX, short leftStickY, short rightStickX, short rightStickY) +{ + return sendControllerEventInternal(controllerNumber, buttonFlags, leftTrigger, rightTrigger, + leftStickX, leftStickY, rightStickX, rightStickY); } /* Send a scroll event to the streaming machine */ diff --git a/limelight-common/Limelight.h b/limelight-common/Limelight.h index e4f5aa3..d129ff5 100644 --- a/limelight-common/Limelight.h +++ b/limelight-common/Limelight.h @@ -143,6 +143,8 @@ int LiSendKeyboardEvent(short keyCode, char keyAction, char modifiers); #define SPECIAL_FLAG 0x0400 int LiSendControllerEvent(short buttonFlags, char leftTrigger, char rightTrigger, short leftStickX, short leftStickY, short rightStickX, short rightStickY); +int LiSendMultiControllerEvent(short controllerNumber, short buttonFlags, char leftTrigger, char rightTrigger, + short leftStickX, short leftStickY, short rightStickX, short rightStickY); int LiSendScrollEvent(char scrollClicks);