mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #4705 from german77/SplitMotionPoller
HID: Use different timing for motion
This commit is contained in:
		
						commit
						392c1b96bc
					
				| @ -31,6 +31,10 @@ public: | ||||
|     virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | ||||
|                           std::size_t size) = 0; | ||||
| 
 | ||||
|     // When the controller is requesting a motion update for the shared memory
 | ||||
|     virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | ||||
|                                 std::size_t size) {} | ||||
| 
 | ||||
|     // Called when input devices should be loaded
 | ||||
|     virtual void OnLoadInputDevices() = 0; | ||||
| 
 | ||||
|  | ||||
| @ -365,44 +365,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | ||||
|         } | ||||
|         const u32 npad_index = static_cast<u32>(i); | ||||
| 
 | ||||
|         const std::array<SixAxisGeneric*, 6> controller_sixaxes{ | ||||
|             &npad.sixaxis_full,       &npad.sixaxis_handheld, &npad.sixaxis_dual_left, | ||||
|             &npad.sixaxis_dual_right, &npad.sixaxis_left,     &npad.sixaxis_right, | ||||
|         }; | ||||
| 
 | ||||
|         for (auto* sixaxis_sensor : controller_sixaxes) { | ||||
|             sixaxis_sensor->common.entry_count = 16; | ||||
|             sixaxis_sensor->common.total_entry_count = 17; | ||||
| 
 | ||||
|             const auto& last_entry = | ||||
|                 sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index]; | ||||
| 
 | ||||
|             sixaxis_sensor->common.timestamp = core_timing.GetCPUTicks(); | ||||
|             sixaxis_sensor->common.last_entry_index = | ||||
|                 (sixaxis_sensor->common.last_entry_index + 1) % 17; | ||||
| 
 | ||||
|             auto& cur_entry = sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index]; | ||||
| 
 | ||||
|             cur_entry.timestamp = last_entry.timestamp + 1; | ||||
|             cur_entry.timestamp2 = cur_entry.timestamp; | ||||
|         } | ||||
| 
 | ||||
|         // Try to read sixaxis sensor states
 | ||||
|         std::array<MotionDevice, 2> motion_devices; | ||||
| 
 | ||||
