committed by
Narr the Reg
51 changed files with 3333 additions and 43 deletions
-
4src/android/app/src/main/jni/native.cpp
-
2src/core/frontend/applets/controller.cpp
-
2src/core/hle/service/hid/hid_server.cpp
-
34src/hid_core/CMakeLists.txt
-
22src/hid_core/frontend/emulated_controller.cpp
-
3src/hid_core/hid_types.h
-
2src/hid_core/hid_util.h
-
197src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp
-
49src/hid_core/resources/abstracted_pad/abstract_battery_handler.h
-
199src/hid_core/resources/abstracted_pad/abstract_button_handler.cpp
-
75src/hid_core/resources/abstracted_pad/abstract_button_handler.h
-
126src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp
-
56src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h
-
123src/hid_core/resources/abstracted_pad/abstract_led_handler.cpp
-
43src/hid_core/resources/abstracted_pad/abstract_led_handler.h
-
108src/hid_core/resources/abstracted_pad/abstract_mcu_handler.cpp
-
52src/hid_core/resources/abstracted_pad/abstract_mcu_handler.h
-
140src/hid_core/resources/abstracted_pad/abstract_nfc_handler.cpp
-
57src/hid_core/resources/abstracted_pad/abstract_nfc_handler.h
-
294src/hid_core/resources/abstracted_pad/abstract_pad.cpp
-
123src/hid_core/resources/abstracted_pad/abstract_pad.h
-
99src/hid_core/resources/abstracted_pad/abstract_pad_holder.cpp
-
47src/hid_core/resources/abstracted_pad/abstract_pad_holder.h
-
47src/hid_core/resources/abstracted_pad/abstract_palma_handler.cpp
-
37src/hid_core/resources/abstracted_pad/abstract_palma_handler.h
-
322src/hid_core/resources/abstracted_pad/abstract_properties_handler.cpp
-
86src/hid_core/resources/abstracted_pad/abstract_properties_handler.h
-
154src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.cpp
-
61src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.h
-
73src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp
-
51src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h
-
8src/hid_core/resources/npad/npad.cpp
-
2src/hid_core/resources/npad/npad_data.cpp
-
99src/hid_core/resources/npad/npad_types.h
-
80src/hid_core/resources/npad/npad_vibration.cpp
-
34src/hid_core/resources/npad/npad_vibration.h
-
6src/hid_core/resources/six_axis/six_axis.cpp
-
106src/hid_core/resources/vibration/gc_vibration_device.cpp
-
31src/hid_core/resources/vibration/gc_vibration_device.h
-
80src/hid_core/resources/vibration/n64_vibration_device.cpp
-
29src/hid_core/resources/vibration/n64_vibration_device.h
-
30src/hid_core/resources/vibration/vibration_base.cpp
-
28src/hid_core/resources/vibration/vibration_base.h
-
84src/hid_core/resources/vibration/vibration_device.cpp
-
35src/hid_core/resources/vibration/vibration_device.h
-
8src/yuzu/applets/qt_controller.cpp
-
2src/yuzu/applets/qt_software_keyboard.cpp
-
18src/yuzu/configuration/configure_input_player.cpp
-
2src/yuzu/configuration/configure_input_player_widget.cpp
-
2src/yuzu/main.cpp
-
4src/yuzu/util/controller_navigation.cpp
@ -0,0 +1,197 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "core/core_timing.h"
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/hid_util.h"
|
|||
#include "hid_core/resources/abstracted_pad/abstract_battery_handler.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_types.h"
|
|||
#include "hid_core/resources/shared_memory_format.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadAbstractBatteryHandler::NpadAbstractBatteryHandler() {} |
|||
|
|||
NpadAbstractBatteryHandler::~NpadAbstractBatteryHandler() = default; |
|||
|
|||
void NpadAbstractBatteryHandler::SetAbstractPadHolder(NpadAbstractedPadHolder* holder) { |
|||
abstract_pad_holder = holder; |
|||
} |
|||
|
|||
void NpadAbstractBatteryHandler::SetAppletResource(AppletResourceHolder* applet_resource) { |
|||
applet_resource_holder = applet_resource; |
|||
} |
|||
|
|||
void NpadAbstractBatteryHandler::SetPropertiesHandler(NpadAbstractPropertiesHandler* handler) { |
|||
properties_handler = handler; |
|||
} |
|||
|
|||
Result NpadAbstractBatteryHandler::IncrementRefCounter() { |
|||
if (ref_counter == std::numeric_limits<s32>::max() - 1) { |
|||
return ResultNpadHandlerOverflow; |
|||
} |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractBatteryHandler::DecrementRefCounter() { |
|||
if (ref_counter == 0) { |
|||
return ResultNpadHandlerNotInitialized; |
|||
} |
|||
ref_counter--; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractBatteryHandler::UpdateBatteryState(u64 aruid) { |
|||
const auto npad_index = NpadIdTypeToIndex(properties_handler->GetNpadId()); |
|||
AruidData* aruid_data = applet_resource_holder->applet_resource->GetAruidData(aruid); |
|||
if (aruid_data == nullptr) { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
auto& npad_internal_state = |
|||
aruid_data->shared_memory_format->npad.npad_entry[npad_index].internal_state; |
|||
auto& system_properties = npad_internal_state.system_properties; |
|||
|
|||
system_properties.is_charging_joy_dual.Assign(dual_battery.is_charging); |
|||
system_properties.is_powered_joy_dual.Assign(dual_battery.is_powered); |
|||
system_properties.is_charging_joy_left.Assign(left_battery.is_charging); |
|||
system_properties.is_powered_joy_left.Assign(left_battery.is_powered); |
|||
system_properties.is_charging_joy_right.Assign(right_battery.is_charging); |
|||
system_properties.is_powered_joy_right.Assign(right_battery.is_powered); |
|||
|
|||
npad_internal_state.battery_level_dual = dual_battery.battery_level; |
|||
npad_internal_state.battery_level_left = left_battery.battery_level; |
|||
npad_internal_state.battery_level_right = right_battery.battery_level; |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void NpadAbstractBatteryHandler::UpdateBatteryState() { |
|||
if (ref_counter == 0) { |
|||
return; |
|||
} |
|||
has_new_battery_data = GetNewBatteryState(); |
|||
} |
|||
|
|||
bool NpadAbstractBatteryHandler::GetNewBatteryState() { |
|||
bool has_changed = false; |
|||
Core::HID::NpadPowerInfo new_dual_battery_state{}; |
|||
Core::HID::NpadPowerInfo new_left_battery_state{}; |
|||
Core::HID::NpadPowerInfo new_right_battery_state{}; |
|||
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; |
|||
} |
|||
const auto power_info = abstract_pad->power_info; |
|||
if (power_info.battery_level > Core::HID::NpadBatteryLevel::Full) { |
|||
// Abort
|
|||
continue; |
|||
} |
|||
|
|||
const auto style = abstract_pad->assignment_style; |
|||
|
|||
if (style.is_external_assigned || style.is_handheld_assigned) { |
|||
new_dual_battery_state = power_info; |
|||
} |
|||
if (style.is_external_left_assigned || style.is_handheld_left_assigned) { |
|||
new_left_battery_state = power_info; |
|||
} |
|||
if (style.is_external_right_assigned || style.is_handheld_right_assigned) { |
|||
new_right_battery_state = power_info; |
|||
} |
|||
|
|||
if (abstract_pad->internal_flags.is_battery_low_ovln_required) { |
|||
if (abstract_pad->interface_type == Core::HID::NpadInterfaceType::Rail) { |
|||
// TODO
|
|||
} |
|||
abstract_pad->internal_flags.is_battery_low_ovln_required.Assign(false); |
|||
} |
|||
} |
|||
|
|||
if (dual_battery.battery_level != new_dual_battery_state.battery_level || |
|||
dual_battery.is_charging != new_dual_battery_state.is_charging || |
|||
dual_battery.is_powered != new_dual_battery_state.is_powered) { |
|||
has_changed = true; |
|||
dual_battery = new_dual_battery_state; |
|||
} |
|||
|
|||
if (left_battery.battery_level != new_left_battery_state.battery_level || |
|||
left_battery.is_charging != new_left_battery_state.is_charging || |
|||
left_battery.is_powered != new_left_battery_state.is_powered) { |
|||
has_changed = true; |
|||
left_battery = new_left_battery_state; |
|||
} |
|||
|
|||
if (right_battery.battery_level != new_right_battery_state.battery_level || |
|||
right_battery.is_charging != new_right_battery_state.is_charging || |
|||
right_battery.is_powered != new_right_battery_state.is_powered) { |
|||
has_changed = true; |
|||
right_battery = new_right_battery_state; |
|||
} |
|||
|
|||
return has_changed; |
|||
} |
|||
|
|||
void NpadAbstractBatteryHandler::UpdateCoreBatteryState() { |
|||
if (ref_counter == 0) { |
|||
return; |
|||
} |
|||
if (!has_new_battery_data) { |
|||
return; |
|||
} |
|||
|
|||
UpdateBatteryState(0); |
|||
} |
|||
|
|||
void NpadAbstractBatteryHandler::InitializeBatteryState(u64 aruid) { |
|||
UpdateBatteryState(aruid); |
|||
} |
|||
|
|||
bool NpadAbstractBatteryHandler::HasBattery() const { |
|||
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++) { |
|||
const auto* abstract_pad = abstract_pads[i]; |
|||
if (!abstract_pad->internal_flags.is_connected) { |
|||
continue; |
|||
} |
|||
return abstract_pad->disabled_feature_set.has_fullkey_battery || |
|||
abstract_pad->disabled_feature_set.has_left_right_joy_battery; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
void NpadAbstractBatteryHandler::HasLeftRightBattery(bool& has_left, bool& has_right) const { |
|||
std::array<IAbstractedPad*, 5> abstract_pads{}; |
|||
const std::size_t count = abstract_pad_holder->GetAbstractedPads(abstract_pads); |
|||
|
|||
has_left = false; |
|||
has_right = false; |
|||
|
|||
for (std::size_t i = 0; i < count; i++) { |
|||
const auto* abstract_pad = abstract_pads[i]; |
|||
if (!abstract_pad->internal_flags.is_connected) { |
|||
continue; |
|||
} |
|||
if (!abstract_pad->disabled_feature_set.has_fullkey_battery && |
|||
!abstract_pad->disabled_feature_set.has_left_right_joy_battery) { |
|||
continue; |
|||
} |
|||
has_left = abstract_pad->assignment_style.is_external_left_assigned || |
|||
abstract_pad->assignment_style.is_handheld_left_assigned; |
|||
has_right = abstract_pad->assignment_style.is_external_right_assigned || |
|||
abstract_pad->assignment_style.is_handheld_right_assigned; |
|||
} |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,49 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
|
|||
namespace Service::HID { |
|||
struct AppletResourceHolder; |
|||
class NpadAbstractedPadHolder; |
|||
class NpadAbstractPropertiesHandler; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NpadAbstractBatteryHandler final { |
|||
public: |
|||
explicit NpadAbstractBatteryHandler(); |
|||
~NpadAbstractBatteryHandler(); |
|||
|
|||
void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); |
|||
void SetAppletResource(AppletResourceHolder* applet_resource); |
|||
void SetPropertiesHandler(NpadAbstractPropertiesHandler* handler); |
|||
|
|||
Result IncrementRefCounter(); |
|||
Result DecrementRefCounter(); |
|||
|
|||
Result UpdateBatteryState(u64 aruid); |
|||
void UpdateBatteryState(); |
|||
bool GetNewBatteryState(); |
|||
void UpdateCoreBatteryState(); |
|||
void InitializeBatteryState(u64 aruid); |
|||
|
|||
bool HasBattery() const; |
|||
void HasLeftRightBattery(bool& has_left, bool& has_right) const; |
|||
|
|||
private: |
|||
AppletResourceHolder* applet_resource_holder{nullptr}; |
|||
NpadAbstractedPadHolder* abstract_pad_holder{nullptr}; |
|||
NpadAbstractPropertiesHandler* properties_handler{nullptr}; |
|||
|
|||
s32 ref_counter{}; |
|||
Core::HID::NpadPowerInfo dual_battery{}; |
|||
Core::HID::NpadPowerInfo left_battery{}; |
|||
Core::HID::NpadPowerInfo right_battery{}; |
|||
bool has_new_battery_data{}; |
|||
}; |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,199 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/hid_util.h"
|
|||
#include "hid_core/resources/abstracted_pad/abstract_button_handler.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 { |
|||
|
|||
NpadAbstractButtonHandler::NpadAbstractButtonHandler() {} |
|||
|
|||
NpadAbstractButtonHandler::~NpadAbstractButtonHandler() = default; |
|||
|
|||
void NpadAbstractButtonHandler::SetAbstractPadHolder(NpadAbstractedPadHolder* holder) { |
|||
abstract_pad_holder = holder; |
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::SetAppletResource(AppletResourceHolder* applet_resource) { |
|||
applet_resource_holder = applet_resource; |
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::SetPropertiesHandler(NpadAbstractPropertiesHandler* handler) { |
|||
properties_handler = handler; |
|||
} |
|||
|
|||
Result NpadAbstractButtonHandler::IncrementRefCounter() { |
|||
if (ref_counter == std::numeric_limits<s32>::max() - 1) { |
|||
return ResultNpadHandlerOverflow; |
|||
} |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractButtonHandler::DecrementRefCounter() { |
|||
if (ref_counter == 0) { |
|||
return ResultNpadHandlerNotInitialized; |
|||
} |
|||
ref_counter--; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractButtonHandler::UpdateAllButtonWithHomeProtection(u64 aruid) { |
|||
const Core::HID::NpadIdType npad_id = properties_handler->GetNpadId(); |
|||
auto* data = applet_resource_holder->applet_resource->GetAruidData(aruid); |
|||
|
|||
if (data == nullptr) { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)]; |
|||
UpdateButtonLifo(npad_entry, aruid); |
|||
|
|||
bool is_home_button_protection_enabled{}; |
|||
const auto result = applet_resource_holder->shared_npad_resource->GetHomeProtectionEnabled( |
|||
is_home_button_protection_enabled, aruid, npad_id); |
|||
|
|||
if (result.IsError()) { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
npad_entry.internal_state.button_properties.is_home_button_protection_enabled.Assign( |
|||
is_home_button_protection_enabled); |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::UpdateAllButtonLifo() { |
|||
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId(); |
|||
for (std::size_t i = 0; i < AruidIndexMax; i++) { |
|||
auto* data = applet_resource_holder->applet_resource->GetAruidDataByIndex(i); |
|||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)]; |
|||
UpdateButtonLifo(npad_entry, data->aruid); |
|||
} |
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::UpdateCoreBatteryState() { |
|||
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId(); |
|||
for (std::size_t i = 0; i < AruidIndexMax; i++) { |
|||
auto* data = applet_resource_holder->applet_resource->GetAruidDataByIndex(i); |
|||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)]; |
|||
UpdateButtonLifo(npad_entry, data->aruid); |
|||
} |
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::UpdateButtonState(u64 aruid) { |
|||
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId(); |
|||
auto* data = applet_resource_holder->applet_resource->GetAruidData(aruid); |
|||
if (data == nullptr) { |
|||
return; |
|||
} |
|||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)]; |
|||
UpdateButtonLifo(npad_entry, aruid); |
|||
} |
|||
|
|||
Result NpadAbstractButtonHandler::SetHomeProtection(bool is_enabled, u64 aruid) { |
|||
const Core::HID::NpadIdType npad_id = properties_handler->GetNpadId(); |
|||
auto result = applet_resource_holder->shared_npad_resource->SetHomeProtectionEnabled( |
|||
aruid, npad_id, is_enabled); |
|||
if (result.IsError()) { |
|||
return result; |
|||
} |
|||
|
|||
auto* data = applet_resource_holder->applet_resource->GetAruidData(aruid); |
|||
if (data == nullptr) { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
bool is_home_protection_enabled{}; |
|||
result = applet_resource_holder->shared_npad_resource->GetHomeProtectionEnabled( |
|||
is_home_protection_enabled, aruid, npad_id); |
|||
if (result.IsError()) { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)]; |
|||
npad_entry.internal_state.button_properties.is_home_button_protection_enabled.Assign( |
|||
is_home_protection_enabled); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
bool NpadAbstractButtonHandler::IsButtonPressedOnConsoleMode() { |
|||
return is_button_pressed_on_console_mode; |
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::EnableCenterClamp() { |
|||
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; |
|||
} |
|||
abstract_pad->internal_flags.use_center_clamp.Assign(true); |
|||
} |
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::UpdateButtonLifo(NpadSharedMemoryEntry& shared_memory, u64 aruid) { |
|||
auto* npad_resource = applet_resource_holder->shared_npad_resource; |
|||
Core::HID::NpadStyleTag style_tag = {properties_handler->GetStyleSet(aruid)}; |
|||
style_tag.system_ext.Assign(npad_resource->GetActiveData()->GetNpadSystemExtState()); |
|||
|
|||
UpdateNpadFullkeyLifo(style_tag, 0, aruid, shared_memory); |
|||
UpdateHandheldLifo(style_tag, 1, aruid, shared_memory); |
|||
UpdateJoyconDualLifo(style_tag, 2, aruid, shared_memory); |
|||
UpdateJoyconLeftLifo(style_tag, 3, aruid, shared_memory); |
|||
UpdateJoyconRightLifo(style_tag, 4, aruid, shared_memory); |
|||
UpdatePalmaLifo(style_tag, 5, aruid, shared_memory); |
|||
UpdateSystemExtLifo(style_tag, 6, aruid, shared_memory); |
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::UpdateNpadFullkeyLifo(Core::HID::NpadStyleTag style_tag, |
|||
int style_index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory) { |
|||
// TODO
|
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::UpdateHandheldLifo(Core::HID::NpadStyleTag style_tag, |
|||
int style_index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory) { |
|||
// TODO
|
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::UpdateJoyconDualLifo(Core::HID::NpadStyleTag style_tag, |
|||
int style_index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory) { |
|||
// TODO
|
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::UpdateJoyconLeftLifo(Core::HID::NpadStyleTag style_tag, |
|||
int style_index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory) { |
|||
// TODO
|
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::UpdateJoyconRightLifo(Core::HID::NpadStyleTag style_tag, |
|||
int style_index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory) { |
|||
// TODO
|
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::UpdateSystemExtLifo(Core::HID::NpadStyleTag style_tag, |
|||
int style_index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory) { |
|||
// TODO
|
|||
} |
|||
|
|||
void NpadAbstractButtonHandler::UpdatePalmaLifo(Core::HID::NpadStyleTag style_tag, int style_index, |
|||
u64 aruid, NpadSharedMemoryEntry& shared_memory) { |
|||
// TODO
|
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,75 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
|
|||
namespace Service::HID { |
|||
struct NpadSharedMemoryEntry; |
|||
|
|||
struct AppletResourceHolder; |
|||
class NpadAbstractedPadHolder; |
|||
class NpadAbstractPropertiesHandler; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NpadAbstractButtonHandler final { |
|||
public: |
|||
explicit NpadAbstractButtonHandler(); |
|||
~NpadAbstractButtonHandler(); |
|||
|
|||
void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); |
|||
void SetAppletResource(AppletResourceHolder* applet_resource); |
|||
void SetPropertiesHandler(NpadAbstractPropertiesHandler* handler); |
|||
|
|||
Result IncrementRefCounter(); |
|||
Result DecrementRefCounter(); |
|||
|
|||
Result UpdateAllButtonWithHomeProtection(u64 aruid); |
|||
|
|||
void UpdateAllButtonLifo(); |
|||
void UpdateCoreBatteryState(); |
|||
void UpdateButtonState(u64 aruid); |
|||
|
|||
Result SetHomeProtection(bool is_enabled, u64 aruid); |
|||
bool IsButtonPressedOnConsoleMode(); |
|||
void EnableCenterClamp(); |
|||
|
|||
void UpdateButtonLifo(NpadSharedMemoryEntry& shared_memory, u64 aruid); |
|||
|
|||
void UpdateNpadFullkeyLifo(Core::HID::NpadStyleTag style_tag, int index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory); |
|||
void UpdateHandheldLifo(Core::HID::NpadStyleTag style_tag, int index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory); |
|||
void UpdateJoyconDualLifo(Core::HID::NpadStyleTag style_tag, int index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory); |
|||
void UpdateJoyconLeftLifo(Core::HID::NpadStyleTag style_tag, int index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory); |
|||
void UpdateJoyconRightLifo(Core::HID::NpadStyleTag style_tag, int index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory); |
|||
void UpdateSystemExtLifo(Core::HID::NpadStyleTag style_tag, int index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory); |
|||
void UpdatePalmaLifo(Core::HID::NpadStyleTag style_tag, int index, u64 aruid, |
|||
NpadSharedMemoryEntry& shared_memory); |
|||
|
|||
private: |
|||
struct GcTrigger { |
|||
float left; |
|||
float right; |
|||
}; |
|||
|
|||
AppletResourceHolder* applet_resource_holder{nullptr}; |
|||
NpadAbstractedPadHolder* abstract_pad_holder{nullptr}; |
|||
NpadAbstractPropertiesHandler* properties_handler{nullptr}; |
|||
|
|||
s32 ref_counter{}; |
|||
|
|||
bool is_button_pressed_on_console_mode{}; |
|||
|
|||
u64 gc_sampling_number{}; |
|||
GcTrigger gc_trigger_state{}; |
|||
}; |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,126 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "core/hle/kernel/k_event.h"
|
|||
#include "core/hle/kernel/k_readable_event.h"
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.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/npad/npad_types.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadAbstractIrSensorHandler::NpadAbstractIrSensorHandler() {} |
|||
|
|||
NpadAbstractIrSensorHandler::~NpadAbstractIrSensorHandler() = default; |
|||
|
|||
void NpadAbstractIrSensorHandler::SetAbstractPadHolder(NpadAbstractedPadHolder* holder) { |
|||
abstract_pad_holder = holder; |
|||
} |
|||
|
|||
void NpadAbstractIrSensorHandler::SetPropertiesHandler(NpadAbstractPropertiesHandler* handler) { |
|||
properties_handler = handler; |
|||
} |
|||
|
|||
Result NpadAbstractIrSensorHandler::IncrementRefCounter() { |
|||
if (ref_counter == std::numeric_limits<s32>::max() - 1) { |
|||
return ResultNpadHandlerOverflow; |
|||
} |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractIrSensorHandler::DecrementRefCounter() { |
|||
if (ref_counter == 0) { |
|||
return ResultNpadHandlerNotInitialized; |
|||
} |
|||
ref_counter--; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void NpadAbstractIrSensorHandler::UpdateIrSensorState() { |
|||
const auto previous_state = sensor_state; |
|||
std::array<IAbstractedPad*, 5> abstract_pads{}; |
|||
const std::size_t count = abstract_pad_holder->GetAbstractedPads(abstract_pads); |
|||
|
|||
if (count == 0) { |
|||
sensor_state = NpadIrSensorState::Disabled; |
|||
if (sensor_state == previous_state) { |
|||
return; |
|||
} |
|||
ir_sensor_event->Signal(); |
|||
return; |
|||
} |
|||
|
|||
bool is_found{}; |
|||
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_bluetooth_address) { |
|||
continue; |
|||
} |
|||
is_found = true; |
|||
xcd_handle = abstract_pad->xcd_handle; |
|||
} |
|||
|
|||
if (is_found) { |
|||
if (sensor_state == NpadIrSensorState::Active) { |
|||
return; |
|||
} |
|||
sensor_state = NpadIrSensorState::Available; |
|||
if (sensor_state == previous_state) { |
|||
return; |
|||
} |
|||
ir_sensor_event->Signal(); |
|||
return; |
|||
} |
|||
|
|||
sensor_state = NpadIrSensorState::Unavailable; |
|||
if (sensor_state == previous_state) { |
|||
return; |
|||
} |
|||
|
|||
ir_sensor_event->Signal(); |
|||
return; |
|||
} |
|||
|
|||
Result NpadAbstractIrSensorHandler::ActivateIrSensor(bool is_enabled) { |
|||
if (sensor_state == NpadIrSensorState::Unavailable) { |
|||
return ResultIrSensorIsNotReady; |
|||
} |
|||
if (is_enabled && sensor_state == NpadIrSensorState::Available) { |
|||
sensor_state = NpadIrSensorState::Active; |
|||
} else { |
|||
if (is_enabled) { |
|||
return ResultSuccess; |
|||
} |
|||
if (sensor_state != NpadIrSensorState::Active) { |
|||
return ResultSuccess; |
|||
} |
|||
sensor_state = NpadIrSensorState::Available; |
|||
} |
|||
ir_sensor_event->Signal(); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractIrSensorHandler::GetIrSensorEventHandle(Kernel::KReadableEvent** out_event) { |
|||
*out_event = &ir_sensor_event->GetReadableEvent(); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractIrSensorHandler::GetXcdHandleForNpadWithIrSensor(u64& handle) const { |
|||
if (sensor_state < NpadIrSensorState::Available) { |
|||
return ResultIrSensorIsNotReady; |
|||
} |
|||
handle = xcd_handle; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
NpadIrSensorState NpadAbstractIrSensorHandler::GetSensorState() const { |
|||
return sensor_state; |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,56 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
|
|||
namespace Kernel { |
|||
class KEvent; |
|||
class KReadableEvent; |
|||
} // namespace Kernel |
|||
|
|||
enum class NpadIrSensorState : u32 { |
|||
Disabled, |
|||
Unavailable, |
|||
Available, |
|||
Active, |
|||
}; |
|||
|
|||
namespace Service::HID { |
|||
class NpadAbstractedPadHolder; |
|||
class NpadAbstractPropertiesHandler; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NpadAbstractIrSensorHandler final { |
|||
public: |
|||
explicit NpadAbstractIrSensorHandler(); |
|||
~NpadAbstractIrSensorHandler(); |
|||
|
|||
void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); |
|||
void SetPropertiesHandler(NpadAbstractPropertiesHandler* handler); |
|||
|
|||
Result IncrementRefCounter(); |
|||
Result DecrementRefCounter(); |
|||
|
|||
void UpdateIrSensorState(); |
|||
Result ActivateIrSensor(bool param_2); |
|||
|
|||
Result GetIrSensorEventHandle(Kernel::KReadableEvent** out_event); |
|||
|
|||
Result GetXcdHandleForNpadWithIrSensor(u64& handle) const; |
|||
|
|||
NpadIrSensorState GetSensorState() const; |
|||
|
|||
private: |
|||
NpadAbstractedPadHolder* abstract_pad_holder{nullptr}; |
|||
NpadAbstractPropertiesHandler* properties_handler{nullptr}; |
|||
|
|||
s32 ref_counter{}; |
|||
Kernel::KEvent* ir_sensor_event{nullptr}; |
|||
u64 xcd_handle{}; |
|||
NpadIrSensorState sensor_state{}; |
|||
}; |
|||
} // namespace Service::HID |
|||
@ -0,0 +1,123 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "core/core_timing.h"
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/hid_util.h"
|
|||
#include "hid_core/resources/abstracted_pad/abstract_led_handler.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_types.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadAbstractLedHandler::NpadAbstractLedHandler() {} |
|||
|
|||
NpadAbstractLedHandler::~NpadAbstractLedHandler() = default; |
|||
|
|||
void NpadAbstractLedHandler::SetAbstractPadHolder(NpadAbstractedPadHolder* holder) { |
|||
abstract_pad_holder = holder; |
|||
} |
|||
|
|||
void NpadAbstractLedHandler::SetAppletResource(AppletResourceHolder* applet_resource) { |
|||
applet_resource_holder = applet_resource; |
|||
} |
|||
|
|||
void NpadAbstractLedHandler::SetPropertiesHandler(NpadAbstractPropertiesHandler* handler) { |
|||
properties_handler = handler; |
|||
} |
|||
|
|||
Result NpadAbstractLedHandler::IncrementRefCounter() { |
|||
if (ref_counter == std::numeric_limits<s32>::max() - 1) { |
|||
return ResultNpadHandlerOverflow; |
|||
} |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractLedHandler::DecrementRefCounter() { |
|||
if (ref_counter == 0) { |
|||
return ResultNpadHandlerNotInitialized; |
|||
} |
|||
ref_counter--; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void NpadAbstractLedHandler::SetNpadLedHandlerLedPattern() { |
|||
const auto npad_id = properties_handler->GetNpadId(); |
|||
|
|||
switch (npad_id) { |
|||
case Core::HID::NpadIdType::Player1: |
|||
left_pattern = Core::HID::LedPattern{1, 0, 0, 0}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player2: |
|||
left_pattern = Core::HID::LedPattern{1, 1, 0, 0}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player3: |
|||
left_pattern = Core::HID::LedPattern{1, 1, 1, 0}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player4: |
|||
left_pattern = Core::HID::LedPattern{1, 1, 1, 1}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player5: |
|||
left_pattern = Core::HID::LedPattern{1, 0, 0, 1}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player6: |
|||
left_pattern = Core::HID::LedPattern{1, 0, 1, 0}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player7: |
|||
left_pattern = Core::HID::LedPattern{1, 0, 1, 1}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player8: |
|||
left_pattern = Core::HID::LedPattern{0, 1, 1, 0}; |
|||
break; |
|||
case Core::HID::NpadIdType::Other: |
|||
case Core::HID::NpadIdType::Handheld: |
|||
left_pattern = Core::HID::LedPattern{0, 0, 0, 0}; |
|||
break; |
|||
default: |
|||
ASSERT_MSG(false, "Invalid npad id type"); |
|||
break; |
|||
} |
|||
|
|||
switch (npad_id) { |
|||
case Core::HID::NpadIdType::Player1: |
|||
right_pattern = Core::HID::LedPattern{0, 0, 0, 1}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player2: |
|||
right_pattern = Core::HID::LedPattern{0, 1, 1, 1}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player3: |
|||
right_pattern = Core::HID::LedPattern{0, 1, 1, 1}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player4: |
|||
right_pattern = Core::HID::LedPattern{1, 1, 1, 1}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player5: |
|||
right_pattern = Core::HID::LedPattern{1, 0, 0, 1}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player6: |
|||
right_pattern = Core::HID::LedPattern{0, 1, 0, 1}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player7: |
|||
right_pattern = Core::HID::LedPattern{1, 1, 0, 1}; |
|||
break; |
|||
case Core::HID::NpadIdType::Player8: |
|||
right_pattern = Core::HID::LedPattern{0, 1, 1, 0}; |
|||
break; |
|||
case Core::HID::NpadIdType::Other: |
|||
case Core::HID::NpadIdType::Handheld: |
|||
right_pattern = Core::HID::LedPattern{0, 0, 0, 0}; |
|||
break; |
|||
default: |
|||
ASSERT_MSG(false, "Invalid npad id type"); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
void NpadAbstractLedHandler::SetLedBlinkingDevice(Core::HID::LedPattern pattern) { |
|||
led_blinking = pattern; |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,43 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
|
|||
namespace Service::HID { |
|||
struct AppletResourceHolder; |
|||
class NpadAbstractedPadHolder; |
|||
class NpadAbstractPropertiesHandler; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NpadAbstractLedHandler final { |
|||
public: |
|||
explicit NpadAbstractLedHandler(); |
|||
~NpadAbstractLedHandler(); |
|||
|
|||
void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); |
|||
void SetAppletResource(AppletResourceHolder* applet_resource); |
|||
void SetPropertiesHandler(NpadAbstractPropertiesHandler* handler); |
|||
|
|||
Result IncrementRefCounter(); |
|||
Result DecrementRefCounter(); |
|||
|
|||
void SetNpadLedHandlerLedPattern(); |
|||
|
|||
void SetLedBlinkingDevice(Core::HID::LedPattern pattern); |
|||
|
|||
private: |
|||
AppletResourceHolder* applet_resource_holder{nullptr}; |
|||
NpadAbstractedPadHolder* abstract_pad_holder{nullptr}; |
|||
NpadAbstractPropertiesHandler* properties_handler{nullptr}; |
|||
|
|||
s32 ref_counter{}; |
|||
Core::HID::LedPattern led_blinking{0, 0, 0, 0}; |
|||
Core::HID::LedPattern left_pattern{0, 0, 0, 0}; |
|||
Core::HID::LedPattern right_pattern{0, 0, 0, 0}; |
|||
u64 led_interval{}; |
|||
}; |
|||
} // namespace Service::HID |
|||
@ -0,0 +1,108 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/resources/abstracted_pad/abstract_mcu_handler.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/npad/npad_types.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadAbstractMcuHandler::NpadAbstractMcuHandler() {} |
|||
|
|||
NpadAbstractMcuHandler::~NpadAbstractMcuHandler() = default; |
|||
|
|||
void NpadAbstractMcuHandler::SetAbstractPadHolder(NpadAbstractedPadHolder* holder) { |
|||
abstract_pad_holder = holder; |
|||
} |
|||
|
|||
void NpadAbstractMcuHandler::SetPropertiesHandler(NpadAbstractPropertiesHandler* handler) { |
|||
properties_handler = handler; |
|||
} |
|||
|
|||
Result NpadAbstractMcuHandler::IncrementRefCounter() { |
|||
if (ref_counter == std::numeric_limits<s32>::max() - 1) { |
|||
return ResultNpadHandlerOverflow; |
|||
} |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractMcuHandler::DecrementRefCounter() { |
|||
if (ref_counter == 0) { |
|||
return ResultNpadHandlerNotInitialized; |
|||
} |
|||
ref_counter--; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void NpadAbstractMcuHandler::UpdateMcuState() { |
|||
std::array<IAbstractedPad*, 5> abstract_pads{}; |
|||
const std::size_t count = properties_handler->GetAbstractedPads(abstract_pads); |
|||
|
|||
if (count == 0) { |
|||
mcu_holder = {}; |
|||
return; |
|||
} |
|||
|
|||
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_left_joy_rail_bus) { |
|||
if (!abstract_pad->disabled_feature_set.has_left_joy_six_axis_sensor && |
|||
!abstract_pad->disabled_feature_set.has_right_joy_six_axis_sensor) { |
|||
continue; |
|||
} |
|||
if (mcu_holder[1].state != NpadMcuState::Active) { |
|||
mcu_holder[1].state = NpadMcuState::Available; |
|||
} |
|||
mcu_holder[1].abstracted_pad = abstract_pad; |
|||
continue; |
|||
} |
|||
if (mcu_holder[0].state != NpadMcuState::Active) { |
|||
mcu_holder[0].state = NpadMcuState::Available; |
|||
} |
|||
mcu_holder[0].abstracted_pad = abstract_pad; |
|||
} |
|||
} |
|||
|
|||
Result NpadAbstractMcuHandler::GetAbstractedPad(IAbstractedPad** data, u32 mcu_index) { |
|||
if (mcu_holder[mcu_index].state == NpadMcuState::None || |
|||
mcu_holder[mcu_index].abstracted_pad == nullptr) { |
|||
return ResultMcuIsNotReady; |
|||
} |
|||
*data = mcu_holder[mcu_index].abstracted_pad; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
NpadMcuState NpadAbstractMcuHandler::GetMcuState(u32 mcu_index) { |
|||
return mcu_holder[mcu_index].state; |
|||
} |
|||
|
|||
Result NpadAbstractMcuHandler::SetMcuState(bool is_enabled, u32 mcu_index) { |
|||
NpadMcuState& state = mcu_holder[mcu_index].state; |
|||
|
|||
if (state == NpadMcuState::None) { |
|||
return ResultMcuIsNotReady; |
|||
} |
|||
|
|||
if ((is_enabled) && (state == NpadMcuState::Available)) { |
|||
state = NpadMcuState::Active; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
if (is_enabled) { |
|||
return ResultSuccess; |
|||
} |
|||
if (state != NpadMcuState::Active) { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
state = NpadMcuState::Available; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,52 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
|
|||
namespace Service::HID { |
|||
struct IAbstractedPad; |
|||
class NpadAbstractedPadHolder; |
|||
class NpadAbstractPropertiesHandler; |
|||
|
|||
enum class NpadMcuState : u32 { |
|||
None, |
|||
Available, |
|||
Active, |
|||
}; |
|||
|
|||
struct NpadMcuHolder { |
|||
NpadMcuState state; |
|||
INSERT_PADDING_BYTES(0x4); |
|||
IAbstractedPad* abstracted_pad; |
|||
}; |
|||
static_assert(sizeof(NpadMcuHolder) == 0x10, "NpadMcuHolder is an invalid size"); |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NpadAbstractMcuHandler final { |
|||
public: |
|||
explicit NpadAbstractMcuHandler(); |
|||
~NpadAbstractMcuHandler(); |
|||
|
|||
void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); |
|||
void SetPropertiesHandler(NpadAbstractPropertiesHandler* handler); |
|||
|
|||
Result IncrementRefCounter(); |
|||
Result DecrementRefCounter(); |
|||
|
|||
void UpdateMcuState(); |
|||
Result GetAbstractedPad(IAbstractedPad** data, u32 mcu_index); |
|||
NpadMcuState GetMcuState(u32 mcu_index); |
|||
Result SetMcuState(bool is_enabled, u32 mcu_index); |
|||
|
|||
private: |
|||
NpadAbstractedPadHolder* abstract_pad_holder{nullptr}; |
|||
NpadAbstractPropertiesHandler* properties_handler{nullptr}; |
|||
|
|||
s32 ref_counter{}; |
|||
std::array<NpadMcuHolder, 2> mcu_holder{}; |
|||
}; |
|||
} // namespace Service::HID |
|||
@ -0,0 +1,140 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "core/hle/kernel/k_event.h"
|
|||
#include "core/hle/kernel/k_readable_event.h"
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/resources/abstracted_pad/abstract_nfc_handler.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/npad/npad_types.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadAbstractNfcHandler::NpadAbstractNfcHandler() {} |
|||
|
|||
NpadAbstractNfcHandler::~NpadAbstractNfcHandler() = default; |
|||
|
|||
void NpadAbstractNfcHandler::SetAbstractPadHolder(NpadAbstractedPadHolder* holder) { |
|||
abstract_pad_holder = holder; |
|||
} |
|||
|
|||
void NpadAbstractNfcHandler::SetPropertiesHandler(NpadAbstractPropertiesHandler* handler) { |
|||
properties_handler = handler; |
|||
} |
|||
|
|||
Result NpadAbstractNfcHandler::IncrementRefCounter() { |
|||
if (ref_counter == std::numeric_limits<s32>::max() - 1) { |
|||
return ResultNpadHandlerOverflow; |
|||
} |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractNfcHandler::DecrementRefCounter() { |
|||
if (ref_counter == 0) { |
|||
return ResultNpadHandlerNotInitialized; |
|||
} |
|||
ref_counter--; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void NpadAbstractNfcHandler::UpdateNfcState() { |
|||
std::array<IAbstractedPad*, 5> abstract_pads{}; |
|||
const std::size_t count = properties_handler->GetAbstractedPads(abstract_pads); |
|||
|
|||
if (count == 0) { |
|||
if (sensor_state == NpadNfcState::Active) { |
|||
nfc_activate_event->Signal(); |
|||
} |
|||
if (sensor_state == NpadNfcState::Unavailable) { |
|||
return; |
|||
} |
|||
sensor_state = NpadNfcState::Unavailable; |
|||
input_event->Signal(); |
|||
return; |
|||
} |
|||
|
|||
bool is_found{}; |
|||
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_nfc) { |
|||
continue; |
|||
} |
|||
is_found = true; |
|||
xcd_handle = 0; |
|||
} |
|||
|
|||
if (is_found) { |
|||
if (sensor_state == NpadNfcState::Active) { |
|||
return; |
|||
} |
|||
if (sensor_state == NpadNfcState::Available) { |
|||
return; |
|||
} |
|||
sensor_state = NpadNfcState::Available; |
|||
input_event->Signal(); |
|||
return; |
|||
} |
|||
|
|||
if (sensor_state == NpadNfcState::Active) { |
|||
nfc_activate_event->Signal(); |
|||
} |
|||
if (sensor_state == NpadNfcState::Unavailable) { |
|||
return; |
|||
} |
|||
sensor_state = NpadNfcState::Unavailable; |
|||
input_event->Signal(); |
|||
return; |
|||
} |
|||
|
|||
bool NpadAbstractNfcHandler::HasNfcSensor() { |
|||
return sensor_state != NpadNfcState::Unavailable; |
|||
} |
|||
|
|||
bool NpadAbstractNfcHandler::IsNfcActivated() { |
|||
return sensor_state == NpadNfcState::Active; |
|||
} |
|||
|
|||
Result NpadAbstractNfcHandler::GetAcquireNfcActivateEventHandle( |
|||
Kernel::KReadableEvent** out_event) { |
|||
*out_event = &nfc_activate_event->GetReadableEvent(); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void NpadAbstractNfcHandler::SetInputEvent(Kernel::KEvent* event) { |
|||
input_event = event; |
|||
} |
|||
|
|||
Result NpadAbstractNfcHandler::ActivateNfc(bool is_enabled) { |
|||
if (sensor_state == NpadNfcState::Active) { |
|||
return ResultNfcIsNotReady; |
|||
} |
|||
|
|||
NpadNfcState new_state = NpadNfcState::Available; |
|||
if (is_enabled) { |
|||
new_state = NpadNfcState::Active; |
|||
} |
|||
if (sensor_state != new_state) { |
|||
sensor_state = new_state; |
|||
nfc_activate_event->Signal(); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractNfcHandler::GetXcdHandleWithNfc(u64& out_xcd_handle) const { |
|||
if (sensor_state == NpadNfcState::Unavailable) { |
|||
return ResultNfcIsNotReady; |
|||
} |
|||
if (xcd_handle == 0) { |
|||
return ResultNfcXcdHandleIsNotInitialized; |
|||
} |
|||
|
|||
out_xcd_handle = xcd_handle; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,57 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
|
|||
namespace Kernel { |
|||
class KReadableEvent; |
|||
} |
|||
|
|||
enum class NpadNfcState : u32 { |
|||
Unavailable, |
|||
Available, |
|||
Active, |
|||
}; |
|||
|
|||
namespace Service::HID { |
|||
class NpadAbstractedPadHolder; |
|||
class NpadAbstractPropertiesHandler; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NpadAbstractNfcHandler final { |
|||
public: |
|||
explicit NpadAbstractNfcHandler(); |
|||
~NpadAbstractNfcHandler(); |
|||
|
|||
void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); |
|||
void SetPropertiesHandler(NpadAbstractPropertiesHandler* handler); |
|||
|
|||
Result IncrementRefCounter(); |
|||
Result DecrementRefCounter(); |
|||
|
|||
void UpdateNfcState(); |
|||
bool HasNfcSensor(); |
|||
bool IsNfcActivated(); |
|||
|
|||
Result GetAcquireNfcActivateEventHandle(Kernel::KReadableEvent** out_event); |
|||
void SetInputEvent(Kernel::KEvent* event); |
|||
|
|||
Result ActivateNfc(bool is_enabled); |
|||
|
|||
Result GetXcdHandleWithNfc(u64& out_xcd_handle) const; |
|||
|
|||
private: |
|||
NpadAbstractedPadHolder* abstract_pad_holder{nullptr}; |
|||
NpadAbstractPropertiesHandler* properties_handler{nullptr}; |
|||
|
|||
s32 ref_counter{}; |
|||
Kernel::KEvent* nfc_activate_event{nullptr}; |
|||
Kernel::KEvent* input_event{nullptr}; |
|||
u64 xcd_handle{}; |
|||
NpadNfcState sensor_state{NpadNfcState::Unavailable}; |
|||
}; |
|||
} // namespace Service::HID |
|||
@ -0,0 +1,294 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/resources/abstracted_pad/abstract_pad.h"
|
|||
#include "hid_core/resources/applet_resource.h"
|
|||
#include "hid_core/resources/npad/npad_types.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
AbstractPad::AbstractPad() {} |
|||
|
|||
AbstractPad::~AbstractPad() = default; |
|||
|
|||
void AbstractPad::SetExternals(AppletResourceHolder* applet_resource, |
|||
CaptureButtonResource* capture_button_resource, |
|||
HomeButtonResource* home_button_resource, |
|||
SixAxisResource* sixaxis_resource, PalmaResource* palma_resource, |
|||
VibrationHandler* vibration) { |
|||
applet_resource_holder = applet_resource; |
|||
|
|||
properties_handler.SetAppletResource(applet_resource_holder); |
|||
properties_handler.SetAbstractPadHolder(&abstract_pad_holder); |
|||
|
|||
led_handler.SetAppletResource(applet_resource_holder); |
|||
led_handler.SetAbstractPadHolder(&abstract_pad_holder); |
|||
led_handler.SetPropertiesHandler(&properties_handler); |
|||
|
|||
ir_sensor_handler.SetAbstractPadHolder(&abstract_pad_holder); |
|||
ir_sensor_handler.SetPropertiesHandler(&properties_handler); |
|||
|
|||
nfc_handler.SetAbstractPadHolder(&abstract_pad_holder); |
|||
nfc_handler.SetPropertiesHandler(&properties_handler); |
|||
|
|||
mcu_handler.SetAbstractPadHolder(&abstract_pad_holder); |
|||
mcu_handler.SetPropertiesHandler(&properties_handler); |
|||
|
|||
std::array<NpadVibrationDevice*, 2> vibration_devices{&vibration_left, &vibration_right}; |
|||
vibration_handler.SetAppletResource(applet_resource_holder); |
|||
vibration_handler.SetAbstractPadHolder(&abstract_pad_holder); |
|||
vibration_handler.SetPropertiesHandler(&properties_handler); |
|||
vibration_handler.SetN64Vibration(&vibration_n64); |
|||
vibration_handler.SetVibration(vibration_devices); |
|||
vibration_handler.SetGcVibration(&vibration_gc); |
|||
|
|||
sixaxis_handler.SetAppletResource(applet_resource_holder); |
|||
sixaxis_handler.SetAbstractPadHolder(&abstract_pad_holder); |
|||
sixaxis_handler.SetPropertiesHandler(&properties_handler); |
|||
sixaxis_handler.SetSixaxisResource(sixaxis_resource); |
|||
|
|||
button_handler.SetAppletResource(applet_resource_holder); |
|||
button_handler.SetAbstractPadHolder(&abstract_pad_holder); |
|||
button_handler.SetPropertiesHandler(&properties_handler); |
|||
|
|||
battery_handler.SetAppletResource(applet_resource_holder); |
|||
battery_handler.SetAbstractPadHolder(&abstract_pad_holder); |
|||
battery_handler.SetPropertiesHandler(&properties_handler); |
|||
|
|||
palma_handler.SetAbstractPadHolder(&abstract_pad_holder); |
|||
palma_handler.SetPropertiesHandler(&properties_handler); |
|||
palma_handler.SetPalmaResource(palma_resource); |
|||
} |
|||
|
|||
void AbstractPad::SetNpadId(Core::HID::NpadIdType npad_id) { |
|||
properties_handler.SetNpadId(npad_id); |
|||
} |
|||
|
|||
Result AbstractPad::Activate() { |
|||
if (ref_counter == std::numeric_limits<s32>::max() - 1) { |
|||
return ResultNpadHandlerOverflow; |
|||
} |
|||
|
|||
if (ref_counter != 0) { |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
std::size_t stage = 0; |
|||
Result result = ResultSuccess; |
|||
|
|||
if (result.IsSuccess()) { |
|||
stage++; |
|||
result = properties_handler.IncrementRefCounter(); |
|||
} |
|||
if (result.IsSuccess()) { |
|||
stage++; |
|||
result = led_handler.IncrementRefCounter(); |
|||
} |
|||
if (result.IsSuccess()) { |
|||
stage++; |
|||
result = ir_sensor_handler.IncrementRefCounter(); |
|||
} |
|||
if (result.IsSuccess()) { |
|||
stage++; |
|||
result = mcu_handler.IncrementRefCounter(); |
|||
} |
|||
if (result.IsSuccess()) { |
|||
stage++; |
|||
result = nfc_handler.IncrementRefCounter(); |
|||
} |
|||
if (result.IsSuccess()) { |
|||
stage++; |
|||
result = vibration_handler.IncrementRefCounter(); |
|||
} |
|||
if (result.IsSuccess()) { |
|||
stage++; |
|||
result = sixaxis_handler.IncrementRefCounter(); |
|||
} |
|||
if (result.IsSuccess()) { |
|||
stage++; |
|||
result = button_handler.IncrementRefCounter(); |
|||
} |
|||
if (result.IsSuccess()) { |
|||
stage++; |
|||
result = battery_handler.IncrementRefCounter(); |
|||
} |
|||
if (result.IsSuccess()) { |
|||
stage++; |
|||
result = palma_handler.IncrementRefCounter(); |
|||
} |
|||
|
|||
if (result.IsSuccess()) { |
|||
ref_counter++; |
|||
return result; |
|||
} |
|||
|
|||
if (stage > 9) { |
|||
battery_handler.DecrementRefCounter(); |
|||
} |
|||
if (stage > 8) { |
|||
button_handler.DecrementRefCounter(); |
|||
} |
|||
if (stage > 7) { |
|||
sixaxis_handler.DecrementRefCounter(); |
|||
} |
|||
if (stage > 6) { |
|||
vibration_handler.DecrementRefCounter(); |
|||
} |
|||
if (stage > 5) { |
|||
nfc_handler.DecrementRefCounter(); |
|||
} |
|||
if (stage > 4) { |
|||
mcu_handler.DecrementRefCounter(); |
|||
} |
|||
if (stage > 3) { |
|||
ir_sensor_handler.DecrementRefCounter(); |
|||
} |
|||
if (stage > 2) { |
|||
led_handler.DecrementRefCounter(); |
|||
} |
|||
if (stage > 1) { |
|||
properties_handler.DecrementRefCounter(); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
Result AbstractPad::Deactivate() { |
|||
if (ref_counter == 0) { |
|||
return ResultNpadResourceNotInitialized; |
|||
} |
|||
|
|||
ref_counter--; |
|||
battery_handler.DecrementRefCounter(); |
|||
button_handler.DecrementRefCounter(); |
|||
sixaxis_handler.DecrementRefCounter(); |
|||
vibration_handler.DecrementRefCounter(); |
|||
nfc_handler.DecrementRefCounter(); |
|||
ir_sensor_handler.DecrementRefCounter(); |
|||
mcu_handler.DecrementRefCounter(); |
|||
led_handler.DecrementRefCounter(); |
|||
properties_handler.DecrementRefCounter(); |
|||
palma_handler.DecrementRefCounter(); |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result AbstractPad::ActivateNpad(u64 aruid) { |
|||
Result result = ResultSuccess; |
|||
if (result.IsSuccess()) { |
|||
result = properties_handler.ActivateNpadUnknown0x88(aruid); |
|||
} |
|||
if (result.IsSuccess()) { |
|||
result = sixaxis_handler.UpdateSixAxisState2(aruid); |
|||
} |
|||
if (result.IsSuccess()) { |
|||
result = battery_handler.UpdateBatteryState(aruid); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
NpadAbstractedPadHolder* AbstractPad::GetAbstractedPadHolder() { |
|||
return &abstract_pad_holder; |
|||
} |
|||
|
|||
NpadAbstractPropertiesHandler* AbstractPad::GetAbstractPropertiesHandler() { |
|||
return &properties_handler; |
|||
} |
|||
|
|||
NpadAbstractLedHandler* AbstractPad::GetAbstractLedHandler() { |
|||
return &led_handler; |
|||
} |
|||
|
|||
NpadAbstractIrSensorHandler* AbstractPad::GetAbstractIrSensorHandler() { |
|||
return &ir_sensor_handler; |
|||
} |
|||
|
|||
NpadAbstractMcuHandler* AbstractPad::GetAbstractMcuHandler() { |
|||
return &mcu_handler; |
|||
} |
|||
|
|||
NpadAbstractNfcHandler* AbstractPad::GetAbstractNfcHandler() { |
|||
return &nfc_handler; |
|||
} |
|||
|
|||
NpadAbstractVibrationHandler* AbstractPad::GetAbstractVibrationHandler() { |
|||
return &vibration_handler; |
|||
} |
|||
|
|||
NpadAbstractSixAxisHandler* AbstractPad::GetAbstractSixAxisHandler() { |
|||
return &sixaxis_handler; |
|||
} |
|||
|
|||
NpadAbstractButtonHandler* AbstractPad::GetAbstractButtonHandler() { |
|||
return &button_handler; |
|||
} |
|||
|
|||
NpadAbstractBatteryHandler* AbstractPad::GetAbstractBatteryHandler() { |
|||
return &battery_handler; |
|||
} |
|||
|
|||
NpadN64VibrationDevice* AbstractPad::GetN64VibrationDevice() { |
|||
return &vibration_n64; |
|||
} |
|||
|
|||
NpadVibrationDevice* AbstractPad::GetVibrationDevice(Core::HID::DeviceIndex device_index) { |
|||
if (device_index == Core::HID::DeviceIndex::Right) { |
|||
return &vibration_right; |
|||
} |
|||
return &vibration_left; |
|||
} |
|||
|
|||
void AbstractPad::GetLeftRightVibrationDevice(std::vector<NpadVibrationDevice*> list) { |
|||
list.emplace_back(&vibration_left); |
|||
list.emplace_back(&vibration_right); |
|||
} |
|||
|
|||
NpadGcVibrationDevice* AbstractPad::GetGCVibrationDevice() { |
|||
return &vibration_gc; |
|||
} |
|||
|
|||
Core::HID::NpadIdType AbstractPad::GetLastActiveNpad() { |
|||
return properties_handler.GetNpadId(); |
|||
} |
|||
|
|||
void AbstractPad::UpdateInterfaceType() { |
|||
if (interface_type != properties_handler.GetInterfaceType()) { |
|||
Update(); |
|||
} |
|||
battery_handler.UpdateBatteryState(); |
|||
} |
|||
|
|||
void AbstractPad::Update() { |
|||
properties_handler.UpdateDeviceType(); |
|||
led_handler.SetNpadLedHandlerLedPattern(); |
|||
vibration_handler.UpdateVibrationState(); |
|||
sixaxis_handler.UpdateSixAxisState(); |
|||
nfc_handler.UpdateNfcState(); |
|||
ir_sensor_handler.UpdateIrSensorState(); |
|||
mcu_handler.UpdateMcuState(); |
|||
palma_handler.UpdatePalmaState(); |
|||
battery_handler.UpdateBatteryState(); |
|||
button_handler.EnableCenterClamp(); |
|||
|
|||
interface_type = properties_handler.GetInterfaceType(); |
|||
|
|||
std::scoped_lock lock{*applet_resource_holder->shared_mutex}; |
|||
properties_handler.UpdateAllDeviceProperties(); |
|||
battery_handler.UpdateCoreBatteryState(); |
|||
button_handler.UpdateCoreBatteryState(); |
|||
} |
|||
|
|||
void AbstractPad::UpdatePadState() { |
|||
button_handler.UpdateAllButtonLifo(); |
|||
sixaxis_handler.UpdateSixAxisState(); |
|||
battery_handler.UpdateCoreBatteryState(); |
|||
} |
|||
|
|||
void AbstractPad::EnableAppletToGetInput(u64 aruid) { |
|||
button_handler.UpdateButtonState(aruid); |
|||
sixaxis_handler.UpdateSixAxisState(aruid); |
|||
battery_handler.UpdateBatteryState(aruid); |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,123 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <mutex> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
#include "hid_core/resources/applet_resource.h" |
|||
#include "hid_core/resources/npad/npad_types.h" |
|||
|
|||
#include "hid_core/resources/abstracted_pad/abstract_battery_handler.h" |
|||
#include "hid_core/resources/abstracted_pad/abstract_button_handler.h" |
|||
#include "hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h" |
|||
#include "hid_core/resources/abstracted_pad/abstract_led_handler.h" |
|||
#include "hid_core/resources/abstracted_pad/abstract_mcu_handler.h" |
|||
#include "hid_core/resources/abstracted_pad/abstract_nfc_handler.h" |
|||
#include "hid_core/resources/abstracted_pad/abstract_pad_holder.h" |
|||
#include "hid_core/resources/abstracted_pad/abstract_palma_handler.h" |
|||
#include "hid_core/resources/abstracted_pad/abstract_properties_handler.h" |
|||
#include "hid_core/resources/abstracted_pad/abstract_sixaxis_handler.h" |
|||
#include "hid_core/resources/abstracted_pad/abstract_vibration_handler.h" |
|||
#include "hid_core/resources/vibration/gc_vibration_device.h" |
|||
#include "hid_core/resources/vibration/n64_vibration_device.h" |
|||
#include "hid_core/resources/vibration/vibration_device.h" |
|||
|
|||
namespace Service::HID { |
|||
class AppletResource; |
|||
class SixAxisResource; |
|||
class PalmaResource; |
|||
class NPadResource; |
|||
class AbstractPad; |
|||
class NpadLastActiveHandler; |
|||
class NpadIrNfcHandler; |
|||
class UniquePads; |
|||
class NpadPalmaHandler; |
|||
class FirmwareResource; |
|||
class NpadVibration; |
|||
class NpadHighestBattery; |
|||
class NpadGcVibration; |
|||
|
|||
class CaptureButtonResource; |
|||
class HomeButtonResource; |
|||
class VibrationHandler; |
|||
|
|||
struct HandheldConfig; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class AbstractPad final { |
|||
public: |
|||
explicit AbstractPad(); |
|||
~AbstractPad(); |
|||
|
|||
void SetExternals(AppletResourceHolder* applet_resource, |
|||
CaptureButtonResource* capture_button_resource, |
|||
HomeButtonResource* home_button_resource, SixAxisResource* sixaxis_resource, |
|||
PalmaResource* palma_resource, VibrationHandler* vibration); |
|||
void SetNpadId(Core::HID::NpadIdType npad_id); |
|||
|
|||
Result Activate(); |
|||
Result Deactivate(); |
|||
|
|||
Result ActivateNpad(u64 aruid); |
|||
|
|||
NpadAbstractedPadHolder* GetAbstractedPadHolder(); |
|||
NpadAbstractPropertiesHandler* GetAbstractPropertiesHandler(); |
|||
NpadAbstractLedHandler* GetAbstractLedHandler(); |
|||
NpadAbstractIrSensorHandler* GetAbstractIrSensorHandler(); |
|||
NpadAbstractMcuHandler* GetAbstractMcuHandler(); |
|||
NpadAbstractNfcHandler* GetAbstractNfcHandler(); |
|||
NpadAbstractVibrationHandler* GetAbstractVibrationHandler(); |
|||
NpadAbstractSixAxisHandler* GetAbstractSixAxisHandler(); |
|||
NpadAbstractButtonHandler* GetAbstractButtonHandler(); |
|||
NpadAbstractBatteryHandler* GetAbstractBatteryHandler(); |
|||
|
|||
NpadN64VibrationDevice* GetN64VibrationDevice(); |
|||
NpadVibrationDevice* GetVibrationDevice(Core::HID::DeviceIndex device_index); |
|||
void GetLeftRightVibrationDevice(std::vector<NpadVibrationDevice*> list); |
|||
NpadGcVibrationDevice* GetGCVibrationDevice(); |
|||
|
|||
Core::HID::NpadIdType GetLastActiveNpad(); |
|||
void UpdateInterfaceType(); |
|||
void Update(); |
|||
|
|||
void UpdatePadState(); |
|||
void EnableAppletToGetInput(u64 aruid); |
|||
|
|||
private: |
|||
AppletResourceHolder* applet_resource_holder{nullptr}; |
|||
NpadAbstractedPadHolder abstract_pad_holder{}; |
|||
NpadAbstractPropertiesHandler properties_handler{}; |
|||
NpadAbstractLedHandler led_handler{}; |
|||
NpadAbstractIrSensorHandler ir_sensor_handler{}; |
|||
NpadAbstractNfcHandler nfc_handler{}; |
|||
NpadAbstractMcuHandler mcu_handler{}; |
|||
NpadAbstractVibrationHandler vibration_handler{}; |
|||
NpadAbstractSixAxisHandler sixaxis_handler{}; |
|||
NpadAbstractButtonHandler button_handler{}; |
|||
NpadAbstractBatteryHandler battery_handler{}; |
|||
NpadAbstractPalmaHandler palma_handler{}; |
|||
|
|||
NpadN64VibrationDevice vibration_n64{}; |
|||
NpadVibrationDevice vibration_left{}; |
|||
NpadVibrationDevice vibration_right{}; |
|||
NpadGcVibrationDevice vibration_gc{}; |
|||
|
|||
// SixAxisConfigHolder fullkey_config; |
|||
// SixAxisConfigHolder handheld_config; |
|||
// SixAxisConfigHolder dual_left_config; |
|||
// SixAxisConfigHolder dual_right_config; |
|||
// SixAxisConfigHolder left_config; |
|||
// SixAxisConfigHolder right_config; |
|||
|
|||
s32 ref_counter{}; |
|||
Core::HID::NpadInterfaceType interface_type{Core::HID::NpadInterfaceType::None}; |
|||
}; |
|||
|
|||
using FullAbstractPad = std::array<AbstractPad, MaxSupportedNpadIdTypes>; |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,99 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/resources/abstracted_pad/abstract_pad_holder.h"
|
|||
#include "hid_core/resources/npad/npad_types.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
Result NpadAbstractedPadHolder::RegisterAbstractPad(IAbstractedPad* abstracted_pad) { |
|||
if (list_size >= assignment_list.size()) { |
|||
return ResultNpadIsNotProController; |
|||
} |
|||
|
|||
for (std::size_t i = 0; i < list_size; i++) { |
|||
if (assignment_list[i].device_type == abstracted_pad->device_type) { |
|||
return ResultNpadIsNotProController; |
|||
} |
|||
} |
|||
|
|||
assignment_list[list_size] = { |
|||
.abstracted_pad = abstracted_pad, |
|||
.device_type = abstracted_pad->device_type, |
|||
.interface_type = abstracted_pad->interface_type, |
|||
.controller_id = abstracted_pad->controller_id, |
|||
}; |
|||
|
|||
list_size++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void NpadAbstractedPadHolder::RemoveAbstractPadByControllerId(u64 controller_id) { |
|||
if (list_size == 0) { |
|||
return; |
|||
} |
|||
if (controller_id == 0) { |
|||
return; |
|||
} |
|||
for (std::size_t i = 0; i < list_size; i++) { |
|||
if (assignment_list[i].controller_id != controller_id) { |
|||
continue; |
|||
} |
|||
for (std::size_t e = i + 1; e < list_size; e++) { |
|||
assignment_list[e - 1] = assignment_list[e]; |
|||
} |
|||
list_size--; |
|||
return; |
|||
} |
|||
} |
|||
|
|||
void NpadAbstractedPadHolder::DetachAbstractedPad() { |
|||
while (list_size > 0) { |
|||
for (std::size_t i = 1; i < list_size; i++) { |
|||
assignment_list[i - 1] = assignment_list[i]; |
|||
} |
|||
list_size--; |
|||
} |
|||
} |
|||
|
|||
u64 NpadAbstractedPadHolder::RemoveAbstractPadByAssignmentStyle( |
|||
Service::HID::AssignmentStyle assignment_style) { |
|||
for (std::size_t i = 0; i < list_size; i++) { |
|||
if ((assignment_style.raw & assignment_list[i].abstracted_pad->assignment_style.raw) == 0) { |
|||
continue; |
|||
} |
|||
for (std::size_t e = i + 1; e < list_size; e++) { |
|||
assignment_list[e - 1] = assignment_list[e]; |
|||
} |
|||
list_size--; |
|||
return list_size; |
|||
} |
|||
return list_size; |
|||
} |
|||
|
|||
u32 NpadAbstractedPadHolder::GetAbstractedPads(std::span<IAbstractedPad*> list) const { |
|||
u32 num_elements = std::min(static_cast<u32>(list.size()), list_size); |
|||
for (std::size_t i = 0; i < num_elements; i++) { |
|||
list[i] = assignment_list[i].abstracted_pad; |
|||
} |
|||
return num_elements; |
|||
} |
|||
|
|||
void NpadAbstractedPadHolder::SetAssignmentMode(const NpadJoyAssignmentMode& mode) { |
|||
assignment_mode = mode; |
|||
} |
|||
|
|||
NpadJoyAssignmentMode NpadAbstractedPadHolder::GetAssignmentMode() const { |
|||
return assignment_mode; |
|||
} |
|||
|
|||
std::size_t NpadAbstractedPadHolder::GetStyleIndexList( |
|||
std::span<Core::HID::NpadStyleIndex> list) const { |
|||
for (std::size_t i = 0; i < list_size; i++) { |
|||
list[i] = assignment_list[i].device_type; |
|||
} |
|||
return list_size; |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,47 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <mutex> |
|||
#include <span> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
#include "hid_core/resources/npad/npad_types.h" |
|||
|
|||
namespace Service::HID { |
|||
struct IAbstractedPad; |
|||
|
|||
struct AbstractAssignmentHolder { |
|||
IAbstractedPad* abstracted_pad; |
|||
Core::HID::NpadStyleIndex device_type; |
|||
Core::HID::NpadInterfaceType interface_type; |
|||
INSERT_PADDING_BYTES(0x6); |
|||
u64 controller_id; |
|||
}; |
|||
static_assert(sizeof(AbstractAssignmentHolder) == 0x18, |
|||
"AbstractAssignmentHolder is an invalid size"); |
|||
|
|||
/// This is nn::hid::server::NpadAbstractedPadHolder |
|||
class NpadAbstractedPadHolder final { |
|||
public: |
|||
Result RegisterAbstractPad(IAbstractedPad* abstracted_pad); |
|||
void RemoveAbstractPadByControllerId(u64 controller_id); |
|||
void DetachAbstractedPad(); |
|||
u64 RemoveAbstractPadByAssignmentStyle(Service::HID::AssignmentStyle assignment_style); |
|||
u32 GetAbstractedPads(std::span<IAbstractedPad*> list) const; |
|||
|
|||
void SetAssignmentMode(const NpadJoyAssignmentMode& mode); |
|||
NpadJoyAssignmentMode GetAssignmentMode() const; |
|||
|
|||
std::size_t GetStyleIndexList(std::span<Core::HID::NpadStyleIndex> list) const; |
|||
|
|||
private: |
|||
std::array<AbstractAssignmentHolder, 5> assignment_list{}; |
|||
u32 list_size{}; |
|||
NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual}; |
|||
}; |
|||
} // namespace Service::HID |
|||
@ -0,0 +1,47 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/resources/abstracted_pad/abstract_palma_handler.h"
|
|||
#include "hid_core/resources/abstracted_pad/abstract_properties_handler.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadAbstractPalmaHandler::NpadAbstractPalmaHandler() {} |
|||
|
|||
NpadAbstractPalmaHandler::~NpadAbstractPalmaHandler() = default; |
|||
|
|||
void NpadAbstractPalmaHandler::SetAbstractPadHolder(NpadAbstractedPadHolder* holder) { |
|||
abstract_pad_holder = holder; |
|||
} |
|||
|
|||
void NpadAbstractPalmaHandler::SetPropertiesHandler(NpadAbstractPropertiesHandler* handler) { |
|||
properties_handler = handler; |
|||
return; |
|||
} |
|||
|
|||
void NpadAbstractPalmaHandler::SetPalmaResource(PalmaResource* resource) { |
|||
palma_resource = resource; |
|||
} |
|||
|
|||
Result NpadAbstractPalmaHandler::IncrementRefCounter() { |
|||
if (ref_counter == std::numeric_limits<s32>::max() - 1) { |
|||
return ResultNpadHandlerOverflow; |
|||
} |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractPalmaHandler::DecrementRefCounter() { |
|||
if (ref_counter == 0) { |
|||
return ResultNpadHandlerNotInitialized; |
|||
} |
|||
ref_counter--; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void NpadAbstractPalmaHandler::UpdatePalmaState() { |
|||
// TODO
|
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,37 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
|
|||
namespace Service::HID { |
|||
class NpadAbstractedPadHolder; |
|||
class NpadAbstractPropertiesHandler; |
|||
class PalmaResource; |
|||
|
|||
class NpadAbstractPalmaHandler final { |
|||
public: |
|||
explicit NpadAbstractPalmaHandler(); |
|||
~NpadAbstractPalmaHandler(); |
|||
|
|||
void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); |
|||
void SetPropertiesHandler(NpadAbstractPropertiesHandler* handler); |
|||
void SetPalmaResource(PalmaResource* resource); |
|||
|
|||
Result IncrementRefCounter(); |
|||
Result DecrementRefCounter(); |
|||
|
|||
void UpdatePalmaState(); |
|||
|
|||
private: |
|||
NpadAbstractedPadHolder* abstract_pad_holder{nullptr}; |
|||
NpadAbstractPropertiesHandler* properties_handler{nullptr}; |
|||
PalmaResource* palma_resource{nullptr}; |
|||
|
|||
s32 ref_counter{}; |
|||
}; |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,322 @@ |
|||
// 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->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
|
|||
@ -0,0 +1,86 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <span> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
#include "hid_core/resources/npad/npad_types.h" |
|||
|
|||
namespace Service::HID { |
|||
struct NpadSharedMemoryEntry; |
|||
|
|||
struct AppletResourceHolder; |
|||
class NpadAbstractedPadHolder; |
|||
|
|||
struct ColorProperties { |
|||
ColorAttribute attribute; |
|||
Core::HID::NpadControllerColor color; |
|||
INSERT_PADDING_BYTES(0x4); |
|||
}; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NpadAbstractPropertiesHandler final { |
|||
public: |
|||
explicit NpadAbstractPropertiesHandler(); |
|||
~NpadAbstractPropertiesHandler(); |
|||
|
|||
void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); |
|||
void SetAppletResource(AppletResourceHolder* applet_resource); |
|||
void SetNpadId(Core::HID::NpadIdType npad_id); |
|||
|
|||
Core::HID::NpadIdType GetNpadId() const; |
|||
|
|||
Result IncrementRefCounter(); |
|||
Result DecrementRefCounter(); |
|||
|
|||
Result ActivateNpadUnknown0x88(u64 aruid); |
|||
|
|||
void UpdateDeviceType(); |
|||
void UpdateDeviceColor(); |
|||
void UpdateFooterAttributes(); |
|||
void UpdateAllDeviceProperties(); |
|||
|
|||
Core::HID::NpadInterfaceType GetFullkeyInterfaceType(); |
|||
Core::HID::NpadInterfaceType GetInterfaceType(); |
|||
|
|||
Core::HID::NpadStyleSet GetStyleSet(u64 aruid); |
|||
std::size_t GetAbstractedPadsWithStyleTag(std::span<IAbstractedPad*> list, |
|||
Core::HID::NpadStyleTag style); |
|||
std::size_t GetAbstractedPads(std::span<IAbstractedPad*> list); |
|||
|
|||
AppletFooterUiType GetAppletFooterUiType(); |
|||
|
|||
AppletDetailedUiType GetAppletDetailedUiType(); |
|||
|
|||
void UpdateDeviceProperties(u64 aruid, NpadSharedMemoryEntry& internal_state); |
|||
|
|||
Core::HID::NpadInterfaceType GetNpadInterfaceType(); |
|||
|
|||
Result GetNpadFullKeyGripColor(Core::HID::NpadColor& main_color, |
|||
Core::HID::NpadColor& sub_color) const; |
|||
|
|||
void GetNpadLeftRightInterfaceType(Core::HID::NpadInterfaceType& param_2, |
|||
Core::HID::NpadInterfaceType& param_3) const; |
|||
|
|||
private: |
|||
AppletResourceHolder* applet_resource_holder{nullptr}; |
|||
NpadAbstractedPadHolder* abstract_pad_holder{nullptr}; |
|||
Core::HID::NpadIdType npad_id_type{Core::HID::NpadIdType::Invalid}; |
|||
s32 ref_counter{}; |
|||
Core::HID::DeviceIndex device_type{}; |
|||
AppletDetailedUiType applet_ui_type{}; |
|||
AppletFooterUiAttributes applet_ui_attributes{}; |
|||
bool is_vertical{}; |
|||
bool is_horizontal{}; |
|||
bool use_plus{}; |
|||
bool use_minus{}; |
|||
bool has_directional_buttons{}; |
|||
ColorProperties fullkey_color{}; |
|||
ColorProperties left_color{}; |
|||
ColorProperties right_color{}; |
|||
}; |
|||
} // namespace Service::HID |
|||
@ -0,0 +1,154 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "hid_core/hid_result.h"
|
|||
#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/abstracted_pad/abstract_sixaxis_handler.h"
|
|||
#include "hid_core/resources/applet_resource.h"
|
|||
#include "hid_core/resources/npad/npad_types.h"
|
|||
#include "hid_core/resources/shared_memory_format.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadAbstractSixAxisHandler::NpadAbstractSixAxisHandler() {} |
|||
|
|||
NpadAbstractSixAxisHandler::~NpadAbstractSixAxisHandler() = default; |
|||
|
|||
void NpadAbstractSixAxisHandler::SetAbstractPadHolder(NpadAbstractedPadHolder* holder) { |
|||
abstract_pad_holder = holder; |
|||
} |
|||
|
|||
void NpadAbstractSixAxisHandler::SetAppletResource(AppletResourceHolder* applet_resource) { |
|||
applet_resource_holder = applet_resource; |
|||
} |
|||
|
|||
void NpadAbstractSixAxisHandler::SetPropertiesHandler(NpadAbstractPropertiesHandler* handler) { |
|||
properties_handler = handler; |
|||
} |
|||
|
|||
void NpadAbstractSixAxisHandler::SetSixaxisResource(SixAxisResource* resource) { |
|||
six_axis_resource = resource; |
|||
} |
|||
|
|||
Result NpadAbstractSixAxisHandler::IncrementRefCounter() { |
|||
if (ref_counter == std::numeric_limits<s32>::max() - 1) { |
|||
return ResultNpadHandlerOverflow; |
|||
} |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractSixAxisHandler::DecrementRefCounter() { |
|||
if (ref_counter == 0) { |
|||
return ResultNpadHandlerNotInitialized; |
|||
} |
|||
ref_counter--; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
u64 NpadAbstractSixAxisHandler::IsFirmwareUpdateAvailable() { |
|||
// TODO
|
|||
return false; |
|||
} |
|||
|
|||
Result NpadAbstractSixAxisHandler::UpdateSixAxisState() { |
|||
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId(); |
|||
for (std::size_t i = 0; i < AruidIndexMax; i++) { |
|||
auto* data = applet_resource_holder->applet_resource->GetAruidDataByIndex(i); |
|||
if (data->flag.is_assigned) { |
|||
continue; |
|||
} |
|||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)]; |
|||
UpdateSixaxisInternalState(npad_entry, data->aruid, |
|||
data->flag.enable_six_axis_sensor.As<bool>()); |
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractSixAxisHandler::UpdateSixAxisState(u64 aruid) { |
|||
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId(); |
|||
auto* data = applet_resource_holder->applet_resource->GetAruidData(aruid); |
|||
if (data == nullptr) { |
|||
return ResultSuccess; |
|||
} |
|||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)]; |
|||
UpdateSixaxisInternalState(npad_entry, data->aruid, |
|||
data->flag.enable_six_axis_sensor.As<bool>()); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractSixAxisHandler::UpdateSixAxisState2(u64 aruid) { |
|||
const auto npad_index = NpadIdTypeToIndex(properties_handler->GetNpadId()); |
|||
AruidData* aruid_data = applet_resource_holder->applet_resource->GetAruidData(aruid); |
|||
if (aruid_data == nullptr) { |
|||
return ResultSuccess; |
|||
} |
|||
auto& npad_internal_state = aruid_data->shared_memory_format->npad.npad_entry[npad_index]; |
|||
UpdateSixaxisInternalState(npad_internal_state, aruid, |
|||
aruid_data->flag.enable_six_axis_sensor.As<bool>()); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void NpadAbstractSixAxisHandler::UpdateSixaxisInternalState(NpadSharedMemoryEntry& npad_entry, |
|||
u64 aruid, bool is_sensor_enabled) { |
|||
const Core::HID::NpadStyleTag style_tag{properties_handler->GetStyleSet(aruid)}; |
|||
|
|||
if (!style_tag.palma) { |
|||
UpdateSixaxisFullkeyLifo(style_tag, npad_entry.internal_state.sixaxis_fullkey_lifo, |
|||
is_sensor_enabled); |
|||
} else { |
|||
UpdateSixAxisPalmaLifo(style_tag, npad_entry.internal_state.sixaxis_fullkey_lifo, |
|||
is_sensor_enabled); |
|||
} |
|||
UpdateSixaxisHandheldLifo(style_tag, npad_entry.internal_state.sixaxis_handheld_lifo, |
|||
is_sensor_enabled); |
|||
UpdateSixaxisDualLifo(style_tag, npad_entry.internal_state.sixaxis_dual_left_lifo, |
|||
is_sensor_enabled); |
|||
UpdateSixaxisDualLifo(style_tag, npad_entry.internal_state.sixaxis_dual_right_lifo, |
|||
is_sensor_enabled); |
|||
UpdateSixaxisLeftLifo(style_tag, npad_entry.internal_state.sixaxis_left_lifo, |
|||
is_sensor_enabled); |
|||
UpdateSixaxisRightLifo(style_tag, npad_entry.internal_state.sixaxis_right_lifo, |
|||
is_sensor_enabled); |
|||
// TODO: Set sixaxis properties
|
|||
} |
|||
|
|||
void NpadAbstractSixAxisHandler::UpdateSixaxisFullkeyLifo(Core::HID::NpadStyleTag style_tag, |
|||
NpadSixAxisSensorLifo& sensor_lifo, |
|||
bool is_sensor_enabled) { |
|||
// TODO
|
|||
} |
|||
|
|||
void NpadAbstractSixAxisHandler::UpdateSixAxisPalmaLifo(Core::HID::NpadStyleTag style_tag, |
|||
NpadSixAxisSensorLifo& sensor_lifo, |
|||
bool is_sensor_enabled) { |
|||
// TODO
|
|||
} |
|||
|
|||
void NpadAbstractSixAxisHandler::UpdateSixaxisHandheldLifo(Core::HID::NpadStyleTag style_tag, |
|||
NpadSixAxisSensorLifo& sensor_lifo, |
|||
bool is_sensor_enabled) { |
|||
// TODO
|
|||
} |
|||
|
|||
void NpadAbstractSixAxisHandler::UpdateSixaxisDualLifo(Core::HID::NpadStyleTag style_tag, |
|||
NpadSixAxisSensorLifo& sensor_lifo, |
|||
bool is_sensor_enabled) { |
|||
// TODO
|
|||
} |
|||
|
|||
void NpadAbstractSixAxisHandler::UpdateSixaxisLeftLifo(Core::HID::NpadStyleTag style_tag, |
|||
NpadSixAxisSensorLifo& sensor_lifo, |
|||
bool is_sensor_enabled) { |
|||
// TODO
|
|||
} |
|||
|
|||
void NpadAbstractSixAxisHandler::UpdateSixaxisRightLifo(Core::HID::NpadStyleTag style_tag, |
|||
NpadSixAxisSensorLifo& sensor_lifo, |
|||
bool is_sensor_enabled) { |
|||
// TODO
|
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,61 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
|
|||
namespace Service::HID { |
|||
class SixAxisResource; |
|||
struct AppletResourceHolder; |
|||
class NpadAbstractedPadHolder; |
|||
class NpadAbstractPropertiesHandler; |
|||
struct NpadSixAxisSensorLifo; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NpadAbstractSixAxisHandler final { |
|||
public: |
|||
explicit NpadAbstractSixAxisHandler(); |
|||
~NpadAbstractSixAxisHandler(); |
|||
|
|||
void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); |
|||
void SetAppletResource(AppletResourceHolder* applet_resource); |
|||
void SetPropertiesHandler(NpadAbstractPropertiesHandler* handler); |
|||
void SetSixaxisResource(SixAxisResource* resource); |
|||
|
|||
Result IncrementRefCounter(); |
|||
Result DecrementRefCounter(); |
|||
|
|||
u64 IsFirmwareUpdateAvailable(); |
|||
|
|||
Result UpdateSixAxisState(); |
|||
Result UpdateSixAxisState(u64 aruid); |
|||
Result UpdateSixAxisState2(u64 aruid); |
|||
|
|||
private: |
|||
void UpdateSixaxisInternalState(NpadSharedMemoryEntry& npad_entry, u64 aruid, |
|||
bool is_sensor_enabled); |
|||
void UpdateSixaxisFullkeyLifo(Core::HID::NpadStyleTag style_tag, |
|||
NpadSixAxisSensorLifo& sensor_lifo, bool is_sensor_enabled); |
|||
void UpdateSixAxisPalmaLifo(Core::HID::NpadStyleTag style_tag, |
|||
NpadSixAxisSensorLifo& sensor_lifo, bool is_sensor_enabled); |
|||
void UpdateSixaxisHandheldLifo(Core::HID::NpadStyleTag style_tag, |
|||
NpadSixAxisSensorLifo& sensor_lifo, bool is_sensor_enabled); |
|||
void UpdateSixaxisDualLifo(Core::HID::NpadStyleTag style_tag, |
|||
NpadSixAxisSensorLifo& sensor_lifo, bool is_sensor_enabled); |
|||
void UpdateSixaxisLeftLifo(Core::HID::NpadStyleTag style_tag, |
|||
NpadSixAxisSensorLifo& sensor_lifo, bool is_sensor_enabled); |
|||
void UpdateSixaxisRightLifo(Core::HID::NpadStyleTag style_tag, |
|||
NpadSixAxisSensorLifo& sensor_lifo, bool is_sensor_enabled); |
|||
|
|||
AppletResourceHolder* applet_resource_holder{nullptr}; |
|||
NpadAbstractedPadHolder* abstract_pad_holder{nullptr}; |
|||
NpadAbstractPropertiesHandler* properties_handler{nullptr}; |
|||
SixAxisResource* six_axis_resource{nullptr}; |
|||
|
|||
s32 ref_counter{}; |
|||
}; |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,73 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "hid_core/hid_result.h"
|
|||
#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/abstracted_pad/abstract_vibration_handler.h"
|
|||
#include "hid_core/resources/applet_resource.h"
|
|||
#include "hid_core/resources/npad/npad_vibration.h"
|
|||
#include "hid_core/resources/vibration/gc_vibration_device.h"
|
|||
#include "hid_core/resources/vibration/n64_vibration_device.h"
|
|||
#include "hid_core/resources/vibration/vibration_device.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadAbstractVibrationHandler::NpadAbstractVibrationHandler() {} |
|||
|
|||
NpadAbstractVibrationHandler::~NpadAbstractVibrationHandler() = default; |
|||
|
|||
void NpadAbstractVibrationHandler::SetAbstractPadHolder(NpadAbstractedPadHolder* holder) { |
|||
abstract_pad_holder = holder; |
|||
} |
|||
|
|||
void NpadAbstractVibrationHandler::SetAppletResource(AppletResourceHolder* applet_resource) { |
|||
applet_resource_holder = applet_resource; |
|||
} |
|||
|
|||
void NpadAbstractVibrationHandler::SetPropertiesHandler(NpadAbstractPropertiesHandler* handler) { |
|||
properties_handler = handler; |
|||
} |
|||
|
|||
void NpadAbstractVibrationHandler::SetN64Vibration(NpadN64VibrationDevice* n64_device) { |
|||
n64_vibration_device = n64_device; |
|||
} |
|||
|
|||
void NpadAbstractVibrationHandler::SetVibration(std::span<NpadVibrationDevice*> device) { |
|||
for (std::size_t i = 0; i < device.size() && i < vibration_device.size(); i++) { |
|||
vibration_device[i] = device[i]; |
|||
} |
|||
} |
|||
|
|||
void NpadAbstractVibrationHandler::SetGcVibration(NpadGcVibrationDevice* gc_device) { |
|||
gc_vibration_device = gc_device; |
|||
} |
|||
|
|||
Result NpadAbstractVibrationHandler::IncrementRefCounter() { |
|||
if (ref_counter == std::numeric_limits<s32>::max() - 1) { |
|||
return ResultNpadHandlerOverflow; |
|||
} |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadAbstractVibrationHandler::DecrementRefCounter() { |
|||
if (ref_counter == 0) { |
|||
return ResultNpadHandlerNotInitialized; |
|||
} |
|||
ref_counter--; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void NpadAbstractVibrationHandler::UpdateVibrationState() { |
|||
const bool is_handheld_hid_enabled = |
|||
applet_resource_holder->handheld_config->is_handheld_hid_enabled; |
|||
const bool is_force_handheld_style_vibration = |
|||
applet_resource_holder->handheld_config->is_force_handheld_style_vibration; |
|||
|
|||
if (!is_handheld_hid_enabled && is_force_handheld_style_vibration) { |
|||
// TODO
|
|||
} |
|||
} |
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,51 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <span> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
|
|||
namespace Service::HID { |
|||
struct AppletResourceHolder; |
|||
class NpadAbstractedPadHolder; |
|||
class NpadAbstractPropertiesHandler; |
|||
class NpadGcVibrationDevice; |
|||
class NpadVibrationDevice; |
|||
class NpadN64VibrationDevice; |
|||
class NpadVibration; |
|||
|
|||
/// Keeps track of battery levels and updates npad battery shared memory values |
|||
class NpadAbstractVibrationHandler final { |
|||
public: |
|||
explicit NpadAbstractVibrationHandler(); |
|||
~NpadAbstractVibrationHandler(); |
|||
|
|||
void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); |
|||
void SetAppletResource(AppletResourceHolder* applet_resource); |
|||
void SetPropertiesHandler(NpadAbstractPropertiesHandler* handler); |
|||
|
|||
void SetN64Vibration(NpadN64VibrationDevice* n64_device); |
|||
void SetVibration(std::span<NpadVibrationDevice*> device); |
|||
void SetGcVibration(NpadGcVibrationDevice* gc_device); |
|||
|
|||
Result IncrementRefCounter(); |
|||
Result DecrementRefCounter(); |
|||
|
|||
void UpdateVibrationState(); |
|||
|
|||
private: |
|||
AppletResourceHolder* applet_resource_holder{nullptr}; |
|||
NpadAbstractedPadHolder* abstract_pad_holder{nullptr}; |
|||
NpadAbstractPropertiesHandler* properties_handler{nullptr}; |
|||
|
|||
NpadN64VibrationDevice* n64_vibration_device{nullptr}; |
|||
std::array<NpadVibrationDevice*, 2> vibration_device{}; |
|||
NpadGcVibrationDevice* gc_vibration_device{nullptr}; |
|||
NpadVibration* vibration_handler{nullptr}; |
|||
s32 ref_counter{}; |
|||
}; |
|||
} // namespace Service::HID |
|||
@ -0,0 +1,80 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/resources/npad/npad_vibration.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadVibration::NpadVibration() {} |
|||
|
|||
NpadVibration::~NpadVibration() = default; |
|||
|
|||
Result NpadVibration::Activate() { |
|||
std::scoped_lock lock{mutex}; |
|||
|
|||
const f32 master_volume = 1.0f; // nn::settings::system::GetVibrationMasterVolume();
|
|||
// if (master_volume < 0.0f || master_volume > 1.0f) {
|
|||
// return ResultVibrationStrenghtOutOfRange;
|
|||
// }
|
|||
|
|||
volume = master_volume; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadVibration::Deactivate() { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadVibration::SetVibrationMasterVolume(f32 master_volume) { |
|||
std::scoped_lock lock{mutex}; |
|||
|
|||
if (master_volume < 0.0f && master_volume > 1.0f) { |
|||
return ResultVibrationStrenghtOutOfRange; |
|||
} |
|||
|
|||
volume = master_volume; |
|||
// nn::settings::system::SetVibrationMasterVolume(master_volume);
|
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadVibration::GetVibrationVolume(f32& out_volume) const { |
|||
std::scoped_lock lock{mutex}; |
|||
out_volume = volume; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadVibration::GetVibrationMasterVolume(f32& out_volume) const { |
|||
std::scoped_lock lock{mutex}; |
|||
|
|||
const f32 master_volume = 1.0f; // nn::settings::system::GetVibrationMasterVolume();
|
|||
// if (master_volume < 0.0f || master_volume > 1.0f) {
|
|||
// return ResultVibrationStrenghtOutOfRange;
|
|||
// }
|
|||
|
|||
out_volume = master_volume; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadVibration::BeginPermitVibrationSession(u64 aruid) { |
|||
std::scoped_lock lock{mutex}; |
|||
session_aruid = aruid; |
|||
volume = 1.0; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadVibration::EndPermitVibrationSession() { |
|||
std::scoped_lock lock{mutex}; |
|||
|
|||
const f32 master_volume = 1.0f; // nn::settings::system::GetVibrationMasterVolume();
|
|||
// if (master_volume < 0.0f || master_volume > 1.0f) {
|
|||
// return ResultVibrationStrenghtOutOfRange;
|
|||
// }
|
|||
|
|||
volume = master_volume; |
|||
session_aruid = 0; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,34 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <mutex> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
|
|||
namespace Service::HID { |
|||
|
|||
class NpadVibration final { |
|||
public: |
|||
explicit NpadVibration(); |
|||
~NpadVibration(); |
|||
|
|||
Result Activate(); |
|||
Result Deactivate(); |
|||
|
|||
Result SetVibrationMasterVolume(f32 master_volume); |
|||
Result GetVibrationVolume(f32& out_volume) const; |
|||
Result GetVibrationMasterVolume(f32& out_volume) const; |
|||
|
|||
Result BeginPermitVibrationSession(u64 aruid); |
|||
Result EndPermitVibrationSession(); |
|||
|
|||
private: |
|||
f32 volume{}; |
|||
u64 session_aruid{}; |
|||
mutable std::mutex mutex; |
|||
}; |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,106 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/resources/npad/npad_types.h"
|
|||
#include "hid_core/resources/npad/npad_vibration.h"
|
|||
#include "hid_core/resources/vibration/gc_vibration_device.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadGcVibrationDevice::NpadGcVibrationDevice() {} |
|||
|
|||
Result NpadGcVibrationDevice::IncrementRefCounter() { |
|||
if (ref_counter == 0 && is_mounted) { |
|||
f32 volume = 1.0f; |
|||
const auto result = vibration_handler->GetVibrationVolume(volume); |
|||
if (result.IsSuccess()) { |
|||
// TODO: SendVibrationGcErmCommand
|
|||
} |
|||
} |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadGcVibrationDevice::DecrementRefCounter() { |
|||
if (ref_counter == 1 && !is_mounted) { |
|||
f32 volume = 1.0f; |
|||
const auto result = vibration_handler->GetVibrationVolume(volume); |
|||
if (result.IsSuccess()) { |
|||
// TODO: SendVibrationGcErmCommand
|
|||
} |
|||
} |
|||
|
|||
if (ref_counter > 0) { |
|||
ref_counter--; |
|||
} |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadGcVibrationDevice::SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command) { |
|||
if (!is_mounted) { |
|||
return ResultSuccess; |
|||
} |
|||
f32 volume = 1.0f; |
|||
const auto result = vibration_handler->GetVibrationVolume(volume); |
|||
if (result.IsError()) { |
|||
return result; |
|||
} |
|||
if (volume == 0.0) { |
|||
command = Core::HID::VibrationGcErmCommand::Stop; |
|||
} else { |
|||
if (command > Core::HID::VibrationGcErmCommand::StopHard) { |
|||
// Abort
|
|||
return ResultSuccess; |
|||
} |
|||
} |
|||
// TODO: SendVibrationGcErmCommand
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadGcVibrationDevice::GetActualVibrationGcErmCommand( |
|||
Core::HID::VibrationGcErmCommand& out_command) { |
|||
if (!is_mounted) { |
|||
out_command = Core::HID::VibrationGcErmCommand::Stop; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
f32 volume = 1.0f; |
|||
const auto result = vibration_handler->GetVibrationVolume(volume); |
|||
if (result.IsError()) { |
|||
return result; |
|||
} |
|||
if (volume == 0.0f) { |
|||
out_command = Core::HID::VibrationGcErmCommand::Stop; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
// TODO: GetActualVibrationGcErmCommand
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadGcVibrationDevice::SendVibrationNotificationPattern( |
|||
Core::HID::VibrationGcErmCommand command) { |
|||
if (!is_mounted) { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
f32 volume = 1.0f; |
|||
const auto result = vibration_handler->GetVibrationVolume(volume); |
|||
if (result.IsError()) { |
|||
return result; |
|||
} |
|||
if (volume <= 0.0f) { |
|||
command = Core::HID::VibrationGcErmCommand::Stop; |
|||
} |
|||
if (command > Core::HID::VibrationGcErmCommand::StopHard) { |
|||
// Abort
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
// TODO: SendVibrationNotificationPattern
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,31 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <mutex> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
#include "hid_core/resources/npad/npad_types.h" |
|||
#include "hid_core/resources/vibration/vibration_base.h" |
|||
|
|||
namespace Service::HID { |
|||
class NpadVibration; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NpadGcVibrationDevice final : public NpadVibrationBase { |
|||
public: |
|||
explicit NpadGcVibrationDevice(); |
|||
|
|||
Result IncrementRefCounter() override; |
|||
Result DecrementRefCounter() override; |
|||
|
|||
Result SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command); |
|||
|
|||
Result GetActualVibrationGcErmCommand(Core::HID::VibrationGcErmCommand& out_command); |
|||
Result SendVibrationNotificationPattern(Core::HID::VibrationGcErmCommand command); |
|||
}; |
|||
} // namespace Service::HID |
|||
@ -0,0 +1,80 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/resources/npad/npad_types.h"
|
|||
#include "hid_core/resources/npad/npad_vibration.h"
|
|||
#include "hid_core/resources/vibration/n64_vibration_device.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadN64VibrationDevice::NpadN64VibrationDevice() {} |
|||
|
|||
Result NpadN64VibrationDevice::IncrementRefCounter() { |
|||
if (ref_counter == 0 && is_mounted) { |
|||
f32 volume = 1.0f; |
|||
const auto result = vibration_handler->GetVibrationVolume(volume); |
|||
if (result.IsSuccess()) { |
|||
// TODO: SendVibrationInBool
|
|||
} |
|||
} |
|||
|
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadN64VibrationDevice::DecrementRefCounter() { |
|||
if (ref_counter == 1) { |
|||
if (!is_mounted) { |
|||
ref_counter = 0; |
|||
if (is_mounted != false) { |
|||
// TODO: SendVibrationInBool
|
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
f32 volume = 1.0f; |
|||
const auto result = vibration_handler->GetVibrationVolume(volume); |
|||
if (result.IsSuccess()) { |
|||
// TODO
|
|||
} |
|||
} |
|||
|
|||
if (ref_counter > 0) { |
|||
ref_counter--; |
|||
} |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadN64VibrationDevice::SendValueInBool(bool is_vibrating) { |
|||
if (ref_counter < 1) { |
|||
return ResultVibrationNotInitialized; |
|||
} |
|||
if (is_mounted) { |
|||
f32 volume = 1.0f; |
|||
const auto result = vibration_handler->GetVibrationVolume(volume); |
|||
if (result.IsError()) { |
|||
return result; |
|||
} |
|||
// TODO: SendVibrationInBool
|
|||
} |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadN64VibrationDevice::SendVibrationNotificationPattern([[maybe_unused]] u32 pattern) { |
|||
if (!is_mounted) { |
|||
return ResultSuccess; |
|||
} |
|||
f32 volume = 1.0f; |
|||
const auto result = vibration_handler->GetVibrationVolume(volume); |
|||
if (result.IsError()) { |
|||
return result; |
|||
} |
|||
if (volume <= 0.0) { |
|||
pattern = 0; |
|||
} |
|||
// TODO: SendVibrationNotificationPattern
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,29 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <mutex> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
#include "hid_core/resources/npad/npad_types.h" |
|||
#include "hid_core/resources/vibration/vibration_base.h" |
|||
|
|||
namespace Service::HID { |
|||
class NpadVibration; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NpadN64VibrationDevice final : public NpadVibrationBase { |
|||
public: |
|||
explicit NpadN64VibrationDevice(); |
|||
|
|||
Result IncrementRefCounter() override; |
|||
Result DecrementRefCounter() override; |
|||
|
|||
Result SendValueInBool(bool is_vibrating); |
|||
Result SendVibrationNotificationPattern(u32 pattern); |
|||
}; |
|||
} // namespace Service::HID |
|||
@ -0,0 +1,30 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/resources/npad/npad_types.h"
|
|||
#include "hid_core/resources/npad/npad_vibration.h"
|
|||
#include "hid_core/resources/vibration/vibration_base.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadVibrationBase::NpadVibrationBase() {} |
|||
|
|||
Result NpadVibrationBase::IncrementRefCounter() { |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadVibrationBase::DecrementRefCounter() { |
|||
if (ref_counter > 0) { |
|||
ref_counter--; |
|||
} |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
bool NpadVibrationBase::IsVibrationMounted() const { |
|||
return is_mounted; |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,28 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
|
|||
namespace Service::HID { |
|||
class NpadVibration; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NpadVibrationBase { |
|||
public: |
|||
explicit NpadVibrationBase(); |
|||
|
|||
virtual Result IncrementRefCounter(); |
|||
virtual Result DecrementRefCounter(); |
|||
|
|||
bool IsVibrationMounted() const; |
|||
|
|||
protected: |
|||
u64 xcd_handle{}; |
|||
s32 ref_counter{}; |
|||
bool is_mounted{}; |
|||
NpadVibration* vibration_handler{nullptr}; |
|||
}; |
|||
} // namespace Service::HID |
|||
@ -0,0 +1,84 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "hid_core/hid_result.h"
|
|||
#include "hid_core/resources/npad/npad_types.h"
|
|||
#include "hid_core/resources/npad/npad_vibration.h"
|
|||
#include "hid_core/resources/vibration/vibration_device.h"
|
|||
|
|||
namespace Service::HID { |
|||
|
|||
NpadVibrationDevice::NpadVibrationDevice() {} |
|||
|
|||
Result NpadVibrationDevice::IncrementRefCounter() { |
|||
ref_counter++; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadVibrationDevice::DecrementRefCounter() { |
|||
if (ref_counter > 0) { |
|||
ref_counter--; |
|||
} |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue& value) { |
|||
if (ref_counter == 0) { |
|||
return ResultVibrationNotInitialized; |
|||
} |
|||
if (!is_mounted) { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
f32 volume = 1.0f; |
|||
const auto result = vibration_handler->GetVibrationVolume(volume); |
|||
if (result.IsError()) { |
|||
return result; |
|||
} |
|||
if (volume <= 0.0f) { |
|||
// TODO: SendVibrationValue
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Core::HID::VibrationValue vibration_value = value; |
|||
vibration_value.high_amplitude *= volume; |
|||
vibration_value.low_amplitude *= volume; |
|||
|
|||
// TODO: SendVibrationValue
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadVibrationDevice::SendVibrationNotificationPattern([[maybe_unused]] u32 pattern) { |
|||
if (!is_mounted) { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
f32 volume = 1.0f; |
|||
const auto result = vibration_handler->GetVibrationVolume(volume); |
|||
if (result.IsError()) { |
|||
return result; |
|||
} |
|||
if (volume <= 0.0) { |
|||
pattern = 0; |
|||
} |
|||
|
|||
// return xcd_handle->SendVibrationNotificationPattern(pattern);
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result NpadVibrationDevice::GetActualVibrationValue(Core::HID::VibrationValue& out_value) { |
|||
if (ref_counter < 1) { |
|||
return ResultVibrationNotInitialized; |
|||
} |
|||
|
|||
out_value = Core::HID::DEFAULT_VIBRATION_VALUE; |
|||
if (!is_mounted) { |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
// TODO: SendVibrationValue
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,35 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <mutex> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
#include "hid_core/hid_types.h" |
|||
#include "hid_core/resources/npad/npad_types.h" |
|||
#include "hid_core/resources/vibration/vibration_base.h" |
|||
|
|||
namespace Service::HID { |
|||
class NpadVibration; |
|||
|
|||
/// Handles Npad request from HID interfaces |
|||
class NpadVibrationDevice final : public NpadVibrationBase { |
|||
public: |
|||
explicit NpadVibrationDevice(); |
|||
|
|||
Result IncrementRefCounter(); |
|||
Result DecrementRefCounter(); |
|||
|
|||
Result SendVibrationValue(const Core::HID::VibrationValue& value); |
|||
Result SendVibrationNotificationPattern(u32 pattern); |
|||
|
|||
Result GetActualVibrationValue(Core::HID::VibrationValue& out_value); |
|||
|
|||
private: |
|||
u32 device_index{}; |
|||
}; |
|||
|
|||
} // namespace Service::HID |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue