pineapple-src/src/hid_core/resources/abstracted_pad/abstract_properties_handler...

323 lines
12 KiB
C++
Executable File

// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "hid_core/hid_util.h"
#include "hid_core/resources/abstracted_pad/abstract_pad_holder.h"
#include "hid_core/resources/abstracted_pad/abstract_properties_handler.h"
#include "hid_core/resources/applet_resource.h"
#include "hid_core/resources/npad/npad_resource.h"
#include "hid_core/resources/npad/npad_types.h"
#include "hid_core/resources/shared_memory_format.h"
namespace Service::HID {
NpadAbstractPropertiesHandler::NpadAbstractPropertiesHandler() {}
NpadAbstractPropertiesHandler::~NpadAbstractPropertiesHandler() = default;
void NpadAbstractPropertiesHandler::SetAbstractPadHolder(NpadAbstractedPadHolder* holder) {
abstract_pad_holder = holder;
return;
}
void NpadAbstractPropertiesHandler::SetAppletResource(AppletResourceHolder* applet_resource) {
applet_resource_holder = applet_resource;
return;
}
void NpadAbstractPropertiesHandler::SetNpadId(Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
ASSERT_MSG(false, "Invalid npad id");
}
npad_id_type = npad_id;
}
Core::HID::NpadIdType NpadAbstractPropertiesHandler::GetNpadId() const {
return npad_id_type;
}
Result NpadAbstractPropertiesHandler::IncrementRefCounter() {
if (ref_counter == std::numeric_limits<s32>::max() - 1) {
return ResultNpadHandlerOverflow;
}
if (ref_counter != 0) {
ref_counter++;
return ResultSuccess;
}
const auto npad_index = NpadIdTypeToIndex(npad_id_type);
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
auto* data = applet_resource_holder->applet_resource->GetAruidData(aruid_index);
auto& internal_state =
data->shared_memory_format->npad.npad_entry[npad_index].internal_state;
if (!data->flag.is_assigned) {
continue;
}
internal_state.fullkey_lifo.buffer_count = 0;
internal_state.handheld_lifo.buffer_count = 0;
internal_state.joy_dual_lifo.buffer_count = 0;
internal_state.joy_left_lifo.buffer_count = 0;
internal_state.joy_right_lifo.buffer_count = 0;
internal_state.palma_lifo.buffer_count = 0;
internal_state.system_ext_lifo.buffer_count = 0;
internal_state.gc_trigger_lifo.buffer_count = 0;
internal_state.sixaxis_fullkey_lifo.lifo.buffer_count = 0;
internal_state.sixaxis_handheld_lifo.lifo.buffer_count = 0;
internal_state.sixaxis_dual_left_lifo.lifo.buffer_count = 0;
internal_state.sixaxis_dual_right_lifo.lifo.buffer_count = 0;
internal_state.sixaxis_left_lifo.lifo.buffer_count = 0;
internal_state.sixaxis_right_lifo.lifo.buffer_count = 0;
internal_state.style_tag = {Core::HID::NpadStyleSet::None};
internal_state.assignment_mode = NpadJoyAssignmentMode::Dual;
internal_state.joycon_color = {};
internal_state.fullkey_color = {};
internal_state.system_properties.raw = 0;
internal_state.button_properties.raw = 0;
internal_state.device_type.raw = 0;
internal_state.battery_level_dual = Core::HID::NpadBatteryLevel::Empty;
internal_state.battery_level_left = Core::HID::NpadBatteryLevel::Empty;
internal_state.battery_level_right = Core::HID::NpadBatteryLevel::Empty;
internal_state.applet_footer_type = AppletFooterUiType::None;
internal_state.applet_footer_attributes = {};
internal_state.lark_type_l_and_main = {};
internal_state.lark_type_r = {};
internal_state.sixaxis_fullkey_properties.is_newly_assigned.Assign(true);
internal_state.sixaxis_handheld_properties.is_newly_assigned.Assign(true);
internal_state.sixaxis_dual_left_properties.is_newly_assigned.Assign(true);
internal_state.sixaxis_dual_right_properties.is_newly_assigned.Assign(true);
internal_state.sixaxis_left_properties.is_newly_assigned.Assign(true);
internal_state.sixaxis_right_properties.is_newly_assigned.Assign(true);
}
ref_counter++;
return ResultSuccess;
}
Result NpadAbstractPropertiesHandler::DecrementRefCounter() {
if (ref_counter == 0) {
return ResultNpadHandlerNotInitialized;
}
ref_counter--;
return ResultSuccess;
}
Result NpadAbstractPropertiesHandler::ActivateNpadUnknown0x88(u64 aruid) {
const auto npad_index = NpadIdTypeToIndex(npad_id_type);
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
auto* data = applet_resource_holder->applet_resource->GetAruidData(aruid_index);
if (!data->flag.is_assigned || data->aruid != aruid) {
continue;
}
UpdateDeviceProperties(aruid, data->shared_memory_format->npad.npad_entry[npad_index]);
return ResultSuccess;
}
return ResultSuccess;
}
void NpadAbstractPropertiesHandler::UpdateDeviceType() {
// TODO
}
void NpadAbstractPropertiesHandler::UpdateDeviceColor() {
// TODO
}
void NpadAbstractPropertiesHandler::UpdateFooterAttributes() {
// TODO
}
void NpadAbstractPropertiesHandler::UpdateAllDeviceProperties() {
const auto npad_index = NpadIdTypeToIndex(npad_id_type);
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
auto* data = applet_resource_holder->applet_resource->GetAruidData(aruid_index);
if (data == nullptr || !data->flag.is_assigned) {
continue;
}
auto& npad_entry = data->shared_memory_format->npad.npad_entry[npad_index];
UpdateDeviceProperties(data->aruid, npad_entry);
}
}
Core::HID::NpadInterfaceType NpadAbstractPropertiesHandler::GetFullkeyInterfaceType() {
std::array<IAbstractedPad*, 5> abstract_pads{};
const std::size_t count = abstract_pad_holder->GetAbstractedPads(abstract_pads);
for (std::size_t i = 0; i < count; i++) {
auto* abstract_pad = abstract_pads[i];
if (!abstract_pad->internal_flags.is_connected) {
continue;
}
if (abstract_pad->device_type != Core::HID::NpadStyleIndex::Fullkey) {
continue;
}
if (abstract_pad->interface_type >= Core::HID::NpadInterfaceType::Embedded) {
// Abort
continue;
}
return abstract_pad->interface_type;
}
return Core::HID::NpadInterfaceType::None;
}
Core::HID::NpadInterfaceType NpadAbstractPropertiesHandler::GetInterfaceType() {
std::array<IAbstractedPad*, 5> abstract_pads{};
const std::size_t count = abstract_pad_holder->GetAbstractedPads(abstract_pads);
for (std::size_t i = 0; i < count; i++) {
auto* abstract_pad = abstract_pads[i];
if (!abstract_pad->internal_flags.is_connected) {
continue;
}
if (!abstract_pad->disabled_feature_set.has_identification_code) {
continue;
}
if (abstract_pad->interface_type >= Core::HID::NpadInterfaceType::Embedded) {
// Abort
continue;
}
return abstract_pad->interface_type;
}
return Core::HID::NpadInterfaceType::None;
}
Core::HID::NpadStyleSet NpadAbstractPropertiesHandler::GetStyleSet(u64 aruid) {
// TODO
return Core::HID::NpadStyleSet::None;
}
std::size_t NpadAbstractPropertiesHandler::GetAbstractedPadsWithStyleTag(
std::span<IAbstractedPad*> list, Core::HID::NpadStyleTag style) {
std::array<IAbstractedPad*, 5> abstract_pads{};
const std::size_t count = abstract_pad_holder->GetAbstractedPads(abstract_pads);
if (count == 0) {
return count;
}
bool is_supported_style_set{};
const auto result = applet_resource_holder->shared_npad_resource->IsSupportedNpadStyleSet(
is_supported_style_set, applet_resource_holder->applet_resource->GetActiveAruid());
if (!is_supported_style_set || result.IsError()) {
for (std::size_t i = 0; i < count; i++) {
// TODO
}
return count;
}
std::size_t filtered_count{};
for (std::size_t i = 0; i < count; i++) {
auto* abstract_pad = abstract_pads[i];
const bool is_enabled = true;
if (is_enabled) {
list[filtered_count] = abstract_pad;
filtered_count++;
}
}
return filtered_count;
}
std::size_t NpadAbstractPropertiesHandler::GetAbstractedPads(std::span<IAbstractedPad*> list) {
Core::HID::NpadStyleTag style{
GetStyleSet(applet_resource_holder->applet_resource->GetActiveAruid())};
return GetAbstractedPadsWithStyleTag(list, style);
}
AppletFooterUiType NpadAbstractPropertiesHandler::GetAppletFooterUiType() {
return applet_ui_type.footer;
}
AppletDetailedUiType NpadAbstractPropertiesHandler::GetAppletDetailedUiType() {
return applet_ui_type;
}
void NpadAbstractPropertiesHandler::UpdateDeviceProperties(u64 aruid,
NpadSharedMemoryEntry& internal_state) {
// TODO
}
Core::HID::NpadInterfaceType NpadAbstractPropertiesHandler::GetNpadInterfaceType() {
std::array<IAbstractedPad*, 5> abstract_pads{};
const std::size_t count = abstract_pad_holder->GetAbstractedPads(abstract_pads);
for (std::size_t i = 0; i < count; i++) {
auto* abstract_pad = abstract_pads[i];
if (!abstract_pad->internal_flags.is_connected) {
continue;
}
if (abstract_pad->interface_type >= Core::HID::NpadInterfaceType::Embedded) {
// Abort
continue;
}
return abstract_pad->interface_type;
}
return Core::HID::NpadInterfaceType::None;
}
Result NpadAbstractPropertiesHandler::GetNpadFullKeyGripColor(
Core::HID::NpadColor& main_color, Core::HID::NpadColor& sub_color) const {
std::array<IAbstractedPad*, 5> abstract_pads{};
const std::size_t count = abstract_pad_holder->GetAbstractedPads(abstract_pads);
if (applet_ui_type.footer != AppletFooterUiType::SwitchProController) {
return ResultNpadIsNotProController;
}
for (std::size_t i = 0; i < count; i++) {
auto* abstract_pad = abstract_pads[i];
if (!abstract_pad->internal_flags.is_connected) {
continue;
}
return ResultSuccess;
}
return ResultNpadIsNotProController;
}
void NpadAbstractPropertiesHandler::GetNpadLeftRightInterfaceType(
Core::HID::NpadInterfaceType& out_left_interface,
Core::HID::NpadInterfaceType& out_right_interface) const {
out_left_interface = Core::HID::NpadInterfaceType::None;
out_right_interface = Core::HID::NpadInterfaceType::None;
std::array<IAbstractedPad*, 5> abstract_pads{};
const std::size_t count = abstract_pad_holder->GetAbstractedPads(abstract_pads);
for (std::size_t i = 0; i < count; i++) {
auto* abstract_pad = abstract_pads[i];
if (!abstract_pad->internal_flags.is_connected) {
continue;
}
if (abstract_pad->assignment_style.is_external_left_assigned &&
abstract_pad->assignment_style.is_handheld_left_assigned) {
if (abstract_pad->interface_type > Core::HID::NpadInterfaceType::Embedded) {
// Abort
continue;
}
out_left_interface = abstract_pad->interface_type;
continue;
}
if (abstract_pad->assignment_style.is_external_right_assigned &&
abstract_pad->assignment_style.is_handheld_right_assigned) {
if (abstract_pad->interface_type > Core::HID::NpadInterfaceType::Embedded) {
// Abort
continue;
}
out_right_interface = abstract_pad->interface_type;
continue;
}
}
}
} // namespace Service::HID