diff options
Diffstat (limited to 'src')
23 files changed, 496 insertions, 392 deletions
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h index df2b1dfc5..26ec1091b 100644 --- a/src/core/hid/hid_types.h +++ b/src/core/hid/hid_types.h | |||
| @@ -316,27 +316,27 @@ static_assert(sizeof(TouchAttribute) == 0x4, "TouchAttribute is an invalid size" | |||
| 316 | 316 | ||
| 317 | // This is nn::hid::TouchState | 317 | // This is nn::hid::TouchState |
| 318 | struct TouchState { | 318 | struct TouchState { |
| 319 | u64 delta_time; | 319 | u64 delta_time{}; |
| 320 | TouchAttribute attribute; | 320 | TouchAttribute attribute{}; |
| 321 | u32 finger; | 321 | u32 finger{}; |
| 322 | Common::Point<u32> position; | 322 | Common::Point<u32> position{}; |
| 323 | u32 diameter_x; | 323 | u32 diameter_x{}; |
| 324 | u32 diameter_y; | 324 | u32 diameter_y{}; |
| 325 | u32 rotation_angle; | 325 | u32 rotation_angle{}; |
| 326 | }; | 326 | }; |
| 327 | static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size"); | 327 | static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size"); |
| 328 | 328 | ||
| 329 | // This is nn::hid::NpadControllerColor | 329 | // This is nn::hid::NpadControllerColor |
| 330 | struct NpadControllerColor { | 330 | struct NpadControllerColor { |
| 331 | u32 body; | 331 | u32 body{}; |
| 332 | u32 button; | 332 | u32 button{}; |
| 333 | }; | 333 | }; |
| 334 | static_assert(sizeof(NpadControllerColor) == 8, "NpadControllerColor is an invalid size"); | 334 | static_assert(sizeof(NpadControllerColor) == 8, "NpadControllerColor is an invalid size"); |
| 335 | 335 | ||
| 336 | // This is nn::hid::AnalogStickState | 336 | // This is nn::hid::AnalogStickState |
| 337 | struct AnalogStickState { | 337 | struct AnalogStickState { |
| 338 | s32 x; | 338 | s32 x{}; |
| 339 | s32 y; | 339 | s32 y{}; |
| 340 | }; | 340 | }; |
| 341 | static_assert(sizeof(AnalogStickState) == 8, "AnalogStickState is an invalid size"); | 341 | static_assert(sizeof(AnalogStickState) == 8, "AnalogStickState is an invalid size"); |
| 342 | 342 | ||
| @@ -354,10 +354,10 @@ static_assert(sizeof(NpadBatteryLevel) == 0x4, "NpadBatteryLevel is an invalid s | |||
| 354 | 354 | ||
| 355 | // This is nn::hid::system::NpadPowerInfo | 355 | // This is nn::hid::system::NpadPowerInfo |
| 356 | struct NpadPowerInfo { | 356 | struct NpadPowerInfo { |
| 357 | bool is_powered; | 357 | bool is_powered{}; |
| 358 | bool is_charging; | 358 | bool is_charging{}; |
| 359 | INSERT_PADDING_BYTES(0x6); | 359 | INSERT_PADDING_BYTES(0x6); |
| 360 | NpadBatteryLevel battery_level; | 360 | NpadBatteryLevel battery_level{8}; |
| 361 | }; | 361 | }; |
| 362 | static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size"); | 362 | static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size"); |
| 363 | 363 | ||
| @@ -474,8 +474,8 @@ static_assert(sizeof(DebugPadButton) == 0x4, "DebugPadButton is an invalid size" | |||
| 474 | 474 | ||
| 475 | // This is nn::hid::ConsoleSixAxisSensorHandle | 475 | // This is nn::hid::ConsoleSixAxisSensorHandle |
| 476 | struct ConsoleSixAxisSensorHandle { | 476 | struct ConsoleSixAxisSensorHandle { |
| 477 | u8 unknown_1; | 477 | u8 unknown_1{}; |
| 478 | u8 unknown_2; | 478 | u8 unknown_2{}; |
| 479 | INSERT_PADDING_BYTES_NOINIT(2); | 479 | INSERT_PADDING_BYTES_NOINIT(2); |
| 480 | }; | 480 | }; |
| 481 | static_assert(sizeof(ConsoleSixAxisSensorHandle) == 4, | 481 | static_assert(sizeof(ConsoleSixAxisSensorHandle) == 4, |
| @@ -483,9 +483,9 @@ static_assert(sizeof(ConsoleSixAxisSensorHandle) == 4, | |||
| 483 | 483 | ||
| 484 | // This is nn::hid::SixAxisSensorHandle | 484 | // This is nn::hid::SixAxisSensorHandle |
| 485 | struct SixAxisSensorHandle { | 485 | struct SixAxisSensorHandle { |
| 486 | NpadStyleIndex npad_type; | 486 | NpadStyleIndex npad_type{NpadStyleIndex::None}; |
| 487 | u8 npad_id; | 487 | u8 npad_id{}; |
| 488 | DeviceIndex device_index; | 488 | DeviceIndex device_index{DeviceIndex::None}; |
| 489 | INSERT_PADDING_BYTES_NOINIT(1); | 489 | INSERT_PADDING_BYTES_NOINIT(1); |
| 490 | }; | 490 | }; |
| 491 | static_assert(sizeof(SixAxisSensorHandle) == 4, "SixAxisSensorHandle is an invalid size"); | 491 | static_assert(sizeof(SixAxisSensorHandle) == 4, "SixAxisSensorHandle is an invalid size"); |
| @@ -500,19 +500,19 @@ static_assert(sizeof(SixAxisSensorFusionParameters) == 8, | |||
| 500 | 500 | ||
| 501 | // This is nn::hid::VibrationDeviceHandle | 501 | // This is nn::hid::VibrationDeviceHandle |
| 502 | struct VibrationDeviceHandle { | 502 | struct VibrationDeviceHandle { |
| 503 | NpadStyleIndex npad_type; | 503 | NpadStyleIndex npad_type{NpadStyleIndex::None}; |
| 504 | u8 npad_id; | 504 | u8 npad_id{}; |
| 505 | DeviceIndex device_index; | 505 | DeviceIndex device_index{DeviceIndex::None}; |
| 506 | INSERT_PADDING_BYTES_NOINIT(1); | 506 | INSERT_PADDING_BYTES_NOINIT(1); |
| 507 | }; | 507 | }; |
| 508 | static_assert(sizeof(VibrationDeviceHandle) == 4, "SixAxisSensorHandle is an invalid size"); | 508 | static_assert(sizeof(VibrationDeviceHandle) == 4, "SixAxisSensorHandle is an invalid size"); |
| 509 | 509 | ||
| 510 | // This is nn::hid::VibrationValue | 510 | // This is nn::hid::VibrationValue |
| 511 | struct VibrationValue { | 511 | struct VibrationValue { |
| 512 | f32 low_amplitude; | 512 | f32 low_amplitude{}; |
| 513 | f32 low_frequency; | 513 | f32 low_frequency{}; |
| 514 | f32 high_amplitude; | 514 | f32 high_amplitude{}; |
| 515 | f32 high_frequency; | 515 | f32 high_frequency{}; |
| 516 | }; | 516 | }; |
| 517 | static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size."); | 517 | static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size."); |
| 518 | 518 | ||
| @@ -561,7 +561,7 @@ static_assert(sizeof(KeyboardAttribute) == 0x4, "KeyboardAttribute is an invalid | |||
| 561 | // This is nn::hid::KeyboardKey | 561 | // This is nn::hid::KeyboardKey |
| 562 | struct KeyboardKey { | 562 | struct KeyboardKey { |
| 563 | // This should be a 256 bit flag | 563 | // This should be a 256 bit flag |
| 564 | std::array<u8, 32> key; | 564 | std::array<u8, 32> key{}; |
| 565 | }; | 565 | }; |
| 566 | static_assert(sizeof(KeyboardKey) == 0x20, "KeyboardKey is an invalid size"); | 566 | static_assert(sizeof(KeyboardKey) == 0x20, "KeyboardKey is an invalid size"); |
| 567 | 567 | ||
| @@ -590,16 +590,16 @@ static_assert(sizeof(MouseAttribute) == 0x4, "MouseAttribute is an invalid size" | |||
| 590 | 590 | ||
| 591 | // This is nn::hid::detail::MouseState | 591 | // This is nn::hid::detail::MouseState |
| 592 | struct MouseState { | 592 | struct MouseState { |
| 593 | s64 sampling_number; | 593 | s64 sampling_number{}; |
| 594 | s32 x; | 594 | s32 x{}; |
| 595 | s32 y; | 595 | s32 y{}; |
| 596 | s32 delta_x; | 596 | s32 delta_x{}; |
| 597 | s32 delta_y; | 597 | s32 delta_y{}; |
| 598 | // Axis Order in HW is switched for the wheel | 598 | // Axis Order in HW is switched for the wheel |
| 599 | s32 delta_wheel_y; | 599 | s32 delta_wheel_y{}; |
| 600 | s32 delta_wheel_x; | 600 | s32 delta_wheel_x{}; |
| 601 | MouseButton button; | 601 | MouseButton button{}; |
| 602 | MouseAttribute attribute; | 602 | MouseAttribute attribute{}; |
| 603 | }; | 603 | }; |
| 604 | static_assert(sizeof(MouseState) == 0x28, "MouseState is an invalid size"); | 604 | static_assert(sizeof(MouseState) == 0x28, "MouseState is an invalid size"); |
| 605 | 605 | ||
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp index f5a0b94dd..bb3cba910 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp +++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp | |||
| @@ -9,9 +9,14 @@ | |||
| 9 | namespace Service::HID { | 9 | namespace Service::HID { |
| 10 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200; | 10 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200; |
| 11 | 11 | ||
| 12 | Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_) | 12 | Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_, |
| 13 | u8* raw_shared_memory_) | ||
| 13 | : ControllerBase{hid_core_} { | 14 | : ControllerBase{hid_core_} { |
| 14 | console = hid_core.GetEmulatedConsole(); | 15 | console = hid_core.GetEmulatedConsole(); |
| 16 | static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size, | ||
| 17 | "ConsoleSharedMemory is bigger than the shared memory"); | ||
| 18 | shared_memory = std::construct_at( | ||
| 19 | reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 15 | } | 20 | } |
| 16 | 21 | ||
| 17 | Controller_ConsoleSixAxis::~Controller_ConsoleSixAxis() = default; | 22 | Controller_ConsoleSixAxis::~Controller_ConsoleSixAxis() = default; |
| @@ -20,8 +25,7 @@ void Controller_ConsoleSixAxis::OnInit() {} | |||
| 20 | 25 | ||
| 21 | void Controller_ConsoleSixAxis::OnRelease() {} | 26 | void Controller_ConsoleSixAxis::OnRelease() {} |
| 22 | 27 | ||
| 23 | void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 28 | void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 24 | std::size_t size) { | ||
| 25 | if (!IsControllerActivated() || !is_transfer_memory_set) { | 29 | if (!IsControllerActivated() || !is_transfer_memory_set) { |
| 26 | seven_sixaxis_lifo.buffer_count = 0; | 30 | seven_sixaxis_lifo.buffer_count = 0; |
| 27 | seven_sixaxis_lifo.buffer_tail = 0; | 31 | seven_sixaxis_lifo.buffer_tail = 0; |
| @@ -48,13 +52,11 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti | |||
| 48 | -motion_status.quaternion.xyz.z, | 52 | -motion_status.quaternion.xyz.z, |
| 49 | }; | 53 | }; |
| 50 | 54 | ||
| 51 | console_six_axis.sampling_number++; | 55 | shared_memory->sampling_number++; |
| 52 | console_six_axis.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; | 56 | shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; |
| 53 | console_six_axis.verticalization_error = motion_status.verticalization_error; | 57 | shared_memory->verticalization_error = motion_status.verticalization_error; |
| 54 | console_six_axis.gyro_bias = motion_status.gyro_bias; | 58 | shared_memory->gyro_bias = motion_status.gyro_bias; |
| 55 | 59 | ||
| 56 | // Update console six axis shared memory | ||
| 57 | std::memcpy(data + SHARED_MEMORY_OFFSET, &console_six_axis, sizeof(console_six_axis)); | ||
| 58 | // Update seven six axis transfer memory | 60 | // Update seven six axis transfer memory |
| 59 | seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); | 61 | seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); |
| 60 | std::memcpy(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo)); | 62 | std::memcpy(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo)); |
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/console_sixaxis.h index 6da5e9454..2fd11538f 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.h +++ b/src/core/hle/service/hid/controllers/console_sixaxis.h | |||
| @@ -17,7 +17,7 @@ class EmulatedConsole; | |||
| 17 | namespace Service::HID { | 17 | namespace Service::HID { |
| 18 | class Controller_ConsoleSixAxis final : public ControllerBase { | 18 | class Controller_ConsoleSixAxis final : public ControllerBase { |
| 19 | public: | 19 | public: |
| 20 | explicit Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_); | 20 | explicit Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 21 | ~Controller_ConsoleSixAxis() override; | 21 | ~Controller_ConsoleSixAxis() override; |
| 22 | 22 | ||
| 23 | // Called when the controller is initialized | 23 | // Called when the controller is initialized |
| @@ -27,7 +27,7 @@ public: | |||
| 27 | void OnRelease() override; | 27 | void OnRelease() override; |
| 28 | 28 | ||
| 29 | // When the controller is requesting an update for the shared memory | 29 | // When the controller is requesting an update for the shared memory |
| 30 | void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, size_t size) override; | 30 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 31 | 31 | ||
| 32 | // Called on InitializeSevenSixAxisSensor | 32 | // Called on InitializeSevenSixAxisSensor |
| 33 | void SetTransferMemoryPointer(u8* t_mem); | 33 | void SetTransferMemoryPointer(u8* t_mem); |
| @@ -61,12 +61,13 @@ private: | |||
| 61 | Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{}; | 61 | Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{}; |
| 62 | static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size"); | 62 | static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size"); |
| 63 | 63 | ||
| 64 | Core::HID::EmulatedConsole* console; | 64 | SevenSixAxisState next_seven_sixaxis_state{}; |
| 65 | u8* transfer_memory = nullptr; | 65 | u8* transfer_memory = nullptr; |
| 66 | ConsoleSharedMemory* shared_memory = nullptr; | ||
| 67 | Core::HID::EmulatedConsole* console = nullptr; | ||
| 68 | |||
| 66 | bool is_transfer_memory_set = false; | 69 | bool is_transfer_memory_set = false; |
| 67 | u64 last_saved_timestamp{}; | 70 | u64 last_saved_timestamp{}; |
| 68 | u64 last_global_timestamp{}; | 71 | u64 last_global_timestamp{}; |
| 69 | ConsoleSharedMemory console_six_axis{}; | ||
| 70 | SevenSixAxisState next_seven_sixaxis_state{}; | ||
| 71 | }; | 72 | }; |
| 72 | } // namespace Service::HID | 73 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h index bb01ea643..d6f7a5073 100644 --- a/src/core/hle/service/hid/controllers/controller_base.h +++ b/src/core/hle/service/hid/controllers/controller_base.h | |||
| @@ -26,12 +26,10 @@ public: | |||
| 26 | virtual void OnRelease() = 0; | 26 | virtual void OnRelease() = 0; |
| 27 | 27 | ||
| 28 | // When the controller is requesting an update for the shared memory | 28 | // When the controller is requesting an update for the shared memory |
| 29 | virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 29 | virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing) = 0; |
| 30 | std::size_t size) = 0; | ||
| 31 | 30 | ||
| 32 | // When the controller is requesting a motion update for the shared memory | 31 | // When the controller is requesting a motion update for the shared memory |
| 33 | virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 32 | virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {} |
| 34 | std::size_t size) {} | ||
| 35 | 33 | ||
| 36 | void ActivateController(); | 34 | void ActivateController(); |
| 37 | 35 | ||
| @@ -40,6 +38,7 @@ public: | |||
| 40 | bool IsControllerActivated() const; | 38 | bool IsControllerActivated() const; |
| 41 | 39 | ||
| 42 | static const std::size_t hid_entry_count = 17; | 40 | static const std::size_t hid_entry_count = 17; |
| 41 | static const std::size_t shared_memory_size = 0x40000; | ||
| 43 | 42 | ||
| 44 | protected: | 43 | protected: |
| 45 | bool is_activated{false}; | 44 | bool is_activated{false}; |
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp index 73309d64e..8ec9f4a95 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.cpp +++ b/src/core/hle/service/hid/controllers/debug_pad.cpp | |||
| @@ -13,8 +13,12 @@ | |||
| 13 | namespace Service::HID { | 13 | namespace Service::HID { |
| 14 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000; | 14 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000; |
| 15 | 15 | ||
| 16 | Controller_DebugPad::Controller_DebugPad(Core::HID::HIDCore& hid_core_) | 16 | Controller_DebugPad::Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) |
| 17 | : ControllerBase{hid_core_} { | 17 | : ControllerBase{hid_core_} { |
| 18 | static_assert(SHARED_MEMORY_OFFSET + sizeof(DebugPadSharedMemory) < shared_memory_size, | ||
| 19 | "DebugPadSharedMemory is bigger than the shared memory"); | ||
| 20 | shared_memory = std::construct_at( | ||
| 21 | reinterpret_cast<DebugPadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 18 | controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); | 22 | controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); |
| 19 | } | 23 | } |
| 20 | 24 | ||
| @@ -24,16 +28,14 @@ void Controller_DebugPad::OnInit() {} | |||
| 24 | 28 | ||
| 25 | void Controller_DebugPad::OnRelease() {} | 29 | void Controller_DebugPad::OnRelease() {} |
| 26 | 30 | ||
| 27 | void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 31 | void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 28 | std::size_t size) { | ||
| 29 | if (!IsControllerActivated()) { | 32 | if (!IsControllerActivated()) { |
| 30 | debug_pad_lifo.buffer_count = 0; | 33 | shared_memory->debug_pad_lifo.buffer_count = 0; |
| 31 | debug_pad_lifo.buffer_tail = 0; | 34 | shared_memory->debug_pad_lifo.buffer_tail = 0; |
| 32 | std::memcpy(data + SHARED_MEMORY_OFFSET, &debug_pad_lifo, sizeof(debug_pad_lifo)); | ||
| 33 | return; | 35 | return; |
| 34 | } | 36 | } |
| 35 | 37 | ||
| 36 | const auto& last_entry = debug_pad_lifo.ReadCurrentEntry().state; | 38 | const auto& last_entry = shared_memory->debug_pad_lifo.ReadCurrentEntry().state; |
| 37 | next_state.sampling_number = last_entry.sampling_number + 1; | 39 | next_state.sampling_number = last_entry.sampling_number + 1; |
| 38 | 40 | ||
| 39 | if (Settings::values.debug_pad_enabled) { | 41 | if (Settings::values.debug_pad_enabled) { |
| @@ -47,8 +49,7 @@ void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, | |||
| 47 | next_state.r_stick = stick_state.right; | 49 | next_state.r_stick = stick_state.right; |
| 48 | } | 50 | } |
| 49 | 51 | ||
| 50 | debug_pad_lifo.WriteNextEntry(next_state); | 52 | shared_memory->debug_pad_lifo.WriteNextEntry(next_state); |
| 51 | std::memcpy(data + SHARED_MEMORY_OFFSET, &debug_pad_lifo, sizeof(debug_pad_lifo)); | ||
| 52 | } | 53 | } |
| 53 | 54 | ||
| 54 | } // namespace Service::HID | 55 | } // 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 388d25b3c..68ff0ea79 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.h +++ b/src/core/hle/service/hid/controllers/debug_pad.h | |||
| @@ -17,7 +17,7 @@ struct AnalogStickState; | |||
| 17 | namespace Service::HID { | 17 | namespace Service::HID { |
| 18 | class Controller_DebugPad final : public ControllerBase { | 18 | class Controller_DebugPad final : public ControllerBase { |
| 19 | public: | 19 | public: |
| 20 | explicit Controller_DebugPad(Core::HID::HIDCore& hid_core_); | 20 | explicit Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 21 | ~Controller_DebugPad() override; | 21 | ~Controller_DebugPad() override; |
| 22 | 22 | ||
| 23 | // Called when the controller is initialized | 23 | // Called when the controller is initialized |
| @@ -27,7 +27,7 @@ public: | |||
| 27 | void OnRelease() override; | 27 | void OnRelease() override; |
| 28 | 28 | ||
| 29 | // When the controller is requesting an update for the shared memory | 29 | // When the controller is requesting an update for the shared memory |
| 30 | void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; | 30 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 31 | 31 | ||
| 32 | private: | 32 | private: |
| 33 | // This is nn::hid::DebugPadAttribute | 33 | // This is nn::hid::DebugPadAttribute |
| @@ -41,19 +41,24 @@ private: | |||
| 41 | 41 | ||
| 42 | // This is nn::hid::DebugPadState | 42 | // This is nn::hid::DebugPadState |
| 43 | struct DebugPadState { | 43 | struct DebugPadState { |
| 44 | s64 sampling_number; | 44 | s64 sampling_number{}; |
| 45 | DebugPadAttribute attribute; | 45 | DebugPadAttribute attribute{}; |
| 46 | Core::HID::DebugPadButton pad_state; | 46 | Core::HID::DebugPadButton pad_state{}; |
| 47 | Core::HID::AnalogStickState r_stick; | 47 | Core::HID::AnalogStickState r_stick{}; |
| 48 | Core::HID::AnalogStickState l_stick; | 48 | Core::HID::AnalogStickState l_stick{}; |
| 49 | }; | 49 | }; |
| 50 | static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state"); | 50 | static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state"); |
| 51 | 51 | ||
| 52 | // This is nn::hid::detail::DebugPadLifo | 52 | struct DebugPadSharedMemory { |
| 53 | Lifo<DebugPadState, hid_entry_count> debug_pad_lifo{}; | 53 | // This is nn::hid::detail::DebugPadLifo |
| 54 | static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size"); | 54 | Lifo<DebugPadState, hid_entry_count> debug_pad_lifo{}; |
| 55 | DebugPadState next_state{}; | 55 | static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size"); |
| 56 | INSERT_PADDING_WORDS(0x4E); | ||
| 57 | }; | ||
| 58 | static_assert(sizeof(DebugPadSharedMemory) == 0x400, "DebugPadSharedMemory is an invalid size"); | ||
| 56 | 59 | ||
| 57 | Core::HID::EmulatedController* controller; | 60 | DebugPadState next_state{}; |
| 61 | DebugPadSharedMemory* shared_memory = nullptr; | ||
| 62 | Core::HID::EmulatedController* controller = nullptr; | ||
| 58 | }; | 63 | }; |
| 59 | } // namespace Service::HID | 64 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp index c8dd131dd..3eae1ae35 100644 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ b/src/core/hle/service/hid/controllers/gesture.cpp | |||
| @@ -23,25 +23,28 @@ constexpr f32 Square(s32 num) { | |||
| 23 | return static_cast<f32>(num * num); | 23 | return static_cast<f32>(num * num); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | Controller_Gesture::Controller_Gesture(Core::HID::HIDCore& hid_core_) : ControllerBase(hid_core_) { | 26 | Controller_Gesture::Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) |
| 27 | : ControllerBase(hid_core_) { | ||
| 28 | static_assert(SHARED_MEMORY_OFFSET + sizeof(GestureSharedMemory) < shared_memory_size, | ||
| 29 | "GestureSharedMemory is bigger than the shared memory"); | ||
| 30 | shared_memory = std::construct_at( | ||
| 31 | reinterpret_cast<GestureSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 27 | console = hid_core.GetEmulatedConsole(); | 32 | console = hid_core.GetEmulatedConsole(); |
| 28 | } | 33 | } |
| 29 | Controller_Gesture::~Controller_Gesture() = default; | 34 | Controller_Gesture::~Controller_Gesture() = default; |
| 30 | 35 | ||
| 31 | void Controller_Gesture::OnInit() { | 36 | void Controller_Gesture::OnInit() { |
| 32 | gesture_lifo.buffer_count = 0; | 37 | shared_memory->gesture_lifo.buffer_count = 0; |
| 33 | gesture_lifo.buffer_tail = 0; | 38 | shared_memory->gesture_lifo.buffer_tail = 0; |
| 34 | force_update = true; | 39 | force_update = true; |
| 35 | } | 40 | } |
| 36 | 41 | ||
| 37 | void Controller_Gesture::OnRelease() {} | 42 | void Controller_Gesture::OnRelease() {} |
| 38 | 43 | ||
| 39 | void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 44 | void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 40 | std::size_t size) { | ||
| 41 | if (!IsControllerActivated()) { | 45 | if (!IsControllerActivated()) { |
| 42 | gesture_lifo.buffer_count = 0; | 46 | shared_memory->gesture_lifo.buffer_count = 0; |
| 43 | gesture_lifo.buffer_tail = 0; | 47 | shared_memory->gesture_lifo.buffer_tail = 0; |
| 44 | std::memcpy(data + SHARED_MEMORY_OFFSET, &gesture_lifo, sizeof(gesture_lifo)); | ||
| 45 | return; | 48 | return; |
| 46 | } | 49 | } |
| 47 | 50 | ||
| @@ -49,15 +52,15 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u | |||
| 49 | 52 | ||
| 50 | GestureProperties gesture = GetGestureProperties(); | 53 | GestureProperties gesture = GetGestureProperties(); |
| 51 | f32 time_difference = | 54 | f32 time_difference = |
| 52 | static_cast<f32>(gesture_lifo.timestamp - last_update_timestamp) / (1000 * 1000 * 1000); | 55 | static_cast<f32>(shared_memory->gesture_lifo.timestamp - last_update_timestamp) / |
| 56 | (1000 * 1000 * 1000); | ||
| 53 | 57 | ||
| 54 | // Only update if necesary | 58 | // Only update if necesary |
| 55 | if (!ShouldUpdateGesture(gesture, time_difference)) { | 59 | if (!ShouldUpdateGesture(gesture, time_difference)) { |
| 56 | return; | 60 | return; |
| 57 | } | 61 | } |
| 58 | 62 | ||
| 59 | last_update_timestamp = gesture_lifo.timestamp; | 63 | last_update_timestamp = shared_memory->gesture_lifo.timestamp; |
| 60 | UpdateGestureSharedMemory(data, size, gesture, time_difference); | ||
| 61 | } | 64 | } |
| 62 | 65 | ||
| 63 | void Controller_Gesture::ReadTouchInput() { | 66 | void Controller_Gesture::ReadTouchInput() { |
| @@ -97,7 +100,7 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size, | |||
| 97 | GestureType type = GestureType::Idle; | 100 | GestureType type = GestureType::Idle; |
| 98 | GestureAttribute attributes{}; | 101 | GestureAttribute attributes{}; |
| 99 | 102 | ||
| 100 | const auto& last_entry = gesture_lifo.ReadCurrentEntry().state; | 103 | const auto& last_entry = shared_memory->gesture_lifo.ReadCurrentEntry().state; |
| 101 | 104 | ||
| 102 | // Reset next state to default | 105 | // Reset next state to default |
| 103 | next_state.sampling_number = last_entry.sampling_number + 1; | 106 | next_state.sampling_number = last_entry.sampling_number + 1; |
| @@ -127,8 +130,7 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size, | |||
| 127 | next_state.points = gesture.points; | 130 | next_state.points = gesture.points; |
| 128 | last_gesture = gesture; | 131 | last_gesture = gesture; |
| 129 | 132 | ||
| 130 | gesture_lifo.WriteNextEntry(next_state); | 133 | shared_memory->gesture_lifo.WriteNextEntry(next_state); |
| 131 | std::memcpy(data + SHARED_MEMORY_OFFSET, &gesture_lifo, sizeof(gesture_lifo)); | ||
| 132 | } | 134 | } |
| 133 | 135 | ||
| 134 | void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type, | 136 | void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type, |
| @@ -305,7 +307,7 @@ void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture, | |||
| 305 | } | 307 | } |
| 306 | 308 | ||
| 307 | const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const { | 309 | const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const { |
| 308 | return gesture_lifo.ReadCurrentEntry().state; | 310 | return shared_memory->gesture_lifo.ReadCurrentEntry().state; |
| 309 | } | 311 | } |
| 310 | 312 | ||
| 311 | Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() { | 313 | Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() { |
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h index 7a9d28dc6..c62a341bf 100644 --- a/src/core/hle/service/hid/controllers/gesture.h +++ b/src/core/hle/service/hid/controllers/gesture.h | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | namespace Service::HID { | 14 | namespace Service::HID { |
| 15 | class Controller_Gesture final : public ControllerBase { | 15 | class Controller_Gesture final : public ControllerBase { |
| 16 | public: | 16 | public: |
| 17 | explicit Controller_Gesture(Core::HID::HIDCore& hid_core_); | 17 | explicit Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 18 | ~Controller_Gesture() override; | 18 | ~Controller_Gesture() override; |
| 19 | 19 | ||
| 20 | // Called when the controller is initialized | 20 | // Called when the controller is initialized |
| @@ -24,7 +24,7 @@ public: | |||
| 24 | void OnRelease() override; | 24 | void OnRelease() override; |
| 25 | 25 | ||
| 26 | // When the controller is requesting an update for the shared memory | 26 | // When the controller is requesting an update for the shared memory |
| 27 | void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, size_t size) override; | 27 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 28 | 28 | ||
| 29 | private: | 29 | private: |
| 30 | static constexpr size_t MAX_FINGERS = 16; | 30 | static constexpr size_t MAX_FINGERS = 16; |
| @@ -66,19 +66,19 @@ private: | |||
| 66 | 66 | ||
| 67 | // This is nn::hid::GestureState | 67 | // This is nn::hid::GestureState |
| 68 | struct GestureState { | 68 | struct GestureState { |
| 69 | s64 sampling_number; | 69 | s64 sampling_number{}; |
| 70 | s64 detection_count; | 70 | s64 detection_count{}; |
| 71 | GestureType type; | 71 | GestureType type{GestureType::Idle}; |
| 72 | GestureDirection direction; | 72 | GestureDirection direction{GestureDirection::None}; |
| 73 | Common::Point<s32> pos; | 73 | Common::Point<s32> pos{}; |
| 74 | Common::Point<s32> delta; | 74 | Common::Point<s32> delta{}; |
| 75 | f32 vel_x; | 75 | f32 vel_x{}; |
| 76 | f32 vel_y; | 76 | f32 vel_y{}; |
| 77 | GestureAttribute attributes; | 77 | GestureAttribute attributes{}; |
| 78 | f32 scale; | 78 | f32 scale{}; |
| 79 | f32 rotation_angle; | 79 | f32 rotation_angle{}; |
| 80 | s32 point_count; | 80 | s32 point_count{}; |
| 81 | std::array<Common::Point<s32>, 4> points; | 81 | std::array<Common::Point<s32>, 4> points{}; |
| 82 | }; | 82 | }; |
| 83 | static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); | 83 | static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); |
| 84 | 84 | ||
| @@ -92,6 +92,14 @@ private: | |||
| 92 | f32 angle{}; | 92 | f32 angle{}; |
| 93 | }; | 93 | }; |
| 94 | 94 | ||
| 95 | struct GestureSharedMemory { | ||
| 96 | // This is nn::hid::detail::GestureLifo | ||
| 97 | Lifo<GestureState, hid_entry_count> gesture_lifo{}; | ||
| 98 | static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size"); | ||
| 99 | INSERT_PADDING_WORDS(0x3E); | ||
| 100 | }; | ||
| 101 | static_assert(sizeof(GestureSharedMemory) == 0x800, "GestureSharedMemory is an invalid size"); | ||
| 102 | |||
| 95 | // Reads input from all available input engines | 103 | // Reads input from all available input engines |
| 96 | void ReadTouchInput(); | 104 | void ReadTouchInput(); |
| 97 | 105 | ||
| @@ -134,12 +142,9 @@ private: | |||
| 134 | // Returns the average distance, angle and middle point of the active fingers | 142 | // Returns the average distance, angle and middle point of the active fingers |
| 135 | GestureProperties GetGestureProperties(); | 143 | GestureProperties GetGestureProperties(); |
| 136 | 144 | ||
| 137 | // This is nn::hid::detail::GestureLifo | ||
| 138 | Lifo<GestureState, hid_entry_count> gesture_lifo{}; | ||
| 139 | static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size"); | ||
| 140 | GestureState next_state{}; | 145 | GestureState next_state{}; |
| 141 | 146 | GestureSharedMemory* shared_memory = nullptr; | |
| 142 | Core::HID::EmulatedConsole* console; | 147 | Core::HID::EmulatedConsole* console = nullptr; |
| 143 | 148 | ||
| 144 | std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{}; | 149 | std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{}; |
| 145 | GestureProperties last_gesture{}; | 150 | GestureProperties last_gesture{}; |
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index 8dc67757b..117d87433 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp | |||
| @@ -12,8 +12,12 @@ | |||
| 12 | namespace Service::HID { | 12 | namespace Service::HID { |
| 13 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; | 13 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; |
| 14 | 14 | ||
| 15 | Controller_Keyboard::Controller_Keyboard(Core::HID::HIDCore& hid_core_) | 15 | Controller_Keyboard::Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) |
| 16 | : ControllerBase{hid_core_} { | 16 | : ControllerBase{hid_core_} { |
| 17 | static_assert(SHARED_MEMORY_OFFSET + sizeof(KeyboardSharedMemory) < shared_memory_size, | ||
| 18 | "KeyboardSharedMemory is bigger than the shared memory"); | ||
| 19 | shared_memory = std::construct_at( | ||
| 20 | reinterpret_cast<KeyboardSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 17 | emulated_devices = hid_core.GetEmulatedDevices(); | 21 | emulated_devices = hid_core.GetEmulatedDevices(); |
| 18 | } | 22 | } |
| 19 | 23 | ||
| @@ -23,16 +27,14 @@ void Controller_Keyboard::OnInit() {} | |||
| 23 | 27 | ||
| 24 | void Controller_Keyboard::OnRelease() {} | 28 | void Controller_Keyboard::OnRelease() {} |
| 25 | 29 | ||
| 26 | void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 30 | void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 27 | std::size_t size) { | ||
| 28 | if (!IsControllerActivated()) { | 31 | if (!IsControllerActivated()) { |
| 29 | keyboard_lifo.buffer_count = 0; | 32 | shared_memory->keyboard_lifo.buffer_count = 0; |
| 30 | keyboard_lifo.buffer_tail = 0; | 33 | shared_memory->keyboard_lifo.buffer_tail = 0; |
| 31 | std::memcpy(data + SHARED_MEMORY_OFFSET, &keyboard_lifo, sizeof(keyboard_lifo)); | ||
| 32 | return; | 34 | return; |
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | const auto& last_entry = keyboard_lifo.ReadCurrentEntry().state; | 37 | const auto& last_entry = shared_memory->keyboard_lifo.ReadCurrentEntry().state; |
| 36 | next_state.sampling_number = last_entry.sampling_number + 1; | 38 | next_state.sampling_number = last_entry.sampling_number + 1; |
| 37 | 39 | ||
| 38 | if (Settings::values.keyboard_enabled) { | 40 | if (Settings::values.keyboard_enabled) { |
| @@ -44,8 +46,7 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, | |||
| 44 | next_state.attribute.is_connected.Assign(1); | 46 | next_state.attribute.is_connected.Assign(1); |
| 45 | } | 47 | } |
| 46 | 48 | ||
| 47 | keyboard_lifo.WriteNextEntry(next_state); | 49 | shared_memory->keyboard_lifo.WriteNextEntry(next_state); |
| 48 | std::memcpy(data + SHARED_MEMORY_OFFSET, &keyboard_lifo, sizeof(keyboard_lifo)); | ||
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | } // namespace Service::HID | 52 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h index 39c6085f1..7532f53c6 100644 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ b/src/core/hle/service/hid/controllers/keyboard.h | |||
| @@ -16,7 +16,7 @@ struct KeyboardKey; | |||
| 16 | namespace Service::HID { | 16 | namespace Service::HID { |
| 17 | class Controller_Keyboard final : public ControllerBase { | 17 | class Controller_Keyboard final : public ControllerBase { |
| 18 | public: | 18 | public: |
| 19 | explicit Controller_Keyboard(Core::HID::HIDCore& hid_core_); | 19 | explicit Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 20 | ~Controller_Keyboard() override; | 20 | ~Controller_Keyboard() override; |
| 21 | 21 | ||
| 22 | // Called when the controller is initialized | 22 | // Called when the controller is initialized |
| @@ -26,23 +26,28 @@ public: | |||
| 26 | void OnRelease() override; | 26 | void OnRelease() override; |
| 27 | 27 | ||
| 28 | // When the controller is requesting an update for the shared memory | 28 | // When the controller is requesting an update for the shared memory |
| 29 | void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; | 29 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 30 | 30 | ||
| 31 | private: | 31 | private: |
| 32 | // This is nn::hid::detail::KeyboardState | 32 | // This is nn::hid::detail::KeyboardState |
| 33 | struct KeyboardState { | 33 | struct KeyboardState { |
| 34 | s64 sampling_number; | 34 | s64 sampling_number{}; |
| 35 | Core::HID::KeyboardModifier modifier; | 35 | Core::HID::KeyboardModifier modifier{}; |
| 36 | Core::HID::KeyboardAttribute attribute; | 36 | Core::HID::KeyboardAttribute attribute{}; |
| 37 | Core::HID::KeyboardKey key; | 37 | Core::HID::KeyboardKey key{}; |
| 38 | }; | 38 | }; |
| 39 | static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size"); | 39 | static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size"); |
| 40 | 40 | ||
| 41 | // This is nn::hid::detail::KeyboardLifo | 41 | struct KeyboardSharedMemory { |
| 42 | Lifo<KeyboardState, hid_entry_count> keyboard_lifo{}; | 42 | // This is nn::hid::detail::KeyboardLifo |
| 43 | static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size"); | 43 | Lifo<KeyboardState, hid_entry_count> keyboard_lifo{}; |
| 44 | KeyboardState next_state{}; | 44 | static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size"); |
| 45 | INSERT_PADDING_WORDS(0xA); | ||
| 46 | }; | ||
| 47 | static_assert(sizeof(KeyboardSharedMemory) == 0x400, "KeyboardSharedMemory is an invalid size"); | ||
| 45 | 48 | ||
| 46 | Core::HID::EmulatedDevices* emulated_devices; | 49 | KeyboardState next_state{}; |
| 50 | KeyboardSharedMemory* shared_memory = nullptr; | ||
| 51 | Core::HID::EmulatedDevices* emulated_devices = nullptr; | ||
| 47 | }; | 52 | }; |
| 48 | } // namespace Service::HID | 53 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index a0292f586..b11cb438d 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp | |||
| @@ -12,7 +12,12 @@ | |||
| 12 | namespace Service::HID { | 12 | namespace Service::HID { |
| 13 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400; | 13 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400; |
| 14 | 14 | ||
| 15 | Controller_Mouse::Controller_Mouse(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} { | 15 | Controller_Mouse::Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) |
| 16 | : ControllerBase{hid_core_} { | ||
| 17 | static_assert(SHARED_MEMORY_OFFSET + sizeof(MouseSharedMemory) < shared_memory_size, | ||
| 18 | "MouseSharedMemory is bigger than the shared memory"); | ||
| 19 | shared_memory = std::construct_at( | ||
| 20 | reinterpret_cast<MouseSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 16 | emulated_devices = hid_core.GetEmulatedDevices(); | 21 | emulated_devices = hid_core.GetEmulatedDevices(); |
| 17 | } | 22 | } |
| 18 | 23 | ||
| @@ -21,16 +26,14 @@ Controller_Mouse::~Controller_Mouse() = default; | |||
| 21 | void Controller_Mouse::OnInit() {} | 26 | void Controller_Mouse::OnInit() {} |
| 22 | void Controller_Mouse::OnRelease() {} | 27 | void Controller_Mouse::OnRelease() {} |
| 23 | 28 | ||
| 24 | void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 29 | void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 25 | std::size_t size) { | ||
| 26 | if (!IsControllerActivated()) { | 30 | if (!IsControllerActivated()) { |
| 27 | mouse_lifo.buffer_count = 0; | 31 | shared_memory->mouse_lifo.buffer_count = 0; |
| 28 | mouse_lifo.buffer_tail = 0; | 32 | shared_memory->mouse_lifo.buffer_tail = 0; |
| 29 | std::memcpy(data + SHARED_MEMORY_OFFSET, &mouse_lifo, sizeof(mouse_lifo)); | ||
| 30 | return; | 33 | return; |
| 31 | } | 34 | } |
| 32 | 35 | ||
| 33 | const auto& last_entry = mouse_lifo.ReadCurrentEntry().state; | 36 | const auto& last_entry = shared_memory->mouse_lifo.ReadCurrentEntry().state; |
| 34 | next_state.sampling_number = last_entry.sampling_number + 1; | 37 | next_state.sampling_number = last_entry.sampling_number + 1; |
| 35 | 38 | ||
| 36 | next_state.attribute.raw = 0; | 39 | next_state.attribute.raw = 0; |
| @@ -50,8 +53,7 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 50 | next_state.button = mouse_button_state; | 53 | next_state.button = mouse_button_state; |
| 51 | } | 54 | } |
| 52 | 55 | ||
| 53 | mouse_lifo.WriteNextEntry(next_state); | 56 | shared_memory->mouse_lifo.WriteNextEntry(next_state); |
| 54 | std::memcpy(data + SHARED_MEMORY_OFFSET, &mouse_lifo, sizeof(mouse_lifo)); | ||
| 55 | } | 57 | } |
| 56 | 58 | ||
| 57 | } // namespace Service::HID | 59 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h index 62acdfb77..733d00577 100644 --- a/src/core/hle/service/hid/controllers/mouse.h +++ b/src/core/hle/service/hid/controllers/mouse.h | |||
| @@ -16,7 +16,7 @@ struct AnalogStickState; | |||
| 16 | namespace Service::HID { | 16 | namespace Service::HID { |
| 17 | class Controller_Mouse final : public ControllerBase { | 17 | class Controller_Mouse final : public ControllerBase { |
| 18 | public: | 18 | public: |
| 19 | explicit Controller_Mouse(Core::HID::HIDCore& hid_core_); | 19 | explicit Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 20 | ~Controller_Mouse() override; | 20 | ~Controller_Mouse() override; |
| 21 | 21 | ||
| 22 | // Called when the controller is initialized | 22 | // Called when the controller is initialized |
| @@ -26,15 +26,20 @@ public: | |||
| 26 | void OnRelease() override; | 26 | void OnRelease() override; |
| 27 | 27 | ||
| 28 | // When the controller is requesting an update for the shared memory | 28 | // When the controller is requesting an update for the shared memory |
| 29 | void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; | 29 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 30 | 30 | ||
| 31 | private: | 31 | private: |
| 32 | // This is nn::hid::detail::MouseLifo | 32 | struct MouseSharedMemory { |
| 33 | Lifo<Core::HID::MouseState, hid_entry_count> mouse_lifo{}; | 33 | // This is nn::hid::detail::MouseLifo |
| 34 | static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size"); | 34 | Lifo<Core::HID::MouseState, hid_entry_count> mouse_lifo{}; |
| 35 | Core::HID::MouseState next_state{}; | 35 | static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size"); |
| 36 | INSERT_PADDING_WORDS(0x2C); | ||
| 37 | }; | ||
| 38 | static_assert(sizeof(MouseSharedMemory) == 0x400, "MouseSharedMemory is an invalid size"); | ||
| 36 | 39 | ||
| 37 | Core::HID::AnalogStickState last_mouse_wheel_state; | 40 | Core::HID::MouseState next_state{}; |
| 38 | Core::HID::EmulatedDevices* emulated_devices; | 41 | Core::HID::AnalogStickState last_mouse_wheel_state{}; |
| 42 | MouseSharedMemory* shared_memory = nullptr; | ||
| 43 | Core::HID::EmulatedDevices* emulated_devices = nullptr; | ||
| 39 | }; | 44 | }; |
| 40 | } // namespace Service::HID | 45 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 16e973b25..17f71beaf 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -61,11 +61,14 @@ bool Controller_NPad::IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle& | |||
| 61 | return npad_id && npad_type && device_index; | 61 | return npad_id && npad_type && device_index; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, | 64 | Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, |
| 65 | KernelHelpers::ServiceContext& service_context_) | 65 | KernelHelpers::ServiceContext& service_context_) |
| 66 | : ControllerBase{hid_core_}, service_context{service_context_} { | 66 | : ControllerBase{hid_core_}, service_context{service_context_} { |
| 67 | static_assert(NPAD_OFFSET + (NPAD_COUNT * sizeof(NpadInternalState)) < shared_memory_size); | ||
| 67 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | 68 | for (std::size_t i = 0; i < controller_data.size(); ++i) { |
| 68 | auto& controller = controller_data[i]; | 69 | auto& controller = controller_data[i]; |
| 70 | controller.shared_memory = std::construct_at(reinterpret_cast<NpadInternalState*>( | ||
| 71 | raw_shared_memory_ + NPAD_OFFSET + (i * sizeof(NpadInternalState)))); | ||
| 69 | controller.device = hid_core.GetEmulatedControllerByIndex(i); | 72 | controller.device = hid_core.GetEmulatedControllerByIndex(i); |
| 70 | controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = | 73 | controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = |
| 71 | Core::HID::DEFAULT_VIBRATION_VALUE; | 74 | Core::HID::DEFAULT_VIBRATION_VALUE; |
| @@ -115,11 +118,11 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, | |||
| 115 | if (!controller.device->IsConnected()) { | 118 | if (!controller.device->IsConnected()) { |
| 116 | return; | 119 | return; |
| 117 | } | 120 | } |
| 118 | auto& shared_memory = controller.shared_memory_entry; | 121 | auto* shared_memory = controller.shared_memory; |
| 119 | const auto& battery_level = controller.device->GetBattery(); | 122 | const auto& battery_level = controller.device->GetBattery(); |
| 120 | shared_memory.battery_level_dual = battery_level.dual.battery_level; | 123 | shared_memory->battery_level_dual = battery_level.dual.battery_level; |
| 121 | shared_memory.battery_level_left = battery_level.left.battery_level; | 124 | shared_memory->battery_level_left = battery_level.left.battery_level; |
| 122 | shared_memory.battery_level_right = battery_level.right.battery_level; | 125 | shared_memory->battery_level_right = battery_level.right.battery_level; |
| 123 | break; | 126 | break; |
| 124 | } | 127 | } |
| 125 | default: | 128 | default: |
| @@ -134,99 +137,100 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | |||
| 134 | } | 137 | } |
| 135 | LOG_DEBUG(Service_HID, "Npad connected {}", npad_id); | 138 | LOG_DEBUG(Service_HID, "Npad connected {}", npad_id); |
| 136 | const auto controller_type = controller.device->GetNpadStyleIndex(); | 139 | const auto controller_type = controller.device->GetNpadStyleIndex(); |
| 137 | auto& shared_memory = controller.shared_memory_entry; | 140 | auto* shared_memory = controller.shared_memory; |
| 138 | if (controller_type == Core::HID::NpadStyleIndex::None) { | 141 | if (controller_type == Core::HID::NpadStyleIndex::None) { |
| 139 | controller.styleset_changed_event->GetWritableEvent().Signal(); | 142 | controller.styleset_changed_event->GetWritableEvent().Signal(); |
| 140 | return; | 143 | return; |
| 141 | } | 144 | } |
| 142 | shared_memory.style_tag.raw = Core::HID::NpadStyleSet::None; | 145 | shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None; |
| 143 | shared_memory.device_type.raw = 0; | 146 | shared_memory->device_type.raw = 0; |
| 144 | shared_memory.system_properties.raw = 0; | 147 | shared_memory->system_properties.raw = 0; |
| 145 | switch (controller_type) { | 148 | switch (controller_type) { |
| 146 | case Core::HID::NpadStyleIndex::None: | 149 | case Core::HID::NpadStyleIndex::None: |
| 147 | UNREACHABLE(); | 150 | UNREACHABLE(); |
| 148 | break; | 151 | break; |
| 149 | case Core::HID::NpadStyleIndex::ProController: | 152 | case Core::HID::NpadStyleIndex::ProController: |
| 150 | shared_memory.style_tag.fullkey.Assign(1); | 153 | shared_memory->style_tag.fullkey.Assign(1); |
| 151 | shared_memory.device_type.fullkey.Assign(1); | 154 | shared_memory->device_type.fullkey.Assign(1); |
| 152 | shared_memory.system_properties.is_vertical.Assign(1); | 155 | shared_memory->system_properties.is_vertical.Assign(1); |
| 153 | shared_memory.system_properties.use_plus.Assign(1); | 156 | shared_memory->system_properties.use_plus.Assign(1); |
| 154 | shared_memory.system_properties.use_minus.Assign(1); | 157 | shared_memory->system_properties.use_minus.Assign(1); |
| 155 | shared_memory.applet_footer.type = AppletFooterUiType::SwitchProController; | 158 | shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::SwitchProController; |
| 156 | break; | 159 | break; |
| 157 | case Core::HID::NpadStyleIndex::Handheld: | 160 | case Core::HID::NpadStyleIndex::Handheld: |
| 158 | shared_memory.style_tag.handheld.Assign(1); | 161 | shared_memory->style_tag.handheld.Assign(1); |
| 159 | shared_memory.device_type.handheld_left.Assign(1); | 162 | shared_memory->device_type.handheld_left.Assign(1); |
| 160 | shared_memory.device_type.handheld_right.Assign(1); | 163 | shared_memory->device_type.handheld_right.Assign(1); |
| 161 | shared_memory.system_properties.is_vertical.Assign(1); | 164 | shared_memory->system_properties.is_vertical.Assign(1); |
| 162 | shared_memory.system_properties.use_plus.Assign(1); | 165 | shared_memory->system_properties.use_plus.Assign(1); |
| 163 | shared_memory.system_properties.use_minus.Assign(1); | 166 | shared_memory->system_properties.use_minus.Assign(1); |
| 164 | shared_memory.system_properties.use_directional_buttons.Assign(1); | 167 | shared_memory->system_properties.use_directional_buttons.Assign(1); |
| 165 | shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual; | 168 | shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual; |
| 166 | shared_memory.applet_footer.type = AppletFooterUiType::HandheldJoyConLeftJoyConRight; | 169 | shared_memory->applet_nfc_xcd.applet_footer.type = |
| 170 | AppletFooterUiType::HandheldJoyConLeftJoyConRight; | ||
| 167 | break; | 171 | break; |
| 168 | case Core::HID::NpadStyleIndex::JoyconDual: | 172 | case Core::HID::NpadStyleIndex::JoyconDual: |
| 169 | shared_memory.style_tag.joycon_dual.Assign(1); | 173 | shared_memory->style_tag.joycon_dual.Assign(1); |
| 170 | if (controller.is_dual_left_connected) { | 174 | if (controller.is_dual_left_connected) { |
| 171 | shared_memory.device_type.joycon_left.Assign(1); | 175 | shared_memory->device_type.joycon_left.Assign(1); |
| 172 | shared_memory.system_properties.use_minus.Assign(1); | 176 | shared_memory->system_properties.use_minus.Assign(1); |
| 173 | } | 177 | } |
| 174 | if (controller.is_dual_right_connected) { | 178 | if (controller.is_dual_right_connected) { |
| 175 | shared_memory.device_type.joycon_right.Assign(1); | 179 | shared_memory->device_type.joycon_right.Assign(1); |
| 176 | shared_memory.system_properties.use_plus.Assign(1); | 180 | shared_memory->system_properties.use_plus.Assign(1); |
| 177 | } | 181 | } |
| 178 | shared_memory.system_properties.use_directional_buttons.Assign(1); | 182 | shared_memory->system_properties.use_directional_buttons.Assign(1); |
| 179 | shared_memory.system_properties.is_vertical.Assign(1); | 183 | shared_memory->system_properties.is_vertical.Assign(1); |
| 180 | shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual; | 184 | shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual; |
| 181 | if (controller.is_dual_left_connected && controller.is_dual_right_connected) { | 185 | if (controller.is_dual_left_connected && controller.is_dual_right_connected) { |
| 182 | shared_memory.applet_footer.type = AppletFooterUiType::JoyDual; | 186 | shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDual; |
| 183 | } else if (controller.is_dual_left_connected) { | 187 | } else if (controller.is_dual_left_connected) { |
| 184 | shared_memory.applet_footer.type = AppletFooterUiType::JoyDualLeftOnly; | 188 | shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualLeftOnly; |
| 185 | } else { | 189 | } else { |
| 186 | shared_memory.applet_footer.type = AppletFooterUiType::JoyDualRightOnly; | 190 | shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualRightOnly; |
| 187 | } | 191 | } |
| 188 | break; | 192 | break; |
| 189 | case Core::HID::NpadStyleIndex::JoyconLeft: | 193 | case Core::HID::NpadStyleIndex::JoyconLeft: |
| 190 | shared_memory.style_tag.joycon_left.Assign(1); | 194 | shared_memory->style_tag.joycon_left.Assign(1); |
| 191 | shared_memory.device_type.joycon_left.Assign(1); | 195 | shared_memory->device_type.joycon_left.Assign(1); |
| 192 | shared_memory.system_properties.is_horizontal.Assign(1); | 196 | shared_memory->system_properties.is_horizontal.Assign(1); |
| 193 | shared_memory.system_properties.use_minus.Assign(1); | 197 | shared_memory->system_properties.use_minus.Assign(1); |
| 194 | shared_memory.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal; | 198 | shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal; |
| 195 | break; | 199 | break; |
| 196 | case Core::HID::NpadStyleIndex::JoyconRight: | 200 | case Core::HID::NpadStyleIndex::JoyconRight: |
| 197 | shared_memory.style_tag.joycon_right.Assign(1); | 201 | shared_memory->style_tag.joycon_right.Assign(1); |
| 198 | shared_memory.device_type.joycon_right.Assign(1); | 202 | shared_memory->device_type.joycon_right.Assign(1); |
| 199 | shared_memory.system_properties.is_horizontal.Assign(1); | 203 | shared_memory->system_properties.is_horizontal.Assign(1); |
| 200 | shared_memory.system_properties.use_plus.Assign(1); | 204 | shared_memory->system_properties.use_plus.Assign(1); |
| 201 | shared_memory.applet_footer.type = AppletFooterUiType::JoyRightHorizontal; | 205 | shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyRightHorizontal; |
| 202 | break; | 206 | break; |
| 203 | case Core::HID::NpadStyleIndex::GameCube: | 207 | case Core::HID::NpadStyleIndex::GameCube: |
| 204 | shared_memory.style_tag.gamecube.Assign(1); | 208 | shared_memory->style_tag.gamecube.Assign(1); |
| 205 | shared_memory.device_type.fullkey.Assign(1); | 209 | shared_memory->device_type.fullkey.Assign(1); |
| 206 | shared_memory.system_properties.is_vertical.Assign(1); | 210 | shared_memory->system_properties.is_vertical.Assign(1); |
| 207 | shared_memory.system_properties.use_plus.Assign(1); | 211 | shared_memory->system_properties.use_plus.Assign(1); |
| 208 | break; | 212 | break; |
| 209 | case Core::HID::NpadStyleIndex::Pokeball: | 213 | case Core::HID::NpadStyleIndex::Pokeball: |
| 210 | shared_memory.style_tag.palma.Assign(1); | 214 | shared_memory->style_tag.palma.Assign(1); |
| 211 | shared_memory.device_type.palma.Assign(1); | 215 | shared_memory->device_type.palma.Assign(1); |
| 212 | break; | 216 | break; |
| 213 | case Core::HID::NpadStyleIndex::NES: | 217 | case Core::HID::NpadStyleIndex::NES: |
| 214 | shared_memory.style_tag.lark.Assign(1); | 218 | shared_memory->style_tag.lark.Assign(1); |
| 215 | shared_memory.device_type.fullkey.Assign(1); | 219 | shared_memory->device_type.fullkey.Assign(1); |
| 216 | break; | 220 | break; |
| 217 | case Core::HID::NpadStyleIndex::SNES: | 221 | case Core::HID::NpadStyleIndex::SNES: |
| 218 | shared_memory.style_tag.lucia.Assign(1); | 222 | shared_memory->style_tag.lucia.Assign(1); |
| 219 | shared_memory.device_type.fullkey.Assign(1); | 223 | shared_memory->device_type.fullkey.Assign(1); |
| 220 | shared_memory.applet_footer.type = AppletFooterUiType::Lucia; | 224 | shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::Lucia; |
| 221 | break; | 225 | break; |
| 222 | case Core::HID::NpadStyleIndex::N64: | 226 | case Core::HID::NpadStyleIndex::N64: |
| 223 | shared_memory.style_tag.lagoon.Assign(1); | 227 | shared_memory->style_tag.lagoon.Assign(1); |
| 224 | shared_memory.device_type.fullkey.Assign(1); | 228 | shared_memory->device_type.fullkey.Assign(1); |
| 225 | shared_memory.applet_footer.type = AppletFooterUiType::Lagon; | 229 | shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::Lagon; |
| 226 | break; | 230 | break; |
| 227 | case Core::HID::NpadStyleIndex::SegaGenesis: | 231 | case Core::HID::NpadStyleIndex::SegaGenesis: |
| 228 | shared_memory.style_tag.lager.Assign(1); | 232 | shared_memory->style_tag.lager.Assign(1); |
| 229 | shared_memory.device_type.fullkey.Assign(1); | 233 | shared_memory->device_type.fullkey.Assign(1); |
| 230 | break; | 234 | break; |
| 231 | default: | 235 | default: |
| 232 | break; | 236 | break; |
| @@ -234,23 +238,23 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | |||
| 234 | 238 | ||
| 235 | const auto& body_colors = controller.device->GetColors(); | 239 | const auto& body_colors = controller.device->GetColors(); |
| 236 | 240 | ||
| 237 | shared_memory.fullkey_color.attribute = ColorAttribute::Ok; | 241 | shared_memory->fullkey_color.attribute = ColorAttribute::Ok; |
| 238 | shared_memory.fullkey_color.fullkey = body_colors.fullkey; | 242 | shared_memory->fullkey_color.fullkey = body_colors.fullkey; |
| 239 | 243 | ||
| 240 | shared_memory.joycon_color.attribute = ColorAttribute::Ok; | 244 | shared_memory->joycon_color.attribute = ColorAttribute::Ok; |
| 241 | shared_memory.joycon_color.left = body_colors.left; | 245 | shared_memory->joycon_color.left = body_colors.left; |
| 242 | shared_memory.joycon_color.right = body_colors.right; | 246 | shared_memory->joycon_color.right = body_colors.right; |
| 243 | 247 | ||
| 244 | // TODO: Investigate when we should report all batery types | 248 | // TODO: Investigate when we should report all batery types |
| 245 | const auto& battery_level = controller.device->GetBattery(); | 249 | const auto& battery_level = controller.device->GetBattery(); |
| 246 | shared_memory.battery_level_dual = battery_level.dual.battery_level; | 250 | shared_memory->battery_level_dual = battery_level.dual.battery_level; |
| 247 | shared_memory.battery_level_left = battery_level.left.battery_level; | 251 | shared_memory->battery_level_left = battery_level.left.battery_level; |
| 248 | shared_memory.battery_level_right = battery_level.right.battery_level; | 252 | shared_memory->battery_level_right = battery_level.right.battery_level; |
| 249 | 253 | ||
| 250 | controller.is_connected = true; | 254 | controller.is_connected = true; |
| 251 | controller.device->Connect(); | 255 | controller.device->Connect(); |
| 252 | SignalStyleSetChangedEvent(npad_id); | 256 | SignalStyleSetChangedEvent(npad_id); |
| 253 | WriteEmptyEntry(controller.shared_memory_entry); | 257 | WriteEmptyEntry(controller.shared_memory); |
| 254 | } | 258 | } |
| 255 | 259 | ||
| 256 | void Controller_NPad::OnInit() { | 260 | void Controller_NPad::OnInit() { |
| @@ -270,12 +274,12 @@ void Controller_NPad::OnInit() { | |||
| 270 | 274 | ||
| 271 | // Prefill controller buffers | 275 | // Prefill controller buffers |
| 272 | for (auto& controller : controller_data) { | 276 | for (auto& controller : controller_data) { |
| 273 | auto& npad = controller.shared_memory_entry; | 277 | auto* npad = controller.shared_memory; |
| 274 | npad.fullkey_color = { | 278 | npad->fullkey_color = { |
| 275 | .attribute = ColorAttribute::NoController, | 279 | .attribute = ColorAttribute::NoController, |
| 276 | .fullkey = {}, | 280 | .fullkey = {}, |
| 277 | }; | 281 | }; |
| 278 | npad.joycon_color = { | 282 | npad->joycon_color = { |
| 279 | .attribute = ColorAttribute::NoController, | 283 | .attribute = ColorAttribute::NoController, |
| 280 | .left = {}, | 284 | .left = {}, |
| 281 | .right = {}, | 285 | .right = {}, |
| @@ -287,25 +291,25 @@ void Controller_NPad::OnInit() { | |||
| 287 | } | 291 | } |
| 288 | } | 292 | } |
| 289 | 293 | ||
| 290 | void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) { | 294 | void Controller_NPad::WriteEmptyEntry(NpadInternalState* npad) { |
| 291 | NPadGenericState dummy_pad_state{}; | 295 | NPadGenericState dummy_pad_state{}; |
| 292 | NpadGcTriggerState dummy_gc_state{}; | 296 | NpadGcTriggerState dummy_gc_state{}; |
| 293 | dummy_pad_state.sampling_number = npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1; | 297 | dummy_pad_state.sampling_number = npad->fullkey_lifo.ReadCurrentEntry().sampling_number + 1; |
| 294 | npad.fullkey_lifo.WriteNextEntry(dummy_pad_state); | 298 | npad->fullkey_lifo.WriteNextEntry(dummy_pad_state); |
| 295 | dummy_pad_state.sampling_number = npad.handheld_lifo.ReadCurrentEntry().sampling_number + 1; | 299 | dummy_pad_state.sampling_number = npad->handheld_lifo.ReadCurrentEntry().sampling_number + 1; |
| 296 | npad.handheld_lifo.WriteNextEntry(dummy_pad_state); | 300 | npad->handheld_lifo.WriteNextEntry(dummy_pad_state); |
| 297 | dummy_pad_state.sampling_number = npad.joy_dual_lifo.ReadCurrentEntry().sampling_number + 1; | 301 | dummy_pad_state.sampling_number = npad->joy_dual_lifo.ReadCurrentEntry().sampling_number + 1; |
| 298 | npad.joy_dual_lifo.WriteNextEntry(dummy_pad_state); | 302 | npad->joy_dual_lifo.WriteNextEntry(dummy_pad_state); |
| 299 | dummy_pad_state.sampling_number = npad.joy_left_lifo.ReadCurrentEntry().sampling_number + 1; | 303 | dummy_pad_state.sampling_number = npad->joy_left_lifo.ReadCurrentEntry().sampling_number + 1; |
| 300 | npad.joy_left_lifo.WriteNextEntry(dummy_pad_state); | 304 | npad->joy_left_lifo.WriteNextEntry(dummy_pad_state); |
| 301 | dummy_pad_state.sampling_number = npad.joy_right_lifo.ReadCurrentEntry().sampling_number + 1; | 305 | dummy_pad_state.sampling_number = npad->joy_right_lifo.ReadCurrentEntry().sampling_number + 1; |
| 302 | npad.joy_right_lifo.WriteNextEntry(dummy_pad_state); | 306 | npad->joy_right_lifo.WriteNextEntry(dummy_pad_state); |
| 303 | dummy_pad_state.sampling_number = npad.palma_lifo.ReadCurrentEntry().sampling_number + 1; | 307 | dummy_pad_state.sampling_number = npad->palma_lifo.ReadCurrentEntry().sampling_number + 1; |
| 304 | npad.palma_lifo.WriteNextEntry(dummy_pad_state); | 308 | npad->palma_lifo.WriteNextEntry(dummy_pad_state); |
| 305 | dummy_pad_state.sampling_number = npad.system_ext_lifo.ReadCurrentEntry().sampling_number + 1; | 309 | dummy_pad_state.sampling_number = npad->system_ext_lifo.ReadCurrentEntry().sampling_number + 1; |
| 306 | npad.system_ext_lifo.WriteNextEntry(dummy_pad_state); | 310 | npad->system_ext_lifo.WriteNextEntry(dummy_pad_state); |
| 307 | dummy_gc_state.sampling_number = npad.gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1; | 311 | dummy_gc_state.sampling_number = npad->gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1; |
| 308 | npad.gc_trigger_lifo.WriteNextEntry(dummy_gc_state); | 312 | npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state); |
| 309 | } | 313 | } |
| 310 | 314 | ||
| 311 | void Controller_NPad::OnRelease() { | 315 | void Controller_NPad::OnRelease() { |
| @@ -371,23 +375,19 @@ void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) { | |||
| 371 | } | 375 | } |
| 372 | } | 376 | } |
| 373 | 377 | ||
| 374 | void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 378 | void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 375 | std::size_t data_len) { | ||
| 376 | if (!IsControllerActivated()) { | 379 | if (!IsControllerActivated()) { |
| 377 | return; | 380 | return; |
| 378 | } | 381 | } |
| 379 | 382 | ||
| 380 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | 383 | for (std::size_t i = 0; i < controller_data.size(); ++i) { |
| 381 | auto& controller = controller_data[i]; | 384 | auto& controller = controller_data[i]; |
| 382 | auto& npad = controller.shared_memory_entry; | 385 | auto* npad = controller.shared_memory; |
| 383 | 386 | ||
| 384 | const auto& controller_type = controller.device->GetNpadStyleIndex(); | 387 | const auto& controller_type = controller.device->GetNpadStyleIndex(); |
| 385 | 388 | ||
| 386 | if (controller_type == Core::HID::NpadStyleIndex::None || | 389 | if (controller_type == Core::HID::NpadStyleIndex::None || |
| 387 | !controller.device->IsConnected()) { | 390 | !controller.device->IsConnected()) { |
| 388 | // Refresh shared memory | ||
| 389 | std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)), | ||
| 390 | &controller.shared_memory_entry, sizeof(NpadInternalState)); | ||
| 391 | continue; | 391 | continue; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| @@ -415,8 +415,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 415 | 415 | ||
| 416 | libnx_state.connection_status.is_wired.Assign(1); | 416 | libnx_state.connection_status.is_wired.Assign(1); |
| 417 | pad_state.sampling_number = | 417 | pad_state.sampling_number = |
| 418 | npad.fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; | 418 | npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 419 | npad.fullkey_lifo.WriteNextEntry(pad_state); | 419 | npad->fullkey_lifo.WriteNextEntry(pad_state); |
| 420 | break; | 420 | break; |
| 421 | case Core::HID::NpadStyleIndex::Handheld: | 421 | case Core::HID::NpadStyleIndex::Handheld: |
| 422 | pad_state.connection_status.raw = 0; | 422 | pad_state.connection_status.raw = 0; |
| @@ -433,8 +433,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 433 | libnx_state.connection_status.is_left_wired.Assign(1); | 433 | libnx_state.connection_status.is_left_wired.Assign(1); |
| 434 | libnx_state.connection_status.is_right_wired.Assign(1); | 434 | libnx_state.connection_status.is_right_wired.Assign(1); |
| 435 | pad_state.sampling_number = | 435 | pad_state.sampling_number = |
| 436 | npad.handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; | 436 | npad->handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 437 | npad.handheld_lifo.WriteNextEntry(pad_state); | 437 | npad->handheld_lifo.WriteNextEntry(pad_state); |
| 438 | break; | 438 | break; |
| 439 | case Core::HID::NpadStyleIndex::JoyconDual: | 439 | case Core::HID::NpadStyleIndex::JoyconDual: |
| 440 | pad_state.connection_status.raw = 0; | 440 | pad_state.connection_status.raw = 0; |
| @@ -449,8 +449,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 449 | } | 449 | } |
| 450 | 450 | ||
| 451 | pad_state.sampling_number = | 451 | pad_state.sampling_number = |
| 452 | npad.joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1; | 452 | npad->joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 453 | npad.joy_dual_lifo.WriteNextEntry(pad_state); | 453 | npad->joy_dual_lifo.WriteNextEntry(pad_state); |
| 454 | break; | 454 | break; |
| 455 | case Core::HID::NpadStyleIndex::JoyconLeft: | 455 | case Core::HID::NpadStyleIndex::JoyconLeft: |
| 456 | pad_state.connection_status.raw = 0; | 456 | pad_state.connection_status.raw = 0; |
| @@ -459,8 +459,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 459 | 459 | ||
| 460 | libnx_state.connection_status.is_left_connected.Assign(1); | 460 | libnx_state.connection_status.is_left_connected.Assign(1); |
| 461 | pad_state.sampling_number = | 461 | pad_state.sampling_number = |
| 462 | npad.joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1; | 462 | npad->joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 463 | npad.joy_left_lifo.WriteNextEntry(pad_state); | 463 | npad->joy_left_lifo.WriteNextEntry(pad_state); |
| 464 | break; | 464 | break; |
| 465 | case Core::HID::NpadStyleIndex::JoyconRight: | 465 | case Core::HID::NpadStyleIndex::JoyconRight: |
| 466 | pad_state.connection_status.raw = 0; | 466 | pad_state.connection_status.raw = 0; |
| @@ -469,8 +469,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 469 | 469 | ||
| 470 | libnx_state.connection_status.is_right_connected.Assign(1); | 470 | libnx_state.connection_status.is_right_connected.Assign(1); |
| 471 | pad_state.sampling_number = | 471 | pad_state.sampling_number = |
| 472 | npad.joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1; | 472 | npad->joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 473 | npad.joy_right_lifo.WriteNextEntry(pad_state); | 473 | npad->joy_right_lifo.WriteNextEntry(pad_state); |
| 474 | break; | 474 | break; |
| 475 | case Core::HID::NpadStyleIndex::GameCube: | 475 | case Core::HID::NpadStyleIndex::GameCube: |
| 476 | pad_state.connection_status.raw = 0; | 476 | pad_state.connection_status.raw = 0; |
| @@ -479,18 +479,18 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 479 | 479 | ||
| 480 | libnx_state.connection_status.is_wired.Assign(1); | 480 | libnx_state.connection_status.is_wired.Assign(1); |
| 481 | pad_state.sampling_number = | 481 | pad_state.sampling_number = |
| 482 | npad.fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; | 482 | npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 483 | trigger_state.sampling_number = | 483 | trigger_state.sampling_number = |
| 484 | npad.gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1; | 484 | npad->gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 485 | npad.fullkey_lifo.WriteNextEntry(pad_state); | 485 | npad->fullkey_lifo.WriteNextEntry(pad_state); |
| 486 | npad.gc_trigger_lifo.WriteNextEntry(trigger_state); | 486 | npad->gc_trigger_lifo.WriteNextEntry(trigger_state); |
| 487 | break; | 487 | break; |
| 488 | case Core::HID::NpadStyleIndex::Pokeball: | 488 | case Core::HID::NpadStyleIndex::Pokeball: |
| 489 | pad_state.connection_status.raw = 0; | 489 | pad_state.connection_status.raw = 0; |
| 490 | pad_state.connection_status.is_connected.Assign(1); | 490 | pad_state.connection_status.is_connected.Assign(1); |
| 491 | pad_state.sampling_number = | 491 | pad_state.sampling_number = |
| 492 | npad.palma_lifo.ReadCurrentEntry().state.sampling_number + 1; | 492 | npad->palma_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 493 | npad.palma_lifo.WriteNextEntry(pad_state); | 493 | npad->palma_lifo.WriteNextEntry(pad_state); |
| 494 | break; | 494 | break; |
| 495 | default: | 495 | default: |
| 496 | break; | 496 | break; |
| @@ -499,17 +499,13 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 499 | libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw; | 499 | libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw; |
| 500 | libnx_state.l_stick = pad_state.l_stick; | 500 | libnx_state.l_stick = pad_state.l_stick; |
| 501 | libnx_state.r_stick = pad_state.r_stick; | 501 | libnx_state.r_stick = pad_state.r_stick; |
| 502 | npad.system_ext_lifo.WriteNextEntry(pad_state); | 502 | npad->system_ext_lifo.WriteNextEntry(pad_state); |
| 503 | 503 | ||
| 504 | press_state |= static_cast<u64>(pad_state.npad_buttons.raw); | 504 | press_state |= static_cast<u64>(pad_state.npad_buttons.raw); |
| 505 | |||
| 506 | std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)), | ||
| 507 | &controller.shared_memory_entry, sizeof(NpadInternalState)); | ||
| 508 | } | 505 | } |
| 509 | } | 506 | } |
| 510 | 507 | ||
| 511 | void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 508 | void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 512 | std::size_t data_len) { | ||
| 513 | if (!IsControllerActivated()) { | 509 | if (!IsControllerActivated()) { |
| 514 | return; | 510 | return; |
| 515 | } | 511 | } |
| @@ -524,7 +520,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 524 | continue; | 520 | continue; |
| 525 | } | 521 | } |
| 526 | 522 | ||
| 527 | auto& npad = controller.shared_memory_entry; | 523 | auto* npad = controller.shared_memory; |
| 528 | const auto& motion_state = controller.device->GetMotions(); | 524 | const auto& motion_state = controller.device->GetMotions(); |
| 529 | auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state; | 525 | auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state; |
| 530 | auto& sixaxis_handheld_state = controller.sixaxis_handheld_state; | 526 | auto& sixaxis_handheld_state = controller.sixaxis_handheld_state; |
| @@ -610,32 +606,30 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 610 | } | 606 | } |
| 611 | 607 | ||
| 612 | sixaxis_fullkey_state.sampling_number = | 608 | sixaxis_fullkey_state.sampling_number = |
| 613 | npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; | 609 | npad->sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 614 | sixaxis_handheld_state.sampling_number = | 610 | sixaxis_handheld_state.sampling_number = |
| 615 | npad.sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; | 611 | npad->sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 616 | sixaxis_dual_left_state.sampling_number = | 612 | sixaxis_dual_left_state.sampling_number = |
| 617 | npad.sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1; | 613 | npad->sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 618 | sixaxis_dual_right_state.sampling_number = | 614 | sixaxis_dual_right_state.sampling_number = |
| 619 | npad.sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1; | 615 | npad->sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 620 | sixaxis_left_lifo_state.sampling_number = | 616 | sixaxis_left_lifo_state.sampling_number = |
| 621 | npad.sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1; | 617 | npad->sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 622 | sixaxis_right_lifo_state.sampling_number = | 618 | sixaxis_right_lifo_state.sampling_number = |
| 623 | npad.sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1; | 619 | npad->sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 624 | 620 | ||
| 625 | if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) { | 621 | if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) { |
| 626 | // This buffer only is updated on handheld on HW | 622 | // This buffer only is updated on handheld on HW |
| 627 | npad.sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state); | 623 | npad->sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state); |
| 628 | } else { | 624 | } else { |
| 629 | // Handheld doesn't update this buffer on HW | 625 | // Handheld doesn't update this buffer on HW |
| 630 | npad.sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state); | 626 | npad->sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state); |
| 631 | } | 627 | } |
| 632 | 628 | ||
| 633 | npad.sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state); | 629 | npad->sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state); |
| 634 | npad.sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state); | 630 | npad->sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state); |
| 635 | npad.sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state); | 631 | npad->sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state); |
| 636 | npad.sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state); | 632 | npad->sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state); |
| 637 | std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)), | ||
| 638 | &controller.shared_memory_entry, sizeof(NpadInternalState)); | ||
| 639 | } | 633 | } |
| 640 | } | 634 | } |
| 641 | 635 | ||
| @@ -713,8 +707,8 @@ void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceTy | |||
| 713 | } | 707 | } |
| 714 | 708 | ||
| 715 | auto& controller = GetControllerFromNpadIdType(npad_id); | 709 | auto& controller = GetControllerFromNpadIdType(npad_id); |
| 716 | if (controller.shared_memory_entry.assignment_mode != assignment_mode) { | 710 | if (controller.shared_memory->assignment_mode != assignment_mode) { |
| 717 | controller.shared_memory_entry.assignment_mode = assignment_mode; | 711 | controller.shared_memory->assignment_mode = assignment_mode; |
| 718 | } | 712 | } |
| 719 | 713 | ||
| 720 | if (!controller.device->IsConnected()) { | 714 | if (!controller.device->IsConnected()) { |
| @@ -981,32 +975,32 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { | |||
| 981 | controller.vibration[device_idx].device_mounted = false; | 975 | controller.vibration[device_idx].device_mounted = false; |
| 982 | } | 976 | } |
| 983 | 977 | ||
| 984 | auto& shared_memory_entry = controller.shared_memory_entry; | 978 | auto* shared_memory = controller.shared_memory; |
| 985 | // Don't reset shared_memory_entry.assignment_mode this value is persistent | 979 | // Don't reset shared_memory->assignment_mode this value is persistent |
| 986 | shared_memory_entry.style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out | 980 | shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out |
| 987 | shared_memory_entry.device_type.raw = 0; | 981 | shared_memory->device_type.raw = 0; |
| 988 | shared_memory_entry.system_properties.raw = 0; | 982 | shared_memory->system_properties.raw = 0; |
| 989 | shared_memory_entry.button_properties.raw = 0; | 983 | shared_memory->button_properties.raw = 0; |
| 990 | shared_memory_entry.battery_level_dual = 0; | 984 | shared_memory->battery_level_dual = 0; |
| 991 | shared_memory_entry.battery_level_left = 0; | 985 | shared_memory->battery_level_left = 0; |
| 992 | shared_memory_entry.battery_level_right = 0; | 986 | shared_memory->battery_level_right = 0; |
| 993 | shared_memory_entry.fullkey_color = { | 987 | shared_memory->fullkey_color = { |
| 994 | .attribute = ColorAttribute::NoController, | 988 | .attribute = ColorAttribute::NoController, |
| 995 | .fullkey = {}, | 989 | .fullkey = {}, |
| 996 | }; | 990 | }; |
| 997 | shared_memory_entry.joycon_color = { | 991 | shared_memory->joycon_color = { |
| 998 | .attribute = ColorAttribute::NoController, | 992 | .attribute = ColorAttribute::NoController, |
| 999 | .left = {}, | 993 | .left = {}, |
| 1000 | .right = {}, | 994 | .right = {}, |
| 1001 | }; | 995 | }; |
| 1002 | shared_memory_entry.applet_footer.type = AppletFooterUiType::None; | 996 | shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::None; |
| 1003 | 997 | ||
| 1004 | controller.is_dual_left_connected = true; | 998 | controller.is_dual_left_connected = true; |
| 1005 | controller.is_dual_right_connected = true; | 999 | controller.is_dual_right_connected = true; |
| 1006 | controller.is_connected = false; | 1000 | controller.is_connected = false; |
| 1007 | controller.device->Disconnect(); | 1001 | controller.device->Disconnect(); |
| 1008 | SignalStyleSetChangedEvent(npad_id); | 1002 | SignalStyleSetChangedEvent(npad_id); |
| 1009 | WriteEmptyEntry(controller.shared_memory_entry); | 1003 | WriteEmptyEntry(shared_memory); |
| 1010 | } | 1004 | } |
| 1011 | 1005 | ||
| 1012 | ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle, | 1006 | ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle, |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index b42532b68..0a96825a5 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -35,7 +35,7 @@ namespace Service::HID { | |||
| 35 | 35 | ||
| 36 | class Controller_NPad final : public ControllerBase { | 36 | class Controller_NPad final : public ControllerBase { |
| 37 | public: | 37 | public: |
| 38 | explicit Controller_NPad(Core::HID::HIDCore& hid_core_, | 38 | explicit Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, |
| 39 | KernelHelpers::ServiceContext& service_context_); | 39 | KernelHelpers::ServiceContext& service_context_); |
| 40 | ~Controller_NPad() override; | 40 | ~Controller_NPad() override; |
| 41 | 41 | ||
| @@ -46,11 +46,10 @@ public: | |||
| 46 | void OnRelease() override; | 46 | void OnRelease() override; |
| 47 | 47 | ||
| 48 | // When the controller is requesting an update for the shared memory | 48 | // When the controller is requesting an update for the shared memory |
| 49 | void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; | 49 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 50 | 50 | ||
| 51 | // When the controller is requesting a motion update for the shared memory | 51 | // When the controller is requesting a motion update for the shared memory |
| 52 | void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 52 | void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 53 | std::size_t size) override; | ||
| 54 | 53 | ||
| 55 | // This is nn::hid::GyroscopeZeroDriftMode | 54 | // This is nn::hid::GyroscopeZeroDriftMode |
| 56 | enum class GyroscopeZeroDriftMode : u32 { | 55 | enum class GyroscopeZeroDriftMode : u32 { |
| @@ -188,6 +187,8 @@ public: | |||
| 188 | static bool IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle); | 187 | static bool IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle); |
| 189 | 188 | ||
| 190 | private: | 189 | private: |
| 190 | static constexpr std::size_t NPAD_COUNT = 10; | ||
| 191 | |||
| 191 | // This is nn::hid::detail::ColorAttribute | 192 | // This is nn::hid::detail::ColorAttribute |
| 192 | enum class ColorAttribute : u32 { | 193 | enum class ColorAttribute : u32 { |
| 193 | Ok = 0, | 194 | Ok = 0, |
| @@ -409,6 +410,13 @@ private: | |||
| 409 | U, | 410 | U, |
| 410 | }; | 411 | }; |
| 411 | 412 | ||
| 413 | struct AppletNfcXcd { | ||
| 414 | union { | ||
| 415 | AppletFooterUi applet_footer{}; | ||
| 416 | Lifo<NfcXcdDeviceHandleStateImpl, 0x2> nfc_xcd_device_lifo; | ||
| 417 | }; | ||
| 418 | }; | ||
| 419 | |||
| 412 | // This is nn::hid::detail::NpadInternalState | 420 | // This is nn::hid::detail::NpadInternalState |
| 413 | struct NpadInternalState { | 421 | struct NpadInternalState { |
| 414 | Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None}; | 422 | Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None}; |
| @@ -435,10 +443,7 @@ private: | |||
| 435 | Core::HID::NpadBatteryLevel battery_level_dual{}; | 443 | Core::HID::NpadBatteryLevel battery_level_dual{}; |
| 436 | Core::HID::NpadBatteryLevel battery_level_left{}; | 444 | Core::HID::NpadBatteryLevel battery_level_left{}; |
| 437 | Core::HID::NpadBatteryLevel battery_level_right{}; | 445 | Core::HID::NpadBatteryLevel battery_level_right{}; |
| 438 | union { | 446 | AppletNfcXcd applet_nfc_xcd{}; |
| 439 | AppletFooterUi applet_footer{}; | ||
| 440 | Lifo<NfcXcdDeviceHandleStateImpl, 0x2> nfc_xcd_device_lifo; | ||
| 441 | }; | ||
| 442 | INSERT_PADDING_BYTES(0x20); // Unknown | 447 | INSERT_PADDING_BYTES(0x20); // Unknown |
| 443 | Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo{}; | 448 | Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo{}; |
| 444 | NpadLarkType lark_type_l_and_main{}; | 449 | NpadLarkType lark_type_l_and_main{}; |
| @@ -465,9 +470,9 @@ private: | |||
| 465 | }; | 470 | }; |
| 466 | 471 | ||
| 467 | struct NpadControllerData { | 472 | struct NpadControllerData { |
| 468 | Core::HID::EmulatedController* device; | ||
| 469 | Kernel::KEvent* styleset_changed_event{}; | 473 | Kernel::KEvent* styleset_changed_event{}; |
| 470 | NpadInternalState shared_memory_entry{}; | 474 | NpadInternalState* shared_memory = nullptr; |
| 475 | Core::HID::EmulatedController* device = nullptr; | ||
| 471 | 476 | ||
| 472 | std::array<VibrationData, 2> vibration{}; | 477 | std::array<VibrationData, 2> vibration{}; |
| 473 | bool unintended_home_button_input_protection{}; | 478 | bool unintended_home_button_input_protection{}; |
| @@ -497,15 +502,14 @@ private: | |||
| 497 | SixAxisSensorState sixaxis_dual_right_state{}; | 502 | SixAxisSensorState sixaxis_dual_right_state{}; |
| 498 | SixAxisSensorState sixaxis_left_lifo_state{}; | 503 | SixAxisSensorState sixaxis_left_lifo_state{}; |
| 499 | SixAxisSensorState sixaxis_right_lifo_state{}; | 504 | SixAxisSensorState sixaxis_right_lifo_state{}; |
| 500 | 505 | int callback_key{}; | |
| 501 | int callback_key; | ||
| 502 | }; | 506 | }; |
| 503 | 507 | ||
| 504 | void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx); | 508 | void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx); |
| 505 | void InitNewlyAddedController(Core::HID::NpadIdType npad_id); | 509 | void InitNewlyAddedController(Core::HID::NpadIdType npad_id); |
| 506 | bool IsControllerSupported(Core::HID::NpadStyleIndex controller) const; | 510 | bool IsControllerSupported(Core::HID::NpadStyleIndex controller) const; |
| 507 | void RequestPadStateUpdate(Core::HID::NpadIdType npad_id); | 511 | void RequestPadStateUpdate(Core::HID::NpadIdType npad_id); |
| 508 | void WriteEmptyEntry(NpadInternalState& npad); | 512 | void WriteEmptyEntry(NpadInternalState* npad); |
| 509 | 513 | ||
| 510 | NpadControllerData& GetControllerFromHandle( | 514 | NpadControllerData& GetControllerFromHandle( |
| 511 | const Core::HID::SixAxisSensorHandle& device_handle); | 515 | const Core::HID::SixAxisSensorHandle& device_handle); |
| @@ -520,7 +524,7 @@ private: | |||
| 520 | 524 | ||
| 521 | std::atomic<u64> press_state{}; | 525 | std::atomic<u64> press_state{}; |
| 522 | 526 | ||
| 523 | std::array<NpadControllerData, 10> controller_data{}; | 527 | std::array<NpadControllerData, NPAD_COUNT> controller_data{}; |
| 524 | KernelHelpers::ServiceContext& service_context; | 528 | KernelHelpers::ServiceContext& service_context; |
| 525 | std::mutex mutex; | 529 | std::mutex mutex; |
| 526 | std::vector<Core::HID::NpadIdType> supported_npad_id_types{}; | 530 | std::vector<Core::HID::NpadIdType> supported_npad_id_types{}; |
diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp index 4d3b9d2be..df9ee0c3f 100644 --- a/src/core/hle/service/hid/controllers/stubbed.cpp +++ b/src/core/hle/service/hid/controllers/stubbed.cpp | |||
| @@ -9,15 +9,18 @@ | |||
| 9 | 9 | ||
| 10 | namespace Service::HID { | 10 | namespace Service::HID { |
| 11 | 11 | ||
| 12 | Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {} | 12 | Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) |
| 13 | : ControllerBase{hid_core_} { | ||
| 14 | raw_shared_memory = raw_shared_memory_; | ||
| 15 | } | ||
| 16 | |||
| 13 | Controller_Stubbed::~Controller_Stubbed() = default; | 17 | Controller_Stubbed::~Controller_Stubbed() = default; |
| 14 | 18 | ||
| 15 | void Controller_Stubbed::OnInit() {} | 19 | void Controller_Stubbed::OnInit() {} |
| 16 | 20 | ||
| 17 | void Controller_Stubbed::OnRelease() {} | 21 | void Controller_Stubbed::OnRelease() {} |
| 18 | 22 | ||
| 19 | void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 23 | void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 20 | std::size_t size) { | ||
| 21 | if (!smart_update) { | 24 | if (!smart_update) { |
| 22 | return; | 25 | return; |
| 23 | } | 26 | } |
| @@ -28,7 +31,7 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u | |||
| 28 | header.entry_count = 0; | 31 | header.entry_count = 0; |
| 29 | header.last_entry_index = 0; | 32 | header.last_entry_index = 0; |
| 30 | 33 | ||
| 31 | std::memcpy(data + common_offset, &header, sizeof(CommonHeader)); | 34 | std::memcpy(raw_shared_memory + common_offset, &header, sizeof(CommonHeader)); |
| 32 | } | 35 | } |
| 33 | 36 | ||
| 34 | void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) { | 37 | void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) { |
diff --git a/src/core/hle/service/hid/controllers/stubbed.h b/src/core/hle/service/hid/controllers/stubbed.h index 512066eb3..1483a968e 100644 --- a/src/core/hle/service/hid/controllers/stubbed.h +++ b/src/core/hle/service/hid/controllers/stubbed.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | namespace Service::HID { | 9 | namespace Service::HID { |
| 10 | class Controller_Stubbed final : public ControllerBase { | 10 | class Controller_Stubbed final : public ControllerBase { |
| 11 | public: | 11 | public: |
| 12 | explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_); | 12 | explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 13 | ~Controller_Stubbed() override; | 13 | ~Controller_Stubbed() override; |
| 14 | 14 | ||
| 15 | // Called when the controller is initialized | 15 | // Called when the controller is initialized |
| @@ -19,19 +19,20 @@ public: | |||
| 19 | void OnRelease() override; | 19 | void OnRelease() override; |
| 20 | 20 | ||
| 21 | // When the controller is requesting an update for the shared memory | 21 | // When the controller is requesting an update for the shared memory |
| 22 | void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; | 22 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 23 | 23 | ||
| 24 | void SetCommonHeaderOffset(std::size_t off); | 24 | void SetCommonHeaderOffset(std::size_t off); |
| 25 | 25 | ||
| 26 | private: | 26 | private: |
| 27 | struct CommonHeader { | 27 | struct CommonHeader { |
| 28 | s64 timestamp; | 28 | s64 timestamp{}; |
| 29 | s64 total_entry_count; | 29 | s64 total_entry_count{}; |
| 30 | s64 last_entry_index; | 30 | s64 last_entry_index{}; |
| 31 | s64 entry_count; | 31 | s64 entry_count{}; |
| 32 | }; | 32 | }; |
| 33 | static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); | 33 | static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); |
| 34 | 34 | ||
| 35 | u8* raw_shared_memory = nullptr; | ||
| 35 | bool smart_update{}; | 36 | bool smart_update{}; |
| 36 | std::size_t common_offset{}; | 37 | std::size_t common_offset{}; |
| 37 | }; | 38 | }; |
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 5b4b51a69..108ce5a41 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp | |||
| @@ -15,8 +15,13 @@ | |||
| 15 | namespace Service::HID { | 15 | namespace Service::HID { |
| 16 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400; | 16 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400; |
| 17 | 17 | ||
| 18 | Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_) | 18 | Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_, |
| 19 | u8* raw_shared_memory_) | ||
| 19 | : ControllerBase{hid_core_} { | 20 | : ControllerBase{hid_core_} { |
| 21 | static_assert(SHARED_MEMORY_OFFSET + sizeof(TouchSharedMemory) < shared_memory_size, | ||
| 22 | "TouchSharedMemory is bigger than the shared memory"); | ||
| 23 | shared_memory = std::construct_at( | ||
| 24 | reinterpret_cast<TouchSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 20 | console = hid_core.GetEmulatedConsole(); | 25 | console = hid_core.GetEmulatedConsole(); |
| 21 | } | 26 | } |
| 22 | 27 | ||
| @@ -26,14 +31,12 @@ void Controller_Touchscreen::OnInit() {} | |||
| 26 | 31 | ||
| 27 | void Controller_Touchscreen::OnRelease() {} | 32 | void Controller_Touchscreen::OnRelease() {} |
| 28 | 33 | ||
| 29 | void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 34 | void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 30 | std::size_t size) { | 35 | shared_memory->touch_screen_lifo.timestamp = core_timing.GetCPUTicks(); |
| 31 | touch_screen_lifo.timestamp = core_timing.GetCPUTicks(); | ||
| 32 | 36 | ||
| 33 | if (!IsControllerActivated()) { | 37 | if (!IsControllerActivated()) { |
| 34 | touch_screen_lifo.buffer_count = 0; | 38 | shared_memory->touch_screen_lifo.buffer_count = 0; |
| 35 | touch_screen_lifo.buffer_tail = 0; | 39 | shared_memory->touch_screen_lifo.buffer_tail = 0; |
| 36 | std::memcpy(data, &touch_screen_lifo, sizeof(touch_screen_lifo)); | ||
| 37 | return; | 40 | return; |
| 38 | } | 41 | } |
| 39 | 42 | ||
| @@ -74,7 +77,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin | |||
| 74 | static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); | 77 | static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); |
| 75 | 78 | ||
| 76 | const u64 tick = core_timing.GetCPUTicks(); | 79 | const u64 tick = core_timing.GetCPUTicks(); |
| 77 | const auto& last_entry = touch_screen_lifo.ReadCurrentEntry().state; | 80 | const auto& last_entry = shared_memory->touch_screen_lifo.ReadCurrentEntry().state; |
| 78 | 81 | ||
| 79 | next_state.sampling_number = last_entry.sampling_number + 1; | 82 | next_state.sampling_number = last_entry.sampling_number + 1; |
| 80 | next_state.entry_count = static_cast<s32>(active_fingers_count); | 83 | next_state.entry_count = static_cast<s32>(active_fingers_count); |
| @@ -106,8 +109,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin | |||
| 106 | } | 109 | } |
| 107 | } | 110 | } |
| 108 | 111 | ||
| 109 | touch_screen_lifo.WriteNextEntry(next_state); | 112 | shared_memory->touch_screen_lifo.WriteNextEntry(next_state); |
| 110 | std::memcpy(data + SHARED_MEMORY_OFFSET, &touch_screen_lifo, sizeof(touch_screen_lifo)); | ||
| 111 | } | 113 | } |
| 112 | 114 | ||
| 113 | } // namespace Service::HID | 115 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index 424973b38..e57a3a80e 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h | |||
| @@ -25,14 +25,14 @@ public: | |||
| 25 | 25 | ||
| 26 | // This is nn::hid::TouchScreenConfigurationForNx | 26 | // This is nn::hid::TouchScreenConfigurationForNx |
| 27 | struct TouchScreenConfigurationForNx { | 27 | struct TouchScreenConfigurationForNx { |
| 28 | TouchScreenModeForNx mode; | 28 | TouchScreenModeForNx mode{TouchScreenModeForNx::UseSystemSetting}; |
| 29 | INSERT_PADDING_BYTES_NOINIT(0x7); | 29 | INSERT_PADDING_BYTES_NOINIT(0x7); |
| 30 | INSERT_PADDING_BYTES_NOINIT(0xF); // Reserved | 30 | INSERT_PADDING_BYTES_NOINIT(0xF); // Reserved |
| 31 | }; | 31 | }; |
| 32 | static_assert(sizeof(TouchScreenConfigurationForNx) == 0x17, | 32 | static_assert(sizeof(TouchScreenConfigurationForNx) == 0x17, |
| 33 | "TouchScreenConfigurationForNx is an invalid size"); | 33 | "TouchScreenConfigurationForNx is an invalid size"); |
| 34 | 34 | ||
| 35 | explicit Controller_Touchscreen(Core::HID::HIDCore& hid_core_); | 35 | explicit Controller_Touchscreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 36 | ~Controller_Touchscreen() override; | 36 | ~Controller_Touchscreen() override; |
| 37 | 37 | ||
| 38 | // Called when the controller is initialized | 38 | // Called when the controller is initialized |
| @@ -42,26 +42,32 @@ public: | |||
| 42 | void OnRelease() override; | 42 | void OnRelease() override; |
| 43 | 43 | ||
| 44 | // When the controller is requesting an update for the shared memory | 44 | // When the controller is requesting an update for the shared memory |
| 45 | void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; | 45 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 46 | 46 | ||
| 47 | private: | 47 | private: |
| 48 | static constexpr std::size_t MAX_FINGERS = 16; | 48 | static constexpr std::size_t MAX_FINGERS = 16; |
| 49 | 49 | ||
| 50 | // This is nn::hid::TouchScreenState | 50 | // This is nn::hid::TouchScreenState |
| 51 | struct TouchScreenState { | 51 | struct TouchScreenState { |
| 52 | s64 sampling_number; | 52 | s64 sampling_number{}; |
| 53 | s32 entry_count; | 53 | s32 entry_count{}; |
| 54 | INSERT_PADDING_BYTES(4); // Reserved | 54 | INSERT_PADDING_BYTES(4); // Reserved |
| 55 | std::array<Core::HID::TouchState, MAX_FINGERS> states; | 55 | std::array<Core::HID::TouchState, MAX_FINGERS> states{}; |
| 56 | }; | 56 | }; |
| 57 | static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size"); | 57 | static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size"); |
| 58 | 58 | ||
| 59 | // This is nn::hid::detail::TouchScreenLifo | 59 | struct TouchSharedMemory { |
| 60 | Lifo<TouchScreenState, hid_entry_count> touch_screen_lifo{}; | 60 | // This is nn::hid::detail::TouchScreenLifo |
| 61 | static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size"); | 61 | Lifo<TouchScreenState, hid_entry_count> touch_screen_lifo{}; |
| 62 | static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size"); | ||
| 63 | INSERT_PADDING_WORDS(0xF2); | ||
| 64 | }; | ||
| 65 | static_assert(sizeof(TouchSharedMemory) == 0x3000, "TouchSharedMemory is an invalid size"); | ||
| 66 | |||
| 62 | TouchScreenState next_state{}; | 67 | TouchScreenState next_state{}; |
| 68 | TouchSharedMemory* shared_memory = nullptr; | ||
| 69 | Core::HID::EmulatedConsole* console = nullptr; | ||
| 63 | 70 | ||
| 64 | std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers; | 71 | std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{}; |
| 65 | Core::HID::EmulatedConsole* console; | ||
| 66 | }; | 72 | }; |
| 67 | } // namespace Service::HID | 73 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp index fc6ac6457..62119e2c5 100644 --- a/src/core/hle/service/hid/controllers/xpad.cpp +++ b/src/core/hle/service/hid/controllers/xpad.cpp | |||
| @@ -10,28 +10,31 @@ | |||
| 10 | namespace Service::HID { | 10 | namespace Service::HID { |
| 11 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00; | 11 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00; |
| 12 | 12 | ||
| 13 | Controller_XPad::Controller_XPad(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {} | 13 | Controller_XPad::Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) |
| 14 | : ControllerBase{hid_core_} { | ||
| 15 | static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size, | ||
| 16 | "XpadSharedMemory is bigger than the shared memory"); | ||
| 17 | shared_memory = std::construct_at( | ||
| 18 | reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 19 | } | ||
| 14 | Controller_XPad::~Controller_XPad() = default; | 20 | Controller_XPad::~Controller_XPad() = default; |
| 15 | 21 | ||
| 16 | void Controller_XPad::OnInit() {} | 22 | void Controller_XPad::OnInit() {} |
| 17 | 23 | ||
| 18 | void Controller_XPad::OnRelease() {} | 24 | void Controller_XPad::OnRelease() {} |
| 19 | 25 | ||
| 20 | void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 26 | void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 21 | std::size_t size) { | ||
| 22 | if (!IsControllerActivated()) { | 27 | if (!IsControllerActivated()) { |
| 23 | basic_xpad_lifo.buffer_count = 0; | 28 | shared_memory->basic_xpad_lifo.buffer_count = 0; |
| 24 | basic_xpad_lifo.buffer_tail = 0; | 29 | shared_memory->basic_xpad_lifo.buffer_tail = 0; |
| 25 | std::memcpy(data + SHARED_MEMORY_OFFSET, &basic_xpad_lifo, sizeof(basic_xpad_lifo)); | ||
| 26 | return; | 30 | return; |
| 27 | } | 31 | } |
| 28 | 32 | ||
| 29 | const auto& last_entry = basic_xpad_lifo.ReadCurrentEntry().state; | 33 | const auto& last_entry = shared_memory->basic_xpad_lifo.ReadCurrentEntry().state; |
| 30 | next_state.sampling_number = last_entry.sampling_number + 1; | 34 | next_state.sampling_number = last_entry.sampling_number + 1; |
| 31 | // TODO(ogniK): Update xpad states | 35 | // TODO(ogniK): Update xpad states |
| 32 | 36 | ||
| 33 | basic_xpad_lifo.WriteNextEntry(next_state); | 37 | shared_memory->basic_xpad_lifo.WriteNextEntry(next_state); |
| 34 | std::memcpy(data + SHARED_MEMORY_OFFSET, &basic_xpad_lifo, sizeof(basic_xpad_lifo)); | ||
| 35 | } | 38 | } |
| 36 | 39 | ||
| 37 | } // namespace Service::HID | 40 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h index 8211b6ee3..d01dee5fc 100644 --- a/src/core/hle/service/hid/controllers/xpad.h +++ b/src/core/hle/service/hid/controllers/xpad.h | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | namespace Service::HID { | 12 | namespace Service::HID { |
| 13 | class Controller_XPad final : public ControllerBase { | 13 | class Controller_XPad final : public ControllerBase { |
| 14 | public: | 14 | public: |
| 15 | explicit Controller_XPad(Core::HID::HIDCore& hid_core_); | 15 | explicit Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 16 | ~Controller_XPad() override; | 16 | ~Controller_XPad() override; |
| 17 | 17 | ||
| 18 | // Called when the controller is initialized | 18 | // Called when the controller is initialized |
| @@ -22,7 +22,7 @@ public: | |||
| 22 | void OnRelease() override; | 22 | void OnRelease() override; |
| 23 | 23 | ||
| 24 | // When the controller is requesting an update for the shared memory | 24 | // When the controller is requesting an update for the shared memory |
| 25 | void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; | 25 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 26 | 26 | ||
| 27 | private: | 27 | private: |
| 28 | // This is nn::hid::BasicXpadAttributeSet | 28 | // This is nn::hid::BasicXpadAttributeSet |
| @@ -90,17 +90,23 @@ private: | |||
| 90 | 90 | ||
| 91 | // This is nn::hid::detail::BasicXpadState | 91 | // This is nn::hid::detail::BasicXpadState |
| 92 | struct BasicXpadState { | 92 | struct BasicXpadState { |
| 93 | s64 sampling_number; | 93 | s64 sampling_number{}; |
| 94 | BasicXpadAttributeSet attributes; | 94 | BasicXpadAttributeSet attributes{}; |
| 95 | BasicXpadButtonSet pad_states; | 95 | BasicXpadButtonSet pad_states{}; |
| 96 | Core::HID::AnalogStickState l_stick; | 96 | Core::HID::AnalogStickState l_stick{}; |
| 97 | Core::HID::AnalogStickState r_stick; | 97 | Core::HID::AnalogStickState r_stick{}; |
| 98 | }; | 98 | }; |
| 99 | static_assert(sizeof(BasicXpadState) == 0x20, "BasicXpadState is an invalid size"); | 99 | static_assert(sizeof(BasicXpadState) == 0x20, "BasicXpadState is an invalid size"); |
| 100 | 100 | ||
| 101 | // This is nn::hid::detail::BasicXpadLifo | 101 | struct XpadSharedMemory { |
| 102 | Lifo<BasicXpadState, hid_entry_count> basic_xpad_lifo{}; | 102 | // This is nn::hid::detail::BasicXpadLifo |
| 103 | static_assert(sizeof(basic_xpad_lifo) == 0x2C8, "basic_xpad_lifo is an invalid size"); | 103 | Lifo<BasicXpadState, hid_entry_count> basic_xpad_lifo{}; |
| 104 | static_assert(sizeof(basic_xpad_lifo) == 0x2C8, "basic_xpad_lifo is an invalid size"); | ||
| 105 | INSERT_PADDING_WORDS(0x4E); | ||
| 106 | }; | ||
| 107 | static_assert(sizeof(XpadSharedMemory) == 0x400, "XpadSharedMemory is an invalid size"); | ||
| 108 | |||
| 104 | BasicXpadState next_state{}; | 109 | BasicXpadState next_state{}; |
| 110 | XpadSharedMemory* shared_memory = nullptr; | ||
| 105 | }; | 111 | }; |
| 106 | } // namespace Service::HID | 112 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index fb1ec52b2..36162ac97 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -39,7 +39,6 @@ constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; | |||
| 39 | constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz) | 39 | constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz) |
| 40 | // TODO: Correct update rate for motion is 5ms. Check why some games don't behave at that speed | 40 | // TODO: Correct update rate for motion is 5ms. Check why some games don't behave at that speed |
| 41 | constexpr auto motion_update_ns = std::chrono::nanoseconds{10 * 1000 * 1000}; // (10ms, 100Hz) | 41 | constexpr auto motion_update_ns = std::chrono::nanoseconds{10 * 1000 * 1000}; // (10ms, 100Hz) |
| 42 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; | ||
| 43 | 42 | ||
| 44 | IAppletResource::IAppletResource(Core::System& system_, | 43 | IAppletResource::IAppletResource(Core::System& system_, |
| 45 | KernelHelpers::ServiceContext& service_context_) | 44 | KernelHelpers::ServiceContext& service_context_) |
| @@ -48,20 +47,20 @@ IAppletResource::IAppletResource(Core::System& system_, | |||
| 48 | {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, | 47 | {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, |
| 49 | }; | 48 | }; |
| 50 | RegisterHandlers(functions); | 49 | RegisterHandlers(functions); |
| 51 | 50 | u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer(); | |
| 52 | MakeController<Controller_DebugPad>(HidController::DebugPad); | 51 | MakeController<Controller_DebugPad>(HidController::DebugPad, shared_memory); |
| 53 | MakeController<Controller_Touchscreen>(HidController::Touchscreen); | 52 | MakeController<Controller_Touchscreen>(HidController::Touchscreen, shared_memory); |
| 54 | MakeController<Controller_Mouse>(HidController::Mouse); | 53 | MakeController<Controller_Mouse>(HidController::Mouse, shared_memory); |
| 55 | MakeController<Controller_Keyboard>(HidController::Keyboard); | 54 | MakeController<Controller_Keyboard>(HidController::Keyboard, shared_memory); |
| 56 | MakeController<Controller_XPad>(HidController::XPad); | 55 | MakeController<Controller_XPad>(HidController::XPad, shared_memory); |
| 57 | MakeController<Controller_Stubbed>(HidController::HomeButton); | 56 | MakeController<Controller_Stubbed>(HidController::HomeButton, shared_memory); |
| 58 | MakeController<Controller_Stubbed>(HidController::SleepButton); | 57 | MakeController<Controller_Stubbed>(HidController::SleepButton, shared_memory); |
| 59 | MakeController<Controller_Stubbed>(HidController::CaptureButton); | 58 | MakeController<Controller_Stubbed>(HidController::CaptureButton, shared_memory); |
| 60 | MakeController<Controller_Stubbed>(HidController::InputDetector); | 59 | MakeController<Controller_Stubbed>(HidController::InputDetector, shared_memory); |
| 61 | MakeController<Controller_Stubbed>(HidController::UniquePad); | 60 | MakeController<Controller_Stubbed>(HidController::UniquePad, shared_memory); |
| 62 | MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad); | 61 | MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad, shared_memory); |
| 63 | MakeController<Controller_Gesture>(HidController::Gesture); | 62 | MakeController<Controller_Gesture>(HidController::Gesture, shared_memory); |
| 64 | MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor); | 63 | MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor, shared_memory); |
| 65 | 64 | ||
| 66 | // Homebrew doesn't try to activate some controllers, so we activate them by default | 65 | // Homebrew doesn't try to activate some controllers, so we activate them by default |
| 67 | GetController<Controller_NPad>(HidController::NPad).ActivateController(); | 66 | GetController<Controller_NPad>(HidController::NPad).ActivateController(); |
| @@ -135,8 +134,7 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data, | |||
| 135 | if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) { | 134 | if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) { |
| 136 | continue; | 135 | continue; |
| 137 | } | 136 | } |
| 138 | controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(), | 137 | controller->OnUpdate(core_timing); |
| 139 | SHARED_MEMORY_SIZE); | ||
| 140 | } | 138 | } |
| 141 | 139 | ||
| 142 | // If ns_late is higher than the update rate ignore the delay | 140 | // If ns_late is higher than the update rate ignore the delay |
| @@ -151,10 +149,8 @@ void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data, | |||
| 151 | std::chrono::nanoseconds ns_late) { | 149 | std::chrono::nanoseconds ns_late) { |
| 152 | auto& core_timing = system.CoreTiming(); | 150 | auto& core_timing = system.CoreTiming(); |
| 153 | 151 | ||
| 154 | controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate( | 152 | controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate(core_timing); |
| 155 | core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE); | 153 | controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(core_timing); |
| 156 | controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate( | ||
| 157 | core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE); | ||
| 158 | 154 | ||
| 159 | // If ns_late is higher than the update rate ignore the delay | 155 | // If ns_late is higher than the update rate ignore the delay |
| 160 | if (ns_late > mouse_keyboard_update_ns) { | 156 | if (ns_late > mouse_keyboard_update_ns) { |
| @@ -167,8 +163,7 @@ void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data, | |||
| 167 | void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { | 163 | void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { |
| 168 | auto& core_timing = system.CoreTiming(); | 164 | auto& core_timing = system.CoreTiming(); |
| 169 | 165 | ||
| 170 | controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate( | 166 | controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate(core_timing); |
| 171 | core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE); | ||
| 172 | 167 | ||
| 173 | // If ns_late is higher than the update rate ignore the delay | 168 | // If ns_late is higher than the update rate ignore the delay |
| 174 | if (ns_late > motion_update_ns) { | 169 | if (ns_late > motion_update_ns) { |
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 95778e673..e61f8ed08 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -58,13 +58,14 @@ public: | |||
| 58 | 58 | ||
| 59 | private: | 59 | private: |
| 60 | template <typename T> | 60 | template <typename T> |
| 61 | void MakeController(HidController controller) { | 61 | void MakeController(HidController controller, u8* shared_memory) { |
| 62 | controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>(system.HIDCore()); | 62 | controllers[static_cast<std::size_t>(controller)] = |
| 63 | std::make_unique<T>(system.HIDCore(), shared_memory); | ||
| 63 | } | 64 | } |
| 64 | template <typename T> | 65 | template <typename T> |
| 65 | void MakeControllerWithServiceContext(HidController controller) { | 66 | void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) { |
| 66 | controllers[static_cast<std::size_t>(controller)] = | 67 | controllers[static_cast<std::size_t>(controller)] = |
| 67 | std::make_unique<T>(system.HIDCore(), service_context); | 68 | std::make_unique<T>(system.HIDCore(), shared_memory, service_context); |
| 68 | } | 69 | } |
| 69 | 70 | ||
| 70 | void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); | 71 | void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); |
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp index 46e5409db..d3a60cdd1 100644 --- a/src/yuzu/configuration/configure_ui.cpp +++ b/src/yuzu/configuration/configure_ui.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <QDirIterator> | 9 | #include <QDirIterator> |
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "common/fs/path_util.h" | 11 | #include "common/fs/path_util.h" |
| 12 | #include "common/logging/log.h" | ||
| 12 | #include "common/settings.h" | 13 | #include "common/settings.h" |
| 13 | #include "core/core.h" | 14 | #include "core/core.h" |
| 14 | #include "ui_configure_ui.h" | 15 | #include "ui_configure_ui.h" |
| @@ -170,14 +171,74 @@ void ConfigureUi::RetranslateUI() { | |||
| 170 | } | 171 | } |
| 171 | 172 | ||
| 172 | void ConfigureUi::InitializeLanguageComboBox() { | 173 | void ConfigureUi::InitializeLanguageComboBox() { |
| 174 | // This is a list of lexicographically sorted languages, only the available translations are | ||
| 175 | // shown to the user. | ||
| 176 | static const struct { | ||
| 177 | const QString name; | ||
| 178 | const char* id; | ||
| 179 | } languages[] = { | ||
| 180 | // clang-format off | ||
| 181 | {QStringLiteral(u"Bahasa Indonesia"), "id"}, // Indonesian | ||
| 182 | {QStringLiteral(u"Bahasa Melayu"), "ms"}, // Malay | ||
| 183 | {QStringLiteral(u"Catal\u00E0"), "ca"}, // Catalan | ||
| 184 | {QStringLiteral(u"\u010Ce\u0161tina"), "cs"}, // Czech | ||
| 185 | {QStringLiteral(u"Dansk"), "da"}, // Danish | ||
| 186 | {QStringLiteral(u"Deutsch"), "de"}, // German | ||
| 187 | {QStringLiteral(u"English"), "en"}, // English | ||
| 188 | {QStringLiteral(u"Espa\u00F1ol"), "es"}, // Spanish | ||
| 189 | {QStringLiteral(u"Fran\u00E7ais"), "fr"}, // French | ||
| 190 | {QStringLiteral(u"Hrvatski"), "hr"}, // Croatian | ||
| 191 | {QStringLiteral(u"Italiano"), "it"}, // Italian | ||
| 192 | {QStringLiteral(u"Magyar"), "hu"}, // Hungarian | ||
| 193 | {QStringLiteral(u"Nederlands"), "nl"}, // Dutch | ||
| 194 | {QStringLiteral(u"Norsk bokm\u00E5l"), "nb"}, // Norwegian | ||
| 195 | {QStringLiteral(u"Polski"), "pl"}, // Polish | ||
| 196 | {QStringLiteral(u"Portugu\u00EAs"), "pt_PT"}, // Portuguese | ||
| 197 | {QStringLiteral(u"Portugu\u00EAs (Brasil)"), "pt_BR"}, // Portuguese (Brazil) | ||
| 198 | {QStringLiteral(u"Rom\u00E2n\u0103"), "ro"}, // Romanian | ||
| 199 | {QStringLiteral(u"Srpski"), "sr"}, // Serbian | ||
| 200 | {QStringLiteral(u"Suomi"), "fi"}, // Finnish | ||
| 201 | {QStringLiteral(u"Svenska"), "sv"}, // Swedish | ||
| 202 | {QStringLiteral(u"Ti\u1EBFng Vi\u1EC7t"), "vi"}, // Vietnamese | ||
| 203 | {QStringLiteral(u"Ti\u1EBFng Vi\u1EC7t (Vi\u1EC7t Nam)"), "vi_VN"}, // Vietnamese | ||
| 204 | {QStringLiteral(u"T\u00FCrk\u00E7e"), "tr_TR"}, // Turkish | ||
| 205 | {QStringLiteral(u"\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC"), "el"}, // Greek | ||
| 206 | {QStringLiteral(u"\u0420\u0443\u0441\u0441\u043A\u0438\u0439"), "ru_RU"}, // Russian | ||
| 207 | {QStringLiteral(u"\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430"), | ||
| 208 | "uk"}, // Ukrainian | ||
| 209 | {QStringLiteral(u"\u0627\u0644\u0639\u0631\u0628\u064A\u0629"), "ar"}, // Arabic | ||
| 210 | {QStringLiteral(u"\u0641\u0627\u0631\u0633\u06CC"), "fa"}, // Farsi | ||
| 211 | {QStringLiteral(u"\uD55C\uAD6D\uC5B4"), "ko_KR"}, // Korean | ||
| 212 | {QStringLiteral(u"\u65E5\u672C\u8A9E"), "ja_JP"}, // Japanese | ||
| 213 | {QStringLiteral(u"\u7B80\u4F53\u4E2D\u6587"), "zh_CN"}, // Simplified Chinese | ||
| 214 | {QStringLiteral(u"\u7E41\u9AD4\u4E2D\u6587"), "zh_TW"}, // Traditional Chinese | ||
| 215 | // clang-format on | ||
| 216 | }; | ||
| 173 | ui->language_combobox->addItem(tr("<System>"), QString{}); | 217 | ui->language_combobox->addItem(tr("<System>"), QString{}); |
| 174 | ui->language_combobox->addItem(tr("English"), QStringLiteral("en")); | 218 | QDir languages_dir{QStringLiteral(":/languages")}; |
| 175 | QDirIterator it(QStringLiteral(":/languages"), QDirIterator::NoIteratorFlags); | 219 | QStringList language_files = languages_dir.entryList(); |
| 176 | while (it.hasNext()) { | 220 | for (const auto& lang : languages) { |
| 177 | QString locale = it.next(); | 221 | if (QString::fromLatin1(lang.id) == QStringLiteral("en")) { |
| 222 | ui->language_combobox->addItem(lang.name, QStringLiteral("en")); | ||
| 223 | continue; | ||
| 224 | } | ||
| 225 | for (int i = 0; i < language_files.size(); ++i) { | ||
| 226 | QString locale = language_files[i]; | ||
| 227 | locale.truncate(locale.lastIndexOf(QLatin1Char{'.'})); | ||
| 228 | if (QString::fromLatin1(lang.id) == locale) { | ||
| 229 | ui->language_combobox->addItem(lang.name, locale); | ||
| 230 | language_files.removeAt(i); | ||
| 231 | break; | ||
| 232 | } | ||
| 233 | } | ||
| 234 | } | ||
| 235 | // Anything remaining will be at the bottom | ||
| 236 | for (const QString& file : language_files) { | ||
| 237 | LOG_CRITICAL(Frontend, "Unexpected Language File: {}", file.toStdString()); | ||
| 238 | QString locale = file; | ||
| 178 | locale.truncate(locale.lastIndexOf(QLatin1Char{'.'})); | 239 | locale.truncate(locale.lastIndexOf(QLatin1Char{'.'})); |
| 179 | locale.remove(0, locale.lastIndexOf(QLatin1Char{'/'}) + 1); | 240 | const QString language_name = QLocale::languageToString(QLocale(locale).language()); |
| 180 | const QString lang = QLocale::languageToString(QLocale(locale).language()); | 241 | const QString lang = QStringLiteral("%1 [%2]").arg(language_name, locale); |
| 181 | ui->language_combobox->addItem(lang, locale); | 242 | ui->language_combobox->addItem(lang, locale); |
| 182 | } | 243 | } |
| 183 | 244 | ||