Просмотр исходного кода

Merge pull request #9729 from german77/sdl_input

yuzu_cmd: Fix touch and controller input
liamwhite 3 лет назад
Родитель
Сommit
236b54376d

+ 3 - 0
src/yuzu_cmd/config.cpp

@@ -176,6 +176,9 @@ void Config::ReadValues() {
             Settings::values.debug_pad_analogs[i] = default_param;
     }
 
+    ReadSetting("ControlsGeneral", Settings::values.enable_raw_input);
+    ReadSetting("ControlsGeneral", Settings::values.enable_joycon_driver);
+    ReadSetting("ControlsGeneral", Settings::values.emulate_analog_keyboard);
     ReadSetting("ControlsGeneral", Settings::values.vibration_enabled);
     ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations);
     ReadSetting("ControlsGeneral", Settings::values.motion_enabled);

+ 13 - 0
src/yuzu_cmd/default_ini.h

@@ -14,6 +14,7 @@ const char* sdl2_config_file =
 # Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values
 
 # Indicates if this player should be connected at boot
+# 0 (default): Disabled, 1: Enabled
 connected=
 
 # for button input, the following devices are available:
@@ -94,6 +95,18 @@ motionright=
 # 0 (default): Disabled, 1: Enabled
 debug_pad_enabled =
 
+# Enable sdl raw input. Allows to configure up to 8 xinput controllers.
+# 0 (default): Disabled, 1: Enabled
+enable_raw_input =
+
+# Enable yuzu joycon driver instead of SDL drive.
+# 0: Disabled, 1 (default): Enabled
+enable_joycon_driver =
+
+# Emulates an analog input from buttons. Allowing to dial any angle.
+# 0 (default): Disabled, 1: Enabled
+emulate_analog_keyboard =
+
 # Whether to enable or disable vibration
 # 0: Disabled, 1 (default): Enabled
 vibration_enabled=

+ 18 - 30
src/yuzu_cmd/emu_window/emu_window_sdl2.cpp

@@ -18,11 +18,11 @@
 
 EmuWindow_SDL2::EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_)
     : input_subsystem{input_subsystem_}, system{system_} {
-    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
+    input_subsystem->Initialize();
+    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) {
         LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting...");
         exit(1);
     }
-    input_subsystem->Initialize();
     SDL_SetMainReady();
 }
 
@@ -32,10 +32,6 @@ EmuWindow_SDL2::~EmuWindow_SDL2() {
     SDL_Quit();
 }
 
-void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
-    input_subsystem->GetMouse()->MouseMove(x, y, 0, 0, 0, 0);
-}
-
 InputCommon::MouseButton EmuWindow_SDL2::SDLButtonToMouseButton(u32 button) const {
     switch (button) {
     case SDL_BUTTON_LEFT:
@@ -53,44 +49,36 @@ InputCommon::MouseButton EmuWindow_SDL2::SDLButtonToMouseButton(u32 button) cons
     }
 }
 
+std::pair<float, float> EmuWindow_SDL2::MouseToTouchPos(s32 touch_x, s32 touch_y) const {
+    int w, h;
+    SDL_GetWindowSize(render_window, &w, &h);
+    const float fx = static_cast<float>(touch_x) / w;
+    const float fy = static_cast<float>(touch_y) / h;
+
+    return {std::clamp<float>(fx, 0.0f, 1.0f), std::clamp<float>(fy, 0.0f, 1.0f)};
+}
+
 void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
     const auto mouse_button = SDLButtonToMouseButton(button);
     if (state == SDL_PRESSED) {
-        input_subsystem->GetMouse()->PressButton(x, y, 0, 0, mouse_button);
+        const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
+        input_subsystem->GetMouse()->PressButton(x, y, touch_x, touch_y, mouse_button);
     } else {
         input_subsystem->GetMouse()->ReleaseButton(mouse_button);
     }
 }
 
-std::pair<unsigned, unsigned> EmuWindow_SDL2::TouchToPixelPos(float touch_x, float touch_y) const {
-    int w, h;
-    SDL_GetWindowSize(render_window, &w, &h);
-
-    touch_x *= w;
-    touch_y *= h;
-
-    return {static_cast<unsigned>(std::max(std::round(touch_x), 0.0f)),
-            static_cast<unsigned>(std::max(std::round(touch_y), 0.0f))};
+void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
+    const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
+    input_subsystem->GetMouse()->MouseMove(x, y, touch_x, touch_y, 0, 0);
 }
 
 void EmuWindow_SDL2::OnFingerDown(float x, float y, std::size_t id) {
-    int width, height;
-    SDL_GetWindowSize(render_window, &width, &height);
-    const auto [px, py] = TouchToPixelPos(x, y);
-    const float fx = px * 1.0f / width;
-    const float fy = py * 1.0f / height;
-
-    input_subsystem->GetTouchScreen()->TouchPressed(fx, fy, id);
+    input_subsystem->GetTouchScreen()->TouchPressed(x, y, id);
 }
 
 void EmuWindow_SDL2::OnFingerMotion(float x, float y, std::size_t id) {
-    int width, height;
-    SDL_GetWindowSize(render_window, &width, &height);
-    const auto [px, py] = TouchToPixelPos(x, y);
-    const float fx = px * 1.0f / width;
-    const float fy = py * 1.0f / height;
-
-    input_subsystem->GetTouchScreen()->TouchMoved(fx, fy, id);
+    input_subsystem->GetTouchScreen()->TouchMoved(x, y, id);
 }
 
 void EmuWindow_SDL2::OnFingerUp() {

+ 5 - 5
src/yuzu_cmd/emu_window/emu_window_sdl2.h

@@ -38,17 +38,17 @@ protected:
     /// Called by WaitEvent when a key is pressed or released.
     void OnKeyEvent(int key, u8 state);
 
-    /// Called by WaitEvent when the mouse moves.
-    void OnMouseMotion(s32 x, s32 y);
-
     /// Converts a SDL mouse button into MouseInput mouse button
     InputCommon::MouseButton SDLButtonToMouseButton(u32 button) const;
 
+    /// Translates pixel position to float position
+    std::pair<float, float> MouseToTouchPos(s32 touch_x, s32 touch_y) const;
+
     /// Called by WaitEvent when a mouse button is pressed or released
     void OnMouseButton(u32 button, u8 state, s32 x, s32 y);
 
-    /// Translates pixel position (0..1) to pixel positions
-    std::pair<unsigned, unsigned> TouchToPixelPos(float touch_x, float touch_y) const;
+    /// Called by WaitEvent when the mouse moves.
+    void OnMouseMotion(s32 x, s32 y);
 
     /// Called by WaitEvent when a finger starts touching the touchscreen
     void OnFingerDown(float x, float y, std::size_t id);