Enough vibration for today

This commit is contained in:
Narr the Reg 2023-08-19 22:34:39 -06:00
parent b7c7505aca
commit 3f5d6c115f
10 changed files with 460 additions and 22 deletions

View File

@ -14,6 +14,8 @@ constexpr Result ResultVibrationInvalidStyleIndex{ErrorModule::HID, 122};
constexpr Result ResultVibrationInvalidNpadId{ErrorModule::HID, 123};
constexpr Result ResultVibrationVolumeOutOfRange{ErrorModule::HID, 126};
constexpr Result ResultVibrationDeviceIndexOutOfRange{ErrorModule::HID, 124};
constexpr Result ResultVibrationArraySizeMismatch{ErrorModule::HID, 131};
constexpr Result ResultInvalidSixAxisFusionRange{ErrorModule::HID, 423};
constexpr Result ResultNpadIsDualJoycon{ErrorModule::HID, 601};
constexpr Result ResultNpadIsSameType{ErrorModule::HID, 602};

View File

@ -35,6 +35,30 @@ IAppletResource::IAppletResource(Core::System& system_)
IAppletResource::~IAppletResource() = default;
IActiveVibrationDeviceList::IActiveVibrationDeviceList(Core::System& system_,
std::shared_ptr<ResourceManager> resource)
: ServiceFramework{system_, "IActiveVibrationDeviceList"}, resource_manager(resource) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IActiveVibrationDeviceList::InitializeVibrationDevice, "InitializeVibrationDevice"},
};
// clang-format on
RegisterHandlers(functions);
}
void IActiveVibrationDeviceList::InitializeVibrationDevice(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto vibration_device_handle{rp.PopRaw<VibrationDeviceHandle>()};
LOG_DEBUG(Service_HID, "called, npad_style_index={}, npad_id={}, device_index={}",
vibration_device_handle.npad_style_index, vibration_device_handle.npad_id,
vibration_device_handle.device_index);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called");
@ -130,7 +154,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"},
@ -1751,12 +1775,120 @@ void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) {
rb.PushRaw(device_info);
}
void IHidServer::SendVibrationValue(HLERequestContext& ctx) {}
void IHidServer::GetActualVibrationValue(HLERequestContext& ctx) {}
void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {}
void IHidServer::PermitVibration(HLERequestContext& ctx) {}
void IHidServer::SendVibrationValue(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
VibrationDeviceHandle handle;
VibrationValue vibration_value;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
LOG_DEBUG(
Service_HID,
"called, npad_style_index={}, npad_id={}, device_index={}, applet_resource_user_id={}",
parameters.handle.npad_style_index, parameters.handle.npad_id,
parameters.handle.device_index, parameters.applet_resource_user_id);
const Result result = SendVibrationValueImpl(parameters.applet_resource_user_id,
parameters.handle, parameters.vibration_value);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
}
Result IHidServer::SendVibrationValueImpl(const u64 aruid, const VibrationDeviceHandle& handle,
const VibrationValue& vibration_value) {
bool is_enabled{};
const Result result = GetResourceManager()->CheckVibrationAvailability(aruid, is_enabled);
if (result.IsError()) {
return result;
}
if (!is_enabled) {
return ResultSuccess;
}
const Result handle_result = IsVibrationHandleValid(handle);
if (handle_result.IsError()) {
return handle_result;
}
const auto& vibration = GetResourceManager()->GetVibration(handle);
if (vibration == nullptr) {
return ResultSuccess;
}
vibration->SendVibrationValue(vibration_value);
return ResultSuccess;
}
void IHidServer::GetActualVibrationValue(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
VibrationDeviceHandle handle;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_DEBUG(
Service_HID,
"called, npad_style_index={}, npad_id={}, device_index={}, applet_resource_user_id={}",
parameters.handle.npad_style_index, parameters.handle.npad_id,
parameters.handle.device_index, parameters.applet_resource_user_id);
bool is_enabled{};
Result result = GetResourceManager()->CheckVibrationAvailability(
parameters.applet_resource_user_id, is_enabled);
if (result.IsError()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
return;
}
VibrationValue vibration_value{
.low_amplitude = 0.0f,
.low_frequency = 160.0f,
.high_amplitude = 0.0f,
.high_frequency = 320.0f,
};
if (is_enabled) {
const Result handle_result = IsVibrationHandleValid(parameters.handle);
if (handle_result.IsError()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(handle_result);
return;
}
const auto& vibration = GetResourceManager()->GetVibration(parameters.handle);
if (vibration != nullptr) {
vibration->GetActualVibrationValue(vibration_value);
}
}
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(ResultSuccess);
rb.PushRaw(vibration_value);
}
void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IActiveVibrationDeviceList>(system, GetResourceManager());
}
void IHidServer::PermitVibration(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto can_vibrate{rp.Pop<bool>()};
@ -1769,12 +1901,208 @@ void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) {
rb.Push(result);
}
void IHidServer::SendVibrationValues(HLERequestContext& ctx) {}
void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) {}
void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {}
void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) {
float vibration_volume{};
const Result result =
GetResourceManager()->GetNpad()->GetVibrationMasterVolume(vibration_volume);
bool can_vibrate{};
if (result.IsSuccess()) {
can_vibrate = vibration_volume > 0.0f;
}
LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(result);
rb.Push<u8>(can_vibrate);
}
void IHidServer::SendVibrationValues(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto handle_data = ctx.ReadBuffer(0);
const auto handle_count = ctx.GetReadBufferNumElements<VibrationDeviceHandle>(0);
const auto vibration_data = ctx.ReadBuffer(1);
const auto vibration_count = ctx.GetReadBufferNumElements<VibrationValue>(1);
auto vibration_device_handles =
std::span(reinterpret_cast<const VibrationDeviceHandle*>(handle_data.data()), handle_count);
auto vibration_values =
std::span(reinterpret_cast<const VibrationValue*>(vibration_data.data()), vibration_count);
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 && result.IsSuccess(); ++i) {
result = SendVibrationValueImpl(applet_resource_user_id, vibration_device_handles[i],
vibration_values[i]);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
}
void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
VibrationDeviceHandle handle;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
VibrationGcErmCommand gc_erm_command;
};
static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_DEBUG(Service_HID,
"called, npad_style_index={}, npad_id={}, device_index={}, "
"applet_resource_user_id={}, gc_erm_command={}",
parameters.handle.npad_style_index, parameters.handle.npad_id,
parameters.handle.device_index, parameters.applet_resource_user_id,
parameters.gc_erm_command);
bool is_enabled{};
Result result = GetResourceManager()->CheckVibrationAvailability(
parameters.applet_resource_user_id, is_enabled);
IPC::ResponseBuilder rb{ctx, 2};
if (result.IsError()) {
rb.Push(result);
return;
}
if (!is_enabled) {
rb.Push(ResultSuccess);
return;
}
const Result handle_result = IsVibrationHandleValid(parameters.handle);
if (handle_result.IsError()) {
rb.Push(handle_result);
return;
}
const auto& vibration = GetResourceManager()->GetGCVibration(parameters.handle);
if (vibration == nullptr) {
rb.Push(ResultSuccess);
return;
}
vibration->SendVibrationValue(parameters.gc_erm_command);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
VibrationDeviceHandle handle;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_DEBUG(
Service_HID,
"called, npad_style_index={}, npad_id={}, device_index={}, applet_resource_user_id={}",
parameters.handle.npad_style_index, parameters.handle.npad_id,
parameters.handle.device_index, parameters.applet_resource_user_id);
bool is_enabled{};
Result result = GetResourceManager()->CheckVibrationAvailability(
parameters.applet_resource_user_id, is_enabled);
if (result.IsError()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
return;
}
VibrationGcErmCommand vibration_command{VibrationGcErmCommand::Stop};
if (is_enabled) {
const Result handle_result = IsVibrationHandleValid(parameters.handle);
if (handle_result.IsError()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(handle_result);
return;
}
const auto& vibration = GetResourceManager()->GetGCVibration(parameters.handle);
if (vibration != nullptr) {
vibration->GetActualVibrationValue(vibration_value);
}
}
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.PushEnum(vibration_command);
}
void IHidServer::BeginPermitVibrationSession(HLERequestContext& ctx) {}
void IHidServer::EndPermitVibrationSession(HLERequestContext& ctx) {}
void IHidServer::IsVibrationDeviceMounted(HLERequestContext& ctx) {}
void IHidServer::SendVibrationValueInBool(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
VibrationDeviceHandle handle;
bool should_vibrate;
INSERT_PADDING_BYTES_NOINIT(3);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_DEBUG(Service_HID,
"called, npad_style_index={}, npad_id={}, device_index={}, "
"applet_resource_user_id={}, should_vibrate={}",
parameters.handle.npad_style_index, parameters.handle.npad_id,
parameters.handle.device_index, parameters.applet_resource_user_id,
parameters.should_vibrate);
bool is_enabled{};
Result result = GetResourceManager()->CheckVibrationAvailability(
parameters.applet_resource_user_id, is_enabled);
IPC::ResponseBuilder rb{ctx, 2};
if (result.IsError()) {
rb.Push(result);
return;
}
if (!is_enabled) {
rb.Push(ResultSuccess);
return;
}
const Result handle_result = IsVibrationHandleValid(parameters.handle);
if (handle_result.IsError()) {
rb.Push(handle_result);
return;
}
const auto& vibration = GetResourceManager()->GetN64Vibration(parameters.handle);
if (vibration == nullptr) {
rb.Push(ResultSuccess);
return;
}
vibration->SendVibrationValue(parameters.should_vibrate);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {}
void IHidServer::StartConsoleSixAxisSensor(HLERequestContext& ctx) {}
void IHidServer::StopConsoleSixAxisSensor(HLERequestContext& ctx) {}

View File

@ -21,6 +21,18 @@ private:
void GetSharedMemoryHandle(HLERequestContext& ctx);
};
class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
public:
explicit IActiveVibrationDeviceList(Core::System& system_,
std::shared_ptr<ResourceManager> resource);
~IActiveVibrationDeviceList() override;
private:
void InitializeVibrationDevice(HLERequestContext& ctx);
std::shared_ptr<ResourceManager> resource_manager = nullptr;
};
class IHidServer final : public ServiceFramework<IHidServer> {
public:
explicit IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
@ -109,6 +121,7 @@ private:
void BeginPermitVibrationSession(HLERequestContext& ctx);
void EndPermitVibrationSession(HLERequestContext& ctx);
void IsVibrationDeviceMounted(HLERequestContext& ctx);
void SendVibrationValueInBool(HLERequestContext& ctx);
void ActivateConsoleSixAxisSensor(HLERequestContext& ctx);
void StartConsoleSixAxisSensor(HLERequestContext& ctx);
void StopConsoleSixAxisSensor(HLERequestContext& ctx);
@ -154,6 +167,9 @@ private:
void SetTouchScreenConfiguration(HLERequestContext& ctx);
void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx);
Result SendVibrationValueImpl(const u64 aruid, const VibrationDeviceHandle& handle,
const VibrationValue& value);
bool IsDeviceManaged();
void InitializeDebugSettings();
std::shared_ptr<ResourceManager> GetResourceManager();

