forked from eden-emu/eden
		
	hid: core: Properly emulate controller color and battery level
This commit is contained in:
		
							parent
							
								
									6907d1758d
								
							
						
					
					
						commit
						67f4daf029
					
				
					 4 changed files with 97 additions and 25 deletions
				
			
		|  | @ -84,18 +84,19 @@ void EmulatedController::ReloadFromSettings() { | ||||||
|         motion_params[index] = Common::ParamPackage(player.motions[index]); |         motion_params[index] = Common::ParamPackage(player.motions[index]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     controller.colors_state.fullkey = { | ||||||
|  |         .body = GetNpadColor(player.body_color_left), | ||||||
|  |         .button = GetNpadColor(player.button_color_left), | ||||||
|  |     }; | ||||||
|     controller.colors_state.left = { |     controller.colors_state.left = { | ||||||
|         .body = player.body_color_left, |         .body = GetNpadColor(player.body_color_left), | ||||||
|         .button = player.button_color_left, |         .button = GetNpadColor(player.button_color_left), | ||||||
|     }; |     }; | ||||||
| 
 |     controller.colors_state.left = { | ||||||
|     controller.colors_state.right = { |         .body = GetNpadColor(player.body_color_right), | ||||||
|         .body = player.body_color_right, |         .button = GetNpadColor(player.button_color_right), | ||||||
|         .button = player.button_color_right, |  | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     controller.colors_state.fullkey = controller.colors_state.left; |  | ||||||
| 
 |  | ||||||
|     // Other or debug controller should always be a pro controller
 |     // Other or debug controller should always be a pro controller
 | ||||||
|     if (npad_id_type != NpadIdType::Other) { |     if (npad_id_type != NpadIdType::Other) { | ||||||
|         SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type)); |         SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type)); | ||||||
|  | @ -1310,6 +1311,15 @@ const CameraState& EmulatedController::GetCamera() const { | ||||||
|     return controller.camera_state; |     return controller.camera_state; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | NpadColor EmulatedController::GetNpadColor(u32 color) { | ||||||
|  |     return { | ||||||
|  |         .r = static_cast<u8>((color >> 16) & 0xFF), | ||||||
|  |         .g = static_cast<u8>((color >> 8) & 0xFF), | ||||||
|  |         .b = static_cast<u8>(color & 0xFF), | ||||||
|  |         .a = 0xff, | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npad_service_update) { | void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npad_service_update) { | ||||||
|     std::scoped_lock lock{callback_mutex}; |     std::scoped_lock lock{callback_mutex}; | ||||||
|     for (const auto& poller_pair : callback_list) { |     for (const auto& poller_pair : callback_list) { | ||||||
|  |  | ||||||
|  | @ -424,6 +424,13 @@ private: | ||||||
|      */ |      */ | ||||||
|     void SetCamera(const Common::Input::CallbackStatus& callback); |     void SetCamera(const Common::Input::CallbackStatus& callback); | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Converts a color format from bgra to rgba | ||||||
|  |      * @param color in bgra format | ||||||
|  |      * @return NpadColor in rgba format | ||||||
|  |      */ | ||||||
|  |     NpadColor GetNpadColor(u32 color); | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Triggers a callback that something has changed on the controller status |      * Triggers a callback that something has changed on the controller status | ||||||
|      * @param type Input type of the event to trigger |      * @param type Input type of the event to trigger | ||||||
|  |  | ||||||
|  | @ -327,10 +327,18 @@ struct TouchState { | ||||||
| }; | }; | ||||||
| static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size"); | static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size"); | ||||||
| 
 | 
 | ||||||
|  | struct NpadColor { | ||||||
|  |     u8 r{}; | ||||||
|  |     u8 g{}; | ||||||
|  |     u8 b{}; | ||||||
|  |     u8 a{}; | ||||||
|  | }; | ||||||
|  | static_assert(sizeof(NpadColor) == 4, "NpadColor is an invalid size"); | ||||||
|  | 
 | ||||||
| // This is nn::hid::NpadControllerColor
 | // This is nn::hid::NpadControllerColor
 | ||||||
| struct NpadControllerColor { | struct NpadControllerColor { | ||||||
|     u32 body{}; |     NpadColor body{}; | ||||||
|     u32 button{}; |     NpadColor button{}; | ||||||
| }; | }; | ||||||
| static_assert(sizeof(NpadControllerColor) == 8, "NpadControllerColor is an invalid size"); | static_assert(sizeof(NpadControllerColor) == 8, "NpadControllerColor is an invalid size"); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -163,28 +163,51 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | ||||||
|     } |     } | ||||||
|     LOG_DEBUG(Service_HID, "Npad connected {}", npad_id); |     LOG_DEBUG(Service_HID, "Npad connected {}", npad_id); | ||||||
|     const auto controller_type = controller.device->GetNpadStyleIndex(); |     const auto controller_type = controller.device->GetNpadStyleIndex(); | ||||||
|  |     const auto& body_colors = controller.device->GetColors(); | ||||||
|  |     const auto& battery_level = controller.device->GetBattery(); | ||||||
|     auto* shared_memory = controller.shared_memory; |     auto* shared_memory = controller.shared_memory; | ||||||
|     if (controller_type == Core::HID::NpadStyleIndex::None) { |     if (controller_type == Core::HID::NpadStyleIndex::None) { | ||||||
|         controller.styleset_changed_event->GetWritableEvent().Signal(); |         controller.styleset_changed_event->GetWritableEvent().Signal(); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     // Reset memory values
 | ||||||
|     shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None; |     shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None; | ||||||
|     shared_memory->device_type.raw = 0; |     shared_memory->device_type.raw = 0; | ||||||
|     shared_memory->system_properties.raw = 0; |     shared_memory->system_properties.raw = 0; | ||||||
|  |     shared_memory->joycon_color.attribute = ColorAttribute::NoController; | ||||||
|  |     shared_memory->joycon_color.attribute = ColorAttribute::NoController; | ||||||
|  |     shared_memory->fullkey_color = {}; | ||||||
|  |     shared_memory->joycon_color.left = {}; | ||||||
|  |     shared_memory->joycon_color.right = {}; | ||||||
|  |     shared_memory->battery_level_dual = {}; | ||||||
|  |     shared_memory->battery_level_left = {}; | ||||||
|  |     shared_memory->battery_level_right = {}; | ||||||
|  | 
 | ||||||
|     switch (controller_type) { |     switch (controller_type) { | ||||||
|     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::ProController: | ||||||
|  |         shared_memory->fullkey_color.attribute = ColorAttribute::Ok; | ||||||
|  |         shared_memory->fullkey_color.fullkey = body_colors.fullkey; | ||||||
|  |         shared_memory->battery_level_dual = battery_level.dual.battery_level; | ||||||
|         shared_memory->style_tag.fullkey.Assign(1); |         shared_memory->style_tag.fullkey.Assign(1); | ||||||
|         shared_memory->device_type.fullkey.Assign(1); |         shared_memory->device_type.fullkey.Assign(1); | ||||||
|         shared_memory->system_properties.is_vertical.Assign(1); |         shared_memory->system_properties.is_vertical.Assign(1); | ||||||
|         shared_memory->system_properties.use_plus.Assign(1); |         shared_memory->system_properties.use_plus.Assign(1); | ||||||
|         shared_memory->system_properties.use_minus.Assign(1); |         shared_memory->system_properties.use_minus.Assign(1); | ||||||
|  |         shared_memory->system_properties.is_charging_joy_dual.Assign( | ||||||
|  |             battery_level.dual.is_charging); | ||||||
|         shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::SwitchProController; |         shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::SwitchProController; | ||||||
|         shared_memory->sixaxis_fullkey_properties.is_newly_assigned.Assign(1); |         shared_memory->sixaxis_fullkey_properties.is_newly_assigned.Assign(1); | ||||||
|         break; |         break; | ||||||
|     case Core::HID::NpadStyleIndex::Handheld: |     case Core::HID::NpadStyleIndex::Handheld: | ||||||
|  |         shared_memory->fullkey_color.attribute = ColorAttribute::Ok; | ||||||
|  |         shared_memory->joycon_color.attribute = ColorAttribute::Ok; | ||||||
|  |         shared_memory->fullkey_color.fullkey = body_colors.fullkey; | ||||||
|  |         shared_memory->joycon_color.left = body_colors.left; | ||||||
|  |         shared_memory->joycon_color.right = body_colors.right; | ||||||
|         shared_memory->style_tag.handheld.Assign(1); |         shared_memory->style_tag.handheld.Assign(1); | ||||||
|         shared_memory->device_type.handheld_left.Assign(1); |         shared_memory->device_type.handheld_left.Assign(1); | ||||||
|         shared_memory->device_type.handheld_right.Assign(1); |         shared_memory->device_type.handheld_right.Assign(1); | ||||||
|  | @ -192,47 +215,86 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | ||||||
|         shared_memory->system_properties.use_plus.Assign(1); |         shared_memory->system_properties.use_plus.Assign(1); | ||||||
|         shared_memory->system_properties.use_minus.Assign(1); |         shared_memory->system_properties.use_minus.Assign(1); | ||||||
|         shared_memory->system_properties.use_directional_buttons.Assign(1); |         shared_memory->system_properties.use_directional_buttons.Assign(1); | ||||||
|  |         shared_memory->system_properties.is_charging_joy_dual.Assign( | ||||||
|  |             battery_level.left.is_charging); | ||||||
|  |         shared_memory->system_properties.is_charging_joy_left.Assign( | ||||||
|  |             battery_level.left.is_charging); | ||||||
|  |         shared_memory->system_properties.is_charging_joy_right.Assign( | ||||||
|  |             battery_level.right.is_charging); | ||||||
|         shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual; |         shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual; | ||||||
|         shared_memory->applet_nfc_xcd.applet_footer.type = |         shared_memory->applet_nfc_xcd.applet_footer.type = | ||||||
|             AppletFooterUiType::HandheldJoyConLeftJoyConRight; |             AppletFooterUiType::HandheldJoyConLeftJoyConRight; | ||||||
|         shared_memory->sixaxis_handheld_properties.is_newly_assigned.Assign(1); |         shared_memory->sixaxis_handheld_properties.is_newly_assigned.Assign(1); | ||||||
|         break; |         break; | ||||||
|     case Core::HID::NpadStyleIndex::JoyconDual: |     case Core::HID::NpadStyleIndex::JoyconDual: | ||||||
|  |         shared_memory->fullkey_color.attribute = ColorAttribute::Ok; | ||||||
|  |         shared_memory->joycon_color.attribute = ColorAttribute::Ok; | ||||||
|         shared_memory->style_tag.joycon_dual.Assign(1); |         shared_memory->style_tag.joycon_dual.Assign(1); | ||||||
|         if (controller.is_dual_left_connected) { |         if (controller.is_dual_left_connected) { | ||||||
|  |             shared_memory->joycon_color.left = body_colors.left; | ||||||
|  |             shared_memory->battery_level_left = battery_level.left.battery_level; | ||||||
|             shared_memory->device_type.joycon_left.Assign(1); |             shared_memory->device_type.joycon_left.Assign(1); | ||||||
|             shared_memory->system_properties.use_minus.Assign(1); |             shared_memory->system_properties.use_minus.Assign(1); | ||||||
|  |             shared_memory->system_properties.is_charging_joy_left.Assign( | ||||||
|  |                 battery_level.left.is_charging); | ||||||
|             shared_memory->sixaxis_dual_left_properties.is_newly_assigned.Assign(1); |             shared_memory->sixaxis_dual_left_properties.is_newly_assigned.Assign(1); | ||||||
|         } |         } | ||||||
|         if (controller.is_dual_right_connected) { |         if (controller.is_dual_right_connected) { | ||||||
|  |             shared_memory->joycon_color.right = body_colors.right; | ||||||
|  |             shared_memory->battery_level_right = battery_level.right.battery_level; | ||||||
|             shared_memory->device_type.joycon_right.Assign(1); |             shared_memory->device_type.joycon_right.Assign(1); | ||||||
|             shared_memory->system_properties.use_plus.Assign(1); |             shared_memory->system_properties.use_plus.Assign(1); | ||||||
|  |             shared_memory->system_properties.is_charging_joy_right.Assign( | ||||||
|  |                 battery_level.right.is_charging); | ||||||
|             shared_memory->sixaxis_dual_right_properties.is_newly_assigned.Assign(1); |             shared_memory->sixaxis_dual_right_properties.is_newly_assigned.Assign(1); | ||||||
|         } |         } | ||||||
|         shared_memory->system_properties.use_directional_buttons.Assign(1); |         shared_memory->system_properties.use_directional_buttons.Assign(1); | ||||||
|         shared_memory->system_properties.is_vertical.Assign(1); |         shared_memory->system_properties.is_vertical.Assign(1); | ||||||
|         shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual; |         shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual; | ||||||
|  | 
 | ||||||
|         if (controller.is_dual_left_connected && controller.is_dual_right_connected) { |         if (controller.is_dual_left_connected && controller.is_dual_right_connected) { | ||||||
|             shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDual; |             shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDual; | ||||||
|  |             shared_memory->fullkey_color.fullkey = body_colors.left; | ||||||
|  |             shared_memory->battery_level_dual = battery_level.left.battery_level; | ||||||
|  |             shared_memory->system_properties.is_charging_joy_dual.Assign( | ||||||
|  |                 battery_level.left.is_charging); | ||||||
|         } else if (controller.is_dual_left_connected) { |         } else if (controller.is_dual_left_connected) { | ||||||
|             shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualLeftOnly; |             shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualLeftOnly; | ||||||
|  |             shared_memory->fullkey_color.fullkey = body_colors.left; | ||||||
|  |             shared_memory->battery_level_dual = battery_level.left.battery_level; | ||||||
|  |             shared_memory->system_properties.is_charging_joy_dual.Assign( | ||||||
|  |                 battery_level.left.is_charging); | ||||||
|         } else { |         } else { | ||||||
|             shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualRightOnly; |             shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualRightOnly; | ||||||
|  |             shared_memory->fullkey_color.fullkey = body_colors.right; | ||||||
|  |             shared_memory->battery_level_dual = battery_level.right.battery_level; | ||||||
|  |             shared_memory->system_properties.is_charging_joy_dual.Assign( | ||||||
|  |                 battery_level.right.is_charging); | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|     case Core::HID::NpadStyleIndex::JoyconLeft: |     case Core::HID::NpadStyleIndex::JoyconLeft: | ||||||
|  |         shared_memory->joycon_color.attribute = ColorAttribute::Ok; | ||||||
|  |         shared_memory->joycon_color.left = body_colors.left; | ||||||
|  |         shared_memory->battery_level_dual = battery_level.left.battery_level; | ||||||
|         shared_memory->style_tag.joycon_left.Assign(1); |         shared_memory->style_tag.joycon_left.Assign(1); | ||||||
|         shared_memory->device_type.joycon_left.Assign(1); |         shared_memory->device_type.joycon_left.Assign(1); | ||||||
|         shared_memory->system_properties.is_horizontal.Assign(1); |         shared_memory->system_properties.is_horizontal.Assign(1); | ||||||
|         shared_memory->system_properties.use_minus.Assign(1); |         shared_memory->system_properties.use_minus.Assign(1); | ||||||
|  |         shared_memory->system_properties.is_charging_joy_left.Assign( | ||||||
|  |             battery_level.left.is_charging); | ||||||
|         shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal; |         shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal; | ||||||
|         shared_memory->sixaxis_left_properties.is_newly_assigned.Assign(1); |         shared_memory->sixaxis_left_properties.is_newly_assigned.Assign(1); | ||||||
|         break; |         break; | ||||||
|     case Core::HID::NpadStyleIndex::JoyconRight: |     case Core::HID::NpadStyleIndex::JoyconRight: | ||||||
|  |         shared_memory->joycon_color.attribute = ColorAttribute::Ok; | ||||||
|  |         shared_memory->joycon_color.right = body_colors.right; | ||||||
|  |         shared_memory->battery_level_right = battery_level.right.battery_level; | ||||||
|         shared_memory->style_tag.joycon_right.Assign(1); |         shared_memory->style_tag.joycon_right.Assign(1); | ||||||
|         shared_memory->device_type.joycon_right.Assign(1); |         shared_memory->device_type.joycon_right.Assign(1); | ||||||
|         shared_memory->system_properties.is_horizontal.Assign(1); |         shared_memory->system_properties.is_horizontal.Assign(1); | ||||||
|         shared_memory->system_properties.use_plus.Assign(1); |         shared_memory->system_properties.use_plus.Assign(1); | ||||||
|  |         shared_memory->system_properties.is_charging_joy_right.Assign( | ||||||
|  |             battery_level.right.is_charging); | ||||||
|         shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyRightHorizontal; |         shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyRightHorizontal; | ||||||
|         shared_memory->sixaxis_right_properties.is_newly_assigned.Assign(1); |         shared_memory->sixaxis_right_properties.is_newly_assigned.Assign(1); | ||||||
|         break; |         break; | ||||||
|  | @ -269,21 +331,6 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const auto& body_colors = controller.device->GetColors(); |  | ||||||
| 
 |  | ||||||
|     shared_memory->fullkey_color.attribute = ColorAttribute::Ok; |  | ||||||
|     shared_memory->fullkey_color.fullkey = body_colors.fullkey; |  | ||||||
| 
 |  | ||||||
|     shared_memory->joycon_color.attribute = ColorAttribute::Ok; |  | ||||||
|     shared_memory->joycon_color.left = body_colors.left; |  | ||||||
|     shared_memory->joycon_color.right = body_colors.right; |  | ||||||
| 
 |  | ||||||
|     // TODO: Investigate when we should report all batery types
 |  | ||||||
|     const auto& battery_level = controller.device->GetBattery(); |  | ||||||
|     shared_memory->battery_level_dual = battery_level.dual.battery_level; |  | ||||||
|     shared_memory->battery_level_left = battery_level.left.battery_level; |  | ||||||
|     shared_memory->battery_level_right = battery_level.right.battery_level; |  | ||||||
| 
 |  | ||||||
|     controller.is_connected = true; |     controller.is_connected = true; | ||||||
|     controller.device->Connect(); |     controller.device->Connect(); | ||||||
|     SignalStyleSetChangedEvent(npad_id); |     SignalStyleSetChangedEvent(npad_id); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Narr the Reg
						Narr the Reg