beep boop

This commit is contained in:
Narr the Reg 2023-08-18 20:08:51 -06:00
parent d669f7e15f
commit b7c7505aca
14 changed files with 386 additions and 200 deletions

View File

@ -12,6 +12,7 @@ constexpr Result ResultNpadInvalidHandle{ErrorModule::HID, 100};
constexpr Result ResultNpadDeviceIndexOutOfRange{ErrorModule::HID, 107};
constexpr Result ResultVibrationInvalidStyleIndex{ErrorModule::HID, 122};
constexpr Result ResultVibrationInvalidNpadId{ErrorModule::HID, 123};
constexpr Result ResultVibrationVolumeOutOfRange{ErrorModule::HID, 126};
constexpr Result ResultVibrationDeviceIndexOutOfRange{ErrorModule::HID, 124};
constexpr Result ResultInvalidSixAxisFusionRange{ErrorModule::HID, 423};
constexpr Result ResultNpadIsDualJoycon{ErrorModule::HID, 601};

View File

@ -1735,12 +1735,40 @@ void IHidServer::ClearNpadCaptureButtonAssignment(HLERequestContext& ctx) {
rb.Push(result);
}
void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) {}
void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto vibration_device_handle{rp.PopRaw<VibrationDeviceHandle>()};
VibrationDeviceInfo device_info;
const Result result =
GetResourceManager()->GetVibrationDeviceInfo(device_info, vibration_device_handle);
LOG_DEBUG(Service_HID, "called, device_type={}, device_position={}", device_info.type,
device_info.position);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(result);
rb.PushRaw(device_info);
}
void IHidServer::SendVibrationValue(HLERequestContext& ctx) {}
void IHidServer::GetActualVibrationValue(HLERequestContext& ctx) {}
void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {}
void IHidServer::PermitVibration(HLERequestContext& ctx) {}
void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) {}
void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto can_vibrate{rp.Pop<bool>()};
LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
const Result result =
GetResourceManager()->GetNpad()->SetVibrationMasterVolume(can_vibrate ? 1.0f : 0.0f);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
}
void IHidServer::SendVibrationValues(HLERequestContext& ctx) {}
void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) {}
void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {}

View File

