I don't like abstract npad
This commit is contained in:
parent
74a1fba8e0
commit
d669f7e15f
|
@ -534,6 +534,7 @@ add_library(core STATIC
|
|||
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/npad_resource/npad_shared_types.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
|
||||
|
@ -546,6 +547,7 @@ add_library(core STATIC
|
|||
hle/service/hid/resource_manager/mouse.h
|
||||
hle/service/hid/resource_manager/palma.cpp
|
||||
hle/service/hid/resource_manager/palma.h
|
||||
hle/service/hid/resource_manager/ring_lifo.h
|
||||
hle/service/hid/resource_manager/sixaxis.cpp
|
||||
hle/service/hid/resource_manager/sixaxis.h
|
||||
hle/service/hid/resource_manager/touch_screen.cpp
|
||||
|
|
|
@ -1264,7 +1264,7 @@ void IHidServer::ActivateNpad(HLERequestContext& ctx) {
|
|||
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||
|
||||
const auto npad = GetResourceManager()->GetNpad();
|
||||
npad->ActivateWithRevision(applet_resource_user_id, 0);
|
||||
npad->ActivateWithRevision(applet_resource_user_id, NpadRevision::Revision0);
|
||||
const auto result = npad->Activate(applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
|
@ -1370,7 +1370,7 @@ void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) {
|
|||
void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
s32 revision;
|
||||
NpadRevision revision;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u64 applet_resource_user_id;
|
||||
};
|
||||
|
|
|
@ -220,15 +220,15 @@ enum class NpadIdType : u32 {
|
|||
Invalid = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
enum class MaskIndex : u32 {
|
||||
Normal = 0,
|
||||
GC = 1,
|
||||
Extended = 2,
|
||||
Full = 3,
|
||||
enum class NpadRevision : u32 {
|
||||
Revision0 = 0,
|
||||
Revision1 = 1,
|
||||
Revision2 = 2,
|
||||
Revision3 = 3,
|
||||
};
|
||||
static_assert(sizeof(MaskIndex) == 4, "MaskIndex is an invalid size");
|
||||
static_assert(sizeof(NpadRevision) == 4, "NpadRevision is an invalid size");
|
||||
|
||||
// This is nn::hid::NpadStyleIndex
|
||||
// This is nn::hid::NpadStyleIndex
|
||||
enum class NpadStyleIndex : u8 {
|
||||
None = 0,
|
||||
FullKey = 3,
|
||||
|
@ -271,7 +271,6 @@ enum class NpadStyleSet : u32 {
|
|||
DECLARE_ENUM_FLAG_OPERATORS(NpadStyleSet);
|
||||
static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
|
||||
|
||||
|
||||
// This is nn::hid::VibrationDevicePosition
|
||||
enum class VibrationDevicePosition : u32 {
|
||||
None = 0,
|
||||
|
@ -364,6 +363,131 @@ enum class NpadJoyHoldType : u64 {
|
|||
Horizontal = 1,
|
||||
};
|
||||
|
||||
// This is nn::hid::system::AppletFooterUiAttributesSet
|
||||
struct AppletFooterUiAttributes {
|
||||
INSERT_PADDING_BYTES(0x4);
|
||||
};
|
||||
|
||||
// This is nn::hid::system::AppletFooterUiType
|
||||
enum class AppletFooterUiType : u8 {
|
||||
None = 0,
|
||||
HandheldNone = 1,
|
||||
HandheldJoyConLeftOnly = 1,
|
||||
HandheldJoyConRightOnly = 3,
|
||||
HandheldJoyConLeftJoyConRight = 4,
|
||||
JoyDual = 5,
|
||||
JoyDualLeftOnly = 6,
|
||||
JoyDualRightOnly = 7,
|
||||
JoyLeftHorizontal = 8,
|
||||
JoyLeftVertical = 9,
|
||||
JoyRightHorizontal = 10,
|
||||
JoyRightVertical = 11,
|
||||
SwitchProController = 12,
|
||||
CompatibleProController = 13,
|
||||
CompatibleJoyCon = 14,
|
||||
LarkHvc1 = 15,
|
||||
LarkHvc2 = 16,
|
||||
LarkNesLeft = 17,
|
||||
LarkNesRight = 18,
|
||||
Lucia = 19,
|
||||
Verification = 20,
|
||||
Lagon = 21,
|
||||
};
|
||||
|
||||
// This is nn::hid::detail::ColorAttribute
|
||||
enum class ColorAttribute : u32 {
|
||||
Ok = 0,
|
||||
ReadError = 1,
|
||||
NoController = 2,
|
||||
};
|
||||
static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size");
|
||||
|
||||
// This is nn::hid::NpadLarkType
|
||||
enum class NpadLarkType : u32 {
|
||||
Invalid,
|
||||
H1,
|
||||
H2,
|
||||
NL,
|
||||
NR,
|
||||
};
|
||||
|
||||
// This is nn::hid::NpadLuciaType
|
||||
enum class NpadLuciaType : u32 {
|
||||
Invalid,
|
||||
J,
|
||||
E,
|
||||
U,
|
||||
};
|
||||
|
||||
// This is nn::hid::NpadLagonType
|
||||
enum class NpadLagonType : u32 {
|
||||
Invalid,
|
||||
};
|
||||
|
||||
// This is nn::hid::NpadLagerType
|
||||
enum class NpadLagerType : u32 {
|
||||
Invalid,
|
||||
J,
|
||||
E,
|
||||
U,
|
||||
};
|
||||
|
||||
// This is nn::hid::NpadSystemProperties
|
||||
struct NPadSystemProperties {
|
||||
union {
|
||||
s64 raw{};
|
||||
BitField<0, 1, s64> is_charging_joy_dual;
|
||||
BitField<1, 1, s64> is_charging_joy_left;
|
||||
BitField<2, 1, s64> is_charging_joy_right;
|
||||
BitField<3, 1, s64> is_powered_joy_dual;
|
||||
BitField<4, 1, s64> is_powered_joy_left;
|
||||
BitField<5, 1, s64> is_powered_joy_right;
|
||||
BitField<9, 1, s64> is_system_unsupported_button;
|
||||
BitField<10, 1, s64> is_system_ext_unsupported_button;
|
||||
BitField<11, 1, s64> is_vertical;
|
||||
BitField<12, 1, s64> is_horizontal;
|
||||
BitField<13, 1, s64> use_plus;
|
||||
BitField<14, 1, s64> use_minus;
|
||||
BitField<15, 1, s64> use_directional_buttons;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size");
|
||||
|
||||
// This is nn::hid::NpadSystemButtonProperties
|
||||
struct NpadSystemButtonProperties {
|
||||
union {
|
||||
s32 raw{};
|
||||
BitField<0, 1, s32> is_home_button_protection_enabled;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(NpadSystemButtonProperties) == 0x4, "NPadButtonProperties is an invalid size");
|
||||
|
||||
// This is nn::hid::system::DeviceType
|
||||
struct DeviceType {
|
||||
union {
|
||||
u32 raw{};
|
||||
BitField<0, 1, s32> fullkey;
|
||||
BitField<1, 1, s32> debug_pad;
|
||||
BitField<2, 1, s32> handheld_left;
|
||||
BitField<3, 1, s32> handheld_right;
|
||||
BitField<4, 1, s32> joycon_left;
|
||||
BitField<5, 1, s32> joycon_right;
|
||||
BitField<6, 1, s32> palma;
|
||||
BitField<7, 1, s32> lark_hvc_left;
|
||||
BitField<8, 1, s32> lark_hvc_right;
|
||||
BitField<9, 1, s32> lark_nes_left;
|
||||
BitField<10, 1, s32> lark_nes_right;
|
||||
BitField<11, 1, s32> handheld_lark_hvc_left;
|
||||
BitField<12, 1, s32> handheld_lark_hvc_right;
|
||||
BitField<13, 1, s32> handheld_lark_nes_left;
|
||||
BitField<14, 1, s32> handheld_lark_nes_right;
|
||||
BitField<15, 1, s32> lucia;
|
||||
BitField<16, 1, s32> lagon;
|
||||
BitField<17, 1, s32> lager;
|
||||
BitField<31, 1, s32> system;
|
||||
};
|
||||
};
|
||||
|
||||
// This is nn::hid::TouchAttribute
|
||||
struct TouchAttribute {
|
||||
union {
|
||||
|
@ -374,6 +498,20 @@ struct TouchAttribute {
|
|||
};
|
||||
static_assert(sizeof(TouchAttribute) == 0x4, "TouchAttribute is an invalid size");
|
||||
|
||||
// This is nn::hid::NpadAttribute
|
||||
struct NpadAttribute {
|
||||
union {
|
||||
u32 raw{};
|
||||
BitField<0, 1, u32> is_connected;
|
||||
BitField<1, 1, u32> is_wired;
|
||||
BitField<2, 1, u32> is_left_connected;
|
||||
BitField<3, 1, u32> is_left_wired;
|
||||
BitField<4, 1, u32> is_right_connected;
|
||||
BitField<5, 1, u32> is_right_wired;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(NpadAttribute) == 4, "NpadAttribute is an invalid size");
|
||||
|
||||
// This is nn::hid::TouchState
|
||||
struct TouchState {
|
||||
u64 delta_time{};
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Service::HID {
|
|||
constexpr std::size_t ARUID_MAX = 0x2; // Console real limit is 0x20
|
||||
constexpr std::size_t PLAYERS_MAX = 10;
|
||||
constexpr std::size_t SUPPORTED_NPAD_TYPES_MAX = 11;
|
||||
constexpr std::size_t HID_ENTRY_COUNT = 17;
|
||||
|
||||
class BaseResource {
|
||||
public:
|
||||
|
|
|
@ -8,9 +8,69 @@
|
|||
#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"
|
||||
#include "core/hle/service/hid/resource_manager/npad_resource/npad_shared_types.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
AbstractNpadState::AbstractNpadState() {}
|
||||
AbstractNpadState::~AbstractNpadState() = default;
|
||||
|
||||
Result AbstractNpadState::ActivateNpad(const u64 aruid) {
|
||||
Result result{}; // UpdateSpecial Controller State
|
||||
if (result.IsSuccess()) {
|
||||
result = UpdateNpadLifo(aruid);
|
||||
if (result.IsError()) {
|
||||
return result;
|
||||
}
|
||||
result = UpdateSixaxisLifo(aruid);
|
||||
if (result.IsError()) {
|
||||
return result;
|
||||
}
|
||||
result = UpdateBatteryLifo(aruid);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Result AbstractNpadState::UpdateNpadLifo(const u64 aruid) {}
|
||||
Result AbstractNpadState::UpdateSixaxisLifo(const u64 aruid) {}
|
||||
Result AbstractNpadState::UpdateBatteryLifo(const u64 aruid) {}
|
||||
void AbstractNpadState::UpdateNpadLifoImpl(const BatteryState& battery_state,
|
||||
NpadInternalState& internal_state) {}
|
||||
void AbstractNpadState::UpdateSixaxisLifoImpl(const BatteryState& battery_state,
|
||||
NpadInternalState& internal_state) {
|
||||
|
||||
}
|
||||
|
||||
void AbstractNpadState::UpdateBatteryLifoImpl(const BatteryState& battery_state,
|
||||
NpadInternalState& internal_state) {
|
||||
NPadSystemProperties properties{};
|
||||
|
||||
if (battery_state.is_powered_joy_dual) {
|
||||
properties.is_powered_joy_dual.Assign(1);
|
||||
}
|
||||
if (battery_state.is_powered_joy_left) {
|
||||
properties.is_powered_joy_left.Assign(1);
|
||||
}
|
||||
if (battery_state.is_powered_joy_right) {
|
||||
properties.is_powered_joy_right.Assign(1);
|
||||
}
|
||||
|
||||
if (battery_state.is_charging_joy_dual) {
|
||||
properties.is_charging_joy_dual.Assign(1);
|
||||
}
|
||||
if (battery_state.is_charging_joy_left) {
|
||||
properties.is_charging_joy_left.Assign(1);
|
||||
}
|
||||
if (battery_state.is_charging_joy_right) {
|
||||
properties.is_charging_joy_right.Assign(1);
|
||||
}
|
||||
|
||||
internal_state.system_properties = properties;
|
||||
internal_state.battery_level_dual = battery_state.battery_level_dual;
|
||||
internal_state.battery_level_left = battery_state.battery_level_left;
|
||||
internal_state.battery_level_right = battery_state.battery_level_right;
|
||||
}
|
||||
|
||||
Npad::Npad(KernelHelpers::ServiceContext& context) : service_context{context} {
|
||||
for (auto& npad : npad_state) {
|
||||
npad = std::make_shared<NpadState>();
|
||||
|
@ -26,11 +86,28 @@ Npad::Npad(KernelHelpers::ServiceContext& context) : service_context{context} {
|
|||
Npad::~Npad() = default;
|
||||
|
||||
Result Npad::Activate(const u64 aruid) {
|
||||
// No mistake was made here. It uses two different locks
|
||||
std::scoped_lock lock{mutex};
|
||||
std::scoped_lock lock{recursive_mutex};
|
||||
|
||||
for (std::size_t i = 0; i < PLAYERS_MAX; ++i) {
|
||||
const Result result= abstract_npad_state[i]->ActivateNpad(aruid);
|
||||
if (result.IsError()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result Npad::ActivateWithRevision(const u64 aruid, const s32 revision) {
|
||||
return ResultSuccess;
|
||||
void Npad::ActivateWithRevision(const u64 aruid, const NpadRevision revision) {
|
||||
const auto index = GetIndexFromAruid(aruid);
|
||||
|
||||
if (index >= ARUID_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
npad_state[index]->SetNpadRevision(revision);
|
||||
}
|
||||
|
||||
void Npad::DisconnectNpad(const u64 aruid, const NpadIdType npad_id) {
|
||||
|
@ -711,19 +788,19 @@ Result Npad::GetMaskedSupportedNpadStyleSetImpl(const u64 aruid,
|
|||
out_npad_styleset = npad_state[index]->GetSupportedNpadStyleSet();
|
||||
|
||||
if (index < ARUID_MAX) {
|
||||
switch (npad_state[index]->GetMaskIndex()) {
|
||||
case MaskIndex::GC:
|
||||
switch (npad_state[index]->GetNpadRevision()) {
|
||||
case NpadRevision::Revision1:
|
||||
mask = NpadStyleSet::Fullkey | NpadStyleSet::Handheld | NpadStyleSet::JoyDual |
|
||||
NpadStyleSet::JoyLeft | NpadStyleSet::JoyRight | NpadStyleSet::Gc |
|
||||
NpadStyleSet::SystemExt | NpadStyleSet::System;
|
||||
break;
|
||||
case MaskIndex::Extended:
|
||||
case NpadRevision::Revision2:
|
||||
mask = NpadStyleSet::Fullkey | NpadStyleSet::Handheld | NpadStyleSet::JoyDual |
|
||||
NpadStyleSet::JoyLeft | NpadStyleSet::JoyRight | NpadStyleSet::Gc |
|
||||
NpadStyleSet::Palma | NpadStyleSet::Lark | NpadStyleSet::SystemExt |
|
||||
NpadStyleSet::System;
|
||||
break;
|
||||
case MaskIndex::Full:
|
||||
case NpadRevision::Revision3:
|
||||
mask = NpadStyleSet::Fullkey | NpadStyleSet::Handheld | NpadStyleSet::JoyDual |
|
||||
NpadStyleSet::JoyLeft | NpadStyleSet::JoyRight | NpadStyleSet::Gc |
|
||||
NpadStyleSet::Palma | NpadStyleSet::Lark | NpadStyleSet::HandheldLark |
|
||||
|
|
|
@ -29,22 +29,60 @@ enum class NpadJoyDeviceType : s64;
|
|||
enum class NpadStyleSet : u32;
|
||||
enum class NpadJoyHoldType : u64;
|
||||
enum class NpadButton : u64;
|
||||
enum class MaskIndex : u32;
|
||||
enum class NpadRevision : u32;
|
||||
|
||||
struct SixAxisSensorHandle;
|
||||
struct NpadInternalState;
|
||||
|
||||
class NpadState;
|
||||
} // namespace Service::HID
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
class AbstractNpadState {
|
||||
public:
|
||||
explicit AbstractNpadState();
|
||||
~AbstractNpadState();
|
||||
|
||||
Result ActivateNpad(const u64 aruid);
|
||||
|
||||
private:
|
||||
struct BatteryState {
|
||||
INSERT_PADDING_BYTES(0x1c);
|
||||
bool is_powered_joy_dual;
|
||||
bool is_charging_joy_dual;
|
||||
INSERT_PADDING_BYTES(0x6);
|
||||
NpadBatteryLevel battery_level_dual;
|
||||
bool is_powered_joy_left;
|
||||
bool is_charging_joy_left;
|
||||
INSERT_PADDING_BYTES(0x6);
|
||||
NpadBatteryLevel battery_level_left;
|
||||
bool is_powered_joy_right;
|
||||
bool is_charging_joy_right;
|
||||
INSERT_PADDING_BYTES(0x6);
|
||||
NpadBatteryLevel battery_level_right;
|
||||
};
|
||||
static_assert(sizeof(BatteryState) == 0x40, "BatteryState is an invalid size");
|
||||
|
||||
|
||||
|
||||
Result UpdateNpadLifo(const u64 aruid);
|
||||
Result UpdateSixaxisLifo(const u64 aruid);
|
||||
Result UpdateBatteryLifo(const u64 aruid);
|
||||
void UpdateNpadLifoImpl(const BatteryState& battery_state, NpadInternalState& internal_state);
|
||||
void UpdateSixaxisLifoImpl(const BatteryState& battery_state,
|
||||
NpadInternalState& internal_state);
|
||||
void UpdateBatteryLifoImpl(const BatteryState& battery_state,
|
||||
NpadInternalState& internal_state);
|
||||
};
|
||||
|
||||
class Npad final : public BaseResource {
|
||||
public:
|
||||
explicit Npad(KernelHelpers::ServiceContext& context);
|
||||
~Npad();
|
||||
|
||||
Result Activate(const u64 aruid);
|
||||
Result ActivateWithRevision(const u64 aruid, const s32 revision);
|
||||
void ActivateWithRevision(const u64 aruid, const NpadRevision revision);
|
||||
void DisconnectNpad(const u64 aruid, const NpadIdType npad_id);
|
||||
void ForceDisconnectNpad(const NpadIdType npad_id);
|
||||
void DisconnectAbstractPad(const NpadIdType npad_id);
|
||||
|
@ -136,10 +174,12 @@ private:
|
|||
u64 GetNpadActiveAruid();
|
||||
|
||||
mutable std::mutex mutex;
|
||||
mutable std::recursive_mutex recursive_mutex;
|
||||
u64 active_aruid{};
|
||||
std::shared_ptr<NpadState> active_npad_state = nullptr;
|
||||
NpadJoyHoldType default_joy_hold_type{};
|
||||
std::array<std::shared_ptr<NpadState>, ARUID_MAX> npad_state{};
|
||||
std::array<std::shared_ptr<AbstractNpadState>, PLAYERS_MAX> abstract_npad_state;
|
||||
KernelHelpers::ServiceContext& service_context;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <span>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/vector_math.h"
|
||||
#include "core/hle/service/hid/hid_types.h"
|
||||
#include "core/hle/service/hid/resource_manager/base_resource.h"
|
||||
#include "core/hle/service/hid/resource_manager/ring_lifo.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
// This is nn::hid::detail::NpadFullKeyColorState
|
||||
struct NpadFullKeyColorState {
|
||||
ColorAttribute attribute{ColorAttribute::NoController};
|
||||
NpadControllerColor fullkey{};
|
||||
};
|
||||
static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size");
|
||||
|
||||
// This is nn::hid::detail::NpadJoyColorState
|
||||
struct NpadJoyColorState {
|
||||
ColorAttribute attribute{ColorAttribute::NoController};
|
||||
NpadControllerColor left{};
|
||||
NpadControllerColor right{};
|
||||
};
|
||||
static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size");
|
||||
|
||||
// This is nn::hid::NpadFullKeyState
|
||||
// This is nn::hid::NpadHandheldState
|
||||
// This is nn::hid::NpadJoyDualState
|
||||
// This is nn::hid::NpadJoyLeftState
|
||||
// This is nn::hid::NpadJoyRightState
|
||||
// This is nn::hid::NpadPalmaState
|
||||
// This is nn::hid::NpadSystemExtState
|
||||
struct NPadGenericState {
|
||||
s64_le sampling_number{};
|
||||
NpadButtonState npad_buttons{};
|
||||
AnalogStickState l_stick{};
|
||||
AnalogStickState r_stick{};
|
||||
NpadAttribute connection_status{};
|
||||
INSERT_PADDING_BYTES(4); // Reserved
|
||||
};
|
||||
static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size");
|
||||
|
||||
// This is nn::hid::SixAxisSensorAttribute
|
||||
struct SixAxisSensorAttribute {
|
||||
union {
|
||||
u32 raw{};
|
||||
BitField<0, 1, u32> is_connected;
|
||||
BitField<1, 1, u32> is_interpolated;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(SixAxisSensorAttribute) == 4, "SixAxisSensorAttribute is an invalid size");
|
||||
|
||||
// This is nn::hid::SixAxisSensorState
|
||||
struct SixAxisSensorState {
|
||||
s64 delta_time{};
|
||||
s64 sampling_number{};
|
||||
Common::Vec3f accel{};
|
||||
Common::Vec3f gyro{};
|
||||
Common::Vec3f rotation{};
|
||||
std::array<Common::Vec3f, 3> orientation{};
|
||||
SixAxisSensorAttribute attribute{};
|
||||
INSERT_PADDING_BYTES(4); // Reserved
|
||||
};
|
||||
static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size");
|
||||
|
||||
// This is nn::hid::server::NpadGcTriggerState
|
||||
struct NpadGcTriggerState {
|
||||
s64 sampling_number{};
|
||||
s32 l_analog{};
|
||||
s32 r_analog{};
|
||||
};
|
||||
static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size");
|
||||
|
||||
// This is nn::hid::detail::NfcXcdDeviceHandleStateImpl
|
||||
struct NfcXcdDeviceHandleStateImpl {
|
||||
u64 handle{};
|
||||
bool is_available{};
|
||||
bool is_activated{};
|
||||
INSERT_PADDING_BYTES(0x6); // Reserved
|
||||
u64 sampling_number{};
|
||||
};
|
||||
static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18,
|
||||
"NfcXcdDeviceHandleStateImpl is an invalid size");
|
||||
|
||||
struct AppletFooterUi {
|
||||
AppletFooterUiAttributes attributes{};
|
||||
AppletFooterUiType type{AppletFooterUiType::None};
|
||||
INSERT_PADDING_BYTES(0x5B); // Reserved
|
||||
};
|
||||
static_assert(sizeof(AppletFooterUi) == 0x60, "AppletFooterUi is an invalid size");
|
||||
|
||||
struct AppletNfcXcd {
|
||||
union {
|
||||
AppletFooterUi applet_footer{};
|
||||
Lifo<NfcXcdDeviceHandleStateImpl, 0x2> nfc_xcd_device_lifo;
|
||||
};
|
||||
};
|
||||
|
||||
// This is nn::hid::detail::NpadInternalState
|
||||
struct NpadInternalState {
|
||||
NpadStyleTag style_tag{NpadStyleSet::None};
|
||||
NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual};
|
||||
NpadFullKeyColorState fullkey_color{};
|
||||
NpadJoyColorState joycon_color{};
|
||||
Lifo<NPadGenericState, HID_ENTRY_COUNT> fullkey_lifo{};
|
||||
Lifo<NPadGenericState, HID_ENTRY_COUNT> handheld_lifo{};
|
||||
Lifo<NPadGenericState, HID_ENTRY_COUNT> joy_dual_lifo{};
|
||||
Lifo<NPadGenericState, HID_ENTRY_COUNT> joy_left_lifo{};
|
||||
Lifo<NPadGenericState, HID_ENTRY_COUNT> joy_right_lifo{};
|
||||
Lifo<NPadGenericState, HID_ENTRY_COUNT> palma_lifo{};
|
||||
Lifo<NPadGenericState, HID_ENTRY_COUNT> system_ext_lifo{};
|
||||
Lifo<SixAxisSensorState, HID_ENTRY_COUNT> sixaxis_fullkey_lifo{};
|
||||
Lifo<SixAxisSensorState, HID_ENTRY_COUNT> sixaxis_handheld_lifo{};
|
||||
Lifo<SixAxisSensorState, HID_ENTRY_COUNT> sixaxis_dual_left_lifo{};
|
||||
Lifo<SixAxisSensorState, HID_ENTRY_COUNT> sixaxis_dual_right_lifo{};
|
||||
Lifo<SixAxisSensorState, HID_ENTRY_COUNT> sixaxis_left_lifo{};
|
||||
Lifo<SixAxisSensorState, HID_ENTRY_COUNT> sixaxis_right_lifo{};
|
||||
DeviceType device_type{};
|
||||
INSERT_PADDING_BYTES(0x4); // Reserved
|
||||
NPadSystemProperties system_properties{};
|
||||
NpadSystemButtonProperties button_properties{};
|
||||
NpadBatteryLevel battery_level_dual{};
|
||||
NpadBatteryLevel battery_level_left{};
|
||||
NpadBatteryLevel battery_level_right{};
|
||||
AppletNfcXcd applet_nfc_xcd{};
|
||||
INSERT_PADDING_BYTES(0x20); // Unknown
|
||||
Lifo<NpadGcTriggerState, HID_ENTRY_COUNT> gc_trigger_lifo{};
|
||||
NpadLarkType lark_type_l_and_main{};
|
||||
NpadLarkType lark_type_r{};
|
||||
NpadLuciaType lucia_type{};
|
||||
NpadLagonType lagon_type{};
|
||||
NpadLagerType lager_type{};
|
||||
SixAxisSensorProperties sixaxis_fullkey_properties;
|
||||
SixAxisSensorProperties sixaxis_handheld_properties;
|
||||
SixAxisSensorProperties sixaxis_dual_left_properties;
|
||||
SixAxisSensorProperties sixaxis_dual_right_properties;
|
||||
SixAxisSensorProperties sixaxis_left_properties;
|
||||
SixAxisSensorProperties sixaxis_right_properties;
|
||||
INSERT_PADDING_BYTES(0xc06); // Unknown
|
||||
};
|
||||
static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size");
|
||||
|
||||
} // namespace Service::HID
|
|
@ -194,8 +194,13 @@ 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;
|
||||
NpadRevision NpadState::GetNpadRevision() const {
|
||||
return npad_revision;
|
||||
}
|
||||
|
||||
|
||||
void NpadState::SetNpadRevision(const NpadRevision revision) {
|
||||
npad_revision = revision;
|
||||
}
|
||||
|
||||
} // namespace Service::HID
|
||||
|
|
|
@ -19,7 +19,7 @@ enum class NpadHandheldActivationMode : u64;
|
|||
enum class NpadStyleSet : u32;
|
||||
enum class NpadJoyHoldType : u64;
|
||||
enum class NpadButton : u64;
|
||||
enum class MaskIndex : u32;
|
||||
enum class NpadRevision : u32;
|
||||
|
||||
class NpadControllerState;
|
||||
} // namespace Service::HID
|
||||
|
@ -75,7 +75,8 @@ public:
|
|||
bool GetAssigningSingleOnSlSrPress() const;
|
||||
void SetAssigningSingleOnSlSrPress(const bool is_enabled);
|
||||
|
||||
MaskIndex GetMaskIndex() const;
|
||||
NpadRevision GetNpadRevision() const;
|
||||
void SetNpadRevision(const NpadRevision revision);
|
||||
|
||||
private:
|
||||
struct DataStructure {
|
||||
|
@ -95,7 +96,7 @@ private:
|
|||
DataStructure data{};
|
||||
|
||||
std::array<std::shared_ptr<NpadControllerState>, PLAYERS_MAX> state;
|
||||
MaskIndex mask_index{};
|
||||
NpadRevision npad_revision{};
|
||||
};
|
||||
|
||||
} // namespace Service::HID
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
template <typename State>
|
||||
struct AtomicStorage {
|
||||
s64 sampling_number;
|
||||
State state;
|
||||
};
|
||||
|
||||
template <typename State, std::size_t max_buffer_size>
|
||||
struct Lifo {
|
||||
s64 timestamp{};
|
||||
s64 total_buffer_count = static_cast<s64>(max_buffer_size);
|
||||
s64 buffer_tail{};
|
||||
s64 buffer_count{};
|
||||
std::array<AtomicStorage<State>, max_buffer_size> entries{};
|
||||
|
||||
const AtomicStorage<State>& ReadCurrentEntry() const {
|
||||
return entries[buffer_tail];
|
||||
}
|
||||
|
||||
const AtomicStorage<State>& ReadPreviousEntry() const {
|
||||
return entries[GetPreviousEntryIndex()];
|
||||
}
|
||||
|
||||
std::size_t GetPreviousEntryIndex() const {
|
||||
return static_cast<size_t>((buffer_tail + total_buffer_count - 1) % total_buffer_count);
|
||||
}
|
||||
|
||||
std::size_t GetNextEntryIndex() const {
|
||||
return static_cast<size_t>((buffer_tail + 1) % total_buffer_count);
|
||||
}
|
||||
|
||||
void WriteNextEntry(const State& new_state) {
|
||||
if (buffer_count < total_buffer_count - 1) {
|
||||
buffer_count++;
|
||||
}
|
||||
buffer_tail = GetNextEntryIndex();
|
||||
const auto& previous_entry = ReadPreviousEntry();
|
||||
entries[buffer_tail].sampling_number = previous_entry.sampling_number + 1;
|
||||
entries[buffer_tail].state = new_state;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Service::HID
|
Loading…
Reference in New Issue