|         if (sixaxis_sensors_enabled && Settings::values.motion_enabled) { | ||||
|             sixaxis_at_rest = true; | ||||
|             for (std::size_t e = 0; e < motion_devices.size(); ++e) { | ||||
|                 const auto& device = motions[i][e]; | ||||
|                 if (device) { | ||||
|                     std::tie(motion_devices[e].accel, motion_devices[e].gyro, | ||||
|                              motion_devices[e].rotation, motion_devices[e].orientation) = | ||||
|                         device->GetStatus(); | ||||
|                     sixaxis_at_rest = sixaxis_at_rest && motion_devices[e].gyro.Length2() < 0.0001f; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         RequestPadStateUpdate(npad_index); | ||||
|         auto& pad_state = npad_pad_states[npad_index]; | ||||
| 
 | ||||
| @ -446,13 +408,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | ||||
|             main_controller.pad.r_stick = pad_state.r_stick; | ||||
| 
 | ||||
|             libnx_entry.connection_status.IsWired.Assign(1); | ||||
| 
 | ||||
|             if (sixaxis_sensors_enabled && motions[i][0]) { | ||||
|                 full_sixaxis_entry.accel = motion_devices[0].accel; | ||||
|                 full_sixaxis_entry.gyro = motion_devices[0].gyro; | ||||
|                 full_sixaxis_entry.rotation = motion_devices[0].rotation; | ||||
|                 full_sixaxis_entry.orientation = motion_devices[0].orientation; | ||||
|             } | ||||
|             break; | ||||
|         case NPadControllerType::Handheld: | ||||
|             handheld_entry.connection_status.raw = 0; | ||||
| @ -471,13 +426,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | ||||
|             libnx_entry.connection_status.IsRightJoyConnected.Assign(1); | ||||
|             libnx_entry.connection_status.IsLeftJoyWired.Assign(1); | ||||
|             libnx_entry.connection_status.IsRightJoyWired.Assign(1); | ||||
| 
 | ||||
|             if (sixaxis_sensors_enabled && motions[i][0]) { | ||||
|                 handheld_sixaxis_entry.accel = motion_devices[0].accel; | ||||
|                 handheld_sixaxis_entry.gyro = motion_devices[0].gyro; | ||||
|                 handheld_sixaxis_entry.rotation = motion_devices[0].rotation; | ||||
|                 handheld_sixaxis_entry.orientation = motion_devices[0].orientation; | ||||
|             } | ||||
|             break; | ||||
|         case NPadControllerType::JoyDual: | ||||
|             dual_entry.connection_status.raw = 0; | ||||
| @ -490,21 +438,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | ||||
| 
 | ||||
|             libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); | ||||
|             libnx_entry.connection_status.IsRightJoyConnected.Assign(1); | ||||
| 
 | ||||
|             if (sixaxis_sensors_enabled && motions[i][0]) { | ||||
|                 // Set motion for the left joycon
 | ||||
|                 dual_left_sixaxis_entry.accel = motion_devices[0].accel; | ||||
|                 dual_left_sixaxis_entry.gyro = motion_devices[0].gyro; | ||||
|                 dual_left_sixaxis_entry.rotation = motion_devices[0].rotation; | ||||
|                 dual_left_sixaxis_entry.orientation = motion_devices[0].orientation; | ||||
|             } | ||||
|             if (sixaxis_sensors_enabled && motions[i][1]) { | ||||
|                 // Set motion for the right joycon
 | ||||
|                 dual_right_sixaxis_entry.accel = motion_devices[1].accel; | ||||
|                 dual_right_sixaxis_entry.gyro = motion_devices[1].gyro; | ||||
|                 dual_right_sixaxis_entry.rotation = motion_devices[1].rotation; | ||||
|                 dual_right_sixaxis_entry.orientation = motion_devices[1].orientation; | ||||
|             } | ||||
|             break; | ||||
|         case NPadControllerType::JoyLeft: | ||||
|             left_entry.connection_status.raw = 0; | ||||
| @ -515,13 +448,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | ||||
|             left_entry.pad.r_stick = pad_state.r_stick; | ||||
| 
 | ||||
|             libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); | ||||
| 
 | ||||
|             if (sixaxis_sensors_enabled && motions[i][0]) { | ||||
|                 left_sixaxis_entry.accel = motion_devices[0].accel; | ||||
|                 left_sixaxis_entry.gyro = motion_devices[0].gyro; | ||||
|                 left_sixaxis_entry.rotation = motion_devices[0].rotation; | ||||
|                 left_sixaxis_entry.orientation = motion_devices[0].orientation; | ||||
|             } | ||||
|             break; | ||||
|         case NPadControllerType::JoyRight: | ||||
|             right_entry.connection_status.raw = 0; | ||||
| @ -532,13 +458,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | ||||
|             right_entry.pad.r_stick = pad_state.r_stick; | ||||
| 
 | ||||
|             libnx_entry.connection_status.IsRightJoyConnected.Assign(1); | ||||
| 
 | ||||
|             if (sixaxis_sensors_enabled && motions[i][1]) { | ||||
|                 right_sixaxis_entry.accel = motion_devices[1].accel; | ||||
|                 right_sixaxis_entry.gyro = motion_devices[1].gyro; | ||||
|                 right_sixaxis_entry.rotation = motion_devices[1].rotation; | ||||
|                 right_sixaxis_entry.orientation = motion_devices[1].orientation; | ||||
|             } | ||||
|             break; | ||||
|         case NPadControllerType::Pokeball: | ||||
|             pokeball_entry.connection_status.raw = 0; | ||||
| @ -561,6 +480,143 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | ||||
|                 shared_memory_entries.size() * sizeof(NPadEntry)); | ||||
| } | ||||
| 
 | ||||
| void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | ||||
|                                      std::size_t data_len) { | ||||
|     if (!IsControllerActivated()) { | ||||
|         return; | ||||
|     } | ||||
|     for (std::size_t i = 0; i < shared_memory_entries.size(); i++) { | ||||
|         auto& npad = shared_memory_entries[i]; | ||||
| 
 | ||||
|         const auto& controller_type = connected_controllers[i].type; | ||||
| 
 | ||||
|         if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         const std::array<SixAxisGeneric*, 6> controller_sixaxes{ | ||||
|             &npad.sixaxis_full,       &npad.sixaxis_handheld, &npad.sixaxis_dual_left, | ||||
|             &npad.sixaxis_dual_right, &npad.sixaxis_left,     &npad.sixaxis_right, | ||||
|         }; | ||||
| 
 | ||||
|         for (auto* sixaxis_sensor : controller_sixaxes) { | ||||
|             sixaxis_sensor->common.entry_count = 16; | ||||
|             sixaxis_sensor->common.total_entry_count = 17; | ||||
| 
 | ||||
|             const auto& last_entry = | ||||
|                 sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index]; | ||||
| 
 | ||||
|             sixaxis_sensor->common.timestamp = core_timing.GetCPUTicks(); | ||||
|             sixaxis_sensor->common.last_entry_index = | ||||
|                 (sixaxis_sensor->common.last_entry_index + 1) % 17; | ||||
| 
 | ||||
|             auto& cur_entry = sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index]; | ||||
| 
 | ||||
|             cur_entry.timestamp = last_entry.timestamp + 1; | ||||
|             cur_entry.timestamp2 = cur_entry.timestamp; | ||||
|         } | ||||
| 
 | ||||
