diff options
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 56 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.h | 37 |
2 files changed, 56 insertions, 37 deletions
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index fb3acb507..b19e831fe 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -2,10 +2,14 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 6 | #include <atomic> | ||
| 5 | #include <cmath> | 7 | #include <cmath> |
| 8 | #include <memory> | ||
| 6 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 7 | #include "core/core_timing.h" | 10 | #include "core/core_timing.h" |
| 8 | #include "core/frontend/emu_window.h" | 11 | #include "core/frontend/emu_window.h" |
| 12 | #include "core/frontend/input.h" | ||
| 9 | #include "core/hle/kernel/event.h" | 13 | #include "core/hle/kernel/event.h" |
| 10 | #include "core/hle/kernel/shared_memory.h" | 14 | #include "core/hle/kernel/shared_memory.h" |
| 11 | #include "core/hle/service/hid/hid.h" | 15 | #include "core/hle/service/hid/hid.h" |
| @@ -44,6 +48,11 @@ constexpr u64 pad_update_ticks = BASE_CLOCK_RATE_ARM11 / 234; | |||
| 44 | constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE_ARM11 / 104; | 48 | constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE_ARM11 / 104; |
| 45 | constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE_ARM11 / 101; | 49 | constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE_ARM11 / 101; |
| 46 | 50 | ||
| 51 | static std::atomic<bool> is_device_reload_pending; | ||
| 52 | static std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID> | ||
| 53 | buttons; | ||
| 54 | static std::unique_ptr<Input::AnalogDevice> circle_pad; | ||
| 55 | |||
| 47 | static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) { | 56 | static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) { |
| 48 | // 30 degree and 60 degree are angular thresholds for directions | 57 | // 30 degree and 60 degree are angular thresholds for directions |
| 49 | constexpr float TAN30 = 0.577350269f; | 58 | constexpr float TAN30 = 0.577350269f; |
| @@ -74,14 +83,48 @@ static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) { | |||
| 74 | return state; | 83 | return state; |
| 75 | } | 84 | } |
| 76 | 85 | ||
| 86 | static void LoadInputDevices() { | ||
| 87 | std::transform(Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN, | ||
| 88 | Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_END, | ||
| 89 | buttons.begin(), Input::CreateDevice<Input::ButtonDevice>); | ||
| 90 | circle_pad = Input::CreateDevice<Input::AnalogDevice>( | ||
| 91 | Settings::values.analogs[Settings::NativeAnalog::CirclePad]); | ||
| 92 | } | ||
| 93 | |||
| 94 | static void UnloadInputDevices() { | ||
| 95 | for (auto& button : buttons) { | ||
| 96 | button.reset(); | ||
| 97 | } | ||
| 98 | circle_pad.reset(); | ||
| 99 | } | ||
| 100 | |||
| 77 | static void UpdatePadCallback(u64 userdata, int cycles_late) { | 101 | static void UpdatePadCallback(u64 userdata, int cycles_late) { |
| 78 | SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); | 102 | SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); |
| 79 | 103 | ||
| 80 | PadState state = VideoCore::g_emu_window->GetPadState(); | 104 | if (is_device_reload_pending.exchange(false)) |
| 105 | LoadInputDevices(); | ||
| 106 | |||
| 107 | PadState state; | ||
| 108 | using namespace Settings::NativeButton; | ||
| 109 | state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 110 | state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 111 | state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 112 | state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 113 | state.right.Assign(buttons[Right - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 114 | state.left.Assign(buttons[Left - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 115 | state.up.Assign(buttons[Up - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 116 | state.down.Assign(buttons[Down - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 117 | state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 118 | state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 119 | state.start.Assign(buttons[Start - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 120 | state.select.Assign(buttons[Select - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 81 | 121 | ||
| 82 | // Get current circle pad position and update circle pad direction | 122 | // Get current circle pad position and update circle pad direction |
| 83 | s16 circle_pad_x, circle_pad_y; | 123 | float circle_pad_x_f, circle_pad_y_f; |
| 84 | std::tie(circle_pad_x, circle_pad_y) = VideoCore::g_emu_window->GetCirclePadState(); | 124 | std::tie(circle_pad_x_f, circle_pad_y_f) = circle_pad->GetStatus(); |
| 125 | constexpr int MAX_CIRCLEPAD_POS = 0x9C; // Max value for a circle pad position | ||
| 126 | s16 circle_pad_x = static_cast<s16>(circle_pad_x_f * MAX_CIRCLEPAD_POS); | ||
| 127 | s16 circle_pad_y = static_cast<s16>(circle_pad_y_f * MAX_CIRCLEPAD_POS); | ||
| 85 | state.hex |= GetCirclePadDirectionState(circle_pad_x, circle_pad_y).hex; | 128 | state.hex |= GetCirclePadDirectionState(circle_pad_x, circle_pad_y).hex; |
| 86 | 129 | ||
| 87 | mem->pad.current_state.hex = state.hex; | 130 | mem->pad.current_state.hex = state.hex; |
| @@ -313,6 +356,8 @@ void Init() { | |||
| 313 | AddService(new HID_U_Interface); | 356 | AddService(new HID_U_Interface); |
| 314 | AddService(new HID_SPVR_Interface); | 357 | AddService(new HID_SPVR_Interface); |
| 315 | 358 | ||
| 359 | is_device_reload_pending.store(true); | ||
| 360 | |||
| 316 | using Kernel::MemoryPermission; | 361 | using Kernel::MemoryPermission; |
| 317 | shared_mem = | 362 | shared_mem = |
| 318 | SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::Read, | 363 | SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::Read, |
| @@ -350,6 +395,11 @@ void Shutdown() { | |||
| 350 | event_accelerometer = nullptr; | 395 | event_accelerometer = nullptr; |
| 351 | event_gyroscope = nullptr; | 396 | event_gyroscope = nullptr; |
| 352 | event_debug_pad = nullptr; | 397 | event_debug_pad = nullptr; |
| 398 | UnloadInputDevices(); | ||
| 399 | } | ||
| 400 | |||
| 401 | void ReloadInputDevices() { | ||
| 402 | is_device_reload_pending.store(true); | ||
| 353 | } | 403 | } |
| 354 | 404 | ||
| 355 | } // namespace HID | 405 | } // namespace HID |
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index c7f4ee138..b505cdcd5 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -39,13 +39,6 @@ struct PadState { | |||
| 39 | BitField<10, 1, u32> x; | 39 | BitField<10, 1, u32> x; |
| 40 | BitField<11, 1, u32> y; | 40 | BitField<11, 1, u32> y; |
| 41 | 41 | ||
| 42 | BitField<14, 1, u32> zl; | ||
| 43 | BitField<15, 1, u32> zr; | ||
| 44 | |||
| 45 | BitField<24, 1, u32> c_right; | ||
| 46 | BitField<25, 1, u32> c_left; | ||
| 47 | BitField<26, 1, u32> c_up; | ||
| 48 | BitField<27, 1, u32> c_down; | ||
| 49 | BitField<28, 1, u32> circle_right; | 42 | BitField<28, 1, u32> circle_right; |
| 50 | BitField<29, 1, u32> circle_left; | 43 | BitField<29, 1, u32> circle_left; |
| 51 | BitField<30, 1, u32> circle_up; | 44 | BitField<30, 1, u32> circle_up; |
| @@ -183,33 +176,6 @@ ASSERT_REG_POSITION(touch.index_reset_ticks, 0x2A); | |||
| 183 | #undef ASSERT_REG_POSITION | 176 | #undef ASSERT_REG_POSITION |
| 184 | #endif // !defined(_MSC_VER) | 177 | #endif // !defined(_MSC_VER) |
| 185 | 178 | ||
| 186 | // Pre-defined PadStates for single button presses | ||
| 187 | const PadState PAD_NONE = {{0}}; | ||
| 188 | const PadState PAD_A = {{1u << 0}}; | ||
| 189 | const PadState PAD_B = {{1u << 1}}; | ||
| 190 | const PadState PAD_SELECT = {{1u << 2}}; | ||
| 191 | const PadState PAD_START = {{1u << 3}}; | ||
| 192 | const PadState PAD_RIGHT = {{1u << 4}}; | ||
| 193 | const PadState PAD_LEFT = {{1u << 5}}; | ||
| 194 | const PadState PAD_UP = {{1u << 6}}; | ||
| 195 | const PadState PAD_DOWN = {{1u << 7}}; | ||
| 196 | const PadState PAD_R = {{1u << 8}}; | ||
| 197 | const PadState PAD_L = {{1u << 9}}; | ||
| 198 | const PadState PAD_X = {{1u << 10}}; | ||
| 199 | const PadState PAD_Y = {{1u << 11}}; | ||
| 200 | |||
| 201 | const PadState PAD_ZL = {{1u << 14}}; | ||
| 202 | const PadState PAD_ZR = {{1u << 15}}; | ||
| 203 | |||
| 204 | const PadState PAD_C_RIGHT = {{1u << 24}}; | ||
| 205 | const PadState PAD_C_LEFT = {{1u << 25}}; | ||
| 206 | const PadState PAD_C_UP = {{1u << 26}}; | ||
| 207 | const PadState PAD_C_DOWN = {{1u << 27}}; | ||
| 208 | const PadState PAD_CIRCLE_RIGHT = {{1u << 28}}; | ||
| 209 | const PadState PAD_CIRCLE_LEFT = {{1u << 29}}; | ||
| 210 | const PadState PAD_CIRCLE_UP = {{1u << 30}}; | ||
| 211 | const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; | ||
| 212 | |||
| 213 | /** | 179 | /** |
| 214 | * HID::GetIPCHandles service function | 180 | * HID::GetIPCHandles service function |
| 215 | * Inputs: | 181 | * Inputs: |
| @@ -297,5 +263,8 @@ void Init(); | |||
| 297 | 263 | ||
| 298 | /// Shutdown HID service | 264 | /// Shutdown HID service |
| 299 | void Shutdown(); | 265 | void Shutdown(); |
| 266 | |||
| 267 | /// Reload input devices. Used when input configuration changed | ||
| 268 | void ReloadInputDevices(); | ||
| 300 | } | 269 | } |
| 301 | } | 270 | } |