forked from suyu/suyu
Merge pull request #5326 from german77/hidUpdate1
HID: Update the HID service to match more closely to switchbrew part 1
This commit is contained in:
commit
61bf850f3d
11 changed files with 408 additions and 170 deletions
|
@ -37,7 +37,7 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters(
|
||||||
.border_colors = std::move(identification_colors),
|
.border_colors = std::move(identification_colors),
|
||||||
.enable_explain_text = enable_text,
|
.enable_explain_text = enable_text,
|
||||||
.explain_text = std::move(text),
|
.explain_text = std::move(text),
|
||||||
.allow_pro_controller = npad_style_set.pro_controller == 1,
|
.allow_pro_controller = npad_style_set.fullkey == 1,
|
||||||
.allow_handheld = npad_style_set.handheld == 1,
|
.allow_handheld = npad_style_set.handheld == 1,
|
||||||
.allow_dual_joycons = npad_style_set.joycon_dual == 1,
|
.allow_dual_joycons = npad_style_set.joycon_dual == 1,
|
||||||
.allow_left_joycon = npad_style_set.joycon_left == 1,
|
.allow_left_joycon = npad_style_set.joycon_left == 1,
|
||||||
|
|
|
@ -39,16 +39,25 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
|
||||||
cur_entry.sampling_number2 = cur_entry.sampling_number;
|
cur_entry.sampling_number2 = cur_entry.sampling_number;
|
||||||
|
|
||||||
cur_entry.key.fill(0);
|
cur_entry.key.fill(0);
|
||||||
cur_entry.modifier = 0;
|
|
||||||
if (Settings::values.keyboard_enabled) {
|
if (Settings::values.keyboard_enabled) {
|
||||||
for (std::size_t i = 0; i < keyboard_keys.size(); ++i) {
|
for (std::size_t i = 0; i < keyboard_keys.size(); ++i) {
|
||||||
auto& entry = cur_entry.key[i / KEYS_PER_BYTE];
|
auto& entry = cur_entry.key[i / KEYS_PER_BYTE];
|
||||||
entry = static_cast<u8>(entry | (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE)));
|
entry = static_cast<u8>(entry | (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < keyboard_mods.size(); ++i) {
|
using namespace Settings::NativeKeyboard;
|
||||||
cur_entry.modifier |= (keyboard_mods[i]->GetStatus() << i);
|
|
||||||
}
|
// TODO: Assign the correct key to all modifiers
|
||||||
|
cur_entry.modifier.control.Assign(keyboard_mods[LeftControl]->GetStatus());
|
||||||
|
cur_entry.modifier.shift.Assign(keyboard_mods[LeftShift]->GetStatus());
|
||||||
|
cur_entry.modifier.left_alt.Assign(keyboard_mods[LeftAlt]->GetStatus());
|
||||||
|
cur_entry.modifier.right_alt.Assign(keyboard_mods[RightAlt]->GetStatus());
|
||||||
|
cur_entry.modifier.gui.Assign(0);
|
||||||
|
cur_entry.modifier.caps_lock.Assign(keyboard_mods[CapsLock]->GetStatus());
|
||||||
|
cur_entry.modifier.scroll_lock.Assign(keyboard_mods[ScrollLock]->GetStatus());
|
||||||
|
cur_entry.modifier.num_lock.Assign(keyboard_mods[NumLock]->GetStatus());
|
||||||
|
cur_entry.modifier.katakana.Assign(0);
|
||||||
|
cur_entry.modifier.hiragana.Assign(0);
|
||||||
}
|
}
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
|
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include "common/bit_field.h"
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
|
@ -31,12 +32,28 @@ public:
|
||||||
void OnLoadInputDevices() override;
|
void OnLoadInputDevices() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Modifiers {
|
||||||
|
union {
|
||||||
|
u32_le raw{};
|
||||||
|
BitField<0, 1, u32> control;
|
||||||
|
BitField<1, 1, u32> shift;
|
||||||
|
BitField<2, 1, u32> left_alt;
|
||||||
|
BitField<3, 1, u32> right_alt;
|
||||||
|
BitField<4, 1, u32> gui;
|
||||||
|
BitField<8, 1, u32> caps_lock;
|
||||||
|
BitField<9, 1, u32> scroll_lock;
|
||||||
|
BitField<10, 1, u32> num_lock;
|
||||||
|
BitField<11, 1, u32> katakana;
|
||||||
|
BitField<12, 1, u32> hiragana;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Modifiers) == 0x4, "Modifiers is an invalid size");
|
||||||
|
|
||||||
struct KeyboardState {
|
struct KeyboardState {
|
||||||
s64_le sampling_number;
|
s64_le sampling_number;
|
||||||
s64_le sampling_number2;
|
s64_le sampling_number2;
|
||||||
|
|
||||||
s32_le modifier;
|
Modifiers modifier;
|
||||||
s32_le attribute;
|
|
||||||
std::array<u8, 32> key;
|
std::array<u8, 32> key;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(KeyboardState) == 0x38, "KeyboardState is an invalid size");
|
static_assert(sizeof(KeyboardState) == 0x38, "KeyboardState is an invalid size");
|
||||||
|
|
|
@ -36,6 +36,7 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
cur_entry.sampling_number = last_entry.sampling_number + 1;
|
cur_entry.sampling_number = last_entry.sampling_number + 1;
|
||||||
cur_entry.sampling_number2 = cur_entry.sampling_number;
|
cur_entry.sampling_number2 = cur_entry.sampling_number;
|
||||||
|
|
||||||
|
cur_entry.attribute.raw = 0;
|
||||||
if (Settings::values.mouse_enabled) {
|
if (Settings::values.mouse_enabled) {
|
||||||
const auto [px, py, sx, sy] = mouse_device->GetStatus();
|
const auto [px, py, sx, sy] = mouse_device->GetStatus();
|
||||||
const auto x = static_cast<s32>(px * Layout::ScreenUndocked::Width);
|
const auto x = static_cast<s32>(px * Layout::ScreenUndocked::Width);
|
||||||
|
@ -46,10 +47,14 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
cur_entry.delta_y = y - last_entry.y;
|
cur_entry.delta_y = y - last_entry.y;
|
||||||
cur_entry.mouse_wheel_x = sx;
|
cur_entry.mouse_wheel_x = sx;
|
||||||
cur_entry.mouse_wheel_y = sy;
|
cur_entry.mouse_wheel_y = sy;
|
||||||
|
cur_entry.attribute.is_connected.Assign(1);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < mouse_button_devices.size(); ++i) {
|
using namespace Settings::NativeMouseButton;
|
||||||
cur_entry.button |= (mouse_button_devices[i]->GetStatus() << i);
|
cur_entry.button.left.Assign(mouse_button_devices[Left]->GetStatus());
|
||||||
}
|
cur_entry.button.right.Assign(mouse_button_devices[Right]->GetStatus());
|
||||||
|
cur_entry.button.middle.Assign(mouse_button_devices[Middle]->GetStatus());
|
||||||
|
cur_entry.button.forward.Assign(mouse_button_devices[Forward]->GetStatus());
|
||||||
|
cur_entry.button.back.Assign(mouse_button_devices[Back]->GetStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
|
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include "common/bit_field.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/frontend/input.h"
|
#include "core/frontend/input.h"
|
||||||
|
@ -30,6 +31,27 @@ public:
|
||||||
void OnLoadInputDevices() override;
|
void OnLoadInputDevices() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Buttons {
|
||||||
|
union {
|
||||||
|
u32_le raw{};
|
||||||
|
BitField<0, 1, u32> left;
|
||||||
|
BitField<1, 1, u32> right;
|
||||||
|
BitField<2, 1, u32> middle;
|
||||||
|
BitField<3, 1, u32> forward;
|
||||||
|
BitField<4, 1, u32> back;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Buttons) == 0x4, "Buttons is an invalid size");
|
||||||
|
|
||||||
|
struct Attributes {
|
||||||
|
union {
|
||||||
|
u32_le raw{};
|
||||||
|
BitField<0, 1, u32> transferable;
|
||||||
|
BitField<1, 1, u32> is_connected;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size");
|
||||||
|
|
||||||
struct MouseState {
|
struct MouseState {
|
||||||
s64_le sampling_number;
|
s64_le sampling_number;
|
||||||
s64_le sampling_number2;
|
s64_le sampling_number2;
|
||||||
|
@ -39,8 +61,8 @@ private:
|
||||||
s32_le delta_y;
|
s32_le delta_y;
|
||||||
s32_le mouse_wheel_x;
|
s32_le mouse_wheel_x;
|
||||||
s32_le mouse_wheel_y;
|
s32_le mouse_wheel_y;
|
||||||
s32_le button;
|
Buttons button;
|
||||||
s32_le attribute;
|
Attributes attribute;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(MouseState) == 0x30, "MouseState is an invalid size");
|
static_assert(sizeof(MouseState) == 0x30, "MouseState is an invalid size");
|
||||||
|
|
||||||
|
|
|
@ -157,76 +157,83 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
|
||||||
styleset_changed_events[controller_idx]->GetWritableEvent()->Signal();
|
styleset_changed_events[controller_idx]->GetWritableEvent()->Signal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
controller.joy_styles.raw = 0; // Zero out
|
controller.style_set.raw = 0; // Zero out
|
||||||
controller.device_type.raw = 0;
|
controller.device_type.raw = 0;
|
||||||
controller.properties.raw = 0;
|
controller.system_properties.raw = 0;
|
||||||
switch (controller_type) {
|
switch (controller_type) {
|
||||||
case NPadControllerType::None:
|
case NPadControllerType::None:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::ProController:
|
case NPadControllerType::ProController:
|
||||||
controller.joy_styles.pro_controller.Assign(1);
|
controller.style_set.fullkey.Assign(1);
|
||||||
controller.device_type.pro_controller.Assign(1);
|
controller.device_type.fullkey.Assign(1);
|
||||||
controller.properties.is_vertical.Assign(1);
|
controller.system_properties.is_vertical.Assign(1);
|
||||||
controller.properties.use_plus.Assign(1);
|
controller.system_properties.use_plus.Assign(1);
|
||||||
controller.properties.use_minus.Assign(1);
|
controller.system_properties.use_minus.Assign(1);
|
||||||
controller.pad_assignment = NpadAssignments::Single;
|
controller.assignment_mode = NpadAssignments::Single;
|
||||||
|
controller.footer_type = AppletFooterUiType::SwitchProController;
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::Handheld:
|
case NPadControllerType::Handheld:
|
||||||
controller.joy_styles.handheld.Assign(1);
|
controller.style_set.handheld.Assign(1);
|
||||||
controller.device_type.handheld.Assign(1);
|
controller.device_type.handheld_left.Assign(1);
|
||||||
controller.properties.is_vertical.Assign(1);
|
controller.device_type.handheld_right.Assign(1);
|
||||||
controller.properties.use_plus.Assign(1);
|
controller.system_properties.is_vertical.Assign(1);
|
||||||
controller.properties.use_minus.Assign(1);
|
controller.system_properties.use_plus.Assign(1);
|
||||||
controller.pad_assignment = NpadAssignments::Dual;
|
controller.system_properties.use_minus.Assign(1);
|
||||||
|
controller.assignment_mode = NpadAssignments::Dual;
|
||||||
|
controller.footer_type = AppletFooterUiType::HandheldJoyConLeftJoyConRight;
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::JoyDual:
|
case NPadControllerType::JoyDual:
|
||||||
controller.joy_styles.joycon_dual.Assign(1);
|
controller.style_set.joycon_dual.Assign(1);
|
||||||
controller.device_type.joycon_left.Assign(1);
|
controller.device_type.joycon_left.Assign(1);
|
||||||
controller.device_type.joycon_right.Assign(1);
|
controller.device_type.joycon_right.Assign(1);
|
||||||
controller.properties.is_vertical.Assign(1);
|
controller.system_properties.is_vertical.Assign(1);
|
||||||
controller.properties.use_plus.Assign(1);
|
controller.system_properties.use_plus.Assign(1);
|
||||||
controller.properties.use_minus.Assign(1);
|
controller.system_properties.use_minus.Assign(1);
|
||||||
controller.pad_assignment = NpadAssignments::Dual;
|
controller.assignment_mode = NpadAssignments::Dual;
|
||||||
|
controller.footer_type = AppletFooterUiType::JoyDual;
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::JoyLeft:
|
case NPadControllerType::JoyLeft:
|
||||||
controller.joy_styles.joycon_left.Assign(1);
|
controller.style_set.joycon_left.Assign(1);
|
||||||
controller.device_type.joycon_left.Assign(1);
|
controller.device_type.joycon_left.Assign(1);
|
||||||
controller.properties.is_horizontal.Assign(1);
|
controller.system_properties.is_horizontal.Assign(1);
|
||||||
controller.properties.use_minus.Assign(1);
|
controller.system_properties.use_minus.Assign(1);
|
||||||
controller.pad_assignment = NpadAssignments::Single;
|
controller.assignment_mode = NpadAssignments::Single;
|
||||||
|
controller.footer_type = AppletFooterUiType::JoyLeftHorizontal;
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::JoyRight:
|
case NPadControllerType::JoyRight:
|
||||||
controller.joy_styles.joycon_right.Assign(1);
|
controller.style_set.joycon_right.Assign(1);
|
||||||
controller.device_type.joycon_right.Assign(1);
|
controller.device_type.joycon_right.Assign(1);
|
||||||
controller.properties.is_horizontal.Assign(1);
|
controller.system_properties.is_horizontal.Assign(1);
|
||||||
controller.properties.use_plus.Assign(1);
|
controller.system_properties.use_plus.Assign(1);
|
||||||
controller.pad_assignment = NpadAssignments::Single;
|
controller.assignment_mode = NpadAssignments::Single;
|
||||||
|
controller.footer_type = AppletFooterUiType::JoyRightHorizontal;
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::Pokeball:
|
case NPadControllerType::Pokeball:
|
||||||
controller.joy_styles.pokeball.Assign(1);
|
controller.style_set.palma.Assign(1);
|
||||||
controller.device_type.pokeball.Assign(1);
|
controller.device_type.palma.Assign(1);
|
||||||
controller.pad_assignment = NpadAssignments::Single;
|
controller.assignment_mode = NpadAssignments::Single;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
controller.single_color_error = ColorReadError::ReadOk;
|
controller.fullkey_color.attribute = ColorAttributes::Ok;
|
||||||
controller.single_color.body_color = 0;
|
controller.fullkey_color.fullkey.body = 0;
|
||||||
controller.single_color.button_color = 0;
|
controller.fullkey_color.fullkey.button = 0;
|
||||||
|
|
||||||
controller.dual_color_error = ColorReadError::ReadOk;
|
controller.joycon_color.attribute = ColorAttributes::Ok;
|
||||||
controller.left_color.body_color =
|
controller.joycon_color.left.body =
|
||||||
Settings::values.players.GetValue()[controller_idx].body_color_left;
|
Settings::values.players.GetValue()[controller_idx].body_color_left;
|
||||||
controller.left_color.button_color =
|
controller.joycon_color.left.button =
|
||||||
Settings::values.players.GetValue()[controller_idx].button_color_left;
|
Settings::values.players.GetValue()[controller_idx].button_color_left;
|
||||||
controller.right_color.body_color =
|
controller.joycon_color.right.body =
|
||||||
Settings::values.players.GetValue()[controller_idx].body_color_right;
|
Settings::values.players.GetValue()[controller_idx].body_color_right;
|
||||||
controller.right_color.button_color =
|
controller.joycon_color.right.button =
|
||||||
Settings::values.players.GetValue()[controller_idx].button_color_right;
|
Settings::values.players.GetValue()[controller_idx].button_color_right;
|
||||||
|
|
||||||
controller.battery_level[0] = BATTERY_FULL;
|
// TODO: Investigate when we should report all batery types
|
||||||
controller.battery_level[1] = BATTERY_FULL;
|
controller.battery_level_dual = BATTERY_FULL;
|
||||||
controller.battery_level[2] = BATTERY_FULL;
|
controller.battery_level_left = BATTERY_FULL;
|
||||||
|
controller.battery_level_right = BATTERY_FULL;
|
||||||
|
|
||||||
SignalStyleSetChangedEvent(IndexToNPad(controller_idx));
|
SignalStyleSetChangedEvent(IndexToNPad(controller_idx));
|
||||||
}
|
}
|
||||||
|
@ -251,8 +258,8 @@ void Controller_NPad::OnInit() {
|
||||||
style.joycon_left.Assign(1);
|
style.joycon_left.Assign(1);
|
||||||
style.joycon_right.Assign(1);
|
style.joycon_right.Assign(1);
|
||||||
style.joycon_dual.Assign(1);
|
style.joycon_dual.Assign(1);
|
||||||
style.pro_controller.Assign(1);
|
style.fullkey.Assign(1);
|
||||||
style.pokeball.Assign(1);
|
style.palma.Assign(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::transform(Settings::values.players.GetValue().begin(),
|
std::transform(Settings::values.players.GetValue().begin(),
|
||||||
|
@ -406,13 +413,10 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
}
|
}
|
||||||
for (std::size_t i = 0; i < shared_memory_entries.size(); ++i) {
|
for (std::size_t i = 0; i < shared_memory_entries.size(); ++i) {
|
||||||
auto& npad = shared_memory_entries[i];
|
auto& npad = shared_memory_entries[i];
|
||||||
const std::array<NPadGeneric*, 7> controller_npads{&npad.main_controller_states,
|
const std::array<NPadGeneric*, 7> controller_npads{
|
||||||
&npad.handheld_states,
|
&npad.fullkey_states, &npad.handheld_states, &npad.joy_dual_states,
|
||||||
&npad.dual_states,
|
&npad.joy_left_states, &npad.joy_right_states, &npad.palma_states,
|
||||||
&npad.left_joy_states,
|
&npad.system_ext_states};
|
||||||
&npad.right_joy_states,
|
|
||||||
&npad.pokeball_states,
|
|
||||||
&npad.libnx};
|
|
||||||
|
|
||||||
for (auto* main_controller : controller_npads) {
|
for (auto* main_controller : controller_npads) {
|
||||||
main_controller->common.entry_count = 16;
|
main_controller->common.entry_count = 16;
|
||||||
|
@ -442,19 +446,19 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
auto& pad_state = npad_pad_states[npad_index];
|
auto& pad_state = npad_pad_states[npad_index];
|
||||||
|
|
||||||
auto& main_controller =
|
auto& main_controller =
|
||||||
npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index];
|
npad.fullkey_states.npad[npad.fullkey_states.common.last_entry_index];
|
||||||
auto& handheld_entry =
|
auto& handheld_entry =
|
||||||
npad.handheld_states.npad[npad.handheld_states.common.last_entry_index];
|
npad.handheld_states.npad[npad.handheld_states.common.last_entry_index];
|
||||||
auto& dual_entry = npad.dual_states.npad[npad.dual_states.common.last_entry_index];
|
auto& dual_entry = npad.joy_dual_states.npad[npad.joy_dual_states.common.last_entry_index];
|
||||||
auto& left_entry = npad.left_joy_states.npad[npad.left_joy_states.common.last_entry_index];
|
auto& left_entry = npad.joy_left_states.npad[npad.joy_left_states.common.last_entry_index];
|
||||||
auto& right_entry =
|
auto& right_entry =
|
||||||
npad.right_joy_states.npad[npad.right_joy_states.common.last_entry_index];
|
npad.joy_right_states.npad[npad.joy_right_states.common.last_entry_index];
|
||||||
auto& pokeball_entry =
|
auto& pokeball_entry = npad.palma_states.npad[npad.palma_states.common.last_entry_index];
|
||||||
npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index];
|
auto& libnx_entry =
|
||||||
auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index];
|
npad.system_ext_states.npad[npad.system_ext_states.common.last_entry_index];
|
||||||
|
|
||||||
libnx_entry.connection_status.raw = 0;
|
libnx_entry.connection_status.raw = 0;
|
||||||
libnx_entry.connection_status.IsConnected.Assign(1);
|
libnx_entry.connection_status.is_connected.Assign(1);
|
||||||
|
|
||||||
switch (controller_type) {
|
switch (controller_type) {
|
||||||
case NPadControllerType::None:
|
case NPadControllerType::None:
|
||||||
|
@ -462,67 +466,67 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::ProController:
|
case NPadControllerType::ProController:
|
||||||
main_controller.connection_status.raw = 0;
|
main_controller.connection_status.raw = 0;
|
||||||
main_controller.connection_status.IsConnected.Assign(1);
|
main_controller.connection_status.is_connected.Assign(1);
|
||||||
main_controller.connection_status.IsWired.Assign(1);
|
main_controller.connection_status.is_wired.Assign(1);
|
||||||
main_controller.pad.pad_states.raw = pad_state.pad_states.raw;
|
main_controller.pad.pad_states.raw = pad_state.pad_states.raw;
|
||||||
main_controller.pad.l_stick = pad_state.l_stick;
|
main_controller.pad.l_stick = pad_state.l_stick;
|
||||||
main_controller.pad.r_stick = pad_state.r_stick;
|
main_controller.pad.r_stick = pad_state.r_stick;
|
||||||
|
|
||||||
libnx_entry.connection_status.IsWired.Assign(1);
|
libnx_entry.connection_status.is_wired.Assign(1);
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::Handheld:
|
case NPadControllerType::Handheld:
|
||||||
handheld_entry.connection_status.raw = 0;
|
handheld_entry.connection_status.raw = 0;
|
||||||
handheld_entry.connection_status.IsConnected.Assign(1);
|
handheld_entry.connection_status.is_connected.Assign(1);
|
||||||
handheld_entry.connection_status.IsWired.Assign(1);
|
handheld_entry.connection_status.is_wired.Assign(1);
|
||||||
handheld_entry.connection_status.IsLeftJoyConnected.Assign(1);
|
handheld_entry.connection_status.is_left_connected.Assign(1);
|
||||||
handheld_entry.connection_status.IsRightJoyConnected.Assign(1);
|
handheld_entry.connection_status.is_right_connected.Assign(1);
|
||||||
handheld_entry.connection_status.IsLeftJoyWired.Assign(1);
|
handheld_entry.connection_status.is_left_wired.Assign(1);
|
||||||
handheld_entry.connection_status.IsRightJoyWired.Assign(1);
|
handheld_entry.connection_status.is_right_wired.Assign(1);
|
||||||
handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
||||||
handheld_entry.pad.l_stick = pad_state.l_stick;
|
handheld_entry.pad.l_stick = pad_state.l_stick;
|
||||||
handheld_entry.pad.r_stick = pad_state.r_stick;
|
handheld_entry.pad.r_stick = pad_state.r_stick;
|
||||||
|
|
||||||
libnx_entry.connection_status.IsWired.Assign(1);
|
libnx_entry.connection_status.is_wired.Assign(1);
|
||||||
libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
|
libnx_entry.connection_status.is_left_connected.Assign(1);
|
||||||
libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
|
libnx_entry.connection_status.is_right_connected.Assign(1);
|
||||||
libnx_entry.connection_status.IsLeftJoyWired.Assign(1);
|
libnx_entry.connection_status.is_left_wired.Assign(1);
|
||||||
libnx_entry.connection_status.IsRightJoyWired.Assign(1);
|
libnx_entry.connection_status.is_right_wired.Assign(1);
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::JoyDual:
|
case NPadControllerType::JoyDual:
|
||||||
dual_entry.connection_status.raw = 0;
|
dual_entry.connection_status.raw = 0;
|
||||||
dual_entry.connection_status.IsConnected.Assign(1);
|
dual_entry.connection_status.is_connected.Assign(1);
|
||||||
dual_entry.connection_status.IsLeftJoyConnected.Assign(1);
|
dual_entry.connection_status.is_left_connected.Assign(1);
|
||||||
dual_entry.connection_status.IsRightJoyConnected.Assign(1);
|
dual_entry.connection_status.is_right_connected.Assign(1);
|
||||||
dual_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
dual_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
||||||
dual_entry.pad.l_stick = pad_state.l_stick;
|
dual_entry.pad.l_stick = pad_state.l_stick;
|
||||||
dual_entry.pad.r_stick = pad_state.r_stick;
|
dual_entry.pad.r_stick = pad_state.r_stick;
|
||||||
|
|
||||||
libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
|
libnx_entry.connection_status.is_left_connected.Assign(1);
|
||||||
libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
|
libnx_entry.connection_status.is_right_connected.Assign(1);
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::JoyLeft:
|
case NPadControllerType::JoyLeft:
|
||||||
left_entry.connection_status.raw = 0;
|
left_entry.connection_status.raw = 0;
|
||||||
left_entry.connection_status.IsConnected.Assign(1);
|
left_entry.connection_status.is_connected.Assign(1);
|
||||||
left_entry.connection_status.IsLeftJoyConnected.Assign(1);
|
left_entry.connection_status.is_left_connected.Assign(1);
|
||||||
left_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
left_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
||||||
left_entry.pad.l_stick = pad_state.l_stick;
|
left_entry.pad.l_stick = pad_state.l_stick;
|
||||||
left_entry.pad.r_stick = pad_state.r_stick;
|
left_entry.pad.r_stick = pad_state.r_stick;
|
||||||
|
|
||||||
libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
|
libnx_entry.connection_status.is_left_connected.Assign(1);
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::JoyRight:
|
case NPadControllerType::JoyRight:
|
||||||
right_entry.connection_status.raw = 0;
|
right_entry.connection_status.raw = 0;
|
||||||
right_entry.connection_status.IsConnected.Assign(1);
|
right_entry.connection_status.is_connected.Assign(1);
|
||||||
right_entry.connection_status.IsRightJoyConnected.Assign(1);
|
right_entry.connection_status.is_right_connected.Assign(1);
|
||||||
right_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
right_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
||||||
right_entry.pad.l_stick = pad_state.l_stick;
|
right_entry.pad.l_stick = pad_state.l_stick;
|
||||||
right_entry.pad.r_stick = pad_state.r_stick;
|
right_entry.pad.r_stick = pad_state.r_stick;
|
||||||
|
|
||||||
libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
|
libnx_entry.connection_status.is_right_connected.Assign(1);
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::Pokeball:
|
case NPadControllerType::Pokeball:
|
||||||
pokeball_entry.connection_status.raw = 0;
|
pokeball_entry.connection_status.raw = 0;
|
||||||
pokeball_entry.connection_status.IsConnected.Assign(1);
|
pokeball_entry.connection_status.is_connected.Assign(1);
|
||||||
pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
||||||
pokeball_entry.pad.l_stick = pad_state.l_stick;
|
pokeball_entry.pad.l_stick = pad_state.l_stick;
|
||||||
pokeball_entry.pad.r_stick = pad_state.r_stick;
|
pokeball_entry.pad.r_stick = pad_state.r_stick;
|
||||||
|
@ -556,7 +560,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::array<SixAxisGeneric*, 6> controller_sixaxes{
|
const std::array<SixAxisGeneric*, 6> controller_sixaxes{
|
||||||
&npad.sixaxis_full, &npad.sixaxis_handheld, &npad.sixaxis_dual_left,
|
&npad.sixaxis_fullkey, &npad.sixaxis_handheld, &npad.sixaxis_dual_left,
|
||||||
&npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right,
|
&npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -594,7 +598,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& full_sixaxis_entry =
|
auto& full_sixaxis_entry =
|
||||||
npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index];
|
npad.sixaxis_fullkey.sixaxis[npad.sixaxis_fullkey.common.last_entry_index];
|
||||||
auto& handheld_sixaxis_entry =
|
auto& handheld_sixaxis_entry =
|
||||||
npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index];
|
npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index];
|
||||||
auto& dual_left_sixaxis_entry =
|
auto& dual_left_sixaxis_entry =
|
||||||
|
@ -611,7 +615,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::ProController:
|
case NPadControllerType::ProController:
|
||||||
|
full_sixaxis_entry.attribute.raw = 0;
|
||||||
if (sixaxis_sensors_enabled && motions[i][0]) {
|
if (sixaxis_sensors_enabled && motions[i][0]) {
|
||||||
|
full_sixaxis_entry.attribute.is_connected.Assign(1);
|
||||||
full_sixaxis_entry.accel = motion_devices[0].accel;
|
full_sixaxis_entry.accel = motion_devices[0].accel;
|
||||||
full_sixaxis_entry.gyro = motion_devices[0].gyro;
|
full_sixaxis_entry.gyro = motion_devices[0].gyro;
|
||||||
full_sixaxis_entry.rotation = motion_devices[0].rotation;
|
full_sixaxis_entry.rotation = motion_devices[0].rotation;
|
||||||
|
@ -619,7 +625,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::Handheld:
|
case NPadControllerType::Handheld:
|
||||||
|
handheld_sixaxis_entry.attribute.raw = 0;
|
||||||
if (sixaxis_sensors_enabled && motions[i][0]) {
|
if (sixaxis_sensors_enabled && motions[i][0]) {
|
||||||
|
handheld_sixaxis_entry.attribute.is_connected.Assign(1);
|
||||||
handheld_sixaxis_entry.accel = motion_devices[0].accel;
|
handheld_sixaxis_entry.accel = motion_devices[0].accel;
|
||||||
handheld_sixaxis_entry.gyro = motion_devices[0].gyro;
|
handheld_sixaxis_entry.gyro = motion_devices[0].gyro;
|
||||||
handheld_sixaxis_entry.rotation = motion_devices[0].rotation;
|
handheld_sixaxis_entry.rotation = motion_devices[0].rotation;
|
||||||
|
@ -627,8 +635,11 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::JoyDual:
|
case NPadControllerType::JoyDual:
|
||||||
|
dual_left_sixaxis_entry.attribute.raw = 0;
|
||||||
|
dual_right_sixaxis_entry.attribute.raw = 0;
|
||||||
if (sixaxis_sensors_enabled && motions[i][0]) {
|
if (sixaxis_sensors_enabled && motions[i][0]) {
|
||||||
// Set motion for the left joycon
|
// Set motion for the left joycon
|
||||||
|
dual_left_sixaxis_entry.attribute.is_connected.Assign(1);
|
||||||
dual_left_sixaxis_entry.accel = motion_devices[0].accel;
|
dual_left_sixaxis_entry.accel = motion_devices[0].accel;
|
||||||
dual_left_sixaxis_entry.gyro = motion_devices[0].gyro;
|
dual_left_sixaxis_entry.gyro = motion_devices[0].gyro;
|
||||||
dual_left_sixaxis_entry.rotation = motion_devices[0].rotation;
|
dual_left_sixaxis_entry.rotation = motion_devices[0].rotation;
|
||||||
|
@ -636,6 +647,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||||
}
|
}
|
||||||
if (sixaxis_sensors_enabled && motions[i][1]) {
|
if (sixaxis_sensors_enabled && motions[i][1]) {
|
||||||
// Set motion for the right joycon
|
// Set motion for the right joycon
|
||||||
|
dual_right_sixaxis_entry.attribute.is_connected.Assign(1);
|
||||||
dual_right_sixaxis_entry.accel = motion_devices[1].accel;
|
dual_right_sixaxis_entry.accel = motion_devices[1].accel;
|
||||||
dual_right_sixaxis_entry.gyro = motion_devices[1].gyro;
|
dual_right_sixaxis_entry.gyro = motion_devices[1].gyro;
|
||||||
dual_right_sixaxis_entry.rotation = motion_devices[1].rotation;
|
dual_right_sixaxis_entry.rotation = motion_devices[1].rotation;
|
||||||
|
@ -643,7 +655,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::JoyLeft:
|
case NPadControllerType::JoyLeft:
|
||||||
|
left_sixaxis_entry.attribute.raw = 0;
|
||||||
if (sixaxis_sensors_enabled && motions[i][0]) {
|
if (sixaxis_sensors_enabled && motions[i][0]) {
|
||||||
|
left_sixaxis_entry.attribute.is_connected.Assign(1);
|
||||||
left_sixaxis_entry.accel = motion_devices[0].accel;
|
left_sixaxis_entry.accel = motion_devices[0].accel;
|
||||||
left_sixaxis_entry.gyro = motion_devices[0].gyro;
|
left_sixaxis_entry.gyro = motion_devices[0].gyro;
|
||||||
left_sixaxis_entry.rotation = motion_devices[0].rotation;
|
left_sixaxis_entry.rotation = motion_devices[0].rotation;
|
||||||
|
@ -651,7 +665,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NPadControllerType::JoyRight:
|
case NPadControllerType::JoyRight:
|
||||||
|
right_sixaxis_entry.attribute.raw = 0;
|
||||||
if (sixaxis_sensors_enabled && motions[i][1]) {
|
if (sixaxis_sensors_enabled && motions[i][1]) {
|
||||||
|
right_sixaxis_entry.attribute.is_connected.Assign(1);
|
||||||
right_sixaxis_entry.accel = motion_devices[1].accel;
|
right_sixaxis_entry.accel = motion_devices[1].accel;
|
||||||
right_sixaxis_entry.gyro = motion_devices[1].gyro;
|
right_sixaxis_entry.gyro = motion_devices[1].gyro;
|
||||||
right_sixaxis_entry.rotation = motion_devices[1].rotation;
|
right_sixaxis_entry.rotation = motion_devices[1].rotation;
|
||||||
|
@ -717,8 +733,8 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode
|
||||||
void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode) {
|
void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode) {
|
||||||
const std::size_t npad_index = NPadIdToIndex(npad_id);
|
const std::size_t npad_index = NPadIdToIndex(npad_id);
|
||||||
ASSERT(npad_index < shared_memory_entries.size());
|
ASSERT(npad_index < shared_memory_entries.size());
|
||||||
if (shared_memory_entries[npad_index].pad_assignment != assignment_mode) {
|
if (shared_memory_entries[npad_index].assignment_mode != assignment_mode) {
|
||||||
shared_memory_entries[npad_index].pad_assignment = assignment_mode;
|
shared_memory_entries[npad_index].assignment_mode = assignment_mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -926,9 +942,17 @@ void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) {
|
||||||
connected_controllers[npad_index].is_connected = false;
|
connected_controllers[npad_index].is_connected = false;
|
||||||
|
|
||||||
auto& controller = shared_memory_entries[npad_index];
|
auto& controller = shared_memory_entries[npad_index];
|
||||||
controller.joy_styles.raw = 0; // Zero out
|
controller.style_set.raw = 0; // Zero out
|
||||||
controller.device_type.raw = 0;
|
controller.device_type.raw = 0;
|
||||||
controller.properties.raw = 0;
|
controller.system_properties.raw = 0;
|
||||||
|
controller.button_properties.raw = 0;
|
||||||
|
controller.battery_level_dual = 0;
|
||||||
|
controller.battery_level_left = 0;
|
||||||
|
controller.battery_level_right = 0;
|
||||||
|
controller.fullkey_color = {};
|
||||||
|
controller.joycon_color = {};
|
||||||
|
controller.assignment_mode = NpadAssignments::Dual;
|
||||||
|
controller.footer_type = AppletFooterUiType::None;
|
||||||
|
|
||||||
SignalStyleSetChangedEvent(IndexToNPad(npad_index));
|
SignalStyleSetChangedEvent(IndexToNPad(npad_index));
|
||||||
}
|
}
|
||||||
|
@ -1104,7 +1128,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const
|
||||||
[](u32 npad_id) { return npad_id <= MAX_NPAD_ID; })) {
|
[](u32 npad_id) { return npad_id <= MAX_NPAD_ID; })) {
|
||||||
switch (controller) {
|
switch (controller) {
|
||||||
case NPadControllerType::ProController:
|
case NPadControllerType::ProController:
|
||||||
return style.pro_controller;
|
return style.fullkey;
|
||||||
case NPadControllerType::JoyDual:
|
case NPadControllerType::JoyDual:
|
||||||
return style.joycon_dual;
|
return style.joycon_dual;
|
||||||
case NPadControllerType::JoyLeft:
|
case NPadControllerType::JoyLeft:
|
||||||
|
@ -1112,7 +1136,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const
|
||||||
case NPadControllerType::JoyRight:
|
case NPadControllerType::JoyRight:
|
||||||
return style.joycon_right;
|
return style.joycon_right;
|
||||||
case NPadControllerType::Pokeball:
|
case NPadControllerType::Pokeball:
|
||||||
return style.pokeball;
|
return style.palma;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,10 +94,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class NpadCommunicationMode : u64 {
|
enum class NpadCommunicationMode : u64 {
|
||||||
Unknown0 = 0,
|
Mode_5ms = 0,
|
||||||
Unknown1 = 1,
|
Mode_10ms = 1,
|
||||||
Unknown2 = 2,
|
Mode_15ms = 2,
|
||||||
Unknown3 = 3,
|
Default = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DeviceHandle {
|
struct DeviceHandle {
|
||||||
|
@ -112,13 +112,18 @@ public:
|
||||||
union {
|
union {
|
||||||
u32_le raw{};
|
u32_le raw{};
|
||||||
|
|
||||||
BitField<0, 1, u32> pro_controller;
|
BitField<0, 1, u32> fullkey;
|
||||||
BitField<1, 1, u32> handheld;
|
BitField<1, 1, u32> handheld;
|
||||||
BitField<2, 1, u32> joycon_dual;
|
BitField<2, 1, u32> joycon_dual;
|
||||||
BitField<3, 1, u32> joycon_left;
|
BitField<3, 1, u32> joycon_left;
|
||||||
BitField<4, 1, u32> joycon_right;
|
BitField<4, 1, u32> joycon_right;
|
||||||
|
BitField<5, 1, u32> gamecube;
|
||||||
BitField<6, 1, u32> pokeball; // TODO(ogniK): Confirm when possible
|
BitField<6, 1, u32> palma;
|
||||||
|
BitField<7, 1, u32> lark;
|
||||||
|
BitField<8, 1, u32> handheld_lark;
|
||||||
|
BitField<9, 1, u32> lucia;
|
||||||
|
BitField<29, 1, u32> system_ext;
|
||||||
|
BitField<30, 1, u32> system;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
|
static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
|
||||||
|
@ -242,12 +247,32 @@ private:
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
|
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
|
||||||
|
|
||||||
|
enum class ColorAttributes : u32_le {
|
||||||
|
Ok = 0,
|
||||||
|
ReadError = 1,
|
||||||
|
NoController = 2,
|
||||||
|
};
|
||||||
|
static_assert(sizeof(ColorAttributes) == 4, "ColorAttributes is an invalid size");
|
||||||
|
|
||||||
struct ControllerColor {
|
struct ControllerColor {
|
||||||
u32_le body_color;
|
u32_le body;
|
||||||
u32_le button_color;
|
u32_le button;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(ControllerColor) == 8, "ControllerColor is an invalid size");
|
static_assert(sizeof(ControllerColor) == 8, "ControllerColor is an invalid size");
|
||||||
|
|
||||||
|
struct FullKeyColor {
|
||||||
|
ColorAttributes attribute;
|
||||||
|
ControllerColor fullkey;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(FullKeyColor) == 0xC, "FullKeyColor is an invalid size");
|
||||||
|
|
||||||
|
struct JoyconColor {
|
||||||
|
ColorAttributes attribute;
|
||||||
|
ControllerColor left;
|
||||||
|
ControllerColor right;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(JoyconColor) == 0x14, "JoyconColor is an invalid size");
|
||||||
|
|
||||||
struct ControllerPadState {
|
struct ControllerPadState {
|
||||||
union {
|
union {
|
||||||
u64_le raw{};
|
u64_le raw{};
|
||||||
|
@ -289,6 +314,9 @@ private:
|
||||||
|
|
||||||
BitField<26, 1, u64> right_sl;
|
BitField<26, 1, u64> right_sl;
|
||||||
BitField<27, 1, u64> right_sr;
|
BitField<27, 1, u64> right_sr;
|
||||||
|
|
||||||
|
BitField<28, 1, u64> palma;
|
||||||
|
BitField<30, 1, u64> handheld_left_b;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size");
|
static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size");
|
||||||
|
@ -302,12 +330,12 @@ private:
|
||||||
struct ConnectionState {
|
struct ConnectionState {
|
||||||
union {
|
union {
|
||||||
u32_le raw{};
|
u32_le raw{};
|
||||||
BitField<0, 1, u32> IsConnected;
|
BitField<0, 1, u32> is_connected;
|
||||||
BitField<1, 1, u32> IsWired;
|
BitField<1, 1, u32> is_wired;
|
||||||
BitField<2, 1, u32> IsLeftJoyConnected;
|
BitField<2, 1, u32> is_left_connected;
|
||||||
BitField<3, 1, u32> IsLeftJoyWired;
|
BitField<3, 1, u32> is_left_wired;
|
||||||
BitField<4, 1, u32> IsRightJoyConnected;
|
BitField<4, 1, u32> is_right_connected;
|
||||||
BitField<5, 1, u32> IsRightJoyWired;
|
BitField<5, 1, u32> is_right_wired;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size");
|
static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size");
|
||||||
|
@ -333,6 +361,15 @@ private:
|
||||||
};
|
};
|
||||||
static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size");
|
static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size");
|
||||||
|
|
||||||
|
struct SixAxisAttributes {
|
||||||
|
union {
|
||||||
|
u32_le raw{};
|
||||||
|
BitField<0, 1, u32> is_connected;
|
||||||
|
BitField<1, 1, u32> is_interpolated;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SixAxisAttributes) == 4, "SixAxisAttributes is an invalid size");
|
||||||
|
|
||||||
struct SixAxisStates {
|
struct SixAxisStates {
|
||||||
s64_le timestamp{};
|
s64_le timestamp{};
|
||||||
INSERT_PADDING_WORDS(2);
|
INSERT_PADDING_WORDS(2);
|
||||||
|
@ -341,7 +378,8 @@ private:
|
||||||
Common::Vec3f gyro{};
|
Common::Vec3f gyro{};
|
||||||
Common::Vec3f rotation{};
|
Common::Vec3f rotation{};
|
||||||
std::array<Common::Vec3f, 3> orientation{};
|
std::array<Common::Vec3f, 3> orientation{};
|
||||||
s64_le always_one{1};
|
SixAxisAttributes attribute;
|
||||||
|
INSERT_PADDING_BYTES(4); // Reserved
|
||||||
};
|
};
|
||||||
static_assert(sizeof(SixAxisStates) == 0x68, "SixAxisStates is an invalid size");
|
static_assert(sizeof(SixAxisStates) == 0x68, "SixAxisStates is an invalid size");
|
||||||
|
|
||||||
|
@ -351,32 +389,54 @@ private:
|
||||||
};
|
};
|
||||||
static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size");
|
static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size");
|
||||||
|
|
||||||
enum class ColorReadError : u32_le {
|
struct NPadSystemProperties {
|
||||||
ReadOk = 0,
|
|
||||||
ColorDoesntExist = 1,
|
|
||||||
NoController = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NPadProperties {
|
|
||||||
union {
|
union {
|
||||||
s64_le raw{};
|
s64_le raw{};
|
||||||
|
BitField<0, 1, s64> is_charging_joy_dual;
|
||||||
|
BitField<1, 1, s64> is_charging_joy_left;
|
||||||
|
BitField<2, 1, s64> is_charging_joy_right;
|
||||||
|
BitField<3, 1, s64> is_powered_joy_dual;
|
||||||
|
BitField<4, 1, s64> is_powered_joy_left;
|
||||||
|
BitField<5, 1, s64> is_powered_joy_right;
|
||||||
|
BitField<9, 1, s64> is_system_unsupported_button;
|
||||||
|
BitField<10, 1, s64> is_system_ext_unsupported_button;
|
||||||
BitField<11, 1, s64> is_vertical;
|
BitField<11, 1, s64> is_vertical;
|
||||||
BitField<12, 1, s64> is_horizontal;
|
BitField<12, 1, s64> is_horizontal;
|
||||||
BitField<13, 1, s64> use_plus;
|
BitField<13, 1, s64> use_plus;
|
||||||
BitField<14, 1, s64> use_minus;
|
BitField<14, 1, s64> use_minus;
|
||||||
|
BitField<15, 1, s64> use_directional_buttons;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size");
|
||||||
|
|
||||||
|
struct NPadButtonProperties {
|
||||||
|
union {
|
||||||
|
s32_le raw{};
|
||||||
|
BitField<0, 1, s32> is_home_button_protection_enabled;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(NPadButtonProperties) == 0x4, "NPadButtonProperties is an invalid size");
|
||||||
|
|
||||||
struct NPadDevice {
|
struct NPadDevice {
|
||||||
union {
|
union {
|
||||||
u32_le raw{};
|
u32_le raw{};
|
||||||
BitField<0, 1, s32> pro_controller;
|
BitField<0, 1, s32> fullkey;
|
||||||
BitField<1, 1, s32> handheld;
|
BitField<1, 1, s32> debug_pad;
|
||||||
BitField<2, 1, s32> handheld_left;
|
BitField<2, 1, s32> handheld_left;
|
||||||
BitField<3, 1, s32> handheld_right;
|
BitField<3, 1, s32> handheld_right;
|
||||||
BitField<4, 1, s32> joycon_left;
|
BitField<4, 1, s32> joycon_left;
|
||||||
BitField<5, 1, s32> joycon_right;
|
BitField<5, 1, s32> joycon_right;
|
||||||
BitField<6, 1, s32> pokeball;
|
BitField<6, 1, s32> palma;
|
||||||
|
BitField<7, 1, s32> lark_hvc_left;
|
||||||
|
BitField<8, 1, s32> lark_hvc_right;
|
||||||
|
BitField<9, 1, s32> lark_nes_left;
|
||||||
|
BitField<10, 1, s32> lark_nes_right;
|
||||||
|
BitField<11, 1, s32> handheld_lark_hvc_left;
|
||||||
|
BitField<12, 1, s32> handheld_lark_hvc_right;
|
||||||
|
BitField<13, 1, s32> handheld_lark_nes_left;
|
||||||
|
BitField<14, 1, s32> handheld_lark_nes_right;
|
||||||
|
BitField<15, 1, s32> lucia;
|
||||||
|
BitField<31, 1, s32> system;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -387,37 +447,69 @@ private:
|
||||||
std::array<Common::Vec3f, 3> orientation;
|
std::array<Common::Vec3f, 3> orientation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NfcXcdHandle {
|
||||||
|
INSERT_PADDING_BYTES(0x60);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AppletFooterUiAttributes {
|
||||||
|
INSERT_PADDING_BYTES(0x4);
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AppletFooterUiType : u8 {
|
||||||
|
None = 0,
|
||||||
|
HandheldNone = 1,
|
||||||
|
HandheldJoyConLeftOnly = 1,
|
||||||
|
HandheldJoyConRightOnly = 3,
|
||||||
|
HandheldJoyConLeftJoyConRight = 4,
|
||||||
|
JoyDual = 5,
|
||||||
|
JoyDualLeftOnly = 6,
|
||||||
|
JoyDualRightOnly = 7,
|
||||||
|
JoyLeftHorizontal = 8,
|
||||||
|
JoyLeftVertical = 9,
|
||||||
|
JoyRightHorizontal = 10,
|
||||||
|
JoyRightVertical = 11,
|
||||||
|
SwitchProController = 12,
|
||||||
|
CompatibleProController = 13,
|
||||||
|
CompatibleJoyCon = 14,
|
||||||
|
LarkHvc1 = 15,
|
||||||
|
LarkHvc2 = 16,
|
||||||
|
LarkNesLeft = 17,
|
||||||
|
LarkNesRight = 18,
|
||||||
|
Lucia = 19,
|
||||||
|
Verification = 20,
|
||||||
|
};
|
||||||
|
|
||||||
struct NPadEntry {
|
struct NPadEntry {
|
||||||
NpadStyleSet joy_styles;
|
NpadStyleSet style_set;
|
||||||
NpadAssignments pad_assignment;
|
NpadAssignments assignment_mode;
|
||||||
|
FullKeyColor fullkey_color;
|
||||||
|
JoyconColor joycon_color;
|
||||||
|
|
||||||
ColorReadError single_color_error;
|
NPadGeneric fullkey_states;
|
||||||
ControllerColor single_color;
|
|
||||||
|
|
||||||
ColorReadError dual_color_error;
|
|
||||||
ControllerColor left_color;
|
|
||||||
ControllerColor right_color;
|
|
||||||
|
|
||||||
NPadGeneric main_controller_states;
|
|
||||||
NPadGeneric handheld_states;
|
NPadGeneric handheld_states;
|
||||||
NPadGeneric dual_states;
|
NPadGeneric joy_dual_states;
|
||||||
NPadGeneric left_joy_states;
|
NPadGeneric joy_left_states;
|
||||||
NPadGeneric right_joy_states;
|
NPadGeneric joy_right_states;
|
||||||
NPadGeneric pokeball_states;
|
NPadGeneric palma_states;
|
||||||
NPadGeneric libnx; // TODO(ogniK): Find out what this actually is, libnx seems to only be
|
NPadGeneric system_ext_states;
|
||||||
// relying on this for the time being
|
SixAxisGeneric sixaxis_fullkey;
|
||||||
SixAxisGeneric sixaxis_full;
|
|
||||||
SixAxisGeneric sixaxis_handheld;
|
SixAxisGeneric sixaxis_handheld;
|
||||||
SixAxisGeneric sixaxis_dual_left;
|
SixAxisGeneric sixaxis_dual_left;
|
||||||
SixAxisGeneric sixaxis_dual_right;
|
SixAxisGeneric sixaxis_dual_right;
|
||||||
SixAxisGeneric sixaxis_left;
|
SixAxisGeneric sixaxis_left;
|
||||||
SixAxisGeneric sixaxis_right;
|
SixAxisGeneric sixaxis_right;
|
||||||
NPadDevice device_type;
|
NPadDevice device_type;
|
||||||
NPadProperties properties;
|
INSERT_PADDING_BYTES(0x4); // reserved
|
||||||
INSERT_PADDING_WORDS(1);
|
NPadSystemProperties system_properties;
|
||||||
std::array<u32, 3> battery_level;
|
NPadButtonProperties button_properties;
|
||||||
INSERT_PADDING_BYTES(0x5c);
|
u32 battery_level_dual;
|
||||||
INSERT_PADDING_BYTES(0xdf8);
|
u32 battery_level_left;
|
||||||
|
u32 battery_level_right;
|
||||||
|
AppletFooterUiAttributes footer_attributes;
|
||||||
|
AppletFooterUiType footer_type;
|
||||||
|
// nfc_states needs to be checked switchbrew does not match with HW
|
||||||
|
NfcXcdHandle nfc_states;
|
||||||
|
INSERT_PADDING_BYTES(0xdef);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size");
|
static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size");
|
||||||
|
|
||||||
|
@ -453,8 +545,7 @@ private:
|
||||||
std::vector<u32> supported_npad_id_types{};
|
std::vector<u32> supported_npad_id_types{};
|
||||||
NpadHoldType hold_type{NpadHoldType::Vertical};
|
NpadHoldType hold_type{NpadHoldType::Vertical};
|
||||||
NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
|
NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
|
||||||
// NpadCommunicationMode is unknown, default value is 1
|
NpadCommunicationMode communication_mode{NpadCommunicationMode::Default};
|
||||||
NpadCommunicationMode communication_mode{NpadCommunicationMode::Unknown1};
|
|
||||||
// Each controller should have their own styleset changed event
|
// Each controller should have their own styleset changed event
|
||||||
std::array<std::shared_ptr<Kernel::KEvent>, 10> styleset_changed_events;
|
std::array<std::shared_ptr<Kernel::KEvent>, 10> styleset_changed_events;
|
||||||
std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints;
|
std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/bit_field.h"
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
|
@ -28,6 +29,67 @@ public:
|
||||||
void OnLoadInputDevices() override;
|
void OnLoadInputDevices() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Attributes {
|
||||||
|
union {
|
||||||
|
u32_le raw{};
|
||||||
|
BitField<0, 1, u32> is_connected;
|
||||||
|
BitField<1, 1, u32> is_wired;
|
||||||
|
BitField<2, 1, u32> is_left_connected;
|
||||||
|
BitField<3, 1, u32> is_left_wired;
|
||||||
|
BitField<4, 1, u32> is_right_connected;
|
||||||
|
BitField<5, 1, u32> is_right_wired;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Attributes) == 4, "Attributes is an invalid size");
|
||||||
|
|
||||||
|
struct Buttons {
|
||||||
|
union {
|
||||||
|
u32_le raw{};
|
||||||
|
// Button states
|
||||||
|
BitField<0, 1, u32> a;
|
||||||
|
BitField<1, 1, u32> b;
|
||||||
|
BitField<2, 1, u32> x;
|
||||||
|
BitField<3, 1, u32> y;
|
||||||
|
BitField<4, 1, u32> l_stick;
|
||||||
|
BitField<5, 1, u32> r_stick;
|
||||||
|
BitField<6, 1, u32> l;
|
||||||
|
BitField<7, 1, u32> r;
|
||||||
|
BitField<8, 1, u32> zl;
|
||||||
|
BitField<9, 1, u32> zr;
|
||||||
|
BitField<10, 1, u32> plus;
|
||||||
|
BitField<11, 1, u32> minus;
|
||||||
|
|
||||||
|
// D-Pad
|
||||||
|
BitField<12, 1, u32> d_left;
|
||||||
|
BitField<13, 1, u32> d_up;
|
||||||
|
BitField<14, 1, u32> d_right;
|
||||||
|
BitField<15, 1, u32> d_down;
|
||||||
|
|
||||||
|
// Left JoyStick
|
||||||
|
BitField<16, 1, u32> l_stick_left;
|
||||||
|
BitField<17, 1, u32> l_stick_up;
|
||||||
|
BitField<18, 1, u32> l_stick_right;
|
||||||
|
BitField<19, 1, u32> l_stick_down;
|
||||||
|
|
||||||
|
// Right JoyStick
|
||||||
|
BitField<20, 1, u32> r_stick_left;
|
||||||
|
BitField<21, 1, u32> r_stick_up;
|
||||||
|
BitField<22, 1, u32> r_stick_right;
|
||||||
|
BitField<23, 1, u32> r_stick_down;
|
||||||
|
|
||||||
|
// Not always active?
|
||||||
|
BitField<24, 1, u32> left_sl;
|
||||||
|
BitField<25, 1, u32> left_sr;
|
||||||
|
|
||||||
|
BitField<26, 1, u32> right_sl;
|
||||||
|
BitField<27, 1, u32> right_sr;
|
||||||
|
|
||||||
|
BitField<28, 1, u32> palma;
|
||||||
|
BitField<30, 1, u32> handheld_left_b;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Buttons) == 4, "Buttons is an invalid size");
|
||||||
|
|
||||||
struct AnalogStick {
|
struct AnalogStick {
|
||||||
s32_le x;
|
s32_le x;
|
||||||
s32_le y;
|
s32_le y;
|
||||||
|
@ -37,10 +99,10 @@ private:
|
||||||
struct XPadState {
|
struct XPadState {
|
||||||
s64_le sampling_number;
|
s64_le sampling_number;
|
||||||
s64_le sampling_number2;
|
s64_le sampling_number2;
|
||||||
s32_le attributes;
|
Attributes attributes;
|
||||||
u32_le pad_states;
|
Buttons pad_states;
|
||||||
AnalogStick x_stick;
|
AnalogStick l_stick;
|
||||||
AnalogStick y_stick;
|
AnalogStick r_stick;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(XPadState) == 0x28, "XPadState is an invalid size");
|
static_assert(sizeof(XPadState) == 0x28, "XPadState is an invalid size");
|
||||||
|
|
||||||
|
|
|
@ -59,20 +59,26 @@ IAppletResource::IAppletResource(Core::System& system_)
|
||||||
MakeController<Controller_Mouse>(HidController::Mouse);
|
MakeController<Controller_Mouse>(HidController::Mouse);
|
||||||
MakeController<Controller_Keyboard>(HidController::Keyboard);
|
MakeController<Controller_Keyboard>(HidController::Keyboard);
|
||||||
MakeController<Controller_XPad>(HidController::XPad);
|
MakeController<Controller_XPad>(HidController::XPad);
|
||||||
MakeController<Controller_Stubbed>(HidController::Unknown1);
|
MakeController<Controller_Stubbed>(HidController::HomeButton);
|
||||||
MakeController<Controller_Stubbed>(HidController::Unknown2);
|
MakeController<Controller_Stubbed>(HidController::SleepButton);
|
||||||
MakeController<Controller_Stubbed>(HidController::Unknown3);
|
MakeController<Controller_Stubbed>(HidController::CaptureButton);
|
||||||
MakeController<Controller_Stubbed>(HidController::SixAxisSensor);
|
MakeController<Controller_Stubbed>(HidController::InputDetector);
|
||||||
|
MakeController<Controller_Stubbed>(HidController::UniquePad);
|
||||||
MakeController<Controller_NPad>(HidController::NPad);
|
MakeController<Controller_NPad>(HidController::NPad);
|
||||||
MakeController<Controller_Gesture>(HidController::Gesture);
|
MakeController<Controller_Gesture>(HidController::Gesture);
|
||||||
|
MakeController<Controller_Stubbed>(HidController::ConsoleSixAxisSensor);
|
||||||
|
|
||||||
// Homebrew doesn't try to activate some controllers, so we activate them by default
|
// Homebrew doesn't try to activate some controllers, so we activate them by default
|
||||||
GetController<Controller_NPad>(HidController::NPad).ActivateController();
|
GetController<Controller_NPad>(HidController::NPad).ActivateController();
|
||||||
GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController();
|
GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController();
|
||||||
|
|
||||||
GetController<Controller_Stubbed>(HidController::Unknown1).SetCommonHeaderOffset(0x4c00);
|
GetController<Controller_Stubbed>(HidController::HomeButton).SetCommonHeaderOffset(0x4C00);
|
||||||
GetController<Controller_Stubbed>(HidController::Unknown2).SetCommonHeaderOffset(0x4e00);
|
GetController<Controller_Stubbed>(HidController::SleepButton).SetCommonHeaderOffset(0x4E00);
|
||||||
GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000);
|
GetController<Controller_Stubbed>(HidController::CaptureButton).SetCommonHeaderOffset(0x5000);
|
||||||
|
GetController<Controller_Stubbed>(HidController::InputDetector).SetCommonHeaderOffset(0x5200);
|
||||||
|
GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00);
|
||||||
|
GetController<Controller_Stubbed>(HidController::ConsoleSixAxisSensor)
|
||||||
|
.SetCommonHeaderOffset(0x3C200);
|
||||||
|
|
||||||
// Register update callbacks
|
// Register update callbacks
|
||||||
pad_update_event = Core::Timing::CreateEvent(
|
pad_update_event = Core::Timing::CreateEvent(
|
||||||
|
|
|
@ -29,12 +29,14 @@ enum class HidController : std::size_t {
|
||||||
Mouse,
|
Mouse,
|
||||||
Keyboard,
|
Keyboard,
|
||||||
XPad,
|
XPad,
|
||||||
Unknown1,
|
HomeButton,
|
||||||
Unknown2,
|
SleepButton,
|
||||||
Unknown3,
|
CaptureButton,
|
||||||
SixAxisSensor,
|
InputDetector,
|
||||||
|
UniquePad,
|
||||||
NPad,
|
NPad,
|
||||||
Gesture,
|
Gesture,
|
||||||
|
ConsoleSixAxisSensor,
|
||||||
|
|
||||||
MaxControllers,
|
MaxControllers,
|
||||||
};
|
};
|
||||||
|
|
|
@ -884,7 +884,7 @@ void ConfigureInputPlayer::SetConnectableControllers() {
|
||||||
index_controller_type_pairs.clear();
|
index_controller_type_pairs.clear();
|
||||||
ui->comboControllerType->clear();
|
ui->comboControllerType->clear();
|
||||||
|
|
||||||
if (enable_all || npad_style_set.pro_controller == 1) {
|
if (enable_all || npad_style_set.fullkey == 1) {
|
||||||
index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
|
index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
|
||||||
Settings::ControllerType::ProController);
|
Settings::ControllerType::ProController);
|
||||||
ui->comboControllerType->addItem(tr("Pro Controller"));
|
ui->comboControllerType->addItem(tr("Pro Controller"));
|
||||||
|
|
Loading…
Reference in a new issue