|         // Try to read sixaxis sensor states
 | ||||
|         std::array<MotionDevice, 2> motion_devices; | ||||
| 
 | ||||
|         if (sixaxis_sensors_enabled && Settings::values.motion_enabled) { | ||||
|             sixaxis_at_rest = true; | ||||
|             for (std::size_t e = 0; e < motion_devices.size(); ++e) { | ||||
|                 const auto& device = motions[i][e]; | ||||
|                 if (device) { | ||||
|                     std::tie(motion_devices[e].accel, motion_devices[e].gyro, | ||||
|                              motion_devices[e].rotation, motion_devices[e].orientation) = | ||||
|                         device->GetStatus(); | ||||
|                     sixaxis_at_rest = sixaxis_at_rest && motion_devices[e].gyro.Length2() < 0.0001f; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         auto& main_controller = | ||||
|             npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; | ||||
|         auto& handheld_entry = | ||||
|             npad.handheld_states.npad[npad.handheld_states.common.last_entry_index]; | ||||
|         auto& dual_entry = npad.dual_states.npad[npad.dual_states.common.last_entry_index]; | ||||
|         auto& left_entry = npad.left_joy_states.npad[npad.left_joy_states.common.last_entry_index]; | ||||
|         auto& right_entry = | ||||
|             npad.right_joy_states.npad[npad.right_joy_states.common.last_entry_index]; | ||||
|         auto& pokeball_entry = | ||||
|             npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index]; | ||||
|         auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; | ||||
| 
 | ||||
|         auto& full_sixaxis_entry = | ||||
|             npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index]; | ||||
|         auto& handheld_sixaxis_entry = | ||||
|             npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index]; | ||||
|         auto& dual_left_sixaxis_entry = | ||||
|             npad.sixaxis_dual_left.sixaxis[npad.sixaxis_dual_left.common.last_entry_index]; | ||||
|         auto& dual_right_sixaxis_entry = | ||||
|             npad.sixaxis_dual_right.sixaxis[npad.sixaxis_dual_right.common.last_entry_index]; | ||||
|         auto& left_sixaxis_entry = | ||||
|             npad.sixaxis_left.sixaxis[npad.sixaxis_left.common.last_entry_index]; | ||||
|         auto& right_sixaxis_entry = | ||||
|             npad.sixaxis_right.sixaxis[npad.sixaxis_right.common.last_entry_index]; | ||||
| 
 | ||||
|         switch (controller_type) { | ||||
|         case NPadControllerType::None: | ||||
|             UNREACHABLE(); | ||||
|             break; | ||||
|         case NPadControllerType::ProController: | ||||
|             if (sixaxis_sensors_enabled && motions[i][0]) { | ||||
|                 full_sixaxis_entry.accel = motion_devices[0].accel; | ||||
|                 full_sixaxis_entry.gyro = motion_devices[0].gyro; | ||||
|                 full_sixaxis_entry.rotation = motion_devices[0].rotation; | ||||
|                 full_sixaxis_entry.orientation = motion_devices[0].orientation; | ||||
|             } | ||||
|             break; | ||||
|         case NPadControllerType::Handheld: | ||||
|             if (sixaxis_sensors_enabled && motions[i][0]) { | ||||
|                 handheld_sixaxis_entry.accel = motion_devices[0].accel; | ||||
|                 handheld_sixaxis_entry.gyro = motion_devices[0].gyro; | ||||
|                 handheld_sixaxis_entry.rotation = motion_devices[0].rotation; | ||||
|                 handheld_sixaxis_entry.orientation = motion_devices[0].orientation; | ||||
|             } | ||||
|             break; | ||||
|         case NPadControllerType::JoyDual: | ||||
|             if (sixaxis_sensors_enabled && motions[i][0]) { | ||||
|                 // Set motion for the left joycon
 | ||||
|                 dual_left_sixaxis_entry.accel = motion_devices[0].accel; | ||||
|                 dual_left_sixaxis_entry.gyro = motion_devices[0].gyro; | ||||
|                 dual_left_sixaxis_entry.rotation = motion_devices[0].rotation; | ||||
|                 dual_left_sixaxis_entry.orientation = motion_devices[0].orientation; | ||||
|             } | ||||
|             if (sixaxis_sensors_enabled && motions[i][1]) { | ||||
|                 // Set motion for the right joycon
 | ||||
|                 dual_right_sixaxis_entry.accel = motion_devices[1].accel; | ||||
|                 dual_right_sixaxis_entry.gyro = motion_devices[1].gyro; | ||||
|                 dual_right_sixaxis_entry.rotation = motion_devices[1].rotation; | ||||
|                 dual_right_sixaxis_entry.orientation = motion_devices[1].orientation; | ||||
|             } | ||||
|             break; | ||||
|         case NPadControllerType::JoyLeft: | ||||
|             if (sixaxis_sensors_enabled && motions[i][0]) { | ||||
|                 left_sixaxis_entry.accel = motion_devices[0].accel; | ||||
|                 left_sixaxis_entry.gyro = motion_devices[0].gyro; | ||||
|                 left_sixaxis_entry.rotation = motion_devices[0].rotation; | ||||
|                 left_sixaxis_entry.orientation = motion_devices[0].orientation; | ||||
|             } | ||||
|             break; | ||||
|         case NPadControllerType::JoyRight: | ||||
|             if (sixaxis_sensors_enabled && motions[i][1]) { | ||||
|                 right_sixaxis_entry.accel = motion_devices[1].accel; | ||||
|                 right_sixaxis_entry.gyro = motion_devices[1].gyro; | ||||
|                 right_sixaxis_entry.rotation = motion_devices[1].rotation; | ||||
|                 right_sixaxis_entry.orientation = motion_devices[1].orientation; | ||||
|             } | ||||
|             break; | ||||
|         case NPadControllerType::Pokeball: | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), | ||||
|                 shared_memory_entries.size() * sizeof(NPadEntry)); | ||||
| } | ||||
| 
 | ||||
