summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/hid/hid_server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/hid/hid_server.cpp')
-rw-r--r--src/core/hle/service/hid/hid_server.cpp587
1 files changed, 350 insertions, 237 deletions
diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
index 3174672af..09c47b5e3 100644
--- a/src/core/hle/service/hid/hid_server.cpp
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -5,30 +5,33 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/settings.h"
-#include "core/hid/hid_core.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/kernel.h"
-#include "core/hle/service/hid/errors.h"
-#include "core/hle/service/hid/hid_firmware_settings.h"
#include "core/hle/service/hid/hid_server.h"
-#include "core/hle/service/hid/hid_util.h"
-#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/memory.h"
-
-#include "core/hle/service/hid/controllers/console_six_axis.h"
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/hid/controllers/debug_pad.h"
-#include "core/hle/service/hid/controllers/gesture.h"
-#include "core/hle/service/hid/controllers/keyboard.h"
-#include "core/hle/service/hid/controllers/mouse.h"
-#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/controllers/palma.h"
-#include "core/hle/service/hid/controllers/seven_six_axis.h"
-#include "core/hle/service/hid/controllers/six_axis.h"
-#include "core/hle/service/hid/controllers/touchscreen.h"
-#include "core/hle/service/hid/controllers/types/npad_types.h"
+#include "hid_core/hid_result.h"
+#include "hid_core/hid_util.h"
+#include "hid_core/resource_manager.h"
+#include "hid_core/resources/hid_firmware_settings.h"
+
+#include "hid_core/resources/controller_base.h"
+#include "hid_core/resources/debug_pad/debug_pad.h"
+#include "hid_core/resources/keyboard/keyboard.h"
+#include "hid_core/resources/mouse/mouse.h"
+#include "hid_core/resources/npad/npad.h"
+#include "hid_core/resources/npad/npad_types.h"
+#include "hid_core/resources/npad/npad_vibration.h"
+#include "hid_core/resources/palma/palma.h"
+#include "hid_core/resources/six_axis/console_six_axis.h"
+#include "hid_core/resources/six_axis/seven_six_axis.h"
+#include "hid_core/resources/six_axis/six_axis.h"
+#include "hid_core/resources/touch_screen/gesture.h"
+#include "hid_core/resources/touch_screen/touch_screen.h"
+#include "hid_core/resources/vibration/gc_vibration_device.h"
+#include "hid_core/resources/vibration/n64_vibration_device.h"
+#include "hid_core/resources/vibration/vibration_device.h"
namespace Service::HID {
@@ -39,7 +42,7 @@ public:
: ServiceFramework{system_, "IActiveVibrationDeviceList"}, resource_manager(resource) {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &IActiveVibrationDeviceList::InitializeVibrationDevice, "InitializeVibrationDevice"},
+ {0, &IActiveVibrationDeviceList::ActivateVibrationDevice, "ActivateVibrationDevice"},
};
// clang-format on
@@ -47,22 +50,49 @@ public:
}
private:
- void InitializeVibrationDevice(HLERequestContext& ctx) {
+ void ActivateVibrationDevice(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
- if (resource_manager != nullptr && resource_manager->GetNpad()) {
- resource_manager->GetNpad()->InitializeVibrationDevice(vibration_device_handle);
- }
-
LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}",
vibration_device_handle.npad_type, vibration_device_handle.npad_id,
vibration_device_handle.device_index);
+ const auto result = ActivateVibrationDeviceImpl(vibration_device_handle);
+
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
+ Result ActivateVibrationDeviceImpl(const Core::HID::VibrationDeviceHandle& handle) {
+ std::scoped_lock lock{mutex};
+
+ const Result is_valid = IsVibrationHandleValid(handle);
+ if (is_valid.IsError()) {
+ return is_valid;
+ }
+
+ for (std::size_t i = 0; i < list_size; i++) {
+ if (handle.device_index == vibration_device_list[i].device_index &&
+ handle.npad_id == vibration_device_list[i].npad_id &&
+ handle.npad_type == vibration_device_list[i].npad_type) {
+ return ResultSuccess;
+ }
+ }
+ if (list_size == vibration_device_list.size()) {
+ return ResultVibrationDeviceIndexOutOfRange;
+ }
+ const Result result = resource_manager->GetVibrationDevice(handle)->Activate();
+ if (result.IsError()) {
+ return result;
+ }
+ vibration_device_list[list_size++] = handle;
+ return ResultSuccess;
+ }
+
+ mutable std::mutex mutex;
+ std::size_t list_size{};
+ std::array<Core::HID::VibrationDeviceHandle, 0x100> vibration_device_list{};
std::shared_ptr<ResourceManager> resource_manager;
};
@@ -154,7 +184,7 @@ IHidServer::IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> r
{209, &IHidServer::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
{210, &IHidServer::EndPermitVibrationSession, "EndPermitVibrationSession"},
{211, &IHidServer::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"},
- {212, nullptr, "SendVibrationValueInBool"},
+ {212, &IHidServer::SendVibrationValueInBool, "SendVibrationValueInBool"},
{300, &IHidServer::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
{301, &IHidServer::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
{302, &IHidServer::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"},
@@ -785,8 +815,8 @@ void IHidServer::IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ct
bool is_firmware_available{};
auto controller = GetResourceManager()->GetNpad();
- controller->IsFirmwareUpdateAvailableForSixAxisSensor(parameters.sixaxis_handle,
- is_firmware_available);
+ controller->IsFirmwareUpdateAvailableForSixAxisSensor(
+ parameters.applet_resource_user_id, parameters.sixaxis_handle, is_firmware_available);
LOG_WARNING(
Service_HID,
@@ -924,8 +954,8 @@ void IHidServer::ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx)
const auto parameters{rp.PopRaw<Parameters>()};
auto controller = GetResourceManager()->GetNpad();
- const auto result =
- controller->ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle);
+ const auto result = controller->ResetIsSixAxisSensorDeviceNewlyAssigned(
+ parameters.applet_resource_user_id, parameters.sixaxis_handle);
LOG_WARNING(
Service_HID,
@@ -970,7 +1000,7 @@ void IHidServer::ActivateGesture(HLERequestContext& ctx) {
void IHidServer::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
- Core::HID::NpadStyleSet supported_styleset;
+ Core::HID::NpadStyleSet supported_style_set;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
@@ -978,13 +1008,25 @@ void IHidServer::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- GetResourceManager()->GetNpad()->SetSupportedStyleSet({parameters.supported_styleset});
+ LOG_DEBUG(Service_HID, "called, supported_style_set={}, applet_resource_user_id={}",
+ parameters.supported_style_set, parameters.applet_resource_user_id);
+
+ const auto npad = GetResourceManager()->GetNpad();
+ const Result result = npad->SetSupportedNpadStyleSet(parameters.applet_resource_user_id,
+ parameters.supported_style_set);
- LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}",
- parameters.supported_styleset, parameters.applet_resource_user_id);
+ if (result.IsSuccess()) {
+ Core::HID::NpadStyleTag style_tag{parameters.supported_style_set};
+ const auto revision = npad->GetRevision(parameters.applet_resource_user_id);
+
+ if (style_tag.palma != 0 && revision < NpadRevision::Revision3) {
+ // GetResourceManager()->GetPalma()->EnableBoostMode(parameters.applet_resource_user_id,
+ // true);
+ }
+ }
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::GetSupportedNpadStyleSet(HLERequestContext& ctx) {
@@ -993,19 +1035,31 @@ void IHidServer::GetSupportedNpadStyleSet(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ Core::HID::NpadStyleSet supported_style_set{};
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result =
+ npad->GetSupportedNpadStyleSet(applet_resource_user_id, supported_style_set);
+
IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.PushEnum(GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw);
+ rb.Push(result);
+ rb.PushEnum(supported_style_set);
}
void IHidServer::SetSupportedNpadIdType(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
-
- const auto result = GetResourceManager()->GetNpad()->SetSupportedNpadIdTypes(ctx.ReadBuffer());
+ const auto buffer = ctx.ReadBuffer();
+ const std::size_t elements = ctx.GetReadBufferNumElements<Core::HID::NpadIdType>();
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ std::vector<Core::HID::NpadIdType> supported_npad_list(elements);
+ memcpy(supported_npad_list.data(), buffer.data(), buffer.size());
+
+ const auto npad = GetResourceManager()->GetNpad();
+ const Result result =
+ npad->SetSupportedNpadIdType(applet_resource_user_id, supported_npad_list);
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
}
@@ -1018,7 +1072,7 @@ void IHidServer::ActivateNpad(HLERequestContext& ctx) {
auto npad = GetResourceManager()->GetNpad();
- // TODO: npad->SetRevision(applet_resource_user_id, NpadRevision::Revision0);
+ npad->SetRevision(applet_resource_user_id, NpadRevision::Revision0);
const Result result = npad->Activate(applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
@@ -1052,13 +1106,13 @@ void IHidServer::AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}",
parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown);
- // Games expect this event to be signaled after calling this function
- GetResourceManager()->GetNpad()->SignalStyleSetChangedEvent(parameters.npad_id);
+ Kernel::KReadableEvent* style_set_update_event;
+ const auto result = GetResourceManager()->GetNpad()->AcquireNpadStyleSetUpdateEventHandle(
+ parameters.applet_resource_user_id, &style_set_update_event, parameters.npad_id);
IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(ResultSuccess);
- rb.PushCopyObjects(
- GetResourceManager()->GetNpad()->GetStyleSetChangedEvent(parameters.npad_id));
+ rb.Push(result);
+ rb.PushCopyObjects(style_set_update_event);
}
void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
@@ -1073,7 +1127,7 @@ void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
auto controller = GetResourceManager()->GetNpad();
- controller->DisconnectNpad(parameters.npad_id);
+ controller->DisconnectNpad(parameters.applet_resource_user_id, parameters.npad_id);
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id);
@@ -1113,7 +1167,7 @@ void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
auto npad = GetResourceManager()->GetNpad();
- // TODO: npad->SetRevision(applet_resource_user_id, revision);
+ npad->SetRevision(parameters.applet_resource_user_id, parameters.revision);
const auto result = npad->Activate(parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
@@ -1125,13 +1179,19 @@ void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) {
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto hold_type{rp.PopEnum<NpadJoyHoldType>()};
- GetResourceManager()->GetNpad()->SetHoldType(hold_type);
-
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
applet_resource_user_id, hold_type);
+ if (hold_type != NpadJoyHoldType::Horizontal && hold_type != NpadJoyHoldType::Vertical) {
+ // This should crash console
+ ASSERT_MSG(false, "Invalid npad joy hold type");
+ }
+
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result = npad->SetNpadJoyHoldType(applet_resource_user_id, hold_type);
+
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::GetNpadJoyHoldType(HLERequestContext& ctx) {
@@ -1140,9 +1200,13 @@ void IHidServer::GetNpadJoyHoldType(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ NpadJoyHoldType hold_type{};
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result = npad->GetNpadJoyHoldType(applet_resource_user_id, hold_type);
+
IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
- rb.PushEnum(GetResourceManager()->GetNpad()->GetHoldType());
+ rb.Push(result);
+ rb.PushEnum(hold_type);
}
void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) {
@@ -1158,8 +1222,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx)
Core::HID::NpadIdType new_npad_id{};
auto controller = GetResourceManager()->GetNpad();
- controller->SetNpadMode(new_npad_id, parameters.npad_id, NpadJoyDeviceType::Left,
- NpadJoyAssignmentMode::Single);
+ controller->SetNpadMode(parameters.applet_resource_user_id, new_npad_id, parameters.npad_id,
+ NpadJoyDeviceType::Left, NpadJoyAssignmentMode::Single);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id);
@@ -1182,8 +1246,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) {
Core::HID::NpadIdType new_npad_id{};
auto controller = GetResourceManager()->GetNpad();
- controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
- NpadJoyAssignmentMode::Single);
+ controller->SetNpadMode(parameters.applet_resource_user_id, new_npad_id, parameters.npad_id,
+ parameters.npad_joy_device_type, NpadJoyAssignmentMode::Single);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
parameters.npad_id, parameters.applet_resource_user_id,
@@ -1206,7 +1270,8 @@ void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
Core::HID::NpadIdType new_npad_id{};
auto controller = GetResourceManager()->GetNpad();
- controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NpadJoyAssignmentMode::Dual);
+ controller->SetNpadMode(parameters.applet_resource_user_id, new_npad_id, parameters.npad_id, {},
+ NpadJoyAssignmentMode::Dual);
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id); // Spams a lot when controller applet is open
@@ -1222,7 +1287,8 @@ void IHidServer::MergeSingleJoyAsDualJoy(HLERequestContext& ctx) {
const auto applet_resource_user_id{rp.Pop<u64>()};
auto controller = GetResourceManager()->GetNpad();
- const auto result = controller->MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
+ const auto result =
+ controller->MergeSingleJoyAsDualJoy(applet_resource_user_id, npad_id_1, npad_id_2);
LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
npad_id_1, npad_id_2, applet_resource_user_id);
@@ -1235,10 +1301,10 @@ void IHidServer::StartLrAssignmentMode(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
- GetResourceManager()->GetNpad()->StartLRAssignmentMode();
-
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ GetResourceManager()->GetNpad()->StartLrAssignmentMode(applet_resource_user_id);
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
@@ -1247,10 +1313,10 @@ void IHidServer::StopLrAssignmentMode(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
- GetResourceManager()->GetNpad()->StopLRAssignmentMode();
-
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ GetResourceManager()->GetNpad()->StopLrAssignmentMode(applet_resource_user_id);
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
@@ -1260,13 +1326,23 @@ void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) {
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto activation_mode{rp.PopEnum<NpadHandheldActivationMode>()};
- GetResourceManager()->GetNpad()->SetNpadHandheldActivationMode(activation_mode);
-
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}",
applet_resource_user_id, activation_mode);
+ if (activation_mode >= NpadHandheldActivationMode::MaxActivationMode) {
+ // Console should crash here
+ ASSERT_MSG(false, "Activation mode should be always None, Single or Dual");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ return;
+ }
+
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result =
+ npad->SetNpadHandheldActivationMode(applet_resource_user_id, activation_mode);
+
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::GetNpadHandheldActivationMode(HLERequestContext& ctx) {
@@ -1275,9 +1351,14 @@ void IHidServer::GetNpadHandheldActivationMode(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ NpadHandheldActivationMode activation_mode{};
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result =
+ npad->GetNpadHandheldActivationMode(applet_resource_user_id, activation_mode);
+
IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
- rb.PushEnum(GetResourceManager()->GetNpad()->GetNpadHandheldActivationMode());
+ rb.Push(result);
+ rb.PushEnum(activation_mode);
}
void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) {
@@ -1286,12 +1367,12 @@ void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) {
const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
- auto controller = GetResourceManager()->GetNpad();
- const auto result = controller->SwapNpadAssignment(npad_id_1, npad_id_2);
-
LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
npad_id_1, npad_id_2, applet_resource_user_id);
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result = npad->SwapNpadAssignment(applet_resource_user_id, npad_id_1, npad_id_2);
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
}
@@ -1307,13 +1388,19 @@ void IHidServer::IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext&
const auto parameters{rp.PopRaw<Parameters>()};
- bool is_enabled = false;
- auto controller = GetResourceManager()->GetNpad();
- const auto result =
- controller->IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled);
+ LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
+ parameters.applet_resource_user_id);
- LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
- parameters.npad_id, parameters.applet_resource_user_id);
+ if (!IsNpadIdValid(parameters.npad_id)) {
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultInvalidNpadId);
+ return;
+ }
+
+ bool is_enabled{};
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result = npad->IsUnintendedHomeButtonInputProtectionEnabled(
+ is_enabled, parameters.applet_resource_user_id, parameters.npad_id);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(result);
@@ -1332,14 +1419,19 @@ void IHidServer::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ct
const auto parameters{rp.PopRaw<Parameters>()};
- auto controller = GetResourceManager()->GetNpad();
- const auto result = controller->SetUnintendedHomeButtonInputProtectionEnabled(
- parameters.is_enabled, parameters.npad_id);
-
- LOG_DEBUG(Service_HID,
- "(STUBBED) called, is_enabled={}, npad_id={}, applet_resource_user_id={}",
+ LOG_DEBUG(Service_HID, "called, is_enabled={}, npad_id={}, applet_resource_user_id={}",
parameters.is_enabled, parameters.npad_id, parameters.applet_resource_user_id);
+ if (!IsNpadIdValid(parameters.npad_id)) {
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultInvalidNpadId);
+ return;
+ }
+
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result = npad->EnableUnintendedHomeButtonInputProtection(
+ parameters.applet_resource_user_id, parameters.npad_id, parameters.is_enabled);
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
}
@@ -1359,8 +1451,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext
Core::HID::NpadIdType new_npad_id{};
auto controller = GetResourceManager()->GetNpad();
const auto is_reassigned =
- controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
- NpadJoyAssignmentMode::Single);
+ controller->SetNpadMode(parameters.applet_resource_user_id, new_npad_id, parameters.npad_id,
+ parameters.npad_joy_device_type, NpadJoyAssignmentMode::Single);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
parameters.npad_id, parameters.applet_resource_user_id,
@@ -1375,7 +1467,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext
void IHidServer::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
- bool analog_stick_use_center_clamp;
+ bool use_center_clamp;
INSERT_PADDING_BYTES_NOINIT(7);
u64 applet_resource_user_id;
};
@@ -1383,12 +1475,11 @@ void IHidServer::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- GetResourceManager()->GetNpad()->SetAnalogStickUseCenterClamp(
- parameters.analog_stick_use_center_clamp);
+ LOG_INFO(Service_HID, "called, use_center_clamp={}, applet_resource_user_id={}",
+ parameters.use_center_clamp, parameters.applet_resource_user_id);
- LOG_WARNING(Service_HID,
- "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}",
- parameters.analog_stick_use_center_clamp, parameters.applet_resource_user_id);
+ GetResourceManager()->GetNpad()->SetNpadAnalogStickUseCenterClamp(
+ parameters.applet_resource_user_id, parameters.use_center_clamp);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@@ -1406,81 +1497,39 @@ void IHidServer::SetNpadCaptureButtonAssignment(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- LOG_WARNING(Service_HID,
- "(STUBBED) called, npad_styleset={}, applet_resource_user_id={}, button={}",
- parameters.npad_styleset, parameters.applet_resource_user_id, parameters.button);
+ LOG_INFO(Service_HID, "called, npad_styleset={}, applet_resource_user_id={}, button={}",
+ parameters.npad_styleset, parameters.applet_resource_user_id, parameters.button);
+
+ const auto result = GetResourceManager()->GetNpad()->SetNpadCaptureButtonAssignment(
+ parameters.applet_resource_user_id, parameters.npad_styleset, parameters.button);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::ClearNpadCaptureButtonAssignment(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
- LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
- applet_resource_user_id);
+ LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ const auto result =
+ GetResourceManager()->GetNpad()->ClearNpadCaptureButtonAssignment(applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
- const auto controller = GetResourceManager()->GetNpad();
-
- Core::HID::VibrationDeviceInfo vibration_device_info;
- bool check_device_index = false;
-
- switch (vibration_device_handle.npad_type) {
- case Core::HID::NpadStyleIndex::ProController:
- case Core::HID::NpadStyleIndex::Handheld:
- case Core::HID::NpadStyleIndex::JoyconDual:
- case Core::HID::NpadStyleIndex::JoyconLeft:
- case Core::HID::NpadStyleIndex::JoyconRight:
- vibration_device_info.type = Core::HID::VibrationDeviceType::LinearResonantActuator;
- check_device_index = true;
- break;
- case Core::HID::NpadStyleIndex::GameCube:
- vibration_device_info.type = Core::HID::VibrationDeviceType::GcErm;
- break;
- case Core::HID::NpadStyleIndex::N64:
- vibration_device_info.type = Core::HID::VibrationDeviceType::N64;
- break;
- default:
- vibration_device_info.type = Core::HID::VibrationDeviceType::Unknown;
- break;
- }
-
- vibration_device_info.position = Core::HID::VibrationDevicePosition::None;
- if (check_device_index) {
- switch (vibration_device_handle.device_index) {
- case Core::HID::DeviceIndex::Left:
- vibration_device_info.position = Core::HID::VibrationDevicePosition::Left;
- break;
- case Core::HID::DeviceIndex::Right:
- vibration_device_info.position = Core::HID::VibrationDevicePosition::Right;
- break;
- case Core::HID::DeviceIndex::None:
- default:
- ASSERT_MSG(false, "DeviceIndex should never be None!");
- break;
- }
- }
-
- LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}",
- vibration_device_info.type, vibration_device_info.position);
- const auto result = IsVibrationHandleValid(vibration_device_handle);
- if (result.IsError()) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
+ Core::HID::VibrationDeviceInfo vibration_device_info{};
+ const auto result = GetResourceManager()->GetVibrationDeviceInfo(vibration_device_info,
+ vibration_device_handle);
IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
+ rb.Push(result);
rb.PushRaw(vibration_device_info);
}
@@ -1496,15 +1545,16 @@ void IHidServer::SendVibrationValue(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle,
- parameters.vibration_value);
-
LOG_DEBUG(Service_HID,
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
parameters.vibration_device_handle.npad_type,
parameters.vibration_device_handle.npad_id,
parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
+ GetResourceManager()->SendVibrationValue(parameters.applet_resource_user_id,
+ parameters.vibration_device_handle,
+ parameters.vibration_value);
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
@@ -1526,10 +1576,28 @@ void IHidServer::GetActualVibrationValue(HLERequestContext& ctx) {
parameters.vibration_device_handle.npad_id,
parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
+ bool has_active_aruid{};
+ NpadVibrationDevice* device{nullptr};
+ Core::HID::VibrationValue vibration_value{};
+ Result result = GetResourceManager()->IsVibrationAruidActive(parameters.applet_resource_user_id,
+ has_active_aruid);
+
+ if (result.IsSuccess() && has_active_aruid) {
+ result = IsVibrationHandleValid(parameters.vibration_device_handle);
+ }
+ if (result.IsSuccess() && has_active_aruid) {
+ device = GetResourceManager()->GetNSVibrationDevice(parameters.vibration_device_handle);
+ }
+ if (device != nullptr) {
+ result = device->GetActualVibrationValue(vibration_value);
+ }
+ if (result.IsError()) {
+ vibration_value = Core::HID::DEFAULT_VIBRATION_VALUE;
+ }
+
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(ResultSuccess);
- rb.PushRaw(
- GetResourceManager()->GetNpad()->GetLastVibration(parameters.vibration_device_handle));
+ rb.PushRaw(vibration_value);
}
void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {
@@ -1544,25 +1612,27 @@ void IHidServer::PermitVibration(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto can_vibrate{rp.Pop<bool>()};
- // nnSDK saves this value as a float. Since it can only be 1.0f or 0.0f we simplify this value
- // by converting it to a bool
- Settings::values.vibration_enabled.SetValue(can_vibrate);
-
LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
+ const auto result =
+ GetResourceManager()->GetNpad()->GetVibrationHandler()->SetVibrationMasterVolume(
+ can_vibrate ? 1.0f : 0.0f);
+
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called");
- // nnSDK checks if a float is greater than zero. We return the bool we stored earlier
- const auto is_enabled = Settings::values.vibration_enabled.GetValue();
+ f32 master_volume{};
+ const auto result =
+ GetResourceManager()->GetNpad()->GetVibrationHandler()->GetVibrationMasterVolume(
+ master_volume);
IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(is_enabled);
+ rb.Push(result);
+ rb.Push(master_volume > 0.0f);
}
void IHidServer::SendVibrationValues(HLERequestContext& ctx) {
@@ -1580,12 +1650,22 @@ void IHidServer::SendVibrationValues(HLERequestContext& ctx) {
auto vibration_values = std::span(
reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count);
- GetResourceManager()->GetNpad()->VibrateControllers(vibration_device_handles, vibration_values);
-
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ Result result = ResultSuccess;
+ if (handle_count != vibration_count) {
+ result = ResultVibrationArraySizeMismatch;
+ }
+
+ for (std::size_t i = 0; i < handle_count; i++) {
+ if (result.IsSuccess()) {
+ result = GetResourceManager()->SendVibrationValue(
+ applet_resource_user_id, vibration_device_handles[i], vibration_values[i]);
+ }
+ }
+
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) {
@@ -1600,43 +1680,6 @@ void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- /**
- * Note: This uses yuzu-specific behavior such that the StopHard command produces
- * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined below,
- * in order to differentiate between Stop and StopHard commands.
- * This is done to reuse the controller vibration functions made for regular controllers.
- */
- const auto vibration_value = [parameters] {
- switch (parameters.gc_erm_command) {
- case Core::HID::VibrationGcErmCommand::Stop:
- return Core::HID::VibrationValue{
- .low_amplitude = 0.0f,
- .low_frequency = 160.0f,
- .high_amplitude = 0.0f,
- .high_frequency = 320.0f,
- };
- case Core::HID::VibrationGcErmCommand::Start:
- return Core::HID::VibrationValue{
- .low_amplitude = 1.0f,
- .low_frequency = 160.0f,
- .high_amplitude = 1.0f,
- .high_frequency = 320.0f,
- };
- case Core::HID::VibrationGcErmCommand::StopHard:
- return Core::HID::VibrationValue{
- .low_amplitude = 0.0f,
- .low_frequency = 0.0f,
- .high_amplitude = 0.0f,
- .high_frequency = 0.0f,
- };
- default:
- return Core::HID::DEFAULT_VIBRATION_VALUE;
- }
- }();
-
- GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle,
- vibration_value);
-
LOG_DEBUG(Service_HID,
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, "
"gc_erm_command={}",
@@ -1645,8 +1688,23 @@ void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) {
parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id,
parameters.gc_erm_command);
+ bool has_active_aruid{};
+ NpadGcVibrationDevice* gc_device{nullptr};
+ Result result = GetResourceManager()->IsVibrationAruidActive(parameters.applet_resource_user_id,
+ has_active_aruid);
+
+ if (result.IsSuccess() && has_active_aruid) {
+ result = IsVibrationHandleValid(parameters.vibration_device_handle);
+ }
+ if (result.IsSuccess() && has_active_aruid) {
+ gc_device = GetResourceManager()->GetGcVibrationDevice(parameters.vibration_device_handle);
+ }
+ if (gc_device != nullptr) {
+ result = gc_device->SendVibrationGcErmCommand(parameters.gc_erm_command);
+ }
+
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {
@@ -1659,33 +1717,31 @@ void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- const auto last_vibration =
- GetResourceManager()->GetNpad()->GetLastVibration(parameters.vibration_device_handle);
-
- const auto gc_erm_command = [last_vibration] {
- if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) {
- return Core::HID::VibrationGcErmCommand::Start;
- }
-
- /**
- * Note: This uses yuzu-specific behavior such that the StopHard command produces
- * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined in the HID function
- * SendVibrationGcErmCommand, in order to differentiate between Stop and StopHard commands.
- * This is done to reuse the controller vibration functions made for regular controllers.
- */
- if (last_vibration.low_frequency == 0.0f && last_vibration.high_frequency == 0.0f) {
- return Core::HID::VibrationGcErmCommand::StopHard;
- }
-
- return Core::HID::VibrationGcErmCommand::Stop;
- }();
-
LOG_DEBUG(Service_HID,
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
parameters.vibration_device_handle.npad_type,
parameters.vibration_device_handle.npad_id,
parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
+ bool has_active_aruid{};
+ NpadGcVibrationDevice* gc_device{nullptr};
+ Core::HID::VibrationGcErmCommand gc_erm_command{};
+ Result result = GetResourceManager()->IsVibrationAruidActive(parameters.applet_resource_user_id,
+ has_active_aruid);
+
+ if (result.IsSuccess() && has_active_aruid) {
+ result = IsVibrationHandleValid(parameters.vibration_device_handle);
+ }
+ if (result.IsSuccess() && has_active_aruid) {
+ gc_device = GetResourceManager()->GetGcVibrationDevice(parameters.vibration_device_handle);
+ }
+ if (gc_device != nullptr) {
+ result = gc_device->GetActualVibrationGcErmCommand(gc_erm_command);
+ }
+ if (result.IsError()) {
+ gc_erm_command = Core::HID::VibrationGcErmCommand::Stop;
+ }
+
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.PushEnum(gc_erm_command);
@@ -1695,21 +1751,24 @@ void IHidServer::BeginPermitVibrationSession(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
- GetResourceManager()->GetNpad()->SetPermitVibrationSession(true);
-
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ const auto result =
+ GetResourceManager()->GetNpad()->GetVibrationHandler()->BeginPermitVibrationSession(
+ applet_resource_user_id);
+
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::EndPermitVibrationSession(HLERequestContext& ctx) {
- GetResourceManager()->GetNpad()->SetPermitVibrationSession(false);
-
LOG_DEBUG(Service_HID, "called");
+ const auto result =
+ GetResourceManager()->GetNpad()->GetVibrationHandler()->EndPermitVibrationSession();
+
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::IsVibrationDeviceMounted(HLERequestContext& ctx) {
@@ -1729,10 +1788,61 @@ void IHidServer::IsVibrationDeviceMounted(HLERequestContext& ctx) {
parameters.vibration_device_handle.npad_id,
parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
+ bool is_mounted{};
+ NpadVibrationBase* device{nullptr};
+ Result result = IsVibrationHandleValid(parameters.vibration_device_handle);
+
+ if (result.IsSuccess()) {
+ device = GetResourceManager()->GetVibrationDevice(parameters.vibration_device_handle);
+ }
+
+ if (device != nullptr) {
+ is_mounted = device->IsVibrationMounted();
+ }
+
IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(GetResourceManager()->GetNpad()->IsVibrationDeviceMounted(
- parameters.vibration_device_handle));
+ rb.Push(result);
+ rb.Push(is_mounted);
+}
+
+void IHidServer::SendVibrationValueInBool(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::VibrationDeviceHandle vibration_device_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ bool is_vibrating;
+ };
+ static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, "
+ "is_vibrating={}",
+ parameters.vibration_device_handle.npad_type,
+ parameters.vibration_device_handle.npad_id,
+ parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id,
+ parameters.is_vibrating);
+
+ bool has_active_aruid{};
+ NpadN64VibrationDevice* n64_device{nullptr};
+ Result result = GetResourceManager()->IsVibrationAruidActive(parameters.applet_resource_user_id,
+ has_active_aruid);
+
+ if (result.IsSuccess() && has_active_aruid) {
+ result = IsVibrationHandleValid(parameters.vibration_device_handle);
+ }
+ if (result.IsSuccess() && has_active_aruid) {
+ n64_device =
+ GetResourceManager()->GetN64VibrationDevice(parameters.vibration_device_handle);
+ }
+ if (n64_device != nullptr) {
+ result = n64_device->SendValueInBool(parameters.is_vibrating);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
}
void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {
@@ -2315,10 +2425,10 @@ void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) {
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto communication_mode{rp.PopEnum<NpadCommunicationMode>()};
- GetResourceManager()->GetNpad()->SetNpadCommunicationMode(communication_mode);
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, communication_mode={}",
+ applet_resource_user_id, communication_mode);
- LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, communication_mode={}",
- applet_resource_user_id, communication_mode);
+ // This function has been stubbed since 2.0.0+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@@ -2326,12 +2436,15 @@ void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) {
void IHidServer::GetNpadCommunicationMode(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
- LOG_WARNING(Service_HID, "(STUBBED) called");
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ // This function has been stubbed since 2.0.0+
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
- rb.PushEnum(GetResourceManager()->GetNpad()->GetNpadCommunicationMode());
+ rb.PushEnum(NpadCommunicationMode::Default);
}
void IHidServer::SetTouchScreenConfiguration(HLERequestContext& ctx) {