accuracy fixes and end of day 4

This commit is contained in:
Narr the Reg 2023-08-16 01:29:43 -06:00
parent bb6b22482f
commit 62edb120c1
4 changed files with 111 additions and 38 deletions

View File

@ -6,6 +6,7 @@
#include "core/hle/service/hid/hid_types.h" #include "core/hle/service/hid/hid_types.h"
#include "core/hle/service/hid/hid_util.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.h"
#include "core/hle/service/kernel_helpers.h"
#pragma optimize("", off) #pragma optimize("", off)
namespace Service::HID { namespace Service::HID {
@ -28,6 +29,18 @@ void NpadControllerState::SetNpadAssignmentMode(const NpadJoyAssignmentMode mode
assignament_mode = 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() { Kernel::KReadableEvent& NpadControllerState::GetNpadStyleSetUpdateEvent() {
return style_set_update_event->GetReadableEvent(); return style_set_update_event->GetReadableEvent();
} }
@ -70,13 +83,17 @@ std::shared_ptr<NpadControllerState> NpadState::GetControllerState(
return state[NpadIdTypeToIndex(npad_id)]; return state[NpadIdTypeToIndex(npad_id)];
} }
NpadState::NpadStatus NpadState::GetStatus() const {
return data.status;
}
void NpadState::SetNpadJoyHoldType(const NpadJoyHoldType hold_type) { void NpadState::SetNpadJoyHoldType(const NpadJoyHoldType hold_type) {
status.is_hold_type_set.Assign(1); data.status.is_hold_type_set.Assign(1);
npad_hold_type = hold_type; data.npad_hold_type = static_cast<u32>(hold_type);
} }
NpadJoyHoldType NpadState::GetNpadJoyHoldType() const { NpadJoyHoldType NpadState::GetNpadJoyHoldType() const {
return npad_hold_type; return static_cast<NpadJoyHoldType>(data.npad_hold_type);
} }
Result NpadState::SetSupportedNpadIdType(std::span<const NpadIdType> list) { Result NpadState::SetSupportedNpadIdType(std::span<const NpadIdType> list) {
@ -84,47 +101,47 @@ Result NpadState::SetSupportedNpadIdType(std::span<const NpadIdType> list) {
return ResultInvalidArraySize; return ResultInvalidArraySize;
} }
supported_npad_id_types_count = list.size(); data.supported_npad_id_types_count = list.size();
memcpy(supported_npad_id_types.data(), list.data(), list.size_bytes()); memcpy(data.supported_npad_id_types.data(), list.data(), list.size_bytes());
return ResultSuccess; return ResultSuccess;
} }
void NpadState::SetSupportedNpadStyleSet(const NpadStyleSet supported_style_set) { void NpadState::SetSupportedNpadStyleSet(const NpadStyleSet supported_style_set) {
status.is_supported_style_set.Assign(1); data.status.is_supported_style_set.Assign(1);
status.is_hold_type_set.Assign(1); data.status.is_hold_type_set.Assign(1);
supported_npad_style_set = supported_style_set; data.supported_npad_style_set = supported_style_set;
} }
NpadStyleSet NpadState::GetSupportedNpadStyleSet() const { NpadStyleSet NpadState::GetSupportedNpadStyleSet() const {
return supported_npad_style_set; return data.supported_npad_style_set;
} }
void NpadState::SetLrAssignmentMode(const bool is_enabled) { void NpadState::SetLrAssignmentMode(const bool is_enabled) {
status.lr_assignment_mode.Assign(is_enabled); data.status.lr_assignment_mode.Assign(is_enabled);
} }
bool NpadState::GetLrAssignmentMode() const { bool NpadState::GetLrAssignmentMode() const {
return status.lr_assignment_mode != 0; return data.status.lr_assignment_mode != 0;
} }
void NpadState::SetNpadHandheldActivationMode(const NpadHandheldActivationMode mode) { void NpadState::SetNpadHandheldActivationMode(const NpadHandheldActivationMode mode) {
handheld_activation_mode = mode; data.handheld_activation_mode = static_cast<u32>(mode);
} }
NpadHandheldActivationMode NpadState::GetNpadHandheldActivationMode() const { NpadHandheldActivationMode NpadState::GetNpadHandheldActivationMode() const {
return handheld_activation_mode; return static_cast<NpadHandheldActivationMode>(data.handheld_activation_mode);
} }
bool NpadState::IsUnintendedHomeButtonInputProtectionEnabled() const { bool NpadState::IsUnintendedHomeButtonInputProtectionEnabled(const NpadIdType npad_id) const {
return unintended_home_button_input_proptection; return data.is_unintended_home_button_input_proptection[NpadIdTypeToIndex(npad_id)];
} }
void NpadState::SetNpadAnalogStickUseCenterClampImpl(const bool is_enabled) { void NpadState::SetNpadAnalogStickUseCenterClampImpl(const bool is_enabled) {
status.use_center_clamp.Assign(is_enabled); data.status.use_center_clamp.Assign(is_enabled);
} }
Npad::Npad() { Npad::Npad(KernelHelpers::ServiceContext& context) : service_context{context} {
for (auto& npad : npad_state) { for (auto& npad : npad_state) {
npad = std::make_shared<NpadState>(); npad = std::make_shared<NpadState>();
} }
@ -163,6 +180,7 @@ void Npad::ForceDisconnectNpad(const NpadIdType npad_id) {
void Npad::DisconnectAbstractPad(const NpadIdType npad_id) {} void Npad::DisconnectAbstractPad(const NpadIdType npad_id) {}
Result Npad::SetNpadJoyHoldType(const u64 aruid, const NpadJoyHoldType hold_type) { Result Npad::SetNpadJoyHoldType(const u64 aruid, const NpadJoyHoldType hold_type) {
std::scoped_lock lock{mutex};
const auto index = GetIndexFromAruid(aruid); const auto index = GetIndexFromAruid(aruid);
if (index >= ARUID_MAX) { if (index >= ARUID_MAX) {
@ -178,15 +196,16 @@ Result Npad::SetNpadJoyHoldType(const u64 aruid, const NpadJoyHoldType hold_type
} }
Result Npad::GetNpadJoyHoldType(const u64 aruid, NpadJoyHoldType& out_hold_type) const { Result Npad::GetNpadJoyHoldType(const u64 aruid, NpadJoyHoldType& out_hold_type) const {
std::scoped_lock lock{mutex};
const auto index = GetIndexFromAruid(aruid); const auto index = GetIndexFromAruid(aruid);
if (index >= ARUID_MAX) { if (index >= ARUID_MAX) {
return ResultNpadNotConnected; return ResultNpadNotConnected;
} }
const auto state = npad_state[index]; const auto& state = npad_state[index];
out_hold_type = state->GetNpadJoyHoldType(); out_hold_type = state->GetNpadJoyHoldType();
if ((state->status.raw & 0x30) != 0) { if ((state->GetStatus().raw & 0x30) != 0) { // TODO: Find name for 0x30
out_hold_type = active_npad_state->GetNpadJoyHoldType(); out_hold_type = active_npad_state->GetNpadJoyHoldType();
} }
@ -194,6 +213,7 @@ Result Npad::GetNpadJoyHoldType(const u64 aruid, NpadJoyHoldType& out_hold_type)
} }
Result Npad::SetSupportedNpadIdType(const u64 aruid, std::span<const NpadIdType> list) { Result Npad::SetSupportedNpadIdType(const u64 aruid, std::span<const NpadIdType> list) {
std::scoped_lock lock{mutex};
if (list.size() >= SUPPORTED_NPAD_TYPES_MAX) { if (list.size() >= SUPPORTED_NPAD_TYPES_MAX) {
return ResultInvalidArraySize; return ResultInvalidArraySize;
} }
@ -228,6 +248,7 @@ Result Npad::SetSupportedNpadIdTypeImpl(const u64 aruid, std::span<const NpadIdT
} }
Result Npad::SetSupportedNpadStyleSet(const u64 aruid, const NpadStyleSet supported_style_set) { Result Npad::SetSupportedNpadStyleSet(const u64 aruid, const NpadStyleSet supported_style_set) {
std::scoped_lock lock{mutex};
const Result result = SetSupportedNpadStyleSetImpl(aruid, supported_style_set); const Result result = SetSupportedNpadStyleSetImpl(aruid, supported_style_set);
if (result.IsSuccess()) { if (result.IsSuccess()) {
@ -257,6 +278,7 @@ Result Npad::SetSupportedNpadStyleSetImpl(const u64 aruid, const NpadStyleSet su
Result Npad::GetSupportedNpadStyleSet(const u64 aruid, Result Npad::GetSupportedNpadStyleSet(const u64 aruid,
NpadStyleSet& out_supported_style_set) const { NpadStyleSet& out_supported_style_set) const {
std::scoped_lock lock{mutex};
const Result result = GetSupportedNpadStyleSetImpl(aruid, out_supported_style_set); const Result result = GetSupportedNpadStyleSetImpl(aruid, out_supported_style_set);
if (result == ResultNpadNotConnected) { if (result == ResultNpadNotConnected) {
@ -275,7 +297,7 @@ Result Npad::GetSupportedNpadStyleSetImpl(const u64 aruid,
return ResultNpadNotConnected; return ResultNpadNotConnected;
} }
if (npad_state[index]->status.is_supported_style_set == 0) { if (npad_state[index]->GetStatus().is_supported_style_set == 0) {
return ResultUndefinedStyleSet; return ResultUndefinedStyleSet;
} }
@ -421,6 +443,7 @@ Result Npad::SwapNpadAssignment(const u64 aruid, const NpadIdType npad_id_1,
} }
Result Npad::StartLrAssignmentMode(const u64 aruid) { Result Npad::StartLrAssignmentMode(const u64 aruid) {
std::scoped_lock lock{mutex};
bool is_enabled{}; bool is_enabled{};
Result result = GetLrAssignmentMode(is_enabled, aruid); Result result = GetLrAssignmentMode(is_enabled, aruid);
@ -432,6 +455,7 @@ Result Npad::StartLrAssignmentMode(const u64 aruid) {
} }
Result Npad::StopLrAssignmentMode(const u64 aruid) { Result Npad::StopLrAssignmentMode(const u64 aruid) {
std::scoped_lock lock{mutex};
bool is_enabled{}; bool is_enabled{};
Result result = GetLrAssignmentMode(is_enabled, aruid); Result result = GetLrAssignmentMode(is_enabled, aruid);
@ -470,9 +494,11 @@ Result Npad::GetLrAssignmentMode(bool& out_is_enabled, const u64 aruid) const {
} }
Result Npad::SetNpadHandheldActivationMode(const u64 aruid, const NpadHandheldActivationMode mode) { Result Npad::SetNpadHandheldActivationMode(const u64 aruid, const NpadHandheldActivationMode mode) {
std::scoped_lock lock{mutex};
const Result result = SetNpadHandheldActivationModeImpl(aruid, mode); const Result result = SetNpadHandheldActivationModeImpl(aruid, mode);
if (result.IsSuccess()) { if (result.IsSuccess()) {
// TODO: recheck this part
active_npad_state->GetControllerState(NpadIdType::Handheld)->Update(); active_npad_state->GetControllerState(NpadIdType::Handheld)->Update();
} }
@ -497,6 +523,12 @@ Result Npad::SetNpadHandheldActivationModeImpl(const u64 aruid,
Result Npad::GetNpadHandheldActivationMode(const u64 aruid, Result Npad::GetNpadHandheldActivationMode(const u64 aruid,
NpadHandheldActivationMode& out_mode) const { NpadHandheldActivationMode& out_mode) const {
std::scoped_lock lock{mutex};
return GetNpadHandheldActivationModeImpl(aruid, out_mode);
}
Result Npad::GetNpadHandheldActivationModeImpl(const u64 aruid,
NpadHandheldActivationMode& out_mode) const {
const auto index = GetIndexFromAruid(aruid); const auto index = GetIndexFromAruid(aruid);
if (index >= ARUID_MAX) { if (index >= ARUID_MAX) {
@ -510,13 +542,19 @@ Result Npad::GetNpadHandheldActivationMode(const u64 aruid,
Result Npad::IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, const u64 aruid, Result Npad::IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, const u64 aruid,
const NpadIdType npad_id) const { const NpadIdType npad_id) const {
std::scoped_lock lock{mutex};
return IsUnintendedHomeButtonInputProtectionEnabledImpl(out_is_enabled, aruid, npad_id);
}
Result Npad::IsUnintendedHomeButtonInputProtectionEnabledImpl(bool& out_is_enabled, const u64 aruid,
const NpadIdType npad_id) const {
const auto index = GetIndexFromAruid(aruid); const auto index = GetIndexFromAruid(aruid);
if (index >= ARUID_MAX) { if (index >= ARUID_MAX) {
return ResultNpadNotConnected; return ResultNpadNotConnected;
} }
out_is_enabled = npad_state[index]->IsUnintendedHomeButtonInputProtectionEnabled(); out_is_enabled = npad_state[index]->IsUnintendedHomeButtonInputProtectionEnabled(npad_id);
return ResultSuccess; return ResultSuccess;
} }
@ -561,17 +599,31 @@ Result Npad::ClearNpadCaptureButtonAssignment(const u64 aruid) {
Result Npad::AcquireNpadStyleSetUpdateEventHandle(const u64 aruid, Result Npad::AcquireNpadStyleSetUpdateEventHandle(const u64 aruid,
Kernel::KReadableEvent** out_event, Kernel::KReadableEvent** out_event,
const NpadIdType npad_id) { const NpadIdType npad_id) {
std::scoped_lock lock{mutex};
const auto index = GetIndexFromAruid(aruid); const auto index = GetIndexFromAruid(aruid);
if (index >= ARUID_MAX) { if (index >= ARUID_MAX) {
return ResultNpadNotConnected; return ResultNpadNotConnected;
} }
// This is greatly simplified. The event should be created here on first call
auto state = npad_state[index]->GetControllerState(npad_id); auto state = npad_state[index]->GetControllerState(npad_id);
if (!state->IsStyleSetUpdateEventInitialized()) {
state->SetStyleSetUpdateEventInitialized(false);
// Auto clear = true
Kernel::KEvent* styleset_update_event =
service_context.CreateEvent("ResourceManager:Npad:StylesetUpdateEvent");
state->SetNpadStyleSetUpdateEvent(std::move(styleset_update_event));
// Assume creating the event succeeds otherwise crash the system here
state->SetStyleSetUpdateEventInitialized(true);
}
*out_event = &state->GetNpadStyleSetUpdateEvent(); *out_event = &state->GetNpadStyleSetUpdateEvent();
state->SignalStyleSetUpdateEvent();
if (state->IsStyleSetUpdateEventInitialized()) {
state->SignalStyleSetUpdateEvent();
}
return ResultSuccess; return ResultSuccess;
} }

View File

@ -15,6 +15,10 @@ namespace Kernel {
class KReadableEvent; class KReadableEvent;
} }
namespace KernelHelpers {
class ServiceContext;
}
namespace Service::HID { namespace Service::HID {
enum class NpadIdType : u32; enum class NpadIdType : u32;
enum class NpadJoyAssignmentMode : u32; enum class NpadJoyAssignmentMode : u32;
@ -40,6 +44,9 @@ public:
void SetNpadAssignmentMode(const NpadJoyAssignmentMode mode); void SetNpadAssignmentMode(const NpadJoyAssignmentMode mode);
bool IsStyleSetUpdateEventInitialized() const;
void SetStyleSetUpdateEventInitialized(const bool is_initialized);
void SetNpadStyleSetUpdateEvent(Kernel::KEvent* event);
Kernel::KReadableEvent& GetNpadStyleSetUpdateEvent(); Kernel::KReadableEvent& GetNpadStyleSetUpdateEvent();
void SignalStyleSetUpdateEvent(); void SignalStyleSetUpdateEvent();
@ -49,6 +56,7 @@ private:
NpadIdType npad_id{}; NpadIdType npad_id{};
NpadJoyAssignmentMode assignament_mode{}; NpadJoyAssignmentMode assignament_mode{};
bool is_styleset_update_event_initialized{};
Kernel::KEvent* style_set_update_event = nullptr; Kernel::KEvent* style_set_update_event = nullptr;
}; };
@ -61,7 +69,7 @@ public:
BitField<0, 1, u32> is_supported_style_set; BitField<0, 1, u32> is_supported_style_set;
BitField<1, 1, u32> is_hold_type_set; BitField<1, 1, u32> is_hold_type_set;
BitField<2, 1, u32> lr_assignment_mode; BitField<2, 1, u32> lr_assignment_mode;
BitField<7, 1, u32> use_center_clamp; BitField<6, 1, u32> use_center_clamp;
}; };
}; };
static_assert(sizeof(NpadStatus) == 4, "NpadStatus is an invalid size"); static_assert(sizeof(NpadStatus) == 4, "NpadStatus is an invalid size");
@ -70,6 +78,7 @@ public:
~NpadState(); ~NpadState();
std::shared_ptr<NpadControllerState> GetControllerState(const NpadIdType& npad_id) const; std::shared_ptr<NpadControllerState> GetControllerState(const NpadIdType& npad_id) const;
NpadStatus GetStatus() const;
void SetNpadJoyHoldType(const NpadJoyHoldType hold_type); void SetNpadJoyHoldType(const NpadJoyHoldType hold_type);
NpadJoyHoldType GetNpadJoyHoldType() const; NpadJoyHoldType GetNpadJoyHoldType() const;
@ -85,26 +94,31 @@ public:
void SetNpadHandheldActivationMode(const NpadHandheldActivationMode mode); void SetNpadHandheldActivationMode(const NpadHandheldActivationMode mode);
NpadHandheldActivationMode GetNpadHandheldActivationMode() const; NpadHandheldActivationMode GetNpadHandheldActivationMode() const;
bool IsUnintendedHomeButtonInputProtectionEnabled() const; bool IsUnintendedHomeButtonInputProtectionEnabled(const NpadIdType npad_id) const;
void SetNpadAnalogStickUseCenterClampImpl(const bool is_enabled); void SetNpadAnalogStickUseCenterClampImpl(const bool is_enabled);
NpadStatus status{};
private: private:
NpadJoyHoldType npad_hold_type{}; struct DataStructure {
NpadStyleSet supported_npad_style_set{}; NpadStatus status{};
NpadHandheldActivationMode handheld_activation_mode{}; NpadStyleSet supported_npad_style_set{};
bool unintended_home_button_input_proptection{}; u32 npad_hold_type{};
u32 handheld_activation_mode{};
std::array<NpadIdType, SUPPORTED_NPAD_TYPES_MAX> supported_npad_id_types{};
INSERT_PADDING_BYTES(0x64);
u32 supported_npad_id_types_count{};
std::array<bool, PLAYERS_MAX> is_unintended_home_button_input_proptection{};
INSERT_PADDING_BYTES(0x2);
};
static_assert(sizeof(DataStructure) == 0xB0, "DataStructure is an invalid size");
std::size_t supported_npad_id_types_count{}; DataStructure data{};
std::array<NpadIdType, SUPPORTED_NPAD_TYPES_MAX> supported_npad_id_types{};
std::array<std::shared_ptr<NpadControllerState>, PLAYERS_MAX> state; std::array<std::shared_ptr<NpadControllerState>, PLAYERS_MAX> state;
}; };
class Npad final : public BaseResource { class Npad final : public BaseResource {
public: public:
explicit Npad(); explicit Npad(KernelHelpers::ServiceContext& context);
~Npad(); ~Npad();
Result Activate(const u64 aruid); Result Activate(const u64 aruid);
@ -170,6 +184,11 @@ private:
Result GetLrAssignmentMode(bool& out_is_enabled, const u64 aruid) const; Result GetLrAssignmentMode(bool& out_is_enabled, const u64 aruid) const;
Result SetNpadHandheldActivationModeImpl(const u64 aruid, Result SetNpadHandheldActivationModeImpl(const u64 aruid,
const NpadHandheldActivationMode mode); const NpadHandheldActivationMode mode);
Result GetNpadHandheldActivationModeImpl(const u64 aruid,
NpadHandheldActivationMode& out_mode) const;
Result IsUnintendedHomeButtonInputProtectionEnabledImpl(bool& out_is_enabled, const u64 aruid,
const NpadIdType npad_id) const;
Result SetNpadAnalogStickUseCenterClampImpl(const u64 aruid, const bool use_center_clamp); Result SetNpadAnalogStickUseCenterClampImpl(const u64 aruid, const bool use_center_clamp);
// Update state // Update state
@ -177,9 +196,11 @@ private:
void UpdateSupportedStyleSet(); void UpdateSupportedStyleSet();
u64 GetNpadActiveAruid(); u64 GetNpadActiveAruid();
mutable std::mutex mutex;
u64 active_aruid{}; u64 active_aruid{};
std::shared_ptr<NpadState> active_npad_state = nullptr; std::shared_ptr<NpadState> active_npad_state = nullptr;
std::array<std::shared_ptr<NpadState>, ARUID_MAX> npad_state{}; std::array<std::shared_ptr<NpadState>, ARUID_MAX> npad_state{};
KernelHelpers::ServiceContext& service_context;
}; };
} // namespace Service::HID } // namespace Service::HID

View File

@ -5,7 +5,7 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/service/hid/hid_server/hid_types.h" #include "core/hle/service/hid/hid_types.h"
#include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_event.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/nfc/common/device.h" #include "core/hle/service/nfc/common/device.h"
@ -13,7 +13,7 @@
#include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/nfc/nfc_result.h"
#include "core/hle/service/time/clock_types.h" #include "core/hle/service/time/clock_types.h"
#include "core/hle/service/time/time_manager.h" #include "core/hle/service/time/time_manager.h"
#include "core/hle/service/hid/hid_server/hid_util.h" #include "core/hle/service/hid/hid_util.h"
namespace Service::NFC { namespace Service::NFC {

View File

@ -100,7 +100,7 @@ private:
std::array<std::shared_ptr<NfcDevice>, 10> devices{}; std::array<std::shared_ptr<NfcDevice>, 10> devices{};
Core::System& system; Core::System& system;
KernelHelpers::ServiceContext service_context; KernelHelpers::ServiceContext& service_context;
Kernel::KEvent* availability_change_event; Kernel::KEvent* availability_change_event;
}; };