| void Controller_NPad::SetSupportedStyleSet(NPadType style_set) { | ||||
|     style.raw = style_set.raw; | ||||
| } | ||||
|  | ||||
| @ -32,6 +32,10 @@ public: | ||||
|     // When the controller is requesting an update for the shared memory
 | ||||
|     void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; | ||||
| 
 | ||||
|     // When the controller is requesting a motion update for the shared memory
 | ||||
|     void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | ||||
|                         std::size_t size) override; | ||||
| 
 | ||||
|     // Called when input devices should be loaded
 | ||||
|     void OnLoadInputDevices() override; | ||||
| 
 | ||||
|  | ||||
| @ -40,7 +40,8 @@ namespace Service::HID { | ||||
| // Updating period for each HID device.
 | ||||
| // HID is polled every 15ms, this value was derived from
 | ||||
| // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering#joy-con-status-data-packet
 | ||||
| constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz)
 | ||||
| constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000};         // (1ms, 1000Hz)
 | ||||
| constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz)
 | ||||
| constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; | ||||
| 
 | ||||
| IAppletResource::IAppletResource(Core::System& system) | ||||
| @ -79,10 +80,14 @@ IAppletResource::IAppletResource(Core::System& system) | ||||
|         [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { | ||||
|             UpdateControllers(user_data, ns_late); | ||||
|         }); | ||||
| 
 | ||||
|     // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
 | ||||
|     motion_update_event = Core::Timing::CreateEvent( | ||||
|         "HID::MotionPadCallback", | ||||
|         [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { | ||||
|             UpdateMotion(user_data, ns_late); | ||||
|         }); | ||||
| 
 | ||||
|     system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event); | ||||
|     system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event); | ||||
| 
 | ||||
|     ReloadInputDevices(); | ||||
| } | ||||
| @ -122,6 +127,16 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data, | ||||
|     core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event); | ||||
| } | ||||
| 
 | ||||
| void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { | ||||
|     auto& core_timing = system.CoreTiming(); | ||||
| 
 | ||||
|     for (const auto& controller : controllers) { | ||||
|         controller->OnMotionUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); | ||||
|     } | ||||
| 
 | ||||
|     core_timing.ScheduleEvent(motion_update_ns - ns_late, motion_update_event); | ||||
| } | ||||
| 
 | ||||
| class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { | ||||
| public: | ||||
|     IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") { | ||||
|  | ||||
| @ -65,10 +65,12 @@ private: | ||||
| 
 | ||||
|     void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); | ||||
|     void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||||
|     void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||||
| 
 | ||||
|     std::shared_ptr<Kernel::SharedMemory> shared_mem; | ||||
| 
 | ||||
|     std::shared_ptr<Core::Timing::EventType> pad_update_event; | ||||
|     std::shared_ptr<Core::Timing::EventType> motion_update_event; | ||||
|     Core::System& system; | ||||
| 
 | ||||
|     std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei