mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-06-18 06:41:06 +00:00
Fix excessive high-res scroll speed on newer GFE versions
This commit is contained in:
+77
-18
@@ -4,6 +4,8 @@ static SOCKET inputSock = INVALID_SOCKET;
|
|||||||
static unsigned char currentAesIv[16];
|
static unsigned char currentAesIv[16];
|
||||||
static bool initialized;
|
static bool initialized;
|
||||||
static bool encryptedControlStream;
|
static bool encryptedControlStream;
|
||||||
|
static bool needsBatchedScroll;
|
||||||
|
static int batchedScrollDelta;
|
||||||
static PPLT_CRYPTO_CONTEXT cryptoContext;
|
static PPLT_CRYPTO_CONTEXT cryptoContext;
|
||||||
|
|
||||||
static LINKED_BLOCKING_QUEUE packetQueue;
|
static LINKED_BLOCKING_QUEUE packetQueue;
|
||||||
@@ -18,6 +20,9 @@ static PLT_THREAD inputSendThread;
|
|||||||
#define PAYLOAD_SIZE(x) BE32((x)->packet.header.size)
|
#define PAYLOAD_SIZE(x) BE32((x)->packet.header.size)
|
||||||
#define PACKET_SIZE(x) (PAYLOAD_SIZE(x) + sizeof(uint32_t))
|
#define PACKET_SIZE(x) (PAYLOAD_SIZE(x) + sizeof(uint32_t))
|
||||||
|
|
||||||
|
// Matches Win32 WHEEL_DELTA definition
|
||||||
|
#define LI_WHEEL_DELTA 120
|
||||||
|
|
||||||
// Contains input stream packets
|
// Contains input stream packets
|
||||||
typedef struct _PACKET_HOLDER {
|
typedef struct _PACKET_HOLDER {
|
||||||
LINKED_BLOCKING_QUEUE_ENTRY entry;
|
LINKED_BLOCKING_QUEUE_ENTRY entry;
|
||||||
@@ -50,6 +55,13 @@ int initializeInputStream(void) {
|
|||||||
|
|
||||||
cryptoContext = PltCreateCryptoContext();
|
cryptoContext = PltCreateCryptoContext();
|
||||||
encryptedControlStream = APP_VERSION_AT_LEAST(7, 1, 431);
|
encryptedControlStream = APP_VERSION_AT_LEAST(7, 1, 431);
|
||||||
|
|
||||||
|
// FIXME: Unsure if this is exactly right, but it's probably good enough.
|
||||||
|
//
|
||||||
|
// GFE 3.13.1.30 is not using NVVHCI for mouse/keyboard (and is confirmed unaffected)
|
||||||
|
// GFE 3.15.0.164 seems to be the first release using NVVHCI for mouse/keyboard
|
||||||
|
needsBatchedScroll = APP_VERSION_AT_LEAST(7, 1, 409);
|
||||||
|
batchedScrollDelta = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,27 +832,74 @@ int LiSendHighResScrollEvent(short scrollAmount) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
holder = allocatePacketHolder(0);
|
// Newer version of GFE that use virtual HID devices have a bug that requires
|
||||||
if (holder == NULL) {
|
// the scroll events to be batched to WHEEL_DELTA. Due to the their HID report
|
||||||
return -1;
|
// descriptor, they don't actually support smooth scrolling. _Any_ scroll gets
|
||||||
}
|
// converted into a full WHEEL_DELTA scroll, even if the actual delta is tiny.
|
||||||
|
// Similarly, large scrolls are capped at +/- WHEEL_DELTA too so we'll need to
|
||||||
|
// split those up too.
|
||||||
|
if (needsBatchedScroll) {
|
||||||
|
if ((batchedScrollDelta < 0 && scrollAmount > 0) ||
|
||||||
|
(batchedScrollDelta > 0 && scrollAmount < 0)) {
|
||||||
|
// Reset the accumulated scroll delta when the direction changes
|
||||||
|
// FIXME: Maybe reset accumulated delta based on time too?
|
||||||
|
batchedScrollDelta = 0;
|
||||||
|
}
|
||||||
|
|
||||||
holder->packet.scroll.header.size = BE32(sizeof(NV_SCROLL_PACKET) - sizeof(uint32_t));
|
batchedScrollDelta += scrollAmount;
|
||||||
if (AppVersionQuad[0] >= 5) {
|
|
||||||
holder->packet.scroll.header.magic = LE32(SCROLL_MAGIC_GEN5);
|
while (abs(batchedScrollDelta) >= LI_WHEEL_DELTA) {
|
||||||
|
scrollAmount = batchedScrollDelta > 0 ? LI_WHEEL_DELTA : -LI_WHEEL_DELTA;
|
||||||
|
|
||||||
|
holder = allocatePacketHolder(0);
|
||||||
|
if (holder == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
holder->packet.scroll.header.size = BE32(sizeof(NV_SCROLL_PACKET) - sizeof(uint32_t));
|
||||||
|
if (AppVersionQuad[0] >= 5) {
|
||||||
|
holder->packet.scroll.header.magic = LE32(SCROLL_MAGIC_GEN5);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
holder->packet.scroll.header.magic = LE32(SCROLL_MAGIC);
|
||||||
|
}
|
||||||
|
holder->packet.scroll.scrollAmt1 = BE16(scrollAmount);
|
||||||
|
holder->packet.scroll.scrollAmt2 = holder->packet.scroll.scrollAmt1;
|
||||||
|
holder->packet.scroll.zero3 = 0;
|
||||||
|
|
||||||
|
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
|
||||||
|
if (err != LBQ_SUCCESS) {
|
||||||
|
LC_ASSERT(err == LBQ_BOUND_EXCEEDED);
|
||||||
|
Limelog("Input queue reached maximum size limit\n");
|
||||||
|
freePacketHolder(holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
batchedScrollDelta -= scrollAmount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
holder->packet.scroll.header.magic = LE32(SCROLL_MAGIC);
|
holder = allocatePacketHolder(0);
|
||||||
}
|
if (holder == NULL) {
|
||||||
holder->packet.scroll.scrollAmt1 = BE16(scrollAmount);
|
return -1;
|
||||||
holder->packet.scroll.scrollAmt2 = holder->packet.scroll.scrollAmt1;
|
}
|
||||||
holder->packet.scroll.zero3 = 0;
|
|
||||||
|
|
||||||
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
|
holder->packet.scroll.header.size = BE32(sizeof(NV_SCROLL_PACKET) - sizeof(uint32_t));
|
||||||
if (err != LBQ_SUCCESS) {
|
if (AppVersionQuad[0] >= 5) {
|
||||||
LC_ASSERT(err == LBQ_BOUND_EXCEEDED);
|
holder->packet.scroll.header.magic = LE32(SCROLL_MAGIC_GEN5);
|
||||||
Limelog("Input queue reached maximum size limit\n");
|
}
|
||||||
freePacketHolder(holder);
|
else {
|
||||||
|
holder->packet.scroll.header.magic = LE32(SCROLL_MAGIC);
|
||||||
|
}
|
||||||
|
holder->packet.scroll.scrollAmt1 = BE16(scrollAmount);
|
||||||
|
holder->packet.scroll.scrollAmt2 = holder->packet.scroll.scrollAmt1;
|
||||||
|
holder->packet.scroll.zero3 = 0;
|
||||||
|
|
||||||
|
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
|
||||||
|
if (err != LBQ_SUCCESS) {
|
||||||
|
LC_ASSERT(err == LBQ_BOUND_EXCEEDED);
|
||||||
|
Limelog("Input queue reached maximum size limit\n");
|
||||||
|
freePacketHolder(holder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@@ -848,5 +907,5 @@ int LiSendHighResScrollEvent(short scrollAmount) {
|
|||||||
|
|
||||||
// Send a scroll event to the streaming machine
|
// Send a scroll event to the streaming machine
|
||||||
int LiSendScrollEvent(signed char scrollClicks) {
|
int LiSendScrollEvent(signed char scrollClicks) {
|
||||||
return LiSendHighResScrollEvent(scrollClicks * 120);
|
return LiSendHighResScrollEvent(scrollClicks * LI_WHEEL_DELTA);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user