diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 71 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 6 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 4 |
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 | |||
| 295 | void 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 | ||
| 296 | const void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { | 317 | const 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 | |||
| 336 | Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { | 362 | Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { |
| 337 | return last_processed_vibration; | 363 | return last_processed_vibration; |
| 338 | } | 364 | } |
| 339 | void Controller_NPad::AddNewController(NPadControllerType controller) { | 365 | void 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 | ||
| 353 | void Controller_NPad::ConnectNPad(u32 npad_id) { | 383 | void Controller_NPad::ConnectNPad(u32 npad_id) { |
| @@ -392,4 +422,13 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { | |||
| 392 | void Controller_NPad::SetVibrationEnabled(bool can_vibrate) { | 422 | void Controller_NPad::SetVibrationEnabled(bool can_vibrate) { |
| 393 | can_controllers_vibrate = can_vibrate; | 423 | can_controllers_vibrate = can_vibrate; |
| 394 | } | 424 | } |
| 425 | |||
| 426 | void 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 | ||
| 116 | private: | 116 | private: |
| 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) { |