mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #4939 from german77/MouseInput
InputCommon: Implement full mouse support
This commit is contained in:
		
						commit
						7bc3e80399
					
				@ -163,10 +163,15 @@ using MotionStatus = std::tuple<Common::Vec3<float>, Common::Vec3<float>, Common
 | 
				
			|||||||
using MotionDevice = InputDevice<MotionStatus>;
 | 
					using MotionDevice = InputDevice<MotionStatus>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A touch device is an input device that returns a tuple of two floats and a bool. The floats are
 | 
					 * A touch status is an object that returns a tuple of two floats and a bool. The floats are
 | 
				
			||||||
 * x and y coordinates in the range 0.0 - 1.0, and the bool indicates whether it is pressed.
 | 
					 * x and y coordinates in the range 0.0 - 1.0, and the bool indicates whether it is pressed.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
using TouchDevice = InputDevice<std::tuple<float, float, bool>>;
 | 
					using TouchStatus = std::tuple<float, float, bool>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A touch device is an input device that returns a touch status object
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					using TouchDevice = InputDevice<TouchStatus>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A mouse device is an input device that returns a tuple of two floats and four ints.
 | 
					 * A mouse device is an input device that returns a tuple of two floats and four ints.
 | 
				
			||||||
 | 
				
			|||||||
@ -5,8 +5,6 @@ add_library(input_common STATIC
 | 
				
			|||||||
    keyboard.h
 | 
					    keyboard.h
 | 
				
			||||||
    main.cpp
 | 
					    main.cpp
 | 
				
			||||||
    main.h
 | 
					    main.h
 | 
				
			||||||
    motion_emu.cpp
 | 
					 | 
				
			||||||
    motion_emu.h
 | 
					 | 
				
			||||||
    motion_from_button.cpp
 | 
					    motion_from_button.cpp
 | 
				
			||||||
    motion_from_button.h
 | 
					    motion_from_button.h
 | 
				
			||||||
    motion_input.cpp
 | 
					    motion_input.cpp
 | 
				
			||||||
@ -19,6 +17,10 @@ add_library(input_common STATIC
 | 
				
			|||||||
    gcadapter/gc_adapter.h
 | 
					    gcadapter/gc_adapter.h
 | 
				
			||||||
    gcadapter/gc_poller.cpp
 | 
					    gcadapter/gc_poller.cpp
 | 
				
			||||||
    gcadapter/gc_poller.h
 | 
					    gcadapter/gc_poller.h
 | 
				
			||||||
 | 
					    mouse/mouse_input.cpp
 | 
				
			||||||
 | 
					    mouse/mouse_input.h
 | 
				
			||||||
 | 
					    mouse/mouse_poller.cpp
 | 
				
			||||||
 | 
					    mouse/mouse_poller.h
 | 
				
			||||||
    sdl/sdl.cpp
 | 
					    sdl/sdl.cpp
 | 
				
			||||||
    sdl/sdl.h
 | 
					    sdl/sdl.h
 | 
				
			||||||
    udp/client.cpp
 | 
					    udp/client.cpp
 | 
				
			||||||
 | 
				
			|||||||
@ -10,8 +10,9 @@
 | 
				
			|||||||
#include "input_common/gcadapter/gc_poller.h"
 | 
					#include "input_common/gcadapter/gc_poller.h"
 | 
				
			||||||
#include "input_common/keyboard.h"
 | 
					#include "input_common/keyboard.h"
 | 
				
			||||||
#include "input_common/main.h"
 | 
					#include "input_common/main.h"
 | 
				
			||||||
#include "input_common/motion_emu.h"
 | 
					 | 
				
			||||||
#include "input_common/motion_from_button.h"
 | 
					#include "input_common/motion_from_button.h"
 | 
				
			||||||
 | 
					#include "input_common/mouse/mouse_input.h"
 | 
				
			||||||
 | 
					#include "input_common/mouse/mouse_poller.h"
 | 
				
			||||||
#include "input_common/touch_from_button.h"
 | 
					#include "input_common/touch_from_button.h"
 | 
				
			||||||
#include "input_common/udp/client.h"
 | 
					#include "input_common/udp/client.h"
 | 
				
			||||||
#include "input_common/udp/udp.h"
 | 
					#include "input_common/udp/udp.h"
 | 
				
			||||||
@ -37,8 +38,6 @@ struct InputSubsystem::Impl {
 | 
				
			|||||||
                                                    std::make_shared<AnalogFromButton>());
 | 
					                                                    std::make_shared<AnalogFromButton>());
 | 
				
			||||||
        Input::RegisterFactory<Input::MotionDevice>("keyboard",
 | 
					        Input::RegisterFactory<Input::MotionDevice>("keyboard",
 | 
				
			||||||
                                                    std::make_shared<MotionFromButton>());
 | 
					                                                    std::make_shared<MotionFromButton>());
 | 
				
			||||||
        motion_emu = std::make_shared<MotionEmu>();
 | 
					 | 
				
			||||||
        Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu);
 | 
					 | 
				
			||||||
        Input::RegisterFactory<Input::TouchDevice>("touch_from_button",
 | 
					        Input::RegisterFactory<Input::TouchDevice>("touch_from_button",
 | 
				
			||||||
                                                   std::make_shared<TouchFromButtonFactory>());
 | 
					                                                   std::make_shared<TouchFromButtonFactory>());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -51,6 +50,16 @@ struct InputSubsystem::Impl {
 | 
				
			|||||||
        Input::RegisterFactory<Input::MotionDevice>("cemuhookudp", udpmotion);
 | 
					        Input::RegisterFactory<Input::MotionDevice>("cemuhookudp", udpmotion);
 | 
				
			||||||
        udptouch = std::make_shared<UDPTouchFactory>(udp);
 | 
					        udptouch = std::make_shared<UDPTouchFactory>(udp);
 | 
				
			||||||
        Input::RegisterFactory<Input::TouchDevice>("cemuhookudp", udptouch);
 | 
					        Input::RegisterFactory<Input::TouchDevice>("cemuhookudp", udptouch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mouse = std::make_shared<MouseInput::Mouse>();
 | 
				
			||||||
 | 
					        mousebuttons = std::make_shared<MouseButtonFactory>(mouse);
 | 
				
			||||||
 | 
					        Input::RegisterFactory<Input::ButtonDevice>("mouse", mousebuttons);
 | 
				
			||||||
 | 
					        mouseanalog = std::make_shared<MouseAnalogFactory>(mouse);
 | 
				
			||||||
 | 
					        Input::RegisterFactory<Input::AnalogDevice>("mouse", mouseanalog);
 | 
				
			||||||
 | 
					        mousemotion = std::make_shared<MouseMotionFactory>(mouse);
 | 
				
			||||||
 | 
					        Input::RegisterFactory<Input::MotionDevice>("mouse", mousemotion);
 | 
				
			||||||
 | 
					        mousetouch = std::make_shared<MouseTouchFactory>(mouse);
 | 
				
			||||||
 | 
					        Input::RegisterFactory<Input::TouchDevice>("mouse", mousetouch);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Shutdown() {
 | 
					    void Shutdown() {
 | 
				
			||||||
@ -58,8 +67,6 @@ struct InputSubsystem::Impl {
 | 
				
			|||||||
        Input::UnregisterFactory<Input::MotionDevice>("keyboard");
 | 
					        Input::UnregisterFactory<Input::MotionDevice>("keyboard");
 | 
				
			||||||
        keyboard.reset();
 | 
					        keyboard.reset();
 | 
				
			||||||
        Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button");
 | 
					        Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button");
 | 
				
			||||||
        Input::UnregisterFactory<Input::MotionDevice>("motion_emu");
 | 
					 | 
				
			||||||
        motion_emu.reset();
 | 
					 | 
				
			||||||
        Input::UnregisterFactory<Input::TouchDevice>("touch_from_button");
 | 
					        Input::UnregisterFactory<Input::TouchDevice>("touch_from_button");
 | 
				
			||||||
#ifdef HAVE_SDL2
 | 
					#ifdef HAVE_SDL2
 | 
				
			||||||
        sdl.reset();
 | 
					        sdl.reset();
 | 
				
			||||||
@ -77,6 +84,16 @@ struct InputSubsystem::Impl {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        udpmotion.reset();
 | 
					        udpmotion.reset();
 | 
				
			||||||
        udptouch.reset();
 | 
					        udptouch.reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Input::UnregisterFactory<Input::ButtonDevice>("mouse");
 | 
				
			||||||
 | 
					        Input::UnregisterFactory<Input::AnalogDevice>("mouse");
 | 
				
			||||||
 | 
					        Input::UnregisterFactory<Input::MotionDevice>("mouse");
 | 
				
			||||||
 | 
					        Input::UnregisterFactory<Input::TouchDevice>("mouse");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mousebuttons.reset();
 | 
				
			||||||
 | 
					        mouseanalog.reset();
 | 
				
			||||||
 | 
					        mousemotion.reset();
 | 
				
			||||||
 | 
					        mousetouch.reset();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const {
 | 
					    [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const {
 | 
				
			||||||
@ -140,7 +157,6 @@ struct InputSubsystem::Impl {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::shared_ptr<Keyboard> keyboard;
 | 
					    std::shared_ptr<Keyboard> keyboard;
 | 
				
			||||||
    std::shared_ptr<MotionEmu> motion_emu;
 | 
					 | 
				
			||||||
#ifdef HAVE_SDL2
 | 
					#ifdef HAVE_SDL2
 | 
				
			||||||
    std::unique_ptr<SDL::State> sdl;
 | 
					    std::unique_ptr<SDL::State> sdl;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -149,8 +165,13 @@ struct InputSubsystem::Impl {
 | 
				
			|||||||
    std::shared_ptr<GCVibrationFactory> gcvibration;
 | 
					    std::shared_ptr<GCVibrationFactory> gcvibration;
 | 
				
			||||||
    std::shared_ptr<UDPMotionFactory> udpmotion;
 | 
					    std::shared_ptr<UDPMotionFactory> udpmotion;
 | 
				
			||||||
    std::shared_ptr<UDPTouchFactory> udptouch;
 | 
					    std::shared_ptr<UDPTouchFactory> udptouch;
 | 
				
			||||||
 | 
					    std::shared_ptr<MouseButtonFactory> mousebuttons;
 | 
				
			||||||
 | 
					    std::shared_ptr<MouseAnalogFactory> mouseanalog;
 | 
				
			||||||
 | 
					    std::shared_ptr<MouseMotionFactory> mousemotion;
 | 
				
			||||||
 | 
					    std::shared_ptr<MouseTouchFactory> mousetouch;
 | 
				
			||||||
    std::shared_ptr<CemuhookUDP::Client> udp;
 | 
					    std::shared_ptr<CemuhookUDP::Client> udp;
 | 
				
			||||||
    std::shared_ptr<GCAdapter::Adapter> gcadapter;
 | 
					    std::shared_ptr<GCAdapter::Adapter> gcadapter;
 | 
				
			||||||
 | 
					    std::shared_ptr<MouseInput::Mouse> mouse;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {}
 | 
					InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {}
 | 
				
			||||||
@ -173,12 +194,12 @@ const Keyboard* InputSubsystem::GetKeyboard() const {
 | 
				
			|||||||
    return impl->keyboard.get();
 | 
					    return impl->keyboard.get();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MotionEmu* InputSubsystem::GetMotionEmu() {
 | 
					MouseInput::Mouse* InputSubsystem::GetMouse() {
 | 
				
			||||||
    return impl->motion_emu.get();
 | 
					    return impl->mouse.get();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const MotionEmu* InputSubsystem::GetMotionEmu() const {
 | 
					const MouseInput::Mouse* InputSubsystem::GetMouse() const {
 | 
				
			||||||
    return impl->motion_emu.get();
 | 
					    return impl->mouse.get();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
 | 
					std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
 | 
				
			||||||
@ -229,6 +250,38 @@ const UDPTouchFactory* InputSubsystem::GetUDPTouch() const {
 | 
				
			|||||||
    return impl->udptouch.get();
 | 
					    return impl->udptouch.get();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MouseButtonFactory* InputSubsystem::GetMouseButtons() {
 | 
				
			||||||
 | 
					    return impl->mousebuttons.get();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const MouseButtonFactory* InputSubsystem::GetMouseButtons() const {
 | 
				
			||||||
 | 
					    return impl->mousebuttons.get();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MouseAnalogFactory* InputSubsystem::GetMouseAnalogs() {
 | 
				
			||||||
 | 
					    return impl->mouseanalog.get();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const MouseAnalogFactory* InputSubsystem::GetMouseAnalogs() const {
 | 
				
			||||||
 | 
					    return impl->mouseanalog.get();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MouseMotionFactory* InputSubsystem::GetMouseMotions() {
 | 
				
			||||||
 | 
					    return impl->mousemotion.get();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const MouseMotionFactory* InputSubsystem::GetMouseMotions() const {
 | 
				
			||||||
 | 
					    return impl->mousemotion.get();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MouseTouchFactory* InputSubsystem::GetMouseTouch() {
 | 
				
			||||||
 | 
					    return impl->mousetouch.get();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const MouseTouchFactory* InputSubsystem::GetMouseTouch() const {
 | 
				
			||||||
 | 
					    return impl->mousetouch.get();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void InputSubsystem::ReloadInputDevices() {
 | 
					void InputSubsystem::ReloadInputDevices() {
 | 
				
			||||||
    if (!impl->udp) {
 | 
					    if (!impl->udp) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,10 @@ namespace Settings::NativeMotion {
 | 
				
			|||||||
enum Values : int;
 | 
					enum Values : int;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MouseInput {
 | 
				
			||||||
 | 
					class Mouse;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace InputCommon {
 | 
					namespace InputCommon {
 | 
				
			||||||
namespace Polling {
 | 
					namespace Polling {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -56,8 +60,11 @@ class GCAnalogFactory;
 | 
				
			|||||||
class GCButtonFactory;
 | 
					class GCButtonFactory;
 | 
				
			||||||
class UDPMotionFactory;
 | 
					class UDPMotionFactory;
 | 
				
			||||||
class UDPTouchFactory;
 | 
					class UDPTouchFactory;
 | 
				
			||||||
 | 
					class MouseButtonFactory;
 | 
				
			||||||
 | 
					class MouseAnalogFactory;
 | 
				
			||||||
 | 
					class MouseMotionFactory;
 | 
				
			||||||
 | 
					class MouseTouchFactory;
 | 
				
			||||||
class Keyboard;
 | 
					class Keyboard;
 | 
				
			||||||
class MotionEmu;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Given a ParamPackage for a Device returned from `GetInputDevices`, attempt to get the default
 | 
					 * Given a ParamPackage for a Device returned from `GetInputDevices`, attempt to get the default
 | 
				
			||||||
@ -90,11 +97,11 @@ public:
 | 
				
			|||||||
    /// Retrieves the underlying keyboard device.
 | 
					    /// Retrieves the underlying keyboard device.
 | 
				
			||||||
    [[nodiscard]] const Keyboard* GetKeyboard() const;
 | 
					    [[nodiscard]] const Keyboard* GetKeyboard() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Retrieves the underlying motion emulation factory.
 | 
					    /// Retrieves the underlying mouse device.
 | 
				
			||||||
    [[nodiscard]] MotionEmu* GetMotionEmu();
 | 
					    [[nodiscard]] MouseInput::Mouse* GetMouse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Retrieves the underlying motion emulation factory.
 | 
					    /// Retrieves the underlying mouse device.
 | 
				
			||||||
    [[nodiscard]] const MotionEmu* GetMotionEmu() const;
 | 
					    [[nodiscard]] const MouseInput::Mouse* GetMouse() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns all available input devices that this Factory can create a new device with.
 | 
					     * Returns all available input devices that this Factory can create a new device with.
 | 
				
			||||||
@ -137,6 +144,30 @@ public:
 | 
				
			|||||||
    /// Retrieves the underlying udp touch handler.
 | 
					    /// Retrieves the underlying udp touch handler.
 | 
				
			||||||
    [[nodiscard]] const UDPTouchFactory* GetUDPTouch() const;
 | 
					    [[nodiscard]] const UDPTouchFactory* GetUDPTouch() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Retrieves the underlying GameCube button handler.
 | 
				
			||||||
 | 
					    [[nodiscard]] MouseButtonFactory* GetMouseButtons();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Retrieves the underlying GameCube button handler.
 | 
				
			||||||
 | 
					    [[nodiscard]] const MouseButtonFactory* GetMouseButtons() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Retrieves the underlying udp touch handler.
 | 
				
			||||||
 | 
					    [[nodiscard]] MouseAnalogFactory* GetMouseAnalogs();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Retrieves the underlying udp touch handler.
 | 
				
			||||||
 | 
					    [[nodiscard]] const MouseAnalogFactory* GetMouseAnalogs() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Retrieves the underlying udp motion handler.
 | 
				
			||||||
 | 
					    [[nodiscard]] MouseMotionFactory* GetMouseMotions();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Retrieves the underlying udp motion handler.
 | 
				
			||||||
 | 
					    [[nodiscard]] const MouseMotionFactory* GetMouseMotions() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Retrieves the underlying udp touch handler.
 | 
				
			||||||
 | 
					    [[nodiscard]] MouseTouchFactory* GetMouseTouch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Retrieves the underlying udp touch handler.
 | 
				
			||||||
 | 
					    [[nodiscard]] const MouseTouchFactory* GetMouseTouch() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Reloads the input devices
 | 
					    /// Reloads the input devices
 | 
				
			||||||
    void ReloadInputDevices();
 | 
					    void ReloadInputDevices();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,179 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 Citra Emulator Project
 | 
					 | 
				
			||||||
// Licensed under GPLv2 or any later version
 | 
					 | 
				
			||||||
// Refer to the license.txt file included.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <algorithm>
 | 
					 | 
				
			||||||
#include <chrono>
 | 
					 | 
				
			||||||
#include <mutex>
 | 
					 | 
				
			||||||
#include <thread>
 | 
					 | 
				
			||||||
#include <tuple>
 | 
					 | 
				
			||||||
#include "common/math_util.h"
 | 
					 | 
				
			||||||
#include "common/quaternion.h"
 | 
					 | 
				
			||||||
#include "common/thread.h"
 | 
					 | 
				
			||||||
#include "common/vector_math.h"
 | 
					 | 
				
			||||||
#include "input_common/motion_emu.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace InputCommon {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Implementation class of the motion emulation device
 | 
					 | 
				
			||||||
class MotionEmuDevice {
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
    explicit MotionEmuDevice(int update_millisecond_, float sensitivity_)
 | 
					 | 
				
			||||||
        : update_millisecond(update_millisecond_),
 | 
					 | 
				
			||||||
          update_duration(std::chrono::duration_cast<std::chrono::steady_clock::duration>(
 | 
					 | 
				
			||||||
              std::chrono::milliseconds(update_millisecond))),
 | 
					 | 
				
			||||||
          sensitivity(sensitivity_), motion_emu_thread(&MotionEmuDevice::MotionEmuThread, this) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ~MotionEmuDevice() {
 | 
					 | 
				
			||||||
        if (motion_emu_thread.joinable()) {
 | 
					 | 
				
			||||||
            shutdown_event.Set();
 | 
					 | 
				
			||||||
            motion_emu_thread.join();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void BeginTilt(int x, int y) {
 | 
					 | 
				
			||||||
        mouse_origin = Common::MakeVec(x, y);
 | 
					 | 
				
			||||||
        is_tilting = true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Tilt(int x, int y) {
 | 
					 | 
				
			||||||
        if (!is_tilting) {
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::lock_guard guard{tilt_mutex};
 | 
					 | 
				
			||||||
        const auto mouse_move = Common::MakeVec(x, y) - mouse_origin;
 | 
					 | 
				
			||||||
        if (mouse_move.x == 0 && mouse_move.y == 0) {
 | 
					 | 
				
			||||||
            tilt_angle = 0;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            tilt_direction = mouse_move.Cast<float>();
 | 
					 | 
				
			||||||
            tilt_angle =
 | 
					 | 
				
			||||||
                std::clamp(tilt_direction.Normalize() * sensitivity, 0.0f, Common::PI * 0.5f);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void EndTilt() {
 | 
					 | 
				
			||||||
        std::lock_guard guard{tilt_mutex};
 | 
					 | 
				
			||||||
        tilt_angle = 0;
 | 
					 | 
				
			||||||
        is_tilting = false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Input::MotionStatus GetStatus() {
 | 
					 | 
				
			||||||
        std::lock_guard guard{status_mutex};
 | 
					 | 
				
			||||||
        return status;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
    const int update_millisecond;
 | 
					 | 
				
			||||||
    const std::chrono::steady_clock::duration update_duration;
 | 
					 | 
				
			||||||
    const float sensitivity;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Common::Vec2<int> mouse_origin;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::mutex tilt_mutex;
 | 
					 | 
				
			||||||
    Common::Vec2<float> tilt_direction;
 | 
					 | 
				
			||||||
    float tilt_angle = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool is_tilting = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Common::Event shutdown_event;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Input::MotionStatus status;
 | 
					 | 
				
			||||||
    std::mutex status_mutex;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Note: always keep the thread declaration at the end so that other objects are initialized
 | 
					 | 
				
			||||||
    // before this!
 | 
					 | 
				
			||||||
    std::thread motion_emu_thread;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void MotionEmuThread() {
 | 
					 | 
				
			||||||
        auto update_time = std::chrono::steady_clock::now();
 | 
					 | 
				
			||||||
        Common::Quaternion<float> q = Common::MakeQuaternion(Common::Vec3<float>(), 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        while (!shutdown_event.WaitUntil(update_time)) {
 | 
					 | 
				
			||||||
            update_time += update_duration;
 | 
					 | 
				
			||||||
            const Common::Quaternion<float> old_q = q;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                std::lock_guard guard{tilt_mutex};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Find the quaternion describing current 3DS tilting
 | 
					 | 
				
			||||||
                q = Common::MakeQuaternion(
 | 
					 | 
				
			||||||
                    Common::MakeVec(-tilt_direction.y, 0.0f, tilt_direction.x), tilt_angle);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            const auto inv_q = q.Inverse();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Set the gravity vector in world space
 | 
					 | 
				
			||||||
            auto gravity = Common::MakeVec(0.0f, -1.0f, 0.0f);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Find the angular rate vector in world space
 | 
					 | 
				
			||||||
            auto angular_rate = ((q - old_q) * inv_q).xyz * 2;
 | 
					 | 
				
			||||||
            angular_rate *= static_cast<float>(1000 / update_millisecond) / Common::PI * 180.0f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Transform the two vectors from world space to 3DS space
 | 
					 | 
				
			||||||
            gravity = QuaternionRotate(inv_q, gravity);
 | 
					 | 
				
			||||||
            angular_rate = QuaternionRotate(inv_q, angular_rate);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // TODO: Calculate the correct rotation vector and orientation matrix
 | 
					 | 
				
			||||||
            const auto matrix4x4 = q.ToMatrix();
 | 
					 | 
				
			||||||
            const auto rotation = Common::MakeVec(0.0f, 0.0f, 0.0f);
 | 
					 | 
				
			||||||
            const std::array orientation{
 | 
					 | 
				
			||||||
                Common::Vec3f(matrix4x4[0], matrix4x4[1], -matrix4x4[2]),
 | 
					 | 
				
			||||||
                Common::Vec3f(matrix4x4[4], matrix4x4[5], -matrix4x4[6]),
 | 
					 | 
				
			||||||
                Common::Vec3f(-matrix4x4[8], -matrix4x4[9], matrix4x4[10]),
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Update the sensor state
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                std::lock_guard guard{status_mutex};
 | 
					 | 
				
			||||||
                status = std::make_tuple(gravity, angular_rate, rotation, orientation);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Interface wrapper held by input receiver as a unique_ptr. It holds the implementation class as
 | 
					 | 
				
			||||||
// a shared_ptr, which is also observed by the factory class as a weak_ptr. In this way the factory
 | 
					 | 
				
			||||||
// can forward all the inputs to the implementation only when it is valid.
 | 
					 | 
				
			||||||
class MotionEmuDeviceWrapper : public Input::MotionDevice {
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
    explicit MotionEmuDeviceWrapper(int update_millisecond, float sensitivity) {
 | 
					 | 
				
			||||||
        device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Input::MotionStatus GetStatus() const override {
 | 
					 | 
				
			||||||
        return device->GetStatus();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::shared_ptr<MotionEmuDevice> device;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
std::unique_ptr<Input::MotionDevice> MotionEmu::Create(const Common::ParamPackage& params) {
 | 
					 | 
				
			||||||
    const int update_period = params.Get("update_period", 100);
 | 
					 | 
				
			||||||
    const float sensitivity = params.Get("sensitivity", 0.01f);
 | 
					 | 
				
			||||||
    auto device_wrapper = std::make_unique<MotionEmuDeviceWrapper>(update_period, sensitivity);
 | 
					 | 
				
			||||||
    // Previously created device is disconnected here. Having two motion devices for 3DS is not
 | 
					 | 
				
			||||||
    // expected.
 | 
					 | 
				
			||||||
    current_device = device_wrapper->device;
 | 
					 | 
				
			||||||
    return device_wrapper;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void MotionEmu::BeginTilt(int x, int y) {
 | 
					 | 
				
			||||||
    if (auto ptr = current_device.lock()) {
 | 
					 | 
				
			||||||
        ptr->BeginTilt(x, y);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void MotionEmu::Tilt(int x, int y) {
 | 
					 | 
				
			||||||
    if (auto ptr = current_device.lock()) {
 | 
					 | 
				
			||||||
        ptr->Tilt(x, y);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void MotionEmu::EndTilt() {
 | 
					 | 
				
			||||||
    if (auto ptr = current_device.lock()) {
 | 
					 | 
				
			||||||
        ptr->EndTilt();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace InputCommon
 | 
					 | 
				
			||||||
@ -1,46 +0,0 @@
 | 
				
			|||||||
// Copyright 2017 Citra Emulator Project
 | 
					 | 
				
			||||||
// Licensed under GPLv2 or any later version
 | 
					 | 
				
			||||||
// Refer to the license.txt file included.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "core/frontend/input.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace InputCommon {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class MotionEmuDevice;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class MotionEmu : public Input::Factory<Input::MotionDevice> {
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Creates a motion device emulated from mouse input
 | 
					 | 
				
			||||||
     * @param params contains parameters for creating the device:
 | 
					 | 
				
			||||||
     *     - "update_period": update period in milliseconds
 | 
					 | 
				
			||||||
     *     - "sensitivity": the coefficient converting mouse movement to tilting angle
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Signals that a motion sensor tilt has begun.
 | 
					 | 
				
			||||||
     * @param x the x-coordinate of the cursor
 | 
					 | 
				
			||||||
     * @param y the y-coordinate of the cursor
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    void BeginTilt(int x, int y);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Signals that a motion sensor tilt is occurring.
 | 
					 | 
				
			||||||
     * @param x the x-coordinate of the cursor
 | 
					 | 
				
			||||||
     * @param y the y-coordinate of the cursor
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    void Tilt(int x, int y);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Signals that a motion sensor tilt has ended.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    void EndTilt();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
    std::weak_ptr<MotionEmuDevice> current_device;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace InputCommon
 | 
					 | 
				
			||||||
							
								
								
									
										125
									
								
								src/input_common/mouse/mouse_input.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								src/input_common/mouse/mouse_input.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,125 @@
 | 
				
			|||||||
 | 
					// Copyright 2020 yuzu Emulator Project
 | 
				
			||||||
 | 
					// Licensed under GPLv2+
 | 
				
			||||||
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "common/logging/log.h"
 | 
				
			||||||
 | 
					#include "common/math_util.h"
 | 
				
			||||||
 | 
					#include "common/param_package.h"
 | 
				
			||||||
 | 
					#include "input_common/mouse/mouse_input.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MouseInput {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Mouse::Mouse() {
 | 
				
			||||||
 | 
					    update_thread = std::thread(&Mouse::UpdateThread, this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Mouse::~Mouse() {
 | 
				
			||||||
 | 
					    update_thread_running = false;
 | 
				
			||||||
 | 
					    if (update_thread.joinable()) {
 | 
				
			||||||
 | 
					        update_thread.join();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Mouse::UpdateThread() {
 | 
				
			||||||
 | 
					    constexpr int update_time = 10;
 | 
				
			||||||
 | 
					    while (update_thread_running) {
 | 
				
			||||||
 | 
					        for (MouseInfo& info : mouse_info) {
 | 
				
			||||||
 | 
					            Common::Vec3f angular_direction = {-info.tilt_direction.y, 0.0f,
 | 
				
			||||||
 | 
					                                               -info.tilt_direction.x};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            info.motion.SetGyroscope(angular_direction * info.tilt_speed);
 | 
				
			||||||
 | 
					            info.motion.UpdateRotation(update_time * 1000);
 | 
				
			||||||
 | 
					            info.motion.UpdateOrientation(update_time * 1000);
 | 
				
			||||||
 | 
					            info.tilt_speed = 0;
 | 
				
			||||||
 | 
					            info.data.motion = info.motion.GetMotion();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (configuring) {
 | 
				
			||||||
 | 
					            UpdateYuzuSettings();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        std::this_thread::sleep_for(std::chrono::milliseconds(update_time));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Mouse::UpdateYuzuSettings() {
 | 
				
			||||||
 | 
					    MouseStatus pad_status{};
 | 
				
			||||||
 | 
					    if (buttons != 0) {
 | 
				
			||||||
 | 
					        pad_status.button = last_button;
 | 
				
			||||||
 | 
					        mouse_queue.Push(pad_status);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Mouse::PressButton(int x, int y, int button_) {
 | 
				
			||||||
 | 
					    if (button_ >= static_cast<int>(mouse_info.size())) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int button = 1 << button_;
 | 
				
			||||||
 | 
					    buttons |= static_cast<u16>(button);
 | 
				
			||||||
 | 
					    last_button = static_cast<MouseButton>(button_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mouse_info[button_].mouse_origin = Common::MakeVec(x, y);
 | 
				
			||||||
 | 
					    mouse_info[button_].last_mouse_position = Common::MakeVec(x, y);
 | 
				
			||||||
 | 
					    mouse_info[button_].data.pressed = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Mouse::MouseMove(int x, int y) {
 | 
				
			||||||
 | 
					    for (MouseInfo& info : mouse_info) {
 | 
				
			||||||
 | 
					        if (info.data.pressed) {
 | 
				
			||||||
 | 
					            auto mouse_move = Common::MakeVec(x, y) - info.mouse_origin;
 | 
				
			||||||
 | 
					            auto mouse_change = Common::MakeVec(x, y) - info.last_mouse_position;
 | 
				
			||||||
 | 
					            info.last_mouse_position = Common::MakeVec(x, y);
 | 
				
			||||||
 | 
					            info.data.axis = {mouse_move.x, -mouse_move.y};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (mouse_change.x == 0 && mouse_change.y == 0) {
 | 
				
			||||||
 | 
					                info.tilt_speed = 0;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                info.tilt_direction = mouse_change.Cast<float>();
 | 
				
			||||||
 | 
					                info.tilt_speed = info.tilt_direction.Normalize() * info.sensitivity;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Mouse::ReleaseButton(int button_) {
 | 
				
			||||||
 | 
					    if (button_ >= static_cast<int>(mouse_info.size())) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int button = 1 << button_;
 | 
				
			||||||
 | 
					    buttons &= static_cast<u16>(0xFF - button);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mouse_info[button_].tilt_speed = 0;
 | 
				
			||||||
 | 
					    mouse_info[button_].data.pressed = false;
 | 
				
			||||||
 | 
					    mouse_info[button_].data.axis = {0, 0};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Mouse::BeginConfiguration() {
 | 
				
			||||||
 | 
					    buttons = 0;
 | 
				
			||||||
 | 
					    last_button = MouseButton::Undefined;
 | 
				
			||||||
 | 
					    mouse_queue.Clear();
 | 
				
			||||||
 | 
					    configuring = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Mouse::EndConfiguration() {
 | 
				
			||||||
 | 
					    buttons = 0;
 | 
				
			||||||
 | 
					    last_button = MouseButton::Undefined;
 | 
				
			||||||
 | 
					    mouse_queue.Clear();
 | 
				
			||||||
 | 
					    configuring = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() {
 | 
				
			||||||
 | 
					    return mouse_queue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() const {
 | 
				
			||||||
 | 
					    return mouse_queue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MouseData& Mouse::GetMouseState(std::size_t button) {
 | 
				
			||||||
 | 
					    return mouse_info[button].data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const MouseData& Mouse::GetMouseState(std::size_t button) const {
 | 
				
			||||||
 | 
					    return mouse_info[button].data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					} // namespace MouseInput
 | 
				
			||||||
							
								
								
									
										99
									
								
								src/input_common/mouse/mouse_input.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/input_common/mouse/mouse_input.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,99 @@
 | 
				
			|||||||
 | 
					// Copyright 2020 yuzu Emulator Project
 | 
				
			||||||
 | 
					// Licensed under GPLv2 or any later version
 | 
				
			||||||
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					#include <functional>
 | 
				
			||||||
 | 
					#include <mutex>
 | 
				
			||||||
 | 
					#include <thread>
 | 
				
			||||||
 | 
					#include <unordered_map>
 | 
				
			||||||
 | 
					#include "common/common_types.h"
 | 
				
			||||||
 | 
					#include "common/threadsafe_queue.h"
 | 
				
			||||||
 | 
					#include "core/frontend/input.h"
 | 
				
			||||||
 | 
					#include "input_common/main.h"
 | 
				
			||||||
 | 
					#include "input_common/motion_input.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MouseInput {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum class MouseButton {
 | 
				
			||||||
 | 
					    Left,
 | 
				
			||||||
 | 
					    Wheel,
 | 
				
			||||||
 | 
					    Right,
 | 
				
			||||||
 | 
					    Foward,
 | 
				
			||||||
 | 
					    Backward,
 | 
				
			||||||
 | 
					    Undefined,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct MouseStatus {
 | 
				
			||||||
 | 
					    MouseButton button{MouseButton::Undefined};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct MouseData {
 | 
				
			||||||
 | 
					    bool pressed{};
 | 
				
			||||||
 | 
					    std::array<int, 2> axis{};
 | 
				
			||||||
 | 
					    Input::MotionStatus motion{};
 | 
				
			||||||
 | 
					    Input::TouchStatus touch{};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Mouse {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    Mouse();
 | 
				
			||||||
 | 
					    ~Mouse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Used for polling
 | 
				
			||||||
 | 
					    void BeginConfiguration();
 | 
				
			||||||
 | 
					    void EndConfiguration();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Signals that a button is pressed.
 | 
				
			||||||
 | 
					     * @param x the x-coordinate of the cursor
 | 
				
			||||||
 | 
					     * @param y the y-coordinate of the cursor
 | 
				
			||||||
 | 
					     * @param button the button pressed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void PressButton(int x, int y, int button_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Signals that mouse has moved.
 | 
				
			||||||
 | 
					     * @param x the x-coordinate of the cursor
 | 
				
			||||||
 | 
					     * @param y the y-coordinate of the cursor
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void MouseMove(int x, int y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Signals that a motion sensor tilt has ended.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void ReleaseButton(int button_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue();
 | 
				
			||||||
 | 
					    [[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [[nodiscard]] MouseData& GetMouseState(std::size_t button);
 | 
				
			||||||
 | 
					    [[nodiscard]] const MouseData& GetMouseState(std::size_t button) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    void UpdateThread();
 | 
				
			||||||
 | 
					    void UpdateYuzuSettings();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct MouseInfo {
 | 
				
			||||||
 | 
					        InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f};
 | 
				
			||||||
 | 
					        Common::Vec2<int> mouse_origin;
 | 
				
			||||||
 | 
					        Common::Vec2<int> last_mouse_position;
 | 
				
			||||||
 | 
					        bool is_tilting = false;
 | 
				
			||||||
 | 
					        float sensitivity{0.120f};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float tilt_speed = 0;
 | 
				
			||||||
 | 
					        Common::Vec2<float> tilt_direction;
 | 
				
			||||||
 | 
					        MouseData data;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u16 buttons{};
 | 
				
			||||||
 | 
					    std::thread update_thread;
 | 
				
			||||||
 | 
					    MouseButton last_button{MouseButton::Undefined};
 | 
				
			||||||
 | 
					    std::array<MouseInfo, 5> mouse_info;
 | 
				
			||||||
 | 
					    Common::SPSCQueue<MouseStatus> mouse_queue;
 | 
				
			||||||
 | 
					    bool configuring{false};
 | 
				
			||||||
 | 
					    bool update_thread_running{true};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					} // namespace MouseInput
 | 
				
			||||||
							
								
								
									
										261
									
								
								src/input_common/mouse/mouse_poller.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								src/input_common/mouse/mouse_poller.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,261 @@
 | 
				
			|||||||
 | 
					// Copyright 2020 yuzu Emulator Project
 | 
				
			||||||
 | 
					// Licensed under GPLv2 or any later version
 | 
				
			||||||
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <atomic>
 | 
				
			||||||
 | 
					#include <list>
 | 
				
			||||||
 | 
					#include <mutex>
 | 
				
			||||||
 | 
					#include <utility>
 | 
				
			||||||
 | 
					#include "common/assert.h"
 | 
				
			||||||
 | 
					#include "common/threadsafe_queue.h"
 | 
				
			||||||
 | 
					#include "input_common/mouse/mouse_input.h"
 | 
				
			||||||
 | 
					#include "input_common/mouse/mouse_poller.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace InputCommon {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MouseButton final : public Input::ButtonDevice {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit MouseButton(u32 button_, const MouseInput::Mouse* mouse_input_)
 | 
				
			||||||
 | 
					        : button(button_), mouse_input(mouse_input_) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool GetStatus() const override {
 | 
				
			||||||
 | 
					        return mouse_input->GetMouseState(button).pressed;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    const u32 button;
 | 
				
			||||||
 | 
					    const MouseInput::Mouse* mouse_input;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
 | 
				
			||||||
 | 
					    : mouse_input(std::move(mouse_input_)) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create(
 | 
				
			||||||
 | 
					    const Common::ParamPackage& params) {
 | 
				
			||||||
 | 
					    const auto button_id = params.Get("button", 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return std::make_unique<MouseButton>(button_id, mouse_input.get());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Common::ParamPackage MouseButtonFactory::GetNextInput() const {
 | 
				
			||||||
 | 
					    MouseInput::MouseStatus pad;
 | 
				
			||||||
 | 
					    Common::ParamPackage params;
 | 
				
			||||||
 | 
					    auto& queue = mouse_input->GetMouseQueue();
 | 
				
			||||||
 | 
					    while (queue.Pop(pad)) {
 | 
				
			||||||
 | 
					        // This while loop will break on the earliest detected button
 | 
				
			||||||
 | 
					        if (pad.button != MouseInput::MouseButton::Undefined) {
 | 
				
			||||||
 | 
					            params.Set("engine", "mouse");
 | 
				
			||||||
 | 
					            params.Set("button", static_cast<u16>(pad.button));
 | 
				
			||||||
 | 
					            return params;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return params;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MouseButtonFactory::BeginConfiguration() {
 | 
				
			||||||
 | 
					    polling = true;
 | 
				
			||||||
 | 
					    mouse_input->BeginConfiguration();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MouseButtonFactory::EndConfiguration() {
 | 
				
			||||||
 | 
					    polling = false;
 | 
				
			||||||
 | 
					    mouse_input->EndConfiguration();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MouseAnalog final : public Input::AnalogDevice {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit MouseAnalog(u32 port_, u32 axis_x_, u32 axis_y_, float deadzone_, float range_,
 | 
				
			||||||
 | 
					                         const MouseInput::Mouse* mouse_input_)
 | 
				
			||||||
 | 
					        : button(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), range(range_),
 | 
				
			||||||
 | 
					          mouse_input(mouse_input_) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    float GetAxis(u32 axis) const {
 | 
				
			||||||
 | 
					        std::lock_guard lock{mutex};
 | 
				
			||||||
 | 
					        const auto axis_value =
 | 
				
			||||||
 | 
					            static_cast<float>(mouse_input->GetMouseState(button).axis.at(axis));
 | 
				
			||||||
 | 
					        return axis_value / (100.0f * range);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const {
 | 
				
			||||||
 | 
					        float x = GetAxis(analog_axis_x);
 | 
				
			||||||
 | 
					        float y = GetAxis(analog_axis_y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Make sure the coordinates are in the unit circle,
 | 
				
			||||||
 | 
					        // otherwise normalize it.
 | 
				
			||||||
 | 
					        float r = x * x + y * y;
 | 
				
			||||||
 | 
					        if (r > 1.0f) {
 | 
				
			||||||
 | 
					            r = std::sqrt(r);
 | 
				
			||||||
 | 
					            x /= r;
 | 
				
			||||||
 | 
					            y /= r;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return {x, y};
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::tuple<float, float> GetStatus() const override {
 | 
				
			||||||
 | 
					        const auto [x, y] = GetAnalog(axis_x, axis_y);
 | 
				
			||||||
 | 
					        const float r = std::sqrt((x * x) + (y * y));
 | 
				
			||||||
 | 
					        if (r > deadzone) {
 | 
				
			||||||
 | 
					            return {x / r * (r - deadzone) / (1 - deadzone),
 | 
				
			||||||
 | 
					                    y / r * (r - deadzone) / (1 - deadzone)};
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return {0.0f, 0.0f};
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    const u32 button;
 | 
				
			||||||
 | 
					    const u32 axis_x;
 | 
				
			||||||
 | 
					    const u32 axis_y;
 | 
				
			||||||
 | 
					    const float deadzone;
 | 
				
			||||||
 | 
					    const float range;
 | 
				
			||||||
 | 
					    const MouseInput::Mouse* mouse_input;
 | 
				
			||||||
 | 
					    mutable std::mutex mutex;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// An analog device factory that creates analog devices from GC Adapter
 | 
				
			||||||
 | 
					MouseAnalogFactory::MouseAnalogFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
 | 
				
			||||||
 | 
					    : mouse_input(std::move(mouse_input_)) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Creates analog device from joystick axes
 | 
				
			||||||
 | 
					 * @param params contains parameters for creating the device:
 | 
				
			||||||
 | 
					 *     - "port": the nth gcpad on the adapter
 | 
				
			||||||
 | 
					 *     - "axis_x": the index of the axis to be bind as x-axis
 | 
				
			||||||
 | 
					 *     - "axis_y": the index of the axis to be bind as y-axis
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::unique_ptr<Input::AnalogDevice> MouseAnalogFactory::Create(
 | 
				
			||||||
 | 
					    const Common::ParamPackage& params) {
 | 
				
			||||||
 | 
					    const auto port = static_cast<u32>(params.Get("port", 0));
 | 
				
			||||||
 | 
					    const auto axis_x = static_cast<u32>(params.Get("axis_x", 0));
 | 
				
			||||||
 | 
					    const auto axis_y = static_cast<u32>(params.Get("axis_y", 1));
 | 
				
			||||||
 | 
					    const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
 | 
				
			||||||
 | 
					    const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return std::make_unique<MouseAnalog>(port, axis_x, axis_y, deadzone, range, mouse_input.get());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MouseAnalogFactory::BeginConfiguration() {
 | 
				
			||||||
 | 
					    polling = true;
 | 
				
			||||||
 | 
					    mouse_input->BeginConfiguration();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MouseAnalogFactory::EndConfiguration() {
 | 
				
			||||||
 | 
					    polling = false;
 | 
				
			||||||
 | 
					    mouse_input->EndConfiguration();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Common::ParamPackage MouseAnalogFactory::GetNextInput() const {
 | 
				
			||||||
 | 
					    MouseInput::MouseStatus pad;
 | 
				
			||||||
 | 
					    Common::ParamPackage params;
 | 
				
			||||||
 | 
					    auto& queue = mouse_input->GetMouseQueue();
 | 
				
			||||||
 | 
					    while (queue.Pop(pad)) {
 | 
				
			||||||
 | 
					        // This while loop will break on the earliest detected button
 | 
				
			||||||
 | 
					        if (pad.button != MouseInput::MouseButton::Undefined) {
 | 
				
			||||||
 | 
					            params.Set("engine", "mouse");
 | 
				
			||||||
 | 
					            params.Set("port", static_cast<u16>(pad.button));
 | 
				
			||||||
 | 
					            params.Set("axis_x", 0);
 | 
				
			||||||
 | 
					            params.Set("axis_y", 1);
 | 
				
			||||||
 | 
					            return params;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return params;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MouseMotion final : public Input::MotionDevice {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit MouseMotion(u32 button_, const MouseInput::Mouse* mouse_input_)
 | 
				
			||||||
 | 
					        : button(button_), mouse_input(mouse_input_) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Input::MotionStatus GetStatus() const override {
 | 
				
			||||||
 | 
					        return mouse_input->GetMouseState(button).motion;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    const u32 button;
 | 
				
			||||||
 | 
					    const MouseInput::Mouse* mouse_input;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MouseMotionFactory::MouseMotionFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
 | 
				
			||||||
 | 
					    : mouse_input(std::move(mouse_input_)) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::unique_ptr<Input::MotionDevice> MouseMotionFactory::Create(
 | 
				
			||||||
 | 
					    const Common::ParamPackage& params) {
 | 
				
			||||||
 | 
					    const auto button_id = params.Get("button", 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return std::make_unique<MouseMotion>(button_id, mouse_input.get());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Common::ParamPackage MouseMotionFactory::GetNextInput() const {
 | 
				
			||||||
 | 
					    MouseInput::MouseStatus pad;
 | 
				
			||||||
 | 
					    Common::ParamPackage params;
 | 
				
			||||||
 | 
					    auto& queue = mouse_input->GetMouseQueue();
 | 
				
			||||||
 | 
					    while (queue.Pop(pad)) {
 | 
				
			||||||
 | 
					        // This while loop will break on the earliest detected button
 | 
				
			||||||
 | 
					        if (pad.button != MouseInput::MouseButton::Undefined) {
 | 
				
			||||||
 | 
					            params.Set("engine", "mouse");
 | 
				
			||||||
 | 
					            params.Set("button", static_cast<u16>(pad.button));
 | 
				
			||||||
 | 
					            return params;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return params;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MouseMotionFactory::BeginConfiguration() {
 | 
				
			||||||
 | 
					    polling = true;
 | 
				
			||||||
 | 
					    mouse_input->BeginConfiguration();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MouseMotionFactory::EndConfiguration() {
 | 
				
			||||||
 | 
					    polling = false;
 | 
				
			||||||
 | 
					    mouse_input->EndConfiguration();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MouseTouch final : public Input::TouchDevice {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit MouseTouch(u32 button_, const MouseInput::Mouse* mouse_input_)
 | 
				
			||||||
 | 
					        : button(button_), mouse_input(mouse_input_) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Input::TouchStatus GetStatus() const override {
 | 
				
			||||||
 | 
					        return mouse_input->GetMouseState(button).touch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    const u32 button;
 | 
				
			||||||
 | 
					    const MouseInput::Mouse* mouse_input;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MouseTouchFactory::MouseTouchFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
 | 
				
			||||||
 | 
					    : mouse_input(std::move(mouse_input_)) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::unique_ptr<Input::TouchDevice> MouseTouchFactory::Create(const Common::ParamPackage& params) {
 | 
				
			||||||
 | 
					    const auto button_id = params.Get("button", 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return std::make_unique<MouseTouch>(button_id, mouse_input.get());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Common::ParamPackage MouseTouchFactory::GetNextInput() const {
 | 
				
			||||||
 | 
					    MouseInput::MouseStatus pad;
 | 
				
			||||||
 | 
					    Common::ParamPackage params;
 | 
				
			||||||
 | 
					    auto& queue = mouse_input->GetMouseQueue();
 | 
				
			||||||
 | 
					    while (queue.Pop(pad)) {
 | 
				
			||||||
 | 
					        // This while loop will break on the earliest detected button
 | 
				
			||||||
 | 
					        if (pad.button != MouseInput::MouseButton::Undefined) {
 | 
				
			||||||
 | 
					            params.Set("engine", "mouse");
 | 
				
			||||||
 | 
					            params.Set("button", static_cast<u16>(pad.button));
 | 
				
			||||||
 | 
					            return params;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return params;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MouseTouchFactory::BeginConfiguration() {
 | 
				
			||||||
 | 
					    polling = true;
 | 
				
			||||||
 | 
					    mouse_input->BeginConfiguration();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MouseTouchFactory::EndConfiguration() {
 | 
				
			||||||
 | 
					    polling = false;
 | 
				
			||||||
 | 
					    mouse_input->EndConfiguration();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace InputCommon
 | 
				
			||||||
							
								
								
									
										109
									
								
								src/input_common/mouse/mouse_poller.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/input_common/mouse/mouse_poller.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,109 @@
 | 
				
			|||||||
 | 
					// Copyright 2020 yuzu Emulator Project
 | 
				
			||||||
 | 
					// Licensed under GPLv2 or any later version
 | 
				
			||||||
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					#include "core/frontend/input.h"
 | 
				
			||||||
 | 
					#include "input_common/mouse/mouse_input.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace InputCommon {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A button device factory representing a mouse. It receives mouse events and forward them
 | 
				
			||||||
 | 
					 * to all button devices it created.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class MouseButtonFactory final : public Input::Factory<Input::ButtonDevice> {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Creates a button device from a button press
 | 
				
			||||||
 | 
					     * @param params contains parameters for creating the device:
 | 
				
			||||||
 | 
					     *     - "code": the code of the key to bind with the button
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Common::ParamPackage GetNextInput() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// For device input configuration/polling
 | 
				
			||||||
 | 
					    void BeginConfiguration();
 | 
				
			||||||
 | 
					    void EndConfiguration();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool IsPolling() const {
 | 
				
			||||||
 | 
					        return polling;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    std::shared_ptr<MouseInput::Mouse> mouse_input;
 | 
				
			||||||
 | 
					    bool polling = false;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// An analog device factory that creates analog devices from mouse
 | 
				
			||||||
 | 
					class MouseAnalogFactory final : public Input::Factory<Input::AnalogDevice> {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit MouseAnalogFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::unique_ptr<Input::AnalogDevice> Create(const Common::ParamPackage& params) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Common::ParamPackage GetNextInput() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// For device input configuration/polling
 | 
				
			||||||
 | 
					    void BeginConfiguration();
 | 
				
			||||||
 | 
					    void EndConfiguration();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool IsPolling() const {
 | 
				
			||||||
 | 
					        return polling;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    std::shared_ptr<MouseInput::Mouse> mouse_input;
 | 
				
			||||||
 | 
					    bool polling = false;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// A motion device factory that creates motion devices from mouse
 | 
				
			||||||
 | 
					class MouseMotionFactory final : public Input::Factory<Input::MotionDevice> {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit MouseMotionFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Common::ParamPackage GetNextInput() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// For device input configuration/polling
 | 
				
			||||||
 | 
					    void BeginConfiguration();
 | 
				
			||||||
 | 
					    void EndConfiguration();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool IsPolling() const {
 | 
				
			||||||
 | 
					        return polling;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    std::shared_ptr<MouseInput::Mouse> mouse_input;
 | 
				
			||||||
 | 
					    bool polling = false;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// An touch device factory that creates touch devices from mouse
 | 
				
			||||||
 | 
					class MouseTouchFactory final : public Input::Factory<Input::TouchDevice> {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit MouseTouchFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::unique_ptr<Input::TouchDevice> Create(const Common::ParamPackage& params) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Common::ParamPackage GetNextInput() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// For device input configuration/polling
 | 
				
			||||||
 | 
					    void BeginConfiguration();
 | 
				
			||||||
 | 
					    void EndConfiguration();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool IsPolling() const {
 | 
				
			||||||
 | 
					        return polling;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    std::shared_ptr<MouseInput::Mouse> mouse_input;
 | 
				
			||||||
 | 
					    bool polling = false;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace InputCommon
 | 
				
			||||||
@ -35,7 +35,7 @@
 | 
				
			|||||||
#include "core/settings.h"
 | 
					#include "core/settings.h"
 | 
				
			||||||
#include "input_common/keyboard.h"
 | 
					#include "input_common/keyboard.h"
 | 
				
			||||||
#include "input_common/main.h"
 | 
					#include "input_common/main.h"
 | 
				
			||||||
#include "input_common/motion_emu.h"
 | 
					#include "input_common/mouse/mouse_input.h"
 | 
				
			||||||
#include "video_core/renderer_base.h"
 | 
					#include "video_core/renderer_base.h"
 | 
				
			||||||
#include "video_core/video_core.h"
 | 
					#include "video_core/video_core.h"
 | 
				
			||||||
#include "yuzu/bootmanager.h"
 | 
					#include "yuzu/bootmanager.h"
 | 
				
			||||||
@ -388,23 +388,19 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void GRenderWindow::mousePressEvent(QMouseEvent* event) {
 | 
					void GRenderWindow::mousePressEvent(QMouseEvent* event) {
 | 
				
			||||||
    if (!Settings::values.touchscreen.enabled) {
 | 
					 | 
				
			||||||
        input_subsystem->GetKeyboard()->PressKey(event->button());
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Touch input is handled in TouchBeginEvent
 | 
					    // Touch input is handled in TouchBeginEvent
 | 
				
			||||||
    if (event->source() == Qt::MouseEventSynthesizedBySystem) {
 | 
					    if (event->source() == Qt::MouseEventSynthesizedBySystem) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto pos = event->pos();
 | 
					    auto pos = event->pos();
 | 
				
			||||||
 | 
					    const auto [x, y] = ScaleTouch(pos);
 | 
				
			||||||
 | 
					    input_subsystem->GetMouse()->PressButton(x, y, event->button());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (event->button() == Qt::LeftButton) {
 | 
					    if (event->button() == Qt::LeftButton) {
 | 
				
			||||||
        const auto [x, y] = ScaleTouch(pos);
 | 
					 | 
				
			||||||
        this->TouchPressed(x, y);
 | 
					        this->TouchPressed(x, y);
 | 
				
			||||||
    } else if (event->button() == Qt::RightButton) {
 | 
					 | 
				
			||||||
        input_subsystem->GetMotionEmu()->BeginTilt(pos.x(), pos.y());
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QWidget::mousePressEvent(event);
 | 
					    QWidget::mousePressEvent(event);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -416,26 +412,22 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    auto pos = event->pos();
 | 
					    auto pos = event->pos();
 | 
				
			||||||
    const auto [x, y] = ScaleTouch(pos);
 | 
					    const auto [x, y] = ScaleTouch(pos);
 | 
				
			||||||
 | 
					    input_subsystem->GetMouse()->MouseMove(x, y);
 | 
				
			||||||
    this->TouchMoved(x, y);
 | 
					    this->TouchMoved(x, y);
 | 
				
			||||||
    input_subsystem->GetMotionEmu()->Tilt(pos.x(), pos.y());
 | 
					
 | 
				
			||||||
    QWidget::mouseMoveEvent(event);
 | 
					    QWidget::mouseMoveEvent(event);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
 | 
					void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
 | 
				
			||||||
    if (!Settings::values.touchscreen.enabled) {
 | 
					 | 
				
			||||||
        input_subsystem->GetKeyboard()->ReleaseKey(event->button());
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Touch input is handled in TouchEndEvent
 | 
					    // Touch input is handled in TouchEndEvent
 | 
				
			||||||
    if (event->source() == Qt::MouseEventSynthesizedBySystem) {
 | 
					    if (event->source() == Qt::MouseEventSynthesizedBySystem) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    input_subsystem->GetMouse()->ReleaseButton(event->button());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (event->button() == Qt::LeftButton) {
 | 
					    if (event->button() == Qt::LeftButton) {
 | 
				
			||||||
        this->TouchReleased();
 | 
					        this->TouchReleased();
 | 
				
			||||||
    } else if (event->button() == Qt::RightButton) {
 | 
					 | 
				
			||||||
        input_subsystem->GetMotionEmu()->EndTilt();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,7 @@
 | 
				
			|||||||
#include "core/hle/service/sm/sm.h"
 | 
					#include "core/hle/service/sm/sm.h"
 | 
				
			||||||
#include "input_common/gcadapter/gc_poller.h"
 | 
					#include "input_common/gcadapter/gc_poller.h"
 | 
				
			||||||
#include "input_common/main.h"
 | 
					#include "input_common/main.h"
 | 
				
			||||||
 | 
					#include "input_common/mouse/mouse_poller.h"
 | 
				
			||||||
#include "input_common/udp/udp.h"
 | 
					#include "input_common/udp/udp.h"
 | 
				
			||||||
#include "ui_configure_input_player.h"
 | 
					#include "ui_configure_input_player.h"
 | 
				
			||||||
#include "yuzu/configuration/config.h"
 | 
					#include "yuzu/configuration/config.h"
 | 
				
			||||||
@ -152,6 +153,14 @@ QString ButtonToText(const Common::ParamPackage& param) {
 | 
				
			|||||||
        return {};
 | 
					        return {};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (param.Get("engine", "") == "mouse") {
 | 
				
			||||||
 | 
					        if (param.Has("button")) {
 | 
				
			||||||
 | 
					            const QString button_str = QString::number(int(param.Get("button", 0)));
 | 
				
			||||||
 | 
					            return QObject::tr("Click %1").arg(button_str);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return GetKeyName(param.Get("code", 0));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return QObject::tr("[unknown]");
 | 
					    return QObject::tr("[unknown]");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -203,6 +212,26 @@ QString AnalogToText(const Common::ParamPackage& param, const std::string& dir)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return {};
 | 
					        return {};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (param.Get("engine", "") == "mouse") {
 | 
				
			||||||
 | 
					        if (dir == "modifier") {
 | 
				
			||||||
 | 
					            return QObject::tr("[unused]");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (dir == "left" || dir == "right") {
 | 
				
			||||||
 | 
					            const QString axis_x_str = QString::fromStdString(param.Get("axis_x", ""));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return QObject::tr("Mouse %1").arg(axis_x_str);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (dir == "up" || dir == "down") {
 | 
				
			||||||
 | 
					            const QString axis_y_str = QString::fromStdString(param.Get("axis_y", ""));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return QObject::tr("Mouse %1").arg(axis_y_str);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return {};
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return QObject::tr("[unknown]");
 | 
					    return QObject::tr("[unknown]");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
@ -484,6 +513,34 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (input_subsystem->GetMouseButtons()->IsPolling()) {
 | 
				
			||||||
 | 
					            params = input_subsystem->GetMouseButtons()->GetNextInput();
 | 
				
			||||||
 | 
					            if (params.Has("engine") && IsInputAcceptable(params)) {
 | 
				
			||||||
 | 
					                SetPollingResult(params, false);
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (input_subsystem->GetMouseAnalogs()->IsPolling()) {
 | 
				
			||||||
 | 
					            params = input_subsystem->GetMouseAnalogs()->GetNextInput();
 | 
				
			||||||
 | 
					            if (params.Has("engine") && IsInputAcceptable(params)) {
 | 
				
			||||||
 | 
					                SetPollingResult(params, false);
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (input_subsystem->GetMouseMotions()->IsPolling()) {
 | 
				
			||||||
 | 
					            params = input_subsystem->GetMouseMotions()->GetNextInput();
 | 
				
			||||||
 | 
					            if (params.Has("engine") && IsInputAcceptable(params)) {
 | 
				
			||||||
 | 
					                SetPollingResult(params, false);
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (input_subsystem->GetMouseTouch()->IsPolling()) {
 | 
				
			||||||
 | 
					            params = input_subsystem->GetMouseTouch()->GetNextInput();
 | 
				
			||||||
 | 
					            if (params.Has("engine") && IsInputAcceptable(params)) {
 | 
				
			||||||
 | 
					                SetPollingResult(params, false);
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        for (auto& poller : device_pollers) {
 | 
					        for (auto& poller : device_pollers) {
 | 
				
			||||||
            params = poller->GetNextInput();
 | 
					            params = poller->GetNextInput();
 | 
				
			||||||
            if (params.Has("engine") && IsInputAcceptable(params)) {
 | 
					            if (params.Has("engine") && IsInputAcceptable(params)) {
 | 
				
			||||||
@ -761,8 +818,9 @@ void ConfigureInputPlayer::UpdateUI() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        int slider_value;
 | 
					        int slider_value;
 | 
				
			||||||
        auto& param = analogs_param[analog_id];
 | 
					        auto& param = analogs_param[analog_id];
 | 
				
			||||||
        const bool is_controller =
 | 
					        const bool is_controller = param.Get("engine", "") == "sdl" ||
 | 
				
			||||||
            param.Get("engine", "") == "sdl" || param.Get("engine", "") == "gcpad";
 | 
					                                   param.Get("engine", "") == "gcpad" ||
 | 
				
			||||||
 | 
					                                   param.Get("engine", "") == "mouse";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (is_controller) {
 | 
					        if (is_controller) {
 | 
				
			||||||
            if (!param.Has("deadzone")) {
 | 
					            if (!param.Has("deadzone")) {
 | 
				
			||||||
@ -1078,6 +1136,16 @@ void ConfigureInputPlayer::HandleClick(
 | 
				
			|||||||
        input_subsystem->GetUDPMotions()->BeginConfiguration();
 | 
					        input_subsystem->GetUDPMotions()->BeginConfiguration();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (type == InputCommon::Polling::DeviceType::Button) {
 | 
				
			||||||
 | 
					        input_subsystem->GetMouseButtons()->BeginConfiguration();
 | 
				
			||||||
 | 
					    } else if (type == InputCommon::Polling::DeviceType::AnalogPreferred) {
 | 
				
			||||||
 | 
					        input_subsystem->GetMouseAnalogs()->BeginConfiguration();
 | 
				
			||||||
 | 
					    } else if (type == InputCommon::Polling::DeviceType::Motion) {
 | 
				
			||||||
 | 
					        input_subsystem->GetMouseMotions()->BeginConfiguration();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        input_subsystem->GetMouseTouch()->BeginConfiguration();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    timeout_timer->start(2500); // Cancel after 2.5 seconds
 | 
					    timeout_timer->start(2500); // Cancel after 2.5 seconds
 | 
				
			||||||
    poll_timer->start(50);      // Check for new inputs every 50ms
 | 
					    poll_timer->start(50);      // Check for new inputs every 50ms
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1097,6 +1165,11 @@ void ConfigureInputPlayer::SetPollingResult(const Common::ParamPackage& params,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    input_subsystem->GetUDPMotions()->EndConfiguration();
 | 
					    input_subsystem->GetUDPMotions()->EndConfiguration();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    input_subsystem->GetMouseButtons()->EndConfiguration();
 | 
				
			||||||
 | 
					    input_subsystem->GetMouseAnalogs()->EndConfiguration();
 | 
				
			||||||
 | 
					    input_subsystem->GetMouseMotions()->EndConfiguration();
 | 
				
			||||||
 | 
					    input_subsystem->GetMouseTouch()->EndConfiguration();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!abort) {
 | 
					    if (!abort) {
 | 
				
			||||||
        (*input_setter)(params);
 | 
					        (*input_setter)(params);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -1128,15 +1201,7 @@ void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) {
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (want_keyboard_mouse) {
 | 
					    input_subsystem->GetMouse()->PressButton(0, 0, event->button());
 | 
				
			||||||
        SetPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->button())},
 | 
					 | 
				
			||||||
                         false);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        // We don't want any mouse buttons, so don't stop polling
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SetPollingResult({}, true);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) {
 | 
					void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) {
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,7 @@
 | 
				
			|||||||
#include "core/perf_stats.h"
 | 
					#include "core/perf_stats.h"
 | 
				
			||||||
#include "input_common/keyboard.h"
 | 
					#include "input_common/keyboard.h"
 | 
				
			||||||
#include "input_common/main.h"
 | 
					#include "input_common/main.h"
 | 
				
			||||||
#include "input_common/motion_emu.h"
 | 
					#include "input_common/mouse/mouse_input.h"
 | 
				
			||||||
#include "input_common/sdl/sdl.h"
 | 
					#include "input_common/sdl/sdl.h"
 | 
				
			||||||
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
 | 
					#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -30,7 +30,7 @@ EmuWindow_SDL2::~EmuWindow_SDL2() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
 | 
					void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
 | 
				
			||||||
    TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
 | 
					    TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
 | 
				
			||||||
    input_subsystem->GetMotionEmu()->Tilt(x, y);
 | 
					    input_subsystem->GetMouse()->MouseMove(x, y);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
 | 
					void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
 | 
				
			||||||
@ -42,9 +42,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    } else if (button == SDL_BUTTON_RIGHT) {
 | 
					    } else if (button == SDL_BUTTON_RIGHT) {
 | 
				
			||||||
        if (state == SDL_PRESSED) {
 | 
					        if (state == SDL_PRESSED) {
 | 
				
			||||||
            input_subsystem->GetMotionEmu()->BeginTilt(x, y);
 | 
					            input_subsystem->GetMouse()->PressButton(x, y, button);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            input_subsystem->GetMotionEmu()->EndTilt();
 | 
					            input_subsystem->GetMouse()->ReleaseButton(button);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -17,7 +17,6 @@
 | 
				
			|||||||
#include "core/settings.h"
 | 
					#include "core/settings.h"
 | 
				
			||||||
#include "input_common/keyboard.h"
 | 
					#include "input_common/keyboard.h"
 | 
				
			||||||
#include "input_common/main.h"
 | 
					#include "input_common/main.h"
 | 
				
			||||||
#include "input_common/motion_emu.h"
 | 
					 | 
				
			||||||
#include "video_core/renderer_base.h"
 | 
					#include "video_core/renderer_base.h"
 | 
				
			||||||
#include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h"
 | 
					#include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user