forked from eden-emu/eden
		
	service: hid: Create abstracted pad structure
This commit is contained in:
		
							parent
							
								
									a4d90a9a64
								
							
						
					
					
						commit
						b5dac5f525
					
				
					 51 changed files with 3333 additions and 43 deletions
				
			
		|  | @ -410,8 +410,8 @@ void EmulationSession::OnGamepadConnectEvent([[maybe_unused]] int index) { | ||||||
|         jauto handheld = m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); |         jauto handheld = m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); | ||||||
| 
 | 
 | ||||||
|         if (controller->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::Handheld) { |         if (controller->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::Handheld) { | ||||||
|             handheld->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController); |             handheld->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Fullkey); | ||||||
|             controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController); |             controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Fullkey); | ||||||
|             handheld->Disconnect(); |             handheld->Disconnect(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -47,7 +47,7 @@ void DefaultControllerApplet::ReconfigureControllers(ReconfigureCallback callbac | ||||||
|         // Connect controllers based on the following priority list from highest to lowest priority:
 |         // Connect controllers based on the following priority list from highest to lowest priority:
 | ||||||
|         // Pro Controller -> Dual Joycons -> Left Joycon/Right Joycon -> Handheld
 |         // Pro Controller -> Dual Joycons -> Left Joycon/Right Joycon -> Handheld
 | ||||||
|         if (parameters.allow_pro_controller) { |         if (parameters.allow_pro_controller) { | ||||||
|             controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController); |             controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Fullkey); | ||||||
|             controller->Connect(true); |             controller->Connect(true); | ||||||
|         } else if (parameters.allow_dual_joycons) { |         } else if (parameters.allow_dual_joycons) { | ||||||
|             controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::JoyconDual); |             controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::JoyconDual); | ||||||
|  |  | ||||||
|  | @ -1498,7 +1498,7 @@ void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) { | ||||||
|     bool check_device_index = false; |     bool check_device_index = false; | ||||||
| 
 | 
 | ||||||
|     switch (vibration_device_handle.npad_type) { |     switch (vibration_device_handle.npad_type) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|     case Core::HID::NpadStyleIndex::JoyconDual: |     case Core::HID::NpadStyleIndex::JoyconDual: | ||||||
|     case Core::HID::NpadStyleIndex::JoyconLeft: |     case Core::HID::NpadStyleIndex::JoyconLeft: | ||||||
|  |  | ||||||
|  | @ -36,6 +36,30 @@ add_library(hid_core STATIC | ||||||
|     irsensor/processor_base.h |     irsensor/processor_base.h | ||||||
|     irsensor/tera_plugin_processor.cpp |     irsensor/tera_plugin_processor.cpp | ||||||
|     irsensor/tera_plugin_processor.h |     irsensor/tera_plugin_processor.h | ||||||
|  |     resources/abstracted_pad/abstract_battery_handler.cpp | ||||||
|  |     resources/abstracted_pad/abstract_battery_handler.h | ||||||
|  |     resources/abstracted_pad/abstract_button_handler.cpp | ||||||
|  |     resources/abstracted_pad/abstract_button_handler.h | ||||||
|  |     resources/abstracted_pad/abstract_ir_sensor_handler.cpp | ||||||
|  |     resources/abstracted_pad/abstract_ir_sensor_handler.h | ||||||
|  |     resources/abstracted_pad/abstract_led_handler.cpp | ||||||
|  |     resources/abstracted_pad/abstract_led_handler.h | ||||||
|  |     resources/abstracted_pad/abstract_mcu_handler.cpp | ||||||
|  |     resources/abstracted_pad/abstract_mcu_handler.h | ||||||
|  |     resources/abstracted_pad/abstract_nfc_handler.cpp | ||||||
|  |     resources/abstracted_pad/abstract_nfc_handler.h | ||||||
|  |     resources/abstracted_pad/abstract_pad.cpp | ||||||
|  |     resources/abstracted_pad/abstract_pad.h | ||||||
|  |     resources/abstracted_pad/abstract_pad_holder.cpp | ||||||
|  |     resources/abstracted_pad/abstract_pad_holder.h | ||||||
|  |     resources/abstracted_pad/abstract_palma_handler.cpp | ||||||
|  |     resources/abstracted_pad/abstract_palma_handler.h | ||||||
|  |     resources/abstracted_pad/abstract_properties_handler.cpp | ||||||
|  |     resources/abstracted_pad/abstract_properties_handler.h | ||||||
|  |     resources/abstracted_pad/abstract_sixaxis_handler.cpp | ||||||
|  |     resources/abstracted_pad/abstract_sixaxis_handler.h | ||||||
|  |     resources/abstracted_pad/abstract_vibration_handler.cpp | ||||||
|  |     resources/abstracted_pad/abstract_vibration_handler.h | ||||||
|     resources/debug_pad/debug_pad.cpp |     resources/debug_pad/debug_pad.cpp | ||||||
|     resources/debug_pad/debug_pad.h |     resources/debug_pad/debug_pad.h | ||||||
|     resources/debug_pad/debug_pad_types.h |     resources/debug_pad/debug_pad_types.h | ||||||
|  | @ -56,6 +80,8 @@ add_library(hid_core STATIC | ||||||
|     resources/npad/npad_resource.cpp |     resources/npad/npad_resource.cpp | ||||||
|     resources/npad/npad_resource.h |     resources/npad/npad_resource.h | ||||||
|     resources/npad/npad_types.h |     resources/npad/npad_types.h | ||||||
|  |     resources/npad/npad_vibration.cpp | ||||||
|  |     resources/npad/npad_vibration.h | ||||||
|     resources/palma/palma.cpp |     resources/palma/palma.cpp | ||||||
|     resources/palma/palma.h |     resources/palma/palma.h | ||||||
|     resources/six_axis/console_six_axis.cpp |     resources/six_axis/console_six_axis.cpp | ||||||
|  | @ -78,6 +104,14 @@ add_library(hid_core STATIC | ||||||
|     resources/touch_screen/touch_types.h |     resources/touch_screen/touch_types.h | ||||||
|     resources/unique_pad/unique_pad.cpp |     resources/unique_pad/unique_pad.cpp | ||||||
|     resources/unique_pad/unique_pad.h |     resources/unique_pad/unique_pad.h | ||||||
|  |     resources/vibration/gc_vibration_device.h | ||||||
|  |     resources/vibration/gc_vibration_device.cpp | ||||||
|  |     resources/vibration/n64_vibration_device.h | ||||||
|  |     resources/vibration/n64_vibration_device.cpp | ||||||
|  |     resources/vibration/vibration_base.h | ||||||
|  |     resources/vibration/vibration_base.cpp | ||||||
|  |     resources/vibration/vibration_device.h | ||||||
|  |     resources/vibration/vibration_device.cpp | ||||||
|     resources/applet_resource.cpp |     resources/applet_resource.cpp | ||||||
|     resources/applet_resource.h |     resources/applet_resource.h | ||||||
|     resources/controller_base.cpp |     resources/controller_base.cpp | ||||||
|  |  | ||||||
|  | @ -27,7 +27,7 @@ EmulatedController::~EmulatedController() = default; | ||||||
| NpadStyleIndex EmulatedController::MapSettingsTypeToNPad(Settings::ControllerType type) { | NpadStyleIndex EmulatedController::MapSettingsTypeToNPad(Settings::ControllerType type) { | ||||||
|     switch (type) { |     switch (type) { | ||||||
|     case Settings::ControllerType::ProController: |     case Settings::ControllerType::ProController: | ||||||
|         return NpadStyleIndex::ProController; |         return NpadStyleIndex::Fullkey; | ||||||
|     case Settings::ControllerType::DualJoyconDetached: |     case Settings::ControllerType::DualJoyconDetached: | ||||||
|         return NpadStyleIndex::JoyconDual; |         return NpadStyleIndex::JoyconDual; | ||||||
|     case Settings::ControllerType::LeftJoycon: |     case Settings::ControllerType::LeftJoycon: | ||||||
|  | @ -49,13 +49,13 @@ NpadStyleIndex EmulatedController::MapSettingsTypeToNPad(Settings::ControllerTyp | ||||||
|     case Settings::ControllerType::SegaGenesis: |     case Settings::ControllerType::SegaGenesis: | ||||||
|         return NpadStyleIndex::SegaGenesis; |         return NpadStyleIndex::SegaGenesis; | ||||||
|     default: |     default: | ||||||
|         return NpadStyleIndex::ProController; |         return NpadStyleIndex::Fullkey; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Settings::ControllerType EmulatedController::MapNPadToSettingsType(NpadStyleIndex type) { | Settings::ControllerType EmulatedController::MapNPadToSettingsType(NpadStyleIndex type) { | ||||||
|     switch (type) { |     switch (type) { | ||||||
|     case NpadStyleIndex::ProController: |     case NpadStyleIndex::Fullkey: | ||||||
|         return Settings::ControllerType::ProController; |         return Settings::ControllerType::ProController; | ||||||
|     case NpadStyleIndex::JoyconDual: |     case NpadStyleIndex::JoyconDual: | ||||||
|         return Settings::ControllerType::DualJoyconDetached; |         return Settings::ControllerType::DualJoyconDetached; | ||||||
|  | @ -106,7 +106,7 @@ void EmulatedController::ReloadFromSettings() { | ||||||
|         SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type)); |         SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type)); | ||||||
|         original_npad_type = npad_type; |         original_npad_type = npad_type; | ||||||
|     } else { |     } else { | ||||||
|         SetNpadStyleIndex(NpadStyleIndex::ProController); |         SetNpadStyleIndex(NpadStyleIndex::Fullkey); | ||||||
|         original_npad_type = npad_type; |         original_npad_type = npad_type; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -1073,7 +1073,7 @@ void EmulatedController::SetColors(const Common::Input::CallbackStatus& callback | ||||||
|         .body = GetNpadColor(controller.color_values[index].body), |         .body = GetNpadColor(controller.color_values[index].body), | ||||||
|         .button = GetNpadColor(controller.color_values[index].buttons), |         .button = GetNpadColor(controller.color_values[index].buttons), | ||||||
|     }; |     }; | ||||||
|     if (npad_type == NpadStyleIndex::ProController) { |     if (npad_type == NpadStyleIndex::Fullkey) { | ||||||
|         controller.colors_state.left = { |         controller.colors_state.left = { | ||||||
|             .body = GetNpadColor(controller.color_values[index].left_grip), |             .body = GetNpadColor(controller.color_values[index].left_grip), | ||||||
|             .button = GetNpadColor(controller.color_values[index].buttons), |             .button = GetNpadColor(controller.color_values[index].buttons), | ||||||
|  | @ -1356,7 +1356,7 @@ bool EmulatedController::HasNfc() const { | ||||||
|     switch (npad_type) { |     switch (npad_type) { | ||||||
|     case NpadStyleIndex::JoyconRight: |     case NpadStyleIndex::JoyconRight: | ||||||
|     case NpadStyleIndex::JoyconDual: |     case NpadStyleIndex::JoyconDual: | ||||||
|     case NpadStyleIndex::ProController: |     case NpadStyleIndex::Fullkey: | ||||||
|     case NpadStyleIndex::Handheld: |     case NpadStyleIndex::Handheld: | ||||||
|         break; |         break; | ||||||
|     default: |     default: | ||||||
|  | @ -1548,7 +1548,7 @@ void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) | ||||||
|     // Fallback Fullkey controllers to Pro controllers
 |     // Fallback Fullkey controllers to Pro controllers
 | ||||||
|     if (IsControllerFullkey() && supported_style_tag.fullkey) { |     if (IsControllerFullkey() && supported_style_tag.fullkey) { | ||||||
|         LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type); |         LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type); | ||||||
|         SetNpadStyleIndex(NpadStyleIndex::ProController); |         SetNpadStyleIndex(NpadStyleIndex::Fullkey); | ||||||
|         Connect(); |         Connect(); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | @ -1556,13 +1556,13 @@ void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) | ||||||
|     // Fallback Dual joycon controllers to Pro controllers
 |     // Fallback Dual joycon controllers to Pro controllers
 | ||||||
|     if (npad_type == NpadStyleIndex::JoyconDual && supported_style_tag.fullkey) { |     if (npad_type == NpadStyleIndex::JoyconDual && supported_style_tag.fullkey) { | ||||||
|         LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type); |         LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type); | ||||||
|         SetNpadStyleIndex(NpadStyleIndex::ProController); |         SetNpadStyleIndex(NpadStyleIndex::Fullkey); | ||||||
|         Connect(); |         Connect(); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Fallback Pro controllers to Dual joycon
 |     // Fallback Pro controllers to Dual joycon
 | ||||||
|     if (npad_type == NpadStyleIndex::ProController && supported_style_tag.joycon_dual) { |     if (npad_type == NpadStyleIndex::Fullkey && supported_style_tag.joycon_dual) { | ||||||
|         LOG_WARNING(Service_HID, "Reconnecting controller type {} as Dual Joycons", npad_type); |         LOG_WARNING(Service_HID, "Reconnecting controller type {} as Dual Joycons", npad_type); | ||||||
|         SetNpadStyleIndex(NpadStyleIndex::JoyconDual); |         SetNpadStyleIndex(NpadStyleIndex::JoyconDual); | ||||||
|         Connect(); |         Connect(); | ||||||
|  | @ -1577,7 +1577,7 @@ bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const { | ||||||
|     std::scoped_lock lock{mutex}; |     std::scoped_lock lock{mutex}; | ||||||
|     const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; |     const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; | ||||||
|     switch (type) { |     switch (type) { | ||||||
|     case NpadStyleIndex::ProController: |     case NpadStyleIndex::Fullkey: | ||||||
|     case NpadStyleIndex::GameCube: |     case NpadStyleIndex::GameCube: | ||||||
|     case NpadStyleIndex::NES: |     case NpadStyleIndex::NES: | ||||||
|     case NpadStyleIndex::SNES: |     case NpadStyleIndex::SNES: | ||||||
|  | @ -1593,7 +1593,7 @@ bool EmulatedController::IsControllerSupported(bool use_temporary_value) const { | ||||||
|     std::scoped_lock lock{mutex}; |     std::scoped_lock lock{mutex}; | ||||||
|     const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; |     const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; | ||||||
|     switch (type) { |     switch (type) { | ||||||
|     case NpadStyleIndex::ProController: |     case NpadStyleIndex::Fullkey: | ||||||
|         return supported_style_tag.fullkey.As<bool>(); |         return supported_style_tag.fullkey.As<bool>(); | ||||||
|     case NpadStyleIndex::Handheld: |     case NpadStyleIndex::Handheld: | ||||||
|         return supported_style_tag.handheld.As<bool>(); |         return supported_style_tag.handheld.As<bool>(); | ||||||
|  |  | ||||||
|  | @ -220,6 +220,7 @@ enum class NpadIdType : u32 { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| enum class NpadInterfaceType : u8 { | enum class NpadInterfaceType : u8 { | ||||||
|  |     None = 0, | ||||||
|     Bluetooth = 1, |     Bluetooth = 1, | ||||||
|     Rail = 2, |     Rail = 2, | ||||||
|     Usb = 3, |     Usb = 3, | ||||||
|  | @ -229,7 +230,7 @@ enum class NpadInterfaceType : u8 { | ||||||
| // This is nn::hid::NpadStyleIndex
 | // This is nn::hid::NpadStyleIndex
 | ||||||
| enum class NpadStyleIndex : u8 { | enum class NpadStyleIndex : u8 { | ||||||
|     None = 0, |     None = 0, | ||||||
|     ProController = 3, |     Fullkey = 3, | ||||||
|     Handheld = 4, |     Handheld = 4, | ||||||
|     HandheldNES = 4, |     HandheldNES = 4, | ||||||
|     JoyconDual = 5, |     JoyconDual = 5, | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ constexpr Result IsSixaxisHandleValid(const Core::HID::SixAxisSensorHandle& hand | ||||||
| 
 | 
 | ||||||
| constexpr Result IsVibrationHandleValid(const Core::HID::VibrationDeviceHandle& handle) { | constexpr Result IsVibrationHandleValid(const Core::HID::VibrationDeviceHandle& handle) { | ||||||
|     switch (handle.npad_type) { |     switch (handle.npad_type) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|     case Core::HID::NpadStyleIndex::JoyconDual: |     case Core::HID::NpadStyleIndex::JoyconDual: | ||||||
|     case Core::HID::NpadStyleIndex::JoyconLeft: |     case Core::HID::NpadStyleIndex::JoyconLeft: | ||||||
|  |  | ||||||
|  | @ -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
 | ||||||
							
								
								
									
										123
									
								
								src/hid_core/resources/abstracted_pad/abstract_led_handler.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/hid_core/resources/abstracted_pad/abstract_led_handler.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										43
									
								
								src/hid_core/resources/abstracted_pad/abstract_led_handler.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/hid_core/resources/abstracted_pad/abstract_led_handler.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										108
									
								
								src/hid_core/resources/abstracted_pad/abstract_mcu_handler.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/hid_core/resources/abstracted_pad/abstract_mcu_handler.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										52
									
								
								src/hid_core/resources/abstracted_pad/abstract_mcu_handler.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/hid_core/resources/abstracted_pad/abstract_mcu_handler.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										140
									
								
								src/hid_core/resources/abstracted_pad/abstract_nfc_handler.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								src/hid_core/resources/abstracted_pad/abstract_nfc_handler.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										57
									
								
								src/hid_core/resources/abstracted_pad/abstract_nfc_handler.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/hid_core/resources/abstracted_pad/abstract_nfc_handler.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										294
									
								
								src/hid_core/resources/abstracted_pad/abstract_pad.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										294
									
								
								src/hid_core/resources/abstracted_pad/abstract_pad.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										123
									
								
								src/hid_core/resources/abstracted_pad/abstract_pad.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/hid_core/resources/abstracted_pad/abstract_pad.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										47
									
								
								src/hid_core/resources/abstracted_pad/abstract_pad_holder.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/hid_core/resources/abstracted_pad/abstract_pad_holder.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
|  | @ -193,7 +193,7 @@ void NPad::InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id) { | ||||||
|     case Core::HID::NpadStyleIndex::None: |     case Core::HID::NpadStyleIndex::None: | ||||||
|         ASSERT(false); |         ASSERT(false); | ||||||
|         break; |         break; | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|         shared_memory->fullkey_color.attribute = ColorAttribute::Ok; |         shared_memory->fullkey_color.attribute = ColorAttribute::Ok; | ||||||
|         shared_memory->fullkey_color.fullkey = body_colors.fullkey; |         shared_memory->fullkey_color.fullkey = body_colors.fullkey; | ||||||
|         shared_memory->battery_level_dual = battery_level.dual.battery_level; |         shared_memory->battery_level_dual = battery_level.dual.battery_level; | ||||||
|  | @ -491,7 +491,7 @@ void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||||
|             case Core::HID::NpadStyleIndex::None: |             case Core::HID::NpadStyleIndex::None: | ||||||
|                 ASSERT(false); |                 ASSERT(false); | ||||||
|                 break; |                 break; | ||||||
|             case Core::HID::NpadStyleIndex::ProController: |             case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|             case Core::HID::NpadStyleIndex::NES: |             case Core::HID::NpadStyleIndex::NES: | ||||||
|             case Core::HID::NpadStyleIndex::SNES: |             case Core::HID::NpadStyleIndex::SNES: | ||||||
|             case Core::HID::NpadStyleIndex::N64: |             case Core::HID::NpadStyleIndex::N64: | ||||||
|  | @ -1292,7 +1292,7 @@ Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties( | ||||||
|     u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle) { |     u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle) { | ||||||
|     auto& controller = GetControllerFromHandle(aruid, sixaxis_handle); |     auto& controller = GetControllerFromHandle(aruid, sixaxis_handle); | ||||||
|     switch (sixaxis_handle.npad_type) { |     switch (sixaxis_handle.npad_type) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::Pokeball: |     case Core::HID::NpadStyleIndex::Pokeball: | ||||||
|         return controller.shared_memory->sixaxis_fullkey_properties; |         return controller.shared_memory->sixaxis_fullkey_properties; | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|  | @ -1315,7 +1315,7 @@ const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties( | ||||||
|     u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { |     u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { | ||||||
|     const auto& controller = GetControllerFromHandle(aruid, sixaxis_handle); |     const auto& controller = GetControllerFromHandle(aruid, sixaxis_handle); | ||||||
|     switch (sixaxis_handle.npad_type) { |     switch (sixaxis_handle.npad_type) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::Pokeball: |     case Core::HID::NpadStyleIndex::Pokeball: | ||||||
|         return controller.shared_memory->sixaxis_fullkey_properties; |         return controller.shared_memory->sixaxis_fullkey_properties; | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|  |  | ||||||
|  | @ -151,7 +151,7 @@ Core::HID::NpadStyleSet NPadData::GetSupportedNpadStyleSet() const { | ||||||
| bool NPadData::IsNpadStyleIndexSupported(Core::HID::NpadStyleIndex style_index) const { | bool NPadData::IsNpadStyleIndexSupported(Core::HID::NpadStyleIndex style_index) const { | ||||||
|     Core::HID::NpadStyleTag style = {supported_npad_style_set}; |     Core::HID::NpadStyleTag style = {supported_npad_style_set}; | ||||||
|     switch (style_index) { |     switch (style_index) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|         return style.fullkey.As<bool>(); |         return style.fullkey.As<bool>(); | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|         return style.handheld.As<bool>(); |         return style.handheld.As<bool>(); | ||||||
|  |  | ||||||
|  | @ -252,4 +252,103 @@ enum class NpadLagerType : u32 { | ||||||
|     U, |     U, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | // nn::hidtypes::FeatureType
 | ||||||
|  | struct FeatureType { | ||||||
|  |     union { | ||||||
|  |         u64 raw{}; | ||||||
|  |         BitField<0, 1, u64> has_left_analog_stick; | ||||||
|  |         BitField<1, 1, u64> has_right_analog_stick; | ||||||
|  |         BitField<2, 1, u64> has_left_joy_six_axis_sensor; | ||||||
|  |         BitField<3, 1, u64> has_right_joy_six_axis_sensor; | ||||||
|  |         BitField<4, 1, u64> has_fullkey_joy_six_axis_sensor; | ||||||
|  |         BitField<5, 1, u64> has_left_lra_vibration_device; | ||||||
|  |         BitField<6, 1, u64> has_right_lra_vibration_device; | ||||||
|  |         BitField<7, 1, u64> has_gc_vibration_device; | ||||||
|  |         BitField<8, 1, u64> has_erm_vibration_device; | ||||||
|  |         BitField<9, 1, u64> has_left_joy_rail_bus; | ||||||
|  |         BitField<10, 1, u64> has_right_joy_rail_bus; | ||||||
|  |         BitField<11, 1, u64> has_internal_bus; | ||||||
|  |         BitField<12, 1, u64> is_palma; | ||||||
|  |         BitField<13, 1, u64> has_nfc; | ||||||
|  |         BitField<14, 1, u64> has_ir_sensor; | ||||||
|  |         BitField<15, 1, u64> is_analog_stick_calibration_supported; | ||||||
|  |         BitField<16, 1, u64> is_six_axis_Sensor_user_calibration_supported; | ||||||
|  |         BitField<17, 1, u64> has_left_right_joy_battery; | ||||||
|  |         BitField<18, 1, u64> has_fullkey_battery; | ||||||
|  |         BitField<19, 1, u64> is_disconnect_controller_if_battery_none; | ||||||
|  |         BitField<20, 1, u64> has_controller_color; | ||||||
|  |         BitField<21, 1, u64> has_grip_color; | ||||||
|  |         BitField<22, 1, u64> has_identification_code; | ||||||
|  |         BitField<23, 1, u64> has_bluetooth_address; | ||||||
|  |         BitField<24, 1, u64> has_mcu; | ||||||
|  |         BitField<25, 1, u64> has_notification_led; | ||||||
|  |         BitField<26, 1, u64> has_directional_buttons; | ||||||
|  |         BitField<27, 1, u64> has_indicator_led; | ||||||
|  |         BitField<28, 1, u64> is_button_config_embedded_supported; | ||||||
|  |         BitField<29, 1, u64> is_button_config_full_supported; | ||||||
|  |         BitField<30, 1, u64> is_button_config_left_supported; | ||||||
|  |         BitField<31, 1, u64> is_button_config_right_supported; | ||||||
|  |         BitField<32, 1, u64> is_usb_hid_device; | ||||||
|  |         BitField<33, 1, u64> is_kuina_device; | ||||||
|  |         BitField<34, 1, u64> is_direct_usb_to_bt_switching_device; | ||||||
|  |         BitField<35, 1, u64> is_normalize_analog_stick_with_inner_cross; | ||||||
|  |     }; | ||||||
|  | }; | ||||||
|  | static_assert(sizeof(FeatureType) == 8, "FeatureType is an invalid size"); | ||||||
|  | 
 | ||||||
|  | // This is nn::hid::AssignmentStyle
 | ||||||
|  | struct AssignmentStyle { | ||||||
|  |     union { | ||||||
|  |         u32 raw{}; | ||||||
|  |         BitField<0, 1, u32> is_external_assigned; | ||||||
|  |         BitField<1, 1, u32> is_external_left_assigned; | ||||||
|  |         BitField<2, 1, u32> is_external_right_assigned; | ||||||
|  |         BitField<3, 1, u32> is_handheld_assigned; | ||||||
|  |         BitField<4, 1, u32> is_handheld_left_assigned; | ||||||
|  |         BitField<5, 1, u32> is_handheld_right_assigned; | ||||||
|  |     }; | ||||||
|  | }; | ||||||
|  | static_assert(sizeof(AssignmentStyle) == 4, "AssignmentStyle is an invalid size"); | ||||||
|  | 
 | ||||||
|  | // This is nn::hid::server::IAbstractedPad::InternalFlags
 | ||||||
|  | struct InternalFlags { | ||||||
|  |     union { | ||||||
|  |         u32 raw{}; | ||||||
|  |         BitField<0, 1, u32> is_bound; | ||||||
|  |         BitField<1, 1, u32> is_connected; | ||||||
|  |         BitField<2, 1, u32> is_battery_low_ovln_required; | ||||||
|  |         BitField<3, 1, u32> is_battery_low_ovln_delay_required; | ||||||
|  |         BitField<4, 1, u32> is_sample_recieved; | ||||||
|  |         BitField<5, 1, u32> is_virtual_input; | ||||||
|  |         BitField<6, 1, u32> is_wired; | ||||||
|  |         BitField<8, 1, u32> use_center_clamp; | ||||||
|  |         BitField<9, 1, u32> has_virtual_six_axis_sensor_acceleration; | ||||||
|  |         BitField<10, 1, u32> has_virtual_six_axis_sensor_angle; | ||||||
|  |         BitField<11, 1, u32> is_debug_pad; | ||||||
|  |     }; | ||||||
|  | }; | ||||||
|  | static_assert(sizeof(InternalFlags) == 4, "InternalFlags is an invalid size"); | ||||||
|  | 
 | ||||||
|  | /// This is nn::hid::server::IAbstractedPad
 | ||||||
|  | struct IAbstractedPad { | ||||||
|  |     InternalFlags internal_flags; | ||||||
|  |     u64 controller_id; | ||||||
|  |     u32 controller_number; | ||||||
|  |     u64 low_battery_display_delay_time; | ||||||
|  |     u64 low_battery_display_delay_interval; | ||||||
|  |     FeatureType feature_set; | ||||||
|  |     FeatureType disabled_feature_set; | ||||||
|  |     AssignmentStyle assignment_style; | ||||||
|  |     Core::HID::NpadStyleIndex device_type; | ||||||
|  |     Core::HID::NpadInterfaceType interface_type; | ||||||
|  |     Core::HID::NpadPowerInfo power_info; | ||||||
|  |     u32 pad_state; | ||||||
|  |     u32 button_mask; | ||||||
|  |     u32 system_button_mask; | ||||||
|  |     u8 indicator; | ||||||
|  |     std::vector<f32> virtual_six_axis_sensor_acceleration; | ||||||
|  |     std::vector<f32> virtual_six_axis_sensor_angle; | ||||||
|  |     u64 xcd_handle; | ||||||
|  |     u64 color; | ||||||
|  | }; | ||||||
| } // namespace Service::HID
 | } // namespace Service::HID
 | ||||||
|  |  | ||||||
							
								
								
									
										80
									
								
								src/hid_core/resources/npad/npad_vibration.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/hid_core/resources/npad/npad_vibration.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										34
									
								
								src/hid_core/resources/npad/npad_vibration.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/hid_core/resources/npad/npad_vibration.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
|  | @ -114,7 +114,7 @@ void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||||
|         case Core::HID::NpadStyleIndex::None: |         case Core::HID::NpadStyleIndex::None: | ||||||
|             ASSERT(false); |             ASSERT(false); | ||||||
|             break; |             break; | ||||||
|         case Core::HID::NpadStyleIndex::ProController: |         case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|             set_motion_state(sixaxis_fullkey_state, motion_state[0]); |             set_motion_state(sixaxis_fullkey_state, motion_state[0]); | ||||||
|             break; |             break; | ||||||
|         case Core::HID::NpadStyleIndex::Handheld: |         case Core::HID::NpadStyleIndex::Handheld: | ||||||
|  | @ -345,7 +345,7 @@ SixAxis::SixaxisParameters& SixAxis::GetSixaxisState( | ||||||
|     const Core::HID::SixAxisSensorHandle& sixaxis_handle) { |     const Core::HID::SixAxisSensorHandle& sixaxis_handle) { | ||||||
|     auto& controller = GetControllerFromHandle(sixaxis_handle); |     auto& controller = GetControllerFromHandle(sixaxis_handle); | ||||||
|     switch (sixaxis_handle.npad_type) { |     switch (sixaxis_handle.npad_type) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::Pokeball: |     case Core::HID::NpadStyleIndex::Pokeball: | ||||||
|         return controller.sixaxis_fullkey; |         return controller.sixaxis_fullkey; | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|  | @ -368,7 +368,7 @@ const SixAxis::SixaxisParameters& SixAxis::GetSixaxisState( | ||||||
|     const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { |     const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { | ||||||
|     const auto& controller = GetControllerFromHandle(sixaxis_handle); |     const auto& controller = GetControllerFromHandle(sixaxis_handle); | ||||||
|     switch (sixaxis_handle.npad_type) { |     switch (sixaxis_handle.npad_type) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::Pokeball: |     case Core::HID::NpadStyleIndex::Pokeball: | ||||||
|         return controller.sixaxis_fullkey; |         return controller.sixaxis_fullkey; | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|  |  | ||||||
							
								
								
									
										106
									
								
								src/hid_core/resources/vibration/gc_vibration_device.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								src/hid_core/resources/vibration/gc_vibration_device.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										31
									
								
								src/hid_core/resources/vibration/gc_vibration_device.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/hid_core/resources/vibration/gc_vibration_device.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										80
									
								
								src/hid_core/resources/vibration/n64_vibration_device.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/hid_core/resources/vibration/n64_vibration_device.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										29
									
								
								src/hid_core/resources/vibration/n64_vibration_device.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/hid_core/resources/vibration/n64_vibration_device.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										30
									
								
								src/hid_core/resources/vibration/vibration_base.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/hid_core/resources/vibration/vibration_base.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										28
									
								
								src/hid_core/resources/vibration/vibration_base.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/hid_core/resources/vibration/vibration_base.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										84
									
								
								src/hid_core/resources/vibration/vibration_device.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/hid_core/resources/vibration/vibration_device.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
							
								
								
									
										35
									
								
								src/hid_core/resources/vibration/vibration_device.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/hid_core/resources/vibration/vibration_device.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
|  | @ -41,7 +41,7 @@ void UpdateController(Core::HID::EmulatedController* controller, | ||||||
| bool IsControllerCompatible(Core::HID::NpadStyleIndex controller_type, | bool IsControllerCompatible(Core::HID::NpadStyleIndex controller_type, | ||||||
|                             Core::Frontend::ControllerParameters parameters) { |                             Core::Frontend::ControllerParameters parameters) { | ||||||
|     switch (controller_type) { |     switch (controller_type) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|         return parameters.allow_pro_controller; |         return parameters.allow_pro_controller; | ||||||
|     case Core::HID::NpadStyleIndex::JoyconDual: |     case Core::HID::NpadStyleIndex::JoyconDual: | ||||||
|         return parameters.allow_dual_joycons; |         return parameters.allow_dual_joycons; | ||||||
|  | @ -462,7 +462,7 @@ void QtControllerSelectorDialog::SetEmulatedControllers(std::size_t player_index | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     if (npad_style_set.fullkey == 1) { |     if (npad_style_set.fullkey == 1) { | ||||||
|         add_item(Core::HID::NpadStyleIndex::ProController, tr("Pro Controller")); |         add_item(Core::HID::NpadStyleIndex::Fullkey, tr("Pro Controller")); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (npad_style_set.joycon_dual == 1) { |     if (npad_style_set.joycon_dual == 1) { | ||||||
|  | @ -519,7 +519,7 @@ Core::HID::NpadStyleIndex QtControllerSelectorDialog::GetControllerTypeFromIndex | ||||||
|                                  [index](const auto& pair) { return pair.first == index; }); |                                  [index](const auto& pair) { return pair.first == index; }); | ||||||
| 
 | 
 | ||||||
|     if (it == pairs.end()) { |     if (it == pairs.end()) { | ||||||
|         return Core::HID::NpadStyleIndex::ProController; |         return Core::HID::NpadStyleIndex::Fullkey; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return it->second; |     return it->second; | ||||||
|  | @ -549,7 +549,7 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index) | ||||||
|     const QString stylesheet = [this, player_index] { |     const QString stylesheet = [this, player_index] { | ||||||
|         switch (GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex(), |         switch (GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex(), | ||||||
|                                            player_index)) { |                                            player_index)) { | ||||||
|         case Core::HID::NpadStyleIndex::ProController: |         case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|         case Core::HID::NpadStyleIndex::GameCube: |         case Core::HID::NpadStyleIndex::GameCube: | ||||||
|             return QStringLiteral("image: url(:/controller/applet_pro_controller%0); "); |             return QStringLiteral("image: url(:/controller/applet_pro_controller%0); "); | ||||||
|         case Core::HID::NpadStyleIndex::JoyconDual: |         case Core::HID::NpadStyleIndex::JoyconDual: | ||||||
|  |  | ||||||
|  | @ -832,7 +832,7 @@ void QtSoftwareKeyboardDialog::SetControllerImage() { | ||||||
|     }(); |     }(); | ||||||
| 
 | 
 | ||||||
|     switch (controller_type) { |     switch (controller_type) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::GameCube: |     case Core::HID::NpadStyleIndex::GameCube: | ||||||
|         ui->icon_controller->setStyleSheet( |         ui->icon_controller->setStyleSheet( | ||||||
|             QStringLiteral("image: url(:/overlay/controller_pro%1.png);").arg(theme)); |             QStringLiteral("image: url(:/overlay/controller_pro%1.png);").arg(theme)); | ||||||
|  |  | ||||||
|  | @ -1094,7 +1094,7 @@ void ConfigureInputPlayer::SetConnectableControllers() { | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     if (npad_style_set.fullkey == 1) { |     if (npad_style_set.fullkey == 1) { | ||||||
|         add_item(Core::HID::NpadStyleIndex::ProController, tr("Pro Controller")); |         add_item(Core::HID::NpadStyleIndex::Fullkey, tr("Pro Controller")); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (npad_style_set.joycon_dual == 1) { |     if (npad_style_set.joycon_dual == 1) { | ||||||
|  | @ -1149,7 +1149,7 @@ Core::HID::NpadStyleIndex ConfigureInputPlayer::GetControllerTypeFromIndex(int i | ||||||
|                      [index](const auto& pair) { return pair.first == index; }); |                      [index](const auto& pair) { return pair.first == index; }); | ||||||
| 
 | 
 | ||||||
|     if (it == index_controller_type_pairs.end()) { |     if (it == index_controller_type_pairs.end()) { | ||||||
|         return Core::HID::NpadStyleIndex::ProController; |         return Core::HID::NpadStyleIndex::Fullkey; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return it->second; |     return it->second; | ||||||
|  | @ -1178,7 +1178,7 @@ void ConfigureInputPlayer::UpdateInputDevices() { | ||||||
| void ConfigureInputPlayer::UpdateControllerAvailableButtons() { | void ConfigureInputPlayer::UpdateControllerAvailableButtons() { | ||||||
|     auto layout = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); |     auto layout = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); | ||||||
|     if (debug) { |     if (debug) { | ||||||
|         layout = Core::HID::NpadStyleIndex::ProController; |         layout = Core::HID::NpadStyleIndex::Fullkey; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // List of all the widgets that will be hidden by any of the following layouts that need
 |     // List of all the widgets that will be hidden by any of the following layouts that need
 | ||||||
|  | @ -1206,7 +1206,7 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() { | ||||||
| 
 | 
 | ||||||
|     std::vector<QWidget*> layout_hidden; |     std::vector<QWidget*> layout_hidden; | ||||||
|     switch (layout) { |     switch (layout) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|         layout_hidden = { |         layout_hidden = { | ||||||
|             ui->buttonShoulderButtonsSLSRLeft, |             ui->buttonShoulderButtonsSLSRLeft, | ||||||
|  | @ -1254,7 +1254,7 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() { | ||||||
| void ConfigureInputPlayer::UpdateControllerEnabledButtons() { | void ConfigureInputPlayer::UpdateControllerEnabledButtons() { | ||||||
|     auto layout = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); |     auto layout = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); | ||||||
|     if (debug) { |     if (debug) { | ||||||
|         layout = Core::HID::NpadStyleIndex::ProController; |         layout = Core::HID::NpadStyleIndex::Fullkey; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // List of all the widgets that will be disabled by any of the following layouts that need
 |     // List of all the widgets that will be disabled by any of the following layouts that need
 | ||||||
|  | @ -1271,7 +1271,7 @@ void ConfigureInputPlayer::UpdateControllerEnabledButtons() { | ||||||
| 
 | 
 | ||||||
|     std::vector<QWidget*> layout_disable; |     std::vector<QWidget*> layout_disable; | ||||||
|     switch (layout) { |     switch (layout) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::JoyconDual: |     case Core::HID::NpadStyleIndex::JoyconDual: | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|     case Core::HID::NpadStyleIndex::JoyconLeft: |     case Core::HID::NpadStyleIndex::JoyconLeft: | ||||||
|  | @ -1304,7 +1304,7 @@ void ConfigureInputPlayer::UpdateMotionButtons() { | ||||||
| 
 | 
 | ||||||
|     // Show/hide the "Motion 1/2" groupboxes depending on the currently selected controller.
 |     // Show/hide the "Motion 1/2" groupboxes depending on the currently selected controller.
 | ||||||
|     switch (GetControllerTypeFromIndex(ui->comboControllerType->currentIndex())) { |     switch (GetControllerTypeFromIndex(ui->comboControllerType->currentIndex())) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::JoyconLeft: |     case Core::HID::NpadStyleIndex::JoyconLeft: | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|         // Show "Motion 1" and hide "Motion 2".
 |         // Show "Motion 1" and hide "Motion 2".
 | ||||||
|  | @ -1333,11 +1333,11 @@ void ConfigureInputPlayer::UpdateMotionButtons() { | ||||||
| void ConfigureInputPlayer::UpdateControllerButtonNames() { | void ConfigureInputPlayer::UpdateControllerButtonNames() { | ||||||
|     auto layout = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); |     auto layout = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); | ||||||
|     if (debug) { |     if (debug) { | ||||||
|         layout = Core::HID::NpadStyleIndex::ProController; |         layout = Core::HID::NpadStyleIndex::Fullkey; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch (layout) { |     switch (layout) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::JoyconDual: |     case Core::HID::NpadStyleIndex::JoyconDual: | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|     case Core::HID::NpadStyleIndex::JoyconLeft: |     case Core::HID::NpadStyleIndex::JoyconLeft: | ||||||
|  |  | ||||||
|  | @ -244,7 +244,7 @@ void PlayerControlPreview::paintEvent(QPaintEvent* event) { | ||||||
|     case Core::HID::NpadStyleIndex::GameCube: |     case Core::HID::NpadStyleIndex::GameCube: | ||||||
|         DrawGCController(p, center); |         DrawGCController(p, center); | ||||||
|         break; |         break; | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     default: |     default: | ||||||
|         DrawProController(p, center); |         DrawProController(p, center); | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|  | @ -3988,7 +3988,7 @@ void GMainWindow::OnToggleDockedMode() { | ||||||
|                              tr("Handheld controller can't be used on docked mode. Pro " |                              tr("Handheld controller can't be used on docked mode. Pro " | ||||||
|                                 "controller will be selected.")); |                                 "controller will be selected.")); | ||||||
|         handheld->Disconnect(); |         handheld->Disconnect(); | ||||||
|         player_1->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController); |         player_1->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Fullkey); | ||||||
|         player_1->Connect(); |         player_1->Connect(); | ||||||
|         controller_dialog->refreshConfiguration(); |         controller_dialog->refreshConfiguration(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -66,7 +66,7 @@ void ControllerNavigation::ControllerUpdateButton() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch (controller_type) { |     switch (controller_type) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::JoyconDual: |     case Core::HID::NpadStyleIndex::JoyconDual: | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|     case Core::HID::NpadStyleIndex::GameCube: |     case Core::HID::NpadStyleIndex::GameCube: | ||||||
|  | @ -116,7 +116,7 @@ void ControllerNavigation::ControllerUpdateStick() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch (controller_type) { |     switch (controller_type) { | ||||||
|     case Core::HID::NpadStyleIndex::ProController: |     case Core::HID::NpadStyleIndex::Fullkey: | ||||||
|     case Core::HID::NpadStyleIndex::JoyconDual: |     case Core::HID::NpadStyleIndex::JoyconDual: | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|     case Core::HID::NpadStyleIndex::GameCube: |     case Core::HID::NpadStyleIndex::GameCube: | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 german77
						german77