diff options
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 67 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.h | 27 |
2 files changed, 30 insertions, 64 deletions
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 9a5b60263..18f29bb78 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/core_timing.h" | 10 | #include "core/core_timing.h" |
| 11 | #include "core/frontend/input.h" | 11 | #include "core/frontend/input.h" |
| 12 | #include "core/hardware_properties.h" | ||
| 12 | #include "core/hle/ipc_helpers.h" | 13 | #include "core/hle/ipc_helpers.h" |
| 13 | #include "core/hle/kernel/k_readable_event.h" | 14 | #include "core/hle/kernel/k_readable_event.h" |
| 14 | #include "core/hle/kernel/k_shared_memory.h" | 15 | #include "core/hle/kernel/k_shared_memory.h" |
| @@ -34,10 +35,9 @@ | |||
| 34 | namespace Service::HID { | 35 | namespace Service::HID { |
| 35 | 36 | ||
| 36 | // Updating period for each HID device. | 37 | // Updating period for each HID device. |
| 37 | // HID is polled every 15ms, this value was derived from | 38 | // Period time is obtained by measuring the number of samples in a second |
| 38 | // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering#joy-con-status-data-packet | 39 | constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz) |
| 39 | constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz) | 40 | constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) |
| 40 | constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz) | ||
| 41 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; | 41 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; |
| 42 | 42 | ||
| 43 | IAppletResource::IAppletResource(Core::System& system_, | 43 | IAppletResource::IAppletResource(Core::System& system_, |
| @@ -89,7 +89,7 @@ IAppletResource::IAppletResource(Core::System& system_, | |||
| 89 | system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event); | 89 | system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event); |
| 90 | system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event); | 90 | system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event); |
| 91 | 91 | ||
| 92 | ReloadInputDevices(); | 92 | system.HIDCore().ReloadInputDevices(); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | void IAppletResource::ActivateController(HidController controller) { | 95 | void IAppletResource::ActivateController(HidController controller) { |
| @@ -117,11 +117,7 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data, | |||
| 117 | std::chrono::nanoseconds ns_late) { | 117 | std::chrono::nanoseconds ns_late) { |
| 118 | auto& core_timing = system.CoreTiming(); | 118 | auto& core_timing = system.CoreTiming(); |
| 119 | 119 | ||
| 120 | const bool should_reload = false; | ||
| 121 | for (const auto& controller : controllers) { | 120 | for (const auto& controller : controllers) { |
| 122 | if (should_reload) { | ||
| 123 | controller->OnLoadInputDevices(); | ||
| 124 | } | ||
| 125 | controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(), | 121 | controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(), |
| 126 | SHARED_MEMORY_SIZE); | 122 | SHARED_MEMORY_SIZE); |
| 127 | } | 123 | } |
| @@ -891,7 +887,7 @@ void Hid::ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) { | |||
| 891 | void Hid::SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { | 887 | void Hid::SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { |
| 892 | IPC::RequestParser rp{ctx}; | 888 | IPC::RequestParser rp{ctx}; |
| 893 | const auto applet_resource_user_id{rp.Pop<u64>()}; | 889 | const auto applet_resource_user_id{rp.Pop<u64>()}; |
| 894 | const auto hold_type{rp.PopEnum<Controller_NPad::NpadHoldType>()}; | 890 | const auto hold_type{rp.PopEnum<Controller_NPad::NpadJoyHoldType>()}; |
| 895 | 891 | ||
| 896 | applet_resource->GetController<Controller_NPad>(HidController::NPad).SetHoldType(hold_type); | 892 | applet_resource->GetController<Controller_NPad>(HidController::NPad).SetHoldType(hold_type); |
| 897 | 893 | ||
| @@ -924,7 +920,7 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx | |||
| 924 | const auto parameters{rp.PopRaw<Parameters>()}; | 920 | const auto parameters{rp.PopRaw<Parameters>()}; |
| 925 | 921 | ||
| 926 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | 922 | applet_resource->GetController<Controller_NPad>(HidController::NPad) |
| 927 | .SetNpadMode(parameters.npad_id, Controller_NPad::NpadAssignments::Single); | 923 | .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyAssignmentMode::Single); |
| 928 | 924 | ||
| 929 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", | 925 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", |
| 930 | parameters.npad_id, parameters.applet_resource_user_id); | 926 | parameters.npad_id, parameters.applet_resource_user_id); |
| @@ -946,7 +942,7 @@ void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) { | |||
| 946 | const auto parameters{rp.PopRaw<Parameters>()}; | 942 | const auto parameters{rp.PopRaw<Parameters>()}; |
| 947 | 943 | ||
| 948 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | 944 | applet_resource->GetController<Controller_NPad>(HidController::NPad) |
| 949 | .SetNpadMode(parameters.npad_id, Controller_NPad::NpadAssignments::Single); | 945 | .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyAssignmentMode::Single); |
| 950 | 946 | ||
| 951 | LOG_WARNING(Service_HID, | 947 | LOG_WARNING(Service_HID, |
| 952 | "(STUBBED) called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | 948 | "(STUBBED) called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", |
| @@ -968,7 +964,7 @@ void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { | |||
| 968 | const auto parameters{rp.PopRaw<Parameters>()}; | 964 | const auto parameters{rp.PopRaw<Parameters>()}; |
| 969 | 965 | ||
| 970 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | 966 | applet_resource->GetController<Controller_NPad>(HidController::NPad) |
| 971 | .SetNpadMode(parameters.npad_id, Controller_NPad::NpadAssignments::Dual); | 967 | .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyAssignmentMode::Dual); |
| 972 | 968 | ||
| 973 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", | 969 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", |
| 974 | parameters.npad_id, parameters.applet_resource_user_id); | 970 | parameters.npad_id, parameters.applet_resource_user_id); |
| @@ -1134,36 +1130,36 @@ void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { | |||
| 1134 | IPC::RequestParser rp{ctx}; | 1130 | IPC::RequestParser rp{ctx}; |
| 1135 | const auto vibration_device_handle{rp.PopRaw<Controller_NPad::DeviceHandle>()}; | 1131 | const auto vibration_device_handle{rp.PopRaw<Controller_NPad::DeviceHandle>()}; |
| 1136 | 1132 | ||
| 1137 | VibrationDeviceInfo vibration_device_info; | 1133 | Core::HID::VibrationDeviceInfo vibration_device_info; |
| 1138 | 1134 | ||
| 1139 | switch (vibration_device_handle.npad_type) { | 1135 | switch (vibration_device_handle.npad_type) { |
| 1140 | case Controller_NPad::NpadType::ProController: | 1136 | case Core::HID::NpadType::ProController: |
| 1141 | case Controller_NPad::NpadType::Handheld: | 1137 | case Core::HID::NpadType::Handheld: |
| 1142 | case Controller_NPad::NpadType::JoyconDual: | 1138 | case Core::HID::NpadType::JoyconDual: |
| 1143 | case Controller_NPad::NpadType::JoyconLeft: | 1139 | case Core::HID::NpadType::JoyconLeft: |
| 1144 | case Controller_NPad::NpadType::JoyconRight: | 1140 | case Core::HID::NpadType::JoyconRight: |
| 1145 | default: | 1141 | default: |
| 1146 | vibration_device_info.type = VibrationDeviceType::LinearResonantActuator; | 1142 | vibration_device_info.type = Core::HID::VibrationDeviceType::LinearResonantActuator; |
| 1147 | break; | 1143 | break; |
| 1148 | case Controller_NPad::NpadType::GameCube: | 1144 | case Core::HID::NpadType::GameCube: |
| 1149 | vibration_device_info.type = VibrationDeviceType::GcErm; | 1145 | vibration_device_info.type = Core::HID::VibrationDeviceType::GcErm; |
| 1150 | break; | 1146 | break; |
| 1151 | case Controller_NPad::NpadType::Pokeball: | 1147 | case Core::HID::NpadType::Pokeball: |
| 1152 | vibration_device_info.type = VibrationDeviceType::Unknown; | 1148 | vibration_device_info.type = Core::HID::VibrationDeviceType::Unknown; |
| 1153 | break; | 1149 | break; |
| 1154 | } | 1150 | } |
| 1155 | 1151 | ||
| 1156 | switch (vibration_device_handle.device_index) { | 1152 | switch (vibration_device_handle.device_index) { |
| 1157 | case Controller_NPad::DeviceIndex::Left: | 1153 | case Controller_NPad::DeviceIndex::Left: |
| 1158 | vibration_device_info.position = VibrationDevicePosition::Left; | 1154 | vibration_device_info.position = Core::HID::VibrationDevicePosition::Left; |
| 1159 | break; | 1155 | break; |
| 1160 | case Controller_NPad::DeviceIndex::Right: | 1156 | case Controller_NPad::DeviceIndex::Right: |
| 1161 | vibration_device_info.position = VibrationDevicePosition::Right; | 1157 | vibration_device_info.position = Core::HID::VibrationDevicePosition::Right; |
| 1162 | break; | 1158 | break; |
| 1163 | case Controller_NPad::DeviceIndex::None: | 1159 | case Controller_NPad::DeviceIndex::None: |
| 1164 | default: | 1160 | default: |
| 1165 | UNREACHABLE_MSG("DeviceIndex should never be None!"); | 1161 | UNREACHABLE_MSG("DeviceIndex should never be None!"); |
| 1166 | vibration_device_info.position = VibrationDevicePosition::None; | 1162 | vibration_device_info.position = Core::HID::VibrationDevicePosition::None; |
| 1167 | break; | 1163 | break; |
| 1168 | } | 1164 | } |
| 1169 | 1165 | ||
| @@ -1278,7 +1274,7 @@ void Hid::SendVibrationGcErmCommand(Kernel::HLERequestContext& ctx) { | |||
| 1278 | struct Parameters { | 1274 | struct Parameters { |
| 1279 | Controller_NPad::DeviceHandle vibration_device_handle; | 1275 | Controller_NPad::DeviceHandle vibration_device_handle; |
| 1280 | u64 applet_resource_user_id; | 1276 | u64 applet_resource_user_id; |
| 1281 | VibrationGcErmCommand gc_erm_command; | 1277 | Core::HID::VibrationGcErmCommand gc_erm_command; |
| 1282 | }; | 1278 | }; |
| 1283 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | 1279 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); |
| 1284 | 1280 | ||
| @@ -1292,21 +1288,21 @@ void Hid::SendVibrationGcErmCommand(Kernel::HLERequestContext& ctx) { | |||
| 1292 | */ | 1288 | */ |
| 1293 | const auto vibration_value = [parameters] { | 1289 | const auto vibration_value = [parameters] { |
| 1294 | switch (parameters.gc_erm_command) { | 1290 | switch (parameters.gc_erm_command) { |
| 1295 | case VibrationGcErmCommand::Stop: | 1291 | case Core::HID::VibrationGcErmCommand::Stop: |
| 1296 | return Controller_NPad::VibrationValue{ | 1292 | return Controller_NPad::VibrationValue{ |
| 1297 | .amp_low = 0.0f, | 1293 | .amp_low = 0.0f, |
| 1298 | .freq_low = 160.0f, | 1294 | .freq_low = 160.0f, |
| 1299 | .amp_high = 0.0f, | 1295 | .amp_high = 0.0f, |
| 1300 | .freq_high = 320.0f, | 1296 | .freq_high = 320.0f, |
| 1301 | }; | 1297 | }; |
| 1302 | case VibrationGcErmCommand::Start: | 1298 | case Core::HID::VibrationGcErmCommand::Start: |
| 1303 | return Controller_NPad::VibrationValue{ | 1299 | return Controller_NPad::VibrationValue{ |
| 1304 | .amp_low = 1.0f, | 1300 | .amp_low = 1.0f, |
| 1305 | .freq_low = 160.0f, | 1301 | .freq_low = 160.0f, |
| 1306 | .amp_high = 1.0f, | 1302 | .amp_high = 1.0f, |
| 1307 | .freq_high = 320.0f, | 1303 | .freq_high = 320.0f, |
| 1308 | }; | 1304 | }; |
| 1309 | case VibrationGcErmCommand::StopHard: | 1305 | case Core::HID::VibrationGcErmCommand::StopHard: |
| 1310 | return Controller_NPad::VibrationValue{ | 1306 | return Controller_NPad::VibrationValue{ |
| 1311 | .amp_low = 0.0f, | 1307 | .amp_low = 0.0f, |
| 1312 | .freq_low = 0.0f, | 1308 | .freq_low = 0.0f, |
| @@ -1348,7 +1344,7 @@ void Hid::GetActualVibrationGcErmCommand(Kernel::HLERequestContext& ctx) { | |||
| 1348 | 1344 | ||
| 1349 | const auto gc_erm_command = [last_vibration] { | 1345 | const auto gc_erm_command = [last_vibration] { |
| 1350 | if (last_vibration.amp_low != 0.0f || last_vibration.amp_high != 0.0f) { | 1346 | if (last_vibration.amp_low != 0.0f || last_vibration.amp_high != 0.0f) { |
| 1351 | return VibrationGcErmCommand::Start; | 1347 | return Core::HID::VibrationGcErmCommand::Start; |
| 1352 | } | 1348 | } |
| 1353 | 1349 | ||
| 1354 | /** | 1350 | /** |
| @@ -1358,10 +1354,10 @@ void Hid::GetActualVibrationGcErmCommand(Kernel::HLERequestContext& ctx) { | |||
| 1358 | * This is done to reuse the controller vibration functions made for regular controllers. | 1354 | * This is done to reuse the controller vibration functions made for regular controllers. |
| 1359 | */ | 1355 | */ |
| 1360 | if (last_vibration.freq_low == 0.0f && last_vibration.freq_high == 0.0f) { | 1356 | if (last_vibration.freq_low == 0.0f && last_vibration.freq_high == 0.0f) { |
| 1361 | return VibrationGcErmCommand::StopHard; | 1357 | return Core::HID::VibrationGcErmCommand::StopHard; |
| 1362 | } | 1358 | } |
| 1363 | 1359 | ||
| 1364 | return VibrationGcErmCommand::Stop; | 1360 | return Core::HID::VibrationGcErmCommand::Stop; |
| 1365 | }(); | 1361 | }(); |
| 1366 | 1362 | ||
| 1367 | LOG_DEBUG(Service_HID, | 1363 | LOG_DEBUG(Service_HID, |
| @@ -2037,9 +2033,6 @@ public: | |||
| 2037 | } | 2033 | } |
| 2038 | }; | 2034 | }; |
| 2039 | 2035 | ||
| 2040 | void ReloadInputDevices() { | ||
| 2041 | } | ||
| 2042 | |||
| 2043 | void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { | 2036 | void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { |
| 2044 | std::make_shared<Hid>(system)->InstallAsService(service_manager); | 2037 | std::make_shared<Hid>(system)->InstallAsService(service_manager); |
| 2045 | std::make_shared<HidBus>(system)->InstallAsService(service_manager); | 2038 | std::make_shared<HidBus>(system)->InstallAsService(service_manager); |
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index b1fe75e94..2e0c33c1c 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -161,38 +161,11 @@ private: | |||
| 161 | void GetNpadCommunicationMode(Kernel::HLERequestContext& ctx); | 161 | void GetNpadCommunicationMode(Kernel::HLERequestContext& ctx); |
| 162 | void SetTouchScreenConfiguration(Kernel::HLERequestContext& ctx); | 162 | void SetTouchScreenConfiguration(Kernel::HLERequestContext& ctx); |
| 163 | 163 | ||
| 164 | enum class VibrationDeviceType : u32 { | ||
| 165 | Unknown = 0, | ||
| 166 | LinearResonantActuator = 1, | ||
| 167 | GcErm = 2, | ||
| 168 | }; | ||
| 169 | |||
| 170 | enum class VibrationDevicePosition : u32 { | ||
| 171 | None = 0, | ||
| 172 | Left = 1, | ||
| 173 | Right = 2, | ||
| 174 | }; | ||
| 175 | |||
| 176 | enum class VibrationGcErmCommand : u64 { | ||
| 177 | Stop = 0, | ||
| 178 | Start = 1, | ||
| 179 | StopHard = 2, | ||
| 180 | }; | ||
| 181 | |||
| 182 | struct VibrationDeviceInfo { | ||
| 183 | VibrationDeviceType type{}; | ||
| 184 | VibrationDevicePosition position{}; | ||
| 185 | }; | ||
| 186 | static_assert(sizeof(VibrationDeviceInfo) == 0x8, "VibrationDeviceInfo has incorrect size."); | ||
| 187 | |||
| 188 | std::shared_ptr<IAppletResource> applet_resource; | 164 | std::shared_ptr<IAppletResource> applet_resource; |
| 189 | 165 | ||
| 190 | KernelHelpers::ServiceContext service_context; | 166 | KernelHelpers::ServiceContext service_context; |
| 191 | }; | 167 | }; |
| 192 | 168 | ||
| 193 | /// Reload input devices. Used when input configuration changed | ||
| 194 | void ReloadInputDevices(); | ||
| 195 | |||
| 196 | /// Registers all HID services with the specified service manager. | 169 | /// Registers all HID services with the specified service manager. |
| 197 | void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); | 170 | void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); |
| 198 | 171 | ||