19 changed files with 1930 additions and 676 deletions
-
4src/core/CMakeLists.txt
-
1src/core/hid/hid_types.h
-
1src/core/hle/service/hid/controllers/applet_resource.h
-
678src/core/hle/service/hid/controllers/npad.cpp
-
155src/core/hle/service/hid/controllers/npad.h
-
228src/core/hle/service/hid/controllers/npad/npad_data.cpp
-
88src/core/hle/service/hid/controllers/npad/npad_data.h
-
685src/core/hle/service/hid/controllers/npad/npad_resource.cpp
-
132src/core/hle/service/hid/controllers/npad/npad_resource.h
-
3src/core/hle/service/hid/controllers/types/npad_types.h
-
2src/core/hle/service/hid/controllers/types/shared_memory_format.h
-
32src/core/hle/service/hid/errors.h
-
1src/core/hle/service/hid/hid.cpp
-
220src/core/hle/service/hid/hid_server.cpp
-
38src/core/hle/service/hid/hid_system_server.cpp
-
8src/core/hle/service/hid/hid_util.h
-
2src/core/hle/service/hid/irs.cpp
-
14src/core/hle/service/hid/resource_manager.cpp
-
2src/core/hle/service/hid/resource_manager.h
678
src/core/hle/service/hid/controllers/npad.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,228 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "core/hle/service/hid/controllers/npad/npad_data.h"
|
|||
#include "core/hle/service/hid/hid_util.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NPadData::NPadData() { |
|||
ClearNpadSystemCommonPolicy(); |
|||
} |
|||
|
|||
NPadData::~NPadData() = default; |
|||
|
|||
NpadStatus NPadData::GetNpadStatus() const { |
|||
return status; |
|||
} |
|||
|
|||
void NPadData::SetNpadAnalogStickUseCenterClamp(bool is_enabled) { |
|||
status.use_center_clamp.Assign(is_enabled); |
|||
} |
|||
|
|||
bool NPadData::GetNpadAnalogStickUseCenterClamp() const { |
|||
return status.use_center_clamp.As<bool>(); |
|||
} |
|||
|
|||
void NPadData::SetNpadSystemExtStateEnabled(bool is_enabled) { |
|||
status.system_ext_state.Assign(is_enabled); |
|||
} |
|||
|
|||
bool NPadData::GetNpadSystemExtState() const { |
|||
return status.system_ext_state.As<bool>(); |
|||
} |
|||
|
|||
Result NPadData::SetSupportedNpadIdType(std::span<const Core::HID::NpadIdType> list) { |
|||
// Note: Real limit is 11. But array size is 10. N's bug?
|
|||
if (list.size() > MaxSupportedNpadIdTypes) { |
|||
return ResultInvalidArraySize; |
|||
} |
|||
|
|||
supported_npad_id_types_count = list.size(); |
|||
memcpy(supported_npad_id_types.data(), list.data(), |
|||
list.size() * sizeof(Core::HID::NpadIdType)); |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
std::size_t NPadData::GetSupportedNpadIdType(std::span<Core::HID::NpadIdType> out_list) const { |
|||
std::size_t out_size = std::min(supported_npad_id_types_count, out_list.size()); |
|||
|
|||
memcpy(out_list.data(), supported_npad_id_types.data(), |
|||
out_size * sizeof(Core::HID::NpadIdType)); |
|||
|
|||
return out_size; |
|||
} |
|||
|
|||
bool NPadData::IsNpadIdTypeSupported(Core::HID::NpadIdType npad_id) const { |
|||
for (std::size_t i = 0; i < supported_npad_id_types_count; i++) { |
|||
if (supported_npad_id_types[i] == npad_id) { |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
void NPadData::SetNpadSystemCommonPolicy(bool is_full_policy) { |
|||
supported_npad_style_set = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::JoyDual | |
|||
Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System; |
|||
handheld_activation_mode = NpadHandheldActivationMode::Dual; |
|||
|
|||
status.is_supported_styleset_set.Assign(true); |
|||
status.is_hold_type_set.Assign(true); |
|||
status.lr_assignment_mode.Assign(false); |
|||
status.is_policy.Assign(true); |
|||
if (is_full_policy) { |
|||
status.is_full_policy.Assign(true); |
|||
} |
|||
|
|||
supported_npad_id_types_count = 10; |
|||
supported_npad_id_types[0] = Core::HID::NpadIdType::Player1; |
|||
supported_npad_id_types[1] = Core::HID::NpadIdType::Player2; |
|||
supported_npad_id_types[2] = Core::HID::NpadIdType::Player3; |
|||
supported_npad_id_types[3] = Core::HID::NpadIdType::Player4; |
|||
supported_npad_id_types[4] = Core::HID::NpadIdType::Player5; |
|||
supported_npad_id_types[5] = Core::HID::NpadIdType::Player6; |
|||
supported_npad_id_types[6] = Core::HID::NpadIdType::Player7; |
|||
supported_npad_id_types[7] = Core::HID::NpadIdType::Player8; |
|||
supported_npad_id_types[8] = Core::HID::NpadIdType::Other; |
|||
supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld; |
|||
|
|||
for (auto& input_protection : is_unintended_home_button_input_protection) { |
|||
input_protection = true; |
|||
} |
|||
} |
|||
|
|||
void NPadData::ClearNpadSystemCommonPolicy() { |
|||
status.raw = 0; |
|||
supported_npad_style_set = Core::HID::NpadStyleSet::All; |
|||
npad_hold_type = NpadJoyHoldType::Vertical; |
|||
handheld_activation_mode = NpadHandheldActivationMode::Dual; |
|||
|
|||
for (auto& button_assignment : npad_button_assignment) { |
|||
button_assignment = Core::HID::NpadButton::None; |
|||
} |
|||
|
|||
supported_npad_id_types_count = 10; |
|||
supported_npad_id_types[0] = Core::HID::NpadIdType::Player1; |
|||
supported_npad_id_types[1] = Core::HID::NpadIdType::Player2; |
|||
supported_npad_id_types[2] = Core::HID::NpadIdType::Player3; |
|||
supported_npad_id_types[3] = Core::HID::NpadIdType::Player4; |
|||
supported_npad_id_types[4] = Core::HID::NpadIdType::Player5; |
|||
supported_npad_id_types[5] = Core::HID::NpadIdType::Player6; |
|||
supported_npad_id_types[6] = Core::HID::NpadIdType::Player7; |
|||
supported_npad_id_types[7] = Core::HID::NpadIdType::Player8; |
|||
supported_npad_id_types[8] = Core::HID::NpadIdType::Other; |
|||
supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld; |
|||
|
|||
for (auto& input_protection : is_unintended_home_button_input_protection) { |
|||
input_protection = true; |
|||
} |
|||
} |
|||
|
|||
void NPadData::SetNpadJoyHoldType(NpadJoyHoldType hold_type) { |
|||
npad_hold_type = hold_type; |
|||
status.is_hold_type_set.Assign(true); |
|||
} |
|||
|
|||
NpadJoyHoldType NPadData::GetNpadJoyHoldType() const { |
|||
return npad_hold_type; |
|||
} |
|||
|
|||
void NPadData::SetHandheldActivationMode(NpadHandheldActivationMode activation_mode) { |
|||
handheld_activation_mode = activation_mode; |
|||
} |
|||
|
|||
NpadHandheldActivationMode NPadData::GetHandheldActivationMode() const { |
|||
return handheld_activation_mode; |
|||
} |
|||
|
|||
void NPadData::SetSupportedNpadStyleSet(Core::HID::NpadStyleSet style_set) { |
|||
supported_npad_style_set = style_set; |
|||
status.is_supported_styleset_set.Assign(true); |
|||
status.is_hold_type_set.Assign(true); |
|||
} |
|||
|
|||
Core::HID::NpadStyleSet NPadData::GetSupportedNpadStyleSet() const { |
|||
return supported_npad_style_set; |
|||
} |
|||
|
|||
bool NPadData::IsNpadStyleIndexSupported(Core::HID::NpadStyleIndex style_index) const { |
|||
Core::HID::NpadStyleTag style = {supported_npad_style_set}; |
|||
switch (style_index) { |
|||
case Core::HID::NpadStyleIndex::ProController: |
|||
return style.fullkey.As<bool>(); |
|||
case Core::HID::NpadStyleIndex::Handheld: |
|||
return style.handheld.As<bool>(); |
|||
case Core::HID::NpadStyleIndex::JoyconDual: |
|||
return style.joycon_dual.As<bool>(); |
|||
case Core::HID::NpadStyleIndex::JoyconLeft: |
|||
return style.joycon_left.As<bool>(); |
|||
case Core::HID::NpadStyleIndex::JoyconRight: |
|||
return style.joycon_right.As<bool>(); |
|||
case Core::HID::NpadStyleIndex::GameCube: |
|||
return style.gamecube.As<bool>(); |
|||
case Core::HID::NpadStyleIndex::Pokeball: |
|||
return style.palma.As<bool>(); |
|||
case Core::HID::NpadStyleIndex::NES: |
|||
return style.lark.As<bool>(); |
|||
case Core::HID::NpadStyleIndex::SNES: |
|||
return style.lucia.As<bool>(); |
|||
case Core::HID::NpadStyleIndex::N64: |
|||
return style.lagoon.As<bool>(); |
|||
case Core::HID::NpadStyleIndex::SegaGenesis: |
|||
return style.lager.As<bool>(); |
|||
default: |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
void NPadData::SetLrAssignmentMode(bool is_enabled) { |
|||
status.lr_assignment_mode.Assign(is_enabled); |
|||
} |
|||
|
|||
bool NPadData::GetLrAssignmentMode() const { |
|||
return status.lr_assignment_mode.As<bool>(); |
|||
} |
|||
|
|||
void NPadData::SetAssigningSingleOnSlSrPress(bool is_enabled) { |
|||
status.assigning_single_on_sl_sr_press.Assign(is_enabled); |
|||
} |
|||
|
|||
bool NPadData::GetAssigningSingleOnSlSrPress() const { |
|||
return status.assigning_single_on_sl_sr_press.As<bool>(); |
|||
} |
|||
|
|||
void NPadData::SetHomeProtectionEnabled(bool is_enabled, Core::HID::NpadIdType npad_id) { |
|||
is_unintended_home_button_input_protection[NpadIdTypeToIndex(npad_id)] = is_enabled; |
|||
} |
|||
|
|||
bool NPadData::GetHomeProtectionEnabled(Core::HID::NpadIdType npad_id) const { |
|||
return is_unintended_home_button_input_protection[NpadIdTypeToIndex(npad_id)]; |
|||
} |
|||
|
|||
void NPadData::SetCaptureButtonAssignment(Core::HID::NpadButton button_assignment, |
|||
std::size_t style_index) { |
|||
npad_button_assignment[style_index] = button_assignment; |
|||
} |
|||
|
|||
Core::HID::NpadButton NPadData::GetCaptureButtonAssignment(std::size_t style_index) const { |
|||
return npad_button_assignment[style_index]; |
|||
} |
|||
|
|||
std::size_t NPadData::GetNpadCaptureButtonAssignmentList( |
|||
std::span<Core::HID::NpadButton> out_list) const { |
|||
for (std::size_t i = 0; i < out_list.size(); i++) { |
|||
Core::HID::NpadStyleSet style_set = GetStylesetByIndex(i); |
|||
if ((style_set & supported_npad_style_set) == Core::HID::NpadStyleSet::None || |
|||
npad_button_assignment[i] == Core::HID::NpadButton::None) { |
|||
return i; |
|||
} |
|||
out_list[i] = npad_button_assignment[i]; |
|||
} |
|||
|
|||
return out_list.size(); |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,88 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <span> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hid/hid_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "core/hle/service/hid/controllers/types/npad_types.h" |
|||
|
|||
namespace Service::HID { |
|||
|
|||
struct NpadStatus { |
|||
union { |
|||
u32 raw{}; |
|||
|
|||
BitField<0, 1, u32> is_supported_styleset_set; |
|||
BitField<1, 1, u32> is_hold_type_set; |
|||
BitField<2, 1, u32> lr_assignment_mode; |
|||
BitField<3, 1, u32> assigning_single_on_sl_sr_press; |
|||
BitField<4, 1, u32> is_full_policy; |
|||
BitField<5, 1, u32> is_policy; |
|||
BitField<6, 1, u32> use_center_clamp; |
|||
BitField<7, 1, u32> system_ext_state; |
|||
}; |
|||
}; |
|||
static_assert(sizeof(NpadStatus) == 4, "NpadStatus is an invalid size"); |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NPadData final { |
|||
public: |
|||
explicit NPadData(); |
|||
~NPadData(); |
|||
|
|||
NpadStatus GetNpadStatus() const; |
|||
|
|||
void SetNpadAnalogStickUseCenterClamp(bool is_enabled); |
|||
bool GetNpadAnalogStickUseCenterClamp() const; |
|||
|
|||
void SetNpadSystemExtStateEnabled(bool is_enabled); |
|||
bool GetNpadSystemExtState() const; |
|||
|
|||
Result SetSupportedNpadIdType(std::span<const Core::HID::NpadIdType> list); |
|||
std::size_t GetSupportedNpadIdType(std::span<Core::HID::NpadIdType> out_list) const; |
|||
bool IsNpadIdTypeSupported(Core::HID::NpadIdType npad_id) const; |
|||
|
|||
void SetNpadSystemCommonPolicy(bool is_full_policy); |
|||
void ClearNpadSystemCommonPolicy(); |
|||
|
|||
void SetNpadJoyHoldType(NpadJoyHoldType hold_type); |
|||
NpadJoyHoldType GetNpadJoyHoldType() const; |
|||
|
|||
void SetHandheldActivationMode(NpadHandheldActivationMode activation_mode); |
|||
NpadHandheldActivationMode GetHandheldActivationMode() const; |
|||
|
|||
void SetSupportedNpadStyleSet(Core::HID::NpadStyleSet style_set); |
|||
Core::HID::NpadStyleSet GetSupportedNpadStyleSet() const; |
|||
bool IsNpadStyleIndexSupported(Core::HID::NpadStyleIndex style_index) const; |
|||
|
|||
void SetLrAssignmentMode(bool is_enabled); |
|||
bool GetLrAssignmentMode() const; |
|||
|
|||
void SetAssigningSingleOnSlSrPress(bool is_enabled); |
|||
bool GetAssigningSingleOnSlSrPress() const; |
|||
|
|||
void SetHomeProtectionEnabled(bool is_enabled, Core::HID::NpadIdType npad_id); |
|||
bool GetHomeProtectionEnabled(Core::HID::NpadIdType npad_id) const; |
|||
|
|||
void SetCaptureButtonAssignment(Core::HID::NpadButton button_assignment, |
|||
std::size_t style_index); |
|||
Core::HID::NpadButton GetCaptureButtonAssignment(std::size_t style_index) const; |
|||
std::size_t GetNpadCaptureButtonAssignmentList(std::span<Core::HID::NpadButton> out_list) const; |
|||
|
|||
private: |
|||
NpadStatus status{}; |
|||
Core::HID::NpadStyleSet supported_npad_style_set{Core::HID::NpadStyleSet::All}; |
|||
NpadJoyHoldType npad_hold_type{NpadJoyHoldType::Vertical}; |
|||
NpadHandheldActivationMode handheld_activation_mode{}; |
|||
std::array<Core::HID::NpadIdType, MaxSupportedNpadIdTypes> supported_npad_id_types{}; |
|||
std::array<Core::HID::NpadButton, StyleIndexCount> npad_button_assignment{}; |
|||
std::size_t supported_npad_id_types_count{}; |
|||
std::array<bool, MaxSupportedNpadIdTypes> is_unintended_home_button_input_protection{}; |
|||
}; |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,685 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "core/hle/kernel/k_event.h"
|
|||
#include "core/hle/kernel/k_readable_event.h"
|
|||
#include "core/hle/service/hid/controllers/npad/npad_resource.h"
|
|||
#include "core/hle/service/hid/controllers/types/npad_types.h"
|
|||
#include "core/hle/service/hid/errors.h"
|
|||
#include "core/hle/service/hid/hid_util.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NPadResource::NPadResource(KernelHelpers::ServiceContext& context) : service_context{context} {} |
|||
|
|||
NPadResource::~NPadResource() = default; |
|||
|
|||
Result NPadResource::RegisterAppletResourceUserId(u64 aruid) { |
|||
const auto aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index < AruidIndexMax) { |
|||
return ResultAruidAlreadyRegistered; |
|||
} |
|||
|
|||
std::size_t data_index = AruidIndexMax; |
|||
for (std::size_t i = 0; i < AruidIndexMax; i++) { |
|||
if (!state[i].flag.is_initialized) { |
|||
data_index = i; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (data_index == AruidIndexMax) { |
|||
return ResultAruidNoAvailableEntries; |
|||
} |
|||
|
|||
auto& aruid_data = state[data_index]; |
|||
|
|||
aruid_data.aruid = aruid; |
|||
aruid_data.flag.is_initialized.Assign(true); |
|||
|
|||
data_index = AruidIndexMax; |
|||
for (std::size_t i = 0; i < AruidIndexMax; i++) { |
|||
if (registration_list.flag[i] == RegistrationStatus::Initialized) { |
|||
if (registration_list.aruid[i] != aruid) { |
|||
continue; |
|||
} |
|||
data_index = i; |
|||
break; |
|||
} |
|||
if (registration_list.flag[i] == RegistrationStatus::None) { |
|||
data_index = i; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (data_index == AruidIndexMax) { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
registration_list.flag[data_index] = RegistrationStatus::Initialized; |
|||
registration_list.aruid[data_index] = aruid; |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void NPadResource::UnregisterAppletResourceUserId(u64 aruid) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
|
|||
DestroyStyleSetUpdateEvents(aruid); |
|||
if (aruid_index < AruidIndexMax) { |
|||
state[aruid_index] = {}; |
|||
registration_list.flag[aruid_index] = RegistrationStatus::PendingDelete; |
|||
} |
|||
} |
|||
|
|||
void NPadResource::DestroyStyleSetUpdateEvents(u64 aruid) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
|
|||
if (aruid_index >= AruidIndexMax) { |
|||
return; |
|||
} |
|||
|
|||
for (auto& controller_state : state[aruid_index].controller_state) { |
|||
if (!controller_state.is_styleset_update_event_initialized) { |
|||
continue; |
|||
} |
|||
service_context.CloseEvent(controller_state.style_set_update_event); |
|||
controller_state.is_styleset_update_event_initialized = false; |
|||
} |
|||
} |
|||
|
|||
Result NPadResource::Activate(u64 aruid) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
|
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
auto& state_data = state[aruid_index]; |
|||
|
|||
if (state_data.flag.is_assigned) { |
|||
return ResultAruidAlreadyRegistered; |
|||
} |
|||
|
|||
state_data.flag.is_assigned.Assign(true); |
|||
state_data.data.ClearNpadSystemCommonPolicy(); |
|||
state_data.npad_revision = NpadRevision::Revision0; |
|||
state_data.button_config = {}; |
|||
|
|||
if (active_data_aruid == aruid) { |
|||
default_hold_type = active_data.GetNpadJoyHoldType(); |
|||
active_data.SetNpadJoyHoldType(default_hold_type); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::Activate() { |
|||
if (ref_counter == std::numeric_limits<s32>::max() - 1) { |
|||
return ResultAppletResourceOverflow; |
|||
} |
|||
if (ref_counter == 0) { |
|||
RegisterAppletResourceUserId(SystemAruid); |
|||
Activate(SystemAruid); |
|||
} |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::Deactivate() { |
|||
if (ref_counter == 0) { |
|||
return ResultAppletResourceNotInitialized; |
|||
} |
|||
|
|||
UnregisterAppletResourceUserId(SystemAruid); |
|||
ref_counter--; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
NPadData* NPadResource::GetActiveData() { |
|||
return &active_data; |
|||
} |
|||
|
|||
u64 NPadResource::GetActiveDataAruid() { |
|||
return active_data_aruid; |
|||
} |
|||
|
|||
void NPadResource::SetAppletResourceUserId(u64 aruid) { |
|||
if (active_data_aruid == aruid) { |
|||
return; |
|||
} |
|||
|
|||
active_data_aruid = aruid; |
|||
default_hold_type = active_data.GetNpadJoyHoldType(); |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
|
|||
if (aruid_index >= AruidIndexMax) { |
|||
return; |
|||
} |
|||
|
|||
auto& data = state[aruid_index].data; |
|||
if (data.GetNpadStatus().is_policy || data.GetNpadStatus().is_full_policy) { |
|||
data.SetNpadJoyHoldType(default_hold_type); |
|||
} |
|||
|
|||
active_data = data; |
|||
if (data.GetNpadStatus().is_hold_type_set) { |
|||
active_data.SetNpadJoyHoldType(default_hold_type); |
|||
} |
|||
} |
|||
|
|||
std::size_t NPadResource::GetIndexFromAruid(u64 aruid) const { |
|||
for (std::size_t i = 0; i < AruidIndexMax; i++) { |
|||
if (registration_list.flag[i] == RegistrationStatus::Initialized && |
|||
registration_list.aruid[i] == aruid) { |
|||
return i; |
|||
} |
|||
} |
|||
return AruidIndexMax; |
|||
} |
|||
|
|||
Result NPadResource::ApplyNpadSystemCommonPolicy(u64 aruid, bool is_full_policy) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
auto& data = state[aruid_index].data; |
|||
data.SetNpadSystemCommonPolicy(is_full_policy); |
|||
data.SetNpadJoyHoldType(default_hold_type); |
|||
if (active_data_aruid == aruid) { |
|||
active_data.SetNpadSystemCommonPolicy(is_full_policy); |
|||
active_data.SetNpadJoyHoldType(default_hold_type); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::ClearNpadSystemCommonPolicy(u64 aruid) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
state[aruid_index].data.ClearNpadSystemCommonPolicy(); |
|||
if (active_data_aruid == aruid) { |
|||
active_data.ClearNpadSystemCommonPolicy(); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet style_set) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
auto& data = state[aruid_index].data; |
|||
data.SetSupportedNpadStyleSet(style_set); |
|||
if (active_data_aruid == aruid) { |
|||
active_data.SetSupportedNpadStyleSet(style_set); |
|||
active_data.SetNpadJoyHoldType(data.GetNpadJoyHoldType()); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::GetSupportedNpadStyleSet(Core::HID::NpadStyleSet& out_style_Set, |
|||
u64 aruid) const { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
auto& data = state[aruid_index].data; |
|||
if (!data.GetNpadStatus().is_supported_styleset_set) { |
|||
return ResultUndefinedStyleset; |
|||
} |
|||
|
|||
out_style_Set = data.GetSupportedNpadStyleSet(); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::GetMaskedSupportedNpadStyleSet(Core::HID::NpadStyleSet& out_style_set, |
|||
u64 aruid) const { |
|||
if (aruid == SystemAruid) { |
|||
out_style_set = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | |
|||
Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | |
|||
Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Palma | |
|||
Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
auto& data = state[aruid_index].data; |
|||
if (!data.GetNpadStatus().is_supported_styleset_set) { |
|||
return ResultUndefinedStyleset; |
|||
} |
|||
|
|||
Core::HID::NpadStyleSet mask{Core::HID::NpadStyleSet::None}; |
|||
out_style_set = data.GetSupportedNpadStyleSet(); |
|||
|
|||
switch (state[aruid_index].npad_revision) { |
|||
case NpadRevision::Revision1: |
|||
mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | |
|||
Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | |
|||
Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc | |
|||
Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::SystemExt | |
|||
Core::HID::NpadStyleSet::System; |
|||
break; |
|||
case NpadRevision::Revision2: |
|||
mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | |
|||
Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | |
|||
Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc | |
|||
Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::Lark | |
|||
Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System; |
|||
break; |
|||
case NpadRevision::Revision3: |
|||
mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | |
|||
Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | |
|||
Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc | |
|||
Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::Lark | |
|||
Core::HID::NpadStyleSet::HandheldLark | Core::HID::NpadStyleSet::Lucia | |
|||
Core::HID::NpadStyleSet::Lagoon | Core::HID::NpadStyleSet::Lager | |
|||
Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System; |
|||
break; |
|||
default: |
|||
mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | |
|||
Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | |
|||
Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::SystemExt | |
|||
Core::HID::NpadStyleSet::System; |
|||
break; |
|||
} |
|||
|
|||
out_style_set = out_style_set & mask; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::GetAvailableStyleset(Core::HID::NpadStyleSet& out_style_set, u64 aruid) const { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
auto& data = state[aruid_index].data; |
|||
if (!data.GetNpadStatus().is_supported_styleset_set) { |
|||
return ResultUndefinedStyleset; |
|||
} |
|||
|
|||
Core::HID::NpadStyleSet mask{Core::HID::NpadStyleSet::None}; |
|||
out_style_set = data.GetSupportedNpadStyleSet(); |
|||
|
|||
switch (state[aruid_index].npad_revision) { |
|||
case NpadRevision::Revision1: |
|||
mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | |
|||
Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | |
|||
Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc | |
|||
Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::SystemExt | |
|||
Core::HID::NpadStyleSet::System; |
|||
break; |
|||
case NpadRevision::Revision2: |
|||
mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | |
|||
Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | |
|||
Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc | |
|||
Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::Lark | |
|||
Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System; |
|||
break; |
|||
case NpadRevision::Revision3: |
|||
mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | |
|||
Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | |
|||
Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc | |
|||
Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::Lark | |
|||
Core::HID::NpadStyleSet::HandheldLark | Core::HID::NpadStyleSet::Lucia | |
|||
Core::HID::NpadStyleSet::Lagoon | Core::HID::NpadStyleSet::Lager | |
|||
Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System; |
|||
break; |
|||
default: |
|||
mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | |
|||
Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | |
|||
Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::SystemExt | |
|||
Core::HID::NpadStyleSet::System; |
|||
break; |
|||
} |
|||
|
|||
out_style_set = out_style_set & mask; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
NpadRevision NPadResource::GetNpadRevision(u64 aruid) const { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return NpadRevision::Revision0; |
|||
} |
|||
|
|||
return state[aruid_index].npad_revision; |
|||
} |
|||
|
|||
Result NPadResource::IsSupportedNpadStyleSet(bool& is_set, u64 aruid) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
is_set = state[aruid_index].data.GetNpadStatus().is_supported_styleset_set.Value() != 0; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
state[aruid_index].data.SetNpadJoyHoldType(hold_type); |
|||
if (active_data_aruid == aruid) { |
|||
active_data.SetNpadJoyHoldType(hold_type); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::GetNpadJoyHoldType(NpadJoyHoldType& hold_type, u64 aruid) const { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
auto& data = state[aruid_index].data; |
|||
if (data.GetNpadStatus().is_policy || data.GetNpadStatus().is_full_policy) { |
|||
hold_type = active_data.GetNpadJoyHoldType(); |
|||
return ResultSuccess; |
|||
} |
|||
hold_type = data.GetNpadJoyHoldType(); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::SetNpadHandheldActivationMode(u64 aruid, |
|||
NpadHandheldActivationMode activation_mode) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
state[aruid_index].data.SetHandheldActivationMode(activation_mode); |
|||
if (active_data_aruid == aruid) { |
|||
active_data.SetHandheldActivationMode(activation_mode); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::GetNpadHandheldActivationMode(NpadHandheldActivationMode& activation_mode, |
|||
u64 aruid) const { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
activation_mode = state[aruid_index].data.GetHandheldActivationMode(); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::SetSupportedNpadIdType( |
|||
u64 aruid, std::span<const Core::HID::NpadIdType> supported_npad_list) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
if (supported_npad_list.size() > MaxSupportedNpadIdTypes) { |
|||
return ResultInvalidArraySize; |
|||
} |
|||
|
|||
Result result = state[aruid_index].data.SetSupportedNpadIdType(supported_npad_list); |
|||
if (result.IsSuccess() && active_data_aruid == aruid) { |
|||
result = active_data.SetSupportedNpadIdType(supported_npad_list); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
bool NPadResource::IsControllerSupported(u64 aruid, Core::HID::NpadStyleIndex style_index) const { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return false; |
|||
} |
|||
return state[aruid_index].data.IsNpadStyleIndexSupported(style_index); |
|||
} |
|||
|
|||
Result NPadResource::SetLrAssignmentMode(u64 aruid, bool is_enabled) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
state[aruid_index].data.SetLrAssignmentMode(is_enabled); |
|||
if (active_data_aruid == aruid) { |
|||
active_data.SetLrAssignmentMode(is_enabled); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::GetLrAssignmentMode(bool& is_enabled, u64 aruid) const { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
is_enabled = state[aruid_index].data.GetLrAssignmentMode(); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::SetAssigningSingleOnSlSrPress(u64 aruid, bool is_enabled) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
state[aruid_index].data.SetAssigningSingleOnSlSrPress(is_enabled); |
|||
if (active_data_aruid == aruid) { |
|||
active_data.SetAssigningSingleOnSlSrPress(is_enabled); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::IsAssigningSingleOnSlSrPressEnabled(bool& is_enabled, u64 aruid) const { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
is_enabled = state[aruid_index].data.GetAssigningSingleOnSlSrPress(); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::AcquireNpadStyleSetUpdateEventHandle(u64 aruid, |
|||
Kernel::KReadableEvent** out_event, |
|||
Core::HID::NpadIdType npad_id) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
auto& controller_state = state[aruid_index].controller_state[NpadIdTypeToIndex(npad_id)]; |
|||
if (!controller_state.is_styleset_update_event_initialized) { |
|||
// Auto clear = true
|
|||
controller_state.style_set_update_event = |
|||
service_context.CreateEvent("NpadResource:StylesetUpdateEvent"); |
|||
|
|||
// Assume creating the event succeeds otherwise crash the system here
|
|||
controller_state.is_styleset_update_event_initialized = true; |
|||
} |
|||
|
|||
*out_event = &controller_state.style_set_update_event->GetReadableEvent(); |
|||
|
|||
if (controller_state.is_styleset_update_event_initialized) { |
|||
controller_state.style_set_update_event->Signal(); |
|||
} |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::SignalStyleSetUpdateEvent(u64 aruid, Core::HID::NpadIdType npad_id) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
auto controller = state[aruid_index].controller_state[NpadIdTypeToIndex(npad_id)]; |
|||
if (controller.is_styleset_update_event_initialized) { |
|||
controller.style_set_update_event->Signal(); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::GetHomeProtectionEnabled(bool& is_enabled, u64 aruid, |
|||
Core::HID::NpadIdType npad_id) const { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
is_enabled = state[aruid_index].data.GetHomeProtectionEnabled(npad_id); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::SetHomeProtectionEnabled(u64 aruid, Core::HID::NpadIdType npad_id, |
|||
bool is_enabled) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
state[aruid_index].data.SetHomeProtectionEnabled(is_enabled, npad_id); |
|||
if (active_data_aruid == aruid) { |
|||
active_data.SetHomeProtectionEnabled(is_enabled, npad_id); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
state[aruid_index].data.SetNpadAnalogStickUseCenterClamp(is_enabled); |
|||
if (active_data_aruid == aruid) { |
|||
active_data.SetNpadAnalogStickUseCenterClamp(is_enabled); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::SetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, std::size_t index, |
|||
Core::HID::NpadButton button_config) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
state[aruid_index].button_config[NpadIdTypeToIndex(npad_id)][index] = button_config; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Core::HID::NpadButton NPadResource::GetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, |
|||
std::size_t index, Core::HID::NpadButton mask, |
|||
bool is_enabled) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return Core::HID::NpadButton::None; |
|||
} |
|||
|
|||
auto& button_config = state[aruid_index].button_config[NpadIdTypeToIndex(npad_id)][index]; |
|||
if (is_enabled) { |
|||
button_config = button_config | mask; |
|||
return button_config; |
|||
} |
|||
|
|||
button_config = Core::HID::NpadButton::None; |
|||
return Core::HID::NpadButton::None; |
|||
} |
|||
|
|||
void NPadResource::ResetButtonConfig() { |
|||
for (auto& selected_state : state) { |
|||
selected_state.button_config = {}; |
|||
} |
|||
} |
|||
|
|||
Result NPadResource::SetNpadCaptureButtonAssignment(u64 aruid, |
|||
Core::HID::NpadStyleSet npad_style_set, |
|||
Core::HID::NpadButton button_assignment) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
// Must be a power of two
|
|||
const auto raw_styleset = static_cast<u32>(npad_style_set); |
|||
if (raw_styleset == 0 && (raw_styleset & (raw_styleset - 1)) != 0) { |
|||
return ResultMultipleStyleSetSelected; |
|||
} |
|||
|
|||
std::size_t style_index{}; |
|||
Core::HID::NpadStyleSet style_selected{}; |
|||
for (style_index = 0; style_index < StyleIndexCount; ++style_index) { |
|||
style_selected = GetStylesetByIndex(style_index); |
|||
if (npad_style_set == style_selected) { |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (style_selected == Core::HID::NpadStyleSet::None) { |
|||
return ResultMultipleStyleSetSelected; |
|||
} |
|||
|
|||
state[aruid_index].data.SetCaptureButtonAssignment(button_assignment, style_index); |
|||
if (active_data_aruid == aruid) { |
|||
active_data.SetCaptureButtonAssignment(button_assignment, style_index); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NPadResource::ClearNpadCaptureButtonAssignment(u64 aruid) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
for (std::size_t i = 0; i < StyleIndexCount; i++) { |
|||
state[aruid_index].data.SetCaptureButtonAssignment(Core::HID::NpadButton::None, i); |
|||
if (active_data_aruid == aruid) { |
|||
active_data.SetCaptureButtonAssignment(Core::HID::NpadButton::None, i); |
|||
} |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
std::size_t NPadResource::GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list, |
|||
u64 aruid) const { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return 0; |
|||
} |
|||
return state[aruid_index].data.GetNpadCaptureButtonAssignmentList(out_list); |
|||
} |
|||
|
|||
void NPadResource::SetNpadRevision(u64 aruid, NpadRevision revision) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return; |
|||
} |
|||
|
|||
state[aruid_index].npad_revision = revision; |
|||
} |
|||
|
|||
Result NPadResource::SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled) { |
|||
const u64 aruid_index = GetIndexFromAruid(aruid); |
|||
if (aruid_index >= AruidIndexMax) { |
|||
return ResultNpadNotConnected; |
|||
} |
|||
|
|||
state[aruid_index].data.SetNpadAnalogStickUseCenterClamp(is_enabled); |
|||
if (active_data_aruid == aruid) { |
|||
active_data.SetNpadAnalogStickUseCenterClamp(is_enabled); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,132 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <mutex> |
|||
#include <span> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hid/hid_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "core/hle/service/hid/controllers/applet_resource.h" |
|||
#include "core/hle/service/hid/controllers/npad/npad_data.h" |
|||
#include "core/hle/service/hid/controllers/types/npad_types.h" |
|||
#include "core/hle/service/kernel_helpers.h" |
|||
|
|||
namespace Core { |
|||
class System; |
|||
} |
|||
|
|||
namespace Kernel { |
|||
class KReadableEvent; |
|||
} |
|||
|
|||
namespace Service::HID { |
|||
struct DataStatusFlag; |
|||
|
|||
struct NpadControllerState { |
|||
bool is_styleset_update_event_initialized{}; |
|||
INSERT_PADDING_BYTES(0x7); |
|||
Kernel::KEvent* style_set_update_event{nullptr}; |
|||
INSERT_PADDING_BYTES(0x27); |
|||
}; |
|||
|
|||
struct NpadState { |
|||
DataStatusFlag flag{}; |
|||
u64 aruid{}; |
|||
NPadData data{}; |
|||
std::array<std::array<Core::HID::NpadButton, StyleIndexCount>, MaxSupportedNpadIdTypes> |
|||
button_config; |
|||
std::array<NpadControllerState, MaxSupportedNpadIdTypes> controller_state; |
|||
NpadRevision npad_revision; |
|||
}; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NPadResource final { |
|||
public: |
|||
explicit NPadResource(KernelHelpers::ServiceContext& context); |
|||
~NPadResource(); |
|||
|
|||
NPadData* GetActiveData(); |
|||
u64 GetActiveDataAruid(); |
|||
|
|||
Result RegisterAppletResourceUserId(u64 aruid); |
|||
void UnregisterAppletResourceUserId(u64 aruid); |
|||
|
|||
void DestroyStyleSetUpdateEvents(u64 aruid); |
|||
|
|||
Result Activate(u64 aruid); |
|||
Result Activate(); |
|||
Result Deactivate(); |
|||
|
|||
void SetAppletResourceUserId(u64 aruid); |
|||
std::size_t GetIndexFromAruid(u64 aruid) const; |
|||
|
|||
Result ApplyNpadSystemCommonPolicy(u64 aruid, bool is_full_policy); |
|||
Result ClearNpadSystemCommonPolicy(u64 aruid); |
|||
|
|||
Result SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet style_set); |
|||
Result GetSupportedNpadStyleSet(Core::HID::NpadStyleSet& out_style_Set, u64 aruid) const; |
|||
Result GetMaskedSupportedNpadStyleSet(Core::HID::NpadStyleSet& out_style_set, u64 aruid) const; |
|||
Result GetAvailableStyleset(Core::HID::NpadStyleSet& out_style_set, u64 aruid) const; |
|||
|
|||
NpadRevision GetNpadRevision(u64 aruid) const; |
|||
void SetNpadRevision(u64 aruid, NpadRevision revision); |
|||
|
|||
Result IsSupportedNpadStyleSet(bool& is_set, u64 aruid); |
|||
|
|||
Result SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type); |
|||
Result GetNpadJoyHoldType(NpadJoyHoldType& hold_type, u64 aruid) const; |
|||
|
|||
Result SetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode activation_mode); |
|||
Result GetNpadHandheldActivationMode(NpadHandheldActivationMode& activation_mode, |
|||
u64 aruid) const; |
|||
|
|||
Result SetSupportedNpadIdType(u64 aruid, |
|||
std::span<const Core::HID::NpadIdType> supported_npad_list); |
|||
bool IsControllerSupported(u64 aruid, Core::HID::NpadStyleIndex style_index) const; |
|||
|
|||
Result SetLrAssignmentMode(u64 aruid, bool is_enabled); |
|||
Result GetLrAssignmentMode(bool& is_enabled, u64 aruid) const; |
|||
|
|||
Result SetAssigningSingleOnSlSrPress(u64 aruid, bool is_enabled); |
|||
Result IsAssigningSingleOnSlSrPressEnabled(bool& is_enabled, u64 aruid) const; |
|||
|
|||
Result AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event, |
|||
Core::HID::NpadIdType npad_id); |
|||
Result SignalStyleSetUpdateEvent(u64 aruid, Core::HID::NpadIdType npad_id); |
|||
|
|||
Result GetHomeProtectionEnabled(bool& is_enabled, u64 aruid, |
|||
Core::HID::NpadIdType npad_id) const; |
|||
Result SetHomeProtectionEnabled(u64 aruid, Core::HID::NpadIdType npad_id, bool is_enabled); |
|||
|
|||
Result SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled); |
|||
|
|||
Result SetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, std::size_t index, |
|||
Core::HID::NpadButton button_config); |
|||
Core::HID::NpadButton GetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, |
|||
std::size_t index, Core::HID::NpadButton mask, |
|||
bool is_enabled); |
|||
void ResetButtonConfig(); |
|||
|
|||
Result SetNpadCaptureButtonAssignment(u64 aruid, Core::HID::NpadStyleSet npad_style_set, |
|||
Core::HID::NpadButton button_assignment); |
|||
Result ClearNpadCaptureButtonAssignment(u64 aruid); |
|||
std::size_t GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list, |
|||
u64 aruid) const; |
|||
|
|||
Result SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled); |
|||
|
|||
private: |
|||
NPadData active_data{}; |
|||
AruidRegisterList registration_list{}; |
|||
std::array<NpadState, AruidIndexMax> state{}; |
|||
u64 active_data_aruid{}; |
|||
NpadJoyHoldType default_hold_type{}; |
|||
s32 ref_counter{}; |
|||
|
|||
KernelHelpers::ServiceContext& service_context; |
|||
}; |
|||
} // namespace Service::HID |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue