summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/hid/hid.cpp67
-rw-r--r--src/core/hle/service/hid/hid.h27
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 @@
34namespace Service::HID { 35namespace 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 39constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz)
39constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz) 40constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
40constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz)
41constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; 41constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
42 42
43IAppletResource::IAppletResource(Core::System& system_, 43IAppletResource::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
95void IAppletResource::ActivateController(HidController controller) { 95void 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) {
891void Hid::SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { 887void 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
2040void ReloadInputDevices() {
2041}
2042
2043void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 2036void 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
194void ReloadInputDevices();
195
196/// Registers all HID services with the specified service manager. 169/// Registers all HID services with the specified service manager.
197void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); 170void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
198 171