Enough vibration for today
This commit is contained in:
parent
b7c7505aca
commit
3f5d6c115f
|
@ -14,6 +14,8 @@ constexpr Result ResultVibrationInvalidStyleIndex{ErrorModule::HID, 122};
|
||||||
constexpr Result ResultVibrationInvalidNpadId{ErrorModule::HID, 123};
|
constexpr Result ResultVibrationInvalidNpadId{ErrorModule::HID, 123};
|
||||||
constexpr Result ResultVibrationVolumeOutOfRange{ErrorModule::HID, 126};
|
constexpr Result ResultVibrationVolumeOutOfRange{ErrorModule::HID, 126};
|
||||||
constexpr Result ResultVibrationDeviceIndexOutOfRange{ErrorModule::HID, 124};
|
constexpr Result ResultVibrationDeviceIndexOutOfRange{ErrorModule::HID, 124};
|
||||||
|
constexpr Result ResultVibrationArraySizeMismatch{ErrorModule::HID, 131};
|
||||||
|
|
||||||
constexpr Result ResultInvalidSixAxisFusionRange{ErrorModule::HID, 423};
|
constexpr Result ResultInvalidSixAxisFusionRange{ErrorModule::HID, 423};
|
||||||
constexpr Result ResultNpadIsDualJoycon{ErrorModule::HID, 601};
|
constexpr Result ResultNpadIsDualJoycon{ErrorModule::HID, 601};
|
||||||
constexpr Result ResultNpadIsSameType{ErrorModule::HID, 602};
|
constexpr Result ResultNpadIsSameType{ErrorModule::HID, 602};
|
||||||
|
|
|
@ -35,6 +35,30 @@ IAppletResource::IAppletResource(Core::System& system_)
|
||||||
|
|
||||||
IAppletResource::~IAppletResource() = default;
|
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) {
|
void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_HID, "called");
|
LOG_DEBUG(Service_HID, "called");
|
||||||
|
|
||||||
|
@ -130,7 +154,7 @@ IHidServer::IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> r
|
||||||
{209, &IHidServer::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
|
{209, &IHidServer::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
|
||||||
{210, &IHidServer::EndPermitVibrationSession, "EndPermitVibrationSession"},
|
{210, &IHidServer::EndPermitVibrationSession, "EndPermitVibrationSession"},
|
||||||
{211, &IHidServer::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"},
|
{211, &IHidServer::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"},
|
||||||
{212, nullptr, "SendVibrationValueInBool"},
|
{212, &IHidServer::SendVibrationValueInBool, "SendVibrationValueInBool"},
|
||||||
{300, &IHidServer::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
|
{300, &IHidServer::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
|
||||||
{301, &IHidServer::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
|
{301, &IHidServer::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
|
||||||
{302, &IHidServer::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"},
|
{302, &IHidServer::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"},
|
||||||
|
@ -1751,12 +1775,120 @@ void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) {
|
||||||
rb.PushRaw(device_info);
|
rb.PushRaw(device_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IHidServer::SendVibrationValue(HLERequestContext& ctx) {}
|
void IHidServer::SendVibrationValue(HLERequestContext& ctx) {
|
||||||
void IHidServer::GetActualVibrationValue(HLERequestContext& ctx) {}
|
IPC::RequestParser rp{ctx};
|
||||||
void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {}
|
struct Parameters {
|
||||||
void IHidServer::PermitVibration(HLERequestContext& ctx) {}
|
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};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto can_vibrate{rp.Pop<bool>()};
|
const auto can_vibrate{rp.Pop<bool>()};
|
||||||
|
|
||||||
|
@ -1769,12 +1901,208 @@ void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) {
|
||||||
rb.Push(result);
|
rb.Push(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IHidServer::SendVibrationValues(HLERequestContext& ctx) {}
|
void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) {
|
||||||
void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) {}
|
float vibration_volume{};
|
||||||
void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {}
|
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::BeginPermitVibrationSession(HLERequestContext& ctx) {}
|
||||||
void IHidServer::EndPermitVibrationSession(HLERequestContext& ctx) {}
|
void IHidServer::EndPermitVibrationSession(HLERequestContext& ctx) {}
|
||||||
void IHidServer::IsVibrationDeviceMounted(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::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {}
|
||||||
void IHidServer::StartConsoleSixAxisSensor(HLERequestContext& ctx) {}
|
void IHidServer::StartConsoleSixAxisSensor(HLERequestContext& ctx) {}
|
||||||
void IHidServer::StopConsoleSixAxisSensor(HLERequestContext& ctx) {}
|
void IHidServer::StopConsoleSixAxisSensor(HLERequestContext& ctx) {}
|
||||||
|
|
|
@ -21,6 +21,18 @@ private:
|
||||||
void GetSharedMemoryHandle(HLERequestContext& ctx);
|
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> {
|
class IHidServer final : public ServiceFramework<IHidServer> {
|
||||||
public:
|
public:
|
||||||
explicit IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
|
explicit IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
|
||||||
|
@ -109,6 +121,7 @@ private:
|
||||||
void BeginPermitVibrationSession(HLERequestContext& ctx);
|
void BeginPermitVibrationSession(HLERequestContext& ctx);
|
||||||
void EndPermitVibrationSession(HLERequestContext& ctx);
|
void EndPermitVibrationSession(HLERequestContext& ctx);
|
||||||
void IsVibrationDeviceMounted(HLERequestContext& ctx);
|
void IsVibrationDeviceMounted(HLERequestContext& ctx);
|
||||||
|
void SendVibrationValueInBool(HLERequestContext& ctx);
|
||||||
void ActivateConsoleSixAxisSensor(HLERequestContext& ctx);
|
void ActivateConsoleSixAxisSensor(HLERequestContext& ctx);
|
||||||
void StartConsoleSixAxisSensor(HLERequestContext& ctx);
|
void StartConsoleSixAxisSensor(HLERequestContext& ctx);
|
||||||
void StopConsoleSixAxisSensor(HLERequestContext& ctx);
|
void StopConsoleSixAxisSensor(HLERequestContext& ctx);
|
||||||
|
@ -154,6 +167,9 @@ private:
|
||||||
void SetTouchScreenConfiguration(HLERequestContext& ctx);
|
void SetTouchScreenConfiguration(HLERequestContext& ctx);
|
||||||
void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx);
|
void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx);
|
||||||
|
|
||||||
|
Result SendVibrationValueImpl(const u64 aruid, const VibrationDeviceHandle& handle,
|
||||||
|
const VibrationValue& value);
|
||||||
|
|
||||||
bool IsDeviceManaged();
|
bool IsDeviceManaged();
|
||||||
void InitializeDebugSettings();
|
void InitializeDebugSettings();
|
||||||
std::shared_ptr<ResourceManager> GetResourceManager();
|
std::shared_ptr<ResourceManager> GetResourceManager();
|
||||||
|
|
|
@ -330,14 +330,11 @@ void IHidSystemServer::SetVibrationMasterVolume(HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void IHidSystemServer::GetVibrationMasterVolume(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{};
|
float volume{};
|
||||||
const Result result = GetResourceManager()->GetNpad()->GetVibrationMasterVolume(volume);
|
const Result result = GetResourceManager()->GetNpad()->GetVibrationMasterVolume(volume);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_HID, "called, volume={}", volume);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(result);
|
rb.Push(result);
|
||||||
rb.Push(volume);
|
rb.Push(volume);
|
||||||
|
|
|
@ -774,7 +774,7 @@ static_assert(sizeof(SixAxisSensorIcInformation) == 0xC8,
|
||||||
|
|
||||||
// This is nn::hid::VibrationDeviceHandle
|
// This is nn::hid::VibrationDeviceHandle
|
||||||
struct VibrationDeviceHandle {
|
struct VibrationDeviceHandle {
|
||||||
NpadStyleIndex npad_type{NpadStyleIndex::None};
|
NpadStyleIndex npad_style_index{NpadStyleIndex::None};
|
||||||
u8 npad_id{};
|
u8 npad_id{};
|
||||||
DeviceIndex device_index{DeviceIndex::None};
|
DeviceIndex device_index{DeviceIndex::None};
|
||||||
INSERT_PADDING_BYTES_NOINIT(1);
|
INSERT_PADDING_BYTES_NOINIT(1);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/hle/service/hid/hid_result.h"
|
||||||
#include "core/hle/service/hid/hid_types.h"
|
#include "core/hle/service/hid/hid_types.h"
|
||||||
|
|
||||||
namespace Service::HID {
|
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.
|
/// Converts a NpadIdType to an array index.
|
||||||
constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
|
constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
|
||||||
switch (npad_id_type) {
|
switch (npad_id_type) {
|
||||||
|
|
|
@ -84,12 +84,13 @@ void ResourceManager::Initialize() {
|
||||||
sixaxis = std::make_shared<SixAxis>();
|
sixaxis = std::make_shared<SixAxis>();
|
||||||
touch_screen = std::make_shared<TouchScreen>();
|
touch_screen = std::make_shared<TouchScreen>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ResourceManager::GetVibrationDeviceInfo(VibrationDeviceInfo& out_device_info,
|
Result ResourceManager::GetVibrationDeviceInfo(VibrationDeviceInfo& out_device_info,
|
||||||
VibrationDeviceHandle handle) const {
|
const VibrationDeviceHandle& handle) const {
|
||||||
out_device_info.type = VibrationDeviceType::Unknown;
|
out_device_info.type = VibrationDeviceType::Unknown;
|
||||||
out_device_info.position = VibrationDevicePosition::None;
|
out_device_info.position = VibrationDevicePosition::None;
|
||||||
|
|
||||||
switch (handle.npad_type) {
|
switch (handle.npad_style_index) {
|
||||||
case NpadStyleIndex::FullKey:
|
case NpadStyleIndex::FullKey:
|
||||||
case NpadStyleIndex::Handheld:
|
case NpadStyleIndex::Handheld:
|
||||||
case NpadStyleIndex::JoyconDual:
|
case NpadStyleIndex::JoyconDual:
|
||||||
|
@ -114,7 +115,7 @@ Result ResourceManager::GetVibrationDeviceInfo(VibrationDeviceInfo& out_device_i
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_device_index = false;
|
bool check_device_index = false;
|
||||||
switch (handle.npad_type) {
|
switch (handle.npad_style_index) {
|
||||||
case NpadStyleIndex::FullKey:
|
case NpadStyleIndex::FullKey:
|
||||||
case NpadStyleIndex::Handheld:
|
case NpadStyleIndex::Handheld:
|
||||||
case NpadStyleIndex::JoyconDual:
|
case NpadStyleIndex::JoyconDual:
|
||||||
|
@ -152,6 +153,19 @@ Result ResourceManager::GetVibrationDeviceInfo(VibrationDeviceInfo& out_device_i
|
||||||
return ResultSuccess;
|
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() {
|
std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() {
|
||||||
return debug_pad;
|
return debug_pad;
|
||||||
}
|
}
|
||||||
|
@ -184,4 +198,46 @@ std::shared_ptr<TouchScreen> ResourceManager::GetTouchScreen() {
|
||||||
return touch_screen;
|
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
|
} // namespace Service::HID
|
|
@ -34,7 +34,8 @@ public:
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
||||||
Result GetVibrationDeviceInfo(VibrationDeviceInfo& out_device_info,
|
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<DebugPad> GetDebugPad();
|
||||||
std::shared_ptr<Gesture> GetGesture();
|
std::shared_ptr<Gesture> GetGesture();
|
||||||
|
@ -44,6 +45,9 @@ public:
|
||||||
std::shared_ptr<Palma> GetPalma();
|
std::shared_ptr<Palma> GetPalma();
|
||||||
std::shared_ptr<SixAxis> GetSixAxis();
|
std::shared_ptr<SixAxis> GetSixAxis();
|
||||||
std::shared_ptr<TouchScreen> GetTouchScreen();
|
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<DebugPad> debug_pad = nullptr;
|
||||||
std::shared_ptr<Gesture> gesture = nullptr;
|
std::shared_ptr<Gesture> gesture = nullptr;
|
||||||
|
@ -53,6 +57,7 @@ public:
|
||||||
std::shared_ptr<Palma> palma = nullptr;
|
std::shared_ptr<Palma> palma = nullptr;
|
||||||
std::shared_ptr<SixAxis> sixaxis = nullptr;
|
std::shared_ptr<SixAxis> sixaxis = nullptr;
|
||||||
std::shared_ptr<TouchScreen> touch_screen = nullptr;
|
std::shared_ptr<TouchScreen> touch_screen = nullptr;
|
||||||
|
std::shared_ptr<Vibration> vibration = nullptr;
|
||||||
|
|
||||||
KernelHelpers::ServiceContext service_context;
|
KernelHelpers::ServiceContext service_context;
|
||||||
};
|
};
|
||||||
|
|
|
@ -837,9 +837,8 @@ Result Npad::SetVibrationMasterVolume(const float volume) {
|
||||||
|
|
||||||
Result Npad::GetVibrationMasterVolume(float& out_volume) const {
|
Result Npad::GetVibrationMasterVolume(float& out_volume) const {
|
||||||
// std::scoped_lock lock{external_mutex};
|
// std::scoped_lock lock{external_mutex};
|
||||||
float current_volume{}; // nn::settings::detail::GetVibrationMasterVolume()
|
// nn::settings::detail::GetVibrationMasterVolume()
|
||||||
|
float current_volume{vibration_master_volume};
|
||||||
current_volume = vibration_master_volume; // TODO: Replace this with setting
|
|
||||||
|
|
||||||
if (current_volume < 0.0f || current_volume > 1.0f) {
|
if (current_volume < 0.0f || current_volume > 1.0f) {
|
||||||
return ResultVibrationVolumeOutOfRange;
|
return ResultVibrationVolumeOutOfRange;
|
||||||
|
@ -850,6 +849,10 @@ Result Npad::GetVibrationMasterVolume(float& out_volume) const {
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<AbstractNpadState> Npad::GetAbstractNpad(const NpadIdType npad_id) {
|
||||||
|
return abstract_npad_state[NpadIdTypeToIndex(npad_id)];
|
||||||
|
}
|
||||||
|
|
||||||
void Npad::UpdateSupportedNpadIdType() {
|
void Npad::UpdateSupportedNpadIdType() {
|
||||||
// Set some u64
|
// Set some u64
|
||||||
// Call DisconnectAbstracPads(u64)
|
// Call DisconnectAbstracPads(u64)
|
||||||
|
|
|
@ -143,6 +143,8 @@ public:
|
||||||
Result SetVibrationMasterVolume(const float volume);
|
Result SetVibrationMasterVolume(const float volume);
|
||||||
Result GetVibrationMasterVolume(float& out_volume) const;
|
Result GetVibrationMasterVolume(float& out_volume) const;
|
||||||
|
|
||||||
|
std::shared_ptr<AbstractNpadState> GetAbstractNpad(const NpadIdType npad_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Interface implementations
|
// Interface implementations
|
||||||
Result SetSupportedNpadIdTypeImpl(const u64 aruid, std::span<const NpadIdType> list);
|
Result SetSupportedNpadIdTypeImpl(const u64 aruid, std::span<const NpadIdType> list);
|
||||||
|
|
Loading…
Reference in New Issue