diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/frontend/input.h | 7 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/debug_pad.cpp | 42 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/debug_pad.h | 41 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/keyboard.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/keyboard.h | 7 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/mouse.cpp | 25 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/mouse.h | 9 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 464 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 45 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/touchscreen.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/touchscreen.h | 12 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 4 | ||||
| -rw-r--r-- | src/core/settings.cpp | 50 | ||||
| -rw-r--r-- | src/core/settings.h | 318 |
14 files changed, 833 insertions, 224 deletions
diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h index 39bdf4e21..16fdcd376 100644 --- a/src/core/frontend/input.h +++ b/src/core/frontend/input.h | |||
| @@ -132,4 +132,11 @@ using MotionDevice = InputDevice<std::tuple<Math::Vec3<float>, Math::Vec3<float> | |||
| 132 | */ | 132 | */ |
| 133 | using TouchDevice = InputDevice<std::tuple<float, float, bool>>; | 133 | using TouchDevice = InputDevice<std::tuple<float, float, bool>>; |
| 134 | 134 | ||
| 135 | /** | ||
| 136 | * A mouse device is an input device that returns a tuple of two floats and four ints. | ||
| 137 | * The first two floats are X and Y device coordinates of the mouse (from 0-1). | ||
| 138 | * The s32s are the mouse wheel. | ||
| 139 | */ | ||
| 140 | using MouseDevice = InputDevice<std::tuple<float, float, s32, s32>>; | ||
| 141 | |||
| 135 | } // namespace Input | 142 | } // namespace Input |
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp index 3d100763f..e76c83aee 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.cpp +++ b/src/core/hle/service/hid/controllers/debug_pad.cpp | |||
| @@ -6,9 +6,14 @@ | |||
| 6 | #include "common/common_types.h" | 6 | #include "common/common_types.h" |
| 7 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| 8 | #include "core/hle/service/hid/controllers/debug_pad.h" | 8 | #include "core/hle/service/hid/controllers/debug_pad.h" |
| 9 | #include "core/settings.h" | ||
| 9 | 10 | ||
| 10 | namespace Service::HID { | 11 | namespace Service::HID { |
| 11 | 12 | ||
| 13 | constexpr s32 HID_JOYSTICK_MAX = 0x7fff; | ||
| 14 | constexpr s32 HID_JOYSTICK_MIN = -0x7fff; | ||
| 15 | enum class JoystickId : std::size_t { Joystick_Left, Joystick_Right }; | ||
| 16 | |||
| 12 | Controller_DebugPad::Controller_DebugPad() = default; | 17 | Controller_DebugPad::Controller_DebugPad() = default; |
| 13 | Controller_DebugPad::~Controller_DebugPad() = default; | 18 | Controller_DebugPad::~Controller_DebugPad() = default; |
| 14 | 19 | ||
| @@ -33,10 +38,43 @@ void Controller_DebugPad::OnUpdate(u8* data, std::size_t size) { | |||
| 33 | 38 | ||
| 34 | cur_entry.sampling_number = last_entry.sampling_number + 1; | 39 | cur_entry.sampling_number = last_entry.sampling_number + 1; |
| 35 | cur_entry.sampling_number2 = cur_entry.sampling_number; | 40 | cur_entry.sampling_number2 = cur_entry.sampling_number; |
| 36 | // TODO(ogniK): Update debug pad states | 41 | cur_entry.attribute.connected.Assign(1); |
| 42 | auto& pad = cur_entry.pad_state; | ||
| 43 | |||
| 44 | using namespace Settings::NativeButton; | ||
| 45 | pad.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 46 | pad.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 47 | pad.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 48 | pad.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 49 | pad.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 50 | pad.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 51 | pad.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 52 | pad.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 53 | pad.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 54 | pad.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 55 | pad.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 56 | pad.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 57 | pad.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 58 | pad.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 59 | |||
| 60 | const auto [stick_l_x_f, stick_l_y_f] = | ||
| 61 | analogs[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus(); | ||
| 62 | const auto [stick_r_x_f, stick_r_y_f] = | ||
| 63 | analogs[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus(); | ||
| 64 | cur_entry.l_stick.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX); | ||
| 65 | cur_entry.l_stick.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX); | ||
| 66 | cur_entry.r_stick.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX); | ||
| 67 | cur_entry.r_stick.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX); | ||
| 37 | 68 | ||
| 38 | std::memcpy(data, &shared_memory, sizeof(SharedMemory)); | 69 | std::memcpy(data, &shared_memory, sizeof(SharedMemory)); |
| 39 | } | 70 | } |
| 40 | 71 | ||
| 41 | void Controller_DebugPad::OnLoadInputDevices() {} | 72 | void Controller_DebugPad::OnLoadInputDevices() { |
| 73 | std::transform(Settings::values.debug_pad_buttons.begin(), | ||
| 74 | Settings::values.debug_pad_buttons.end(), buttons.begin(), | ||
| 75 | Input::CreateDevice<Input::ButtonDevice>); | ||
| 76 | std::transform(Settings::values.debug_pad_analogs.begin(), | ||
| 77 | Settings::values.debug_pad_analogs.end(), analogs.begin(), | ||
| 78 | Input::CreateDevice<Input::AnalogDevice>); | ||
| 79 | } | ||
| 42 | } // namespace Service::HID | 80 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h index 62b4f2682..68b734248 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.h +++ b/src/core/hle/service/hid/controllers/debug_pad.h | |||
| @@ -5,10 +5,13 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include "common/bit_field.h" | ||
| 8 | #include "common/common_funcs.h" | 9 | #include "common/common_funcs.h" |
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | #include "common/swap.h" | 11 | #include "common/swap.h" |
| 12 | #include "core/frontend/input.h" | ||
| 11 | #include "core/hle/service/hid/controllers/controller_base.h" | 13 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 14 | #include "core/settings.h" | ||
| 12 | 15 | ||
| 13 | namespace Service::HID { | 16 | namespace Service::HID { |
| 14 | class Controller_DebugPad final : public ControllerBase { | 17 | class Controller_DebugPad final : public ControllerBase { |
| @@ -35,11 +38,40 @@ private: | |||
| 35 | }; | 38 | }; |
| 36 | static_assert(sizeof(AnalogStick) == 0x8); | 39 | static_assert(sizeof(AnalogStick) == 0x8); |
| 37 | 40 | ||
| 41 | struct PadState { | ||
| 42 | union { | ||
| 43 | u32_le raw{}; | ||
| 44 | BitField<0, 1, u32_le> a; | ||
| 45 | BitField<1, 1, u32_le> b; | ||
| 46 | BitField<2, 1, u32_le> x; | ||
| 47 | BitField<3, 1, u32_le> y; | ||
| 48 | BitField<4, 1, u32_le> l; | ||
| 49 | BitField<5, 1, u32_le> r; | ||
| 50 | BitField<6, 1, u32_le> zl; | ||
| 51 | BitField<7, 1, u32_le> zr; | ||
| 52 | BitField<8, 1, u32_le> plus; | ||
| 53 | BitField<9, 1, u32_le> minus; | ||
| 54 | BitField<10, 1, u32_le> d_left; | ||
| 55 | BitField<11, 1, u32_le> d_up; | ||
| 56 | BitField<12, 1, u32_le> d_right; | ||
| 57 | BitField<13, 1, u32_le> d_down; | ||
| 58 | }; | ||
| 59 | }; | ||
| 60 | static_assert(sizeof(PadState) == 0x4, "PadState is an invalid size"); | ||
| 61 | |||
| 62 | struct Attributes { | ||
| 63 | union { | ||
| 64 | u32_le raw{}; | ||
| 65 | BitField<0, 1, u32_le> connected; | ||
| 66 | }; | ||
| 67 | }; | ||
| 68 | static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size"); | ||
| 69 | |||
| 38 | struct PadStates { | 70 | struct PadStates { |
| 39 | s64_le sampling_number; | 71 | s64_le sampling_number; |
| 40 | s64_le sampling_number2; | 72 | s64_le sampling_number2; |
| 41 | u32_le attribute; | 73 | Attributes attribute; |
| 42 | u32_le button_state; | 74 | PadState pad_state; |
| 43 | AnalogStick r_stick; | 75 | AnalogStick r_stick; |
| 44 | AnalogStick l_stick; | 76 | AnalogStick l_stick; |
| 45 | }; | 77 | }; |
| @@ -52,5 +84,10 @@ private: | |||
| 52 | }; | 84 | }; |
| 53 | static_assert(sizeof(SharedMemory) == 0x400, "SharedMemory is an invalid size"); | 85 | static_assert(sizeof(SharedMemory) == 0x400, "SharedMemory is an invalid size"); |
| 54 | SharedMemory shared_memory{}; | 86 | SharedMemory shared_memory{}; |
| 87 | |||
| 88 | std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID> | ||
| 89 | buttons; | ||
| 90 | std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID> | ||
| 91 | analogs; | ||
| 55 | }; | 92 | }; |
| 56 | } // namespace Service::HID | 93 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index ccfbce9ac..ca75adc2b 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp | |||
| @@ -6,9 +6,11 @@ | |||
| 6 | #include "common/common_types.h" | 6 | #include "common/common_types.h" |
| 7 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| 8 | #include "core/hle/service/hid/controllers/keyboard.h" | 8 | #include "core/hle/service/hid/controllers/keyboard.h" |
| 9 | #include "core/settings.h" | ||
| 9 | 10 | ||
| 10 | namespace Service::HID { | 11 | namespace Service::HID { |
| 11 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; | 12 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; |
| 13 | constexpr u8 KEYS_PER_BYTE = 8; | ||
| 12 | 14 | ||
| 13 | Controller_Keyboard::Controller_Keyboard() = default; | 15 | Controller_Keyboard::Controller_Keyboard() = default; |
| 14 | Controller_Keyboard::~Controller_Keyboard() = default; | 16 | Controller_Keyboard::~Controller_Keyboard() = default; |
| @@ -34,10 +36,24 @@ void Controller_Keyboard::OnUpdate(u8* data, std::size_t size) { | |||
| 34 | 36 | ||
| 35 | cur_entry.sampling_number = last_entry.sampling_number + 1; | 37 | cur_entry.sampling_number = last_entry.sampling_number + 1; |
| 36 | cur_entry.sampling_number2 = cur_entry.sampling_number; | 38 | cur_entry.sampling_number2 = cur_entry.sampling_number; |
| 37 | // TODO(ogniK): Update keyboard states | 39 | |
| 40 | for (std::size_t i = 0; i < keyboard_keys.size(); ++i) { | ||
| 41 | for (std::size_t k = 0; k < KEYS_PER_BYTE; ++k) { | ||
| 42 | cur_entry.key[i / KEYS_PER_BYTE] |= (keyboard_keys[i]->GetStatus() << k); | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | for (std::size_t i = 0; i < keyboard_mods.size(); ++i) { | ||
| 47 | cur_entry.modifier |= (keyboard_mods[i]->GetStatus() << i); | ||
| 48 | } | ||
| 38 | 49 | ||
| 39 | std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); | 50 | std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); |
| 40 | } | 51 | } |
| 41 | 52 | ||
| 42 | void Controller_Keyboard::OnLoadInputDevices() {} | 53 | void Controller_Keyboard::OnLoadInputDevices() { |
| 54 | std::transform(Settings::values.keyboard_keys.begin(), Settings::values.keyboard_keys.end(), | ||
| 55 | keyboard_keys.begin(), Input::CreateDevice<Input::ButtonDevice>); | ||
| 56 | std::transform(Settings::values.keyboard_mods.begin(), Settings::values.keyboard_mods.end(), | ||
| 57 | keyboard_mods.begin(), Input::CreateDevice<Input::ButtonDevice>); | ||
| 58 | } | ||
| 43 | } // namespace Service::HID | 59 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h index 493e68fce..f52775456 100644 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ b/src/core/hle/service/hid/controllers/keyboard.h | |||
| @@ -8,7 +8,9 @@ | |||
| 8 | #include "common/common_funcs.h" | 8 | #include "common/common_funcs.h" |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "common/swap.h" | 10 | #include "common/swap.h" |
| 11 | #include "core/frontend/input.h" | ||
| 11 | #include "core/hle/service/hid/controllers/controller_base.h" | 12 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 13 | #include "core/settings.h" | ||
| 12 | 14 | ||
| 13 | namespace Service::HID { | 15 | namespace Service::HID { |
| 14 | class Controller_Keyboard final : public ControllerBase { | 16 | class Controller_Keyboard final : public ControllerBase { |
| @@ -46,5 +48,10 @@ private: | |||
| 46 | }; | 48 | }; |
| 47 | static_assert(sizeof(SharedMemory) == 0x400, "SharedMemory is an invalid size"); | 49 | static_assert(sizeof(SharedMemory) == 0x400, "SharedMemory is an invalid size"); |
| 48 | SharedMemory shared_memory{}; | 50 | SharedMemory shared_memory{}; |
| 51 | |||
| 52 | std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeKeyboard::NumKeyboardKeys> | ||
| 53 | keyboard_keys; | ||
| 54 | std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeKeyboard::NumKeyboardMods> | ||
| 55 | keyboard_mods; | ||
| 49 | }; | 56 | }; |
| 50 | } // namespace Service::HID | 57 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index 4e246a57d..63391dbe9 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <cstring> | 5 | #include <cstring> |
| 6 | #include "common/common_types.h" | 6 | #include "common/common_types.h" |
| 7 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| 8 | #include "core/frontend/emu_window.h" | ||
| 8 | #include "core/hle/service/hid/controllers/mouse.h" | 9 | #include "core/hle/service/hid/controllers/mouse.h" |
| 9 | 10 | ||
| 10 | namespace Service::HID { | 11 | namespace Service::HID { |
| @@ -14,7 +15,6 @@ Controller_Mouse::Controller_Mouse() = default; | |||
| 14 | Controller_Mouse::~Controller_Mouse() = default; | 15 | Controller_Mouse::~Controller_Mouse() = default; |
| 15 | 16 | ||
| 16 | void Controller_Mouse::OnInit() {} | 17 | void Controller_Mouse::OnInit() {} |
| 17 | |||
| 18 | void Controller_Mouse::OnRelease() {} | 18 | void Controller_Mouse::OnRelease() {} |
| 19 | 19 | ||
| 20 | void Controller_Mouse::OnUpdate(u8* data, std::size_t size) { | 20 | void Controller_Mouse::OnUpdate(u8* data, std::size_t size) { |
| @@ -34,10 +34,29 @@ void Controller_Mouse::OnUpdate(u8* data, std::size_t size) { | |||
| 34 | 34 | ||
| 35 | cur_entry.sampling_number = last_entry.sampling_number + 1; | 35 | cur_entry.sampling_number = last_entry.sampling_number + 1; |
| 36 | cur_entry.sampling_number2 = cur_entry.sampling_number; | 36 | cur_entry.sampling_number2 = cur_entry.sampling_number; |
| 37 | // TODO(ogniK): Update mouse states | 37 | |
| 38 | if (Settings::values.mouse_enabled) { | ||
| 39 | const auto [px, py, sx, sy] = mouse_device->GetStatus(); | ||
| 40 | const auto x = static_cast<s32>(px * Layout::ScreenUndocked::Width); | ||
| 41 | const auto y = static_cast<s32>(py * Layout::ScreenUndocked::Height); | ||
| 42 | cur_entry.x = x; | ||
| 43 | cur_entry.y = y; | ||
| 44 | cur_entry.delta_x = x - last_entry.x; | ||
| 45 | cur_entry.delta_y = y - last_entry.y; | ||
| 46 | cur_entry.mouse_wheel_x = sx; | ||
| 47 | cur_entry.mouse_wheel_y = sy; | ||
| 48 | |||
| 49 | for (std::size_t i = 0; i < mouse_button_devices.size(); ++i) { | ||
| 50 | cur_entry.button |= (mouse_button_devices[i]->GetStatus() << i); | ||
| 51 | } | ||
| 52 | } | ||
| 38 | 53 | ||
| 39 | std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); | 54 | std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); |
| 40 | } | 55 | } |
| 41 | 56 | ||
| 42 | void Controller_Mouse::OnLoadInputDevices() {} | 57 | void Controller_Mouse::OnLoadInputDevices() { |
| 58 | mouse_device = Input::CreateDevice<Input::MouseDevice>(Settings::values.mouse_device); | ||
| 59 | std::transform(Settings::values.mouse_buttons.begin(), Settings::values.mouse_buttons.end(), | ||
| 60 | mouse_button_devices.begin(), Input::CreateDevice<Input::ButtonDevice>); | ||
| 61 | } | ||
| 43 | } // namespace Service::HID | 62 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h index 543b0b71f..70b654d07 100644 --- a/src/core/hle/service/hid/controllers/mouse.h +++ b/src/core/hle/service/hid/controllers/mouse.h | |||
| @@ -7,7 +7,9 @@ | |||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "common/swap.h" | 9 | #include "common/swap.h" |
| 10 | #include "core/frontend/input.h" | ||
| 10 | #include "core/hle/service/hid/controllers/controller_base.h" | 11 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 12 | #include "core/settings.h" | ||
| 11 | 13 | ||
| 12 | namespace Service::HID { | 14 | namespace Service::HID { |
| 13 | class Controller_Mouse final : public ControllerBase { | 15 | class Controller_Mouse final : public ControllerBase { |
| @@ -35,7 +37,8 @@ private: | |||
| 35 | s32_le y; | 37 | s32_le y; |
| 36 | s32_le delta_x; | 38 | s32_le delta_x; |
| 37 | s32_le delta_y; | 39 | s32_le delta_y; |
| 38 | s32_le mouse_wheel; | 40 | s32_le mouse_wheel_x; |
| 41 | s32_le mouse_wheel_y; | ||
| 39 | s32_le button; | 42 | s32_le button; |
| 40 | s32_le attribute; | 43 | s32_le attribute; |
| 41 | }; | 44 | }; |
| @@ -46,5 +49,9 @@ private: | |||
| 46 | std::array<MouseState, 17> mouse_states; | 49 | std::array<MouseState, 17> mouse_states; |
| 47 | }; | 50 | }; |
| 48 | SharedMemory shared_memory{}; | 51 | SharedMemory shared_memory{}; |
| 52 | |||
| 53 | std::unique_ptr<Input::MouseDevice> mouse_device; | ||
| 54 | std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeMouseButton::NumMouseButtons> | ||
| 55 | mouse_button_devices; | ||
| 49 | }; | 56 | }; |
| 50 | } // namespace Service::HID | 57 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 205e4fd14..46604887c 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -17,22 +17,13 @@ | |||
| 17 | #include "core/settings.h" | 17 | #include "core/settings.h" |
| 18 | 18 | ||
| 19 | namespace Service::HID { | 19 | namespace Service::HID { |
| 20 | |||
| 21 | constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28; | ||
| 22 | constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A; | ||
| 23 | constexpr u32 JOYCON_BODY_NEON_BLUE = 0x0AB9E6; | ||
| 24 | constexpr u32 JOYCON_BUTTONS_NEON_BLUE = 0x001E1E; | ||
| 25 | constexpr s32 HID_JOYSTICK_MAX = 0x7fff; | 20 | constexpr s32 HID_JOYSTICK_MAX = 0x7fff; |
| 26 | constexpr s32 HID_JOYSTICK_MIN = -0x7fff; | 21 | constexpr s32 HID_JOYSTICK_MIN = -0x7fff; |
| 27 | constexpr std::size_t NPAD_OFFSET = 0x9A00; | 22 | constexpr std::size_t NPAD_OFFSET = 0x9A00; |
| 28 | constexpr u32 BATTERY_FULL = 2; | 23 | constexpr u32 BATTERY_FULL = 2; |
| 29 | constexpr u32 NPAD_HANDHELD = 32; | ||
| 30 | constexpr u32 NPAD_UNKNOWN = 16; // TODO(ogniK): What is this? | ||
| 31 | constexpr u32 MAX_NPAD_ID = 7; | 24 | constexpr u32 MAX_NPAD_ID = 7; |
| 32 | constexpr Controller_NPad::NPadControllerType PREFERRED_CONTROLLER = | ||
| 33 | Controller_NPad::NPadControllerType::JoyDual; | ||
| 34 | constexpr std::array<u32, 10> npad_id_list{ | 25 | constexpr std::array<u32, 10> npad_id_list{ |
| 35 | 0, 1, 2, 3, 4, 5, 6, 7, 32, 16, | 26 | 0, 1, 2, 3, 4, 5, 6, 7, NPAD_HANDHELD, NPAD_UNKNOWN, |
| 36 | }; | 27 | }; |
| 37 | 28 | ||
| 38 | enum class JoystickId : std::size_t { | 29 | enum class JoystickId : std::size_t { |
| @@ -40,7 +31,23 @@ enum class JoystickId : std::size_t { | |||
| 40 | Joystick_Right, | 31 | Joystick_Right, |
| 41 | }; | 32 | }; |
| 42 | 33 | ||
| 43 | static std::size_t NPadIdToIndex(u32 npad_id) { | 34 | static Controller_NPad::NPadControllerType MapSettingsTypeToNPad(Settings::ControllerType type) { |
| 35 | switch (type) { | ||
| 36 | case Settings::ControllerType::ProController: | ||
| 37 | return Controller_NPad::NPadControllerType::ProController; | ||
| 38 | case Settings::ControllerType::DualJoycon: | ||
| 39 | return Controller_NPad::NPadControllerType::JoyDual; | ||
| 40 | case Settings::ControllerType::LeftJoycon: | ||
| 41 | return Controller_NPad::NPadControllerType::JoyLeft; | ||
| 42 | case Settings::ControllerType::RightJoycon: | ||
| 43 | return Controller_NPad::NPadControllerType::JoyRight; | ||
| 44 | default: | ||
| 45 | UNREACHABLE(); | ||
| 46 | return Controller_NPad::NPadControllerType::JoyDual; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | std::size_t Controller_NPad::NPadIdToIndex(u32 npad_id) { | ||
| 44 | switch (npad_id) { | 51 | switch (npad_id) { |
| 45 | case 0: | 52 | case 0: |
| 46 | case 1: | 53 | case 1: |
| @@ -63,6 +70,27 @@ static std::size_t NPadIdToIndex(u32 npad_id) { | |||
| 63 | } | 70 | } |
| 64 | } | 71 | } |
| 65 | 72 | ||
| 73 | u32 Controller_NPad::IndexToNPad(std::size_t index) { | ||
| 74 | switch (index) { | ||
| 75 | case 0: | ||
| 76 | case 1: | ||
| 77 | case 2: | ||
| 78 | case 3: | ||
| 79 | case 4: | ||
| 80 | case 5: | ||
| 81 | case 6: | ||
| 82 | case 7: | ||
| 83 | return static_cast<u32>(index); | ||
| 84 | case 8: | ||
| 85 | return NPAD_HANDHELD; | ||
| 86 | case 9: | ||
| 87 | return NPAD_UNKNOWN; | ||
| 88 | default: | ||
| 89 | UNIMPLEMENTED_MSG("Unknown npad index {}", index); | ||
| 90 | return 0; | ||
| 91 | }; | ||
| 92 | } | ||
| 93 | |||
| 66 | Controller_NPad::Controller_NPad() = default; | 94 | Controller_NPad::Controller_NPad() = default; |
| 67 | Controller_NPad::~Controller_NPad() = default; | 95 | Controller_NPad::~Controller_NPad() = default; |
| 68 | 96 | ||
| @@ -79,22 +107,32 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { | |||
| 79 | controller.joy_styles.handheld.Assign(1); | 107 | controller.joy_styles.handheld.Assign(1); |
| 80 | controller.device_type.handheld.Assign(1); | 108 | controller.device_type.handheld.Assign(1); |
| 81 | controller.pad_assignment = NPadAssignments::Dual; | 109 | controller.pad_assignment = NPadAssignments::Dual; |
| 110 | controller.properties.is_vertical.Assign(1); | ||
| 111 | controller.properties.use_plus.Assign(1); | ||
| 112 | controller.properties.use_minus.Assign(1); | ||
| 82 | break; | 113 | break; |
| 83 | case NPadControllerType::JoyDual: | 114 | case NPadControllerType::JoyDual: |
| 84 | controller.joy_styles.joycon_dual.Assign(1); | 115 | controller.joy_styles.joycon_dual.Assign(1); |
| 85 | controller.device_type.joycon_left.Assign(1); | 116 | controller.device_type.joycon_left.Assign(1); |
| 86 | controller.device_type.joycon_right.Assign(1); | 117 | controller.device_type.joycon_right.Assign(1); |
| 118 | controller.properties.is_vertical.Assign(1); | ||
| 119 | controller.properties.use_plus.Assign(1); | ||
| 120 | controller.properties.use_minus.Assign(1); | ||
| 87 | controller.pad_assignment = NPadAssignments::Dual; | 121 | controller.pad_assignment = NPadAssignments::Dual; |
| 88 | break; | 122 | break; |
| 89 | case NPadControllerType::JoyLeft: | 123 | case NPadControllerType::JoyLeft: |
| 90 | controller.joy_styles.joycon_left.Assign(1); | 124 | controller.joy_styles.joycon_left.Assign(1); |
| 91 | controller.device_type.joycon_left.Assign(1); | 125 | controller.device_type.joycon_left.Assign(1); |
| 92 | controller.pad_assignment = NPadAssignments::Dual; | 126 | controller.properties.is_horizontal.Assign(1); |
| 127 | controller.properties.use_minus.Assign(1); | ||
| 128 | controller.pad_assignment = NPadAssignments::Single; | ||
| 93 | break; | 129 | break; |
| 94 | case NPadControllerType::JoyRight: | 130 | case NPadControllerType::JoyRight: |
| 95 | controller.joy_styles.joycon_right.Assign(1); | 131 | controller.joy_styles.joycon_right.Assign(1); |
| 96 | controller.device_type.joycon_right.Assign(1); | 132 | controller.device_type.joycon_right.Assign(1); |
| 97 | controller.pad_assignment = NPadAssignments::Dual; | 133 | controller.properties.is_horizontal.Assign(1); |
| 134 | controller.properties.use_plus.Assign(1); | ||
| 135 | controller.pad_assignment = NPadAssignments::Single; | ||
| 98 | break; | 136 | break; |
| 99 | case NPadControllerType::Pokeball: | 137 | case NPadControllerType::Pokeball: |
| 100 | controller.joy_styles.pokeball.Assign(1); | 138 | controller.joy_styles.pokeball.Assign(1); |
| @@ -104,6 +142,9 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { | |||
| 104 | case NPadControllerType::ProController: | 142 | case NPadControllerType::ProController: |
| 105 | controller.joy_styles.pro_controller.Assign(1); | 143 | controller.joy_styles.pro_controller.Assign(1); |
| 106 | controller.device_type.pro_controller.Assign(1); | 144 | controller.device_type.pro_controller.Assign(1); |
| 145 | controller.properties.is_vertical.Assign(1); | ||
| 146 | controller.properties.use_plus.Assign(1); | ||
| 147 | controller.properties.use_minus.Assign(1); | ||
| 107 | controller.pad_assignment = NPadAssignments::Single; | 148 | controller.pad_assignment = NPadAssignments::Single; |
| 108 | break; | 149 | break; |
| 109 | } | 150 | } |
| @@ -113,14 +154,12 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { | |||
| 113 | controller.single_color.button_color = 0; | 154 | controller.single_color.button_color = 0; |
| 114 | 155 | ||
| 115 | controller.dual_color_error = ColorReadError::ReadOk; | 156 | controller.dual_color_error = ColorReadError::ReadOk; |
| 116 | controller.left_color.body_color = JOYCON_BODY_NEON_BLUE; | 157 | controller.left_color.body_color = Settings::values.players[controller_idx].body_color_left; |
| 117 | controller.left_color.button_color = JOYCON_BUTTONS_NEON_BLUE; | 158 | controller.left_color.button_color = Settings::values.players[controller_idx].button_color_left; |
| 118 | controller.right_color.body_color = JOYCON_BODY_NEON_RED; | 159 | controller.right_color.body_color = Settings::values.players[controller_idx].body_color_right; |
| 119 | controller.right_color.button_color = JOYCON_BUTTONS_NEON_RED; | 160 | controller.right_color.button_color = |
| 120 | 161 | Settings::values.players[controller_idx].button_color_right; | |
| 121 | controller.properties.is_vertical.Assign(1); // TODO(ogniK): Swap joycons orientations | 162 | |
| 122 | controller.properties.use_plus.Assign(1); | ||
| 123 | controller.properties.use_minus.Assign(1); | ||
| 124 | controller.battery_level[0] = BATTERY_FULL; | 163 | controller.battery_level[0] = BATTERY_FULL; |
| 125 | controller.battery_level[1] = BATTERY_FULL; | 164 | controller.battery_level[1] = BATTERY_FULL; |
| 126 | controller.battery_level[2] = BATTERY_FULL; | 165 | controller.battery_level[2] = BATTERY_FULL; |
| @@ -144,26 +183,109 @@ void Controller_NPad::OnInit() { | |||
| 144 | style.pro_controller.Assign(1); | 183 | style.pro_controller.Assign(1); |
| 145 | style.pokeball.Assign(1); | 184 | style.pokeball.Assign(1); |
| 146 | } | 185 | } |
| 186 | |||
| 187 | std::transform( | ||
| 188 | Settings::values.players.begin(), Settings::values.players.end(), | ||
| 189 | connected_controllers.begin(), [](const Settings::PlayerInput& player) { | ||
| 190 | return ControllerHolder{MapSettingsTypeToNPad(player.type), player.connected}; | ||
| 191 | }); | ||
| 192 | |||
| 193 | std::stable_partition(connected_controllers.begin(), connected_controllers.begin() + 8, | ||
| 194 | [](const ControllerHolder& holder) { return holder.is_connected; }); | ||
| 195 | |||
| 196 | // Account for handheld | ||
| 197 | if (connected_controllers[8].is_connected) | ||
| 198 | connected_controllers[8].type = NPadControllerType::Handheld; | ||
| 199 | |||
| 200 | supported_npad_id_types.resize(npad_id_list.size()); | ||
| 201 | std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), | ||
| 202 | npad_id_list.size() * sizeof(u32)); | ||
| 203 | |||
| 204 | // Add a default dual joycon controller if none are present. | ||
| 147 | if (std::none_of(connected_controllers.begin(), connected_controllers.end(), | 205 | if (std::none_of(connected_controllers.begin(), connected_controllers.end(), |
| 148 | [](const ControllerHolder& controller) { return controller.is_connected; })) { | 206 | [](const ControllerHolder& controller) { return controller.is_connected; })) { |
| 149 | supported_npad_id_types.resize(npad_id_list.size()); | 207 | supported_npad_id_types.resize(npad_id_list.size()); |
| 150 | std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), | 208 | std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), |
| 151 | npad_id_list.size() * sizeof(u32)); | 209 | npad_id_list.size() * sizeof(u32)); |
| 152 | AddNewController(PREFERRED_CONTROLLER); | 210 | AddNewController(NPadControllerType::JoyDual); |
| 211 | } | ||
| 212 | |||
| 213 | for (std::size_t i = 0; i < connected_controllers.size(); ++i) { | ||
| 214 | const auto& controller = connected_controllers[i]; | ||
| 215 | if (controller.is_connected) { | ||
| 216 | AddNewControllerAt(controller.type, IndexToNPad(i)); | ||
| 217 | } | ||
| 153 | } | 218 | } |
| 154 | } | 219 | } |
| 155 | 220 | ||
| 156 | void Controller_NPad::OnLoadInputDevices() { | 221 | void Controller_NPad::OnLoadInputDevices() { |
| 157 | std::transform(Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN, | 222 | const auto& players = Settings::values.players; |
| 158 | Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_END, | 223 | for (std::size_t i = 0; i < players.size(); ++i) { |
| 159 | buttons.begin(), Input::CreateDevice<Input::ButtonDevice>); | 224 | std::transform(players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN, |
| 160 | std::transform(Settings::values.analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN, | 225 | players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_END, |
| 161 | Settings::values.analogs.begin() + Settings::NativeAnalog::STICK_HID_END, | 226 | buttons[i].begin(), Input::CreateDevice<Input::ButtonDevice>); |
| 162 | sticks.begin(), Input::CreateDevice<Input::AnalogDevice>); | 227 | std::transform(players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN, |
| 228 | players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_END, | ||
| 229 | sticks[i].begin(), Input::CreateDevice<Input::AnalogDevice>); | ||
| 230 | } | ||
| 163 | } | 231 | } |
| 164 | 232 | ||
| 165 | void Controller_NPad::OnRelease() {} | 233 | void Controller_NPad::OnRelease() {} |
| 166 | 234 | ||
| 235 | void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { | ||
| 236 | const auto controller_idx = NPadIdToIndex(npad_id); | ||
| 237 | const auto controller_type = connected_controllers[controller_idx].type; | ||
| 238 | if (!connected_controllers[controller_idx].is_connected) { | ||
| 239 | return; | ||
| 240 | } | ||
| 241 | auto& pad_state = npad_pad_states[controller_idx].pad_states; | ||
| 242 | auto& lstick_entry = npad_pad_states[controller_idx].l_stick; | ||
| 243 | auto& rstick_entry = npad_pad_states[controller_idx].r_stick; | ||
| 244 | const auto& button_state = buttons[controller_idx]; | ||
| 245 | const auto& analog_state = sticks[controller_idx]; | ||
| 246 | |||
| 247 | using namespace Settings::NativeButton; | ||
| 248 | pad_state.a.Assign(button_state[A - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 249 | pad_state.b.Assign(button_state[B - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 250 | pad_state.x.Assign(button_state[X - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 251 | pad_state.y.Assign(button_state[Y - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 252 | pad_state.l_stick.Assign(button_state[LStick - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 253 | pad_state.r_stick.Assign(button_state[RStick - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 254 | pad_state.l.Assign(button_state[L - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 255 | pad_state.r.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 256 | pad_state.zl.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 257 | pad_state.zr.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 258 | pad_state.plus.Assign(button_state[Plus - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 259 | pad_state.minus.Assign(button_state[Minus - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 260 | |||
| 261 | pad_state.d_left.Assign(button_state[DLeft - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 262 | pad_state.d_up.Assign(button_state[DUp - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 263 | pad_state.d_right.Assign(button_state[DRight - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 264 | pad_state.d_down.Assign(button_state[DDown - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 265 | |||
| 266 | pad_state.l_stick_left.Assign(button_state[LStick_Left - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 267 | pad_state.l_stick_up.Assign(button_state[LStick_Up - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 268 | pad_state.l_stick_right.Assign(button_state[LStick_Right - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 269 | pad_state.l_stick_down.Assign(button_state[LStick_Down - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 270 | |||
| 271 | pad_state.r_stick_left.Assign(button_state[RStick_Left - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 272 | pad_state.r_stick_up.Assign(button_state[RStick_Up - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 273 | pad_state.r_stick_right.Assign(button_state[RStick_Right - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 274 | pad_state.r_stick_down.Assign(button_state[RStick_Down - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 275 | |||
| 276 | pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 277 | pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 278 | |||
| 279 | const auto [stick_l_x_f, stick_l_y_f] = | ||
| 280 | analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus(); | ||
| 281 | const auto [stick_r_x_f, stick_r_y_f] = | ||
| 282 | analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus(); | ||
| 283 | lstick_entry.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX); | ||
| 284 | lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX); | ||
| 285 | rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX); | ||
| 286 | rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX); | ||
| 287 | } | ||
| 288 | |||
| 167 | void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { | 289 | void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { |
| 168 | if (!IsControllerActivated()) | 290 | if (!IsControllerActivated()) |
| 169 | return; | 291 | return; |
| @@ -199,97 +321,9 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { | |||
| 199 | if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { | 321 | if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { |
| 200 | continue; | 322 | continue; |
| 201 | } | 323 | } |
| 202 | 324 | const u32 npad_index = static_cast<u32>(i); | |
| 203 | // Pad states | 325 | RequestPadStateUpdate(npad_index); |
| 204 | ControllerPadState pad_state{}; | 326 | auto& pad_state = npad_pad_states[npad_index]; |
| 205 | using namespace Settings::NativeButton; | ||
| 206 | pad_state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 207 | pad_state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 208 | pad_state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 209 | pad_state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 210 | pad_state.l_stick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 211 | pad_state.r_stick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 212 | pad_state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 213 | pad_state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 214 | pad_state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 215 | pad_state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 216 | pad_state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 217 | pad_state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 218 | |||
| 219 | pad_state.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 220 | pad_state.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 221 | pad_state.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 222 | pad_state.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 223 | |||
| 224 | pad_state.l_stick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 225 | pad_state.l_stick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 226 | pad_state.l_stick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 227 | pad_state.l_stick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 228 | |||
| 229 | pad_state.r_stick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 230 | pad_state.r_stick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 231 | pad_state.r_stick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 232 | pad_state.r_stick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 233 | |||
| 234 | pad_state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 235 | pad_state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 236 | |||
| 237 | AnalogPosition lstick_entry{}; | ||
| 238 | AnalogPosition rstick_entry{}; | ||
| 239 | |||
| 240 | const auto [stick_l_x_f, stick_l_y_f] = | ||
| 241 | sticks[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus(); | ||
| 242 | const auto [stick_r_x_f, stick_r_y_f] = | ||
| 243 | sticks[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus(); | ||
| 244 | lstick_entry.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX); | ||
| 245 | lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX); | ||
| 246 | rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX); | ||
| 247 | rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX); | ||
| 248 | |||
| 249 | if (controller_type == NPadControllerType::JoyLeft || | ||
| 250 | controller_type == NPadControllerType::JoyRight) { | ||
| 251 | if (npad.properties.is_horizontal) { | ||
| 252 | ControllerPadState state{}; | ||
| 253 | AnalogPosition temp_lstick_entry{}; | ||
| 254 | AnalogPosition temp_rstick_entry{}; | ||
| 255 | if (controller_type == NPadControllerType::JoyLeft) { | ||
| 256 | state.d_down.Assign(pad_state.d_left.Value()); | ||
| 257 | state.d_left.Assign(pad_state.d_up.Value()); | ||
| 258 | state.d_right.Assign(pad_state.d_down.Value()); | ||
| 259 | state.d_up.Assign(pad_state.d_right.Value()); | ||
| 260 | state.l.Assign(pad_state.l.Value() | pad_state.sl.Value()); | ||
| 261 | state.r.Assign(pad_state.r.Value() | pad_state.sr.Value()); | ||
| 262 | |||
| 263 | state.zl.Assign(pad_state.zl.Value()); | ||
| 264 | state.plus.Assign(pad_state.minus.Value()); | ||
| 265 | |||
| 266 | temp_lstick_entry = lstick_entry; | ||
| 267 | temp_rstick_entry = rstick_entry; | ||
| 268 | std::swap(temp_lstick_entry.x, temp_lstick_entry.y); | ||
| 269 | std::swap(temp_rstick_entry.x, temp_rstick_entry.y); | ||
| 270 | temp_lstick_entry.y *= -1; | ||
| 271 | } else if (controller_type == NPadControllerType::JoyRight) { | ||
| 272 | state.x.Assign(pad_state.a.Value()); | ||
| 273 | state.a.Assign(pad_state.b.Value()); | ||
| 274 | state.b.Assign(pad_state.y.Value()); | ||
| 275 | state.y.Assign(pad_state.b.Value()); | ||
| 276 | |||
| 277 | state.l.Assign(pad_state.l.Value() | pad_state.sl.Value()); | ||
| 278 | state.r.Assign(pad_state.r.Value() | pad_state.sr.Value()); | ||
| 279 | state.zr.Assign(pad_state.zr.Value()); | ||
| 280 | state.plus.Assign(pad_state.plus.Value()); | ||
| 281 | |||
| 282 | temp_lstick_entry = lstick_entry; | ||
| 283 | temp_rstick_entry = rstick_entry; | ||
| 284 | std::swap(temp_lstick_entry.x, temp_lstick_entry.y); | ||
| 285 | std::swap(temp_rstick_entry.x, temp_rstick_entry.y); | ||
| 286 | temp_rstick_entry.x *= -1; | ||
| 287 | } | ||
| 288 | pad_state.raw = state.raw; | ||
| 289 | lstick_entry = temp_lstick_entry; | ||
| 290 | rstick_entry = temp_rstick_entry; | ||
| 291 | } | ||
| 292 | } | ||
| 293 | 327 | ||
| 294 | auto& main_controller = | 328 | auto& main_controller = |
| 295 | npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; | 329 | npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; |
| @@ -304,8 +338,51 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { | |||
| 304 | auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; | 338 | auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; |
| 305 | 339 | ||
| 306 | if (hold_type == NpadHoldType::Horizontal) { | 340 | if (hold_type == NpadHoldType::Horizontal) { |
| 307 | // TODO(ogniK): Remap buttons for different orientations | 341 | ControllerPadState state{}; |
| 342 | AnalogPosition temp_lstick_entry{}; | ||
| 343 | AnalogPosition temp_rstick_entry{}; | ||
| 344 | if (controller_type == NPadControllerType::JoyLeft) { | ||
| 345 | state.d_down.Assign(pad_state.pad_states.d_left.Value()); | ||
| 346 | state.d_left.Assign(pad_state.pad_states.d_up.Value()); | ||
| 347 | state.d_right.Assign(pad_state.pad_states.d_down.Value()); | ||
| 348 | state.d_up.Assign(pad_state.pad_states.d_right.Value()); | ||
| 349 | state.l.Assign(pad_state.pad_states.l.Value() | | ||
| 350 | pad_state.pad_states.left_sl.Value()); | ||
| 351 | state.r.Assign(pad_state.pad_states.r.Value() | | ||
| 352 | pad_state.pad_states.left_sr.Value()); | ||
| 353 | |||
| 354 | state.zl.Assign(pad_state.pad_states.zl.Value()); | ||
| 355 | state.plus.Assign(pad_state.pad_states.minus.Value()); | ||
| 356 | |||
| 357 | temp_lstick_entry = pad_state.l_stick; | ||
| 358 | temp_rstick_entry = pad_state.r_stick; | ||
| 359 | std::swap(temp_lstick_entry.x, temp_lstick_entry.y); | ||
| 360 | std::swap(temp_rstick_entry.x, temp_rstick_entry.y); | ||
| 361 | temp_lstick_entry.y *= -1; | ||
| 362 | } else if (controller_type == NPadControllerType::JoyRight) { | ||
| 363 | state.x.Assign(pad_state.pad_states.a.Value()); | ||
| 364 | state.a.Assign(pad_state.pad_states.b.Value()); | ||
| 365 | state.b.Assign(pad_state.pad_states.y.Value()); | ||
| 366 | state.y.Assign(pad_state.pad_states.b.Value()); | ||
| 367 | |||
| 368 | state.l.Assign(pad_state.pad_states.l.Value() | | ||
| 369 | pad_state.pad_states.right_sl.Value()); | ||
| 370 | state.r.Assign(pad_state.pad_states.r.Value() | | ||
| 371 | pad_state.pad_states.right_sr.Value()); | ||
| 372 | state.zr.Assign(pad_state.pad_states.zr.Value()); | ||
| 373 | state.plus.Assign(pad_state.pad_states.plus.Value()); | ||
| 374 | |||
| 375 | temp_lstick_entry = pad_state.l_stick; | ||
| 376 | temp_rstick_entry = pad_state.r_stick; | ||
| 377 | std::swap(temp_lstick_entry.x, temp_lstick_entry.y); | ||
| 378 | std::swap(temp_rstick_entry.x, temp_rstick_entry.y); | ||
| 379 | temp_rstick_entry.x *= -1; | ||
| 380 | } | ||
| 381 | pad_state.pad_states.raw = state.raw; | ||
| 382 | pad_state.l_stick = temp_lstick_entry; | ||
| 383 | pad_state.r_stick = temp_rstick_entry; | ||
| 308 | } | 384 | } |
| 385 | |||
| 309 | libnx_entry.connection_status.raw = 0; | 386 | libnx_entry.connection_status.raw = 0; |
| 310 | 387 | ||
| 311 | switch (controller_type) { | 388 | switch (controller_type) { |
| @@ -316,9 +393,9 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { | |||
| 316 | handheld_entry.connection_status.IsRightJoyConnected.Assign(1); | 393 | handheld_entry.connection_status.IsRightJoyConnected.Assign(1); |
| 317 | handheld_entry.connection_status.IsLeftJoyWired.Assign(1); | 394 | handheld_entry.connection_status.IsLeftJoyWired.Assign(1); |
| 318 | handheld_entry.connection_status.IsRightJoyWired.Assign(1); | 395 | handheld_entry.connection_status.IsRightJoyWired.Assign(1); |
| 319 | handheld_entry.pad_states.raw = pad_state.raw; | 396 | handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 320 | handheld_entry.l_stick = lstick_entry; | 397 | handheld_entry.pad.l_stick = pad_state.l_stick; |
| 321 | handheld_entry.r_stick = rstick_entry; | 398 | handheld_entry.pad.r_stick = pad_state.r_stick; |
| 322 | break; | 399 | break; |
| 323 | case NPadControllerType::JoyDual: | 400 | case NPadControllerType::JoyDual: |
| 324 | dual_entry.connection_status.raw = 0; | 401 | dual_entry.connection_status.raw = 0; |
| @@ -331,25 +408,25 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { | |||
| 331 | libnx_entry.connection_status.IsRightJoyConnected.Assign(1); | 408 | libnx_entry.connection_status.IsRightJoyConnected.Assign(1); |
| 332 | libnx_entry.connection_status.IsConnected.Assign(1); | 409 | libnx_entry.connection_status.IsConnected.Assign(1); |
| 333 | 410 | ||
| 334 | dual_entry.pad_states.raw = pad_state.raw; | 411 | dual_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 335 | dual_entry.l_stick = lstick_entry; | 412 | dual_entry.pad.l_stick = pad_state.l_stick; |
| 336 | dual_entry.r_stick = rstick_entry; | 413 | dual_entry.pad.r_stick = pad_state.r_stick; |
| 337 | break; | 414 | break; |
| 338 | case NPadControllerType::JoyLeft: | 415 | case NPadControllerType::JoyLeft: |
| 339 | left_entry.connection_status.raw = 0; | 416 | left_entry.connection_status.raw = 0; |
| 340 | 417 | ||
| 341 | left_entry.connection_status.IsConnected.Assign(1); | 418 | left_entry.connection_status.IsConnected.Assign(1); |
| 342 | left_entry.pad_states.raw = pad_state.raw; | 419 | left_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 343 | left_entry.l_stick = lstick_entry; | 420 | left_entry.pad.l_stick = pad_state.l_stick; |
| 344 | left_entry.r_stick = rstick_entry; | 421 | left_entry.pad.r_stick = pad_state.r_stick; |
| 345 | break; | 422 | break; |
| 346 | case NPadControllerType::JoyRight: | 423 | case NPadControllerType::JoyRight: |
| 347 | right_entry.connection_status.raw = 0; | 424 | right_entry.connection_status.raw = 0; |
| 348 | 425 | ||
| 349 | right_entry.connection_status.IsConnected.Assign(1); | 426 | right_entry.connection_status.IsConnected.Assign(1); |
| 350 | right_entry.pad_states.raw = pad_state.raw; | 427 | right_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 351 | right_entry.l_stick = lstick_entry; | 428 | right_entry.pad.l_stick = pad_state.l_stick; |
| 352 | right_entry.r_stick = rstick_entry; | 429 | right_entry.pad.r_stick = pad_state.r_stick; |
| 353 | break; | 430 | break; |
| 354 | case NPadControllerType::Pokeball: | 431 | case NPadControllerType::Pokeball: |
| 355 | pokeball_entry.connection_status.raw = 0; | 432 | pokeball_entry.connection_status.raw = 0; |
| @@ -357,30 +434,30 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { | |||
| 357 | pokeball_entry.connection_status.IsConnected.Assign(1); | 434 | pokeball_entry.connection_status.IsConnected.Assign(1); |
| 358 | pokeball_entry.connection_status.IsWired.Assign(1); | 435 | pokeball_entry.connection_status.IsWired.Assign(1); |
| 359 | 436 | ||
| 360 | pokeball_entry.pad_states.raw = pad_state.raw; | 437 | pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 361 | pokeball_entry.l_stick = lstick_entry; | 438 | pokeball_entry.pad.l_stick = pad_state.l_stick; |
| 362 | pokeball_entry.r_stick = rstick_entry; | 439 | pokeball_entry.pad.r_stick = pad_state.r_stick; |
| 363 | break; | 440 | break; |
| 364 | case NPadControllerType::ProController: | 441 | case NPadControllerType::ProController: |
| 365 | main_controller.connection_status.raw = 0; | 442 | main_controller.connection_status.raw = 0; |
| 366 | 443 | ||
| 367 | main_controller.connection_status.IsConnected.Assign(1); | 444 | main_controller.connection_status.IsConnected.Assign(1); |
| 368 | main_controller.connection_status.IsWired.Assign(1); | 445 | main_controller.connection_status.IsWired.Assign(1); |
| 369 | main_controller.pad_states.raw = pad_state.raw; | 446 | main_controller.pad.pad_states.raw = pad_state.pad_states.raw; |
| 370 | main_controller.l_stick = lstick_entry; | 447 | main_controller.pad.l_stick = pad_state.l_stick; |
| 371 | main_controller.r_stick = rstick_entry; | 448 | main_controller.pad.r_stick = pad_state.r_stick; |
| 372 | break; | 449 | break; |
| 373 | } | 450 | } |
| 374 | 451 | ||
| 375 | // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate | 452 | // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate |
| 376 | // any controllers. | 453 | // any controllers. |
| 377 | libnx_entry.pad_states.raw = pad_state.raw; | 454 | libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 378 | libnx_entry.l_stick = lstick_entry; | 455 | libnx_entry.pad.l_stick = pad_state.l_stick; |
| 379 | libnx_entry.r_stick = rstick_entry; | 456 | libnx_entry.pad.r_stick = pad_state.r_stick; |
| 380 | } | 457 | } |
| 381 | std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), | 458 | std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), |
| 382 | shared_memory_entries.size() * sizeof(NPadEntry)); | 459 | shared_memory_entries.size() * sizeof(NPadEntry)); |
| 383 | } // namespace Service::HID | 460 | } |
| 384 | 461 | ||
| 385 | void Controller_NPad::SetSupportedStyleSet(NPadType style_set) { | 462 | void Controller_NPad::SetSupportedStyleSet(NPadType style_set) { |
| 386 | style.raw = style_set.raw; | 463 | style.raw = style_set.raw; |
| @@ -401,23 +478,24 @@ void Controller_NPad::SetSupportedNPadIdTypes(u8* data, std::size_t length) { | |||
| 401 | if (!controller.is_connected) { | 478 | if (!controller.is_connected) { |
| 402 | continue; | 479 | continue; |
| 403 | } | 480 | } |
| 404 | if (!IsControllerSupported(PREFERRED_CONTROLLER)) { | 481 | const auto requested_controller = |
| 405 | const auto best_type = DecideBestController(PREFERRED_CONTROLLER); | 482 | i <= MAX_NPAD_ID ? MapSettingsTypeToNPad(Settings::values.players[i].type) |
| 406 | const bool is_handheld = (best_type == NPadControllerType::Handheld || | 483 | : NPadControllerType::Handheld; |
| 407 | PREFERRED_CONTROLLER == NPadControllerType::Handheld); | 484 | if (!IsControllerSupported(requested_controller)) { |
| 485 | const auto is_handheld = requested_controller == NPadControllerType::Handheld; | ||
| 408 | if (is_handheld) { | 486 | if (is_handheld) { |
| 409 | controller.type = NPadControllerType::None; | 487 | controller.type = NPadControllerType::None; |
| 410 | controller.is_connected = false; | 488 | controller.is_connected = false; |
| 411 | AddNewController(best_type); | 489 | AddNewController(requested_controller); |
| 412 | } else { | 490 | } else { |
| 413 | controller.type = best_type; | 491 | controller.type = requested_controller; |
| 414 | InitNewlyAddedControler(i); | 492 | InitNewlyAddedControler(i); |
| 415 | } | 493 | } |
| 416 | had_controller_update = true; | 494 | had_controller_update = true; |
| 417 | } | 495 | } |
| 418 | } | 496 | if (had_controller_update) { |
| 419 | if (had_controller_update) { | 497 | styleset_changed_event->Signal(); |
| 420 | styleset_changed_event->Signal(); | 498 | } |
| 421 | } | 499 | } |
| 422 | } | 500 | } |
| 423 | 501 | ||
| @@ -450,15 +528,7 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids, | |||
| 450 | return; | 528 | return; |
| 451 | } | 529 | } |
| 452 | for (std::size_t i = 0; i < controller_ids.size(); i++) { | 530 | for (std::size_t i = 0; i < controller_ids.size(); i++) { |
| 453 | std::size_t controller_pos = i; | 531 | std::size_t controller_pos = NPadIdToIndex(static_cast<u32>(i)); |
| 454 | // Handheld controller conversion | ||
| 455 | if (controller_pos == NPAD_HANDHELD) { | ||
| 456 | controller_pos = 8; | ||
| 457 | } | ||
| 458 | // Unknown controller conversion | ||
| 459 | if (controller_pos == NPAD_UNKNOWN) { | ||
| 460 | controller_pos = 9; | ||
| 461 | } | ||
| 462 | if (connected_controllers[controller_pos].is_connected) { | 532 | if (connected_controllers[controller_pos].is_connected) { |
| 463 | // TODO(ogniK): Vibrate the physical controller | 533 | // TODO(ogniK): Vibrate the physical controller |
| 464 | } | 534 | } |
| @@ -477,7 +547,9 @@ Kernel::SharedPtr<Kernel::Event> Controller_NPad::GetStyleSetChangedEvent() cons | |||
| 477 | Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { | 547 | Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { |
| 478 | return last_processed_vibration; | 548 | return last_processed_vibration; |
| 479 | } | 549 | } |
| 550 | |||
| 480 | void Controller_NPad::AddNewController(NPadControllerType controller) { | 551 | void Controller_NPad::AddNewController(NPadControllerType controller) { |
| 552 | controller = DecideBestController(controller); | ||
| 481 | if (controller == NPadControllerType::Handheld) { | 553 | if (controller == NPadControllerType::Handheld) { |
| 482 | connected_controllers[8] = {controller, true}; | 554 | connected_controllers[8] = {controller, true}; |
| 483 | InitNewlyAddedControler(8); | 555 | InitNewlyAddedControler(8); |
| @@ -495,6 +567,18 @@ void Controller_NPad::AddNewController(NPadControllerType controller) { | |||
| 495 | InitNewlyAddedControler(controller_id); | 567 | InitNewlyAddedControler(controller_id); |
| 496 | } | 568 | } |
| 497 | 569 | ||
| 570 | void Controller_NPad::AddNewControllerAt(NPadControllerType controller, u32 npad_id) { | ||
| 571 | controller = DecideBestController(controller); | ||
| 572 | if (controller == NPadControllerType::Handheld) { | ||
| 573 | connected_controllers[NPadIdToIndex(NPAD_HANDHELD)] = {controller, true}; | ||
| 574 | InitNewlyAddedControler(NPadIdToIndex(NPAD_HANDHELD)); | ||
| 575 | return; | ||
| 576 | } | ||
| 577 | |||
| 578 | connected_controllers[npad_id] = {controller, true}; | ||
| 579 | InitNewlyAddedControler(npad_id); | ||
| 580 | } | ||
| 581 | |||
| 498 | void Controller_NPad::ConnectNPad(u32 npad_id) { | 582 | void Controller_NPad::ConnectNPad(u32 npad_id) { |
| 499 | connected_controllers[NPadIdToIndex(npad_id)].is_connected = true; | 583 | connected_controllers[NPadIdToIndex(npad_id)].is_connected = true; |
| 500 | } | 584 | } |
| @@ -503,6 +587,36 @@ void Controller_NPad::DisconnectNPad(u32 npad_id) { | |||
| 503 | connected_controllers[NPadIdToIndex(npad_id)].is_connected = false; | 587 | connected_controllers[NPadIdToIndex(npad_id)].is_connected = false; |
| 504 | } | 588 | } |
| 505 | 589 | ||
| 590 | bool Controller_NPad::IsControllerSupported(NPadControllerType controller) { | ||
| 591 | if (controller == NPadControllerType::Handheld) { | ||
| 592 | // Handheld is not even a supported type, lets stop here | ||
| 593 | if (std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), | ||
| 594 | NPAD_HANDHELD) == supported_npad_id_types.end()) { | ||
| 595 | return false; | ||
| 596 | } | ||
| 597 | // Handheld should not be supported in docked mode | ||
| 598 | if (Settings::values.use_docked_mode) { | ||
| 599 | return false; | ||
| 600 | } | ||
| 601 | } | ||
| 602 | switch (controller) { | ||
| 603 | case NPadControllerType::ProController: | ||
| 604 | return style.pro_controller; | ||
| 605 | case NPadControllerType::Handheld: | ||
| 606 | return style.handheld; | ||
| 607 | case NPadControllerType::JoyDual: | ||
| 608 | return style.joycon_dual; | ||
| 609 | case NPadControllerType::JoyLeft: | ||
| 610 | return style.joycon_left; | ||
| 611 | case NPadControllerType::JoyRight: | ||
| 612 | return style.joycon_right; | ||
| 613 | case NPadControllerType::Pokeball: | ||
| 614 | return style.pokeball; | ||
| 615 | default: | ||
| 616 | return false; | ||
| 617 | } | ||
| 618 | } | ||
| 619 | |||
| 506 | Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { | 620 | Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { |
| 507 | if (npad_id == npad_id_list.back() || npad_id == npad_id_list[npad_id_list.size() - 2]) { | 621 | if (npad_id == npad_id_list.back() || npad_id == npad_id_list[npad_id_list.size() - 2]) { |
| 508 | // These are controllers without led patterns | 622 | // These are controllers without led patterns |
| @@ -534,6 +648,36 @@ void Controller_NPad::SetVibrationEnabled(bool can_vibrate) { | |||
| 534 | can_controllers_vibrate = can_vibrate; | 648 | can_controllers_vibrate = can_vibrate; |
| 535 | } | 649 | } |
| 536 | 650 | ||
| 651 | void Controller_NPad::ClearAllConnectedControllers() { | ||
| 652 | for (auto& controller : connected_controllers) { | ||
| 653 | if (controller.is_connected && controller.type != NPadControllerType::None) { | ||
| 654 | controller.type = NPadControllerType::None; | ||
| 655 | controller.is_connected = false; | ||
| 656 | } | ||
| 657 | } | ||
| 658 | } | ||
| 659 | void Controller_NPad::DisconnectAllConnectedControllers() { | ||
| 660 | std::for_each(connected_controllers.begin(), connected_controllers.end(), | ||
| 661 | [](ControllerHolder& controller) { controller.is_connected = false; }); | ||
| 662 | } | ||
| 663 | |||
| 664 | void Controller_NPad::ConnectAllDisconnectedControllers() { | ||
| 665 | std::for_each(connected_controllers.begin(), connected_controllers.end(), | ||
| 666 | [](ControllerHolder& controller) { | ||
| 667 | if (controller.type != NPadControllerType::None && !controller.is_connected) { | ||
| 668 | controller.is_connected = false; | ||
| 669 | } | ||
| 670 | }); | ||
| 671 | } | ||
| 672 | |||
| 673 | void Controller_NPad::ClearAllControllers() { | ||
| 674 | std::for_each(connected_controllers.begin(), connected_controllers.end(), | ||
| 675 | [](ControllerHolder& controller) { | ||
| 676 | controller.type = NPadControllerType::None; | ||
| 677 | controller.is_connected = false; | ||
| 678 | }); | ||
| 679 | } | ||
| 680 | |||
| 537 | bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const { | 681 | bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const { |
| 538 | const bool support_handheld = | 682 | const bool support_handheld = |
| 539 | std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), NPAD_HANDHELD) != | 683 | std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), NPAD_HANDHELD) != |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index ac86985ff..ea8057b80 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -5,13 +5,18 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include "common/bit_field.h" | ||
| 8 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 9 | #include "core/frontend/input.h" | 10 | #include "core/frontend/input.h" |
| 11 | #include "core/hle/kernel/event.h" | ||
| 10 | #include "core/hle/service/hid/controllers/controller_base.h" | 12 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 11 | #include "core/settings.h" | 13 | #include "core/settings.h" |
| 12 | 14 | ||
| 13 | namespace Service::HID { | 15 | namespace Service::HID { |
| 14 | 16 | ||
| 17 | constexpr u32 NPAD_HANDHELD = 32; | ||
| 18 | constexpr u32 NPAD_UNKNOWN = 16; // TODO(ogniK): What is this? | ||
| 19 | |||
| 15 | class Controller_NPad final : public ControllerBase { | 20 | class Controller_NPad final : public ControllerBase { |
| 16 | public: | 21 | public: |
| 17 | Controller_NPad(); | 22 | Controller_NPad(); |
| @@ -107,11 +112,19 @@ public: | |||
| 107 | Vibration GetLastVibration() const; | 112 | Vibration GetLastVibration() const; |
| 108 | 113 | ||
| 109 | void AddNewController(NPadControllerType controller); | 114 | void AddNewController(NPadControllerType controller); |
| 115 | void AddNewControllerAt(NPadControllerType controller, u32 npad_id); | ||
| 110 | 116 | ||
| 111 | void ConnectNPad(u32 npad_id); | 117 | void ConnectNPad(u32 npad_id); |
| 112 | void DisconnectNPad(u32 npad_id); | 118 | void DisconnectNPad(u32 npad_id); |
| 113 | LedPattern GetLedPattern(u32 npad_id); | 119 | LedPattern GetLedPattern(u32 npad_id); |
| 114 | void SetVibrationEnabled(bool can_vibrate); | 120 | void SetVibrationEnabled(bool can_vibrate); |
| 121 | void ClearAllConnectedControllers(); | ||
| 122 | void DisconnectAllConnectedControllers(); | ||
| 123 | void ConnectAllDisconnectedControllers(); | ||
| 124 | void ClearAllControllers(); | ||
| 125 | |||
| 126 | static std::size_t NPadIdToIndex(u32 npad_id); | ||
| 127 | static u32 IndexToNPad(std::size_t index); | ||
| 115 | 128 | ||
| 116 | private: | 129 | private: |
| 117 | struct CommonHeader { | 130 | struct CommonHeader { |
| @@ -164,8 +177,11 @@ private: | |||
| 164 | BitField<23, 1, u64_le> r_stick_down; | 177 | BitField<23, 1, u64_le> r_stick_down; |
| 165 | 178 | ||
| 166 | // Not always active? | 179 | // Not always active? |
| 167 | BitField<24, 1, u64_le> sl; | 180 | BitField<24, 1, u64_le> left_sl; |
| 168 | BitField<25, 1, u64_le> sr; | 181 | BitField<25, 1, u64_le> left_sr; |
| 182 | |||
| 183 | BitField<26, 1, u64_le> right_sl; | ||
| 184 | BitField<27, 1, u64_le> right_sr; | ||
| 169 | }; | 185 | }; |
| 170 | }; | 186 | }; |
| 171 | static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size"); | 187 | static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size"); |
| @@ -189,12 +205,17 @@ private: | |||
| 189 | }; | 205 | }; |
| 190 | static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); | 206 | static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); |
| 191 | 207 | ||
| 192 | struct GenericStates { | 208 | struct ControllerPad { |
| 193 | s64_le timestamp; | ||
| 194 | s64_le timestamp2; | ||
| 195 | ControllerPadState pad_states; | 209 | ControllerPadState pad_states; |
| 196 | AnalogPosition l_stick; | 210 | AnalogPosition l_stick; |
| 197 | AnalogPosition r_stick; | 211 | AnalogPosition r_stick; |
| 212 | }; | ||
| 213 | static_assert(sizeof(ControllerPad) == 0x18, "ControllerPad is an invalid size"); | ||
| 214 | |||
| 215 | struct GenericStates { | ||
| 216 | s64_le timestamp; | ||
| 217 | s64_le timestamp2; | ||
| 218 | ControllerPad pad; | ||
| 198 | ConnectionState connection_status; | 219 | ConnectionState connection_status; |
| 199 | }; | 220 | }; |
| 200 | static_assert(sizeof(GenericStates) == 0x30, "NPadGenericStates is an invalid size"); | 221 | static_assert(sizeof(GenericStates) == 0x30, "NPadGenericStates is an invalid size"); |
| @@ -266,15 +287,20 @@ private: | |||
| 266 | static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); | 287 | static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); |
| 267 | 288 | ||
| 268 | struct ControllerHolder { | 289 | struct ControllerHolder { |
| 269 | Controller_NPad::NPadControllerType type; | 290 | NPadControllerType type; |
| 270 | bool is_connected; | 291 | bool is_connected; |
| 271 | }; | 292 | }; |
| 272 | 293 | ||
| 273 | NPadType style{}; | 294 | NPadType style{}; |
| 274 | std::array<NPadEntry, 10> shared_memory_entries{}; | 295 | std::array<NPadEntry, 10> shared_memory_entries{}; |
| 275 | std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID> | 296 | std::array< |
| 297 | std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>, | ||
| 298 | 10> | ||
| 276 | buttons; | 299 | buttons; |
| 277 | std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID> sticks; | 300 | std::array< |
| 301 | std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>, | ||
| 302 | 10> | ||
| 303 | sticks; | ||
| 278 | std::vector<u32> supported_npad_id_types{}; | 304 | std::vector<u32> supported_npad_id_types{}; |
| 279 | NpadHoldType hold_type{NpadHoldType::Vertical}; | 305 | NpadHoldType hold_type{NpadHoldType::Vertical}; |
| 280 | Kernel::SharedPtr<Kernel::Event> styleset_changed_event; | 306 | Kernel::SharedPtr<Kernel::Event> styleset_changed_event; |
| @@ -285,5 +311,8 @@ private: | |||
| 285 | void InitNewlyAddedControler(std::size_t controller_idx); | 311 | void InitNewlyAddedControler(std::size_t controller_idx); |
| 286 | bool IsControllerSupported(NPadControllerType controller) const; | 312 | bool IsControllerSupported(NPadControllerType controller) const; |
| 287 | NPadControllerType DecideBestController(NPadControllerType priority) const; | 313 | NPadControllerType DecideBestController(NPadControllerType priority) const; |
| 314 | void RequestPadStateUpdate(u32 npad_id); | ||
| 315 | std::array<ControllerPad, 10> npad_pad_states{}; | ||
| 316 | bool IsControllerSupported(NPadControllerType controller); | ||
| 288 | }; | 317 | }; |
| 289 | } // namespace Service::HID | 318 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 43efef803..f666b1bd8 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp | |||
| @@ -41,16 +41,17 @@ void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) { | |||
| 41 | 41 | ||
| 42 | const auto [x, y, pressed] = touch_device->GetStatus(); | 42 | const auto [x, y, pressed] = touch_device->GetStatus(); |
| 43 | auto& touch_entry = cur_entry.states[0]; | 43 | auto& touch_entry = cur_entry.states[0]; |
| 44 | if (pressed) { | 44 | touch_entry.attribute.raw = 0; |
| 45 | if (pressed && Settings::values.touchscreen.enabled) { | ||
| 45 | touch_entry.x = static_cast<u16>(x * Layout::ScreenUndocked::Width); | 46 | touch_entry.x = static_cast<u16>(x * Layout::ScreenUndocked::Width); |
| 46 | touch_entry.y = static_cast<u16>(y * Layout::ScreenUndocked::Height); | 47 | touch_entry.y = static_cast<u16>(y * Layout::ScreenUndocked::Height); |
| 47 | touch_entry.diameter_x = 15; | 48 | touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; |
| 48 | touch_entry.diameter_y = 15; | 49 | touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; |
| 49 | touch_entry.rotation_angle = 0; | 50 | touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; |
| 50 | const u64 tick = CoreTiming::GetTicks(); | 51 | const u64 tick = CoreTiming::GetTicks(); |
| 51 | touch_entry.delta_time = tick - last_touch; | 52 | touch_entry.delta_time = tick - last_touch; |
| 52 | last_touch = tick; | 53 | last_touch = tick; |
| 53 | touch_entry.finger = 0; | 54 | touch_entry.finger = Settings::values.touchscreen.finger; |
| 54 | cur_entry.entry_count = 1; | 55 | cur_entry.entry_count = 1; |
| 55 | } else { | 56 | } else { |
| 56 | cur_entry.entry_count = 0; | 57 | cur_entry.entry_count = 0; |
| @@ -60,6 +61,6 @@ void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) { | |||
| 60 | } | 61 | } |
| 61 | 62 | ||
| 62 | void Controller_Touchscreen::OnLoadInputDevices() { | 63 | void Controller_Touchscreen::OnLoadInputDevices() { |
| 63 | touch_device = Input::CreateDevice<Input::TouchDevice>(Settings::values.touch_device); | 64 | touch_device = Input::CreateDevice<Input::TouchDevice>(Settings::values.touchscreen.device); |
| 64 | } | 65 | } |
| 65 | } // namespace Service::HID | 66 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index e5db6e6ba..94cd0eba9 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "common/bit_field.h" | ||
| 7 | #include "common/common_funcs.h" | 8 | #include "common/common_funcs.h" |
| 8 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 9 | #include "common/swap.h" | 10 | #include "common/swap.h" |
| @@ -29,9 +30,18 @@ public: | |||
| 29 | void OnLoadInputDevices() override; | 30 | void OnLoadInputDevices() override; |
| 30 | 31 | ||
| 31 | private: | 32 | private: |
| 33 | struct Attributes { | ||
| 34 | union { | ||
| 35 | u32 raw{}; | ||
| 36 | BitField<0, 1, u32_le> start_touch; | ||
| 37 | BitField<1, 1, u32_le> end_touch; | ||
| 38 | }; | ||
| 39 | }; | ||
| 40 | static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size"); | ||
| 41 | |||
| 32 | struct TouchState { | 42 | struct TouchState { |
| 33 | u64_le delta_time; | 43 | u64_le delta_time; |
| 34 | u32_le attribute; | 44 | Attributes attribute; |
| 35 | u32_le finger; | 45 | u32_le finger; |
| 36 | u32_le x; | 46 | u32_le x; |
| 37 | u32_le y; | 47 | u32_le y; |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 39631b14f..7c0dac5dc 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -34,8 +34,8 @@ | |||
| 34 | namespace Service::HID { | 34 | namespace Service::HID { |
| 35 | 35 | ||
| 36 | // Updating period for each HID device. | 36 | // Updating period for each HID device. |
| 37 | // TODO(shinyquagsire23): These need better values. | 37 | // TODO(ogniK): Find actual polling rate of hid |
| 38 | constexpr u64 pad_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; | 38 | constexpr u64 pad_update_ticks = CoreTiming::BASE_CLOCK_RATE / 66; |
| 39 | constexpr u64 accelerometer_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; | 39 | constexpr u64 accelerometer_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; |
| 40 | constexpr u64 gyroscope_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; | 40 | constexpr u64 gyroscope_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; |
| 41 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; | 41 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; |
diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 0da159559..26fcd3405 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp | |||
| @@ -10,6 +10,56 @@ | |||
| 10 | 10 | ||
| 11 | namespace Settings { | 11 | namespace Settings { |
| 12 | 12 | ||
| 13 | namespace NativeButton { | ||
| 14 | const std::array<const char*, NumButtons> mapping = {{ | ||
| 15 | "button_a", | ||
| 16 | "button_b", | ||
| 17 | "button_x", | ||
| 18 | "button_y", | ||
| 19 | "button_lstick", | ||
| 20 | "button_rstick", | ||
| 21 | "button_l", | ||
| 22 | "button_r", | ||
| 23 | "button_zl", | ||
| 24 | "button_zr", | ||
| 25 | "button_plus", | ||
| 26 | "button_minus", | ||
| 27 | "button_dleft", | ||
| 28 | "button_dup", | ||
| 29 | "button_dright", | ||
| 30 | "button_ddown", | ||
| 31 | "button_lstick_left", | ||
| 32 | "button_lstick_up", | ||
| 33 | "button_lstick_right", | ||
| 34 | "button_lstick_down", | ||
| 35 | "button_rstick_left", | ||
| 36 | "button_rstick_up", | ||
| 37 | "button_rstick_right", | ||
| 38 | "button_rstick_down", | ||
| 39 | "button_sl", | ||
| 40 | "button_sr", | ||
| 41 | "button_home", | ||
| 42 | "button_screenshot", | ||
| 43 | }}; | ||
| 44 | } | ||
| 45 | |||
| 46 | namespace NativeAnalog { | ||
| 47 | const std::array<const char*, NumAnalogs> mapping = {{ | ||
| 48 | "lstick", | ||
| 49 | "rstick", | ||
| 50 | }}; | ||
| 51 | } | ||
| 52 | |||
| 53 | namespace NativeMouseButton { | ||
| 54 | const std::array<const char*, NumMouseButtons> mapping = {{ | ||
| 55 | "left", | ||
| 56 | "right", | ||
| 57 | "middle", | ||
| 58 | "forward", | ||
| 59 | "back", | ||
| 60 | }}; | ||
| 61 | } | ||
| 62 | |||
| 13 | Values values = {}; | 63 | Values values = {}; |
| 14 | 64 | ||
| 15 | void Apply() { | 65 | void Apply() { |
diff --git a/src/core/settings.h b/src/core/settings.h index e424479f2..e63134f80 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -60,36 +60,7 @@ constexpr int BUTTON_NS_END = NumButtons; | |||
| 60 | constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN; | 60 | constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN; |
| 61 | constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN; | 61 | constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN; |
| 62 | 62 | ||
| 63 | static const std::array<const char*, NumButtons> mapping = {{ | 63 | extern const std::array<const char*, NumButtons> mapping; |
| 64 | "button_a", | ||
| 65 | "button_b", | ||
| 66 | "button_x", | ||
| 67 | "button_y", | ||
| 68 | "button_lstick", | ||
| 69 | "button_rstick", | ||
| 70 | "button_l", | ||
| 71 | "button_r", | ||
| 72 | "button_zl", | ||
| 73 | "button_zr", | ||
| 74 | "button_plus", | ||
| 75 | "button_minus", | ||
| 76 | "button_dleft", | ||
| 77 | "button_dup", | ||
| 78 | "button_dright", | ||
| 79 | "button_ddown", | ||
| 80 | "button_lstick_left", | ||
| 81 | "button_lstick_up", | ||
| 82 | "button_lstick_right", | ||
| 83 | "button_lstick_down", | ||
| 84 | "button_rstick_left", | ||
| 85 | "button_rstick_up", | ||
| 86 | "button_rstick_right", | ||
| 87 | "button_rstick_down", | ||
| 88 | "button_sl", | ||
| 89 | "button_sr", | ||
| 90 | "button_home", | ||
| 91 | "button_screenshot", | ||
| 92 | }}; | ||
| 93 | 64 | ||
| 94 | } // namespace NativeButton | 65 | } // namespace NativeButton |
| 95 | 66 | ||
| @@ -105,12 +76,273 @@ constexpr int STICK_HID_BEGIN = LStick; | |||
| 105 | constexpr int STICK_HID_END = NumAnalogs; | 76 | constexpr int STICK_HID_END = NumAnalogs; |
| 106 | constexpr int NUM_STICKS_HID = NumAnalogs; | 77 | constexpr int NUM_STICKS_HID = NumAnalogs; |
| 107 | 78 | ||
| 108 | static const std::array<const char*, NumAnalogs> mapping = {{ | 79 | extern const std::array<const char*, NumAnalogs> mapping; |
| 109 | "lstick", | ||
| 110 | "rstick", | ||
| 111 | }}; | ||
| 112 | } // namespace NativeAnalog | 80 | } // namespace NativeAnalog |
| 113 | 81 | ||
| 82 | namespace NativeMouseButton { | ||
| 83 | enum Values { | ||
| 84 | Left, | ||
| 85 | Right, | ||
| 86 | Middle, | ||
| 87 | Forward, | ||
| 88 | Back, | ||
| 89 | |||
| 90 | NumMouseButtons, | ||
| 91 | }; | ||
| 92 | |||
| 93 | constexpr int MOUSE_HID_BEGIN = Left; | ||
| 94 | constexpr int MOUSE_HID_END = NumMouseButtons; | ||
| 95 | constexpr int NUM_MOUSE_HID = NumMouseButtons; | ||
| 96 | |||
| 97 | extern const std::array<const char*, NumMouseButtons> mapping; | ||
| 98 | } // namespace NativeMouseButton | ||
| 99 | |||
| 100 | namespace NativeKeyboard { | ||
| 101 | enum Keys { | ||
| 102 | None, | ||
| 103 | Error, | ||
| 104 | |||
| 105 | A = 4, | ||
| 106 | B, | ||
| 107 | C, | ||
| 108 | D, | ||
| 109 | E, | ||
| 110 | F, | ||
| 111 | G, | ||
| 112 | H, | ||
| 113 | I, | ||
| 114 | J, | ||
| 115 | K, | ||
| 116 | L, | ||
| 117 | M, | ||
| 118 | N, | ||
| 119 | O, | ||
| 120 | P, | ||
| 121 | Q, | ||
| 122 | R, | ||
| 123 | S, | ||
| 124 | T, | ||
| 125 | U, | ||
| 126 | V, | ||
| 127 | W, | ||
| 128 | X, | ||
| 129 | Y, | ||
| 130 | Z, | ||
| 131 | N1, | ||
| 132 | N2, | ||
| 133 | N3, | ||
| 134 | N4, | ||
| 135 | N5, | ||
| 136 | N6, | ||
| 137 | N7, | ||
| 138 | N8, | ||
| 139 | N9, | ||
| 140 | N0, | ||
| 141 | Enter, | ||
| 142 | Escape, | ||
| 143 | Backspace, | ||
| 144 | Tab, | ||
| 145 | Space, | ||
| 146 | Minus, | ||
| 147 | Equal, | ||
| 148 | LeftBrace, | ||
| 149 | RightBrace, | ||
| 150 | Backslash, | ||
| 151 | Tilde, | ||
| 152 | Semicolon, | ||
| 153 | Apostrophe, | ||
| 154 | Grave, | ||
| 155 | Comma, | ||
| 156 | Dot, | ||
| 157 | Slash, | ||
| 158 | CapsLockKey, | ||
| 159 | |||
| 160 | F1, | ||
| 161 | F2, | ||
| 162 | F3, | ||
| 163 | F4, | ||
| 164 | F5, | ||
| 165 | F6, | ||
| 166 | F7, | ||
| 167 | F8, | ||
| 168 | F9, | ||
| 169 | F10, | ||
| 170 | F11, | ||
| 171 | F12, | ||
| 172 | |||
| 173 | SystemRequest, | ||
| 174 | ScrollLockKey, | ||
| 175 | Pause, | ||
| 176 | Insert, | ||
| 177 | Home, | ||
| 178 | PageUp, | ||
| 179 | Delete, | ||
| 180 | End, | ||
| 181 | PageDown, | ||
| 182 | Right, | ||
| 183 | Left, | ||
| 184 | Down, | ||
| 185 | Up, | ||
| 186 | |||
| 187 | NumLockKey, | ||
| 188 | KPSlash, | ||
| 189 | KPAsterisk, | ||
| 190 | KPMinus, | ||
| 191 | KPPlus, | ||
| 192 | KPEnter, | ||
| 193 | KP1, | ||
| 194 | KP2, | ||
| 195 | KP3, | ||
| 196 | KP4, | ||
| 197 | KP5, | ||
| 198 | KP6, | ||
| 199 | KP7, | ||
| 200 | KP8, | ||
| 201 | KP9, | ||
| 202 | KP0, | ||
| 203 | KPDot, | ||
| 204 | |||
| 205 | Key102, | ||
| 206 | Compose, | ||
| 207 | Power, | ||
| 208 | KPEqual, | ||
| 209 | |||
| 210 | F13, | ||
| 211 | F14, | ||
| 212 | F15, | ||
| 213 | F16, | ||
| 214 | F17, | ||
| 215 | F18, | ||
| 216 | F19, | ||
| 217 | F20, | ||
| 218 | F21, | ||
| 219 | F22, | ||
| 220 | F23, | ||
| 221 | F24, | ||
| 222 | |||
| 223 | Open, | ||
| 224 | Help, | ||
| 225 | Properties, | ||
| 226 | Front, | ||
| 227 | Stop, | ||
| 228 | Repeat, | ||
| 229 | Undo, | ||
| 230 | Cut, | ||
| 231 | Copy, | ||
| 232 | Paste, | ||
| 233 | Find, | ||
| 234 | Mute, | ||
| 235 | VolumeUp, | ||
| 236 | VolumeDown, | ||
| 237 | CapsLockActive, | ||
| 238 | NumLockActive, | ||
| 239 | ScrollLockActive, | ||
| 240 | KPComma, | ||
| 241 | |||
| 242 | KPLeftParenthesis, | ||
| 243 | KPRightParenthesis, | ||
| 244 | |||
| 245 | LeftControlKey = 0xE0, | ||
| 246 | LeftShiftKey, | ||
| 247 | LeftAltKey, | ||
| 248 | LeftMetaKey, | ||
| 249 | RightControlKey, | ||
| 250 | RightShiftKey, | ||
| 251 | RightAltKey, | ||
| 252 | RightMetaKey, | ||
| 253 | |||
| 254 | MediaPlayPause, | ||
| 255 | MediaStopCD, | ||
| 256 | MediaPrevious, | ||
| 257 | MediaNext, | ||
| 258 | MediaEject, | ||
| 259 | MediaVolumeUp, | ||
| 260 | MediaVolumeDown, | ||
| 261 | MediaMute, | ||
| 262 | MediaWebsite, | ||
| 263 | MediaBack, | ||
| 264 | MediaForward, | ||
| 265 | MediaStop, | ||
| 266 | MediaFind, | ||
| 267 | MediaScrollUp, | ||
| 268 | MediaScrollDown, | ||
| 269 | MediaEdit, | ||
| 270 | MediaSleep, | ||
| 271 | MediaCoffee, | ||
| 272 | MediaRefresh, | ||
| 273 | MediaCalculator, | ||
| 274 | |||
| 275 | NumKeyboardKeys, | ||
| 276 | }; | ||
| 277 | |||
| 278 | static_assert(NumKeyboardKeys == 0xFC, "Incorrect number of keyboard keys."); | ||
| 279 | |||
| 280 | enum Modifiers { | ||
| 281 | LeftControl, | ||
| 282 | LeftShift, | ||
| 283 | LeftAlt, | ||
| 284 | LeftMeta, | ||
| 285 | RightControl, | ||
| 286 | RightShift, | ||
| 287 | RightAlt, | ||
| 288 | RightMeta, | ||
| 289 | CapsLock, | ||
| 290 | ScrollLock, | ||
| 291 | NumLock, | ||
| 292 | |||
| 293 | NumKeyboardMods, | ||
| 294 | }; | ||
| 295 | |||
| 296 | constexpr int KEYBOARD_KEYS_HID_BEGIN = None; | ||
| 297 | constexpr int KEYBOARD_KEYS_HID_END = NumKeyboardKeys; | ||
| 298 | constexpr int NUM_KEYBOARD_KEYS_HID = NumKeyboardKeys; | ||
| 299 | |||
| 300 | constexpr int KEYBOARD_MODS_HID_BEGIN = LeftControl; | ||
| 301 | constexpr int KEYBOARD_MODS_HID_END = NumKeyboardMods; | ||
| 302 | constexpr int NUM_KEYBOARD_MODS_HID = NumKeyboardMods; | ||
| 303 | |||
| 304 | } // namespace NativeKeyboard | ||
| 305 | |||
| 306 | using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>; | ||
| 307 | using AnalogsRaw = std::array<std::string, NativeAnalog::NumAnalogs>; | ||
| 308 | using MouseButtonsRaw = std::array<std::string, NativeMouseButton::NumMouseButtons>; | ||
| 309 | using KeyboardKeysRaw = std::array<std::string, NativeKeyboard::NumKeyboardKeys>; | ||
| 310 | using KeyboardModsRaw = std::array<std::string, NativeKeyboard::NumKeyboardMods>; | ||
| 311 | |||
| 312 | constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28; | ||
| 313 | constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A; | ||
| 314 | constexpr u32 JOYCON_BODY_NEON_BLUE = 0x0AB9E6; | ||
| 315 | constexpr u32 JOYCON_BUTTONS_NEON_BLUE = 0x001E1E; | ||
| 316 | |||
| 317 | enum class ControllerType { | ||
| 318 | ProController, | ||
| 319 | DualJoycon, | ||
| 320 | RightJoycon, | ||
| 321 | LeftJoycon, | ||
| 322 | }; | ||
| 323 | |||
| 324 | struct PlayerInput { | ||
| 325 | bool connected; | ||
| 326 | ControllerType type; | ||
| 327 | ButtonsRaw buttons; | ||
| 328 | AnalogsRaw analogs; | ||
| 329 | |||
| 330 | u32 body_color_right; | ||
| 331 | u32 button_color_right; | ||
| 332 | u32 body_color_left; | ||
| 333 | u32 button_color_left; | ||
| 334 | }; | ||
| 335 | |||
| 336 | struct TouchscreenInput { | ||
| 337 | bool enabled; | ||
| 338 | std::string device; | ||
| 339 | |||
| 340 | u32 finger; | ||
| 341 | u32 diameter_x; | ||
| 342 | u32 diameter_y; | ||
| 343 | u32 rotation_angle; | ||
| 344 | }; | ||
| 345 | |||
| 114 | struct Values { | 346 | struct Values { |
| 115 | // System | 347 | // System |
| 116 | bool use_docked_mode; | 348 | bool use_docked_mode; |
| @@ -120,10 +352,22 @@ struct Values { | |||
| 120 | s32 language_index; | 352 | s32 language_index; |
| 121 | 353 | ||
| 122 | // Controls | 354 | // Controls |
| 123 | std::array<std::string, NativeButton::NumButtons> buttons; | 355 | std::array<PlayerInput, 10> players; |
| 124 | std::array<std::string, NativeAnalog::NumAnalogs> analogs; | 356 | |
| 357 | bool mouse_enabled; | ||
| 358 | std::string mouse_device; | ||
| 359 | MouseButtonsRaw mouse_buttons; | ||
| 360 | |||
| 361 | bool keyboard_enabled; | ||
| 362 | KeyboardKeysRaw keyboard_keys; | ||
| 363 | KeyboardModsRaw keyboard_mods; | ||
| 364 | |||
| 365 | bool debug_pad_enabled; | ||
| 366 | ButtonsRaw debug_pad_buttons; | ||
| 367 | AnalogsRaw debug_pad_analogs; | ||
| 368 | |||
| 125 | std::string motion_device; | 369 | std::string motion_device; |
| 126 | std::string touch_device; | 370 | TouchscreenInput touchscreen; |
| 127 | std::atomic_bool is_device_reload_pending{true}; | 371 | std::atomic_bool is_device_reload_pending{true}; |
| 128 | 372 | ||
| 129 | // Core | 373 | // Core |