diff options
Diffstat (limited to '')
23 files changed, 210 insertions, 54 deletions
diff --git a/src/core/hle/service/hid/controllers/controller_base.cpp b/src/core/hle/service/hid/controllers/controller_base.cpp index 0993a7815..8091db9d7 100644 --- a/src/core/hle/service/hid/controllers/controller_base.cpp +++ b/src/core/hle/service/hid/controllers/controller_base.cpp @@ -6,7 +6,7 @@ namespace Service::HID { -ControllerBase::ControllerBase() = default; +ControllerBase::ControllerBase(Core::System& system) : system(system) {} ControllerBase::~ControllerBase() = default; void ControllerBase::ActivateController() { diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h index 5e5097a03..8bc69c372 100644 --- a/src/core/hle/service/hid/controllers/controller_base.h +++ b/src/core/hle/service/hid/controllers/controller_base.h @@ -11,10 +11,14 @@ namespace Core::Timing { class CoreTiming; } +namespace Core { +class System; +} + namespace Service::HID { class ControllerBase { public: - ControllerBase(); + explicit ControllerBase(Core::System& system); virtual ~ControllerBase(); // Called when the controller is initialized @@ -46,5 +50,7 @@ protected: s64_le entry_count; }; static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); + + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp index c5c2e032a..8e8263f5b 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.cpp +++ b/src/core/hle/service/hid/controllers/debug_pad.cpp @@ -14,7 +14,8 @@ constexpr s32 HID_JOYSTICK_MAX = 0x7fff; constexpr s32 HID_JOYSTICK_MIN = -0x7fff; enum class JoystickId : std::size_t { Joystick_Left, Joystick_Right }; -Controller_DebugPad::Controller_DebugPad() = default; +Controller_DebugPad::Controller_DebugPad(Core::System& system) + : ControllerBase(system), system(system) {} Controller_DebugPad::~Controller_DebugPad() = default; void Controller_DebugPad::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h index e584b92ec..6c4de817e 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.h +++ b/src/core/hle/service/hid/controllers/debug_pad.h @@ -16,7 +16,7 @@ namespace Service::HID { class Controller_DebugPad final : public ControllerBase { public: - Controller_DebugPad(); + explicit Controller_DebugPad(Core::System& system); ~Controller_DebugPad() override; // Called when the controller is initialized @@ -89,5 +89,6 @@ private: buttons; std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID> analogs; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp index a179252e3..80da0a0d3 100644 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ b/src/core/hle/service/hid/controllers/gesture.cpp @@ -10,7 +10,8 @@ namespace Service::HID { constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00; -Controller_Gesture::Controller_Gesture() = default; +Controller_Gesture::Controller_Gesture(Core::System& system) + : ControllerBase(system), system(system) {} Controller_Gesture::~Controller_Gesture() = default; void Controller_Gesture::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h index f305fe90f..396897527 100644 --- a/src/core/hle/service/hid/controllers/gesture.h +++ b/src/core/hle/service/hid/controllers/gesture.h @@ -12,7 +12,7 @@ namespace Service::HID { class Controller_Gesture final : public ControllerBase { public: - Controller_Gesture(); + explicit Controller_Gesture(Core::System& system); ~Controller_Gesture() override; // Called when the controller is initialized @@ -59,5 +59,6 @@ private: std::array<GestureState, 17> gesture_states; }; SharedMemory shared_memory{}; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index 92d7bfb52..e587b2e15 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp @@ -12,7 +12,8 @@ namespace Service::HID { constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; constexpr u8 KEYS_PER_BYTE = 8; -Controller_Keyboard::Controller_Keyboard() = default; +Controller_Keyboard::Controller_Keyboard(Core::System& system) + : ControllerBase(system), system(system) {} Controller_Keyboard::~Controller_Keyboard() = default; void Controller_Keyboard::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h index 73cd2c7bb..ef586f7eb 100644 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ b/src/core/hle/service/hid/controllers/keyboard.h @@ -15,7 +15,7 @@ namespace Service::HID { class Controller_Keyboard final : public ControllerBase { public: - Controller_Keyboard(); + explicit Controller_Keyboard(Core::System& system); ~Controller_Keyboard() override; // Called when the controller is initialized @@ -53,5 +53,6 @@ private: keyboard_keys; std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeKeyboard::NumKeyboardMods> keyboard_mods; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index 11ab096d9..88f2ca4c1 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp @@ -11,7 +11,7 @@ namespace Service::HID { constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400; -Controller_Mouse::Controller_Mouse() = default; +Controller_Mouse::Controller_Mouse(Core::System& system) : ControllerBase(system), system(system) {} Controller_Mouse::~Controller_Mouse() = default; void Controller_Mouse::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h index 9d46eecbe..df2da6ae3 100644 --- a/src/core/hle/service/hid/controllers/mouse.h +++ b/src/core/hle/service/hid/controllers/mouse.h @@ -14,7 +14,7 @@ namespace Service::HID { class Controller_Mouse final : public ControllerBase { public: - Controller_Mouse(); + explicit Controller_Mouse(Core::System& system); ~Controller_Mouse() override; // Called when the controller is initialized @@ -53,5 +53,6 @@ private: std::unique_ptr<Input::MouseDevice> mouse_device; std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeMouseButton::NumMouseButtons> mouse_button_devices; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index fdd6d79a2..44b668fbf 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -93,7 +93,7 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) { }; } -Controller_NPad::Controller_NPad() = default; +Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {} Controller_NPad::~Controller_NPad() = default; void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { @@ -168,9 +168,11 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { } void Controller_NPad::OnInit() { - auto& kernel = Core::System::GetInstance().Kernel(); - styleset_changed_event = Kernel::WritableEvent::CreateEventPair( - kernel, Kernel::ResetType::Automatic, "npad:NpadStyleSetChanged"); + auto& kernel = system.Kernel(); + for (std::size_t i = 0; i < styleset_changed_events.size(); i++) { + styleset_changed_events[i] = Kernel::WritableEvent::CreateEventPair( + kernel, Kernel::ResetType::Automatic, fmt::format("npad:NpadStyleSetChanged_{}", i)); + } if (!IsControllerActivated()) { return; @@ -453,7 +455,7 @@ void Controller_NPad::SetSupportedNPadIdTypes(u8* data, std::size_t length) { had_controller_update = true; } if (had_controller_update) { - styleset_changed_event.writable->Signal(); + styleset_changed_events[i].writable->Signal(); } } } @@ -468,7 +470,6 @@ std::size_t Controller_NPad::GetSupportedNPadIdTypesSize() const { } void Controller_NPad::SetHoldType(NpadHoldType joy_hold_type) { - styleset_changed_event.writable->Signal(); hold_type = joy_hold_type; } @@ -479,7 +480,10 @@ Controller_NPad::NpadHoldType Controller_NPad::GetHoldType() const { void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode) { const std::size_t npad_index = NPadIdToIndex(npad_id); ASSERT(npad_index < shared_memory_entries.size()); - shared_memory_entries[npad_index].pad_assignment = assignment_mode; + if (shared_memory_entries[npad_index].pad_assignment != assignment_mode) { + styleset_changed_events[npad_index].writable->Signal(); + shared_memory_entries[npad_index].pad_assignment = assignment_mode; + } } void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids, @@ -498,11 +502,13 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids, last_processed_vibration = vibrations.back(); } -Kernel::SharedPtr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent() const { +Kernel::SharedPtr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent( + u32 npad_id) const { // TODO(ogniK): Figure out the best time to signal this event. This event seems that it should // be signalled at least once, and signaled after a new controller is connected? - styleset_changed_event.writable->Signal(); - return styleset_changed_event.readable; + const auto& styleset_event = styleset_changed_events[NPadIdToIndex(npad_id)]; + styleset_event.writable->Signal(); + return styleset_event.readable; } Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { @@ -548,6 +554,37 @@ void Controller_NPad::DisconnectNPad(u32 npad_id) { connected_controllers[NPadIdToIndex(npad_id)].is_connected = false; } +void Controller_NPad::StartLRAssignmentMode() { + // Nothing internally is used for lr assignment mode. Since we have the ability to set the + // controller types from boot, it doesn't really matter about showing a selection screen + is_in_lr_assignment_mode = true; +} + +void Controller_NPad::StopLRAssignmentMode() { + is_in_lr_assignment_mode = false; +} + +bool Controller_NPad::SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2) { + if (npad_id_1 == NPAD_HANDHELD || npad_id_2 == NPAD_HANDHELD || npad_id_1 == NPAD_UNKNOWN || + npad_id_2 == NPAD_UNKNOWN) { + return true; + } + const auto npad_index_1 = NPadIdToIndex(npad_id_1); + const auto npad_index_2 = NPadIdToIndex(npad_id_2); + + if (!IsControllerSupported(connected_controllers[npad_index_1].type) || + !IsControllerSupported(connected_controllers[npad_index_2].type)) { + return false; + } + + std::swap(connected_controllers[npad_index_1].type, connected_controllers[npad_index_2].type); + + InitNewlyAddedControler(npad_index_1); + InitNewlyAddedControler(npad_index_2); + + return true; +} + bool Controller_NPad::IsControllerSupported(NPadControllerType controller) { if (controller == NPadControllerType::Handheld) { // Handheld is not even a supported type, lets stop here @@ -605,10 +642,15 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { return LedPattern{0, 0, 0, 0}; }; } + void Controller_NPad::SetVibrationEnabled(bool can_vibrate) { can_controllers_vibrate = can_vibrate; } +bool Controller_NPad::IsVibrationEnabled() const { + return can_controllers_vibrate; +} + void Controller_NPad::ClearAllConnectedControllers() { for (auto& controller : connected_controllers) { if (controller.is_connected && controller.type != NPadControllerType::None) { @@ -617,6 +659,7 @@ void Controller_NPad::ClearAllConnectedControllers() { } } } + void Controller_NPad::DisconnectAllConnectedControllers() { std::for_each(connected_controllers.begin(), connected_controllers.end(), [](ControllerHolder& controller) { controller.is_connected = false; }); diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 4ff50b3cd..1bc3d55d6 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -20,7 +20,7 @@ constexpr u32 NPAD_UNKNOWN = 16; // TODO(ogniK): What is this? class Controller_NPad final : public ControllerBase { public: - Controller_NPad(); + explicit Controller_NPad(Core::System& system); ~Controller_NPad() override; // Called when the controller is initialized @@ -109,7 +109,7 @@ public: void VibrateController(const std::vector<u32>& controller_ids, const std::vector<Vibration>& vibrations); - Kernel::SharedPtr<Kernel::ReadableEvent> GetStyleSetChangedEvent() const; + Kernel::SharedPtr<Kernel::ReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const; Vibration GetLastVibration() const; void AddNewController(NPadControllerType controller); @@ -119,11 +119,16 @@ public: void DisconnectNPad(u32 npad_id); LedPattern GetLedPattern(u32 npad_id); void SetVibrationEnabled(bool can_vibrate); + bool IsVibrationEnabled() const; void ClearAllConnectedControllers(); void DisconnectAllConnectedControllers(); void ConnectAllDisconnectedControllers(); void ClearAllControllers(); + void StartLRAssignmentMode(); + void StopLRAssignmentMode(); + bool SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2); + // Logical OR for all buttons presses on all controllers // Specifically for cheat engine and other features. u32 GetAndResetPressState(); @@ -310,7 +315,8 @@ private: sticks; std::vector<u32> supported_npad_id_types{}; NpadHoldType hold_type{NpadHoldType::Vertical}; - Kernel::EventPair styleset_changed_event; + // Each controller should have their own styleset changed event + std::array<Kernel::EventPair, 10> styleset_changed_events; Vibration last_processed_vibration{}; std::array<ControllerHolder, 10> connected_controllers{}; bool can_controllers_vibrate{true}; @@ -321,5 +327,7 @@ private: void RequestPadStateUpdate(u32 npad_id); std::array<ControllerPad, 10> npad_pad_states{}; bool IsControllerSupported(NPadControllerType controller); + bool is_in_lr_assignment_mode{false}; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp index 946948f5e..9b829341e 100644 --- a/src/core/hle/service/hid/controllers/stubbed.cpp +++ b/src/core/hle/service/hid/controllers/stubbed.cpp @@ -9,7 +9,8 @@ namespace Service::HID { -Controller_Stubbed::Controller_Stubbed() = default; +Controller_Stubbed::Controller_Stubbed(Core::System& system) + : ControllerBase(system), system(system) {} Controller_Stubbed::~Controller_Stubbed() = default; void Controller_Stubbed::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/stubbed.h b/src/core/hle/service/hid/controllers/stubbed.h index 24469f03e..37d7d8538 100644 --- a/src/core/hle/service/hid/controllers/stubbed.h +++ b/src/core/hle/service/hid/controllers/stubbed.h @@ -10,7 +10,7 @@ namespace Service::HID { class Controller_Stubbed final : public ControllerBase { public: - Controller_Stubbed(); + explicit Controller_Stubbed(Core::System& system); ~Controller_Stubbed() override; // Called when the controller is initialized @@ -30,5 +30,6 @@ public: private: bool smart_update{}; std::size_t common_offset{}; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 1a8445a43..25912fd69 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp @@ -13,7 +13,8 @@ namespace Service::HID { constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400; -Controller_Touchscreen::Controller_Touchscreen() = default; +Controller_Touchscreen::Controller_Touchscreen(Core::System& system) + : ControllerBase(system), system(system) {} Controller_Touchscreen::~Controller_Touchscreen() = default; void Controller_Touchscreen::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index 76fc340e9..3429c84db 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h @@ -14,7 +14,7 @@ namespace Service::HID { class Controller_Touchscreen final : public ControllerBase { public: - Controller_Touchscreen(); + explicit Controller_Touchscreen(Core::System& system); ~Controller_Touchscreen() override; // Called when the controller is initialized @@ -69,5 +69,6 @@ private: TouchScreenSharedMemory shared_memory{}; std::unique_ptr<Input::TouchDevice> touch_device; s64_le last_touch{}; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp index 1a9da9576..1bce044b4 100644 --- a/src/core/hle/service/hid/controllers/xpad.cpp +++ b/src/core/hle/service/hid/controllers/xpad.cpp @@ -10,7 +10,7 @@ namespace Service::HID { constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00; -Controller_XPad::Controller_XPad() = default; +Controller_XPad::Controller_XPad(Core::System& system) : ControllerBase(system), system(system) {} Controller_XPad::~Controller_XPad() = default; void Controller_XPad::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h index 2864e6617..c445ebec0 100644 --- a/src/core/hle/service/hid/controllers/xpad.h +++ b/src/core/hle/service/hid/controllers/xpad.h @@ -12,7 +12,7 @@ namespace Service::HID { class Controller_XPad final : public ControllerBase { public: - Controller_XPad(); + explicit Controller_XPad(Core::System& system); ~Controller_XPad() override; // Called when the controller is initialized @@ -56,5 +56,6 @@ private: }; static_assert(sizeof(SharedMemory) == 0x1000, "SharedMemory is an invalid size"); SharedMemory shared_memory{}; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h new file mode 100644 index 000000000..3583642e7 --- /dev/null +++ b/src/core/hle/service/hid/errors.h @@ -0,0 +1,13 @@ +// Copyright 2019 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/result.h" + +namespace Service::HID { + +constexpr ResultCode ERR_NPAD_NOT_CONNECTED{ErrorModule::HID, 710}; + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index a4ad95d96..8d76ba746 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -16,6 +16,7 @@ #include "core/hle/kernel/readable_event.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/kernel/writable_event.h" +#include "core/hle/service/hid/errors.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/hid/irs.h" #include "core/hle/service/hid/xcd.h" @@ -41,13 +42,14 @@ constexpr s64 accelerometer_update_ticks = static_cast<s64>(Core::Timing::BASE_C constexpr s64 gyroscope_update_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 100); constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; -IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") { +IAppletResource::IAppletResource(Core::System& system) + : ServiceFramework("IAppletResource"), system(system) { static const FunctionInfo functions[] = { {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, }; RegisterHandlers(functions); - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); shared_mem = Kernel::SharedMemory::Create( kernel, nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory"); @@ -73,7 +75,7 @@ IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") { GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000); // Register update callbacks - auto& core_timing = Core::System::GetInstance().CoreTiming(); + auto& core_timing = system.CoreTiming(); pad_update_event = core_timing.RegisterEvent("HID::UpdatePadCallback", [this](u64 userdata, s64 cycles_late) { UpdateControllers(userdata, cycles_late); @@ -95,7 +97,7 @@ void IAppletResource::DeactivateController(HidController controller) { } IAppletResource ::~IAppletResource() { - Core::System::GetInstance().CoreTiming().UnscheduleEvent(pad_update_event, 0); + system.CoreTiming().UnscheduleEvent(pad_update_event, 0); } void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { @@ -107,7 +109,7 @@ void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { } void IAppletResource::UpdateControllers(u64 userdata, s64 cycles_late) { - auto& core_timing = Core::System::GetInstance().CoreTiming(); + auto& core_timing = system.CoreTiming(); const bool should_reload = Settings::values.is_device_reload_pending.exchange(false); for (const auto& controller : controllers) { @@ -140,13 +142,13 @@ private: std::shared_ptr<IAppletResource> Hid::GetAppletResource() { if (applet_resource == nullptr) { - applet_resource = std::make_shared<IAppletResource>(); + applet_resource = std::make_shared<IAppletResource>(system); } return applet_resource; } -Hid::Hid() : ServiceFramework("hid") { +Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) { // clang-format off static const FunctionInfo functions[] = { {0, &Hid::CreateAppletResource, "CreateAppletResource"}, @@ -202,11 +204,11 @@ Hid::Hid() : ServiceFramework("hid") { {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"}, {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"}, - {126, nullptr, "StartLrAssignmentMode"}, - {127, nullptr, "StopLrAssignmentMode"}, + {126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"}, + {127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"}, {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, {129, nullptr, "GetNpadHandheldActivationMode"}, - {130, nullptr, "SwapNpadAssignment"}, + {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"}, {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"}, {132, nullptr, "EnableUnintendedHomeButtonInputProtection"}, {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"}, @@ -215,8 +217,8 @@ Hid::Hid() : ServiceFramework("hid") { {201, &Hid::SendVibrationValue, "SendVibrationValue"}, {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"}, {203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"}, - {204, nullptr, "PermitVibration"}, - {205, nullptr, "IsVibrationPermitted"}, + {204, &Hid::PermitVibration, "PermitVibration"}, + {205, &Hid::IsVibrationPermitted, "IsVibrationPermitted"}, {206, &Hid::SendVibrationValues, "SendVibrationValues"}, {207, nullptr, "SendVibrationGcErmCommand"}, {208, nullptr, "GetActualVibrationGcErmCommand"}, @@ -285,7 +287,7 @@ void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); if (applet_resource == nullptr) { - applet_resource = std::make_shared<IAppletResource>(); + applet_resource = std::make_shared<IAppletResource>(system); } IPC::ResponseBuilder rb{ctx, 2, 0, 1}; @@ -478,7 +480,7 @@ void Hid::AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(applet_resource->GetController<Controller_NPad>(HidController::NPad) - .GetStyleSetChangedEvent()); + .GetStyleSetChangedEvent(npad_id)); } void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) { @@ -678,6 +680,27 @@ void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) { rb.PushIpcInterface<IActiveVibrationDeviceList>(); } +void Hid::PermitVibration(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto can_vibrate{rp.Pop<bool>()}; + applet_resource->GetController<Controller_NPad>(HidController::NPad) + .SetVibrationEnabled(can_vibrate); + + LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void Hid::IsVibrationPermitted(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_HID, "called"); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push( + applet_resource->GetController<Controller_NPad>(HidController::NPad).IsVibrationEnabled()); +} + void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop<u64>()}; @@ -733,6 +756,49 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); } +void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); + controller.StartLRAssignmentMode(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); + controller.StopLRAssignmentMode(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto npad_1{rp.Pop<u32>()}; + const auto npad_2{rp.Pop<u32>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}", + applet_resource_user_id, npad_1, npad_2); + + auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); + IPC::ResponseBuilder rb{ctx, 2}; + if (controller.SwapNpadAssignment(npad_1, npad_2)) { + rb.Push(RESULT_SUCCESS); + } else { + LOG_ERROR(Service_HID, "Npads are not connected!"); + rb.Push(ERR_NPAD_NOT_CONNECTED); + } +} + class HidDbg final : public ServiceFramework<HidDbg> { public: explicit HidDbg() : ServiceFramework{"hid:dbg"} { @@ -988,14 +1054,14 @@ void ReloadInputDevices() { Settings::values.is_device_reload_pending.store(true); } -void InstallInterfaces(SM::ServiceManager& service_manager) { - std::make_shared<Hid>()->InstallAsService(service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { + std::make_shared<Hid>(system)->InstallAsService(service_manager); std::make_shared<HidBus>()->InstallAsService(service_manager); std::make_shared<HidDbg>()->InstallAsService(service_manager); std::make_shared<HidSys>()->InstallAsService(service_manager); std::make_shared<HidTmp>()->InstallAsService(service_manager); - std::make_shared<IRS>()->InstallAsService(service_manager); + std::make_shared<IRS>(system)->InstallAsService(service_manager); std::make_shared<IRS_SYS>()->InstallAsService(service_manager); std::make_shared<XCD_SYS>()->InstallAsService(service_manager); diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index d3660cad2..35b663679 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -42,7 +42,7 @@ enum class HidController : std::size_t { class IAppletResource final : public ServiceFramework<IAppletResource> { public: - IAppletResource(); + explicit IAppletResource(Core::System& system); ~IAppletResource() override; void ActivateController(HidController controller); @@ -61,7 +61,7 @@ public: private: template <typename T> void MakeController(HidController controller) { - controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>(); + controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>(system); } void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); @@ -70,6 +70,7 @@ private: Kernel::SharedPtr<Kernel::SharedMemory> shared_mem; Core::Timing::EventType* pad_update_event; + Core::System& system; std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)> controllers{}; @@ -77,7 +78,7 @@ private: class Hid final : public ServiceFramework<Hid> { public: - Hid(); + explicit Hid(Core::System& system); ~Hid() override; std::shared_ptr<IAppletResource> GetAppletResource(); @@ -114,19 +115,25 @@ private: void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx); void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx); + void PermitVibration(Kernel::HLERequestContext& ctx); + void IsVibrationPermitted(Kernel::HLERequestContext& ctx); void ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx); void StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx); void StopSixAxisSensor(Kernel::HLERequestContext& ctx); void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx); void SetPalmaBoostMode(Kernel::HLERequestContext& ctx); + void StartLrAssignmentMode(Kernel::HLERequestContext& ctx); + void StopLrAssignmentMode(Kernel::HLERequestContext& ctx); + void SwapNpadAssignment(Kernel::HLERequestContext& ctx); std::shared_ptr<IAppletResource> applet_resource; + Core::System& system; }; /// Reload input devices. Used when input configuration changed void ReloadInputDevices(); /// Registers all HID services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); } // namespace Service::HID diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp index 2c4625c99..5e79e2c1a 100644 --- a/src/core/hle/service/hid/irs.cpp +++ b/src/core/hle/service/hid/irs.cpp @@ -11,7 +11,7 @@ namespace Service::HID { -IRS::IRS() : ServiceFramework{"irs"} { +IRS::IRS(Core::System& system) : ServiceFramework{"irs"}, system(system) { // clang-format off static const FunctionInfo functions[] = { {302, &IRS::ActivateIrsensor, "ActivateIrsensor"}, @@ -37,7 +37,7 @@ IRS::IRS() : ServiceFramework{"irs"} { RegisterHandlers(functions); - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); shared_mem = Kernel::SharedMemory::Create( kernel, nullptr, 0x8000, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "IRS:SharedMemory"); @@ -98,7 +98,7 @@ void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 5}; rb.Push(RESULT_SUCCESS); - rb.PushRaw<u64>(Core::System::GetInstance().CoreTiming().GetTicks()); + rb.PushRaw<u64>(system.CoreTiming().GetTicks()); rb.PushRaw<u32>(0); } diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h index 12de6bfb3..eb4e898dd 100644 --- a/src/core/hle/service/hid/irs.h +++ b/src/core/hle/service/hid/irs.h @@ -15,7 +15,7 @@ namespace Service::HID { class IRS final : public ServiceFramework<IRS> { public: - explicit IRS(); + explicit IRS(Core::System& system); ~IRS() override; private: @@ -39,6 +39,7 @@ private: void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx); Kernel::SharedPtr<Kernel::SharedMemory> shared_mem; const u32 device_handle{0xABCD}; + Core::System& system; }; class IRS_SYS final : public ServiceFramework<IRS_SYS> { |