diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c26941885..849a1359a 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -528,6 +528,12 @@ add_library(core STATIC hle/service/hid/resource_manager.h hle/service/hid/xcd.cpp hle/service/hid/xcd.h + hle/service/hid/resource_manager/npad_resource/npad.cpp + hle/service/hid/resource_manager/npad_resource/npad.h + hle/service/hid/resource_manager/npad_resource/npad_controller_state.cpp + hle/service/hid/resource_manager/npad_resource/npad_controller_state.h + hle/service/hid/resource_manager/npad_resource/npad_state.cpp + hle/service/hid/resource_manager/npad_resource/npad_state.h hle/service/hid/resource_manager/base_resource.cpp hle/service/hid/resource_manager/base_resource.h hle/service/hid/resource_manager/debug_pad.cpp @@ -538,8 +544,6 @@ add_library(core STATIC hle/service/hid/resource_manager/keyboard.h hle/service/hid/resource_manager/mouse.cpp hle/service/hid/resource_manager/mouse.h - hle/service/hid/resource_manager/npad.cpp - hle/service/hid/resource_manager/npad.h hle/service/hid/resource_manager/palma.cpp hle/service/hid/resource_manager/palma.h hle/service/hid/resource_manager/sixaxis.cpp diff --git a/src/core/hle/service/hid/hid_debug_server.cpp b/src/core/hle/service/hid/hid_debug_server.cpp index c64c57f0b..7ec1c8539 100644 --- a/src/core/hle/service/hid/hid_debug_server.cpp +++ b/src/core/hle/service/hid/hid_debug_server.cpp @@ -5,7 +5,7 @@ #include "core/hle/service/hid//hid_types.h" #include "core/hle/service/hid/hid_debug_server.h" #include "core/hle/service/hid/resource_manager.h" -#include "core/hle/service/hid/resource_manager/npad.h" +#include "core/hle/service/hid/resource_manager/npad_resource/npad.h" #include "core/hle/service/hid/resource_manager/sixaxis.h" #include "core/hle/service/ipc_helpers.h" diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp index e0783952c..d9e5ecabb 100644 --- a/src/core/hle/service/hid/hid_server.cpp +++ b/src/core/hle/service/hid/hid_server.cpp @@ -14,7 +14,7 @@ #include "core/hle/service/hid/resource_manager/gesture.h" #include "core/hle/service/hid/resource_manager/keyboard.h" #include "core/hle/service/hid/resource_manager/mouse.h" -#include "core/hle/service/hid/resource_manager/npad.h" +#include "core/hle/service/hid/resource_manager/npad_resource/npad.h" #include "core/hle/service/hid/resource_manager/palma.h" #include "core/hle/service/hid/resource_manager/sixaxis.h" #include "core/hle/service/hid/resource_manager/touch_screen.h" diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp index e3f600ed1..d523a03b5 100644 --- a/src/core/hle/service/hid/hid_system_server.cpp +++ b/src/core/hle/service/hid/hid_system_server.cpp @@ -5,7 +5,7 @@ #include "core/hle/service/hid//hid_types.h" #include "core/hle/service/hid/hid_system_server.h" #include "core/hle/service/hid/resource_manager.h" -#include "core/hle/service/hid/resource_manager/npad.h" +#include "core/hle/service/hid/resource_manager/npad_resource/npad.h" #include "core/hle/service/ipc_helpers.h" namespace Service::HID { diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp index be8f7d6ca..3ca810618 100644 --- a/src/core/hle/service/hid/resource_manager.cpp +++ b/src/core/hle/service/hid/resource_manager.cpp @@ -6,7 +6,7 @@ #include "core/hle/service/hid/resource_manager/gesture.h" #include "core/hle/service/hid/resource_manager/keyboard.h" #include "core/hle/service/hid/resource_manager/mouse.h" -#include "core/hle/service/hid/resource_manager/npad.h" +#include "core/hle/service/hid/resource_manager/npad_resource/npad.h" #include "core/hle/service/hid/resource_manager/palma.h" #include "core/hle/service/hid/resource_manager/sixaxis.h" #include "core/hle/service/hid/resource_manager/touch_screen.h" diff --git a/src/core/hle/service/hid/resource_manager/npad.cpp b/src/core/hle/service/hid/resource_manager/npad_resource/npad.cpp similarity index 73% rename from src/core/hle/service/hid/resource_manager/npad.cpp rename to src/core/hle/service/hid/resource_manager/npad_resource/npad.cpp index ebc7a014e..fc84fdfef 100644 --- a/src/core/hle/service/hid/resource_manager/npad.cpp +++ b/src/core/hle/service/hid/resource_manager/npad_resource/npad.cpp @@ -5,259 +5,12 @@ #include "core/hle/service/hid/hid_result.h" #include "core/hle/service/hid/hid_types.h" #include "core/hle/service/hid/hid_util.h" -#include "core/hle/service/hid/resource_manager/npad.h" +#include "core/hle/service/hid/resource_manager/npad_resource/npad.h" +#include "core/hle/service/hid/resource_manager/npad_resource/npad_controller_state.h" +#include "core/hle/service/hid/resource_manager/npad_resource/npad_state.h" -#pragma optimize("", off) namespace Service::HID { -NpadControllerState::NpadControllerState() {} - -NpadControllerState::~NpadControllerState() = default; - -NpadIdType NpadControllerState::GetNpadId() const { - return npad_id; -} - -u64 NpadControllerState::IsUpdatePending() { - return 0; -} - -void NpadControllerState::Update() {} - -void NpadControllerState::SetNpadAssignmentMode(const NpadJoyAssignmentMode mode) { - assignament_mode = mode; -} - -bool NpadControllerState::IsStyleSetUpdateEventInitialized() const { - return is_styleset_update_event_initialized; -} - -void NpadControllerState::SetStyleSetUpdateEventInitialized(const bool is_initialized) { - is_styleset_update_event_initialized = is_initialized; -} - -void NpadControllerState::SetNpadStyleSetUpdateEvent(Kernel::KEvent* event) { - style_set_update_event = event; -} - -Kernel::KReadableEvent& NpadControllerState::GetNpadStyleSetUpdateEvent() { - return style_set_update_event->GetReadableEvent(); -} - -void NpadControllerState::SignalStyleSetUpdateEvent() { - style_set_update_event->Signal(); -} - -u32 NpadControllerState::GetConnectedControllerIndex() { - u32 connected_controllers = 0; - u32 connected_index = 0; - - // u32 index = 0; - - if (connected_controllers == 0) { - return 0; - } - - if (connected_controllers != 1) { - // Something Fun happens here - } - - if ((connected_controllers & 1) != 0) { - // connected_index |= somearray[index]; - } - - return connected_index; -} - -NpadState::NpadState() { - for (auto npad : state) { - npad = std::make_shared(); - } -} - -NpadState::~NpadState() = default; - -std::shared_ptr NpadState::GetControllerState( - const NpadIdType& npad_id) const { - return state[NpadIdTypeToIndex(npad_id)]; -} - -NpadState::NpadStatus NpadState::GetStatus() const { - return data.status; -} - -void NpadState::SetNpadJoyHoldType(const NpadJoyHoldType hold_type) { - data.status.is_hold_type_set.Assign(1); - data.npad_hold_type = static_cast(hold_type); -} - -NpadJoyHoldType NpadState::GetNpadJoyHoldType() const { - return static_cast(data.npad_hold_type); -} - -Result NpadState::SetSupportedNpadIdType(std::span list) { - // Note: Real limit is 11. But array size is 10. N's bug? - if (list.size() >= PLAYERS_MAX) { - return ResultInvalidArraySize; - } - - data.supported_npad_id_types_count = static_cast(list.size()); - memcpy(data.supported_npad_id_types.data(), list.data(), list.size_bytes()); - - return ResultSuccess; -} - -void NpadState::SetSupportedNpadStyleSet(const NpadStyleSet supported_style_set) { - data.status.is_supported_style_set.Assign(1); - data.status.is_hold_type_set.Assign(1); - data.supported_npad_style_set = supported_style_set; -} - -NpadStyleSet NpadState::GetSupportedNpadStyleSet() const { - return data.supported_npad_style_set; -} - -void NpadState::SetLrAssignmentMode(const bool is_enabled) { - data.status.lr_assignment_mode.Assign(is_enabled); -} - -bool NpadState::GetLrAssignmentMode() const { - return data.status.lr_assignment_mode != 0; -} - -void NpadState::SetNpadHandheldActivationMode(const NpadHandheldActivationMode mode) { - data.handheld_activation_mode = static_cast(mode); -} - -NpadHandheldActivationMode NpadState::GetNpadHandheldActivationMode() const { - return static_cast(data.handheld_activation_mode); -} - -bool NpadState::IsUnintendedHomeButtonInputProtectionEnabled(const NpadIdType npad_id) const { - return data.is_unintended_home_button_input_protection[NpadIdTypeToIndex(npad_id)]; -} - -void NpadState::SetNpadAnalogStickUseCenterClampImpl(const bool is_enabled) { - data.status.use_center_clamp.Assign(is_enabled); -} - -void NpadState::SetCaptureButtonAssignment(const std::size_t index, - const NpadButton npad_button_set) { - data.npad_button_assignment[index] = npad_button_set; -} - -std::size_t NpadState::GetCaptureButtonAssignment( - std::span out_button_assignment) const { - if (out_button_assignment.size() < 1) { - return 0; - } - - std::size_t out_size{}; - for (std::size_t index = 0; index < 6 && out_size < out_button_assignment.size(); ++index) { - const bool is_defined = - (data.supported_npad_style_set & GetStylesetByIndex(index)) != NpadStyleSet::None; - if (is_defined && data.npad_button_assignment[index] != NpadButton::None) { - out_button_assignment[out_size] = data.npad_button_assignment[index]; - out_size++; - } - } - - return out_size; -} - -void NpadState::ClearNpadSystemCommonPolicy() { - data.status.raw = 0; - data.supported_npad_style_set = NpadStyleSet::All; - data.npad_hold_type = static_cast(NpadJoyHoldType::Vertical); - data.handheld_activation_mode = static_cast(NpadHandheldActivationMode::Dual); - - data.npad_button_assignment[0] = NpadButton::None; - data.npad_button_assignment[1] = NpadButton::None; - data.npad_button_assignment[2] = NpadButton::None; - data.npad_button_assignment[3] = NpadButton::None; - data.npad_button_assignment[4] = NpadButton::None; - data.npad_button_assignment[5] = NpadButton::None; - - data.supported_npad_id_types_count = 10; - data.supported_npad_id_types[0] = NpadIdType::Player1; - data.supported_npad_id_types[1] = NpadIdType::Player2; - data.supported_npad_id_types[2] = NpadIdType::Player3; - data.supported_npad_id_types[3] = NpadIdType::Player4; - data.supported_npad_id_types[4] = NpadIdType::Player5; - data.supported_npad_id_types[5] = NpadIdType::Player6; - data.supported_npad_id_types[6] = NpadIdType::Player7; - data.supported_npad_id_types[7] = NpadIdType::Player8; - data.supported_npad_id_types[8] = NpadIdType::Other; - data.supported_npad_id_types[9] = NpadIdType::Handheld; - - data.is_unintended_home_button_input_protection[0] = true; - data.is_unintended_home_button_input_protection[1] = true; - data.is_unintended_home_button_input_protection[2] = true; - data.is_unintended_home_button_input_protection[3] = true; - data.is_unintended_home_button_input_protection[4] = true; - data.is_unintended_home_button_input_protection[5] = true; - data.is_unintended_home_button_input_protection[6] = true; - data.is_unintended_home_button_input_protection[7] = true; - data.is_unintended_home_button_input_protection[8] = true; - data.is_unintended_home_button_input_protection[9] = true; - - data.unknown[0] = 0; - data.unknown[1] = 0; - data.unknown[2] = 0; - data.unknown[3] = 0; - data.unknown[4] = 0; - data.unknown[5] = 0; -} - -void NpadState::ApplyNpadSystemCommonPolicy(const bool is_full_policy) { - data.supported_npad_style_set = NpadStyleSet::Fullkey | NpadStyleSet::JoyDual | - NpadStyleSet::SystemExt | NpadStyleSet::System; - data.handheld_activation_mode = static_cast(NpadHandheldActivationMode::Dual); - - data.status.is_supported_style_set.Assign(1); - data.status.is_hold_type_set.Assign(1); - data.status.lr_assignment_mode.Assign(0); - data.status.is_policy.Assign(1); - if (is_full_policy) { - data.status.is_full_policy.Assign(1); - } - - data.supported_npad_id_types_count = 10; - data.supported_npad_id_types[0] = NpadIdType::Player1; - data.supported_npad_id_types[1] = NpadIdType::Player2; - data.supported_npad_id_types[2] = NpadIdType::Player3; - data.supported_npad_id_types[3] = NpadIdType::Player4; - data.supported_npad_id_types[4] = NpadIdType::Player5; - data.supported_npad_id_types[5] = NpadIdType::Player6; - data.supported_npad_id_types[6] = NpadIdType::Player7; - data.supported_npad_id_types[7] = NpadIdType::Player8; - data.supported_npad_id_types[8] = NpadIdType::Other; - data.supported_npad_id_types[9] = NpadIdType::Handheld; - - data.is_unintended_home_button_input_protection[0] = true; - data.is_unintended_home_button_input_protection[1] = true; - data.is_unintended_home_button_input_protection[2] = true; - data.is_unintended_home_button_input_protection[3] = true; - data.is_unintended_home_button_input_protection[4] = true; - data.is_unintended_home_button_input_protection[5] = true; - data.is_unintended_home_button_input_protection[6] = true; - data.is_unintended_home_button_input_protection[7] = true; - data.is_unintended_home_button_input_protection[8] = true; - data.is_unintended_home_button_input_protection[9] = true; -} - -bool NpadState::GetAssigningSingleOnSlSrPress() const { - return data.status.assigning_single_on_sl_sr_press != 0; -} - -void NpadState::SetAssigningSingleOnSlSrPress(const bool is_enabled) { - data.status.assigning_single_on_sl_sr_press.Assign(is_enabled); -} - -MaskIndex NpadState::GetMaskIndex() const { - return mask_index; -} - Npad::Npad(KernelHelpers::ServiceContext& context) : service_context{context} { for (auto& npad : npad_state) { npad = std::make_shared(); diff --git a/src/core/hle/service/hid/resource_manager/npad.h b/src/core/hle/service/hid/resource_manager/npad_resource/npad.h similarity index 65% rename from src/core/hle/service/hid/resource_manager/npad.h rename to src/core/hle/service/hid/resource_manager/npad_resource/npad.h index 52fd3ffa2..78d6d8211 100644 --- a/src/core/hle/service/hid/resource_manager/npad.h +++ b/src/core/hle/service/hid/resource_manager/npad_resource/npad.h @@ -5,8 +5,11 @@ #include #include +#include #include +#include "common/common_types.h" +#include "core/hle/result.h" #include "core/hle/service/hid/resource_manager/base_resource.h" #include "core/hle/service/kernel_helpers.h" @@ -29,109 +32,12 @@ enum class NpadButton : u64; enum class MaskIndex : u32; struct SixAxisSensorHandle; + +class NpadState; } // namespace Service::HID namespace Service::HID { -class NpadControllerState { -public: - explicit NpadControllerState(); - ~NpadControllerState(); - - NpadIdType GetNpadId() const; - u64 IsUpdatePending(); - void Update(); - - void SetNpadAssignmentMode(const NpadJoyAssignmentMode mode); - - bool IsStyleSetUpdateEventInitialized() const; - void SetStyleSetUpdateEventInitialized(const bool is_initialized); - void SetNpadStyleSetUpdateEvent(Kernel::KEvent* event); - Kernel::KReadableEvent& GetNpadStyleSetUpdateEvent(); - void SignalStyleSetUpdateEvent(); - - u32 GetConnectedControllerIndex(); - -private: - NpadIdType npad_id{}; - NpadJoyAssignmentMode assignament_mode{}; - - bool is_styleset_update_event_initialized{}; - Kernel::KEvent* style_set_update_event = nullptr; -}; - -class NpadState { -public: - struct NpadStatus { - union { - u32 raw{}; - - BitField<0, 1, u32> is_supported_style_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; - }; - }; - static_assert(sizeof(NpadStatus) == 4, "NpadStatus is an invalid size"); - - explicit NpadState(); - ~NpadState(); - - std::shared_ptr GetControllerState(const NpadIdType& npad_id) const; - NpadStatus GetStatus() const; - - void SetNpadJoyHoldType(const NpadJoyHoldType hold_type); - NpadJoyHoldType GetNpadJoyHoldType() const; - - Result SetSupportedNpadIdType(std::span list); - - void SetSupportedNpadStyleSet(const NpadStyleSet supported_style_set); - NpadStyleSet GetSupportedNpadStyleSet() const; - - void SetLrAssignmentMode(const bool is_enabled); - bool GetLrAssignmentMode() const; - - void SetNpadHandheldActivationMode(const NpadHandheldActivationMode mode); - NpadHandheldActivationMode GetNpadHandheldActivationMode() const; - - bool IsUnintendedHomeButtonInputProtectionEnabled(const NpadIdType npad_id) const; - void SetNpadAnalogStickUseCenterClampImpl(const bool is_enabled); - - void SetCaptureButtonAssignment(const std::size_t index, const NpadButton npad_button_set); - std::size_t GetCaptureButtonAssignment(std::span out_button_assignment) const; - - void ClearNpadSystemCommonPolicy(); - void ApplyNpadSystemCommonPolicy(const bool is_full_policy); - - bool GetAssigningSingleOnSlSrPress() const; - void SetAssigningSingleOnSlSrPress(const bool is_enabled); - - MaskIndex GetMaskIndex() const; - -private: - struct DataStructure { - NpadStatus status{}; - NpadStyleSet supported_npad_style_set{}; - u32 npad_hold_type{}; - u32 handheld_activation_mode{}; - std::array supported_npad_id_types{}; - std::array npad_button_assignment; - std::array unknown; - u32 supported_npad_id_types_count{}; - std::array is_unintended_home_button_input_protection{}; - INSERT_PADDING_BYTES(0x2); - }; - static_assert(sizeof(DataStructure) == 0xB0, "DataStructure is an invalid size"); - - DataStructure data{}; - - std::array, PLAYERS_MAX> state; - MaskIndex mask_index{}; -}; - class Npad final : public BaseResource { public: explicit Npad(KernelHelpers::ServiceContext& context); @@ -182,7 +88,8 @@ public: Result SetNpadCaptureButtonAssignment(const u64 aruid, const NpadStyleSet npad_styleset, const NpadButton npad_button_set); Result ClearNpadCaptureButtonAssignment(const u64 aruid); - std::size_t GetNpadCaptureButtonAssignment(const u64 aruid, std::span out_button_assignment) const; + std::size_t GetNpadCaptureButtonAssignment(const u64 aruid, + std::span out_button_assignment) const; // Events Result AcquireNpadStyleSetUpdateEventHandle(const u64 aruid, Kernel::KReadableEvent** out_event, diff --git a/src/core/hle/service/hid/resource_manager/npad_resource/npad_controller_state.cpp b/src/core/hle/service/hid/resource_manager/npad_resource/npad_controller_state.cpp new file mode 100644 index 000000000..208715239 --- /dev/null +++ b/src/core/hle/service/hid/resource_manager/npad_resource/npad_controller_state.cpp @@ -0,0 +1,69 @@ +// 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/service/hid/hid_types.h" +#include "core/hle/service/hid/resource_manager/npad_resource/npad_controller_state.h" + +namespace Service::HID { + +NpadControllerState::NpadControllerState() {} + +NpadControllerState::~NpadControllerState() = default; + +NpadIdType NpadControllerState::GetNpadId() const { + return npad_id; +} + +u64 NpadControllerState::IsUpdatePending() { + return 0; +} + +void NpadControllerState::Update() {} + +void NpadControllerState::SetNpadAssignmentMode(const NpadJoyAssignmentMode mode) { + assignament_mode = mode; +} + +bool NpadControllerState::IsStyleSetUpdateEventInitialized() const { + return is_styleset_update_event_initialized; +} + +void NpadControllerState::SetStyleSetUpdateEventInitialized(const bool is_initialized) { + is_styleset_update_event_initialized = is_initialized; +} + +void NpadControllerState::SetNpadStyleSetUpdateEvent(Kernel::KEvent* event) { + style_set_update_event = event; +} + +Kernel::KReadableEvent& NpadControllerState::GetNpadStyleSetUpdateEvent() { + return style_set_update_event->GetReadableEvent(); +} + +void NpadControllerState::SignalStyleSetUpdateEvent() { + style_set_update_event->Signal(); +} + +u32 NpadControllerState::GetConnectedControllerIndex() { + u32 connected_controllers = 0; + u32 connected_index = 0; + + // u32 index = 0; + + if (connected_controllers == 0) { + return 0; + } + + if (connected_controllers != 1) { + // Something Fun happens here + } + + if ((connected_controllers & 1) != 0) { + // connected_index |= somearray[index]; + } + + return connected_index; +} + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/resource_manager/npad_resource/npad_controller_state.h b/src/core/hle/service/hid/resource_manager/npad_resource/npad_controller_state.h new file mode 100644 index 000000000..1757eb372 --- /dev/null +++ b/src/core/hle/service/hid/resource_manager/npad_resource/npad_controller_state.h @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +namespace Kernel { +class KReadableEvent; +} + +namespace Service::HID { +enum class NpadIdType : u32; +enum class NpadJoyAssignmentMode : u32; +} // namespace Service::HID + +namespace Service::HID { + +class NpadControllerState { +public: + explicit NpadControllerState(); + ~NpadControllerState(); + + NpadIdType GetNpadId() const; + u64 IsUpdatePending(); + void Update(); + + void SetNpadAssignmentMode(const NpadJoyAssignmentMode mode); + + bool IsStyleSetUpdateEventInitialized() const; + void SetStyleSetUpdateEventInitialized(const bool is_initialized); + void SetNpadStyleSetUpdateEvent(Kernel::KEvent* event); + Kernel::KReadableEvent& GetNpadStyleSetUpdateEvent(); + void SignalStyleSetUpdateEvent(); + + u32 GetConnectedControllerIndex(); + +private: + NpadIdType npad_id{}; + NpadJoyAssignmentMode assignament_mode{}; + + bool is_styleset_update_event_initialized{}; + Kernel::KEvent* style_set_update_event = nullptr; +}; + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/resource_manager/npad_resource/npad_state.cpp b/src/core/hle/service/hid/resource_manager/npad_resource/npad_state.cpp new file mode 100644 index 000000000..2d4a3e41c --- /dev/null +++ b/src/core/hle/service/hid/resource_manager/npad_resource/npad_state.cpp @@ -0,0 +1,201 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/service/hid/hid_result.h" +#include "core/hle/service/hid/hid_types.h" +#include "core/hle/service/hid/hid_util.h" +#include "core/hle/service/hid/resource_manager/npad_resource/npad_controller_state.h" +#include "core/hle/service/hid/resource_manager/npad_resource/npad_state.h" + +namespace Service::HID { + +NpadState::NpadState() { + for (auto npad : state) { + npad = std::make_shared(); + } +} + +NpadState::~NpadState() = default; + +std::shared_ptr NpadState::GetControllerState( + const NpadIdType& npad_id) const { + return state[NpadIdTypeToIndex(npad_id)]; +} + +NpadState::NpadStatus NpadState::GetStatus() const { + return data.status; +} + +void NpadState::SetNpadJoyHoldType(const NpadJoyHoldType hold_type) { + data.status.is_hold_type_set.Assign(1); + data.npad_hold_type = static_cast(hold_type); +} + +NpadJoyHoldType NpadState::GetNpadJoyHoldType() const { + return static_cast(data.npad_hold_type); +} + +Result NpadState::SetSupportedNpadIdType(std::span list) { + // Note: Real limit is 11. But array size is 10. N's bug? + if (list.size() >= PLAYERS_MAX) { + return ResultInvalidArraySize; + } + + data.supported_npad_id_types_count = static_cast(list.size()); + memcpy(data.supported_npad_id_types.data(), list.data(), list.size_bytes()); + + return ResultSuccess; +} + +void NpadState::SetSupportedNpadStyleSet(const NpadStyleSet supported_style_set) { + data.status.is_supported_style_set.Assign(1); + data.status.is_hold_type_set.Assign(1); + data.supported_npad_style_set = supported_style_set; +} + +NpadStyleSet NpadState::GetSupportedNpadStyleSet() const { + return data.supported_npad_style_set; +} + +void NpadState::SetLrAssignmentMode(const bool is_enabled) { + data.status.lr_assignment_mode.Assign(is_enabled); +} + +bool NpadState::GetLrAssignmentMode() const { + return data.status.lr_assignment_mode != 0; +} + +void NpadState::SetNpadHandheldActivationMode(const NpadHandheldActivationMode mode) { + data.handheld_activation_mode = static_cast(mode); +} + +NpadHandheldActivationMode NpadState::GetNpadHandheldActivationMode() const { + return static_cast(data.handheld_activation_mode); +} + +bool NpadState::IsUnintendedHomeButtonInputProtectionEnabled(const NpadIdType npad_id) const { + return data.is_unintended_home_button_input_protection[NpadIdTypeToIndex(npad_id)]; +} + +void NpadState::SetNpadAnalogStickUseCenterClampImpl(const bool is_enabled) { + data.status.use_center_clamp.Assign(is_enabled); +} + +void NpadState::SetCaptureButtonAssignment(const std::size_t index, + const NpadButton npad_button_set) { + data.npad_button_assignment[index] = npad_button_set; +} + +std::size_t NpadState::GetCaptureButtonAssignment( + std::span out_button_assignment) const { + if (out_button_assignment.size() < 1) { + return 0; + } + + std::size_t out_size{}; + for (std::size_t index = 0; index < 6 && out_size < out_button_assignment.size(); ++index) { + const bool is_defined = + (data.supported_npad_style_set & GetStylesetByIndex(index)) != NpadStyleSet::None; + if (is_defined && data.npad_button_assignment[index] != NpadButton::None) { + out_button_assignment[out_size] = data.npad_button_assignment[index]; + out_size++; + } + } + + return out_size; +} + +void NpadState::ClearNpadSystemCommonPolicy() { + data.status.raw = 0; + data.supported_npad_style_set = NpadStyleSet::All; + data.npad_hold_type = static_cast(NpadJoyHoldType::Vertical); + data.handheld_activation_mode = static_cast(NpadHandheldActivationMode::Dual); + + data.npad_button_assignment[0] = NpadButton::None; + data.npad_button_assignment[1] = NpadButton::None; + data.npad_button_assignment[2] = NpadButton::None; + data.npad_button_assignment[3] = NpadButton::None; + data.npad_button_assignment[4] = NpadButton::None; + data.npad_button_assignment[5] = NpadButton::None; + + data.supported_npad_id_types_count = 10; + data.supported_npad_id_types[0] = NpadIdType::Player1; + data.supported_npad_id_types[1] = NpadIdType::Player2; + data.supported_npad_id_types[2] = NpadIdType::Player3; + data.supported_npad_id_types[3] = NpadIdType::Player4; + data.supported_npad_id_types[4] = NpadIdType::Player5; + data.supported_npad_id_types[5] = NpadIdType::Player6; + data.supported_npad_id_types[6] = NpadIdType::Player7; + data.supported_npad_id_types[7] = NpadIdType::Player8; + data.supported_npad_id_types[8] = NpadIdType::Other; + data.supported_npad_id_types[9] = NpadIdType::Handheld; + + data.is_unintended_home_button_input_protection[0] = true; + data.is_unintended_home_button_input_protection[1] = true; + data.is_unintended_home_button_input_protection[2] = true; + data.is_unintended_home_button_input_protection[3] = true; + data.is_unintended_home_button_input_protection[4] = true; + data.is_unintended_home_button_input_protection[5] = true; + data.is_unintended_home_button_input_protection[6] = true; + data.is_unintended_home_button_input_protection[7] = true; + data.is_unintended_home_button_input_protection[8] = true; + data.is_unintended_home_button_input_protection[9] = true; + + data.unknown[0] = 0; + data.unknown[1] = 0; + data.unknown[2] = 0; + data.unknown[3] = 0; + data.unknown[4] = 0; + data.unknown[5] = 0; +} + +void NpadState::ApplyNpadSystemCommonPolicy(const bool is_full_policy) { + data.supported_npad_style_set = NpadStyleSet::Fullkey | NpadStyleSet::JoyDual | + NpadStyleSet::SystemExt | NpadStyleSet::System; + data.handheld_activation_mode = static_cast(NpadHandheldActivationMode::Dual); + + data.status.is_supported_style_set.Assign(1); + data.status.is_hold_type_set.Assign(1); + data.status.lr_assignment_mode.Assign(0); + data.status.is_policy.Assign(1); + if (is_full_policy) { + data.status.is_full_policy.Assign(1); + } + + data.supported_npad_id_types_count = 10; + data.supported_npad_id_types[0] = NpadIdType::Player1; + data.supported_npad_id_types[1] = NpadIdType::Player2; + data.supported_npad_id_types[2] = NpadIdType::Player3; + data.supported_npad_id_types[3] = NpadIdType::Player4; + data.supported_npad_id_types[4] = NpadIdType::Player5; + data.supported_npad_id_types[5] = NpadIdType::Player6; + data.supported_npad_id_types[6] = NpadIdType::Player7; + data.supported_npad_id_types[7] = NpadIdType::Player8; + data.supported_npad_id_types[8] = NpadIdType::Other; + data.supported_npad_id_types[9] = NpadIdType::Handheld; + + data.is_unintended_home_button_input_protection[0] = true; + data.is_unintended_home_button_input_protection[1] = true; + data.is_unintended_home_button_input_protection[2] = true; + data.is_unintended_home_button_input_protection[3] = true; + data.is_unintended_home_button_input_protection[4] = true; + data.is_unintended_home_button_input_protection[5] = true; + data.is_unintended_home_button_input_protection[6] = true; + data.is_unintended_home_button_input_protection[7] = true; + data.is_unintended_home_button_input_protection[8] = true; + data.is_unintended_home_button_input_protection[9] = true; +} + +bool NpadState::GetAssigningSingleOnSlSrPress() const { + return data.status.assigning_single_on_sl_sr_press != 0; +} + +void NpadState::SetAssigningSingleOnSlSrPress(const bool is_enabled) { + data.status.assigning_single_on_sl_sr_press.Assign(is_enabled); +} + +MaskIndex NpadState::GetMaskIndex() const { + return mask_index; +} + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/resource_manager/npad_resource/npad_state.h b/src/core/hle/service/hid/resource_manager/npad_resource/npad_state.h new file mode 100644 index 000000000..d4fcf7106 --- /dev/null +++ b/src/core/hle/service/hid/resource_manager/npad_resource/npad_state.h @@ -0,0 +1,101 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include +#include + +#include "core/hle/service/hid/resource_manager/base_resource.h" + +namespace Core { +class System; +} + +namespace Service::HID { +enum class NpadIdType : u32; +enum class NpadHandheldActivationMode : u64; +enum class NpadStyleSet : u32; +enum class NpadJoyHoldType : u64; +enum class NpadButton : u64; +enum class MaskIndex : u32; + +class NpadControllerState; +} // namespace Service::HID + +namespace Service::HID { + +class NpadState { +public: + struct NpadStatus { + union { + u32 raw{}; + + BitField<0, 1, u32> is_supported_style_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; + }; + }; + static_assert(sizeof(NpadStatus) == 4, "NpadStatus is an invalid size"); + + explicit NpadState(); + ~NpadState(); + + std::shared_ptr GetControllerState(const NpadIdType& npad_id) const; + NpadStatus GetStatus() const; + + void SetNpadJoyHoldType(const NpadJoyHoldType hold_type); + NpadJoyHoldType GetNpadJoyHoldType() const; + + Result SetSupportedNpadIdType(std::span list); + + void SetSupportedNpadStyleSet(const NpadStyleSet supported_style_set); + NpadStyleSet GetSupportedNpadStyleSet() const; + + void SetLrAssignmentMode(const bool is_enabled); + bool GetLrAssignmentMode() const; + + void SetNpadHandheldActivationMode(const NpadHandheldActivationMode mode); + NpadHandheldActivationMode GetNpadHandheldActivationMode() const; + + bool IsUnintendedHomeButtonInputProtectionEnabled(const NpadIdType npad_id) const; + void SetNpadAnalogStickUseCenterClampImpl(const bool is_enabled); + + void SetCaptureButtonAssignment(const std::size_t index, const NpadButton npad_button_set); + std::size_t GetCaptureButtonAssignment(std::span out_button_assignment) const; + + void ClearNpadSystemCommonPolicy(); + void ApplyNpadSystemCommonPolicy(const bool is_full_policy); + + bool GetAssigningSingleOnSlSrPress() const; + void SetAssigningSingleOnSlSrPress(const bool is_enabled); + + MaskIndex GetMaskIndex() const; + +private: + struct DataStructure { + NpadStatus status{}; + NpadStyleSet supported_npad_style_set{}; + u32 npad_hold_type{}; + u32 handheld_activation_mode{}; + std::array supported_npad_id_types{}; + std::array npad_button_assignment; + std::array unknown; + u32 supported_npad_id_types_count{}; + std::array is_unintended_home_button_input_protection{}; + INSERT_PADDING_BYTES(0x2); + }; + static_assert(sizeof(DataStructure) == 0xB0, "DataStructure is an invalid size"); + + DataStructure data{}; + + std::array, PLAYERS_MAX> state; + MaskIndex mask_index{}; +}; + +} // namespace Service::HID