From f30ef987615729f5a3b8eab524ce5680369057e9 Mon Sep 17 00:00:00 2001 From: german Date: Sun, 10 Jan 2021 11:37:19 -0600 Subject: Adds missing controller types and properties --- src/core/hle/service/hid/controllers/keyboard.cpp | 17 ++++-- src/core/hle/service/hid/controllers/keyboard.h | 21 ++++++- src/core/hle/service/hid/controllers/mouse.cpp | 12 ++-- src/core/hle/service/hid/controllers/mouse.h | 26 ++++++++- src/core/hle/service/hid/controllers/npad.cpp | 12 ++++ src/core/hle/service/hid/controllers/npad.h | 33 ++++++++++- src/core/hle/service/hid/controllers/xpad.h | 70 +++++++++++++++++++++-- src/core/hle/service/hid/hid.cpp | 20 ++++--- src/core/hle/service/hid/hid.h | 10 ++-- 9 files changed, 191 insertions(+), 30 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index 59b694cd4..fd5d5e057 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp @@ -39,16 +39,25 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, cur_entry.sampling_number2 = cur_entry.sampling_number; cur_entry.key.fill(0); - cur_entry.modifier = 0; if (Settings::values.keyboard_enabled) { for (std::size_t i = 0; i < keyboard_keys.size(); ++i) { auto& entry = cur_entry.key[i / KEYS_PER_BYTE]; entry = static_cast(entry | (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE))); } - for (std::size_t i = 0; i < keyboard_mods.size(); ++i) { - cur_entry.modifier |= (keyboard_mods[i]->GetStatus() << i); - } + using namespace Settings::NativeKeyboard; + + // 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.katana.Assign(0); + cur_entry.modifier.hiragana.Assign(0); } std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); } diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h index f3eef5936..8a89eb4bb 100644 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ b/src/core/hle/service/hid/controllers/keyboard.h @@ -5,6 +5,7 @@ #pragma once #include +#include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" @@ -31,12 +32,28 @@ public: void OnLoadInputDevices() override; private: + struct Modifiers { + union { + s32_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> katana; + BitField<12, 1, u32> hiragana; + }; + }; + static_assert(sizeof(Modifiers) == 0x4, "Modifiers is an invalid size"); + struct KeyboardState { s64_le sampling_number; s64_le sampling_number2; - s32_le modifier; - s32_le attribute; + Modifiers modifier; std::array key; }; static_assert(sizeof(KeyboardState) == 0x38, "KeyboardState is an invalid size"); diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index ac40989c5..30924d9e2 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp @@ -35,7 +35,7 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; - + cur_entry.attribute.raw = 0; if (Settings::values.mouse_enabled) { const auto [px, py, sx, sy] = mouse_device->GetStatus(); const auto x = static_cast(px * Layout::ScreenUndocked::Width); @@ -46,10 +46,14 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* cur_entry.delta_y = y - last_entry.y; cur_entry.mouse_wheel_x = sx; 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) { - cur_entry.button |= (mouse_button_devices[i]->GetStatus() << i); - } + using namespace Settings::NativeMouseButton; + 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)); diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h index 357ab7107..2c8ebe1d5 100644 --- a/src/core/hle/service/hid/controllers/mouse.h +++ b/src/core/hle/service/hid/controllers/mouse.h @@ -5,6 +5,7 @@ #pragma once #include +#include "common/bit_field.h" #include "common/common_types.h" #include "common/swap.h" #include "core/frontend/input.h" @@ -30,6 +31,27 @@ public: void OnLoadInputDevices() override; private: + struct Buttons { + union { + s32_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 { + s32_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 { s64_le sampling_number; s64_le sampling_number2; @@ -39,8 +61,8 @@ private: s32_le delta_y; s32_le mouse_wheel_x; s32_le mouse_wheel_y; - s32_le button; - s32_le attribute; + Buttons button; + Attributes attribute; }; static_assert(sizeof(MouseState) == 0x30, "MouseState is an invalid size"); diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 0c227b135..251db1f84 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -609,7 +609,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing UNREACHABLE(); break; case NPadControllerType::ProController: + full_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][0]) { + full_sixaxis_entry.attribute.IsConnected.Assign(1); full_sixaxis_entry.accel = motion_devices[0].accel; full_sixaxis_entry.gyro = motion_devices[0].gyro; full_sixaxis_entry.rotation = motion_devices[0].rotation; @@ -617,7 +619,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } break; case NPadControllerType::Handheld: + handheld_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][0]) { + handheld_sixaxis_entry.attribute.IsConnected.Assign(1); handheld_sixaxis_entry.accel = motion_devices[0].accel; handheld_sixaxis_entry.gyro = motion_devices[0].gyro; handheld_sixaxis_entry.rotation = motion_devices[0].rotation; @@ -625,8 +629,11 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } break; case NPadControllerType::JoyDual: + dual_left_sixaxis_entry.attribute.raw = 0; + dual_right_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][0]) { // Set motion for the left joycon + dual_left_sixaxis_entry.attribute.IsConnected.Assign(1); dual_left_sixaxis_entry.accel = motion_devices[0].accel; dual_left_sixaxis_entry.gyro = motion_devices[0].gyro; dual_left_sixaxis_entry.rotation = motion_devices[0].rotation; @@ -634,6 +641,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } if (sixaxis_sensors_enabled && motions[i][1]) { // Set motion for the right joycon + dual_right_sixaxis_entry.attribute.IsConnected.Assign(1); dual_right_sixaxis_entry.accel = motion_devices[1].accel; dual_right_sixaxis_entry.gyro = motion_devices[1].gyro; dual_right_sixaxis_entry.rotation = motion_devices[1].rotation; @@ -641,7 +649,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } break; case NPadControllerType::JoyLeft: + left_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][0]) { + left_sixaxis_entry.attribute.IsConnected.Assign(1); left_sixaxis_entry.accel = motion_devices[0].accel; left_sixaxis_entry.gyro = motion_devices[0].gyro; left_sixaxis_entry.rotation = motion_devices[0].rotation; @@ -649,7 +659,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } break; case NPadControllerType::JoyRight: + right_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][1]) { + right_sixaxis_entry.attribute.IsConnected.Assign(1); right_sixaxis_entry.accel = motion_devices[1].accel; right_sixaxis_entry.gyro = motion_devices[1].gyro; right_sixaxis_entry.rotation = motion_devices[1].rotation; diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 2e13922b9..e5778921f 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -113,8 +113,13 @@ public: BitField<2, 1, u32> joycon_dual; BitField<3, 1, u32> joycon_left; BitField<4, 1, u32> joycon_right; - - BitField<6, 1, u32> pokeball; // TODO(ogniK): Confirm when possible + BitField<5, 1, u32> gamecube; + BitField<6, 1, u32> pokeball; + 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"); @@ -285,6 +290,9 @@ private: BitField<26, 1, u64> right_sl; 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"); @@ -329,6 +337,15 @@ private: }; static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size"); + struct SixAxisAttributes { + union { + u32_le raw{}; + BitField<0, 1, u32> IsConnected; + BitField<1, 1, u32> IsInterpolated; + }; + }; + static_assert(sizeof(SixAxisAttributes) == 4, "SixAxisAttributes is an invalid size"); + struct SixAxisStates { s64_le timestamp{}; INSERT_PADDING_WORDS(2); @@ -337,7 +354,8 @@ private: Common::Vec3f gyro{}; Common::Vec3f rotation{}; std::array orientation{}; - s64_le always_one{1}; + SixAxisAttributes attribute; + INSERT_PADDING_BYTES(4); // Reserved }; static_assert(sizeof(SixAxisStates) == 0x68, "SixAxisStates is an invalid size"); @@ -356,10 +374,19 @@ private: struct NPadProperties { union { 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_unsuported_button; + BitField<10, 1, s64> is_system_ext_unsuported_button; BitField<11, 1, s64> is_vertical; BitField<12, 1, s64> is_horizontal; BitField<13, 1, s64> use_plus; BitField<14, 1, s64> use_minus; + BitField<15, 1, s64> use_directional_buttons; }; }; diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h index ad229787c..d91cf62a2 100644 --- a/src/core/hle/service/hid/controllers/xpad.h +++ b/src/core/hle/service/hid/controllers/xpad.h @@ -4,6 +4,7 @@ #pragma once +#include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" @@ -28,6 +29,67 @@ public: void OnLoadInputDevices() override; private: + struct Attributes { + union { + s32_le raw{}; + BitField<0, 1, u32> IsConnected; + BitField<1, 1, u32> IsWired; + BitField<2, 1, u32> IsLeftConnected; + BitField<3, 1, u32> IsLeftWired; + BitField<4, 1, u32> IsRightConnected; + BitField<5, 1, u32> IsRightWired; + }; + }; + 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 { s32_le x; s32_le y; @@ -37,10 +99,10 @@ private: struct XPadState { s64_le sampling_number; s64_le sampling_number2; - s32_le attributes; - u32_le pad_states; - AnalogStick x_stick; - AnalogStick y_stick; + Attributes attributes; + Buttons pad_states; + AnalogStick l_stick; + AnalogStick r_stick; }; static_assert(sizeof(XPadState) == 0x28, "XPadState is an invalid size"); diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 4cee4838c..370e266a8 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -59,20 +59,26 @@ IAppletResource::IAppletResource(Core::System& system_) MakeController(HidController::Mouse); MakeController(HidController::Keyboard); MakeController(HidController::XPad); - MakeController(HidController::Unknown1); - MakeController(HidController::Unknown2); - MakeController(HidController::Unknown3); - MakeController(HidController::SixAxisSensor); + MakeController(HidController::HomeButton); + MakeController(HidController::SleepButton); + MakeController(HidController::CaptureButton); + MakeController(HidController::InputDetector); + MakeController(HidController::UniquePad); MakeController(HidController::NPad); MakeController(HidController::Gesture); + MakeController(HidController::ConsoleSixAxisSensor); // Homebrew doesn't try to activate some controllers, so we activate them by default GetController(HidController::NPad).ActivateController(); GetController(HidController::Touchscreen).ActivateController(); - GetController(HidController::Unknown1).SetCommonHeaderOffset(0x4c00); - GetController(HidController::Unknown2).SetCommonHeaderOffset(0x4e00); - GetController(HidController::Unknown3).SetCommonHeaderOffset(0x5000); + GetController(HidController::HomeButton).SetCommonHeaderOffset(0x4C00); + GetController(HidController::SleepButton).SetCommonHeaderOffset(0x4E00); + GetController(HidController::CaptureButton).SetCommonHeaderOffset(0x5000); + GetController(HidController::InputDetector).SetCommonHeaderOffset(0x5200); + GetController(HidController::UniquePad).SetCommonHeaderOffset(0x5A00); + GetController(HidController::ConsoleSixAxisSensor) + .SetCommonHeaderOffset(0x3C200); // Register update callbacks pad_update_event = Core::Timing::CreateEvent( diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index d991bd721..7cc0433e2 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -29,12 +29,14 @@ enum class HidController : std::size_t { Mouse, Keyboard, XPad, - Unknown1, - Unknown2, - Unknown3, - SixAxisSensor, + HomeButton, + SleepButton, + CaptureButton, + InputDetector, + UniquePad, NPad, Gesture, + ConsoleSixAxisSensor, MaxControllers, }; -- cgit v1.2.3