View File

@ -330,14 +330,11 @@ void IHidSystemServer::SetVibrationMasterVolume(HLERequestContext& ctx) {
}
void IHidSystemServer::GetVibrationMasterVolume(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto can_vibrate{rp.Pop<bool>()};
LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
float volume{};
const Result result = GetResourceManager()->GetNpad()->GetVibrationMasterVolume(volume);
LOG_DEBUG(Service_HID, "called, volume={}", volume);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(result);
rb.Push(volume);

View File

@ -774,7 +774,7 @@ static_assert(sizeof(SixAxisSensorIcInformation) == 0xC8,
// This is nn::hid::VibrationDeviceHandle
struct VibrationDeviceHandle {
NpadStyleIndex npad_type{NpadStyleIndex::None};
NpadStyleIndex npad_style_index{NpadStyleIndex::None};
u8 npad_id{};
DeviceIndex device_index{DeviceIndex::None};
INSERT_PADDING_BYTES_NOINIT(1);

View File

@ -3,6 +3,7 @@
#pragma once
#include "core/hle/service/hid/hid_result.h"
#include "core/hle/service/hid/hid_types.h"
namespace Service::HID {
@ -25,6 +26,34 @@ constexpr bool IsNpadIdValid(const NpadIdType npad_id) {
}
}
Result IsVibrationHandleValid(const VibrationDeviceHandle& handle) const {
switch (handle.npad_style_index) {
case NpadStyleIndex::FullKey:
case NpadStyleIndex::Handheld:
case NpadStyleIndex::JoyconDual:
case NpadStyleIndex::JoyconLeft:
case NpadStyleIndex::JoyconRight:
case NpadStyleIndex::GameCube:
case NpadStyleIndex::N64:
case NpadStyleIndex::SystemExt:
case NpadStyleIndex::System:
// These support vibration
break;
default:
return ResultVibrationInvalidStyleIndex;
}
if (IsNpadIdValid(static_cast<NpadIdType>(handle.npad_id))) {
return ResultVibrationInvalidNpadId;
}
if (handle.device_index >= DeviceIndex::MaxDeviceInfo) {
return ResultVibrationDeviceIndexOutOfRange;
}
return ResultSuccess;
}
/// Converts a NpadIdType to an array index.
constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
switch (npad_id_type) {

View File

@ -84,12 +84,13 @@ void ResourceManager::Initialize() {
sixaxis = std::make_shared<SixAxis>();
touch_screen = std::make_shared<TouchScreen>();
}
Result ResourceManager::GetVibrationDeviceInfo(VibrationDeviceInfo& out_device_info,
VibrationDeviceHandle handle) const {
const VibrationDeviceHandle& handle) const {
out_device_info.type = VibrationDeviceType::Unknown;
out_device_info.position = VibrationDevicePosition::None;
switch (handle.npad_type) {
switch (handle.npad_style_index) {
case NpadStyleIndex::FullKey:
case NpadStyleIndex::Handheld:
case NpadStyleIndex::JoyconDual:
@ -114,7 +115,7 @@ Result ResourceManager::GetVibrationDeviceInfo(VibrationDeviceInfo& out_device_i
}
bool check_device_index = false;
switch (handle.npad_type) {
switch (handle.npad_style_index) {
case NpadStyleIndex::FullKey:
case NpadStyleIndex::Handheld:
case NpadStyleIndex::JoyconDual:
@ -152,6 +153,19 @@ Result ResourceManager::GetVibrationDeviceInfo(VibrationDeviceInfo& out_device_i
return ResultSuccess;
}
Result ResourceManager::CheckVibrationAvailability(const u64 aruid, bool& out_is_enabled) const {
// TODO: Replace this with actual active aruid
u64 active_aruid = aruid;
if (aruid != 0 && active_aruid != aruid) {
out_is_enabled = false;
return ResultSuccess;
}
out_is_enabled = true;
return ResultSuccess;
}
std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() {
return debug_pad;
}
@ -184,4 +198,46 @@ std::shared_ptr<TouchScreen> ResourceManager::GetTouchScreen() {
return touch_screen;
}
std::shared_ptr<Vibration> ResourceManager::GetVibration(const VibrationDeviceHandle& handle) {
if (IsVibrationHandleValid(handle).IsError()) {
return nullptr;
}
switch (handle.npad_style_index) {
case NpadStyleIndex::FullKey:
case NpadStyleIndex::Handheld:
case NpadStyleIndex::JoyconDual:
case NpadStyleIndex::JoyconLeft:
case NpadStyleIndex::JoyconRight:
case NpadStyleIndex::SystemExt:
case NpadStyleIndex::System:
// These support vibration
break;
default:
return nullptr;
}
return GetNpad()
->GetAbstractNpad(static_cast<NpadIdType>(handle.npad_id))
->GetVibration(handle.device_index);
}
std::shared_ptr<Vibration> ResourceManager::GetGCVibration(const VibrationDeviceHandle& handle) {
if (IsVibrationHandleValid(handle).IsError()) {
return nullptr;
}
if (handle.npad_style_index != NpadStyleIndex::GameCube) {
return nullptr;
}
return GetNpad()->GetAbstractNpad(static_cast<NpadIdType>(handle.npad_id))->GetGcVibration();
}
std::shared_ptr<Vibration> ResourceManager::GetN64Vibration(const VibrationDeviceHandle& handle) {
if (IsVibrationHandleValid(handle).IsError()) {
return nullptr;
}
if (handle.npad_style_index != NpadStyleIndex::N64) {
return nullptr;
}
return GetNpad()->GetAbstractNpad(static_cast<NpadIdType>(handle.npad_id))->GetN64Vibration();
}
} // namespace Service::HID

View File

@ -34,7 +34,8 @@ public:
void Initialize();
Result GetVibrationDeviceInfo(VibrationDeviceInfo& out_device_info,
VibrationDeviceHandle handle) const;
const VibrationDeviceHandle& handle) const;
Result CheckVibrationAvailability(const u64 aruid, bool& out_is_enabled) const;
std::shared_ptr<DebugPad> GetDebugPad();
std::shared_ptr<Gesture> GetGesture();
@ -44,6 +45,9 @@ public:
std::shared_ptr<Palma> GetPalma();
std::shared_ptr<SixAxis> GetSixAxis();
std::shared_ptr<TouchScreen> GetTouchScreen();
std::shared_ptr<Vibration> GetVibration(const VibrationDeviceHandle& handle);
std::shared_ptr<Vibration> GetGCVibration(const VibrationDeviceHandle& handle);
std::shared_ptr<Vibration> GetN64Vibration(const VibrationDeviceHandle& handle);
std::shared_ptr<DebugPad> debug_pad = nullptr;
std::shared_ptr<Gesture> gesture = nullptr;
@ -53,6 +57,7 @@ public:
std::shared_ptr<Palma> palma = nullptr;
std::shared_ptr<SixAxis> sixaxis = nullptr;
std::shared_ptr<TouchScreen> touch_screen = nullptr;
std::shared_ptr<Vibration> vibration = nullptr;
KernelHelpers::ServiceContext service_context;
};

View File

@ -837,9 +837,8 @@ Result Npad::SetVibrationMasterVolume(const float volume) {
Result Npad::GetVibrationMasterVolume(float& out_volume) const {
// std::scoped_lock lock{external_mutex};
float current_volume{}; // nn::settings::detail::GetVibrationMasterVolume()
current_volume = vibration_master_volume; // TODO: Replace this with setting
// nn::settings::detail::GetVibrationMasterVolume()
float current_volume{vibration_master_volume};
if (current_volume < 0.0f || current_volume > 1.0f) {
return ResultVibrationVolumeOutOfRange;
@ -850,6 +849,10 @@ Result Npad::GetVibrationMasterVolume(float& out_volume) const {
return ResultSuccess;
}
std::shared_ptr<AbstractNpadState> Npad::GetAbstractNpad(const NpadIdType npad_id) {
return abstract_npad_state[NpadIdTypeToIndex(npad_id)];
}
void Npad::UpdateSupportedNpadIdType() {
// Set some u64
// Call DisconnectAbstracPads(u64)

View File

@ -143,6 +143,8 @@ public:
Result SetVibrationMasterVolume(const float volume);
Result GetVibrationMasterVolume(float& out_volume) const;
std::shared_ptr<AbstractNpadState> GetAbstractNpad(const NpadIdType npad_id);
private:
// Interface implementations
Result SetSupportedNpadIdTypeImpl(const u64 aruid, std::span<const NpadIdType> list);