hid: core: Properly emulate controller color and battery level
This commit is contained in:
parent
cd5bbf0f04
commit
301702e548
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…
Reference in a new issue