summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Narr the Reg2022-04-13 12:52:29 -0500
committerGravatar german772022-04-18 15:02:47 -0500
commit1d26fabaa763560902413ac4ef024e69fe30c45a (patch)
treeaa9ffd9715dd9f6e8a15565f7ad0b1f6fb2b920c /src
parentMerge pull request #8204 from Docteh/translate_gameslist (diff)
downloadyuzu-1d26fabaa763560902413ac4ef024e69fe30c45a.tar.gz
yuzu-1d26fabaa763560902413ac4ef024e69fe30c45a.tar.xz
yuzu-1d26fabaa763560902413ac4ef024e69fe30c45a.zip
service: hid: Improve accuracy of sixaxis functions
Diffstat (limited to 'src')
-rw-r--r--src/core/hid/hid_types.h5
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp273
-rw-r--r--src/core/hle/service/hid/controllers/npad.h50
-rw-r--r--src/core/hle/service/hid/errors.h4
-rw-r--r--src/core/hle/service/hid/hid.cpp129
-rw-r--r--src/core/hle/service/hid/hid.h1
6 files changed, 363 insertions, 99 deletions
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index 778b328b9..422a9af33 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -491,9 +491,10 @@ struct SixAxisSensorHandle {
491}; 491};
492static_assert(sizeof(SixAxisSensorHandle) == 4, "SixAxisSensorHandle is an invalid size"); 492static_assert(sizeof(SixAxisSensorHandle) == 4, "SixAxisSensorHandle is an invalid size");
493 493
494// These parameters seem related to how much gyro/accelerometer is used
494struct SixAxisSensorFusionParameters { 495struct SixAxisSensorFusionParameters {
495 f32 parameter1; 496 f32 parameter1{0.03f}; // Range 0.0 to 1.0, default 0.03
496 f32 parameter2; 497 f32 parameter2{0.4f}; // Default 0.4
497}; 498};
498static_assert(sizeof(SixAxisSensorFusionParameters) == 8, 499static_assert(sizeof(SixAxisSensorFusionParameters) == 8,
499 "SixAxisSensorFusionParameters is an invalid size"); 500 "SixAxisSensorFusionParameters is an invalid size");
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 4e17a952e..68407e39a 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -17,6 +17,7 @@
17#include "core/hle/kernel/k_readable_event.h" 17#include "core/hle/kernel/k_readable_event.h"
18#include "core/hle/kernel/k_writable_event.h" 18#include "core/hle/kernel/k_writable_event.h"
19#include "core/hle/service/hid/controllers/npad.h" 19#include "core/hle/service/hid/controllers/npad.h"
20#include "core/hle/service/hid/errors.h"
20#include "core/hle/service/kernel_helpers.h" 21#include "core/hle/service/kernel_helpers.h"
21 22
22namespace Service::HID { 23namespace Service::HID {
@@ -48,15 +49,17 @@ bool Controller_NPad::IsNpadIdValid(Core::HID::NpadIdType npad_id) {
48} 49}
49 50
50bool Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle) { 51bool Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle) {
51 return IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id)) && 52 const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
52 device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType && 53 const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
53 device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex; 54 const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
55 return npad_id && npad_type && device_index;
54} 56}
55 57
56bool Controller_NPad::IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle& device_handle) { 58bool Controller_NPad::IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle& device_handle) {
57 return IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id)) && 59 const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
58 device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType && 60 const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
59 device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex; 61 const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
62 return npad_id && npad_type && device_index;
60} 63}
61 64
62Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, 65Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_,
@@ -1007,87 +1010,271 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
1007 WriteEmptyEntry(controller.shared_memory_entry); 1010 WriteEmptyEntry(controller.shared_memory_entry);
1008} 1011}
1009 1012
1010void Controller_NPad::SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle, 1013ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
1011 GyroscopeZeroDriftMode drift_mode) { 1014 GyroscopeZeroDriftMode drift_mode) {
1012 if (!IsDeviceHandleValid(sixaxis_handle)) { 1015 if (!IsDeviceHandleValid(sixaxis_handle)) {
1013 LOG_ERROR(Service_HID, "Invalid handle"); 1016 LOG_ERROR(Service_HID, "Invalid handle");
1014 return; 1017 return NpadInvalidHandle;
1015 } 1018 }
1019
1016 auto& controller = GetControllerFromHandle(sixaxis_handle); 1020 auto& controller = GetControllerFromHandle(sixaxis_handle);
1017 controller.gyroscope_zero_drift_mode = drift_mode; 1021 switch (sixaxis_handle.npad_type) {
1022 case Core::HID::NpadStyleIndex::ProController:
1023 controller.sixaxis_fullkey.gyroscope_zero_drift_mode = drift_mode;
1024 break;
1025 case Core::HID::NpadStyleIndex::Handheld:
1026 controller.sixaxis_handheld.gyroscope_zero_drift_mode = drift_mode;
1027 break;
1028 case Core::HID::NpadStyleIndex::JoyconDual:
1029 case Core::HID::NpadStyleIndex::GameCube:
1030 case Core::HID::NpadStyleIndex::Pokeball:
1031 if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
1032 controller.sixaxis_dual_left.gyroscope_zero_drift_mode = drift_mode;
1033 break;
1034 }
1035 controller.sixaxis_dual_right.gyroscope_zero_drift_mode = drift_mode;
1036 break;
1037 case Core::HID::NpadStyleIndex::JoyconLeft:
1038 controller.sixaxis_left.gyroscope_zero_drift_mode = drift_mode;
1039 break;
1040 case Core::HID::NpadStyleIndex::JoyconRight:
1041 controller.sixaxis_right.gyroscope_zero_drift_mode = drift_mode;
1042 break;
1043 default:
1044 LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type);
1045 return NpadInvalidHandle;
1046 }
1047
1048 return ResultSuccess;
1018} 1049}
1019 1050
1020Controller_NPad::GyroscopeZeroDriftMode Controller_NPad::GetGyroscopeZeroDriftMode( 1051ResultCode Controller_NPad::GetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
1021 Core::HID::SixAxisSensorHandle sixaxis_handle) const { 1052 GyroscopeZeroDriftMode& drift_mode) const {
1022 if (!IsDeviceHandleValid(sixaxis_handle)) { 1053 if (!IsDeviceHandleValid(sixaxis_handle)) {
1023 LOG_ERROR(Service_HID, "Invalid handle"); 1054 LOG_ERROR(Service_HID, "Invalid handle");
1024 // Return the default value 1055 return NpadInvalidHandle;
1025 return GyroscopeZeroDriftMode::Standard;
1026 } 1056 }
1027 const auto& controller = GetControllerFromHandle(sixaxis_handle); 1057
1028 return controller.gyroscope_zero_drift_mode; 1058 auto& controller = GetControllerFromHandle(sixaxis_handle);
1059 switch (sixaxis_handle.npad_type) {
1060 case Core::HID::NpadStyleIndex::ProController:
1061 drift_mode = controller.sixaxis_fullkey.gyroscope_zero_drift_mode;
1062 break;
1063 case Core::HID::NpadStyleIndex::Handheld:
1064 drift_mode = controller.sixaxis_handheld.gyroscope_zero_drift_mode;
1065 break;
1066 case Core::HID::NpadStyleIndex::JoyconDual:
1067 case Core::HID::NpadStyleIndex::GameCube:
1068 case Core::HID::NpadStyleIndex::Pokeball:
1069 if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
1070 drift_mode = controller.sixaxis_dual_left.gyroscope_zero_drift_mode;
1071 break;
1072 }
1073 drift_mode = controller.sixaxis_dual_right.gyroscope_zero_drift_mode;
1074 break;
1075 case Core::HID::NpadStyleIndex::JoyconLeft:
1076 drift_mode = controller.sixaxis_left.gyroscope_zero_drift_mode;
1077 break;
1078 case Core::HID::NpadStyleIndex::JoyconRight:
1079 drift_mode = controller.sixaxis_right.gyroscope_zero_drift_mode;
1080 break;
1081 default:
1082 LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type);
1083 return NpadInvalidHandle;
1084 }
1085
1086 return ResultSuccess;
1029} 1087}
1030 1088
1031bool Controller_NPad::IsSixAxisSensorAtRest(Core::HID::SixAxisSensorHandle sixaxis_handle) const { 1089ResultCode Controller_NPad::IsSixAxisSensorAtRest(Core::HID::SixAxisSensorHandle sixaxis_handle,
1090 bool& is_at_rest) const {
1032 if (!IsDeviceHandleValid(sixaxis_handle)) { 1091 if (!IsDeviceHandleValid(sixaxis_handle)) {
1033 LOG_ERROR(Service_HID, "Invalid handle"); 1092 LOG_ERROR(Service_HID, "Invalid handle");
1034 // Return the default value 1093 return NpadInvalidHandle;
1035 return true;
1036 } 1094 }
1037 const auto& controller = GetControllerFromHandle(sixaxis_handle); 1095 const auto& controller = GetControllerFromHandle(sixaxis_handle);
1038 return controller.sixaxis_at_rest; 1096 is_at_rest = controller.sixaxis_at_rest;
1097 return ResultSuccess;
1039} 1098}
1040 1099
1041void Controller_NPad::SetSixAxisEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle, 1100ResultCode Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
1042 bool sixaxis_status) { 1101 Core::HID::SixAxisSensorHandle sixaxis_handle, bool& is_firmware_available) const {
1043 if (!IsDeviceHandleValid(sixaxis_handle)) { 1102 if (!IsDeviceHandleValid(sixaxis_handle)) {
1044 LOG_ERROR(Service_HID, "Invalid handle"); 1103 LOG_ERROR(Service_HID, "Invalid handle");
1045 return; 1104 return NpadInvalidHandle;
1105 }
1106
1107 // We don't support joycon firmware updates
1108 is_firmware_available = false;
1109 return ResultSuccess;
1110}
1111
1112ResultCode Controller_NPad::SetSixAxisEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
1113 bool sixaxis_status) {
1114 if (!IsDeviceHandleValid(sixaxis_handle)) {
1115 LOG_ERROR(Service_HID, "Invalid handle");
1116 return NpadInvalidHandle;
1046 } 1117 }
1047 auto& controller = GetControllerFromHandle(sixaxis_handle); 1118 auto& controller = GetControllerFromHandle(sixaxis_handle);
1048 controller.sixaxis_sensor_enabled = sixaxis_status; 1119 controller.sixaxis_sensor_enabled = sixaxis_status;
1120 return ResultSuccess;
1049} 1121}
1050 1122
1051void Controller_NPad::SetSixAxisFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle, 1123ResultCode Controller_NPad::IsSixAxisSensorFusionEnabled(
1052 bool sixaxis_fusion_status) { 1124 Core::HID::SixAxisSensorHandle sixaxis_handle, bool& is_fusion_enabled) const {
1053 if (!IsDeviceHandleValid(sixaxis_handle)) { 1125 if (!IsDeviceHandleValid(sixaxis_handle)) {
1054 LOG_ERROR(Service_HID, "Invalid handle"); 1126 LOG_ERROR(Service_HID, "Invalid handle");
1055 return; 1127 return NpadInvalidHandle;
1056 } 1128 }
1129
1057 auto& controller = GetControllerFromHandle(sixaxis_handle); 1130 auto& controller = GetControllerFromHandle(sixaxis_handle);
1058 controller.sixaxis_fusion_enabled = sixaxis_fusion_status; 1131 switch (sixaxis_handle.npad_type) {
1059} 1132 case Core::HID::NpadStyleIndex::ProController:
1133 is_fusion_enabled = controller.sixaxis_fullkey.is_fusion_enabled;
1134 break;
1135 case Core::HID::NpadStyleIndex::Handheld:
1136 is_fusion_enabled = controller.sixaxis_handheld.is_fusion_enabled;
1137 break;
1138 case Core::HID::NpadStyleIndex::JoyconDual:
1139 case Core::HID::NpadStyleIndex::GameCube:
1140 case Core::HID::NpadStyleIndex::Pokeball:
1141 if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
1142 is_fusion_enabled = controller.sixaxis_dual_left.is_fusion_enabled;
1143 break;
1144 }
1145 is_fusion_enabled = controller.sixaxis_dual_right.is_fusion_enabled;
1146 break;
1147 case Core::HID::NpadStyleIndex::JoyconLeft:
1148 is_fusion_enabled = controller.sixaxis_left.is_fusion_enabled;
1149 break;
1150 case Core::HID::NpadStyleIndex::JoyconRight:
1151 is_fusion_enabled = controller.sixaxis_right.is_fusion_enabled;
1152 break;
1153 default:
1154 LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type);
1155 return NpadInvalidHandle;
1156 }
1060 1157
1061void Controller_NPad::SetSixAxisFusionParameters( 1158 return ResultSuccess;
1062 Core::HID::SixAxisSensorHandle sixaxis_handle, 1159}
1063 Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) { 1160ResultCode Controller_NPad::SetSixAxisFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
1161 bool is_fusion_enabled) {
1064 if (!IsDeviceHandleValid(sixaxis_handle)) { 1162 if (!IsDeviceHandleValid(sixaxis_handle)) {
1065 LOG_ERROR(Service_HID, "Invalid handle"); 1163 LOG_ERROR(Service_HID, "Invalid handle");
1066 return; 1164 return NpadInvalidHandle;
1067 } 1165 }
1166
1068 auto& controller = GetControllerFromHandle(sixaxis_handle); 1167 auto& controller = GetControllerFromHandle(sixaxis_handle);
1069 controller.sixaxis_fusion = sixaxis_fusion_parameters; 1168 switch (sixaxis_handle.npad_type) {
1169 case Core::HID::NpadStyleIndex::ProController:
1170 controller.sixaxis_fullkey.is_fusion_enabled = is_fusion_enabled;
1171 break;
1172 case Core::HID::NpadStyleIndex::Handheld:
1173 controller.sixaxis_handheld.is_fusion_enabled = is_fusion_enabled;
1174 break;
1175 case Core::HID::NpadStyleIndex::JoyconDual:
1176 case Core::HID::NpadStyleIndex::GameCube:
1177 case Core::HID::NpadStyleIndex::Pokeball:
1178 if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
1179 controller.sixaxis_dual_left.is_fusion_enabled = is_fusion_enabled;
1180 break;
1181 }
1182 controller.sixaxis_dual_right.is_fusion_enabled = is_fusion_enabled;
1183 break;
1184 case Core::HID::NpadStyleIndex::JoyconLeft:
1185 controller.sixaxis_left.is_fusion_enabled = is_fusion_enabled;
1186 break;
1187 case Core::HID::NpadStyleIndex::JoyconRight:
1188 controller.sixaxis_right.is_fusion_enabled = is_fusion_enabled;
1189 break;
1190 default:
1191 LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type);
1192 return NpadInvalidHandle;
1193 }
1194
1195 return ResultSuccess;
1070} 1196}
1071 1197
1072Core::HID::SixAxisSensorFusionParameters Controller_NPad::GetSixAxisFusionParameters( 1198ResultCode Controller_NPad::SetSixAxisFusionParameters(
1073 Core::HID::SixAxisSensorHandle sixaxis_handle) { 1199 Core::HID::SixAxisSensorHandle sixaxis_handle,
1200 Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) {
1074 if (!IsDeviceHandleValid(sixaxis_handle)) { 1201 if (!IsDeviceHandleValid(sixaxis_handle)) {
1075 LOG_ERROR(Service_HID, "Invalid handle"); 1202 LOG_ERROR(Service_HID, "Invalid handle");
1076 // Since these parameters are unknow just return zeros 1203 return NpadInvalidHandle;
1077 return {};
1078 } 1204 }
1205 const auto param1 = sixaxis_fusion_parameters.parameter1;
1206 if (param1 < 0.0f || param1 > 1.0f) {
1207 return InvalidSixAxisFusionRange;
1208 }
1209
1079 auto& controller = GetControllerFromHandle(sixaxis_handle); 1210 auto& controller = GetControllerFromHandle(sixaxis_handle);
1080 return controller.sixaxis_fusion; 1211 switch (sixaxis_handle.npad_type) {
1212 case Core::HID::NpadStyleIndex::ProController:
1213 controller.sixaxis_fullkey.fusion = sixaxis_fusion_parameters;
1214 break;
1215 case Core::HID::NpadStyleIndex::Handheld:
1216 controller.sixaxis_handheld.fusion = sixaxis_fusion_parameters;
1217 break;
1218 case Core::HID::NpadStyleIndex::JoyconDual:
1219 case Core::HID::NpadStyleIndex::GameCube:
1220 case Core::HID::NpadStyleIndex::Pokeball:
1221 if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
1222 controller.sixaxis_dual_left.fusion = sixaxis_fusion_parameters;
1223 break;
1224 }
1225 controller.sixaxis_dual_right.fusion = sixaxis_fusion_parameters;
1226 break;
1227 case Core::HID::NpadStyleIndex::JoyconLeft:
1228 controller.sixaxis_left.fusion = sixaxis_fusion_parameters;
1229 break;
1230 case Core::HID::NpadStyleIndex::JoyconRight:
1231 controller.sixaxis_right.fusion = sixaxis_fusion_parameters;
1232 break;
1233 default:
1234 LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type);
1235 return NpadInvalidHandle;
1236 }
1237
1238 return ResultSuccess;
1081} 1239}
1082 1240
1083void Controller_NPad::ResetSixAxisFusionParameters(Core::HID::SixAxisSensorHandle sixaxis_handle) { 1241ResultCode Controller_NPad::GetSixAxisFusionParameters(
1242 Core::HID::SixAxisSensorHandle sixaxis_handle,
1243 Core::HID::SixAxisSensorFusionParameters& parameters) const {
1084 if (!IsDeviceHandleValid(sixaxis_handle)) { 1244 if (!IsDeviceHandleValid(sixaxis_handle)) {
1085 LOG_ERROR(Service_HID, "Invalid handle"); 1245 LOG_ERROR(Service_HID, "Invalid handle");
1086 return; 1246 return NpadInvalidHandle;
1087 } 1247 }
1088 auto& controller = GetControllerFromHandle(sixaxis_handle); 1248
1089 // Since these parameters are unknow just fill with zeros 1249 const auto& controller = GetControllerFromHandle(sixaxis_handle);
1090 controller.sixaxis_fusion = {}; 1250 switch (sixaxis_handle.npad_type) {
1251 case Core::HID::NpadStyleIndex::ProController:
1252 parameters = controller.sixaxis_fullkey.fusion;
1253 break;
1254 case Core::HID::NpadStyleIndex::Handheld:
1255 parameters = controller.sixaxis_handheld.fusion;
1256 break;
1257 case Core::HID::NpadStyleIndex::JoyconDual:
1258 case Core::HID::NpadStyleIndex::GameCube:
1259 case Core::HID::NpadStyleIndex::Pokeball:
1260 if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
1261 parameters = controller.sixaxis_dual_left.fusion;
1262 break;
1263 }
1264 parameters = controller.sixaxis_dual_right.fusion;
1265 break;
1266 case Core::HID::NpadStyleIndex::JoyconLeft:
1267 parameters = controller.sixaxis_left.fusion;
1268 break;
1269 case Core::HID::NpadStyleIndex::JoyconRight:
1270 parameters = controller.sixaxis_right.fusion;
1271 break;
1272 default:
1273 LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type);
1274 return NpadInvalidHandle;
1275 }
1276
1277 return ResultSuccess;
1091} 1278}
1092 1279
1093void Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, 1280void Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 967379f05..f7313711f 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -28,7 +28,9 @@ class KReadableEvent;
28 28
29namespace Service::KernelHelpers { 29namespace Service::KernelHelpers {
30class ServiceContext; 30class ServiceContext;
31} 31} // namespace Service::KernelHelpers
32
33union ResultCode;
32 34
33namespace Service::HID { 35namespace Service::HID {
34 36
@@ -143,20 +145,26 @@ public:
143 145
144 void DisconnectNpad(Core::HID::NpadIdType npad_id); 146 void DisconnectNpad(Core::HID::NpadIdType npad_id);
145 147
146 void SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle, 148 ResultCode SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
147 GyroscopeZeroDriftMode drift_mode); 149 GyroscopeZeroDriftMode drift_mode);
148 GyroscopeZeroDriftMode GetGyroscopeZeroDriftMode( 150 ResultCode GetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
149 Core::HID::SixAxisSensorHandle sixaxis_handle) const; 151 GyroscopeZeroDriftMode& drift_mode) const;
150 bool IsSixAxisSensorAtRest(Core::HID::SixAxisSensorHandle sixaxis_handle) const; 152 ResultCode IsSixAxisSensorAtRest(Core::HID::SixAxisSensorHandle sixaxis_handle,
151 void SetSixAxisEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle, bool sixaxis_status); 153 bool& is_at_rest) const;
152 void SetSixAxisFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle, 154 ResultCode IsFirmwareUpdateAvailableForSixAxisSensor(
153 bool sixaxis_fusion_status); 155 Core::HID::SixAxisSensorHandle sixaxis_handle, bool& is_firmware_available) const;
154 void SetSixAxisFusionParameters( 156 ResultCode SetSixAxisEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
157 bool sixaxis_status);
158 ResultCode IsSixAxisSensorFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
159 bool& is_fusion_enabled) const;
160 ResultCode SetSixAxisFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
161 bool is_fusion_enabled);
162 ResultCode SetSixAxisFusionParameters(
155 Core::HID::SixAxisSensorHandle sixaxis_handle, 163 Core::HID::SixAxisSensorHandle sixaxis_handle,
156 Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters); 164 Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters);
157 Core::HID::SixAxisSensorFusionParameters GetSixAxisFusionParameters( 165 ResultCode GetSixAxisFusionParameters(
158 Core::HID::SixAxisSensorHandle sixaxis_handle); 166 Core::HID::SixAxisSensorHandle sixaxis_handle,
159 void ResetSixAxisFusionParameters(Core::HID::SixAxisSensorHandle sixaxis_handle); 167 Core::HID::SixAxisSensorFusionParameters& parameters) const;
160 Core::HID::LedPattern GetLedPattern(Core::HID::NpadIdType npad_id); 168 Core::HID::LedPattern GetLedPattern(Core::HID::NpadIdType npad_id);
161 bool IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id) const; 169 bool IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id) const;
162 void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, 170 void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
@@ -451,6 +459,12 @@ private:
451 std::chrono::steady_clock::time_point last_vibration_timepoint{}; 459 std::chrono::steady_clock::time_point last_vibration_timepoint{};
452 }; 460 };
453 461
462 struct SixaxisParameters {
463 bool is_fusion_enabled{true};
464 Core::HID::SixAxisSensorFusionParameters fusion{};
465 GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard};
466 };
467
454 struct NpadControllerData { 468 struct NpadControllerData {
455 Core::HID::EmulatedController* device; 469 Core::HID::EmulatedController* device;
456 Kernel::KEvent* styleset_changed_event{}; 470 Kernel::KEvent* styleset_changed_event{};
@@ -467,9 +481,12 @@ private:
467 // Motion parameters 481 // Motion parameters
468 bool sixaxis_at_rest{true}; 482 bool sixaxis_at_rest{true};
469 bool sixaxis_sensor_enabled{true}; 483 bool sixaxis_sensor_enabled{true};
470 bool sixaxis_fusion_enabled{false}; 484 SixaxisParameters sixaxis_fullkey{};
471 Core::HID::SixAxisSensorFusionParameters sixaxis_fusion{}; 485 SixaxisParameters sixaxis_handheld{};
472 GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard}; 486 SixaxisParameters sixaxis_dual_left{};
487 SixaxisParameters sixaxis_dual_right{};
488 SixaxisParameters sixaxis_left{};
489 SixaxisParameters sixaxis_right{};
473 490
474 // Current pad state 491 // Current pad state
475 NPadGenericState npad_pad_state{}; 492 NPadGenericState npad_pad_state{};
@@ -481,6 +498,7 @@ private:
481 SixAxisSensorState sixaxis_dual_right_state{}; 498 SixAxisSensorState sixaxis_dual_right_state{};
482 SixAxisSensorState sixaxis_left_lifo_state{}; 499 SixAxisSensorState sixaxis_left_lifo_state{};
483 SixAxisSensorState sixaxis_right_lifo_state{}; 500 SixAxisSensorState sixaxis_right_lifo_state{};
501
484 int callback_key; 502 int callback_key;
485 }; 503 };
486 504
diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h
index 3583642e7..7c5fb3e52 100644
--- a/src/core/hle/service/hid/errors.h
+++ b/src/core/hle/service/hid/errors.h
@@ -8,6 +8,8 @@
8 8
9namespace Service::HID { 9namespace Service::HID {
10 10
11constexpr ResultCode ERR_NPAD_NOT_CONNECTED{ErrorModule::HID, 710}; 11constexpr ResultCode NpadInvalidHandle{ErrorModule::HID, 100};
12constexpr ResultCode InvalidSixAxisFusionRange{ErrorModule::HID, 423};
13constexpr ResultCode NpadNotConnected{ErrorModule::HID, 710};
12 14
13} // namespace Service::HID 15} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 9d3e0a658..baf21df62 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -248,7 +248,7 @@ Hid::Hid(Core::System& system_)
248 {65, nullptr, "GetJoySixAxisSensorLifoHandle"}, 248 {65, nullptr, "GetJoySixAxisSensorLifoHandle"},
249 {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"}, 249 {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
250 {67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"}, 250 {67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"},
251 {68, nullptr, "IsSixAxisSensorFusionEnabled"}, 251 {68, &Hid::IsSixAxisSensorFusionEnabled, "IsSixAxisSensorFusionEnabled"},
252 {69, &Hid::EnableSixAxisSensorFusion, "EnableSixAxisSensorFusion"}, 252 {69, &Hid::EnableSixAxisSensorFusion, "EnableSixAxisSensorFusion"},
253 {70, &Hid::SetSixAxisSensorFusionParameters, "SetSixAxisSensorFusionParameters"}, 253 {70, &Hid::SetSixAxisSensorFusionParameters, "SetSixAxisSensorFusionParameters"},
254 {71, &Hid::GetSixAxisSensorFusionParameters, "GetSixAxisSensorFusionParameters"}, 254 {71, &Hid::GetSixAxisSensorFusionParameters, "GetSixAxisSensorFusionParameters"},
@@ -528,8 +528,8 @@ void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
528 528
529 const auto parameters{rp.PopRaw<Parameters>()}; 529 const auto parameters{rp.PopRaw<Parameters>()};
530 530
531 applet_resource->GetController<Controller_NPad>(HidController::NPad) 531 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
532 .SetSixAxisEnabled(parameters.sixaxis_handle, true); 532 const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, true);
533 533
534 LOG_DEBUG(Service_HID, 534 LOG_DEBUG(Service_HID,
535 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 535 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -537,7 +537,7 @@ void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
537 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); 537 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
538 538
539 IPC::ResponseBuilder rb{ctx, 2}; 539 IPC::ResponseBuilder rb{ctx, 2};
540 rb.Push(ResultSuccess); 540 rb.Push(result);
541} 541}
542 542
543void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) { 543void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
@@ -551,8 +551,8 @@ void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
551 551
552 const auto parameters{rp.PopRaw<Parameters>()}; 552 const auto parameters{rp.PopRaw<Parameters>()};
553 553
554 applet_resource->GetController<Controller_NPad>(HidController::NPad) 554 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
555 .SetSixAxisEnabled(parameters.sixaxis_handle, false); 555 const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, false);
556 556
557 LOG_DEBUG(Service_HID, 557 LOG_DEBUG(Service_HID,
558 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 558 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -560,7 +560,33 @@ void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
560 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); 560 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
561 561
562 IPC::ResponseBuilder rb{ctx, 2}; 562 IPC::ResponseBuilder rb{ctx, 2};
563 rb.Push(ResultSuccess); 563 rb.Push(result);
564}
565
566void Hid::IsSixAxisSensorFusionEnabled(Kernel::HLERequestContext& ctx) {
567 IPC::RequestParser rp{ctx};
568 struct Parameters {
569 Core::HID::SixAxisSensorHandle sixaxis_handle;
570 INSERT_PADDING_WORDS_NOINIT(1);
571 u64 applet_resource_user_id;
572 };
573 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
574
575 const auto parameters{rp.PopRaw<Parameters>()};
576
577 bool is_enabled{};
578 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
579 const auto result =
580 controller.IsSixAxisSensorFusionEnabled(parameters.sixaxis_handle, is_enabled);
581
582 LOG_DEBUG(Service_HID,
583 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
584 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
585 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
586
587 IPC::ResponseBuilder rb{ctx, 3};
588 rb.Push(result);
589 rb.Push(is_enabled);
564} 590}
565 591
566void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) { 592void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) {
@@ -575,9 +601,9 @@ void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) {
575 601
576 const auto parameters{rp.PopRaw<Parameters>()}; 602 const auto parameters{rp.PopRaw<Parameters>()};
577 603
578 applet_resource->GetController<Controller_NPad>(HidController::NPad) 604 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
579 .SetSixAxisFusionEnabled(parameters.sixaxis_handle, 605 const auto result = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle,
580 parameters.enable_sixaxis_sensor_fusion); 606 parameters.enable_sixaxis_sensor_fusion);
581 607
582 LOG_DEBUG(Service_HID, 608 LOG_DEBUG(Service_HID,
583 "called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, " 609 "called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, "
@@ -587,7 +613,7 @@ void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) {
587 parameters.applet_resource_user_id); 613 parameters.applet_resource_user_id);
588 614
589 IPC::ResponseBuilder rb{ctx, 2}; 615 IPC::ResponseBuilder rb{ctx, 2};
590 rb.Push(ResultSuccess); 616 rb.Push(result);
591} 617}
592 618
593void Hid::SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) { 619void Hid::SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
@@ -602,8 +628,9 @@ void Hid::SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
602 628
603 const auto parameters{rp.PopRaw<Parameters>()}; 629 const auto parameters{rp.PopRaw<Parameters>()};
604 630
605 applet_resource->GetController<Controller_NPad>(HidController::NPad) 631 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
606 .SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion); 632 const auto result =
633 controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion);
607 634
608 LOG_DEBUG(Service_HID, 635 LOG_DEBUG(Service_HID,
609 "called, npad_type={}, npad_id={}, device_index={}, parameter1={}, " 636 "called, npad_type={}, npad_id={}, device_index={}, parameter1={}, "
@@ -613,7 +640,7 @@ void Hid::SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
613 parameters.sixaxis_fusion.parameter2, parameters.applet_resource_user_id); 640 parameters.sixaxis_fusion.parameter2, parameters.applet_resource_user_id);
614 641
615 IPC::ResponseBuilder rb{ctx, 2}; 642 IPC::ResponseBuilder rb{ctx, 2};
616 rb.Push(ResultSuccess); 643 rb.Push(result);
617} 644}
618 645
619void Hid::GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) { 646void Hid::GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
@@ -627,9 +654,11 @@ void Hid::GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
627 654
628 const auto parameters{rp.PopRaw<Parameters>()}; 655 const auto parameters{rp.PopRaw<Parameters>()};
629 656
630 const auto sixaxis_fusion_parameters = 657 Core::HID::SixAxisSensorFusionParameters fusion_parameters{};
631 applet_resource->GetController<Controller_NPad>(HidController::NPad) 658 const auto& controller =
632 .GetSixAxisFusionParameters(parameters.sixaxis_handle); 659 GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
660 const auto result =
661 controller.GetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
633 662
634 LOG_DEBUG(Service_HID, 663 LOG_DEBUG(Service_HID,
635 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 664 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -637,8 +666,8 @@ void Hid::GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
637 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); 666 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
638 667
639 IPC::ResponseBuilder rb{ctx, 4}; 668 IPC::ResponseBuilder rb{ctx, 4};
640 rb.Push(ResultSuccess); 669 rb.Push(result);
641 rb.PushRaw(sixaxis_fusion_parameters); 670 rb.PushRaw(fusion_parameters);
642} 671}
643 672
644void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) { 673void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
@@ -652,8 +681,15 @@ void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
652 681
653 const auto parameters{rp.PopRaw<Parameters>()}; 682 const auto parameters{rp.PopRaw<Parameters>()};
654 683
655 applet_resource->GetController<Controller_NPad>(HidController::NPad) 684 // Since these parameters are unknow just use what HW outputs
656 .ResetSixAxisFusionParameters(parameters.sixaxis_handle); 685 const Core::HID::SixAxisSensorFusionParameters fusion_parameters{
686 .parameter1 = 0.03f,
687 .parameter2 = 0.4f,
688 };
689 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
690 const auto result1 =
691 controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
692 const auto result2 = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle, true);
657 693
658 LOG_DEBUG(Service_HID, 694 LOG_DEBUG(Service_HID,
659 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 695 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -661,6 +697,14 @@ void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
661 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); 697 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
662 698
663 IPC::ResponseBuilder rb{ctx, 2}; 699 IPC::ResponseBuilder rb{ctx, 2};
700 if (result1.IsError()) {
701 rb.Push(result1);
702 return;
703 }
704 if (result2.IsError()) {
705 rb.Push(result2);
706 return;
707 }
664 rb.Push(ResultSuccess); 708 rb.Push(ResultSuccess);
665} 709}
666 710
@@ -670,8 +714,8 @@ void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
670 const auto drift_mode{rp.PopEnum<Controller_NPad::GyroscopeZeroDriftMode>()}; 714 const auto drift_mode{rp.PopEnum<Controller_NPad::GyroscopeZeroDriftMode>()};
671 const auto applet_resource_user_id{rp.Pop<u64>()}; 715 const auto applet_resource_user_id{rp.Pop<u64>()};
672 716
673 applet_resource->GetController<Controller_NPad>(HidController::NPad) 717 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
674 .SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode); 718 const auto result = controller.SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode);
675 719
676 LOG_DEBUG(Service_HID, 720 LOG_DEBUG(Service_HID,
677 "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, " 721 "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, "
@@ -680,7 +724,7 @@ void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
680 drift_mode, applet_resource_user_id); 724 drift_mode, applet_resource_user_id);
681 725
682 IPC::ResponseBuilder rb{ctx, 2}; 726 IPC::ResponseBuilder rb{ctx, 2};
683 rb.Push(ResultSuccess); 727 rb.Push(result);
684} 728}
685 729
686void Hid::GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { 730void Hid::GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
@@ -694,15 +738,18 @@ void Hid::GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
694 738
695 const auto parameters{rp.PopRaw<Parameters>()}; 739 const auto parameters{rp.PopRaw<Parameters>()};
696 740
741 auto drift_mode{Controller_NPad::GyroscopeZeroDriftMode::Standard};
742 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
743 const auto result = controller.GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
744
697 LOG_DEBUG(Service_HID, 745 LOG_DEBUG(Service_HID,
698 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 746 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
699 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, 747 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
700 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); 748 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
701 749
702 IPC::ResponseBuilder rb{ctx, 3}; 750 IPC::ResponseBuilder rb{ctx, 3};
703 rb.Push(ResultSuccess); 751 rb.Push(result);
704 rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad) 752 rb.PushEnum(drift_mode);
705 .GetGyroscopeZeroDriftMode(parameters.sixaxis_handle));
706} 753}
707 754
708void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { 755void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
@@ -715,10 +762,10 @@ void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
715 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); 762 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
716 763
717 const auto parameters{rp.PopRaw<Parameters>()}; 764 const auto parameters{rp.PopRaw<Parameters>()};
718 const auto drift_mode{Controller_NPad::GyroscopeZeroDriftMode::Standard};
719 765
720 applet_resource->GetController<Controller_NPad>(HidController::NPad) 766 const auto drift_mode{Controller_NPad::GyroscopeZeroDriftMode::Standard};
721 .SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); 767 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
768 const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
722 769
723 LOG_DEBUG(Service_HID, 770 LOG_DEBUG(Service_HID,
724 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 771 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -726,7 +773,7 @@ void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
726 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); 773 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
727 774
728 IPC::ResponseBuilder rb{ctx, 2}; 775 IPC::ResponseBuilder rb{ctx, 2};
729 rb.Push(ResultSuccess); 776 rb.Push(result);
730} 777}
731 778
732void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) { 779void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
@@ -740,15 +787,18 @@ void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
740 787
741 const auto parameters{rp.PopRaw<Parameters>()}; 788 const auto parameters{rp.PopRaw<Parameters>()};
742 789
790 bool is_at_rest{};
791 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
792 const auto result = controller.IsSixAxisSensorAtRest(parameters.sixaxis_handle, is_at_rest);
793
743 LOG_DEBUG(Service_HID, 794 LOG_DEBUG(Service_HID,
744 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 795 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
745 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, 796 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
746 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); 797 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
747 798
748 IPC::ResponseBuilder rb{ctx, 3}; 799 IPC::ResponseBuilder rb{ctx, 3};
749 rb.Push(ResultSuccess); 800 rb.Push(result);
750 rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad) 801 rb.Push(is_at_rest);
751 .IsSixAxisSensorAtRest(parameters.sixaxis_handle));
752} 802}
753 803
754void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& ctx) { 804void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& ctx) {
@@ -762,6 +812,11 @@ void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& c
762 812
763 const auto parameters{rp.PopRaw<Parameters>()}; 813 const auto parameters{rp.PopRaw<Parameters>()};
764 814
815 bool is_firmware_available{};
816 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
817 const auto result = controller.IsFirmwareUpdateAvailableForSixAxisSensor(
818 parameters.sixaxis_handle, is_firmware_available);
819
765 LOG_WARNING( 820 LOG_WARNING(
766 Service_HID, 821 Service_HID,
767 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 822 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -769,8 +824,8 @@ void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& c
769 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); 824 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
770 825
771 IPC::ResponseBuilder rb{ctx, 3}; 826 IPC::ResponseBuilder rb{ctx, 3};
772 rb.Push(ResultSuccess); 827 rb.Push(result);
773 rb.Push(false); 828 rb.Push(is_firmware_available);
774} 829}
775 830
776void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) { 831void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) {
@@ -1120,7 +1175,7 @@ void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
1120 rb.Push(ResultSuccess); 1175 rb.Push(ResultSuccess);
1121 } else { 1176 } else {
1122 LOG_ERROR(Service_HID, "Npads are not connected!"); 1177 LOG_ERROR(Service_HID, "Npads are not connected!");
1123 rb.Push(ERR_NPAD_NOT_CONNECTED); 1178 rb.Push(NpadNotConnected);
1124 } 1179 }
1125} 1180}
1126 1181
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index c281081a7..666cb6ff5 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -103,6 +103,7 @@ private:
103 void DeactivateSixAxisSensor(Kernel::HLERequestContext& ctx); 103 void DeactivateSixAxisSensor(Kernel::HLERequestContext& ctx);
104 void StartSixAxisSensor(Kernel::HLERequestContext& ctx); 104 void StartSixAxisSensor(Kernel::HLERequestContext& ctx);
105 void StopSixAxisSensor(Kernel::HLERequestContext& ctx); 105 void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
106 void IsSixAxisSensorFusionEnabled(Kernel::HLERequestContext& ctx);
106 void EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx); 107 void EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx);
107 void SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx); 108 void SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx);
108 void GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx); 109 void GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx);