mirror of
https://github.com/rock88/moonlight-nx
synced 2024-11-22 03:23:07 +00:00
Add USB mouse support
This commit is contained in:
parent
535708f91f
commit
352d2093f2
5 changed files with 190 additions and 72 deletions
|
@ -319,6 +319,7 @@
|
|||
36BFCCF42479724900245D40 /* GameStreamClient.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GameStreamClient.hpp; sourceTree = "<group>"; };
|
||||
36BFCCF52479724900245D40 /* GameStreamClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GameStreamClient.cpp; sourceTree = "<group>"; };
|
||||
36BFCCF72479725900245D40 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
||||
36CF721D25D038C700878A8E /* switch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = switch.h; sourceTree = "<group>"; };
|
||||
36D3F8422469B5C400CDEF9B /* MoonlightSession.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MoonlightSession.cpp; sourceTree = "<group>"; };
|
||||
36D3F8432469B5C400CDEF9B /* MoonlightSession.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MoonlightSession.hpp; sourceTree = "<group>"; };
|
||||
36D3F8492469CC2600CDEF9B /* IAudioRenderer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = IAudioRenderer.hpp; sourceTree = "<group>"; };
|
||||
|
@ -653,6 +654,7 @@
|
|||
36DFDCF12459F79000FC51CE /* ui */,
|
||||
36D3F8462469C8DD00CDEF9B /* streaming */,
|
||||
36F1646E2474736E00D70AD9 /* switch */,
|
||||
36CF721C25D038C700878A8E /* switch_support */,
|
||||
364A6A8D24786E2200460028 /* BoxArtManager.cpp */,
|
||||
364A6A8E24786E2200460028 /* BoxArtManager.hpp */,
|
||||
36A0C03B2461F03C0083289C /* Settings.cpp */,
|
||||
|
@ -682,6 +684,14 @@
|
|||
path = libgamestream;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
36CF721C25D038C700878A8E /* switch_support */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
36CF721D25D038C700878A8E /* switch.h */,
|
||||
);
|
||||
path = switch_support;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
36D3F8462469C8DD00CDEF9B /* streaming */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1093,6 +1103,7 @@
|
|||
"\"$(SRCROOT)/third_party/moonlight-common-c/enet/include\"",
|
||||
"\"$(SRCROOT)/third_party/moonlight-common-c/src\"",
|
||||
"\"$(SRCROOT)/src/switch\"",
|
||||
"\"$(SRCROOT)/src/switch_support\"",
|
||||
/opt/devkitpro/libnx/include2,
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = /usr/local/lib;
|
||||
|
@ -1185,6 +1196,7 @@
|
|||
"\"$(SRCROOT)/third_party/moonlight-common-c/enet/include\"",
|
||||
"\"$(SRCROOT)/third_party/moonlight-common-c/src\"",
|
||||
"\"$(SRCROOT)/src/switch\"",
|
||||
"\"$(SRCROOT)/src/switch_support\"",
|
||||
/opt/devkitpro/libnx/include2,
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = /usr/local/lib;
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
#include <nanogui/nanogui.h>
|
||||
#include <nanogui/opengl.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <switch.h>
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include <switch.h>
|
||||
static HidVibrationDeviceHandle VibrationDeviceHandles[2][2];
|
||||
static HidVibrationValue VibrationValues[2];
|
||||
static HidVibrationValue VibrationValue_stop;
|
||||
|
@ -167,87 +167,119 @@ bool InputController::gamepad_trigger_is_enabled(int trigger) {
|
|||
return glfw_gamepad_state.axes[trigger] > 0;
|
||||
}
|
||||
|
||||
void InputController::send_to_stream() {
|
||||
// Mouse
|
||||
void InputController::send_mouse_to_stream() {
|
||||
static bool is_pressed = false, is_released = false;
|
||||
static bool l_is_pressed = false, r_is_pressed = false;
|
||||
static int last_mouse_x = 0, last_mouse_y = 0;
|
||||
static int last_send_mouse_x = 0, last_send_mouse_y = 0;
|
||||
|
||||
if (mouse_state.is_pressed && !is_pressed) {
|
||||
is_pressed = true;
|
||||
last_mouse_x = mouse_state.x;
|
||||
last_mouse_y = mouse_state.y;
|
||||
} else if (!mouse_state.is_pressed && is_pressed) {
|
||||
is_pressed = false;
|
||||
}
|
||||
HidMouseState mouseState;
|
||||
|
||||
if (Settings::settings()->click_by_tap()) {
|
||||
if (last_send_mouse_x != mouse_state.x || last_send_mouse_y != mouse_state.y) {
|
||||
LiSendMousePositionEvent(mouse_state.x, mouse_state.y, m_width, m_height);
|
||||
last_send_mouse_x = mouse_state.x;
|
||||
last_send_mouse_y = mouse_state.y;
|
||||
if (hidGetMouseStates(&mouseState, 1) > 0 && (mouseState.attributes & HidMouseAttribute_IsConnected)) {
|
||||
if (last_send_mouse_x != mouseState.x || last_send_mouse_y != mouseState.y) {
|
||||
LiSendMousePositionEvent(mouseState.x, mouseState.y, m_width, m_height);
|
||||
last_send_mouse_x = mouseState.x;
|
||||
last_send_mouse_y = mouseState.y;
|
||||
}
|
||||
|
||||
if (gamepad_button_is_enabled(NANOGUI_GAMEPAD_BUTTON_RIGHT_BUMPER) || gamepad_trigger_is_enabled(NANOGUI_GAMEPAD_AXIS_RIGHT_TRIGGER)) {
|
||||
if (mouse_state.is_pressed) {
|
||||
is_released = false;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT);
|
||||
} else if (!is_released) {
|
||||
is_released = true;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
|
||||
}
|
||||
} else {
|
||||
if (mouse_state.is_pressed) {
|
||||
is_released = false;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
|
||||
} else if (!is_released) {
|
||||
is_released = true;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
||||
}
|
||||
if ((mouseState.buttons & HidMouseButton_Left) && !l_is_pressed) {
|
||||
l_is_pressed = true;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
|
||||
} else if (!(mouseState.buttons & HidMouseButton_Left) && l_is_pressed) {
|
||||
l_is_pressed = false;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
||||
}
|
||||
|
||||
if ((mouseState.buttons & HidMouseButton_Right) && !r_is_pressed) {
|
||||
r_is_pressed = true;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT);
|
||||
} else if (!(mouseState.buttons & HidMouseButton_Right) && r_is_pressed) {
|
||||
r_is_pressed = false;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
|
||||
}
|
||||
|
||||
// Why wheel_delta_x?
|
||||
if (mouseState.wheel_delta_x != 0) {
|
||||
LiSendScrollEvent(mouseState.wheel_delta_x);
|
||||
}
|
||||
} else {
|
||||
bool move_mouse = !gamepad_trigger_is_enabled(NANOGUI_GAMEPAD_AXIS_LEFT_TRIGGER) && !gamepad_trigger_is_enabled(NANOGUI_GAMEPAD_AXIS_RIGHT_TRIGGER);
|
||||
if (mouse_state.is_pressed && !is_pressed) {
|
||||
is_pressed = true;
|
||||
last_mouse_x = mouse_state.x;
|
||||
last_mouse_y = mouse_state.y;
|
||||
} else if (!mouse_state.is_pressed && is_pressed) {
|
||||
is_pressed = false;
|
||||
}
|
||||
|
||||
if (move_mouse) {
|
||||
int relative_mouse_x = mouse_state.x - last_mouse_x;
|
||||
int relative_mouse_y = mouse_state.y - last_mouse_y;
|
||||
if (Settings::settings()->click_by_tap()) {
|
||||
if (last_send_mouse_x != mouse_state.x || last_send_mouse_y != mouse_state.y) {
|
||||
LiSendMousePositionEvent(mouse_state.x, mouse_state.y, m_width, m_height);
|
||||
last_send_mouse_x = mouse_state.x;
|
||||
last_send_mouse_y = mouse_state.y;
|
||||
}
|
||||
|
||||
if (relative_mouse_x != last_send_mouse_x || relative_mouse_y != last_send_mouse_y) {
|
||||
LiSendMouseMoveEvent(relative_mouse_x, relative_mouse_y);
|
||||
last_send_mouse_x = relative_mouse_x;
|
||||
last_send_mouse_y = relative_mouse_y;
|
||||
if (gamepad_button_is_enabled(NANOGUI_GAMEPAD_BUTTON_RIGHT_BUMPER) || gamepad_trigger_is_enabled(NANOGUI_GAMEPAD_AXIS_RIGHT_TRIGGER)) {
|
||||
if (mouse_state.is_pressed) {
|
||||
is_released = false;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT);
|
||||
} else if (!is_released) {
|
||||
is_released = true;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
|
||||
}
|
||||
} else {
|
||||
if (mouse_state.is_pressed) {
|
||||
is_released = false;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
|
||||
} else if (!is_released) {
|
||||
is_released = true;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool move_mouse = !gamepad_trigger_is_enabled(NANOGUI_GAMEPAD_AXIS_LEFT_TRIGGER) && !gamepad_trigger_is_enabled(NANOGUI_GAMEPAD_AXIS_RIGHT_TRIGGER);
|
||||
|
||||
if (move_mouse) {
|
||||
int relative_mouse_x = mouse_state.x - last_mouse_x;
|
||||
int relative_mouse_y = mouse_state.y - last_mouse_y;
|
||||
|
||||
if (relative_mouse_x != last_send_mouse_x || relative_mouse_y != last_send_mouse_y) {
|
||||
LiSendMouseMoveEvent(relative_mouse_x, relative_mouse_y);
|
||||
last_send_mouse_x = relative_mouse_x;
|
||||
last_send_mouse_y = relative_mouse_y;
|
||||
}
|
||||
}
|
||||
|
||||
last_mouse_x = mouse_state.x;
|
||||
last_mouse_y = mouse_state.y;
|
||||
|
||||
if (gamepad_button_is_enabled(NANOGUI_GAMEPAD_BUTTON_LEFT_BUMPER) || gamepad_trigger_is_enabled(NANOGUI_GAMEPAD_AXIS_LEFT_TRIGGER)) {
|
||||
if (mouse_state.is_pressed) {
|
||||
is_released = false;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
|
||||
} else if (!is_released) {
|
||||
is_released = true;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
||||
}
|
||||
} else if (gamepad_button_is_enabled(NANOGUI_GAMEPAD_BUTTON_RIGHT_BUMPER) || gamepad_trigger_is_enabled(NANOGUI_GAMEPAD_AXIS_RIGHT_TRIGGER)) {
|
||||
if (mouse_state.is_pressed) {
|
||||
is_released = false;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT);
|
||||
} else if (!is_released) {
|
||||
is_released = true;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last_mouse_x = mouse_state.x;
|
||||
last_mouse_y = mouse_state.y;
|
||||
|
||||
if (gamepad_button_is_enabled(NANOGUI_GAMEPAD_BUTTON_LEFT_BUMPER) || gamepad_trigger_is_enabled(NANOGUI_GAMEPAD_AXIS_LEFT_TRIGGER)) {
|
||||
if (mouse_state.is_pressed) {
|
||||
is_released = false;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
|
||||
} else if (!is_released) {
|
||||
is_released = true;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
||||
}
|
||||
} else if (gamepad_button_is_enabled(NANOGUI_GAMEPAD_BUTTON_RIGHT_BUMPER) || gamepad_trigger_is_enabled(NANOGUI_GAMEPAD_AXIS_RIGHT_TRIGGER)) {
|
||||
if (mouse_state.is_pressed) {
|
||||
is_released = false;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT);
|
||||
} else if (!is_released) {
|
||||
is_released = true;
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
|
||||
}
|
||||
// Scroll
|
||||
if (m_scroll_y != 0) {
|
||||
LiSendHighResScrollEvent(m_scroll_y > 0 ? fmax(m_scroll_y, 1) : fmin(m_scroll_y, -1));
|
||||
m_scroll_y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll
|
||||
if (m_scroll_y != 0) {
|
||||
LiSendHighResScrollEvent(m_scroll_y > 0 ? fmax(m_scroll_y, 1) : fmin(m_scroll_y, -1));
|
||||
m_scroll_y = 0;
|
||||
}
|
||||
|
||||
// Keyboard
|
||||
}
|
||||
|
||||
void InputController::send_keyboard_to_stream() {
|
||||
static bool send_alt_enter = false;
|
||||
|
||||
if (!send_alt_enter && gamepad_combo_is_enabled(GamepadComboAltEnter)) {
|
||||
|
@ -267,8 +299,9 @@ void InputController::send_to_stream() {
|
|||
send_escape = false;
|
||||
LiSendKeyboardEvent(0x1B, KEY_ACTION_UP, 0);
|
||||
}
|
||||
|
||||
// Gamepad
|
||||
}
|
||||
|
||||
void InputController::send_gamepad_to_stream() {
|
||||
auto mapped_gamepad = GamepadMapper::mapper()->map(glfw_gamepad_state);
|
||||
short buttonFlags = 0;
|
||||
unsigned char leftTrigger = 0xFFFF * (mapped_gamepad.axes[GLFW_GAMEPAD_AXIS_LEFT_TRIGGER] + 1) / 2;
|
||||
|
|
|
@ -20,11 +20,19 @@ public:
|
|||
|
||||
bool gamepad_combo_is_enabled(GamepadCombo combo);
|
||||
|
||||
void send_to_stream();
|
||||
void send_to_stream() {
|
||||
send_mouse_to_stream();
|
||||
send_keyboard_to_stream();
|
||||
send_gamepad_to_stream();
|
||||
}
|
||||
|
||||
private:
|
||||
InputController();
|
||||
|
||||
void send_mouse_to_stream();
|
||||
void send_keyboard_to_stream();
|
||||
void send_gamepad_to_stream();
|
||||
|
||||
bool gamepad_button_is_enabled(int button);
|
||||
bool gamepad_trigger_is_enabled(int trigger);
|
||||
};
|
||||
|
|
|
@ -7,10 +7,7 @@
|
|||
#include "GameStreamClient.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include <glad/glad.h>
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include <switch.h>
|
||||
#endif
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
|
@ -80,6 +77,8 @@ int main(int argc, const char * argv[]) {
|
|||
InputController::controller()->handle_keyboard_event(key, scancode, action, mods);
|
||||
});
|
||||
|
||||
hidInitializeMouse();
|
||||
|
||||
nanogui::init();
|
||||
nanogui::ref<Application> app = new Application(Size(m_width, m_height), Size(m_fb_width, m_fb_height));
|
||||
|
||||
|
|
66
src/switch_support/switch.h
Normal file
66
src/switch_support/switch.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
// Some mock part of libnx stuff for import and use <switch.h> on others plaforms
|
||||
|
||||
typedef uint8_t u8; ///< 8-bit unsigned integer.
|
||||
typedef uint16_t u16; ///< 16-bit unsigned integer.
|
||||
typedef uint32_t u32; ///< 32-bit unsigned integer.
|
||||
typedef uint64_t u64; ///< 64-bit unsigned integer.
|
||||
typedef __uint128_t u128; ///< 128-bit unsigned integer.
|
||||
|
||||
typedef int8_t s8; ///< 8-bit signed integer.
|
||||
typedef int16_t s16; ///< 16-bit signed integer.
|
||||
typedef int32_t s32; ///< 32-bit signed integer.
|
||||
typedef int64_t s64; ///< 64-bit signed integer.
|
||||
typedef __int128_t s128; ///< 128-bit unsigned integer.
|
||||
|
||||
typedef volatile u8 vu8; ///< 8-bit volatile unsigned integer.
|
||||
typedef volatile u16 vu16; ///< 16-bit volatile unsigned integer.
|
||||
typedef volatile u32 vu32; ///< 32-bit volatile unsigned integer.
|
||||
typedef volatile u64 vu64; ///< 64-bit volatile unsigned integer.
|
||||
typedef volatile u128 vu128; ///< 128-bit volatile unsigned integer.
|
||||
|
||||
typedef volatile s8 vs8; ///< 8-bit volatile signed integer.
|
||||
typedef volatile s16 vs16; ///< 16-bit volatile signed integer.
|
||||
typedef volatile s32 vs32; ///< 32-bit volatile signed integer.
|
||||
typedef volatile s64 vs64; ///< 64-bit volatile signed integer.
|
||||
typedef volatile s128 vs128; ///< 128-bit volatile signed integer.
|
||||
|
||||
typedef u32 Handle; ///< Kernel object handle.
|
||||
typedef u32 Result; ///< Function error code result type.
|
||||
|
||||
/// Checks whether a result code indicates success.
|
||||
#define R_SUCCEEDED(res) ((res)==0)
|
||||
/// Checks whether a result code indicates failure.
|
||||
#define R_FAILED(res) ((res)!=0)
|
||||
|
||||
#define BIT(n) (1U<<(n))
|
||||
|
||||
typedef struct HidMouseState {
|
||||
u64 sampling_number; ///< SamplingNumber
|
||||
s32 x; ///< X
|
||||
s32 y; ///< Y
|
||||
s32 delta_x; ///< DeltaX
|
||||
s32 delta_y; ///< DeltaY
|
||||
s32 wheel_delta_x; ///< WheelDeltaX
|
||||
s32 wheel_delta_y; ///< WheelDeltaY
|
||||
u32 buttons; ///< Bitfield of \ref HidMouseButton.
|
||||
u32 attributes; ///< Bitfield of \ref HidMouseAttribute.
|
||||
} HidMouseState;
|
||||
|
||||
typedef enum {
|
||||
HidMouseAttribute_Transferable = BIT(0), ///< Transferable
|
||||
HidMouseAttribute_IsConnected = BIT(1), ///< IsConnected
|
||||
} HidMouseAttribute;
|
||||
|
||||
typedef enum {
|
||||
HidMouseButton_Left = BIT(0),
|
||||
HidMouseButton_Right = BIT(1),
|
||||
HidMouseButton_Middle = BIT(2),
|
||||
HidMouseButton_Forward = BIT(3),
|
||||
HidMouseButton_Back = BIT(4),
|
||||
} HidMouseButton;
|
||||
|
||||
static void hidInitializeMouse(void) {};
|
||||
|
||||
static size_t hidGetMouseStates(HidMouseState *states, size_t count) {
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue