summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp71
-rw-r--r--src/core/hle/service/hid/controllers/npad.h6
-rw-r--r--src/core/hle/service/hid/hid.cpp4
3 files changed, 62 insertions, 19 deletions
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 27b38abab..dbb0dd72d 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -41,7 +41,6 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {
41 controller.joy_styles.raw = 0; // Zero out 41 controller.joy_styles.raw = 0; // Zero out
42 controller.device_type.raw = 0; 42 controller.device_type.raw = 0;
43 switch (controller_type) { 43 switch (controller_type) {
44 case NPadControllerType::HandheldVariant:
45 case NPadControllerType::Handheld: 44 case NPadControllerType::Handheld:
46 controller.joy_styles.handheld.Assign(1); 45 controller.joy_styles.handheld.Assign(1);
47 controller.device_type.handheld.Assign(1); 46 controller.device_type.handheld.Assign(1);
@@ -93,7 +92,6 @@ void Controller_NPad::OnInit() {
93 if (!IsControllerActivated()) 92 if (!IsControllerActivated())
94 return; 93 return;
95 std::size_t controller{}; 94 std::size_t controller{};
96 supported_npad_id_types.resize(npad_id_list.size());
97 if (style.raw == 0) { 95 if (style.raw == 0) {
98 // We want to support all controllers 96 // We want to support all controllers
99 style.handheld.Assign(1); 97 style.handheld.Assign(1);
@@ -103,10 +101,11 @@ void Controller_NPad::OnInit() {
103 style.pro_controller.Assign(1); 101 style.pro_controller.Assign(1);
104 style.pokeball.Assign(1); 102 style.pokeball.Assign(1);
105 } 103 }
106 std::memcpy(supported_npad_id_types.data(), npad_id_list.data(),
107 npad_id_list.size() * sizeof(u32));
108 if (std::none_of(connected_controllers.begin(), connected_controllers.end(), 104 if (std::none_of(connected_controllers.begin(), connected_controllers.end(),
109 [](const ControllerHolder& controller) { return controller.is_connected; })) { 105 [](const ControllerHolder& controller) { return controller.is_connected; })) {
106 supported_npad_id_types.resize(npad_id_list.size());
107 std::memcpy(supported_npad_id_types.data(), npad_id_list.data(),
108 npad_id_list.size() * sizeof(u32));
110 AddNewController(NPadControllerType::Handheld); 109 AddNewController(NPadControllerType::Handheld);
111 } 110 }
112} 111}
@@ -221,7 +220,6 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
221 } 220 }
222 221
223 switch (controller_type) { 222 switch (controller_type) {
224 case NPadControllerType::HandheldVariant:
225 case NPadControllerType::Handheld: 223 case NPadControllerType::Handheld:
226 handheld_entry.connection_status.IsConnected.Assign(1); 224 handheld_entry.connection_status.IsConnected.Assign(1);
227 if (!Settings::values.use_docked_mode) { 225 if (!Settings::values.use_docked_mode) {
@@ -291,6 +289,29 @@ void Controller_NPad::SetSupportedNPadIdTypes(u8* data, std::size_t length) {
291 ASSERT(length > 0 && (length % sizeof(u32)) == 0); 289 ASSERT(length > 0 && (length % sizeof(u32)) == 0);
292 supported_npad_id_types.resize(length / sizeof(u32)); 290 supported_npad_id_types.resize(length / sizeof(u32));
293 std::memcpy(supported_npad_id_types.data(), data, length); 291 std::memcpy(supported_npad_id_types.data(), data, length);
292 CheckForHandheldVariant();
293}
294
295void Controller_NPad::CheckForHandheldVariant() {
296 // As some games expect us to use the variant of handheld mode and some games don't. It's
297 // consistent that games set the npad ids in order of priority. We can just swap the controller
298 // ids on the fly then if we're in handheld mode
299 if (supported_npad_id_types.size() > 0) {
300 const auto& first_controller = supported_npad_id_types.front();
301 if (first_controller == 32 && !connected_controllers[8].is_connected) {
302 const auto& first_controller = connected_controllers.front();
303 if (first_controller.is_connected &&
304 first_controller.type == NPadControllerType::Handheld) {
305 DisconnectNPad(0);
306 AddNewController(NPadControllerType::Handheld, true);
307 }
308 } else if (first_controller != 32 && connected_controllers[8].is_connected) {
309 if (!connected_controllers[0].is_connected) {
310 DisconnectNPad(8);
311 AddNewController(NPadControllerType::Handheld);
312 }
313 }
314 }
294} 315}
295 316
296const void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { 317const void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) {
@@ -320,10 +341,15 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
320 return; 341 return;
321 } 342 }
322 for (std::size_t i = 0; i < controller_ids.size(); i++) { 343 for (std::size_t i = 0; i < controller_ids.size(); i++) {
323 if (i >= controller_count) { 344 std::size_t controller_pos = i;
324 continue; 345 if (controller_pos == 32)
346 controller_pos = 8;
347 if (controller_pos == 16)
348 controller_pos = 9;
349
350 if (connected_controllers[controller_pos].is_connected) {
351 // TODO(ogniK): Vibrate the physical controller
325 } 352 }
326 // TODO(ogniK): Vibrate the physical controller
327 } 353 }
328 LOG_WARNING(Service_HID, "(STUBBED) called"); 354 LOG_WARNING(Service_HID, "(STUBBED) called");
329 last_processed_vibration = vibrations.back(); 355 last_processed_vibration = vibrations.back();
@@ -336,18 +362,22 @@ Kernel::SharedPtr<Kernel::Event> Controller_NPad::GetStyleSetChangedEvent() cons
336Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { 362Controller_NPad::Vibration Controller_NPad::GetLastVibration() const {
337 return last_processed_vibration; 363 return last_processed_vibration;
338} 364}
339void Controller_NPad::AddNewController(NPadControllerType controller) { 365void Controller_NPad::AddNewController(NPadControllerType controller, bool is_handheld_variant) {
340 if (controller_count >= connected_controllers.size()) { 366 if (is_handheld_variant) {
341 LOG_ERROR(Service_HID, "Cannot connect any more controllers!");
342 return;
343 }
344 if (controller == NPadControllerType::HandheldVariant) {
345 connected_controllers[8] = {controller, true}; 367 connected_controllers[8] = {controller, true};
346 InitNewlyAddedControler(8); 368 InitNewlyAddedControler(8);
347 return; 369 return;
348 } 370 }
349 connected_controllers[controller_count] = {controller, true}; 371 const auto pos =
350 InitNewlyAddedControler(controller_count++); 372 std::find_if(connected_controllers.begin(), connected_controllers.end() - 2,
373 [](const ControllerHolder& holder) { return !holder.is_connected; });
374 if (pos == connected_controllers.end() - 2) {
375 LOG_ERROR(Service_HID, "Cannot connect any more controllers!");
376 return;
377 }
378 const auto controller_id = std::distance(connected_controllers.begin(), pos);
379 connected_controllers[controller_id] = {controller, true};
380 InitNewlyAddedControler(controller_id);
351} 381}
352 382
353void Controller_NPad::ConnectNPad(u32 npad_id) { 383void Controller_NPad::ConnectNPad(u32 npad_id) {
@@ -392,4 +422,13 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) {
392void Controller_NPad::SetVibrationEnabled(bool can_vibrate) { 422void Controller_NPad::SetVibrationEnabled(bool can_vibrate) {
393 can_controllers_vibrate = can_vibrate; 423 can_controllers_vibrate = can_vibrate;
394} 424}
425
426void Controller_NPad::SetHandheldActiviationMode(u32 mode) {
427 const auto& first_controller = connected_controllers.front();
428 if (!first_controller.is_connected || connected_controllers[8].is_connected) {
429 return;
430 }
431 DisconnectNPad(0);
432 AddNewController(NPadControllerType::Handheld, true);
433}
395} // namespace Service::HID 434} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index b1aa98820..bc3d15ce6 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -65,7 +65,6 @@ public:
65 None, 65 None,
66 ProController, 66 ProController,
67 Handheld, 67 Handheld,
68 HandheldVariant, // Games which require the handheld controller to be at index 8
69 JoyLeft, 68 JoyLeft,
70 JoyRight, 69 JoyRight,
71 Tabletop, 70 Tabletop,
@@ -106,12 +105,13 @@ public:
106 Kernel::SharedPtr<Kernel::Event> GetStyleSetChangedEvent() const; 105 Kernel::SharedPtr<Kernel::Event> GetStyleSetChangedEvent() const;
107 Vibration GetLastVibration() const; 106 Vibration GetLastVibration() const;
108 107
109 void AddNewController(NPadControllerType controller); 108 void AddNewController(NPadControllerType controller, bool is_handheld_variant = false);
110 109
111 void ConnectNPad(u32 npad_id); 110 void ConnectNPad(u32 npad_id);
112 void DisconnectNPad(u32 npad_id); 111 void DisconnectNPad(u32 npad_id);
113 LedPattern GetLedPattern(u32 npad_id); 112 LedPattern GetLedPattern(u32 npad_id);
114 void SetVibrationEnabled(bool can_vibrate); 113 void SetVibrationEnabled(bool can_vibrate);
114 void SetHandheldActiviationMode(u32 mode);
115 115
116private: 116private:
117 struct CommonHeader { 117 struct CommonHeader {
@@ -273,10 +273,10 @@ private:
273 Kernel::SharedPtr<Kernel::Event> styleset_changed_event; 273 Kernel::SharedPtr<Kernel::Event> styleset_changed_event;
274 std::size_t dump_idx{}; 274 std::size_t dump_idx{};
275 Vibration last_processed_vibration{}; 275 Vibration last_processed_vibration{};
276 std::size_t controller_count{};
277 static constexpr std::array<u32, 10> npad_id_list{0, 1, 2, 3, 4, 5, 6, 7, 32, 16}; 276 static constexpr std::array<u32, 10> npad_id_list{0, 1, 2, 3, 4, 5, 6, 7, 32, 16};
278 std::array<ControllerHolder, 10> connected_controllers{}; 277 std::array<ControllerHolder, 10> connected_controllers{};
279 bool can_controllers_vibrate{true}; 278 bool can_controllers_vibrate{true};
279 void CheckForHandheldVariant();
280 280
281 void InitNewlyAddedControler(std::size_t controller_idx); 281 void InitNewlyAddedControler(std::size_t controller_idx);
282}; 282};
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 65ee1d9bb..e5cbd2ef6 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -347,6 +347,8 @@ private:
347 } 347 }
348 348
349 void StartSixAxisSensor(Kernel::HLERequestContext& ctx) { 349 void StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
350 IPC::RequestParser rp{ctx};
351 auto handle = rp.PopRaw<u32>();
350 IPC::ResponseBuilder rb{ctx, 2}; 352 IPC::ResponseBuilder rb{ctx, 2};
351 rb.Push(RESULT_SUCCESS); 353 rb.Push(RESULT_SUCCESS);
352 LOG_WARNING(Service_HID, "(STUBBED) called"); 354 LOG_WARNING(Service_HID, "(STUBBED) called");
@@ -539,6 +541,8 @@ private:
539 IPC::ResponseBuilder rb{ctx, 2}; 541 IPC::ResponseBuilder rb{ctx, 2};
540 rb.Push(RESULT_SUCCESS); 542 rb.Push(RESULT_SUCCESS);
541 LOG_WARNING(Service_HID, "(STUBBED) called"); 543 LOG_WARNING(Service_HID, "(STUBBED) called");
544 applet_resource->GetController<Controller_NPad>(HidController::NPad)
545 .SetHandheldActiviationMode(mode);
542 } 546 }
543 547
544 void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { 548 void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {