yuzu-emu
/
yuzu
Archived
1
0
Fork 0

core/hid: Fully implement native mouse

This commit is contained in:
german77 2021-11-14 14:09:29 -06:00 committed by Narr the Reg
parent bca299e8e0
commit 654d76e79e
21 changed files with 323 additions and 1039 deletions

View File

@ -568,7 +568,6 @@ struct Values {
BasicSetting<bool> mouse_panning{false, "mouse_panning"}; BasicSetting<bool> mouse_panning{false, "mouse_panning"};
BasicRangedSetting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"}; BasicRangedSetting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"};
BasicSetting<bool> mouse_enabled{false, "mouse_enabled"}; BasicSetting<bool> mouse_enabled{false, "mouse_enabled"};
MouseButtonsRaw mouse_buttons;
BasicSetting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"}; BasicSetting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"};
BasicSetting<bool> keyboard_enabled{false, "keyboard_enabled"}; BasicSetting<bool> keyboard_enabled{false, "keyboard_enabled"};

View File

@ -126,6 +126,17 @@ constexpr int NUM_MOUSE_HID = NumMouseButtons;
extern const std::array<const char*, NumMouseButtons> mapping; extern const std::array<const char*, NumMouseButtons> mapping;
} // namespace NativeMouseButton } // namespace NativeMouseButton
namespace NativeMouseWheel {
enum Values {
X,
Y,
NumMouseWheels,
};
extern const std::array<const char*, NumMouseWheels> mapping;
} // namespace NativeMouseWheel
namespace NativeKeyboard { namespace NativeKeyboard {
enum Keys { enum Keys {
None, None,
@ -348,10 +359,6 @@ using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>;
using MotionsRaw = std::array<std::string, NativeMotion::NumMotions>; using MotionsRaw = std::array<std::string, NativeMotion::NumMotions>;
using VibrationsRaw = std::array<std::string, NativeVibration::NumVibrations>; using VibrationsRaw = std::array<std::string, NativeVibration::NumVibrations>;
using MouseButtonsRaw = std::array<std::string, NativeMouseButton::NumMouseButtons>;
using KeyboardKeysRaw = std::array<std::string, NativeKeyboard::NumKeyboardKeys>;
using KeyboardModsRaw = std::array<std::string, NativeKeyboard::NumKeyboardMods>;
constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28; constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28;
constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A; constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A;
constexpr u32 JOYCON_BODY_NEON_BLUE = 0x0AB9E6; constexpr u32 JOYCON_BODY_NEON_BLUE = 0x0AB9E6;

View File

@ -24,7 +24,10 @@ void EmulatedConsole::SetTouchParams() {
std::size_t index = 0; std::size_t index = 0;
// Hardcode mouse, touchscreen and cemuhook parameters // Hardcode mouse, touchscreen and cemuhook parameters
touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"}; if (!Settings::values.mouse_enabled) {
// We can't use mouse as touch if native mouse is enabled
touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
}
touch_params[index++] = Common::ParamPackage{"engine:touch,axis_x:0,axis_y:1,button:0"}; touch_params[index++] = Common::ParamPackage{"engine:touch,axis_x:0,axis_y:1,button:0"};
touch_params[index++] = Common::ParamPackage{"engine:touch,axis_x:2,axis_y:3,button:1"}; touch_params[index++] = Common::ParamPackage{"engine:touch,axis_x:2,axis_y:3,button:1"};
touch_params[index++] = Common::ParamPackage{"engine:cemuhookudp,axis_x:0,axis_y:1,button:0"}; touch_params[index++] = Common::ParamPackage{"engine:cemuhookudp,axis_x:0,axis_y:1,button:0"};
@ -36,6 +39,9 @@ void EmulatedConsole::SetTouchParams() {
// Map the rest of the fingers from touch from button configuration // Map the rest of the fingers from touch from button configuration
for (const auto& config_entry : touch_buttons) { for (const auto& config_entry : touch_buttons) {
if (index >= touch_params.size()) {
continue;
}
Common::ParamPackage params{config_entry}; Common::ParamPackage params{config_entry};
Common::ParamPackage touch_button_params; Common::ParamPackage touch_button_params;
const int x = params.Get("x", 0); const int x = params.Get("x", 0);
@ -49,9 +55,6 @@ void EmulatedConsole::SetTouchParams() {
touch_button_params.Set("touch_id", static_cast<int>(index)); touch_button_params.Set("touch_id", static_cast<int>(index));
touch_params[index] = touch_button_params; touch_params[index] = touch_button_params;
index++; index++;
if (index >= touch_params.size()) {
return;
}
} }
} }

View File

@ -15,21 +15,34 @@ EmulatedDevices::EmulatedDevices() = default;
EmulatedDevices::~EmulatedDevices() = default; EmulatedDevices::~EmulatedDevices() = default;
void EmulatedDevices::ReloadFromSettings() { void EmulatedDevices::ReloadFromSettings() {
const auto& mouse = Settings::values.mouse_buttons;
for (std::size_t index = 0; index < mouse.size(); ++index) {
mouse_button_params[index] = Common::ParamPackage(mouse[index]);
}
ReloadInput(); ReloadInput();
} }
void EmulatedDevices::ReloadInput() { void EmulatedDevices::ReloadInput() {
std::transform(mouse_button_params.begin() + Settings::NativeMouseButton::MOUSE_HID_BEGIN, // If you load any device here add the equivalent to the UnloadInput() function
mouse_button_params.begin() + Settings::NativeMouseButton::MOUSE_HID_END,
mouse_button_devices.begin(),
Common::Input::CreateDevice<Common::Input::InputDevice>);
std::size_t key_index = 0; std::size_t key_index = 0;
for (auto& mouse_device : mouse_button_devices) {
Common::ParamPackage mouse_params;
mouse_params.Set("engine", "mouse");
mouse_params.Set("button", static_cast<int>(key_index));
mouse_device = Common::Input::CreateDevice<Common::Input::InputDevice>(mouse_params);
key_index++;
}
mouse_stick_device = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
"engine:mouse,axis_x:0,axis_y:1");
// First two axis are reserved for mouse position
key_index = 2;
for (auto& mouse_device : mouse_analog_devices) {
Common::ParamPackage mouse_params;
mouse_params.Set("engine", "mouse");
mouse_params.Set("axis", static_cast<int>(key_index));
mouse_device = Common::Input::CreateDevice<Common::Input::InputDevice>(mouse_params);
key_index++;
}
key_index = 0;
for (auto& keyboard_device : keyboard_devices) { for (auto& keyboard_device : keyboard_devices) {
// Keyboard keys are only mapped on port 1, pad 0 // Keyboard keys are only mapped on port 1, pad 0
Common::ParamPackage keyboard_params; Common::ParamPackage keyboard_params;
@ -64,6 +77,23 @@ void EmulatedDevices::ReloadInput() {
mouse_button_devices[index]->SetCallback(button_callback); mouse_button_devices[index]->SetCallback(button_callback);
} }
for (std::size_t index = 0; index < mouse_analog_devices.size(); ++index) {
if (!mouse_analog_devices[index]) {
continue;
}
Common::Input::InputCallback button_callback{
[this, index](Common::Input::CallbackStatus callback) {
SetMouseAnalog(callback, index);
}};
mouse_analog_devices[index]->SetCallback(button_callback);
}
if (mouse_stick_device) {
Common::Input::InputCallback button_callback{
[this](Common::Input::CallbackStatus callback) { SetMouseStick(callback); }};
mouse_stick_device->SetCallback(button_callback);
}
for (std::size_t index = 0; index < keyboard_devices.size(); ++index) { for (std::size_t index = 0; index < keyboard_devices.size(); ++index) {
if (!keyboard_devices[index]) { if (!keyboard_devices[index]) {
continue; continue;
@ -91,6 +121,10 @@ void EmulatedDevices::UnloadInput() {
for (auto& button : mouse_button_devices) { for (auto& button : mouse_button_devices) {
button.reset(); button.reset();
} }
for (auto& analog : mouse_analog_devices) {
analog.reset();
}
mouse_stick_device.reset();
for (auto& button : keyboard_devices) { for (auto& button : keyboard_devices) {
button.reset(); button.reset();
} }
@ -116,12 +150,6 @@ void EmulatedDevices::SaveCurrentConfig() {
if (!is_configuring) { if (!is_configuring) {
return; return;
} }
auto& mouse = Settings::values.mouse_buttons;
for (std::size_t index = 0; index < mouse.size(); ++index) {
mouse[index] = mouse_button_params[index].Serialize();
}
} }
void EmulatedDevices::RestoreConfig() { void EmulatedDevices::RestoreConfig() {
@ -131,21 +159,6 @@ void EmulatedDevices::RestoreConfig() {
ReloadFromSettings(); ReloadFromSettings();
} }
Common::ParamPackage EmulatedDevices::GetMouseButtonParam(std::size_t index) const {
if (index >= mouse_button_params.size()) {
return {};
}
return mouse_button_params[index];
}
void EmulatedDevices::SetMouseButtonParam(std::size_t index, Common::ParamPackage param) {
if (index >= mouse_button_params.size()) {
return;
}
mouse_button_params[index] = param;
ReloadInput();
}
void EmulatedDevices::SetKeyboardButton(Common::Input::CallbackStatus callback, std::size_t index) { void EmulatedDevices::SetKeyboardButton(Common::Input::CallbackStatus callback, std::size_t index) {
if (index >= device_status.keyboard_values.size()) { if (index >= device_status.keyboard_values.size()) {
return; return;
@ -334,6 +347,51 @@ void EmulatedDevices::SetMouseButton(Common::Input::CallbackStatus callback, std
TriggerOnChange(DeviceTriggerType::Mouse); TriggerOnChange(DeviceTriggerType::Mouse);
} }
void EmulatedDevices::SetMouseAnalog(Common::Input::CallbackStatus callback, std::size_t index) {
if (index >= device_status.mouse_analog_values.size()) {
return;
}
std::lock_guard lock{mutex};
const auto analog_value = TransformToAnalog(callback);
device_status.mouse_analog_values[index] = analog_value;
if (is_configuring) {
device_status.mouse_position_state = {};
TriggerOnChange(DeviceTriggerType::Mouse);
return;
}
switch (index) {
case Settings::NativeMouseWheel::X:
device_status.mouse_wheel_state.x = static_cast<s32>(analog_value.value);
break;
case Settings::NativeMouseWheel::Y:
device_status.mouse_wheel_state.y = static_cast<s32>(analog_value.value);
break;
}
TriggerOnChange(DeviceTriggerType::Mouse);
}
void EmulatedDevices::SetMouseStick(Common::Input::CallbackStatus callback) {
std::lock_guard lock{mutex};
const auto stick_value = TransformToStick(callback);
device_status.mouse_stick_value = stick_value;
if (is_configuring) {
device_status.mouse_position_state = {};
TriggerOnChange(DeviceTriggerType::Mouse);
return;
}
device_status.mouse_position_state.x = stick_value.x.value;
device_status.mouse_position_state.y = stick_value.y.value;
TriggerOnChange(DeviceTriggerType::Mouse);
}
KeyboardValues EmulatedDevices::GetKeyboardValues() const { KeyboardValues EmulatedDevices::GetKeyboardValues() const {
return device_status.keyboard_values; return device_status.keyboard_values;
} }
@ -362,6 +420,10 @@ MousePosition EmulatedDevices::GetMousePosition() const {
return device_status.mouse_position_state; return device_status.mouse_position_state;
} }
AnalogStickState EmulatedDevices::GetMouseDeltaWheel() const {
return device_status.mouse_wheel_state;
}
void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) { void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) {
for (const auto& poller_pair : callback_list) { for (const auto& poller_pair : callback_list) {
const InterfaceUpdateCallback& poller = poller_pair.second; const InterfaceUpdateCallback& poller = poller_pair.second;

View File

@ -17,13 +17,15 @@
#include "core/hid/hid_types.h" #include "core/hid/hid_types.h"
namespace Core::HID { namespace Core::HID {
using KeyboardDevices = std::array<std::unique_ptr<Common::Input::InputDevice>, using KeyboardDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
Settings::NativeKeyboard::NumKeyboardKeys>; Settings::NativeKeyboard::NumKeyboardKeys>;
using KeyboardModifierDevices = std::array<std::unique_ptr<Common::Input::InputDevice>, using KeyboardModifierDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
Settings::NativeKeyboard::NumKeyboardMods>; Settings::NativeKeyboard::NumKeyboardMods>;
using MouseButtonDevices = std::array<std::unique_ptr<Common::Input::InputDevice>, using MouseButtonDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
Settings::NativeMouseButton::NumMouseButtons>; Settings::NativeMouseButton::NumMouseButtons>;
using MouseAnalogDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
Settings::NativeMouseWheel::NumMouseWheels>;
using MouseStickDevice = std::unique_ptr<Common::Input::InputDevice>;
using MouseButtonParams = using MouseButtonParams =
std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons>; std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons>;
@ -34,12 +36,13 @@ using KeyboardModifierValues =
std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardMods>; std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardMods>;
using MouseButtonValues = using MouseButtonValues =
std::array<Common::Input::ButtonStatus, Settings::NativeMouseButton::NumMouseButtons>; std::array<Common::Input::ButtonStatus, Settings::NativeMouseButton::NumMouseButtons>;
using MouseAnalogValues =
std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>;
using MouseStickValue = Common::Input::StickStatus;
struct MousePosition { struct MousePosition {
s32 x; f32 x;
s32 y; f32 y;
s32 delta_wheel_x;
s32 delta_wheel_y;
}; };
struct DeviceStatus { struct DeviceStatus {
@ -47,12 +50,15 @@ struct DeviceStatus {
KeyboardValues keyboard_values{}; KeyboardValues keyboard_values{};
KeyboardModifierValues keyboard_moddifier_values{}; KeyboardModifierValues keyboard_moddifier_values{};
MouseButtonValues mouse_button_values{}; MouseButtonValues mouse_button_values{};
MouseAnalogValues mouse_analog_values{};
MouseStickValue mouse_stick_value{};
// Data for HID serices // Data for HID serices
KeyboardKey keyboard_state{}; KeyboardKey keyboard_state{};
KeyboardModifier keyboard_moddifier_state{}; KeyboardModifier keyboard_moddifier_state{};
MouseButton mouse_button_state{}; MouseButton mouse_button_state{};
MousePosition mouse_position_state{}; MousePosition mouse_position_state{};
AnalogStickState mouse_wheel_state{};
}; };
enum class DeviceTriggerType { enum class DeviceTriggerType {
@ -102,15 +108,6 @@ public:
/// Reverts any mapped changes made that weren't saved /// Reverts any mapped changes made that weren't saved
void RestoreConfig(); void RestoreConfig();
/// Returns the current mapped mouse button device
Common::ParamPackage GetMouseButtonParam(std::size_t index) const;
/**
* Updates the current mapped mouse button device
* @param ParamPackage with controller data to be mapped
*/
void SetMouseButtonParam(std::size_t index, Common::ParamPackage param);
/// Returns the latest status of button input from the keyboard with parameters /// Returns the latest status of button input from the keyboard with parameters
KeyboardValues GetKeyboardValues() const; KeyboardValues GetKeyboardValues() const;
@ -132,9 +129,12 @@ public:
/// Returns the latest mouse coordinates /// Returns the latest mouse coordinates
MousePosition GetMousePosition() const; MousePosition GetMousePosition() const;
/// Returns the latest mouse wheel change
AnalogStickState GetMouseDeltaWheel() const;
/** /**
* Adds a callback to the list of events * Adds a callback to the list of events
* @param ConsoleUpdateCallback that will be triggered * @param InterfaceUpdateCallback that will be triggered
* @return an unique key corresponding to the callback index in the list * @return an unique key corresponding to the callback index in the list
*/ */
int SetCallback(InterfaceUpdateCallback update_callback); int SetCallback(InterfaceUpdateCallback update_callback);
@ -150,26 +150,40 @@ private:
void UpdateKey(std::size_t key_index, bool status); void UpdateKey(std::size_t key_index, bool status);
/** /**
* Updates the touch status of the console * Updates the touch status of the keyboard device
* @param callback: A CallbackStatus containing the key status * @param callback: A CallbackStatus containing the key status
* @param index: key ID to be updated * @param index: key ID to be updated
*/ */
void SetKeyboardButton(Common::Input::CallbackStatus callback, std::size_t index); void SetKeyboardButton(Common::Input::CallbackStatus callback, std::size_t index);
/** /**
* Updates the touch status of the console * Updates the keyboard status of the keyboard device
* @param callback: A CallbackStatus containing the modifier key status * @param callback: A CallbackStatus containing the modifier key status
* @param index: modifier key ID to be updated * @param index: modifier key ID to be updated
*/ */
void SetKeyboardModifier(Common::Input::CallbackStatus callback, std::size_t index); void SetKeyboardModifier(Common::Input::CallbackStatus callback, std::size_t index);
/** /**
* Updates the touch status of the console * Updates the mouse button status of the mouse device
* @param callback: A CallbackStatus containing the button status * @param callback: A CallbackStatus containing the button status
* @param index: Button ID of the to be updated * @param index: Button ID to be updated
*/ */
void SetMouseButton(Common::Input::CallbackStatus callback, std::size_t index); void SetMouseButton(Common::Input::CallbackStatus callback, std::size_t index);
/**
* Updates the mouse wheel status of the mouse device
* @param callback: A CallbackStatus containing the wheel status
* @param index: wheel ID to be updated
*/
void SetMouseAnalog(Common::Input::CallbackStatus callback, std::size_t index);
/**
* Updates the mouse position status of the mouse device
* @param callback: A CallbackStatus containing the position status
* @param index: stick ID to be updated
*/
void SetMouseStick(Common::Input::CallbackStatus callback);
/** /**
* Triggers a callback that something has changed on the device status * Triggers a callback that something has changed on the device status
* @param Input type of the event to trigger * @param Input type of the event to trigger
@ -178,11 +192,11 @@ private:
bool is_configuring{false}; bool is_configuring{false};
MouseButtonParams mouse_button_params;
KeyboardDevices keyboard_devices; KeyboardDevices keyboard_devices;
KeyboardModifierDevices keyboard_modifier_devices; KeyboardModifierDevices keyboard_modifier_devices;
MouseButtonDevices mouse_button_devices; MouseButtonDevices mouse_button_devices;
MouseAnalogDevices mouse_analog_devices;
MouseStickDevice mouse_stick_device;
mutable std::mutex mutex; mutable std::mutex mutex;
std::unordered_map<int, InterfaceUpdateCallback> callback_list; std::unordered_map<int, InterfaceUpdateCallback> callback_list;

View File

@ -242,6 +242,27 @@ Common::Input::TriggerStatus TransformToTrigger(const Common::Input::CallbackSta
return status; return status;
} }
Common::Input::AnalogStatus TransformToAnalog(const Common::Input::CallbackStatus& callback) {
Common::Input::AnalogStatus status{};
switch (callback.type) {
case Common::Input::InputType::Analog:
status.properties = callback.analog_status.properties;
status.raw_value = callback.analog_status.raw_value;
break;
default:
LOG_ERROR(Input, "Conversion from type {} to analog not implemented", callback.type);
break;
}
SanitizeAnalog(status, false);
// Adjust if value is inverted
status.value = status.properties.inverted ? -status.value : status.value;
return status;
}
void SanitizeAnalog(Common::Input::AnalogStatus& analog, bool clamp_value) { void SanitizeAnalog(Common::Input::AnalogStatus& analog, bool clamp_value) {
const auto& properties = analog.properties; const auto& properties = analog.properties;
float& raw_value = analog.raw_value; float& raw_value = analog.raw_value;

View File

@ -68,6 +68,15 @@ Common::Input::TouchStatus TransformToTouch(const Common::Input::CallbackStatus&
*/ */
Common::Input::TriggerStatus TransformToTrigger(const Common::Input::CallbackStatus& callback); Common::Input::TriggerStatus TransformToTrigger(const Common::Input::CallbackStatus& callback);
/**
* Converts raw input data into a valid analog status. Applies offset, deadzone, range and
* invert properties to the output.
*
* @param Supported callbacks: Analog.
* @return A valid AnalogStatus object.
*/
Common::Input::AnalogStatus TransformToAnalog(const Common::Input::CallbackStatus& callback);
/** /**
* Converts raw analog data into a valid analog value * Converts raw analog data into a valid analog value
* @param An analog object containing raw data and properties, bool that determines if the value * @param An analog object containing raw data and properties, bool that determines if the value

View File

@ -38,13 +38,14 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
if (Settings::values.mouse_enabled) { if (Settings::values.mouse_enabled) {
const auto& mouse_button_state = emulated_devices->GetMouseButtons(); const auto& mouse_button_state = emulated_devices->GetMouseButtons();
const auto& mouse_position_state = emulated_devices->GetMousePosition(); const auto& mouse_position_state = emulated_devices->GetMousePosition();
const auto& mouse_wheel_state = emulated_devices->GetMouseDeltaWheel();
next_state.attribute.is_connected.Assign(1); next_state.attribute.is_connected.Assign(1);
next_state.x = mouse_position_state.x; next_state.x = static_cast<s32>(mouse_position_state.x * Layout::ScreenUndocked::Width);
next_state.y = mouse_position_state.y; next_state.y = static_cast<s32>(mouse_position_state.y * Layout::ScreenUndocked::Height);
next_state.delta_x = next_state.x - last_entry.x; next_state.delta_x = next_state.x - last_entry.x;
next_state.delta_y = next_state.y - last_entry.y; next_state.delta_y = next_state.y - last_entry.y;
next_state.delta_wheel_x = mouse_position_state.delta_wheel_x; next_state.delta_wheel_x = mouse_wheel_state.x;
next_state.delta_wheel_y = mouse_position_state.delta_wheel_y; next_state.delta_wheel_y = mouse_wheel_state.y;
next_state.button = mouse_button_state; next_state.button = mouse_button_state;
} }

View File

@ -12,6 +12,10 @@
#include "input_common/drivers/mouse.h" #include "input_common/drivers/mouse.h"
namespace InputCommon { namespace InputCommon {
constexpr int mouse_axis_x = 0;
constexpr int mouse_axis_y = 1;
constexpr int wheel_axis_x = 2;
constexpr int wheel_axis_y = 3;
constexpr int touch_axis_x = 10; constexpr int touch_axis_x = 10;
constexpr int touch_axis_y = 11; constexpr int touch_axis_y = 11;
constexpr PadIdentifier identifier = { constexpr PadIdentifier identifier = {
@ -22,6 +26,12 @@ constexpr PadIdentifier identifier = {
Mouse::Mouse(const std::string input_engine_) : InputEngine(input_engine_) { Mouse::Mouse(const std::string input_engine_) : InputEngine(input_engine_) {
PreSetController(identifier); PreSetController(identifier);
PreSetAxis(identifier, mouse_axis_x);
PreSetAxis(identifier, mouse_axis_y);
PreSetAxis(identifier, wheel_axis_x);
PreSetAxis(identifier, wheel_axis_y);
PreSetAxis(identifier, touch_axis_x);
PreSetAxis(identifier, touch_axis_x);
update_thread = std::jthread([this](std::stop_token stop_token) { UpdateThread(stop_token); }); update_thread = std::jthread([this](std::stop_token stop_token) { UpdateThread(stop_token); });
} }
@ -34,14 +44,18 @@ void Mouse::UpdateThread(std::stop_token stop_token) {
last_mouse_change *= 0.96f; last_mouse_change *= 0.96f;
const float sensitivity = const float sensitivity =
Settings::values.mouse_panning_sensitivity.GetValue() * 0.022f; Settings::values.mouse_panning_sensitivity.GetValue() * 0.022f;
SetAxis(identifier, 0, last_mouse_change.x * sensitivity); SetAxis(identifier, mouse_axis_x, last_mouse_change.x * sensitivity);
SetAxis(identifier, 1, -last_mouse_change.y * sensitivity); SetAxis(identifier, mouse_axis_y, -last_mouse_change.y * sensitivity);
} }
if (mouse_panning_timout++ > 20) { if (mouse_panning_timout++ > 20) {
StopPanning(); StopPanning();
} }
std::this_thread::sleep_for(std::chrono::milliseconds(update_time)); std::this_thread::sleep_for(std::chrono::milliseconds(update_time));
// Reset wheel position
SetAxis(identifier, wheel_axis_x, 0);
SetAxis(identifier, wheel_axis_y, 0);
} }
} }
@ -89,8 +103,8 @@ void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int
if (button_pressed) { if (button_pressed) {
const auto mouse_move = Common::MakeVec<int>(x, y) - mouse_origin; const auto mouse_move = Common::MakeVec<int>(x, y) - mouse_origin;
const float sensitivity = Settings::values.mouse_panning_sensitivity.GetValue() * 0.0012f; const float sensitivity = Settings::values.mouse_panning_sensitivity.GetValue() * 0.0012f;
SetAxis(identifier, 0, static_cast<float>(mouse_move.x) * sensitivity); SetAxis(identifier, mouse_axis_x, static_cast<float>(mouse_move.x) * sensitivity);
SetAxis(identifier, 1, static_cast<float>(-mouse_move.y) * sensitivity); SetAxis(identifier, mouse_axis_y, static_cast<float>(-mouse_move.y) * sensitivity);
} }
} }
@ -108,12 +122,17 @@ void Mouse::ReleaseButton(MouseButton button) {
SetButton(identifier, static_cast<int>(button), false); SetButton(identifier, static_cast<int>(button), false);
if (!Settings::values.mouse_panning) { if (!Settings::values.mouse_panning) {
SetAxis(identifier, 0, 0); SetAxis(identifier, mouse_axis_x, 0);
SetAxis(identifier, 1, 0); SetAxis(identifier, mouse_axis_y, 0);
} }
button_pressed = false; button_pressed = false;
} }
void Mouse::MouseWheelChange(int x, int y) {
SetAxis(identifier, wheel_axis_x, static_cast<f32>(x));
SetAxis(identifier, wheel_axis_y, static_cast<f32>(y));
}
void Mouse::ReleaseAllButtons() { void Mouse::ReleaseAllButtons() {
ResetButtonState(); ResetButtonState();
button_pressed = false; button_pressed = false;

View File

@ -52,6 +52,13 @@ public:
*/ */
void ReleaseButton(MouseButton button); void ReleaseButton(MouseButton button);
/**
* Sets the status of the mouse wheel
* @param x delta movement in the x direction
* @param y delta movement in the y direction
*/
void MouseWheelChange(int x, int y);
void ReleaseAllButtons(); void ReleaseAllButtons();
std::vector<Common::ParamPackage> GetInputDevices() const override; std::vector<Common::ParamPackage> GetInputDevices() const override;

View File

@ -90,9 +90,6 @@ add_executable(yuzu
configuration/configure_motion_touch.cpp configuration/configure_motion_touch.cpp
configuration/configure_motion_touch.h configuration/configure_motion_touch.h
configuration/configure_motion_touch.ui configuration/configure_motion_touch.ui
configuration/configure_mouse_advanced.cpp
configuration/configure_mouse_advanced.h
configuration/configure_mouse_advanced.ui
configuration/configure_per_game.cpp configuration/configure_per_game.cpp
configuration/configure_per_game.h configuration/configure_per_game.h
configuration/configure_per_game.ui configuration/configure_per_game.ui

View File

@ -746,6 +746,12 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
input_subsystem->GetMouse()->ReleaseButton(button); input_subsystem->GetMouse()->ReleaseButton(button);
} }
void GRenderWindow::wheelEvent(QWheelEvent* event) {
const int x = event->delta();
const int y = 0;
input_subsystem->GetMouse()->MouseWheelChange(x, y);
}
void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) { void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) {
QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints(); QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints();
for (const auto& touch_point : touch_points) { for (const auto& touch_point : touch_points) {

View File

@ -173,6 +173,7 @@ public:
void mousePressEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override;
void wheelEvent(QWheelEvent* event) override;
bool event(QEvent* event) override; bool event(QEvent* event) override;

View File

@ -60,11 +60,6 @@ const std::array<int, 2> Config::default_stick_mod = {
0, 0,
}; };
const std::array<int, Settings::NativeMouseButton::NumMouseButtons> Config::default_mouse_buttons =
{
Qt::Key_BracketLeft, Qt::Key_BracketRight, Qt::Key_Apostrophe, Qt::Key_Minus, Qt::Key_Equal,
};
// This shouldn't have anything except static initializers (no functions). So // This shouldn't have anything except static initializers (no functions). So
// QKeySequence(...).toString() is NOT ALLOWED HERE. // QKeySequence(...).toString() is NOT ALLOWED HERE.
// This must be in alphabetical order according to action name as it must have the same order as // This must be in alphabetical order according to action name as it must have the same order as
@ -348,22 +343,6 @@ void Config::ReadKeyboardValues() {
void Config::ReadMouseValues() { void Config::ReadMouseValues() {
ReadBasicSetting(Settings::values.mouse_enabled); ReadBasicSetting(Settings::values.mouse_enabled);
for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
const std::string default_param =
InputCommon::GenerateKeyboardParam(default_mouse_buttons[i]);
auto& mouse_buttons = Settings::values.mouse_buttons[i];
mouse_buttons = qt_config
->value(QStringLiteral("mouse_") +
QString::fromUtf8(Settings::NativeMouseButton::mapping[i]),
QString::fromStdString(default_param))
.toString()
.toStdString();
if (mouse_buttons.empty()) {
mouse_buttons = default_param;
}
}
} }
void Config::ReadTouchscreenValues() { void Config::ReadTouchscreenValues() {
@ -947,15 +926,6 @@ void Config::SaveDebugValues() {
void Config::SaveMouseValues() { void Config::SaveMouseValues() {
WriteBasicSetting(Settings::values.mouse_enabled); WriteBasicSetting(Settings::values.mouse_enabled);
for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
const std::string default_param =
InputCommon::GenerateKeyboardParam(default_mouse_buttons[i]);
WriteSetting(QStringLiteral("mouse_") +
QString::fromStdString(Settings::NativeMouseButton::mapping[i]),
QString::fromStdString(Settings::values.mouse_buttons[i]),
QString::fromStdString(default_param));
}
} }
void Config::SaveTouchscreenValues() { void Config::SaveTouchscreenValues() {

View File

@ -24,7 +24,6 @@
#include "yuzu/configuration/configure_input_advanced.h" #include "yuzu/configuration/configure_input_advanced.h"
#include "yuzu/configuration/configure_input_player.h" #include "yuzu/configuration/configure_input_player.h"
#include "yuzu/configuration/configure_motion_touch.h" #include "yuzu/configuration/configure_motion_touch.h"
#include "yuzu/configuration/configure_mouse_advanced.h"
#include "yuzu/configuration/configure_touchscreen_advanced.h" #include "yuzu/configuration/configure_touchscreen_advanced.h"
#include "yuzu/configuration/configure_vibration.h" #include "yuzu/configuration/configure_vibration.h"
#include "yuzu/configuration/input_profiles.h" #include "yuzu/configuration/input_profiles.h"
@ -157,9 +156,6 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
CallConfigureDialog<ConfigureDebugController>( CallConfigureDialog<ConfigureDebugController>(
*this, input_subsystem, profiles.get(), hid_core, is_powered_on); *this, input_subsystem, profiles.get(), hid_core, is_powered_on);
}); });
connect(advanced, &ConfigureInputAdvanced::CallMouseConfigDialog, [this, input_subsystem] {
CallConfigureDialog<ConfigureMouseAdvanced>(*this, input_subsystem);
});
connect(advanced, &ConfigureInputAdvanced::CallTouchscreenConfigDialog, connect(advanced, &ConfigureInputAdvanced::CallTouchscreenConfigDialog,
[this] { CallConfigureDialog<ConfigureTouchscreenAdvanced>(*this); }); [this] { CallConfigureDialog<ConfigureTouchscreenAdvanced>(*this); });
connect(advanced, &ConfigureInputAdvanced::CallMotionTouchConfigDialog, connect(advanced, &ConfigureInputAdvanced::CallMotionTouchConfigDialog,

View File

@ -82,7 +82,6 @@ ConfigureInputAdvanced::ConfigureInputAdvanced(QWidget* parent)
connect(ui->debug_configure, &QPushButton::clicked, this, connect(ui->debug_configure, &QPushButton::clicked, this,
[this] { CallDebugControllerDialog(); }); [this] { CallDebugControllerDialog(); });
connect(ui->mouse_advanced, &QPushButton::clicked, this, [this] { CallMouseConfigDialog(); });
connect(ui->touchscreen_advanced, &QPushButton::clicked, this, connect(ui->touchscreen_advanced, &QPushButton::clicked, this,
[this] { CallTouchscreenConfigDialog(); }); [this] { CallTouchscreenConfigDialog(); });
connect(ui->buttonMotionTouch, &QPushButton::clicked, this, connect(ui->buttonMotionTouch, &QPushButton::clicked, this,
@ -178,7 +177,6 @@ void ConfigureInputAdvanced::RetranslateUI() {
} }
void ConfigureInputAdvanced::UpdateUIEnabled() { void ConfigureInputAdvanced::UpdateUIEnabled() {
ui->mouse_advanced->setEnabled(ui->mouse_enabled->isChecked());
ui->debug_configure->setEnabled(ui->debug_enabled->isChecked()); ui->debug_configure->setEnabled(ui->debug_enabled->isChecked());
ui->touchscreen_advanced->setEnabled(ui->touchscreen_enabled->isChecked()); ui->touchscreen_advanced->setEnabled(ui->touchscreen_enabled->isChecked());
} }

View File

@ -2528,11 +2528,11 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="QGroupBox" name="gridGroupBox_3"> <widget class="QGroupBox" name="emulatedDevicesGroupBox">
<property name="title"> <property name="title">
<string>Other</string> <string>Emulated Devices</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="emulatedDevicesGridLayout">
<item row="0" column="0"> <item row="0" column="0">
<widget class="QCheckBox" name="keyboard_enabled"> <widget class="QCheckBox" name="keyboard_enabled">
<property name="minimumSize"> <property name="minimumSize">
@ -2547,7 +2547,7 @@
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QCheckBox" name="emulate_analog_keyboard"> <widget class="QCheckBox" name="mouse_enabled">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>0</width>
@ -2555,53 +2555,18 @@
</size> </size>
</property> </property>
<property name="text"> <property name="text">
<string>Emulate Analog with Keyboard Input</string> <string>Mouse</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QCheckBox" name="mouse_panning"> <widget class="QCheckBox" name="touchscreen_enabled">
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text"> <property name="text">
<string>Enable mouse panning</string> <string>Touchscreen</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="2"> <item row="2" column="1">
<widget class="QSpinBox" name="mouse_panning_sensitivity">
<property name="toolTip">
<string>Mouse sensitivity</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="suffix">
<string>%</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QPushButton" name="touchscreen_advanced">
<property name="text">
<string>Advanced</string>
</property>
</widget>
</item>
<item row="3" column="1">
<spacer name="horizontalSpacer_8"> <spacer name="horizontalSpacer_8">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -2617,80 +2582,117 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="3" column="2"> <item row="2" column="2">
<widget class="QPushButton" name="mouse_advanced"> <widget class="QPushButton" name="touchscreen_advanced">
<property name="text"> <property name="text">
<string>Advanced</string> <string>Advanced</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0">
<widget class="QCheckBox" name="touchscreen_enabled">
<property name="text">
<string>Touchscreen</string>
</property>
</widget>
</item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QCheckBox" name="mouse_enabled">
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Mouse</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="motion_touch">
<property name="text">
<string>Motion / Touch</string>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QPushButton" name="buttonMotionTouch">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="debug_enabled"> <widget class="QCheckBox" name="debug_enabled">
<property name="text"> <property name="text">
<string>Debug Controller</string> <string>Debug Controller</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="2"> <item row="3" column="2">
<widget class="QPushButton" name="debug_configure"> <widget class="QPushButton" name="debug_configure">
<property name="text"> <property name="text">
<string>Configure</string> <string>Configure</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="0">
<widget class="QCheckBox" name="enable_raw_input">
<property name="toolTip">
<string>Requires restarting yuzu</string>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Enable XInput 8 player support (disables web applet)</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QGroupBox" name="otherGroupBox">
<property name="title">
<string>Other</string>
</property>
<layout class="QGridLayout" name="OtherGridLayout">
<item row="1" column="0">
<widget class="QCheckBox" name="emulate_analog_keyboard">
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Emulate Analog with Keyboard Input</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="enable_raw_input">
<property name="toolTip">
<string>Requires restarting yuzu</string>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Enable XInput 8 player support (disables web applet)</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="mouse_panning">
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Enable mouse panning</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="mouse_panning_sensitivity">
<property name="toolTip">
<string>Mouse sensitivity</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="suffix">
<string>%</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="motion_touch">
<property name="text">
<string>Motion / Touch</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QPushButton" name="buttonMotionTouch">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">

View File

@ -1,247 +0,0 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include <memory>
#include <QKeyEvent>
#include <QMenu>
#include <QTimer>
#include "common/assert.h"
#include "common/param_package.h"
#include "input_common/drivers/keyboard.h"
#include "input_common/drivers/mouse.h"
#include "input_common/main.h"
#include "ui_configure_mouse_advanced.h"
#include "yuzu/bootmanager.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_mouse_advanced.h"
static QString GetKeyName(int key_code) {
switch (key_code) {
case Qt::LeftButton:
return QObject::tr("Click 0");
case Qt::RightButton:
return QObject::tr("Click 1");
case Qt::MiddleButton:
return QObject::tr("Click 2");
case Qt::BackButton:
return QObject::tr("Click 3");
case Qt::ForwardButton:
return QObject::tr("Click 4");
case Qt::Key_Shift:
return QObject::tr("Shift");
case Qt::Key_Control:
return QObject::tr("Ctrl");
case Qt::Key_Alt:
return QObject::tr("Alt");
case Qt::Key_Meta:
return {};
default:
return QKeySequence(key_code).toString();
}
}
static QString ButtonToText(const Common::ParamPackage& param) {
if (!param.Has("engine")) {
return QObject::tr("[not set]");
}
if (param.Get("engine", "") == "keyboard") {
return GetKeyName(param.Get("code", 0));
}
if (param.Get("engine", "") == "sdl") {
if (param.Has("hat")) {
const QString hat_str = QString::fromStdString(param.Get("hat", ""));
const QString direction_str = QString::fromStdString(param.Get("direction", ""));
return QObject::tr("Hat %1 %2").arg(hat_str, direction_str);
}
if (param.Has("axis")) {
const QString axis_str = QString::fromStdString(param.Get("axis", ""));
const QString direction_str = QString::fromStdString(param.Get("direction", ""));
return QObject::tr("Axis %1%2").arg(axis_str, direction_str);
}
if (param.Has("button")) {
const QString button_str = QString::fromStdString(param.Get("button", ""));
return QObject::tr("Button %1").arg(button_str);
}
return {};
}
return QObject::tr("[unknown]");
}
ConfigureMouseAdvanced::ConfigureMouseAdvanced(QWidget* parent,
InputCommon::InputSubsystem* input_subsystem_)
: QDialog(parent),
ui(std::make_unique<Ui::ConfigureMouseAdvanced>()), input_subsystem{input_subsystem_},
timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) {
ui->setupUi(this);
setFocusPolicy(Qt::ClickFocus);
button_map = {
ui->left_button, ui->right_button, ui->middle_button, ui->forward_button, ui->back_button,
};
for (int button_id = 0; button_id < Settings::NativeMouseButton::NumMouseButtons; button_id++) {
auto* const button = button_map[button_id];
if (button == nullptr) {
continue;
}
button->setContextMenuPolicy(Qt::CustomContextMenu);
connect(button, &QPushButton::clicked, [=, this] {
HandleClick(
button_map[button_id],
[=, this](const Common::ParamPackage& params) {
buttons_param[button_id] = params;
},
InputCommon::Polling::InputType::Button);
});
connect(button, &QPushButton::customContextMenuRequested,
[=, this](const QPoint& menu_location) {
QMenu context_menu;
context_menu.addAction(tr("Clear"), [&] {
buttons_param[button_id].Clear();
button_map[button_id]->setText(tr("[not set]"));
});
context_menu.addAction(tr("Restore Default"), [&] {
buttons_param[button_id] =
Common::ParamPackage{InputCommon::GenerateKeyboardParam(
Config::default_mouse_buttons[button_id])};
button_map[button_id]->setText(ButtonToText(buttons_param[button_id]));
});
context_menu.exec(button_map[button_id]->mapToGlobal(menu_location));
});
}
connect(ui->buttonClearAll, &QPushButton::clicked, [this] { ClearAll(); });
connect(ui->buttonRestoreDefaults, &QPushButton::clicked, [this] { RestoreDefaults(); });
timeout_timer->setSingleShot(true);
connect(timeout_timer.get(), &QTimer::timeout, [this] { SetPollingResult({}, true); });
connect(poll_timer.get(), &QTimer::timeout, [this] {
const auto& params = input_subsystem->GetNextInput();
if (params.Has("engine")) {
SetPollingResult(params, false);
return;
}
});
LoadConfiguration();
resize(0, 0);
}
ConfigureMouseAdvanced::~ConfigureMouseAdvanced() = default;
void ConfigureMouseAdvanced::ApplyConfiguration() {
std::transform(buttons_param.begin(), buttons_param.end(),
Settings::values.mouse_buttons.begin(),
[](const Common::ParamPackage& param) { return param.Serialize(); });
}
void ConfigureMouseAdvanced::LoadConfiguration() {
std::transform(Settings::values.mouse_buttons.begin(), Settings::values.mouse_buttons.end(),
buttons_param.begin(),
[](const std::string& str) { return Common::ParamPackage(str); });
UpdateButtonLabels();
}
void ConfigureMouseAdvanced::changeEvent(QEvent* event) {
if (event->type() == QEvent::LanguageChange) {
RetranslateUI();
}
QDialog::changeEvent(event);
}
void ConfigureMouseAdvanced::RetranslateUI() {
ui->retranslateUi(this);
}
void ConfigureMouseAdvanced::RestoreDefaults() {
for (int button_id = 0; button_id < Settings::NativeMouseButton::NumMouseButtons; button_id++) {
buttons_param[button_id] = Common::ParamPackage{
InputCommon::GenerateKeyboardParam(Config::default_mouse_buttons[button_id])};
}
UpdateButtonLabels();
}
void ConfigureMouseAdvanced::ClearAll() {
for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
const auto* const button = button_map[i];
if (button != nullptr && button->isEnabled()) {
buttons_param[i].Clear();
}
}
UpdateButtonLabels();
}
void ConfigureMouseAdvanced::UpdateButtonLabels() {
for (int button = 0; button < Settings::NativeMouseButton::NumMouseButtons; button++) {
button_map[button]->setText(ButtonToText(buttons_param[button]));
}
}
void ConfigureMouseAdvanced::HandleClick(
QPushButton* button, std::function<void(const Common::ParamPackage&)> new_input_setter,
InputCommon::Polling::InputType type) {
button->setText(tr("[press key]"));
button->setFocus();
input_setter = new_input_setter;
input_subsystem->BeginMapping(type);
QWidget::grabMouse();
QWidget::grabKeyboard();
timeout_timer->start(2500); // Cancel after 2.5 seconds
poll_timer->start(50); // Check for new inputs every 50ms
}
void ConfigureMouseAdvanced::SetPollingResult(const Common::ParamPackage& params, bool abort) {
timeout_timer->stop();
poll_timer->stop();
input_subsystem->StopMapping();
QWidget::releaseMouse();
QWidget::releaseKeyboard();
if (!abort) {
(*input_setter)(params);
}
UpdateButtonLabels();
input_setter = std::nullopt;
}
void ConfigureMouseAdvanced::mousePressEvent(QMouseEvent* event) {
if (!input_setter || !event) {
return;
}
const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
input_subsystem->GetMouse()->PressButton(0, 0, 0, 0, button);
}
void ConfigureMouseAdvanced::keyPressEvent(QKeyEvent* event) {
if (!input_setter || !event) {
return;
}
if (event->key() != Qt::Key_Escape) {
input_subsystem->GetKeyboard()->PressKey(event->key());
}
}

View File

@ -1,72 +0,0 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <optional>
#include <QDialog>
class QCheckBox;
class QPushButton;
class QTimer;
namespace InputCommon {
class InputSubsystem;
}
namespace Ui {
class ConfigureMouseAdvanced;
}
class ConfigureMouseAdvanced : public QDialog {
Q_OBJECT
public:
explicit ConfigureMouseAdvanced(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_);
~ConfigureMouseAdvanced() override;
void ApplyConfiguration();
private:
void changeEvent(QEvent* event) override;
void RetranslateUI();
/// Load configuration settings.
void LoadConfiguration();
/// Restore all buttons to their default values.
void RestoreDefaults();
/// Clear all input configuration
void ClearAll();
/// Update UI to reflect current configuration.
void UpdateButtonLabels();
/// Called when the button was pressed.
void HandleClick(QPushButton* button,
std::function<void(const Common::ParamPackage&)> new_input_setter,
InputCommon::Polling::InputType type);
/// Finish polling and configure input using the input_setter
void SetPollingResult(const Common::ParamPackage& params, bool abort);
/// Handle mouse button press events.
void mousePressEvent(QMouseEvent* event) override;
/// Handle key press events.
void keyPressEvent(QKeyEvent* event) override;
std::unique_ptr<Ui::ConfigureMouseAdvanced> ui;
InputCommon::InputSubsystem* input_subsystem;
/// This will be the the setting function when an input is awaiting configuration.
std::optional<std::function<void(const Common::ParamPackage&)>> input_setter;
std::array<QPushButton*, Settings::NativeMouseButton::NumMouseButtons> button_map;
std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons> buttons_param;
std::unique_ptr<QTimer> timeout_timer;
std::unique_ptr<QTimer> poll_timer;
};

View File

@ -1,335 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConfigureMouseAdvanced</class>
<widget class="QDialog" name="ConfigureMouseAdvanced">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>310</width>
<height>193</height>
</rect>
</property>
<property name="windowTitle">
<string>Configure Mouse</string>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
min-width: 60px;
}</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="gridGroupBox">
<property name="title">
<string>Mouse Buttons</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="5">
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Forward:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="forward_button">
<property name="minimumSize">
<size>
<width>68</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>68</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="1">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="minimumSize">
<size>
<width>54</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Back:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="back_button">
<property name="minimumSize">
<size>
<width>68</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Left:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="left_button">
<property name="minimumSize">
<size>
<width>68</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="3">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Middle:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="middle_button">
<property name="minimumSize">
<size>
<width>68</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>68</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="6">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="5">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Right:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="right_button">
<property name="minimumSize">
<size>
<width>68</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>68</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="4">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QPushButton" name="buttonClearAll">
<property name="minimumSize">
<size>
<width>68</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>68</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonRestoreDefaults">
<property name="minimumSize">
<size>
<width>68</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>68</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Defaults</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ConfigureMouseAdvanced</receiver>
<slot>accept()</slot>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ConfigureMouseAdvanced</receiver>
<slot>reject()</slot>
</connection>
</connections>
</ui>

View File

@ -83,163 +83,6 @@ static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs>
}, },
}}; }};
static const std::array<int, Settings::NativeMouseButton::NumMouseButtons> default_mouse_buttons = {
SDL_SCANCODE_LEFTBRACKET, SDL_SCANCODE_RIGHTBRACKET, SDL_SCANCODE_APOSTROPHE,
SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS,
};
static const std::array<int, 0x8A> keyboard_keys = {
0,
0,
0,
0,
SDL_SCANCODE_A,
SDL_SCANCODE_B,
SDL_SCANCODE_C,
SDL_SCANCODE_D,
SDL_SCANCODE_E,
SDL_SCANCODE_F,
SDL_SCANCODE_G,
SDL_SCANCODE_H,
SDL_SCANCODE_I,
SDL_SCANCODE_J,
SDL_SCANCODE_K,
SDL_SCANCODE_L,
SDL_SCANCODE_M,
SDL_SCANCODE_N,
SDL_SCANCODE_O,
SDL_SCANCODE_P,
SDL_SCANCODE_Q,
SDL_SCANCODE_R,
SDL_SCANCODE_S,
SDL_SCANCODE_T,
SDL_SCANCODE_U,
SDL_SCANCODE_V,
SDL_SCANCODE_W,
SDL_SCANCODE_X,
SDL_SCANCODE_Y,
SDL_SCANCODE_Z,
SDL_SCANCODE_1,
SDL_SCANCODE_2,
SDL_SCANCODE_3,
SDL_SCANCODE_4,
SDL_SCANCODE_5,
SDL_SCANCODE_6,
SDL_SCANCODE_7,
SDL_SCANCODE_8,
SDL_SCANCODE_9,
SDL_SCANCODE_0,
SDL_SCANCODE_RETURN,
SDL_SCANCODE_ESCAPE,
SDL_SCANCODE_BACKSPACE,
SDL_SCANCODE_TAB,
SDL_SCANCODE_SPACE,
SDL_SCANCODE_MINUS,
SDL_SCANCODE_EQUALS,
SDL_SCANCODE_LEFTBRACKET,
SDL_SCANCODE_RIGHTBRACKET,
SDL_SCANCODE_BACKSLASH,
0,
SDL_SCANCODE_SEMICOLON,
SDL_SCANCODE_APOSTROPHE,
SDL_SCANCODE_GRAVE,
SDL_SCANCODE_COMMA,
SDL_SCANCODE_PERIOD,
SDL_SCANCODE_SLASH,
SDL_SCANCODE_CAPSLOCK,
SDL_SCANCODE_F1,
SDL_SCANCODE_F2,
SDL_SCANCODE_F3,
SDL_SCANCODE_F4,
SDL_SCANCODE_F5,
SDL_SCANCODE_F6,
SDL_SCANCODE_F7,
SDL_SCANCODE_F8,
SDL_SCANCODE_F9,
SDL_SCANCODE_F10,
SDL_SCANCODE_F11,
SDL_SCANCODE_F12,
0,
SDL_SCANCODE_SCROLLLOCK,
SDL_SCANCODE_PAUSE,
SDL_SCANCODE_INSERT,
SDL_SCANCODE_HOME,
SDL_SCANCODE_PAGEUP,
SDL_SCANCODE_DELETE,
SDL_SCANCODE_END,
SDL_SCANCODE_PAGEDOWN,
SDL_SCANCODE_RIGHT,
SDL_SCANCODE_LEFT,
SDL_SCANCODE_DOWN,
SDL_SCANCODE_UP,
SDL_SCANCODE_NUMLOCKCLEAR,
SDL_SCANCODE_KP_DIVIDE,
SDL_SCANCODE_KP_MULTIPLY,
SDL_SCANCODE_KP_MINUS,
SDL_SCANCODE_KP_PLUS,
SDL_SCANCODE_KP_ENTER,
SDL_SCANCODE_KP_1,
SDL_SCANCODE_KP_2,
SDL_SCANCODE_KP_3,
SDL_SCANCODE_KP_4,
SDL_SCANCODE_KP_5,
SDL_SCANCODE_KP_6,
SDL_SCANCODE_KP_7,
SDL_SCANCODE_KP_8,
SDL_SCANCODE_KP_9,
SDL_SCANCODE_KP_0,
SDL_SCANCODE_KP_PERIOD,
0,
0,
SDL_SCANCODE_POWER,
SDL_SCANCODE_KP_EQUALS,
SDL_SCANCODE_F13,
SDL_SCANCODE_F14,
SDL_SCANCODE_F15,
SDL_SCANCODE_F16,
SDL_SCANCODE_F17,
SDL_SCANCODE_F18,
SDL_SCANCODE_F19,
SDL_SCANCODE_F20,
SDL_SCANCODE_F21,
SDL_SCANCODE_F22,
SDL_SCANCODE_F23,
SDL_SCANCODE_F24,
0,
SDL_SCANCODE_HELP,
SDL_SCANCODE_MENU,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
SDL_SCANCODE_KP_COMMA,
SDL_SCANCODE_KP_LEFTPAREN,
SDL_SCANCODE_KP_RIGHTPAREN,
0,
0,
0,
0,
};
static const std::array<int, 8> keyboard_mods{
SDL_SCANCODE_LCTRL, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_LALT, SDL_SCANCODE_LGUI,
SDL_SCANCODE_RCTRL, SDL_SCANCODE_RSHIFT, SDL_SCANCODE_RALT, SDL_SCANCODE_RGUI,
};
template <> template <>
void Config::ReadSetting(const std::string& group, Settings::BasicSetting<std::string>& setting) { void Config::ReadSetting(const std::string& group, Settings::BasicSetting<std::string>& setting) {
setting = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault()); setting = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault());
@ -283,14 +126,6 @@ void Config::ReadValues() {
} }
ReadSetting("ControlsGeneral", Settings::values.mouse_enabled); ReadSetting("ControlsGeneral", Settings::values.mouse_enabled);
for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
std::string default_param = InputCommon::GenerateKeyboardParam(default_mouse_buttons[i]);
Settings::values.mouse_buttons[i] = sdl2_config->Get(
"ControlsGeneral", std::string("mouse_") + Settings::NativeMouseButton::mapping[i],
default_param);
if (Settings::values.mouse_buttons[i].empty())
Settings::values.mouse_buttons[i] = default_param;
}
ReadSetting("ControlsGeneral", Settings::values.touch_device); ReadSetting("ControlsGeneral", Settings::values.touch_device);
@ -365,15 +200,6 @@ void Config::ReadValues() {
ReadSetting("ControlsGeneral", Settings::values.udp_input_servers); ReadSetting("ControlsGeneral", Settings::values.udp_input_servers);
std::transform(keyboard_keys.begin(), keyboard_keys.end(),
Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam);
std::transform(keyboard_mods.begin(), keyboard_mods.end(),
Settings::values.keyboard_keys.begin() +
Settings::NativeKeyboard::LeftControlKey,
InputCommon::GenerateKeyboardParam);
std::transform(keyboard_mods.begin(), keyboard_mods.end(),
Settings::values.keyboard_mods.begin(), InputCommon::GenerateKeyboardParam);
// Data Storage // Data Storage
ReadSetting("Data Storage", Settings::values.use_virtual_sd); ReadSetting("Data Storage", Settings::values.use_virtual_sd);
FS::SetYuzuPath(FS::YuzuPath::NANDDir, FS::SetYuzuPath(FS::YuzuPath::NANDDir,