@ -68,8 +68,8 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{505, nullptr, "EnableAppletToGetSixAxisSensor"},
{506, nullptr, "EnableAppletToGetPadInput"},
{507, nullptr, "EnableAppletToGetTouchScreen"},
{510, nullptr, "SetVibrationMasterVolume"},
{511, nullptr, "GetVibrationMasterVolume"},
{510, &IHidSystemServer::SetVibrationMasterVolume, "SetVibrationMasterVolume"},
{511, &IHidSystemServer::GetVibrationMasterVolume, "GetVibrationMasterVolume"},
{512, nullptr, "BeginPermitVibrationSession"},
{513, nullptr, "EndPermitVibrationSession"},
{514, nullptr, "Unknown514"},
@ -317,6 +317,32 @@ void IHidSystemServer::GetNpadCaptureButtonAssignment(HLERequestContext& ctx) {
rb.Push(reply_size);
}
void IHidSystemServer::SetVibrationMasterVolume(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto volume{rp.Pop<float>()};
LOG_DEBUG(Service_HID, "called, volume={}", volume);
const Result result = GetResourceManager()->GetNpad()->SetVibrationMasterVolume(volume);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
}
void IHidSystemServer::GetVibrationMasterVolume(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto can_vibrate{rp.Pop<bool>()};
LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
float volume{};
const Result result = GetResourceManager()->GetNpad()->GetVibrationMasterVolume(volume);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(result);
rb.Push(volume);
}
std::shared_ptr<ResourceManager> IHidSystemServer::GetResourceManager() {
if (!is_resource_manager_initialized) {
resource_manager->Initialize();

View File

@ -25,6 +25,8 @@ private:
void GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx);
void SetSupportedNpadStyleSetAll(HLERequestContext& ctx);
void GetNpadCaptureButtonAssignment(HLERequestContext& ctx);
void SetVibrationMasterVolume(HLERequestContext& ctx);
void GetVibrationMasterVolume(HLERequestContext& ctx);
std::shared_ptr<ResourceManager> GetResourceManager();

View File

@ -18,6 +18,7 @@ enum class DeviceIndex : u8 {
Right = 1,
None = 2,
MaxDeviceIndex = 3,
MaxDeviceInfo = None,
};
// This is nn::hid::NpadButton

View File

@ -1,6 +1,9 @@
// 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.h"
#include "core/hle/service/hid/resource_manager/debug_pad.h"
#include "core/hle/service/hid/resource_manager/gesture.h"
@ -81,6 +84,73 @@ void ResourceManager::Initialize() {
sixaxis = std::make_shared<SixAxis>();
touch_screen = std::make_shared<TouchScreen>();
}
Result ResourceManager::GetVibrationDeviceInfo(VibrationDeviceInfo& out_device_info,
VibrationDeviceHandle handle) const {
out_device_info.type = VibrationDeviceType::Unknown;
out_device_info.position = VibrationDevicePosition::None;
switch (handle.npad_type) {
case NpadStyleIndex::FullKey:
case NpadStyleIndex::Handheld:
case NpadStyleIndex::JoyconDual:
case NpadStyleIndex::JoyconLeft:
case NpadStyleIndex::JoyconRight:
case NpadStyleIndex::GameCube:
case NpadStyleIndex::N64:
case NpadStyleIndex::SystemExt:
case NpadStyleIndex::System:
// These support vibration
break;
default:
return ResultVibrationInvalidStyleIndex;
}
if (IsNpadIdValid(static_cast<NpadIdType>(handle.npad_id))) {
return ResultVibrationInvalidNpadId;
}
if (handle.device_index >= DeviceIndex::MaxDeviceInfo) {
return ResultVibrationDeviceIndexOutOfRange;
}
bool check_device_index = false;
switch (handle.npad_type) {
case NpadStyleIndex::FullKey:
case NpadStyleIndex::Handheld:
case NpadStyleIndex::JoyconDual:
case NpadStyleIndex::JoyconLeft:
case NpadStyleIndex::JoyconRight:
out_device_info.type = VibrationDeviceType::LinearResonantActuator;
check_device_index = true;
break;
case NpadStyleIndex::GameCube:
out_device_info.type = VibrationDeviceType::GcErm;
break;
case NpadStyleIndex::N64:
out_device_info.type = VibrationDeviceType::N64;
break;
default:
out_device_info.type = VibrationDeviceType::Unknown;
break;
}
if (check_device_index) {
switch (handle.device_index) {
case DeviceIndex::Left:
out_device_info.position = VibrationDevicePosition::Left;
break;
case DeviceIndex::Right:
out_device_info.position = VibrationDevicePosition::Right;
break;
case DeviceIndex::None:
default:
ASSERT_MSG("DeviceIndex should never be None!");
break;
}
}
return ResultSuccess;
}
std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() {
return debug_pad;

View File

@ -3,14 +3,17 @@
#pragma once
#include "core/hle/service/service.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::HID {
struct VibrationDeviceInfo;
struct VibrationDeviceHandle;
class DebugPad;
class Gesture;
class Keyboard;
@ -30,6 +33,9 @@ public:
void Initialize();
Result GetVibrationDeviceInfo(VibrationDeviceInfo& out_device_info,
VibrationDeviceHandle handle) const;
std::shared_ptr<DebugPad> GetDebugPad();
std::shared_ptr<Gesture> GetGesture();
std::shared_ptr<Keyboard> GetKeyboard();

View File

@ -7,8 +7,8 @@
#include "core/hle/service/hid/hid_util.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"
#include "core/hle/service/hid/resource_manager/npad_resource/npad_shared_types.h"
#include "core/hle/service/hid/resource_manager/npad_resource/npad_state.h"
namespace Service::HID {
@ -31,15 +31,20 @@ Result AbstractNpadState::ActivateNpad(const u64 aruid) {
return result;
}
Result AbstractNpadState::UpdateNpadLifo(const u64 aruid) {}
Result AbstractNpadState::UpdateSixaxisLifo(const u64 aruid) {}
Result AbstractNpadState::UpdateBatteryLifo(const u64 aruid) {}
Result AbstractNpadState::UpdateNpadLifo(const u64 aruid) {
return ResultSuccess;
}
Result AbstractNpadState::UpdateSixaxisLifo(const u64 aruid) {
return ResultSuccess;
}
Result AbstractNpadState::UpdateBatteryLifo(const u64 aruid) {
return ResultSuccess;
}
void AbstractNpadState::UpdateNpadLifoImpl(const BatteryState& battery_state,
NpadInternalState& internal_state) {}
void AbstractNpadState::UpdateSixaxisLifoImpl(const BatteryState& battery_state,
NpadInternalState& internal_state) {
}
NpadInternalState& internal_state) {}
void AbstractNpadState::UpdateBatteryLifoImpl(const BatteryState& battery_state,
NpadInternalState& internal_state) {
@ -88,10 +93,10 @@ 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};
std::scoped_lock recursive_lock{recursive_mutex};
for (std::size_t i = 0; i < PLAYERS_MAX; ++i) {
const Result result= abstract_npad_state[i]->ActivateNpad(aruid);
const Result result = abstract_npad_state[i]->ActivateNpad(aruid);
if (result.IsError()) {
return result;
}
@ -115,9 +120,9 @@ void Npad::DisconnectNpad(const u64 aruid, const NpadIdType npad_id) {
return;
}
auto state = active_npad_state->GetControllerState(npad_id);
DisconnectAbstractPad(state->GetNpadId());
state->Update();
auto& state = active_npad_state->GetControllerState(npad_id);
DisconnectAbstractPad(state.GetNpadId());
state.Update();
}
void Npad::ForceDisconnectNpad(const NpadIdType npad_id) {
@ -245,7 +250,7 @@ Result Npad::GetSupportedNpadStyleSetImpl(const u64 aruid,
return ResultNpadNotConnected;
}
if (npad_state[index]->GetStatus().is_supported_style_set == 0) {
if (npad_state[index]->GetStatus().is_supported_styleset_set == 0) {
return ResultUndefinedStyleSet;
}
@ -314,9 +319,9 @@ void Npad::SetNpadJoyAssignmentModeDual(const u64 aruid, const NpadIdType npad_i
// TODO: Implement this
auto state = active_npad_state->GetControllerState(npad_id);
state->SetNpadAssignmentMode(NpadJoyAssignmentMode::Dual);
state->Update();
auto& state = active_npad_state->GetControllerState(npad_id);
state.SetNpadAssignmentMode(NpadJoyAssignmentMode::Dual);
state.Update();
}
Result Npad::MergeSingleJoyAsDualJoy(const u64 aruid, const NpadIdType npad_id_1,
@ -328,19 +333,19 @@ Result Npad::MergeSingleJoyAsDualJoy(const u64 aruid, const NpadIdType npad_id_1
return ResultSuccess;
}
auto state_1 = active_npad_state->GetControllerState(npad_id_1);
auto state_2 = active_npad_state->GetControllerState(npad_id_2);
auto& state_1 = active_npad_state->GetControllerState(npad_id_1);
auto& state_2 = active_npad_state->GetControllerState(npad_id_2);
if (state_1->IsUpdatePending() != 0) {
state_1->Update();
if (state_1.IsUpdatePending() != 0) {
state_1.Update();
}
if (state_2->IsUpdatePending() != 0) {
state_2->Update();
if (state_2.IsUpdatePending() != 0) {
state_2.Update();
}
const auto style_index_1 = state_1->GetConnectedControllerIndex();
const auto style_index_2 = state_2->GetConnectedControllerIndex();
const auto style_index_1 = state_1.GetConnectedControllerIndex();
const auto style_index_2 = state_2.GetConnectedControllerIndex();
if (style_index_1 == 2 && style_index_2 == 2) {
return ResultNpadIsSameType;
@ -366,15 +371,15 @@ Result Npad::MergeSingleJoyAsDualJoy(const u64 aruid, const NpadIdType npad_id_1
// something = state_2->SomeFunction(someglobal);
state_1->SetNpadAssignmentMode(NpadJoyAssignmentMode::Dual);
state_2->SetNpadAssignmentMode(NpadJoyAssignmentMode::Dual);
state_1.SetNpadAssignmentMode(NpadJoyAssignmentMode::Dual);
state_2.SetNpadAssignmentMode(NpadJoyAssignmentMode::Dual);
// if (something != 0) {
// fun(npad_id_1, something, 0);
// }
state_1->Update();
state_2->Update();
state_1.Update();
state_2.Update();
return ResultSuccess;
}
@ -447,7 +452,7 @@ Result Npad::SetNpadHandheldActivationMode(const u64 aruid, const NpadHandheldAc
if (result.IsSuccess()) {
// TODO: recheck this part
active_npad_state->GetControllerState(NpadIdType::Handheld)->Update();
active_npad_state->GetControllerState(NpadIdType::Handheld).Update();
}
return result;
@ -620,23 +625,23 @@ Result Npad::AcquireNpadStyleSetUpdateEventHandle(const u64 aruid,
return ResultNpadNotConnected;
}
auto state = npad_state[index]->GetControllerState(npad_id);
if (!state->IsStyleSetUpdateEventInitialized()) {
state->SetStyleSetUpdateEventInitialized(false);
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));
state.SetNpadStyleSetUpdateEvent(std::move(styleset_update_event));
// Assume creating the event succeeds otherwise crash the system here
state->SetStyleSetUpdateEventInitialized(true);
state.SetStyleSetUpdateEventInitialized(true);
}
*out_event = &state->GetNpadStyleSetUpdateEvent();
*out_event = &state.GetNpadStyleSetUpdateEvent();
if (state->IsStyleSetUpdateEventInitialized()) {
state->SignalStyleSetUpdateEvent();
if (state.IsStyleSetUpdateEventInitialized()) {
state.SignalStyleSetUpdateEvent();
}
return ResultSuccess;
@ -778,7 +783,7 @@ Result Npad::GetMaskedSupportedNpadStyleSetImpl(const u64 aruid,
return ResultNpadNotConnected;
}
if (npad_state[index]->GetStatus().is_supported_style_set == 0) {
if (npad_state[index]->GetStatus().is_supported_styleset_set == 0) {
return ResultUndefinedStyleSet;
}
@ -817,22 +822,50 @@ Result Npad::GetMaskedSupportedNpadStyleSetImpl(const u64 aruid,
return ResultSuccess;
}
Result Npad::SetVibrationMasterVolume(const float volume) {
// std::scoped_lock lock{external_mutex};
if (volume < 0.0f || volume > 1.0f) {
return ResultVibrationVolumeOutOfRange;
}
vibration_master_volume = volume;
// nn::settings::detail::SetVibrationMasterVolume()
return ResultSuccess;
}
Result Npad::GetVibrationMasterVolume(float& out_volume) const {
// std::scoped_lock lock{external_mutex};
float current_volume{}; // nn::settings::detail::GetVibrationMasterVolume()
current_volume = vibration_master_volume; // TODO: Replace this with setting
if (current_volume < 0.0f || current_volume > 1.0f) {
return ResultVibrationVolumeOutOfRange;
}
out_volume = current_volume;
return ResultSuccess;
}
void Npad::UpdateSupportedNpadIdType() {
// Set some u64
// Call DisconnectAbstracPads(u64)
// Call ConnectAbstractPads(u64)
auto state = active_npad_state; // Verify this
state->GetControllerState(NpadIdType::Player1)->Update();
state->GetControllerState(NpadIdType::Player2)->Update();
state->GetControllerState(NpadIdType::Player3)->Update();
state->GetControllerState(NpadIdType::Player4)->Update();
state->GetControllerState(NpadIdType::Player5)->Update();
state->GetControllerState(NpadIdType::Player6)->Update();
state->GetControllerState(NpadIdType::Player7)->Update();
state->GetControllerState(NpadIdType::Player8)->Update();
state->GetControllerState(NpadIdType::Other)->Update();
state->GetControllerState(NpadIdType::Handheld)->Update();
auto& state = active_npad_state; // Verify this
state->GetControllerState(NpadIdType::Player1).Update();
state->GetControllerState(NpadIdType::Player2).Update();
state->GetControllerState(NpadIdType::Player3).Update();
state->GetControllerState(NpadIdType::Player4).Update();
state->GetControllerState(NpadIdType::Player5).Update();
state->GetControllerState(NpadIdType::Player6).Update();
state->GetControllerState(NpadIdType::Player7).Update();
state->GetControllerState(NpadIdType::Player8).Update();
state->GetControllerState(NpadIdType::Other).Update();
state->GetControllerState(NpadIdType::Handheld).Update();
}
void Npad::UpdateSupportedStyleSet() {
@ -841,17 +874,17 @@ void Npad::UpdateSupportedStyleSet() {
// Call FUN_7100063fc0(u64)
// Call ConnectAbstractPads(u64)
auto state = active_npad_state; // Verify this
state->GetControllerState(NpadIdType::Player1)->Update();
state->GetControllerState(NpadIdType::Player2)->Update();
state->GetControllerState(NpadIdType::Player3)->Update();
state->GetControllerState(NpadIdType::Player4)->Update();
state->GetControllerState(NpadIdType::Player5)->Update();
state->GetControllerState(NpadIdType::Player6)->Update();
state->GetControllerState(NpadIdType::Player7)->Update();
state->GetControllerState(NpadIdType::Player8)->Update();
state->GetControllerState(NpadIdType::Other)->Update();
state->GetControllerState(NpadIdType::Handheld)->Update();
auto& state = active_npad_state; // Verify this
state->GetControllerState(NpadIdType::Player1).Update();
state->GetControllerState(NpadIdType::Player2).Update();
state->GetControllerState(NpadIdType::Player3).Update();
state->GetControllerState(NpadIdType::Player4).Update();
state->GetControllerState(NpadIdType::Player5).Update();
state->GetControllerState(NpadIdType::Player6).Update();
state->GetControllerState(NpadIdType::Player7).Update();
state->GetControllerState(NpadIdType::Player8).Update();
state->GetControllerState(NpadIdType::Other).Update();
state->GetControllerState(NpadIdType::Handheld).Update();
}
u64 Npad::GetNpadActiveAruid() {

View File

@ -30,6 +30,7 @@ enum class NpadStyleSet : u32;
enum class NpadJoyHoldType : u64;
enum class NpadButton : u64;
enum class NpadRevision : u32;
using NpadBatteryLevel = u32;
struct SixAxisSensorHandle;
struct NpadInternalState;
@ -64,8 +65,6 @@ private:
};
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);
@ -141,6 +140,9 @@ public:
Result GetMaskedSupportedNpadStyleSet(const u64 aruid, NpadStyleSet& out_npad_styleset) const;
Result SetVibrationMasterVolume(const float volume);
Result GetVibrationMasterVolume(float& out_volume) const;
private:
// Interface implementations
Result SetSupportedNpadIdTypeImpl(const u64 aruid, std::span<const NpadIdType> list);
@ -181,6 +183,7 @@ private:
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;
float vibration_master_volume{};
};
} // namespace Service::HID

View File

@ -7,12 +7,8 @@
namespace Service::HID {
NpadControllerState::NpadControllerState() {}
NpadControllerState::~NpadControllerState() = default;
NpadIdType NpadControllerState::GetNpadId() const {
return npad_id;
return {}; // npad_id;
}
u64 NpadControllerState::IsUpdatePending() {
@ -22,27 +18,27 @@ u64 NpadControllerState::IsUpdatePending() {
void NpadControllerState::Update() {}
void NpadControllerState::SetNpadAssignmentMode(const NpadJoyAssignmentMode mode) {
assignament_mode = mode;
// assignament_mode = mode;
}
bool NpadControllerState::IsStyleSetUpdateEventInitialized() const {
return is_styleset_update_event_initialized;
return state.is_styleset_update_event_initialized;
}
void NpadControllerState::SetStyleSetUpdateEventInitialized(const bool is_initialized) {
is_styleset_update_event_initialized = is_initialized;
state.is_styleset_update_event_initialized = is_initialized;
}
void NpadControllerState::SetNpadStyleSetUpdateEvent(Kernel::KEvent* event) {
style_set_update_event = event;
state.style_set_update_event = event;
}
Kernel::KReadableEvent& NpadControllerState::GetNpadStyleSetUpdateEvent() {
return style_set_update_event->GetReadableEvent();
return state.style_set_update_event->GetReadableEvent();
}
void NpadControllerState::SignalStyleSetUpdateEvent() {
style_set_update_event->Signal();
state.style_set_update_event->Signal();
}
u32 NpadControllerState::GetConnectedControllerIndex() {

View File

@ -16,9 +16,6 @@ namespace Service::HID {
class NpadControllerState {
public:
explicit NpadControllerState();
~NpadControllerState();
NpadIdType GetNpadId() const;
u64 IsUpdatePending();
void Update();
@ -34,11 +31,18 @@ public:
u32 GetConnectedControllerIndex();
private:
NpadIdType npad_id{};
NpadJoyAssignmentMode assignament_mode{};
struct StateStructure {
bool is_styleset_update_event_initialized{};
INSERT_PADDING_BYTES(0x7);
Kernel::KEvent* style_set_update_event = nullptr;
INSERT_PADDING_BYTES(0x27);
};
static_assert(sizeof(StateStructure) == 0x38, "StateStructure is an invalid size");
bool is_styleset_update_event_initialized{};
Kernel::KEvent* style_set_update_event = nullptr;
StateStructure state{};
// NpadIdType npad_id{};
// NpadJoyAssignmentMode assignament_mode{};
};
} // namespace Service::HID

View File

@ -71,14 +71,6 @@ struct SixAxisSensorState {
};
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{};

View File

@ -4,35 +4,37 @@
#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<NpadControllerState>();
}
// for (auto& npad : state.controller_state) {
// npad = {};
// }
}
NpadState::~NpadState() = default;
std::shared_ptr<NpadControllerState> NpadState::GetControllerState(
const NpadIdType& npad_id) const {
return state[NpadIdTypeToIndex(npad_id)];
NpadControllerState& NpadState::GetControllerState(const NpadIdType& npad_id) {
return state.controller_state[NpadIdTypeToIndex(npad_id)];
}
const NpadControllerState& NpadState::GetControllerState(const NpadIdType& npad_id) const {
return state.controller_state[NpadIdTypeToIndex(npad_id)];
}
NpadState::NpadStatus NpadState::GetStatus() const {
return data.status;
return state.data.status;
}
void NpadState::SetNpadJoyHoldType(const NpadJoyHoldType hold_type) {
data.status.is_hold_type_set.Assign(1);
data.npad_hold_type = static_cast<u32>(hold_type);
state.data.status.is_hold_type_set.Assign(1);
state.data.npad_hold_type = static_cast<u32>(hold_type);
}
NpadJoyHoldType NpadState::GetNpadJoyHoldType() const {
return static_cast<NpadJoyHoldType>(data.npad_hold_type);
return static_cast<NpadJoyHoldType>(state.data.npad_hold_type);
}
Result NpadState::SetSupportedNpadIdType(std::span<const NpadIdType> list) {
@ -41,49 +43,49 @@ Result NpadState::SetSupportedNpadIdType(std::span<const NpadIdType> list) {
return ResultInvalidArraySize;
}
data.supported_npad_id_types_count = static_cast<u32>(list.size());
memcpy(data.supported_npad_id_types.data(), list.data(), list.size_bytes());
state.data.supported_npad_id_types_count = static_cast<u32>(list.size());
memcpy(state.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;
state.data.status.is_supported_styleset_set.Assign(1);
state.data.status.is_hold_type_set.Assign(1);
state.data.supported_npad_style_set = supported_style_set;
}
NpadStyleSet NpadState::GetSupportedNpadStyleSet() const {
return data.supported_npad_style_set;
return state.data.supported_npad_style_set;
}
void NpadState::SetLrAssignmentMode(const bool is_enabled) {
data.status.lr_assignment_mode.Assign(is_enabled);
state.data.status.lr_assignment_mode.Assign(is_enabled);
}
bool NpadState::GetLrAssignmentMode() const {
return data.status.lr_assignment_mode != 0;
return state.data.status.lr_assignment_mode != 0;
}
void NpadState::SetNpadHandheldActivationMode(const NpadHandheldActivationMode mode) {
data.handheld_activation_mode = static_cast<u32>(mode);
state.data.handheld_activation_mode = static_cast<u32>(mode);
}
NpadHandheldActivationMode NpadState::GetNpadHandheldActivationMode() const {
return static_cast<NpadHandheldActivationMode>(data.handheld_activation_mode);
return static_cast<NpadHandheldActivationMode>(state.data.handheld_activation_mode);
}
bool NpadState::IsUnintendedHomeButtonInputProtectionEnabled(const NpadIdType npad_id) const {
return data.is_unintended_home_button_input_protection[NpadIdTypeToIndex(npad_id)];
return state.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);
state.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;
state.data.npad_button_assignment[index] = npad_button_set;
}
std::size_t NpadState::GetCaptureButtonAssignment(
@ -95,9 +97,9 @@ std::size_t NpadState::GetCaptureButtonAssignment(
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];
(state.data.supported_npad_style_set & GetStylesetByIndex(index)) != NpadStyleSet::None;
if (is_defined && state.data.npad_button_assignment[index] != NpadButton::None) {
out_button_assignment[out_size] = state.data.npad_button_assignment[index];
out_size++;
}
}
@ -106,101 +108,108 @@ std::size_t NpadState::GetCaptureButtonAssignment(
}
void NpadState::ClearNpadSystemCommonPolicy() {
data.status.raw = 0;
data.supported_npad_style_set = NpadStyleSet::All;
data.npad_hold_type = static_cast<u32>(NpadJoyHoldType::Vertical);
data.handheld_activation_mode = static_cast<u32>(NpadHandheldActivationMode::Dual);
state.data.status.raw = 0;
state.data.supported_npad_style_set = NpadStyleSet::All;
state.data.npad_hold_type = static_cast<u32>(NpadJoyHoldType::Vertical);
state.data.handheld_activation_mode = static_cast<u32>(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;
state.data.npad_button_assignment[0] = NpadButton::None;
state.data.npad_button_assignment[1] = NpadButton::None;
state.data.npad_button_assignment[2] = NpadButton::None;
state.data.npad_button_assignment[3] = NpadButton::None;
state.data.npad_button_assignment[4] = NpadButton::None;
state.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;
state.data.supported_npad_id_types_count = 10;
state.data.supported_npad_id_types[0] = NpadIdType::Player1;
state.data.supported_npad_id_types[1] = NpadIdType::Player2;
state.data.supported_npad_id_types[2] = NpadIdType::Player3;
state.data.supported_npad_id_types[3] = NpadIdType::Player4;
state.data.supported_npad_id_types[4] = NpadIdType::Player5;
state.data.supported_npad_id_types[5] = NpadIdType::Player6;
state.data.supported_npad_id_types[6] = NpadIdType::Player7;
state.data.supported_npad_id_types[7] = NpadIdType::Player8;
state.data.supported_npad_id_types[8] = NpadIdType::Other;
state.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;
state.data.is_unintended_home_button_input_protection[0] = true;
state.data.is_unintended_home_button_input_protection[1] = true;
state.data.is_unintended_home_button_input_protection[2] = true;
state.data.is_unintended_home_button_input_protection[3] = true;
state.data.is_unintended_home_button_input_protection[4] = true;
state.data.is_unintended_home_button_input_protection[5] = true;
state.data.is_unintended_home_button_input_protection[6] = true;
state.data.is_unintended_home_button_input_protection[7] = true;
state.data.is_unintended_home_button_input_protection[8] = true;
state.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;
state.data.unknown[0] = 0;
state.data.unknown[1] = 0;
state.data.unknown[2] = 0;
state.data.unknown[3] = 0;
state.data.unknown[4] = 0;
state.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<u32>(NpadHandheldActivationMode::Dual);
state.data.supported_npad_style_set = NpadStyleSet::Fullkey | NpadStyleSet::JoyDual |
NpadStyleSet::SystemExt | NpadStyleSet::System;
state.data.handheld_activation_mode = static_cast<u32>(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);
state.data.status.is_supported_styleset_set.Assign(1);
state.data.status.is_hold_type_set.Assign(1);
state.data.status.lr_assignment_mode.Assign(0);
state.data.status.is_policy.Assign(1);
if (is_full_policy) {
data.status.is_full_policy.Assign(1);
state.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;
state.data.supported_npad_id_types_count = 10;
state.data.supported_npad_id_types[0] = NpadIdType::Player1;
state.data.supported_npad_id_types[1] = NpadIdType::Player2;
state.data.supported_npad_id_types[2] = NpadIdType::Player3;
state.data.supported_npad_id_types[3] = NpadIdType::Player4;
state.data.supported_npad_id_types[4] = NpadIdType::Player5;
state.data.supported_npad_id_types[5] = NpadIdType::Player6;
state.data.supported_npad_id_types[6] = NpadIdType::Player7;
state.data.supported_npad_id_types[7] = NpadIdType::Player8;
state.data.supported_npad_id_types[8] = NpadIdType::Other;
state.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;
state.data.is_unintended_home_button_input_protection[0] = true;
state.data.is_unintended_home_button_input_protection[1] = true;
state.data.is_unintended_home_button_input_protection[2] = true;
state.data.is_unintended_home_button_input_protection[3] = true;
state.data.is_unintended_home_button_input_protection[4] = true;
state.data.is_unintended_home_button_input_protection[5] = true;
state.data.is_unintended_home_button_input_protection[6] = true;
state.data.is_unintended_home_button_input_protection[7] = true;
state.data.is_unintended_home_button_input_protection[8] = true;
state.data.is_unintended_home_button_input_protection[9] = true;
}
bool NpadState::GetAssigningSingleOnSlSrPress() const {
return data.status.assigning_single_on_sl_sr_press != 0;
return state.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);
state.data.status.assigning_single_on_sl_sr_press.Assign(is_enabled);
}
bool NpadState::GetSystenExtState() const {
return state.data.status.system_ext_state != 0;
}
void NpadState::SetSystenExtState(const bool is_enabled) {
state.data.status.system_ext_state.Assign(is_enabled);
}
NpadRevision NpadState::GetNpadRevision() const {
return npad_revision;
return state.npad_revision;
}
void NpadState::SetNpadRevision(const NpadRevision revision) {
npad_revision = revision;
state.npad_revision = revision;
}
} // namespace Service::HID

View File

@ -8,6 +8,7 @@
#include <span>
#include "core/hle/service/hid/resource_manager/base_resource.h"
#include "core/hle/service/hid/resource_manager/npad_resource/npad_controller_state.h"
namespace Core {
class System;
@ -20,8 +21,6 @@ enum class NpadStyleSet : u32;
enum class NpadJoyHoldType : u64;
enum class NpadButton : u64;
enum class NpadRevision : u32;
class NpadControllerState;
} // namespace Service::HID
namespace Service::HID {
@ -32,13 +31,14 @@ public:
union {
u32 raw{};
BitField<0, 1, u32> is_supported_style_set;
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");
@ -46,7 +46,8 @@ public:
explicit NpadState();
~NpadState();
std::shared_ptr<NpadControllerState> GetControllerState(const NpadIdType& npad_id) const;
NpadControllerState& GetControllerState(const NpadIdType& npad_id);
const NpadControllerState& GetControllerState(const NpadIdType& npad_id) const;
NpadStatus GetStatus() const;
void SetNpadJoyHoldType(const NpadJoyHoldType hold_type);
@ -75,6 +76,9 @@ public:
bool GetAssigningSingleOnSlSrPress() const;
void SetAssigningSingleOnSlSrPress(const bool is_enabled);
bool GetSystenExtState() const;
void SetSystenExtState(const bool is_enabled);
NpadRevision GetNpadRevision() const;
void SetNpadRevision(const NpadRevision revision);
@ -85,18 +89,29 @@ private:
u32 npad_hold_type{};
u32 handheld_activation_mode{};
std::array<NpadIdType, PLAYERS_MAX> supported_npad_id_types{};
std::array<NpadButton, 7> npad_button_assignment;
std::array<u64, 6> unknown;
std::array<NpadButton, 7> npad_button_assignment{};
std::array<u64, 6> unknown{};
u32 supported_npad_id_types_count{};
std::array<bool, PLAYERS_MAX> is_unintended_home_button_input_protection{};
INSERT_PADDING_BYTES(0x2);
};
static_assert(sizeof(DataStructure) == 0xB0, "DataStructure is an invalid size");
DataStructure data{};
struct StateStructure {
u32 bit_flag{}; // unknown
INSERT_PADDING_BYTES(0x4);
u64 aruid{};
DataStructure data{};
INSERT_PADDING_BYTES(0x230);
std::array<u8, 0x280> aruid_related{}; // unknown
std::array<NpadControllerState, PLAYERS_MAX> controller_state{};
static_assert(sizeof(controller_state) == 0x230, "controller_state is an invalid size");
NpadRevision npad_revision{};
INSERT_PADDING_BYTES(0x4);
};
static_assert(sizeof(StateStructure) == 0x7a8, "StateStructure is an invalid size");
std::array<std::shared_ptr<NpadControllerState>, PLAYERS_MAX> state;
NpadRevision npad_revision{};
StateStructure state{};
};
} // namespace Service::HID