Add KeyboardFrontend for switch

This commit is contained in:
Andrey Konoplyankin 2021-04-18 13:16:16 +03:00
parent 3cc64faea5
commit 5fe1a27e58
15 changed files with 297 additions and 201 deletions

View file

@ -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 \

View file

@ -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",

View file

@ -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 = {

View file

@ -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;
}

View file

@ -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);
};

View 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;
};

View 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?
}

View 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);
};

View file

@ -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();

View file

@ -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;

View file

@ -16,6 +16,6 @@ public:
private:
OpusMSDecoder* m_decoder = nullptr;
short* m_buffer = nullptr;
bool m_enable;
bool m_enable = false;
Data m_data;
};