mirror of
https://github.com/rock88/moonlight-nx
synced 2024-11-10 06:14:15 +00:00
Add KeyboardFrontend for switch
This commit is contained in:
parent
3cc64faea5
commit
5fe1a27e58
15 changed files with 297 additions and 201 deletions
10
Makefile
10
Makefile
|
@ -44,7 +44,8 @@ APP_AUTHOR := port by rock88
|
|||
APP_VERSION := 1.2.0
|
||||
BUILD := build
|
||||
SOURCES := src src/libgamestream src/switch src/nanogui_resources src/streaming src/streaming/ffmpeg \
|
||||
src/crypto src/streaming/video src/crypto src/streaming/audio src/ui/windows src/ui/buttons src/ui src/utils src/controls\
|
||||
src/crypto src/streaming/video src/crypto src/streaming/audio src/ui/windows src/ui/buttons src/ui src/utils \
|
||||
src/controls src/controls/switch \
|
||||
third_party/moonlight-common-c/enet third_party/moonlight-common-c/reedsolomon third_party/moonlight-common-c/src \
|
||||
third_party/nanogui/ext/nanovg/src third_party/nanogui/src
|
||||
DATA := data
|
||||
|
@ -65,7 +66,7 @@ ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
|||
M_INCLUDES := \
|
||||
-I$(TOPDIR)/src -I$(TOPDIR)/src/switch -I$(TOPDIR)/src/streaming -I$(TOPDIR)/src/crypto -I$(TOPDIR)/src/crypto/keys \
|
||||
-I$(TOPDIR)/src/streaming/ffmpeg -I$(TOPDIR)/src/streaming/video -I$(TOPDIR)/src/streaming/audio \
|
||||
-I$(TOPDIR)/src/nanogui_resources -I$(TOPDIR)/src/utils -I$(TOPDIR)/src/controls \
|
||||
-I$(TOPDIR)/src/nanogui_resources -I$(TOPDIR)/src/utils -I$(TOPDIR)/src/controls -I$(TOPDIR)/src/controls/switch \
|
||||
-I$(TOPDIR)/src/ui -I$(TOPDIR)/src/ui/buttons -I$(TOPDIR)/src/ui/windows \
|
||||
-I$(TOPDIR)/src/libgamestream \
|
||||
-I$(TOPDIR)/third_party/moonlight-common-c/reedsolomon \
|
||||
|
@ -129,7 +130,10 @@ MOONLIGHT_LIBRETRO_CXX_SOURCES = \
|
|||
MouseController.cpp \
|
||||
KeyboardController.cpp \
|
||||
GamepadController.cpp \
|
||||
StreamControlsController.cpp
|
||||
StreamControlsController.cpp \
|
||||
MouseFrontendSwitch.cpp \
|
||||
KeyboardFrontendSwitch.cpp \
|
||||
GamepadFrontendSwitch.cpp
|
||||
|
||||
MOONLIGHT_COMMON_C_SOURCES = \
|
||||
callbacks.c \
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
28896568262B64CD00139ABE /* MouseFrontendSwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28896566262B64CD00139ABE /* MouseFrontendSwitch.cpp */; };
|
||||
28896570262B6EDD00139ABE /* GamepadFrontendSwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2889656E262B6EDD00139ABE /* GamepadFrontendSwitch.cpp */; };
|
||||
28896584262C343C00139ABE /* GamepadFrontendSwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2889657E262C343C00139ABE /* GamepadFrontendSwitch.cpp */; };
|
||||
28896585262C343C00139ABE /* KeyboardFrontendSwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2889657F262C343C00139ABE /* KeyboardFrontendSwitch.cpp */; };
|
||||
28896586262C343C00139ABE /* MouseFrontendSwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28896580262C343C00139ABE /* MouseFrontendSwitch.cpp */; };
|
||||
28AD4A752606120A009314C6 /* glad.c in Sources */ = {isa = PBXBuildFile; fileRef = 28AD4A722606120A009314C6 /* glad.c */; };
|
||||
3602C3B7245D903000368900 /* HostButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3602C3B5245D903000368900 /* HostButton.cpp */; };
|
||||
3602C3BA245DB3C800368900 /* AppListWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3602C3B8245DB3C800368900 /* AppListWindow.cpp */; };
|
||||
|
@ -143,11 +144,14 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
28896563262B628700139ABE /* MouseFrontend.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MouseFrontend.hpp; sourceTree = "<group>"; };
|
||||
28896566262B64CD00139ABE /* MouseFrontendSwitch.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MouseFrontendSwitch.cpp; sourceTree = "<group>"; };
|
||||
28896567262B64CD00139ABE /* MouseFrontendSwitch.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MouseFrontendSwitch.hpp; sourceTree = "<group>"; };
|
||||
2889656B262B6E0100139ABE /* GamepadFrontend.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = GamepadFrontend.hpp; sourceTree = "<group>"; };
|
||||
2889656E262B6EDD00139ABE /* GamepadFrontendSwitch.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GamepadFrontendSwitch.cpp; sourceTree = "<group>"; };
|
||||
2889656F262B6EDD00139ABE /* GamepadFrontendSwitch.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = GamepadFrontendSwitch.hpp; sourceTree = "<group>"; };
|
||||
28896573262C20C000139ABE /* KeyboardFrontend.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = KeyboardFrontend.hpp; sourceTree = "<group>"; };
|
||||
2889657E262C343C00139ABE /* GamepadFrontendSwitch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GamepadFrontendSwitch.cpp; sourceTree = "<group>"; };
|
||||
2889657F262C343C00139ABE /* KeyboardFrontendSwitch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyboardFrontendSwitch.cpp; sourceTree = "<group>"; };
|
||||
28896580262C343C00139ABE /* MouseFrontendSwitch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MouseFrontendSwitch.cpp; sourceTree = "<group>"; };
|
||||
28896581262C343C00139ABE /* GamepadFrontendSwitch.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GamepadFrontendSwitch.hpp; sourceTree = "<group>"; };
|
||||
28896582262C343C00139ABE /* KeyboardFrontendSwitch.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = KeyboardFrontendSwitch.hpp; sourceTree = "<group>"; };
|
||||
28896583262C343C00139ABE /* MouseFrontendSwitch.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MouseFrontendSwitch.hpp; sourceTree = "<group>"; };
|
||||
28AD4A712606120A009314C6 /* glad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glad.h; sourceTree = "<group>"; };
|
||||
28AD4A722606120A009314C6 /* glad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = glad.c; sourceTree = "<group>"; };
|
||||
28AD4A742606120A009314C6 /* khrplatform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = khrplatform.h; sourceTree = "<group>"; };
|
||||
|
@ -394,6 +398,19 @@
|
|||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
2889657D262C343C00139ABE /* switch */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
28896580262C343C00139ABE /* MouseFrontendSwitch.cpp */,
|
||||
28896583262C343C00139ABE /* MouseFrontendSwitch.hpp */,
|
||||
2889657F262C343C00139ABE /* KeyboardFrontendSwitch.cpp */,
|
||||
28896582262C343C00139ABE /* KeyboardFrontendSwitch.hpp */,
|
||||
2889657E262C343C00139ABE /* GamepadFrontendSwitch.cpp */,
|
||||
28896581262C343C00139ABE /* GamepadFrontendSwitch.hpp */,
|
||||
);
|
||||
path = switch;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
28AD4A702606120A009314C6 /* glad */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -450,20 +467,18 @@
|
|||
3620418A25D7F00500D21EE3 /* controls */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2889657D262C343C00139ABE /* switch */,
|
||||
362041A025D94D7700D21EE3 /* StreamControlsController.cpp */,
|
||||
362041A125D94D7700D21EE3 /* StreamControlsController.hpp */,
|
||||
3620418B25D7F04400D21EE3 /* MouseController.cpp */,
|
||||
3620418C25D7F04400D21EE3 /* MouseController.hpp */,
|
||||
28896563262B628700139ABE /* MouseFrontend.hpp */,
|
||||
28896566262B64CD00139ABE /* MouseFrontendSwitch.cpp */,
|
||||
28896567262B64CD00139ABE /* MouseFrontendSwitch.hpp */,
|
||||
3620419625D85B5F00D21EE3 /* KeyboardController.cpp */,
|
||||
3620419725D85B5F00D21EE3 /* KeyboardController.hpp */,
|
||||
28896573262C20C000139ABE /* KeyboardFrontend.hpp */,
|
||||
362041A925D9BE4900D21EE3 /* GamepadController.cpp */,
|
||||
362041AA25D9BE4900D21EE3 /* GamepadController.hpp */,
|
||||
2889656B262B6E0100139ABE /* GamepadFrontend.hpp */,
|
||||
2889656E262B6EDD00139ABE /* GamepadFrontendSwitch.cpp */,
|
||||
2889656F262B6EDD00139ABE /* GamepadFrontendSwitch.hpp */,
|
||||
3689D6DB249154F90008CB75 /* GamepadMapper.cpp */,
|
||||
3689D6DC249154F90008CB75 /* GamepadMapper.hpp */,
|
||||
);
|
||||
|
@ -1009,13 +1024,11 @@
|
|||
3652F075245C292B001FABF3 /* VideoStream.c in Sources */,
|
||||
3652EFE0245B3B00001FABF3 /* imageview.cpp in Sources */,
|
||||
3652EFDB245B3B00001FABF3 /* texture.cpp in Sources */,
|
||||
28896568262B64CD00139ABE /* MouseFrontendSwitch.cpp in Sources */,
|
||||
36A0C03D2461F03C0083289C /* Settings.cpp in Sources */,
|
||||
36BFCCF82479725900245D40 /* main.cpp in Sources */,
|
||||
3652F079245C292B001FABF3 /* RtpReorderQueue.c in Sources */,
|
||||
36BFCCF12479723E00245D40 /* xml.cpp in Sources */,
|
||||
3652F065245C292B001FABF3 /* list.c in Sources */,
|
||||
28896570262B6EDD00139ABE /* GamepadFrontendSwitch.cpp in Sources */,
|
||||
3620418D25D7F04400D21EE3 /* MouseController.cpp in Sources */,
|
||||
36DFE0CD2459FA3F00FC51CE /* nanogui_resources.cpp in Sources */,
|
||||
36DDACF824929919001133D1 /* InputSettingsWindow.cpp in Sources */,
|
||||
|
@ -1047,6 +1060,7 @@
|
|||
3652F067245C292B001FABF3 /* packet.c in Sources */,
|
||||
3661D2F92469D1940060EE24 /* FFmpegVideoDecoder.cpp in Sources */,
|
||||
363898342471B7C500F99920 /* MbedTLSCryptoManager.cpp in Sources */,
|
||||
28896586262C343C00139ABE /* MouseFrontendSwitch.cpp in Sources */,
|
||||
3652F072245C292B001FABF3 /* RtspConnection.c in Sources */,
|
||||
36BFCCF22479723E00245D40 /* client.cpp in Sources */,
|
||||
3678EF732476D9DA0097345D /* DebugFileRecorderAudioRenderer.cpp in Sources */,
|
||||
|
@ -1063,6 +1077,7 @@
|
|||
367D2D7424829A0800A946F4 /* LogsWindow.cpp in Sources */,
|
||||
36A0C03A2461E4C00083289C /* SettingsWindow.cpp in Sources */,
|
||||
3652EFD4245B3B00001FABF3 /* shader_gl.cpp in Sources */,
|
||||
28896585262C343C00139ABE /* KeyboardFrontendSwitch.cpp in Sources */,
|
||||
3602C3BD245DBA9100368900 /* AppButton.cpp in Sources */,
|
||||
36BFCCF32479723E00245D40 /* http.cpp in Sources */,
|
||||
36D3F8442469B5C400CDEF9B /* MoonlightSession.cpp in Sources */,
|
||||
|
@ -1107,6 +1122,7 @@
|
|||
3652F078245C292B001FABF3 /* FakeCallbacks.c in Sources */,
|
||||
3652F06B245C292B001FABF3 /* host.c in Sources */,
|
||||
3602C3BA245DB3C800368900 /* AppListWindow.cpp in Sources */,
|
||||
28896584262C343C00139ABE /* GamepadFrontendSwitch.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1213,9 +1229,7 @@
|
|||
"-lcurl",
|
||||
"-lexpat",
|
||||
"-lavcodec",
|
||||
"-lavformat",
|
||||
"-lavutil",
|
||||
"-lavdevice",
|
||||
"-lz",
|
||||
"-lopus",
|
||||
"-lmbedtls",
|
||||
|
@ -1304,9 +1318,7 @@
|
|||
"-lcurl",
|
||||
"-lexpat",
|
||||
"-lavcodec",
|
||||
"-lavformat",
|
||||
"-lavutil",
|
||||
"-lavdevice",
|
||||
"-lz",
|
||||
"-lopus",
|
||||
"-lmbedtls",
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
#include "Limelight.h"
|
||||
#include <jansson.h>
|
||||
#include <nanogui/opengl.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <vector>
|
||||
|
||||
static inline int button_to_moonlight_button(int button) {
|
||||
static std::map<int, int> map = {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "Logger.hpp"
|
||||
#include <nanogui/opengl.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <switch.h>
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
|
||||
#define VK_0 0x30
|
||||
|
@ -68,155 +67,28 @@ KeyboardState::KeyboardState() {
|
|||
keys.push_back({.codes = KeyCodes(GLFW_KEY_DOWN, -1, -1, 0x28) });
|
||||
}
|
||||
|
||||
static int find_glfw_key_index(int key, KeyboardState& state) {
|
||||
for (int i = 0; i < state.keys.size(); i++) {
|
||||
if (state.keys[i].codes.glfw_keycode == key) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int find_switch_key_index(int key, KeyboardState& state) {
|
||||
if (KBD_A <= key && key <= KBD_Z) {
|
||||
return find_glfw_key_index(key - KBD_A + GLFW_KEY_A, state);
|
||||
} else if (KBD_1 <= key && key <= KBD_9) {
|
||||
return find_glfw_key_index(key - KBD_1 + GLFW_KEY_1, state);
|
||||
} else if (KBD_F1 <= key && key <= KBD_F12) {
|
||||
return find_glfw_key_index(key - KBD_F1 + GLFW_KEY_F1, state);
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case KBD_0: return find_glfw_key_index(GLFW_KEY_0, state);
|
||||
case KBD_SPACE: return find_glfw_key_index(GLFW_KEY_SPACE, state);
|
||||
case KBD_APOSTROPHE: return find_glfw_key_index(GLFW_KEY_APOSTROPHE, state);
|
||||
case KBD_COMMA: return find_glfw_key_index(GLFW_KEY_COMMA, state);
|
||||
case KBD_MINUS: return find_glfw_key_index(GLFW_KEY_MINUS, state);
|
||||
case KBD_DOT: return find_glfw_key_index(GLFW_KEY_PERIOD, state);
|
||||
case KBD_SLASH: return find_glfw_key_index(GLFW_KEY_SLASH, state);
|
||||
case KBD_SEMICOLON: return find_glfw_key_index(GLFW_KEY_SEMICOLON, state);
|
||||
case KBD_EQUAL: return find_glfw_key_index(GLFW_KEY_EQUAL, state);
|
||||
case KBD_LEFTBRACE: return find_glfw_key_index(GLFW_KEY_LEFT_BRACKET, state);
|
||||
case KBD_RIGHTBRACE: return find_glfw_key_index(GLFW_KEY_RIGHT_BRACKET, state);
|
||||
case KBD_BACKSLASH: return find_glfw_key_index(GLFW_KEY_BACKSLASH, state);
|
||||
case KBD_GRAVE: return find_glfw_key_index(GLFW_KEY_GRAVE_ACCENT, state);
|
||||
case KBD_ESC: return find_glfw_key_index(GLFW_KEY_ESCAPE, state);
|
||||
case KBD_ENTER: return find_glfw_key_index(GLFW_KEY_ENTER, state);
|
||||
case KBD_TAB: return find_glfw_key_index(GLFW_KEY_TAB, state);
|
||||
case KBD_BACKSPACE: return find_glfw_key_index(GLFW_KEY_BACKSPACE, state);
|
||||
case KBD_CAPSLOCK: return find_glfw_key_index(GLFW_KEY_CAPS_LOCK, state);
|
||||
case KBD_LEFTSHIFT: return find_glfw_key_index(GLFW_KEY_LEFT_SHIFT, state);
|
||||
case KBD_LEFTCTRL: return find_glfw_key_index(GLFW_KEY_LEFT_CONTROL, state);
|
||||
case KBD_LEFTALT: return find_glfw_key_index(GLFW_KEY_LEFT_ALT, state);
|
||||
case KBD_LEFTMETA: return find_glfw_key_index(GLFW_KEY_LEFT_SUPER, state);
|
||||
case KBD_RIGHTSHIFT: return find_glfw_key_index(GLFW_KEY_RIGHT_SHIFT, state);
|
||||
case KBD_RIGHTCTRL: return find_glfw_key_index(GLFW_KEY_RIGHT_CONTROL, state);
|
||||
case KBD_RIGHTALT: return find_glfw_key_index(GLFW_KEY_RIGHT_ALT, state);
|
||||
case KBD_RIGHTMETA: return find_glfw_key_index(GLFW_KEY_RIGHT_SUPER, state);
|
||||
case KBD_LEFT: return find_glfw_key_index(GLFW_KEY_LEFT, state);
|
||||
case KBD_RIGHT: return find_glfw_key_index(GLFW_KEY_RIGHT, state);
|
||||
case KBD_UP: return find_glfw_key_index(GLFW_KEY_UP, state);
|
||||
case KBD_DOWN: return find_glfw_key_index(GLFW_KEY_DOWN, state);
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardController::init(GLFWwindow* window) {
|
||||
hidInitializeKeyboard();
|
||||
|
||||
glfwSetKeyCallback(window, [](GLFWwindow *w, int key, int scancode, int action, int mods) {
|
||||
#ifndef __SWITCH__
|
||||
KeyboardController::instance().handle_key(key, scancode, action, mods);
|
||||
#endif
|
||||
});
|
||||
|
||||
glfwSetCharCallback(window, [](GLFWwindow *w, auto input) {
|
||||
#ifndef __SWITCH__
|
||||
KeyboardController::instance().handle_char(input);
|
||||
#endif
|
||||
});
|
||||
|
||||
m_hid_keyboard_state.assign(256, false);
|
||||
void KeyboardController::init(KeyboardFrontend* frontend) {
|
||||
m_frontend = frontend;
|
||||
}
|
||||
|
||||
void KeyboardController::handle_keyboard() {
|
||||
HidKeyboardState state;
|
||||
m_frontend->handle_keyboard();
|
||||
|
||||
if (hidGetKeyboardStates(&state, 1)) {
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
auto is_pressed = (state.keys[i / 64] & (1ul << (i % 64))) != 0;
|
||||
|
||||
if (m_hid_keyboard_state[i] != is_pressed) {
|
||||
int index = find_switch_key_index(i, m_keyboard_state);
|
||||
|
||||
if (index != -1) {
|
||||
if (is_pressed) {
|
||||
if ((state.modifiers & HidKeyboardModifier_Shift) && m_keyboard_state.keys[index].codes.glfw_shift_char_code != -1) {
|
||||
handle_char(m_keyboard_state.keys[index].codes.glfw_shift_char_code);
|
||||
} else if (m_keyboard_state.keys[index].codes.glfw_char_code != -1) {
|
||||
handle_char(m_keyboard_state.keys[index].codes.glfw_char_code);
|
||||
}
|
||||
}
|
||||
|
||||
int mods = 0;
|
||||
|
||||
if (state.modifiers & HidKeyboardModifier_Shift) {
|
||||
mods |= GLFW_MOD_SHIFT;
|
||||
}
|
||||
|
||||
if (state.modifiers & HidKeyboardModifier_Control) {
|
||||
mods |= GLFW_MOD_CONTROL;
|
||||
}
|
||||
|
||||
if ((state.modifiers & HidKeyboardModifier_LeftAlt) || (state.modifiers & HidKeyboardModifier_RightAlt)) {
|
||||
mods |= GLFW_MOD_ALT;
|
||||
}
|
||||
|
||||
handle_key(m_keyboard_state.keys[index].codes.glfw_keycode, 0, is_pressed ? GLFW_PRESS : GLFW_RELEASE, mods);
|
||||
auto state = m_frontend->keyboard_state();
|
||||
|
||||
for (int i = 0; i < state.keys.size(); i++) {
|
||||
if (state.keys[i].is_pressed != m_keyboard_state.keys[i].is_pressed) {
|
||||
if (state.keys[i].is_pressed && state.keys[i].codes.glfw_char_code != -1) {
|
||||
if (state.glfw_modifiers & GLFW_MOD_SHIFT && state.keys[i].codes.glfw_shift_char_code != -1) {
|
||||
nanogui::keyboard_character_event(state.keys[i].codes.glfw_shift_char_code);
|
||||
} else {
|
||||
Logger::info("Keyboard", "Unhandled HID keyboard key: 0x%X", i);
|
||||
nanogui::keyboard_character_event(state.keys[i].codes.glfw_char_code);
|
||||
}
|
||||
|
||||
m_hid_keyboard_state[i] = is_pressed;
|
||||
}
|
||||
|
||||
nanogui::keyboard_callback_event(state.keys[i].codes.glfw_keycode, 0, state.keys[i].is_pressed, state.glfw_modifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardController::handle_key(int key, int scancode, int action, int mods) {
|
||||
nanogui::keyboard_callback_event(key, scancode, action, mods);
|
||||
|
||||
int index = find_glfw_key_index(key, m_keyboard_state);
|
||||
|
||||
if (index >= 0) {
|
||||
m_keyboard_state.keys[index].is_pressed = action != 0;
|
||||
} else {
|
||||
Logger::info("Keyboard", "Unhandled GLFW key: %i", key);
|
||||
}
|
||||
|
||||
m_keyboard_state.glfw_modifiers = mods;
|
||||
|
||||
short moonlight_modifiers = 0;
|
||||
|
||||
if (mods & GLFW_MOD_SHIFT) {
|
||||
moonlight_modifiers |= MODIFIER_SHIFT;
|
||||
}
|
||||
|
||||
if (mods & GLFW_MOD_CONTROL) {
|
||||
moonlight_modifiers |= MODIFIER_CTRL;
|
||||
}
|
||||
|
||||
if (mods & GLFW_MOD_ALT) {
|
||||
moonlight_modifiers |= MODIFIER_ALT;
|
||||
}
|
||||
|
||||
if (mods & GLFW_MOD_SUPER) {
|
||||
moonlight_modifiers |= MODIFIER_META;
|
||||
}
|
||||
|
||||
m_keyboard_state.moonlight_modifiers = moonlight_modifiers;
|
||||
}
|
||||
|
||||
void KeyboardController::handle_char(unsigned int input) {
|
||||
nanogui::keyboard_character_event(input);
|
||||
|
||||
m_keyboard_state = state;
|
||||
}
|
||||
|
|
|
@ -1,35 +1,10 @@
|
|||
#include "Singleton.hpp"
|
||||
#include <vector>
|
||||
#include "KeyboardFrontend.hpp"
|
||||
#pragma once
|
||||
|
||||
struct GLFWwindow;
|
||||
|
||||
struct KeyCodes {
|
||||
KeyCodes(short glfw_keycode = 0, short glfw_char_code = 0, short glfw_shift_char_code = 0, short moonlight_keycode = 0);
|
||||
|
||||
short glfw_keycode;
|
||||
short glfw_char_code;
|
||||
short glfw_shift_char_code;
|
||||
|
||||
short moonlight_keycode;
|
||||
};
|
||||
|
||||
struct KeyState {
|
||||
KeyCodes codes;
|
||||
bool is_pressed = false;
|
||||
};
|
||||
|
||||
struct KeyboardState {
|
||||
KeyboardState();
|
||||
|
||||
std::vector<KeyState> keys;
|
||||
int glfw_modifiers = 0;
|
||||
short moonlight_modifiers = 0;
|
||||
};
|
||||
|
||||
class KeyboardController: public Singleton<KeyboardController> {
|
||||
public:
|
||||
void init(GLFWwindow* window);
|
||||
void init(KeyboardFrontend* frontend);
|
||||
void handle_keyboard();
|
||||
|
||||
const KeyboardState& keyboard_state() {
|
||||
|
@ -37,9 +12,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
KeyboardFrontend* m_frontend;
|
||||
KeyboardState m_keyboard_state;
|
||||
std::vector<bool> m_hid_keyboard_state;
|
||||
|
||||
void handle_key(int key, int scancode, int action, int mods);
|
||||
void handle_char(unsigned int input);
|
||||
};
|
||||
|
|
32
src/controls/KeyboardFrontend.hpp
Normal file
32
src/controls/KeyboardFrontend.hpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include <vector>
|
||||
#pragma once
|
||||
|
||||
// TODO: Move glfw stuff out...
|
||||
struct KeyCodes {
|
||||
KeyCodes(short glfw_keycode = 0, short glfw_char_code = 0, short glfw_shift_char_code = 0, short moonlight_keycode = 0);
|
||||
|
||||
short glfw_keycode;
|
||||
short glfw_char_code;
|
||||
short glfw_shift_char_code;
|
||||
|
||||
short moonlight_keycode;
|
||||
};
|
||||
|
||||
struct KeyState {
|
||||
KeyCodes codes;
|
||||
bool is_pressed = false;
|
||||
};
|
||||
|
||||
struct KeyboardState {
|
||||
KeyboardState();
|
||||
|
||||
std::vector<KeyState> keys;
|
||||
int glfw_modifiers = 0;
|
||||
short moonlight_modifiers = 0;
|
||||
};
|
||||
|
||||
class KeyboardFrontend {
|
||||
public:
|
||||
virtual void handle_keyboard() = 0;
|
||||
virtual const KeyboardState& keyboard_state() = 0;
|
||||
};
|
160
src/controls/switch/KeyboardFrontendSwitch.cpp
Normal file
160
src/controls/switch/KeyboardFrontendSwitch.cpp
Normal file
|
@ -0,0 +1,160 @@
|
|||
#include "KeyboardFrontendSwitch.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include "Limelight.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <switch.h>
|
||||
|
||||
static KeyboardFrontendSwitch* m_frontend = NULL;
|
||||
|
||||
static inline int find_glfw_key_index(int key, KeyboardState& state) {
|
||||
for (int i = 0; i < state.keys.size(); i++) {
|
||||
if (state.keys[i].codes.glfw_keycode == key) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int find_switch_key_index(int key, KeyboardState& state) {
|
||||
if (KBD_A <= key && key <= KBD_Z) {
|
||||
return find_glfw_key_index(key - KBD_A + GLFW_KEY_A, state);
|
||||
} else if (KBD_1 <= key && key <= KBD_9) {
|
||||
return find_glfw_key_index(key - KBD_1 + GLFW_KEY_1, state);
|
||||
} else if (KBD_F1 <= key && key <= KBD_F12) {
|
||||
return find_glfw_key_index(key - KBD_F1 + GLFW_KEY_F1, state);
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case KBD_0: return find_glfw_key_index(GLFW_KEY_0, state);
|
||||
case KBD_SPACE: return find_glfw_key_index(GLFW_KEY_SPACE, state);
|
||||
case KBD_APOSTROPHE: return find_glfw_key_index(GLFW_KEY_APOSTROPHE, state);
|
||||
case KBD_COMMA: return find_glfw_key_index(GLFW_KEY_COMMA, state);
|
||||
case KBD_MINUS: return find_glfw_key_index(GLFW_KEY_MINUS, state);
|
||||
case KBD_DOT: return find_glfw_key_index(GLFW_KEY_PERIOD, state);
|
||||
case KBD_SLASH: return find_glfw_key_index(GLFW_KEY_SLASH, state);
|
||||
case KBD_SEMICOLON: return find_glfw_key_index(GLFW_KEY_SEMICOLON, state);
|
||||
case KBD_EQUAL: return find_glfw_key_index(GLFW_KEY_EQUAL, state);
|
||||
case KBD_LEFTBRACE: return find_glfw_key_index(GLFW_KEY_LEFT_BRACKET, state);
|
||||
case KBD_RIGHTBRACE: return find_glfw_key_index(GLFW_KEY_RIGHT_BRACKET, state);
|
||||
case KBD_BACKSLASH: return find_glfw_key_index(GLFW_KEY_BACKSLASH, state);
|
||||
case KBD_GRAVE: return find_glfw_key_index(GLFW_KEY_GRAVE_ACCENT, state);
|
||||
case KBD_ESC: return find_glfw_key_index(GLFW_KEY_ESCAPE, state);
|
||||
case KBD_ENTER: return find_glfw_key_index(GLFW_KEY_ENTER, state);
|
||||
case KBD_TAB: return find_glfw_key_index(GLFW_KEY_TAB, state);
|
||||
case KBD_BACKSPACE: return find_glfw_key_index(GLFW_KEY_BACKSPACE, state);
|
||||
case KBD_CAPSLOCK: return find_glfw_key_index(GLFW_KEY_CAPS_LOCK, state);
|
||||
case KBD_LEFTSHIFT: return find_glfw_key_index(GLFW_KEY_LEFT_SHIFT, state);
|
||||
case KBD_LEFTCTRL: return find_glfw_key_index(GLFW_KEY_LEFT_CONTROL, state);
|
||||
case KBD_LEFTALT: return find_glfw_key_index(GLFW_KEY_LEFT_ALT, state);
|
||||
case KBD_LEFTMETA: return find_glfw_key_index(GLFW_KEY_LEFT_SUPER, state);
|
||||
case KBD_RIGHTSHIFT: return find_glfw_key_index(GLFW_KEY_RIGHT_SHIFT, state);
|
||||
case KBD_RIGHTCTRL: return find_glfw_key_index(GLFW_KEY_RIGHT_CONTROL, state);
|
||||
case KBD_RIGHTALT: return find_glfw_key_index(GLFW_KEY_RIGHT_ALT, state);
|
||||
case KBD_RIGHTMETA: return find_glfw_key_index(GLFW_KEY_RIGHT_SUPER, state);
|
||||
case KBD_LEFT: return find_glfw_key_index(GLFW_KEY_LEFT, state);
|
||||
case KBD_RIGHT: return find_glfw_key_index(GLFW_KEY_RIGHT, state);
|
||||
case KBD_UP: return find_glfw_key_index(GLFW_KEY_UP, state);
|
||||
case KBD_DOWN: return find_glfw_key_index(GLFW_KEY_DOWN, state);
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
KeyboardFrontendSwitch::KeyboardFrontendSwitch(GLFWwindow* window) {
|
||||
m_frontend = this;
|
||||
|
||||
hidInitializeKeyboard();
|
||||
|
||||
glfwSetKeyCallback(window, [](GLFWwindow *w, int key, int scancode, int action, int mods) {
|
||||
#ifndef __SWITCH__
|
||||
m_frontend->handle_key(key, scancode, action, mods);
|
||||
#endif
|
||||
});
|
||||
|
||||
glfwSetCharCallback(window, [](GLFWwindow *w, auto input) {
|
||||
#ifndef __SWITCH__
|
||||
m_frontend->handle_char(input);
|
||||
#endif
|
||||
});
|
||||
|
||||
m_hid_keyboard_state.assign(256, false);
|
||||
}
|
||||
|
||||
void KeyboardFrontendSwitch::handle_keyboard() {
|
||||
HidKeyboardState state;
|
||||
|
||||
if (hidGetKeyboardStates(&state, 1)) {
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
auto is_pressed = (state.keys[i / 64] & (1ul << (i % 64))) != 0;
|
||||
|
||||
if (m_hid_keyboard_state[i] != is_pressed) {
|
||||
int index = find_switch_key_index(i, m_keyboard_state);
|
||||
|
||||
if (index != -1) {
|
||||
if (is_pressed) {
|
||||
if ((state.modifiers & HidKeyboardModifier_Shift) && m_keyboard_state.keys[index].codes.glfw_shift_char_code != -1) {
|
||||
handle_char(m_keyboard_state.keys[index].codes.glfw_shift_char_code);
|
||||
} else if (m_keyboard_state.keys[index].codes.glfw_char_code != -1) {
|
||||
handle_char(m_keyboard_state.keys[index].codes.glfw_char_code);
|
||||
}
|
||||
}
|
||||
|
||||
int mods = 0;
|
||||
|
||||
if (state.modifiers & HidKeyboardModifier_Shift) {
|
||||
mods |= GLFW_MOD_SHIFT;
|
||||
}
|
||||
|
||||
if (state.modifiers & HidKeyboardModifier_Control) {
|
||||
mods |= GLFW_MOD_CONTROL;
|
||||
}
|
||||
|
||||
if ((state.modifiers & HidKeyboardModifier_LeftAlt) || (state.modifiers & HidKeyboardModifier_RightAlt)) {
|
||||
mods |= GLFW_MOD_ALT;
|
||||
}
|
||||
|
||||
handle_key(m_keyboard_state.keys[index].codes.glfw_keycode, 0, is_pressed ? GLFW_PRESS : GLFW_RELEASE, mods);
|
||||
} else {
|
||||
Logger::info("Keyboard", "Unhandled HID keyboard key: 0x%X", i);
|
||||
}
|
||||
|
||||
m_hid_keyboard_state[i] = is_pressed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardFrontendSwitch::handle_key(int key, int scancode, int action, int mods) {
|
||||
int index = find_glfw_key_index(key, m_keyboard_state);
|
||||
|
||||
if (index >= 0) {
|
||||
m_keyboard_state.keys[index].is_pressed = action != 0;
|
||||
} else {
|
||||
Logger::info("Keyboard", "Unhandled GLFW key: %i", key);
|
||||
}
|
||||
|
||||
m_keyboard_state.glfw_modifiers = mods;
|
||||
|
||||
short moonlight_modifiers = 0;
|
||||
|
||||
if (mods & GLFW_MOD_SHIFT) {
|
||||
moonlight_modifiers |= MODIFIER_SHIFT;
|
||||
}
|
||||
|
||||
if (mods & GLFW_MOD_CONTROL) {
|
||||
moonlight_modifiers |= MODIFIER_CTRL;
|
||||
}
|
||||
|
||||
if (mods & GLFW_MOD_ALT) {
|
||||
moonlight_modifiers |= MODIFIER_ALT;
|
||||
}
|
||||
|
||||
if (mods & GLFW_MOD_SUPER) {
|
||||
moonlight_modifiers |= MODIFIER_META;
|
||||
}
|
||||
|
||||
m_keyboard_state.moonlight_modifiers = moonlight_modifiers;
|
||||
}
|
||||
|
||||
void KeyboardFrontendSwitch::handle_char(unsigned int input) {
|
||||
// TODO: no needs anymore?
|
||||
}
|
22
src/controls/switch/KeyboardFrontendSwitch.hpp
Normal file
22
src/controls/switch/KeyboardFrontendSwitch.hpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include "KeyboardFrontend.hpp"
|
||||
#pragma once
|
||||
|
||||
struct GLFWwindow;
|
||||
|
||||
class KeyboardFrontendSwitch: public KeyboardFrontend {
|
||||
public:
|
||||
KeyboardFrontendSwitch(GLFWwindow* window);
|
||||
|
||||
void handle_keyboard();
|
||||
|
||||
const KeyboardState& keyboard_state() {
|
||||
return m_keyboard_state;
|
||||
}
|
||||
|
||||
private:
|
||||
KeyboardState m_keyboard_state;
|
||||
std::vector<bool> m_hid_keyboard_state;
|
||||
|
||||
void handle_key(int key, int scancode, int action, int mods);
|
||||
void handle_char(unsigned int input);
|
||||
};
|
|
@ -8,6 +8,7 @@
|
|||
#include "MouseController.hpp"
|
||||
#include "MouseFrontendSwitch.hpp"
|
||||
#include "KeyboardController.hpp"
|
||||
#include "KeyboardFrontendSwitch.hpp"
|
||||
#include "GamepadController.hpp"
|
||||
#include "GamepadFrontendSwitch.hpp"
|
||||
#include <glad/glad.h>
|
||||
|
@ -66,7 +67,7 @@ int main(int argc, const char * argv[]) {
|
|||
GameStreamClient::instance().start();
|
||||
|
||||
MouseController::instance().init(new MouseFrontendSwitch(window));
|
||||
KeyboardController::instance().init(window);
|
||||
KeyboardController::instance().init(new KeyboardFrontendSwitch(window));
|
||||
GamepadController::instance().init(new GamepadFrontendSwitch());
|
||||
|
||||
nanogui::init();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "GameStreamClient.hpp"
|
||||
#include "Settings.hpp"
|
||||
#include "WakeOnLanManager.hpp"
|
||||
#include <nanogui/nanogui.h>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <algorithm>
|
||||
|
@ -8,9 +9,15 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <future>
|
||||
#include <nanogui/nanogui.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include <switch.h>
|
||||
#endif
|
||||
|
||||
static std::mutex m_async_mutex;
|
||||
static std::vector<std::function<void()>> m_tasks;
|
||||
|
@ -78,10 +85,26 @@ void GameStreamClient::stop() {
|
|||
|
||||
std::vector<std::string> GameStreamClient::host_addresses_for_find() {
|
||||
std::vector<std::string> addresses;
|
||||
u32 address;
|
||||
Result result = nifmGetCurrentIpAddress(&address);
|
||||
uint32_t address = 0;
|
||||
|
||||
if (R_SUCCEEDED(result)) {
|
||||
#ifdef __SWITCH__
|
||||
Result result = nifmGetCurrentIpAddress(&address);
|
||||
bool isSucceed = R_SUCCEEDED(result);
|
||||
#else
|
||||
struct ifreq ifr;
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
strncpy(ifr.ifr_name, "en0", IFNAMSIZ - 1);
|
||||
|
||||
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
ioctl(fd, SIOCGIFADDR, &ifr);
|
||||
close(fd);
|
||||
|
||||
address = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
|
||||
|
||||
bool isSucceed = true;
|
||||
#endif
|
||||
|
||||
if (isSucceed) {
|
||||
int a = address & 0xFF;
|
||||
int b = (address >> 8) & 0xFF;
|
||||
int c = (address >> 16) & 0xFF;
|
||||
|
|
|
@ -16,6 +16,6 @@ public:
|
|||
private:
|
||||
OpusMSDecoder* m_decoder = nullptr;
|
||||
short* m_buffer = nullptr;
|
||||
bool m_enable;
|
||||
bool m_enable = false;
|
||||
Data m_data;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue