diff options
author | Narr the Reg <juangerman-13@hotmail.com> | 2023-12-14 04:39:38 +0100 |
---|---|---|
committer | Narr the Reg <juangerman-13@hotmail.com> | 2023-12-14 06:24:28 +0100 |
commit | 64f68e96354df3afb9bb563c888793f98ecb5026 (patch) | |
tree | 82a1f3f51902e0a926bae4ae8a84ba1dcf2a145b /src/core/hle/service | |
parent | Merge pull request #12342 from FearlessTobi/fix-msvc (diff) | |
download | yuzu-64f68e96354df3afb9bb563c888793f98ecb5026.tar yuzu-64f68e96354df3afb9bb563c888793f98ecb5026.tar.gz yuzu-64f68e96354df3afb9bb563c888793f98ecb5026.tar.bz2 yuzu-64f68e96354df3afb9bb563c888793f98ecb5026.tar.lz yuzu-64f68e96354df3afb9bb563c888793f98ecb5026.tar.xz yuzu-64f68e96354df3afb9bb563c888793f98ecb5026.tar.zst yuzu-64f68e96354df3afb9bb563c888793f98ecb5026.zip |
Diffstat (limited to 'src/core/hle/service')
37 files changed, 1057 insertions, 819 deletions
diff --git a/src/core/hle/service/hid/controllers/applet_resource.cpp b/src/core/hle/service/hid/controllers/applet_resource.cpp index 435b86233..c8e74c764 100644 --- a/src/core/hle/service/hid/controllers/applet_resource.cpp +++ b/src/core/hle/service/hid/controllers/applet_resource.cpp @@ -4,6 +4,7 @@ #include "core/core.h" #include "core/hle/kernel/k_shared_memory.h" #include "core/hle/service/hid/controllers/applet_resource.h" +#include "core/hle/service/hid/controllers/shared_memory_format.h" #include "core/hle/service/hid/errors.h" namespace Service::HID { @@ -23,11 +24,24 @@ Result AppletResource::CreateAppletResource(u64 aruid) { return ResultAruidAlreadyRegistered; } - // TODO: Here shared memory is created for the process we don't quite emulate this part so - // obtain this pointer from system - auto& shared_memory = system.Kernel().GetHidSharedMem(); + auto& shared_memory = shared_memory_holder[index]; + if (!shared_memory.IsMapped()) { + const Result result = shared_memory.Initialize(system); + if (result.IsError()) { + return result; + } + if (shared_memory.GetAddress() == nullptr) { + shared_memory.Finalize(); + return ResultSharedMemoryNotInitialized; + } + } + + auto* shared_memory_format = shared_memory.GetAddress(); + if (shared_memory_format != nullptr) { + shared_memory_format->Initialize(); + } - data[index].shared_memory_handle = &shared_memory; + data[index].shared_memory_format = shared_memory_format; data[index].flag.is_assigned.Assign(true); // TODO: InitializeSixAxisControllerConfig(false); active_aruid = aruid; @@ -94,7 +108,7 @@ void AppletResource::UnregisterAppletResourceUserId(u64 aruid) { if (index < AruidIndexMax) { if (data[index].flag.is_assigned) { - data[index].shared_memory_handle = nullptr; + data[index].shared_memory_format = nullptr; data[index].flag.is_assigned.Assign(false); } } @@ -120,7 +134,7 @@ void AppletResource::FreeAppletResourceId(u64 aruid) { auto& aruid_data = data[index]; if (aruid_data.flag.is_assigned) { - aruid_data.shared_memory_handle = nullptr; + aruid_data.shared_memory_format = nullptr; aruid_data.flag.is_assigned.Assign(false); } } @@ -135,7 +149,18 @@ Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, return ResultAruidNotRegistered; } - *out_handle = data[index].shared_memory_handle; + *out_handle = shared_memory_holder[index].GetHandle(); + return ResultSuccess; +} + +Result AppletResource::GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, + u64 aruid) { + u64 index = GetIndexFromAruid(aruid); + if (index >= AruidIndexMax) { + return ResultAruidNotRegistered; + } + + *out_shared_memory_format = data[index].shared_memory_format; return ResultSuccess; } diff --git a/src/core/hle/service/hid/controllers/applet_resource.h b/src/core/hle/service/hid/controllers/applet_resource.h index 62137db13..e7991f93a 100644 --- a/src/core/hle/service/hid/controllers/applet_resource.h +++ b/src/core/hle/service/hid/controllers/applet_resource.h @@ -8,6 +8,7 @@ #include "common/bit_field.h" #include "common/common_types.h" #include "core/hle/result.h" +#include "core/hle/service/hid/controllers/shared_memory_holder.h" namespace Core { class System; @@ -18,6 +19,8 @@ class KSharedMemory; } namespace Service::HID { +struct SharedMemoryFormat; + class AppletResource { public: explicit AppletResource(Core::System& system_); @@ -32,6 +35,7 @@ public: u64 GetActiveAruid(); Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid); + Result GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, u64 aruid); u64 GetIndexFromAruid(u64 aruid); @@ -80,12 +84,13 @@ private: struct AruidData { DataStatusFlag flag{}; u64 aruid{}; - Kernel::KSharedMemory* shared_memory_handle{nullptr}; + SharedMemoryFormat* shared_memory_format{nullptr}; }; u64 active_aruid{}; AruidRegisterList registration_list{}; std::array<AruidData, AruidIndexMax> data{}; + std::array<SharedMemoryHolder, AruidIndexMax> shared_memory_holder{}; s32 ref_counter{}; Core::System& system; diff --git a/src/core/hle/service/hid/controllers/console_six_axis.cpp b/src/core/hle/service/hid/controllers/console_six_axis.cpp index b2bf1d78d..084e99556 100644 --- a/src/core/hle/service/hid/controllers/console_six_axis.cpp +++ b/src/core/hle/service/hid/controllers/console_six_axis.cpp @@ -6,18 +6,15 @@ #include "core/hid/emulated_console.h" #include "core/hid/hid_core.h" #include "core/hle/service/hid/controllers/console_six_axis.h" +#include "core/hle/service/hid/controllers/shared_memory_format.h" #include "core/memory.h" namespace Service::HID { -constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200; -ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) - : ControllerBase{hid_core_} { +ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_, + ConsoleSixAxisSensorSharedMemoryFormat& console_shared_memory) + : ControllerBase{hid_core_}, shared_memory{console_shared_memory} { console = hid_core.GetEmulatedConsole(); - static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size, - "ConsoleSharedMemory is bigger than the shared memory"); - shared_memory = std::construct_at( - reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); } ConsoleSixAxis::~ConsoleSixAxis() = default; @@ -33,10 +30,10 @@ void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { const auto motion_status = console->GetMotion(); - shared_memory->sampling_number++; - shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; - shared_memory->verticalization_error = motion_status.verticalization_error; - shared_memory->gyro_bias = motion_status.gyro_bias; + shared_memory.sampling_number++; + shared_memory.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; + shared_memory.verticalization_error = motion_status.verticalization_error; + shared_memory.gyro_bias = motion_status.gyro_bias; } } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/console_six_axis.h b/src/core/hle/service/hid/controllers/console_six_axis.h index 5b7c6a29a..3d1c9ce23 100644 --- a/src/core/hle/service/hid/controllers/console_six_axis.h +++ b/src/core/hle/service/hid/controllers/console_six_axis.h @@ -3,7 +3,6 @@ #pragma once -#include "common/vector_math.h" #include "core/hle/service/hid/controllers/controller_base.h" namespace Core::HID { @@ -11,9 +10,12 @@ class EmulatedConsole; } // namespace Core::HID namespace Service::HID { +struct ConsoleSixAxisSensorSharedMemoryFormat; + class ConsoleSixAxis final : public ControllerBase { public: - explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); + explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_, + ConsoleSixAxisSensorSharedMemoryFormat& console_shared_memory); ~ConsoleSixAxis() override; // Called when the controller is initialized @@ -26,18 +28,7 @@ public: void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; private: - // This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat - struct ConsoleSharedMemory { - u64 sampling_number{}; - bool is_seven_six_axis_sensor_at_rest{}; - INSERT_PADDING_BYTES(3); // padding - f32 verticalization_error{}; - Common::Vec3f gyro_bias{}; - INSERT_PADDING_BYTES(4); // padding - }; - static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size"); - - ConsoleSharedMemory* shared_memory = nullptr; + ConsoleSixAxisSensorSharedMemoryFormat& shared_memory; Core::HID::EmulatedConsole* console = nullptr; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h index 9a44ee41e..4326c7821 100644 --- a/src/core/hle/service/hid/controllers/controller_base.h +++ b/src/core/hle/service/hid/controllers/controller_base.h @@ -39,9 +39,6 @@ public: bool IsControllerActivated() const; - static const std::size_t hid_entry_count = 17; - static const std::size_t shared_memory_size = 0x40000; - protected: bool is_activated{false}; diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp index 9de19ebfc..38fafe88f 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.cpp +++ b/src/core/hle/service/hid/controllers/debug_pad.cpp @@ -9,16 +9,13 @@ #include "core/hid/hid_core.h" #include "core/hid/hid_types.h" #include "core/hle/service/hid/controllers/debug_pad.h" +#include "core/hle/service/hid/controllers/shared_memory_format.h" namespace Service::HID { -constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000; - -DebugPad::DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) - : ControllerBase{hid_core_} { - static_assert(SHARED_MEMORY_OFFSET + sizeof(DebugPadSharedMemory) < shared_memory_size, - "DebugPadSharedMemory is bigger than the shared memory"); - shared_memory = std::construct_at( - reinterpret_cast<DebugPadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); + +DebugPad::DebugPad(Core::HID::HIDCore& hid_core_, + DebugPadSharedMemoryFormat& debug_pad_shared_memory) + : ControllerBase{hid_core_}, shared_memory{debug_pad_shared_memory} { controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); } @@ -30,12 +27,12 @@ void DebugPad::OnRelease() {} void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { if (!IsControllerActivated()) { - shared_memory->debug_pad_lifo.buffer_count = 0; - shared_memory->debug_pad_lifo.buffer_tail = 0; + shared_memory.debug_pad_lifo.buffer_count = 0; + shared_memory.debug_pad_lifo.buffer_tail = 0; return; } - const auto& last_entry = shared_memory->debug_pad_lifo.ReadCurrentEntry().state; + const auto& last_entry = shared_memory.debug_pad_lifo.ReadCurrentEntry().state; next_state.sampling_number = last_entry.sampling_number + 1; if (Settings::values.debug_pad_enabled) { @@ -49,7 +46,7 @@ void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { next_state.r_stick = stick_state.right; } - shared_memory->debug_pad_lifo.WriteNextEntry(next_state); + shared_memory.debug_pad_lifo.WriteNextEntry(next_state); } } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h index 5566dba77..704d1fc98 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.h +++ b/src/core/hle/service/hid/controllers/debug_pad.h @@ -3,21 +3,25 @@ #pragma once -#include "common/bit_field.h" #include "common/common_types.h" #include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/hid/ring_lifo.h" +#include "core/hle/service/hid/controllers/types/debug_pad_types.h" namespace Core::HID { -class EmulatedController; -struct DebugPadButton; -struct AnalogStickState; -} // namespace Core::HID +class HIDCore; +} + +namespace Core::Timing { +class CoreTiming; +} namespace Service::HID { +struct DebugPadSharedMemoryFormat; + class DebugPad final : public ControllerBase { public: - explicit DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); + explicit DebugPad(Core::HID::HIDCore& hid_core_, + DebugPadSharedMemoryFormat& debug_pad_shared_memory); ~DebugPad() override; // Called when the controller is initialized @@ -30,35 +34,8 @@ public: void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; private: - // This is nn::hid::DebugPadAttribute - struct DebugPadAttribute { - union { - u32 raw{}; - BitField<0, 1, u32> connected; - }; - }; - static_assert(sizeof(DebugPadAttribute) == 0x4, "DebugPadAttribute is an invalid size"); - - // This is nn::hid::DebugPadState - struct DebugPadState { - s64 sampling_number{}; - DebugPadAttribute attribute{}; - Core::HID::DebugPadButton pad_state{}; - Core::HID::AnalogStickState r_stick{}; - Core::HID::AnalogStickState l_stick{}; - }; - static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state"); - - struct DebugPadSharedMemory { - // This is nn::hid::detail::DebugPadLifo - Lifo<DebugPadState, hid_entry_count> debug_pad_lifo{}; - static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size"); - INSERT_PADDING_WORDS(0x4E); - }; - static_assert(sizeof(DebugPadSharedMemory) == 0x400, "DebugPadSharedMemory is an invalid size"); - DebugPadState next_state{}; - DebugPadSharedMemory* shared_memory = nullptr; + DebugPadSharedMemoryFormat& shared_memory; Core::HID::EmulatedController* controller = nullptr; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp index 59b2ec73c..0b6e9c4e5 100644 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ b/src/core/hle/service/hid/controllers/gesture.cpp @@ -8,10 +8,9 @@ #include "core/frontend/emu_window.h" #include "core/hid/hid_core.h" #include "core/hle/service/hid/controllers/gesture.h" +#include "core/hle/service/hid/controllers/shared_memory_format.h" namespace Service::HID { -constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00; - // HW is around 700, value is set to 400 to make it easier to trigger with mouse constexpr f32 swipe_threshold = 400.0f; // Threshold in pixels/s constexpr f32 angle_threshold = 0.015f; // Threshold in radians @@ -23,19 +22,15 @@ constexpr f32 Square(s32 num) { return static_cast<f32>(num * num); } -Gesture::Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) - : ControllerBase(hid_core_) { - static_assert(SHARED_MEMORY_OFFSET + sizeof(GestureSharedMemory) < shared_memory_size, - "GestureSharedMemory is bigger than the shared memory"); - shared_memory = std::construct_at( - reinterpret_cast<GestureSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); +Gesture::Gesture(Core::HID::HIDCore& hid_core_, GestureSharedMemoryFormat& gesture_shared_memory) + : ControllerBase(hid_core_), shared_memory{gesture_shared_memory} { console = hid_core.GetEmulatedConsole(); } Gesture::~Gesture() = default; void Gesture::OnInit() { - shared_memory->gesture_lifo.buffer_count = 0; - shared_memory->gesture_lifo.buffer_tail = 0; + shared_memory.gesture_lifo.buffer_count = 0; + shared_memory.gesture_lifo.buffer_tail = 0; force_update = true; } @@ -43,8 +38,8 @@ void Gesture::OnRelease() {} void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { if (!IsControllerActivated()) { - shared_memory->gesture_lifo.buffer_count = 0; - shared_memory->gesture_lifo.buffer_tail = 0; + shared_memory.gesture_lifo.buffer_count = 0; + shared_memory.gesture_lifo.buffer_tail = 0; return; } @@ -52,7 +47,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { GestureProperties gesture = GetGestureProperties(); f32 time_difference = - static_cast<f32>(shared_memory->gesture_lifo.timestamp - last_update_timestamp) / + static_cast<f32>(shared_memory.gesture_lifo.timestamp - last_update_timestamp) / (1000 * 1000 * 1000); // Only update if necessary @@ -60,7 +55,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { return; } - last_update_timestamp = shared_memory->gesture_lifo.timestamp; + last_update_timestamp = shared_memory.gesture_lifo.timestamp; UpdateGestureSharedMemory(gesture, time_difference); } @@ -103,7 +98,7 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif GestureType type = GestureType::Idle; GestureAttribute attributes{}; - const auto& last_entry = shared_memory->gesture_lifo.ReadCurrentEntry().state; + const auto& last_entry = shared_memory.gesture_lifo.ReadCurrentEntry().state; // Reset next state to default next_state.sampling_number = last_entry.sampling_number + 1; @@ -133,7 +128,7 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif next_state.points = gesture.points; last_gesture = gesture; - shared_memory->gesture_lifo.WriteNextEntry(next_state); + shared_memory.gesture_lifo.WriteNextEntry(next_state); } void Gesture::NewGesture(GestureProperties& gesture, GestureType& type, @@ -305,11 +300,11 @@ void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_ next_state.direction = GestureDirection::Up; } -const Gesture::GestureState& Gesture::GetLastGestureEntry() const { - return shared_memory->gesture_lifo.ReadCurrentEntry().state; +const GestureState& Gesture::GetLastGestureEntry() const { + return shared_memory.gesture_lifo.ReadCurrentEntry().state; } -Gesture::GestureProperties Gesture::GetGestureProperties() { +GestureProperties Gesture::GetGestureProperties() { GestureProperties gesture; std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers; const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(), diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h index 4c6f8ee07..cee6b6c07 100644 --- a/src/core/hle/service/hid/controllers/gesture.h +++ b/src/core/hle/service/hid/controllers/gesture.h @@ -4,17 +4,19 @@ #pragma once #include <array> -#include "common/bit_field.h" + #include "common/common_types.h" -#include "common/point.h" #include "core/hid/emulated_console.h" #include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/hid/ring_lifo.h" +#include "core/hle/service/hid/controllers/types/touch_types.h" namespace Service::HID { +struct GestureSharedMemoryFormat; + class Gesture final : public ControllerBase { public: - explicit Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); + explicit Gesture(Core::HID::HIDCore& hid_core_, + GestureSharedMemoryFormat& gesture_shared_memory); ~Gesture() override; // Called when the controller is initialized @@ -27,79 +29,6 @@ public: void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; private: - static constexpr size_t MAX_FINGERS = 16; - static constexpr size_t MAX_POINTS = 4; - - // This is nn::hid::GestureType - enum class GestureType : u32 { - Idle, // Nothing touching the screen - Complete, // Set at the end of a touch event - Cancel, // Set when the number of fingers change - Touch, // A finger just touched the screen - Press, // Set if last type is touch and the finger hasn't moved - Tap, // Fast press then release - Pan, // All points moving together across the screen - Swipe, // Fast press movement and release of a single point - Pinch, // All points moving away/closer to the midpoint - Rotate, // All points rotating from the midpoint - }; - - // This is nn::hid::GestureDirection - enum class GestureDirection : u32 { - None, - Left, - Up, - Right, - Down, - }; - - // This is nn::hid::GestureAttribute - struct GestureAttribute { - union { - u32 raw{}; - - BitField<4, 1, u32> is_new_touch; - BitField<8, 1, u32> is_double_tap; - }; - }; - static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); - - // This is nn::hid::GestureState - struct GestureState { - s64 sampling_number{}; - s64 detection_count{}; - GestureType type{GestureType::Idle}; - GestureDirection direction{GestureDirection::None}; - Common::Point<s32> pos{}; - Common::Point<s32> delta{}; - f32 vel_x{}; - f32 vel_y{}; - GestureAttribute attributes{}; - f32 scale{}; - f32 rotation_angle{}; - s32 point_count{}; - std::array<Common::Point<s32>, 4> points{}; - }; - static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); - - struct GestureProperties { - std::array<Common::Point<s32>, MAX_POINTS> points{}; - std::size_t active_points{}; - Common::Point<s32> mid_point{}; - s64 detection_count{}; - u64 delta_time{}; - f32 average_distance{}; - f32 angle{}; - }; - - struct GestureSharedMemory { - // This is nn::hid::detail::GestureLifo - Lifo<GestureState, hid_entry_count> gesture_lifo{}; - static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size"); - INSERT_PADDING_WORDS(0x3E); - }; - static_assert(sizeof(GestureSharedMemory) == 0x800, "GestureSharedMemory is an invalid size"); - // Reads input from all available input engines void ReadTouchInput(); @@ -142,7 +71,7 @@ private: GestureProperties GetGestureProperties(); GestureState next_state{}; - GestureSharedMemory* shared_memory = nullptr; + GestureSharedMemoryFormat& shared_memory; Core::HID::EmulatedConsole* console = nullptr; std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{}; diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index ddb1b0ba4..feab499bd 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp @@ -8,16 +8,13 @@ #include "core/hid/emulated_devices.h" #include "core/hid/hid_core.h" #include "core/hle/service/hid/controllers/keyboard.h" +#include "core/hle/service/hid/controllers/shared_memory_format.h" namespace Service::HID { -constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; - -Keyboard::Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) - : ControllerBase{hid_core_} { - static_assert(SHARED_MEMORY_OFFSET + sizeof(KeyboardSharedMemory) < shared_memory_size, - "KeyboardSharedMemory is bigger than the shared memory"); - shared_memory = std::construct_at( - reinterpret_cast<KeyboardSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); + +Keyboard::Keyboard(Core::HID::HIDCore& hid_core_, + KeyboardSharedMemoryFormat& keyboard_shared_memory) + : ControllerBase{hid_core_}, shared_memory{keyboard_shared_memory} { emulated_devices = hid_core.GetEmulatedDevices(); } @@ -29,12 +26,12 @@ void Keyboard::OnRelease() {} void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { if (!IsControllerActivated()) { - shared_memory->keyboard_lifo.buffer_count = 0; - shared_memory->keyboard_lifo.buffer_tail = 0; + shared_memory.keyboard_lifo.buffer_count = 0; + shared_memory.keyboard_lifo.buffer_tail = 0; return; } - const auto& last_entry = shared_memory->keyboard_lifo.ReadCurrentEntry().state; + const auto& last_entry = shared_memory.keyboard_lifo.ReadCurrentEntry().state; next_state.sampling_number = last_entry.sampling_number + 1; if (Settings::values.keyboard_enabled) { @@ -46,7 +43,7 @@ void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { next_state.attribute.is_connected.Assign(1); } - shared_memory->keyboard_lifo.WriteNextEntry(next_state); + shared_memory.keyboard_lifo.WriteNextEntry(next_state); } } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h index 172ec1309..8abc8c5e9 100644 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ b/src/core/hle/service/hid/controllers/keyboard.h @@ -5,18 +5,16 @@ #include "common/common_types.h" #include "core/hle/service/hid/controllers/controller_base.h" +#include "core/hle/service/hid/controllers/types/keyboard_types.h" #include "core/hle/service/hid/ring_lifo.h" -namespace Core::HID { -class EmulatedDevices; -struct KeyboardModifier; -struct KeyboardKey; -} // namespace Core::HID - namespace Service::HID { +struct KeyboardSharedMemoryFormat; + class Keyboard final : public ControllerBase { public: - explicit Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); + explicit Keyboard(Core::HID::HIDCore& hid_core_, + KeyboardSharedMemoryFormat& keyboard_shared_memory); ~Keyboard() override; // Called when the controller is initialized @@ -29,25 +27,8 @@ public: void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; private: - // This is nn::hid::detail::KeyboardState - struct KeyboardState { - s64 sampling_number{}; - Core::HID::KeyboardModifier modifier{}; - Core::HID::KeyboardAttribute attribute{}; - Core::HID::KeyboardKey key{}; - }; - static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size"); - - struct KeyboardSharedMemory { - // This is nn::hid::detail::KeyboardLifo - Lifo<KeyboardState, hid_entry_count> keyboard_lifo{}; - static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size"); - INSERT_PADDING_WORDS(0xA); - }; - static_assert(sizeof(KeyboardSharedMemory) == 0x400, "KeyboardSharedMemory is an invalid size"); - KeyboardState next_state{}; - KeyboardSharedMemory* shared_memory = nullptr; + KeyboardSharedMemoryFormat& shared_memory; Core::HID::EmulatedDevices* emulated_devices = nullptr; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index 6e5a04e34..cce6deb52 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp @@ -8,15 +8,12 @@ #include "core/hid/emulated_devices.h" #include "core/hid/hid_core.h" #include "core/hle/service/hid/controllers/mouse.h" +#include "core/hle/service/hid/controllers/shared_memory_format.h" namespace Service::HID { -constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400; -Mouse::Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} { - static_assert(SHARED_MEMORY_OFFSET + sizeof(MouseSharedMemory) < shared_memory_size, - "MouseSharedMemory is bigger than the shared memory"); - shared_memory = std::construct_at( - reinterpret_cast<MouseSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); +Mouse::Mouse(Core::HID::HIDCore& hid_core_, MouseSharedMemoryFormat& mouse_shared_memory) + : ControllerBase{hid_core_}, shared_memory{mouse_shared_memory} { emulated_devices = hid_core.GetEmulatedDevices(); } @@ -27,14 +24,14 @@ void Mouse::OnRelease() {} void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { if (!IsControllerActivated()) { - shared_memory->mouse_lifo.buffer_count = 0; - shared_memory->mouse_lifo.buffer_tail = 0; + shared_memory.mouse_lifo.buffer_count = 0; + shared_memory.mouse_lifo.buffer_tail = 0; return; } next_state = {}; - const auto& last_entry = shared_memory->mouse_lifo.ReadCurrentEntry().state; + const auto& last_entry = shared_memory.mouse_lifo.ReadCurrentEntry().state; next_state.sampling_number = last_entry.sampling_number + 1; if (Settings::values.mouse_enabled) { @@ -53,7 +50,7 @@ void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { next_state.button = mouse_button_state; } - shared_memory->mouse_lifo.WriteNextEntry(next_state); + shared_memory.mouse_lifo.WriteNextEntry(next_state); } } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h index a80f3823f..3107915d7 100644 --- a/src/core/hle/service/hid/controllers/mouse.h +++ b/src/core/hle/service/hid/controllers/mouse.h @@ -14,9 +14,11 @@ struct AnalogStickState; } // namespace Core::HID namespace Service::HID { +struct MouseSharedMemoryFormat; + class Mouse final : public ControllerBase { public: - explicit Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); + explicit Mouse(Core::HID::HIDCore& hid_core_, MouseSharedMemoryFormat& mouse_shared_memory); ~Mouse() override; // Called when the controller is initialized @@ -29,17 +31,9 @@ public: void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; private: - struct MouseSharedMemory { - // This is nn::hid::detail::MouseLifo - Lifo<Core::HID::MouseState, hid_entry_count> mouse_lifo{}; - static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size"); - INSERT_PADDING_WORDS(0x2C); - }; - static_assert(sizeof(MouseSharedMemory) == 0x400, "MouseSharedMemory is an invalid size"); - Core::HID::MouseState next_state{}; Core::HID::AnalogStickState last_mouse_wheel_state{}; - MouseSharedMemory* shared_memory = nullptr; + MouseSharedMemoryFormat& shared_memory; Core::HID::EmulatedDevices* emulated_devices = nullptr; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 08ee9de9c..53a737cf5 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -17,12 +17,12 @@ #include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/service/hid/controllers/npad.h" +#include "core/hle/service/hid/controllers/shared_memory_format.h" #include "core/hle/service/hid/errors.h" #include "core/hle/service/hid/hid_util.h" #include "core/hle/service/kernel_helpers.h" namespace Service::HID { -constexpr std::size_t NPAD_OFFSET = 0x9A00; constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{ Core::HID::NpadIdType::Player1, Core::HID::NpadIdType::Player2, Core::HID::NpadIdType::Player3, Core::HID::NpadIdType::Player4, Core::HID::NpadIdType::Player5, Core::HID::NpadIdType::Player6, @@ -30,14 +30,12 @@ constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{ Core::HID::NpadIdType::Handheld, }; -NPad::NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, +NPad::NPad(Core::HID::HIDCore& hid_core_, NpadSharedMemoryFormat& npad_shared_memory_format, KernelHelpers::ServiceContext& service_context_) : ControllerBase{hid_core_}, service_context{service_context_} { - static_assert(NPAD_OFFSET + (NPAD_COUNT * sizeof(NpadInternalState)) < shared_memory_size); for (std::size_t i = 0; i < controller_data.size(); ++i) { auto& controller = controller_data[i]; - controller.shared_memory = std::construct_at(reinterpret_cast<NpadInternalState*>( - raw_shared_memory_ + NPAD_OFFSET + (i * sizeof(NpadInternalState)))); + controller.shared_memory = &npad_shared_memory_format.npad_entry[i].internal_state; controller.device = hid_core.GetEmulatedControllerByIndex(i); controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = Core::HID::DEFAULT_VIBRATION_VALUE; @@ -617,7 +615,7 @@ void NPad::SetHoldType(NpadJoyHoldType joy_hold_type) { hold_type = joy_hold_type; } -NPad::NpadJoyHoldType NPad::GetHoldType() const { +NpadJoyHoldType NPad::GetHoldType() const { return hold_type; } @@ -630,7 +628,7 @@ void NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_m handheld_activation_mode = activation_mode; } -NPad::NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const { +NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const { return handheld_activation_mode; } @@ -638,7 +636,7 @@ void NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) { communication_mode = communication_mode_; } -NPad::NpadCommunicationMode NPad::GetNpadCommunicationMode() const { +NpadCommunicationMode NPad::GetNpadCommunicationMode() const { return communication_mode; } @@ -978,27 +976,27 @@ Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned( return ResultSuccess; } -NPad::SixAxisLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) { +NpadSixAxisSensorLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) { return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_fullkey_lifo; } -NPad::SixAxisLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) { +NpadSixAxisSensorLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) { return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_handheld_lifo; } -NPad::SixAxisLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) { +NpadSixAxisSensorLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) { return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_left_lifo; } -NPad::SixAxisLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) { +NpadSixAxisSensorLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) { return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_right_lifo; } -NPad::SixAxisLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) { +NpadSixAxisSensorLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) { return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_left_lifo; } -NPad::SixAxisLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) { +NpadSixAxisSensorLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) { return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_right_lifo; } @@ -1343,7 +1341,7 @@ const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties( } } -NPad::AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) { +AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) { const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory; return { diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 9167c93f0..19e8becb4 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -13,6 +13,7 @@ #include "core/hid/hid_types.h" #include "core/hle/service/hid/controllers/controller_base.h" +#include "core/hle/service/hid/controllers/types/npad_types.h" #include "core/hle/service/hid/ring_lifo.h" namespace Core::HID { @@ -32,10 +33,13 @@ class ServiceContext; union Result; namespace Service::HID { +struct NpadInternalState; +struct NpadSixAxisSensorLifo; +struct NpadSharedMemoryFormat; class NPad final : public ControllerBase { public: - explicit NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, + explicit NPad(Core::HID::HIDCore& hid_core_, NpadSharedMemoryFormat& npad_shared_memory_format, KernelHelpers::ServiceContext& service_context_); ~NPad() override; @@ -48,89 +52,6 @@ public: // When the controller is requesting an update for the shared memory void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - // This is nn::hid::NpadJoyHoldType - enum class NpadJoyHoldType : u64 { - Vertical = 0, - Horizontal = 1, - }; - - // This is nn::hid::NpadJoyAssignmentMode - enum class NpadJoyAssignmentMode : u32 { - Dual = 0, - Single = 1, - }; - - // This is nn::hid::NpadJoyDeviceType - enum class NpadJoyDeviceType : s64 { - Left = 0, - Right = 1, - }; - - // This is nn::hid::NpadHandheldActivationMode - enum class NpadHandheldActivationMode : u64 { - Dual = 0, - Single = 1, - None = 2, - MaxActivationMode = 3, - }; - - // This is nn::hid::system::AppletFooterUiAttributesSet - struct AppletFooterUiAttributes { - INSERT_PADDING_BYTES(0x4); - }; - - // This is nn::hid::system::AppletFooterUiType - enum class AppletFooterUiType : u8 { - None = 0, - HandheldNone = 1, - HandheldJoyConLeftOnly = 2, - 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, - Lagon = 21, - }; - - using AppletFooterUiVariant = u8; - - // This is "nn::hid::system::AppletDetailedUiType". - struct AppletDetailedUiType { - AppletFooterUiVariant ui_variant; - INSERT_PADDING_BYTES(0x2); - AppletFooterUiType footer; - }; - static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size"); - // This is nn::hid::NpadCommunicationMode - enum class NpadCommunicationMode : u64 { - Mode_5ms = 0, - Mode_10ms = 1, - Mode_15ms = 2, - Default = 3, - }; - - enum class NpadRevision : u32 { - Revision0 = 0, - Revision1 = 1, - Revision2 = 2, - Revision3 = 3, - }; - - using SixAxisLifo = Lifo<Core::HID::SixAxisSensorState, hid_entry_count>; - void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); Core::HID::NpadStyleTag GetSupportedStyleSet() const; @@ -188,12 +109,12 @@ public: Result ResetIsSixAxisSensorDeviceNewlyAssigned( const Core::HID::SixAxisSensorHandle& sixaxis_handle); - SixAxisLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id); - SixAxisLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id); - SixAxisLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id); - SixAxisLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id); - SixAxisLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id); - SixAxisLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id); + NpadSixAxisSensorLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id); + NpadSixAxisSensorLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id); + NpadSixAxisSensorLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id); + NpadSixAxisSensorLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id); + NpadSixAxisSensorLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id); + NpadSixAxisSensorLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id); Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const; Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, @@ -221,214 +142,6 @@ public: AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id); private: - static constexpr std::size_t NPAD_COUNT = 10; - - // This is nn::hid::detail::ColorAttribute - enum class ColorAttribute : u32 { - Ok = 0, - ReadError = 1, - NoController = 2, - }; - static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size"); - - // This is nn::hid::detail::NpadFullKeyColorState - struct NpadFullKeyColorState { - ColorAttribute attribute{ColorAttribute::NoController}; - Core::HID::NpadControllerColor fullkey{}; - }; - static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size"); - - // This is nn::hid::detail::NpadJoyColorState - struct NpadJoyColorState { - ColorAttribute attribute{ColorAttribute::NoController}; - Core::HID::NpadControllerColor left{}; - Core::HID::NpadControllerColor right{}; - }; - static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size"); - - // This is nn::hid::NpadAttribute - struct NpadAttribute { - union { - u32 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(NpadAttribute) == 4, "NpadAttribute is an invalid size"); - - // This is nn::hid::NpadFullKeyState - // This is nn::hid::NpadHandheldState - // This is nn::hid::NpadJoyDualState - // This is nn::hid::NpadJoyLeftState - // This is nn::hid::NpadJoyRightState - // This is nn::hid::NpadPalmaState - // This is nn::hid::NpadSystemExtState - struct NPadGenericState { - s64_le sampling_number{}; - Core::HID::NpadButtonState npad_buttons{}; - Core::HID::AnalogStickState l_stick{}; - Core::HID::AnalogStickState r_stick{}; - NpadAttribute connection_status{}; - INSERT_PADDING_BYTES(4); // Reserved - }; - static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size"); - - // This is nn::hid::server::NpadGcTriggerState - struct NpadGcTriggerState { - s64 sampling_number{}; - s32 l_analog{}; - s32 r_analog{}; - }; - static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size"); - - // This is nn::hid::NpadSystemProperties - struct NPadSystemProperties { - union { - s64 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<12, 1, s64> is_horizontal; - BitField<13, 1, s64> use_plus; - BitField<14, 1, s64> use_minus; - BitField<15, 1, s64> use_directional_buttons; - }; - }; - static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size"); - - // This is nn::hid::NpadSystemButtonProperties - struct NpadSystemButtonProperties { - union { - s32 raw{}; - BitField<0, 1, s32> is_home_button_protection_enabled; - }; - }; - static_assert(sizeof(NpadSystemButtonProperties) == 0x4, - "NPadButtonProperties is an invalid size"); - - // This is nn::hid::system::DeviceType - struct DeviceType { - union { - u32 raw{}; - BitField<0, 1, s32> fullkey; - BitField<1, 1, s32> debug_pad; - BitField<2, 1, s32> handheld_left; - BitField<3, 1, s32> handheld_right; - BitField<4, 1, s32> joycon_left; - BitField<5, 1, s32> joycon_right; - 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<16, 1, s32> lagon; - BitField<17, 1, s32> lager; - BitField<31, 1, s32> system; - }; - }; - - // This is nn::hid::detail::NfcXcdDeviceHandleStateImpl - struct NfcXcdDeviceHandleStateImpl { - u64 handle{}; - bool is_available{}; - bool is_activated{}; - INSERT_PADDING_BYTES(0x6); // Reserved - u64 sampling_number{}; - }; - static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18, - "NfcXcdDeviceHandleStateImpl is an invalid size"); - - // This is nn::hid::NpadLarkType - enum class NpadLarkType : u32 { - Invalid, - H1, - H2, - NL, - NR, - }; - - // This is nn::hid::NpadLuciaType - enum class NpadLuciaType : u32 { - Invalid, - J, - E, - U, - }; - - // This is nn::hid::NpadLagonType - enum class NpadLagonType : u32 { - Invalid, - }; - - // This is nn::hid::NpadLagerType - enum class NpadLagerType : u32 { - Invalid, - J, - E, - U, - }; - - // This is nn::hid::detail::NpadInternalState - struct NpadInternalState { - Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None}; - NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual}; - NpadFullKeyColorState fullkey_color{}; - NpadJoyColorState joycon_color{}; - Lifo<NPadGenericState, hid_entry_count> fullkey_lifo{}; - Lifo<NPadGenericState, hid_entry_count> handheld_lifo{}; - Lifo<NPadGenericState, hid_entry_count> joy_dual_lifo{}; - Lifo<NPadGenericState, hid_entry_count> joy_left_lifo{}; - Lifo<NPadGenericState, hid_entry_count> joy_right_lifo{}; - Lifo<NPadGenericState, hid_entry_count> palma_lifo{}; - Lifo<NPadGenericState, hid_entry_count> system_ext_lifo{}; - Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{}; - Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{}; - Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{}; - Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{}; - Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{}; - Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{}; - DeviceType device_type{}; - INSERT_PADDING_BYTES(0x4); // Reserved - NPadSystemProperties system_properties{}; - NpadSystemButtonProperties button_properties{}; - Core::HID::NpadBatteryLevel battery_level_dual{}; - Core::HID::NpadBatteryLevel battery_level_left{}; - Core::HID::NpadBatteryLevel battery_level_right{}; - AppletFooterUiAttributes applet_footer_attributes{}; - AppletFooterUiType applet_footer_type{AppletFooterUiType::None}; - INSERT_PADDING_BYTES(0x5B); // Reserved - INSERT_PADDING_BYTES(0x20); // Unknown - Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo{}; - NpadLarkType lark_type_l_and_main{}; - NpadLarkType lark_type_r{}; - NpadLuciaType lucia_type{}; - NpadLagonType lagon_type{}; - NpadLagerType lager_type{}; - Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties; - Core::HID::SixAxisSensorProperties sixaxis_handheld_properties; - Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties; - Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties; - Core::HID::SixAxisSensorProperties sixaxis_left_properties; - Core::HID::SixAxisSensorProperties sixaxis_right_properties; - INSERT_PADDING_BYTES(0xc06); // Unknown - }; - static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size"); - struct VibrationData { bool device_mounted{}; Core::HID::VibrationValue latest_vibration_value{}; diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp index 588ff9d62..aa0454b5e 100644 --- a/src/core/hle/service/hid/controllers/palma.cpp +++ b/src/core/hle/service/hid/controllers/palma.cpp @@ -12,8 +12,7 @@ namespace Service::HID { -Palma::Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, - KernelHelpers::ServiceContext& service_context_) +Palma::Palma(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_) : ControllerBase{hid_core_}, service_context{service_context_} { controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent"); diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h index a6047f36a..73884230d 100644 --- a/src/core/hle/service/hid/controllers/palma.h +++ b/src/core/hle/service/hid/controllers/palma.h @@ -97,8 +97,7 @@ public: static_assert(sizeof(PalmaConnectionHandle) == 0x8, "PalmaConnectionHandle has incorrect size."); - explicit Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, - KernelHelpers::ServiceContext& service_context_); + explicit Palma(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_); ~Palma() override; // Called when the controller is initialized diff --git a/src/core/hle/service/hid/controllers/shared_memory_format.h b/src/core/hle/service/hid/controllers/shared_memory_format.h new file mode 100644 index 000000000..63fb46c11 --- /dev/null +++ b/src/core/hle/service/hid/controllers/shared_memory_format.h @@ -0,0 +1,239 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "common/vector_math.h" +#include "core/hid/hid_types.h" +#include "core/hle/service/hid//controllers/types/debug_pad_types.h" +#include "core/hle/service/hid//controllers/types/keyboard_types.h" +#include "core/hle/service/hid//controllers/types/mouse_types.h" +#include "core/hle/service/hid//controllers/types/npad_types.h" +#include "core/hle/service/hid//controllers/types/touch_types.h" +#include "core/hle/service/hid/ring_lifo.h" + +namespace Service::HID { +static const std::size_t HidEntryCount = 17; + +struct CommonHeader { + s64 timestamp{}; + s64 total_entry_count{}; + s64 last_entry_index{}; + s64 entry_count{}; +}; +static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); + +// This is nn::hid::detail::DebugPadSharedMemoryFormat +struct DebugPadSharedMemoryFormat { + // This is nn::hid::detail::DebugPadLifo + Lifo<DebugPadState, HidEntryCount> debug_pad_lifo{}; + static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size"); + INSERT_PADDING_WORDS(0x4E); +}; +static_assert(sizeof(DebugPadSharedMemoryFormat) == 0x400, + "DebugPadSharedMemoryFormat is an invalid size"); + +// This is nn::hid::detail::TouchScreenSharedMemoryFormat +struct TouchScreenSharedMemoryFormat { + // This is nn::hid::detail::TouchScreenLifo + Lifo<TouchScreenState, HidEntryCount> touch_screen_lifo{}; + static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size"); + INSERT_PADDING_WORDS(0xF2); +}; +static_assert(sizeof(TouchScreenSharedMemoryFormat) == 0x3000, + "TouchScreenSharedMemoryFormat is an invalid size"); + +// This is nn::hid::detail::MouseSharedMemoryFormat +struct MouseSharedMemoryFormat { + // This is nn::hid::detail::MouseLifo + Lifo<Core::HID::MouseState, HidEntryCount> mouse_lifo{}; + static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size"); + INSERT_PADDING_WORDS(0x2C); +}; +static_assert(sizeof(MouseSharedMemoryFormat) == 0x400, + "MouseSharedMemoryFormat is an invalid size"); + +// This is nn::hid::detail::KeyboardSharedMemoryFormat +struct KeyboardSharedMemoryFormat { + // This is nn::hid::detail::KeyboardLifo + Lifo<KeyboardState, HidEntryCount> keyboard_lifo{}; + static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size"); + INSERT_PADDING_WORDS(0xA); +}; +static_assert(sizeof(KeyboardSharedMemoryFormat) == 0x400, + "KeyboardSharedMemoryFormat is an invalid size"); + +// This is nn::hid::detail::DigitizerSharedMemoryFormat +struct DigitizerSharedMemoryFormat { + CommonHeader header; + INSERT_PADDING_BYTES(0xFE0); +}; +static_assert(sizeof(DigitizerSharedMemoryFormat) == 0x1000, + "DigitizerSharedMemoryFormat is an invalid size"); + +// This is nn::hid::detail::HomeButtonSharedMemoryFormat +struct HomeButtonSharedMemoryFormat { + CommonHeader header; + INSERT_PADDING_BYTES(0x1E0); +}; +static_assert(sizeof(HomeButtonSharedMemoryFormat) == 0x200, + "HomeButtonSharedMemoryFormat is an invalid size"); + +// This is nn::hid::detail::SleepButtonSharedMemoryFormat +struct SleepButtonSharedMemoryFormat { + CommonHeader header; + INSERT_PADDING_BYTES(0x1E0); +}; +static_assert(sizeof(SleepButtonSharedMemoryFormat) == 0x200, + "SleepButtonSharedMemoryFormat is an invalid size"); + +// This is nn::hid::detail::CaptureButtonSharedMemoryFormat +struct CaptureButtonSharedMemoryFormat { + CommonHeader header; + INSERT_PADDING_BYTES(0x1E0); +}; +static_assert(sizeof(CaptureButtonSharedMemoryFormat) == 0x200, + "CaptureButtonSharedMemoryFormat is an invalid size"); + +// This is nn::hid::detail::InputDetectorSharedMemoryFormat +struct InputDetectorSharedMemoryFormat { + CommonHeader header; + INSERT_PADDING_BYTES(0x7E0); +}; +static_assert(sizeof(InputDetectorSharedMemoryFormat) == 0x800, + "InputDetectorSharedMemoryFormat is an invalid size"); + +// This is nn::hid::detail::UniquePadSharedMemoryFormat +struct UniquePadSharedMemoryFormat { + CommonHeader header; + INSERT_PADDING_BYTES(0x3FE0); +}; +static_assert(sizeof(UniquePadSharedMemoryFormat) == 0x4000, + "UniquePadSharedMemoryFormat is an invalid size"); + +// This is nn::hid::detail::NpadSixAxisSensorLifo +struct NpadSixAxisSensorLifo { + Lifo<Core::HID::SixAxisSensorState, HidEntryCount> lifo; +}; + +// This is nn::hid::detail::NpadInternalState +struct NpadInternalState { + Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None}; + NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual}; + NpadFullKeyColorState fullkey_color{}; + NpadJoyColorState joycon_color{}; + Lifo<NPadGenericState, HidEntryCount> fullkey_lifo{}; + Lifo<NPadGenericState, HidEntryCount> handheld_lifo{}; + Lifo<NPadGenericState, HidEntryCount> joy_dual_lifo{}; + Lifo<NPadGenericState, HidEntryCount> joy_left_lifo{}; + Lifo<NPadGenericState, HidEntryCount> joy_right_lifo{}; + Lifo<NPadGenericState, HidEntryCount> palma_lifo{}; + Lifo<NPadGenericState, HidEntryCount> system_ext_lifo{}; + NpadSixAxisSensorLifo sixaxis_fullkey_lifo{}; + NpadSixAxisSensorLifo sixaxis_handheld_lifo{}; + NpadSixAxisSensorLifo sixaxis_dual_left_lifo{}; + NpadSixAxisSensorLifo sixaxis_dual_right_lifo{}; + NpadSixAxisSensorLifo sixaxis_left_lifo{}; + NpadSixAxisSensorLifo sixaxis_right_lifo{}; + DeviceType device_type{}; + INSERT_PADDING_BYTES(0x4); // Reserved + NPadSystemProperties system_properties{}; + NpadSystemButtonProperties button_properties{}; + Core::HID::NpadBatteryLevel battery_level_dual{}; + Core::HID::NpadBatteryLevel battery_level_left{}; + Core::HID::NpadBatteryLevel battery_level_right{}; + AppletFooterUiAttributes applet_footer_attributes{}; + AppletFooterUiType applet_footer_type{AppletFooterUiType::None}; + INSERT_PADDING_BYTES(0x5B); // Reserved + INSERT_PADDING_BYTES(0x20); // Unknown + Lifo<NpadGcTriggerState, HidEntryCount> gc_trigger_lifo{}; + NpadLarkType lark_type_l_and_main{}; + NpadLarkType lark_type_r{}; + NpadLuciaType lucia_type{}; + NpadLagerType lager_type{}; + Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties; + Core::HID::SixAxisSensorProperties sixaxis_handheld_properties; + Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties; + Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties; + Core::HID::SixAxisSensorProperties sixaxis_left_properties; + Core::HID::SixAxisSensorProperties sixaxis_right_properties; +}; +static_assert(sizeof(NpadInternalState) == 0x43F8, "NpadInternalState is an invalid size"); + +// This is nn::hid::detail::NpadSharedMemoryEntry +struct NpadSharedMemoryEntry { + NpadInternalState internal_state; + INSERT_PADDING_BYTES(0xC08); +}; +static_assert(sizeof(NpadSharedMemoryEntry) == 0x5000, "NpadSharedMemoryEntry is an invalid size"); + +// This is nn::hid::detail::NpadSharedMemoryFormat +struct NpadSharedMemoryFormat { + std::array<NpadSharedMemoryEntry, NPAD_COUNT> npad_entry; +}; +static_assert(sizeof(NpadSharedMemoryFormat) == 0x32000, + "NpadSharedMemoryFormat is an invalid size"); + +// This is nn::hid::detail::GestureSharedMemoryFormat +struct GestureSharedMemoryFormat { + // This is nn::hid::detail::GestureLifo + Lifo<GestureState, HidEntryCount> gesture_lifo{}; + static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size"); + INSERT_PADDING_WORDS(0x3E); +}; +static_assert(sizeof(GestureSharedMemoryFormat) == 0x800, + "GestureSharedMemoryFormat is an invalid size"); + +// This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat +struct ConsoleSixAxisSensorSharedMemoryFormat { + u64 sampling_number{}; + bool is_seven_six_axis_sensor_at_rest{}; + INSERT_PADDING_BYTES(3); // padding + f32 verticalization_error{}; + Common::Vec3f gyro_bias{}; + INSERT_PADDING_BYTES(4); // padding +}; +static_assert(sizeof(ConsoleSixAxisSensorSharedMemoryFormat) == 0x20, + "ConsoleSixAxisSensorSharedMemoryFormat is an invalid size"); + +struct SharedMemoryFormat { + void Initialize() {} + + DebugPadSharedMemoryFormat debug_pad; + TouchScreenSharedMemoryFormat touch_screen; + MouseSharedMemoryFormat mouse; + KeyboardSharedMemoryFormat keyboard; + DigitizerSharedMemoryFormat digitizer; + HomeButtonSharedMemoryFormat home_button; + SleepButtonSharedMemoryFormat sleep_button; + CaptureButtonSharedMemoryFormat capture_button; + InputDetectorSharedMemoryFormat input_detector; + UniquePadSharedMemoryFormat unique_pad; + NpadSharedMemoryFormat npad; + GestureSharedMemoryFormat gesture; + ConsoleSixAxisSensorSharedMemoryFormat console; + INSERT_PADDING_BYTES(0x19E0); + MouseSharedMemoryFormat debug_mouse; + INSERT_PADDING_BYTES(0x2000); +}; +static_assert(offsetof(SharedMemoryFormat, debug_pad) == 0x0, "debug_pad has wrong offset"); +static_assert(offsetof(SharedMemoryFormat, touch_screen) == 0x400, "touch_screen has wrong offset"); +static_assert(offsetof(SharedMemoryFormat, mouse) == 0x3400, "mouse has wrong offset"); +static_assert(offsetof(SharedMemoryFormat, keyboard) == 0x3800, "keyboard has wrong offset"); +static_assert(offsetof(SharedMemoryFormat, digitizer) == 0x3C00, "digitizer has wrong offset"); +static_assert(offsetof(SharedMemoryFormat, home_button) == 0x4C00, "home_button has wrong offset"); +static_assert(offsetof(SharedMemoryFormat, sleep_button) == 0x4E00, + "sleep_button has wrong offset"); +static_assert(offsetof(SharedMemoryFormat, capture_button) == 0x5000, + "capture_button has wrong offset"); +static_assert(offsetof(SharedMemoryFormat, input_detector) == 0x5200, + "input_detector has wrong offset"); +static_assert(offsetof(SharedMemoryFormat, npad) == 0x9A00, "npad has wrong offset"); +static_assert(offsetof(SharedMemoryFormat, gesture) == 0x3BA00, "gesture has wrong offset"); +static_assert(offsetof(SharedMemoryFormat, console) == 0x3C200, "console has wrong offset"); +static_assert(offsetof(SharedMemoryFormat, debug_mouse) == 0x3DC00, "debug_mouse has wrong offset"); +static_assert(sizeof(SharedMemoryFormat) == 0x40000, "SharedMemoryFormat is an invalid size"); + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.cpp b/src/core/hle/service/hid/controllers/shared_memory_holder.cpp new file mode 100644 index 000000000..223487421 --- /dev/null +++ b/src/core/hle/service/hid/controllers/shared_memory_holder.cpp @@ -0,0 +1,49 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/core.h" +#include "core/hle/kernel/k_shared_memory.h" +#include "core/hle/service/hid/controllers/shared_memory_format.h" +#include "core/hle/service/hid/controllers/shared_memory_holder.h" +#include "core/hle/service/hid/errors.h" + +namespace Service::HID { +SharedMemoryHolder::SharedMemoryHolder() {} + +Result SharedMemoryHolder::Initialize(Core::System& system) { + shared_memory = Kernel::KSharedMemory::Create(system.Kernel()); + const Result result = shared_memory->Initialize( + system.DeviceMemory(), nullptr, Kernel::Svc::MemoryPermission::None, + Kernel::Svc::MemoryPermission::Read, sizeof(SharedMemoryFormat)); + if (result.IsError()) { + return result; + } + Kernel::KSharedMemory::Register(system.Kernel(), shared_memory); + + is_created = true; + is_mapped = true; + address = std::construct_at(reinterpret_cast<SharedMemoryFormat*>(shared_memory->GetPointer())); + return ResultSuccess; +} + +void SharedMemoryHolder::Finalize() { + if (address != nullptr) { + shared_memory->Close(); + } + is_created = false; + is_mapped = false; + address = nullptr; +} + +bool SharedMemoryHolder::IsMapped() { + return is_mapped; +} + +SharedMemoryFormat* SharedMemoryHolder::GetAddress() { + return address; +} + +Kernel::KSharedMemory* SharedMemoryHolder::GetHandle() { + return shared_memory; +} +} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.h b/src/core/hle/service/hid/controllers/shared_memory_holder.h new file mode 100644 index 000000000..260402712 --- /dev/null +++ b/src/core/hle/service/hid/controllers/shared_memory_holder.h @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "common/common_types.h" +#include "core/hle/result.h" + +namespace Core { +class System; +} + +namespace Kernel { +class KSharedMemory; +} + +namespace Service::HID { +struct SharedMemoryFormat; + +// This is nn::hid::detail::SharedMemoryHolder +class SharedMemoryHolder { +public: + SharedMemoryHolder(); + + Result Initialize(Core::System& system); + void Finalize(); + + bool IsMapped(); + SharedMemoryFormat* GetAddress(); + Kernel::KSharedMemory* GetHandle(); + +private: + bool is_owner{}; + bool is_created{}; + bool is_mapped{}; + INSERT_PADDING_BYTES(0x5); + Kernel::KSharedMemory* shared_memory; + INSERT_PADDING_BYTES(0x38); + SharedMemoryFormat* address = nullptr; +}; +// Correct size is 0x50 bytes +static_assert(sizeof(SharedMemoryHolder) == 0x50, "SharedMemoryHolder is an invalid size"); + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/six_axis.cpp b/src/core/hle/service/hid/controllers/six_axis.cpp index 3d24a5c04..36b72f9ea 100644 --- a/src/core/hle/service/hid/controllers/six_axis.cpp +++ b/src/core/hle/service/hid/controllers/six_axis.cpp @@ -6,6 +6,7 @@ #include "core/hid/emulated_controller.h" #include "core/hid/hid_core.h" #include "core/hle/service/hid/controllers/npad.h" +#include "core/hle/service/hid/controllers/shared_memory_format.h" #include "core/hle/service/hid/controllers/six_axis.h" #include "core/hle/service/hid/errors.h" #include "core/hle/service/hid/hid_util.h" @@ -132,30 +133,30 @@ void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { } sixaxis_fullkey_state.sampling_number = - sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; + sixaxis_fullkey_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; sixaxis_handheld_state.sampling_number = - sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; + sixaxis_handheld_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; sixaxis_dual_left_state.sampling_number = - sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1; + sixaxis_dual_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; sixaxis_dual_right_state.sampling_number = - sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1; + sixaxis_dual_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; sixaxis_left_lifo_state.sampling_number = - sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1; + sixaxis_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; sixaxis_right_lifo_state.sampling_number = - sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1; + sixaxis_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) { // This buffer only is updated on handheld on HW - sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state); + sixaxis_handheld_lifo.lifo.WriteNextEntry(sixaxis_handheld_state); } else { // Handheld doesn't update this buffer on HW - sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state); + sixaxis_fullkey_lifo.lifo.WriteNextEntry(sixaxis_fullkey_state); } - sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state); - sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state); - sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state); - sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state); + sixaxis_dual_left_lifo.lifo.WriteNextEntry(sixaxis_dual_left_state); + sixaxis_dual_right_lifo.lifo.WriteNextEntry(sixaxis_dual_right_state); + sixaxis_left_lifo.lifo.WriteNextEntry(sixaxis_left_lifo_state); + sixaxis_right_lifo.lifo.WriteNextEntry(sixaxis_right_lifo_state); } } diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp index 9e2f3ab21..26001e914 100644 --- a/src/core/hle/service/hid/controllers/stubbed.cpp +++ b/src/core/hle/service/hid/controllers/stubbed.cpp @@ -4,15 +4,14 @@ #include <cstring> #include "common/common_types.h" #include "core/core_timing.h" -#include "core/hid/hid_core.h" +#include "core/hle/service/hid/controllers/shared_memory_format.h" #include "core/hle/service/hid/controllers/stubbed.h" namespace Service::HID { -Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) - : ControllerBase{hid_core_} { - raw_shared_memory = raw_shared_memory_; -} +Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_, + CommonHeader& ring_lifo_header) + : ControllerBase{hid_core_}, header{ring_lifo_header} {} Controller_Stubbed::~Controller_Stubbed() = default; @@ -25,18 +24,10 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing) { return; } - CommonHeader header{}; header.timestamp = core_timing.GetGlobalTimeNs().count(); header.total_entry_count = 17; header.entry_count = 0; header.last_entry_index = 0; - - std::memcpy(raw_shared_memory + common_offset, &header, sizeof(CommonHeader)); -} - -void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) { - common_offset = off; - smart_update = true; } } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/stubbed.h b/src/core/hle/service/hid/controllers/stubbed.h index 1483a968e..bdf35d84b 100644 --- a/src/core/hle/service/hid/controllers/stubbed.h +++ b/src/core/hle/service/hid/controllers/stubbed.h @@ -7,9 +7,11 @@ #include "core/hle/service/hid/controllers/controller_base.h" namespace Service::HID { +struct CommonHeader; + class Controller_Stubbed final : public ControllerBase { public: - explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); + explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, CommonHeader& ring_lifo_header); ~Controller_Stubbed() override; // Called when the controller is initialized @@ -21,19 +23,8 @@ public: // When the controller is requesting an update for the shared memory void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - void SetCommonHeaderOffset(std::size_t off); - private: - struct CommonHeader { - s64 timestamp{}; - s64 total_entry_count{}; - s64 last_entry_index{}; - s64 entry_count{}; - }; - static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); - - u8* raw_shared_memory = nullptr; + CommonHeader& header; bool smart_update{}; - std::size_t common_offset{}; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index fcd973414..a98f1f85e 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp @@ -10,18 +10,16 @@ #include "core/frontend/emu_window.h" #include "core/hid/emulated_console.h" #include "core/hid/hid_core.h" +#include "core/hle/service/hid/controllers/shared_memory_format.h" #include "core/hle/service/hid/controllers/touchscreen.h" namespace Service::HID { -constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400; -TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) - : ControllerBase{hid_core_}, touchscreen_width(Layout::ScreenUndocked::Width), +TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_, + TouchScreenSharedMemoryFormat& touch_shared_memory) + : ControllerBase{hid_core_}, shared_memory{touch_shared_memory}, + touchscreen_width(Layout::ScreenUndocked::Width), touchscreen_height(Layout::ScreenUndocked::Height) { - static_assert(SHARED_MEMORY_OFFSET + sizeof(TouchSharedMemory) < shared_memory_size, - "TouchSharedMemory is bigger than the shared memory"); - shared_memory = std::construct_at( - reinterpret_cast<TouchSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); console = hid_core.GetEmulatedConsole(); } @@ -32,11 +30,11 @@ void TouchScreen::OnInit() {} void TouchScreen::OnRelease() {} void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - shared_memory->touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count(); + shared_memory.touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count(); if (!IsControllerActivated()) { - shared_memory->touch_screen_lifo.buffer_count = 0; - shared_memory->touch_screen_lifo.buffer_tail = 0; + shared_memory.touch_screen_lifo.buffer_count = 0; + shared_memory.touch_screen_lifo.buffer_tail = 0; return; } @@ -86,7 +84,7 @@ void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); const u64 timestamp = static_cast<u64>(core_timing.GetGlobalTimeNs().count()); - const auto& last_entry = shared_memory->touch_screen_lifo.ReadCurrentEntry().state; + const auto& last_entry = shared_memory.touch_screen_lifo.ReadCurrentEntry().state; next_state.sampling_number = last_entry.sampling_number + 1; next_state.entry_count = static_cast<s32>(active_fingers_count); @@ -118,7 +116,7 @@ void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { } } - shared_memory->touch_screen_lifo.WriteNextEntry(next_state); + shared_memory.touch_screen_lifo.WriteNextEntry(next_state); } void TouchScreen::SetTouchscreenDimensions(u32 width, u32 height) { diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index 79f026a81..63513404b 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h @@ -3,10 +3,12 @@ #pragma once -#include "common/common_funcs.h" +#include <array> + #include "common/common_types.h" #include "core/hid/hid_types.h" #include "core/hle/service/hid/controllers/controller_base.h" +#include "core/hle/service/hid/controllers/types/touch_types.h" #include "core/hle/service/hid/ring_lifo.h" namespace Core::HID { @@ -14,9 +16,12 @@ class EmulatedConsole; } // namespace Core::HID namespace Service::HID { +struct TouchScreenSharedMemoryFormat; + class TouchScreen final : public ControllerBase { public: - explicit TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); + explicit TouchScreen(Core::HID::HIDCore& hid_core_, + TouchScreenSharedMemoryFormat& touch_shared_memory); ~TouchScreen() override; // Called when the controller is initialized @@ -31,27 +36,8 @@ public: void SetTouchscreenDimensions(u32 width, u32 height); private: - static constexpr std::size_t MAX_FINGERS = 16; - - // This is nn::hid::TouchScreenState - struct TouchScreenState { - s64 sampling_number{}; - s32 entry_count{}; - INSERT_PADDING_BYTES(4); // Reserved - std::array<Core::HID::TouchState, MAX_FINGERS> states{}; - }; - static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size"); - - struct TouchSharedMemory { - // This is nn::hid::detail::TouchScreenLifo - Lifo<TouchScreenState, hid_entry_count> touch_screen_lifo{}; - static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size"); - INSERT_PADDING_WORDS(0xF2); - }; - static_assert(sizeof(TouchSharedMemory) == 0x3000, "TouchSharedMemory is an invalid size"); - TouchScreenState next_state{}; - TouchSharedMemory* shared_memory = nullptr; + TouchScreenSharedMemoryFormat& shared_memory; Core::HID::EmulatedConsole* console = nullptr; std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{}; diff --git a/src/core/hle/service/hid/controllers/types/debug_pad_types.h b/src/core/hle/service/hid/controllers/types/debug_pad_types.h new file mode 100644 index 000000000..a96171b62 --- /dev/null +++ b/src/core/hle/service/hid/controllers/types/debug_pad_types.h @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "common/bit_field.h" +#include "common/common_types.h" +#include "core/hid/hid_types.h" + +namespace Service::HID { + +// This is nn::hid::DebugPadAttribute +struct DebugPadAttribute { + union { + u32 raw{}; + BitField<0, 1, u32> connected; + }; +}; +static_assert(sizeof(DebugPadAttribute) == 0x4, "DebugPadAttribute is an invalid size"); + +// This is nn::hid::DebugPadState +struct DebugPadState { + s64 sampling_number{}; + DebugPadAttribute attribute{}; + Core::HID::DebugPadButton pad_state{}; + Core::HID::AnalogStickState r_stick{}; + Core::HID::AnalogStickState l_stick{}; +}; +static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state"); + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/types/gesture_types.h b/src/core/hle/service/hid/controllers/types/gesture_types.h new file mode 100644 index 000000000..b4f034cd3 --- /dev/null +++ b/src/core/hle/service/hid/controllers/types/gesture_types.h @@ -0,0 +1,77 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <array> +#include "common/bit_field.h" +#include "common/common_types.h" +#include "common/point.h" + +namespace Service::HID { +static constexpr size_t MAX_FINGERS = 16; +static constexpr size_t MAX_POINTS = 4; + +// This is nn::hid::GestureType +enum class GestureType : u32 { + Idle, // Nothing touching the screen + Complete, // Set at the end of a touch event + Cancel, // Set when the number of fingers change + Touch, // A finger just touched the screen + Press, // Set if last type is touch and the finger hasn't moved + Tap, // Fast press then release + Pan, // All points moving together across the screen + Swipe, // Fast press movement and release of a single point + Pinch, // All points moving away/closer to the midpoint + Rotate, // All points rotating from the midpoint +}; + +// This is nn::hid::GestureDirection +enum class GestureDirection : u32 { + None, + Left, + Up, + Right, + Down, +}; + +// This is nn::hid::GestureAttribute +struct GestureAttribute { + union { + u32 raw{}; + + BitField<4, 1, u32> is_new_touch; + BitField<8, 1, u32> is_double_tap; + }; +}; +static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); + +// This is nn::hid::GestureState +struct GestureState { + s64 sampling_number{}; + s64 detection_count{}; + GestureType type{GestureType::Idle}; + GestureDirection direction{GestureDirection::None}; + Common::Point<s32> pos{}; + Common::Point<s32> delta{}; + f32 vel_x{}; + f32 vel_y{}; + GestureAttribute attributes{}; + f32 scale{}; + f32 rotation_angle{}; + s32 point_count{}; + std::array<Common::Point<s32>, 4> points{}; +}; +static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); + +struct GestureProperties { + std::array<Common::Point<s32>, MAX_POINTS> points{}; + std::size_t active_points{}; + Common::Point<s32> mid_point{}; + s64 detection_count{}; + u64 delta_time{}; + f32 average_distance{}; + f32 angle{}; +}; + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/types/keyboard_types.h b/src/core/hle/service/hid/controllers/types/keyboard_types.h new file mode 100644 index 000000000..f44a536b9 --- /dev/null +++ b/src/core/hle/service/hid/controllers/types/keyboard_types.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "common/common_types.h" +#include "core/hid/hid_types.h" + +namespace Service::HID { + +// This is nn::hid::detail::KeyboardState +struct KeyboardState { + s64 sampling_number{}; + Core::HID::KeyboardModifier modifier{}; + Core::HID::KeyboardAttribute attribute{}; + Core::HID::KeyboardKey key{}; +}; +static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size"); + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/types/mouse_types.h b/src/core/hle/service/hid/controllers/types/mouse_types.h new file mode 100644 index 000000000..fb9c7703a --- /dev/null +++ b/src/core/hle/service/hid/controllers/types/mouse_types.h @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "common/vector_math.h" +#include "core/hid/hid_types.h" +#include "core/hle/service/hid/ring_lifo.h" + +namespace Service::HID {} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/types/npad_types.h b/src/core/hle/service/hid/controllers/types/npad_types.h new file mode 100644 index 000000000..9eb98ccef --- /dev/null +++ b/src/core/hle/service/hid/controllers/types/npad_types.h @@ -0,0 +1,255 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "common/vector_math.h" +#include "core/hid/hid_types.h" +#include "core/hle/service/hid/ring_lifo.h" + +namespace Service::HID { +static constexpr std::size_t NPAD_COUNT = 10; + +// This is nn::hid::NpadJoyHoldType +enum class NpadJoyHoldType : u64 { + Vertical = 0, + Horizontal = 1, +}; + +// This is nn::hid::NpadJoyAssignmentMode +enum class NpadJoyAssignmentMode : u32 { + Dual = 0, + Single = 1, +}; + +// This is nn::hid::NpadJoyDeviceType +enum class NpadJoyDeviceType : s64 { + Left = 0, + Right = 1, +}; + +// This is nn::hid::NpadHandheldActivationMode +enum class NpadHandheldActivationMode : u64 { + Dual = 0, + Single = 1, + None = 2, + MaxActivationMode = 3, +}; + +// This is nn::hid::system::AppletFooterUiAttributesSet +struct AppletFooterUiAttributes { + INSERT_PADDING_BYTES(0x4); +}; + +// This is nn::hid::system::AppletFooterUiType +enum class AppletFooterUiType : u8 { + None = 0, + HandheldNone = 1, + HandheldJoyConLeftOnly = 2, + 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, + Lagon = 21, +}; + +using AppletFooterUiVariant = u8; + +// This is "nn::hid::system::AppletDetailedUiType". +struct AppletDetailedUiType { + AppletFooterUiVariant ui_variant; + INSERT_PADDING_BYTES(0x2); + AppletFooterUiType footer; +}; +static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size"); +// This is nn::hid::NpadCommunicationMode +enum class NpadCommunicationMode : u64 { + Mode_5ms = 0, + Mode_10ms = 1, + Mode_15ms = 2, + Default = 3, +}; + +enum class NpadRevision : u32 { + Revision0 = 0, + Revision1 = 1, + Revision2 = 2, + Revision3 = 3, +}; + +// This is nn::hid::detail::ColorAttribute +enum class ColorAttribute : u32 { + Ok = 0, + ReadError = 1, + NoController = 2, +}; +static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size"); + +// This is nn::hid::detail::NpadFullKeyColorState +struct NpadFullKeyColorState { + ColorAttribute attribute{ColorAttribute::NoController}; + Core::HID::NpadControllerColor fullkey{}; +}; +static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size"); + +// This is nn::hid::detail::NpadJoyColorState +struct NpadJoyColorState { + ColorAttribute attribute{ColorAttribute::NoController}; + Core::HID::NpadControllerColor left{}; + Core::HID::NpadControllerColor right{}; +}; +static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size"); + +// This is nn::hid::NpadAttribute +struct NpadAttribute { + union { + u32 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(NpadAttribute) == 4, "NpadAttribute is an invalid size"); + +// This is nn::hid::NpadFullKeyState +// This is nn::hid::NpadHandheldState +// This is nn::hid::NpadJoyDualState +// This is nn::hid::NpadJoyLeftState +// This is nn::hid::NpadJoyRightState +// This is nn::hid::NpadPalmaState +// This is nn::hid::NpadSystemExtState +struct NPadGenericState { + s64_le sampling_number{}; + Core::HID::NpadButtonState npad_buttons{}; + Core::HID::AnalogStickState l_stick{}; + Core::HID::AnalogStickState r_stick{}; + NpadAttribute connection_status{}; + INSERT_PADDING_BYTES(4); // Reserved +}; +static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size"); + +// This is nn::hid::server::NpadGcTriggerState +struct NpadGcTriggerState { + s64 sampling_number{}; + s32 l_analog{}; + s32 r_analog{}; +}; +static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size"); + +// This is nn::hid::NpadSystemProperties +struct NPadSystemProperties { + union { + s64 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<12, 1, s64> is_horizontal; + BitField<13, 1, s64> use_plus; + BitField<14, 1, s64> use_minus; + BitField<15, 1, s64> use_directional_buttons; + }; +}; +static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size"); + +// This is nn::hid::NpadSystemButtonProperties +struct NpadSystemButtonProperties { + union { + s32 raw{}; + BitField<0, 1, s32> is_home_button_protection_enabled; + }; +}; +static_assert(sizeof(NpadSystemButtonProperties) == 0x4, "NPadButtonProperties is an invalid size"); + +// This is nn::hid::system::DeviceType +struct DeviceType { + union { + u32 raw{}; + BitField<0, 1, s32> fullkey; + BitField<1, 1, s32> debug_pad; + BitField<2, 1, s32> handheld_left; + BitField<3, 1, s32> handheld_right; + BitField<4, 1, s32> joycon_left; + BitField<5, 1, s32> joycon_right; + 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<16, 1, s32> lagon; + BitField<17, 1, s32> lager; + BitField<31, 1, s32> system; + }; +}; + +// This is nn::hid::detail::NfcXcdDeviceHandleStateImpl +struct NfcXcdDeviceHandleStateImpl { + u64 handle{}; + bool is_available{}; + bool is_activated{}; + INSERT_PADDING_BYTES(0x6); // Reserved + u64 sampling_number{}; +}; +static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18, + "NfcXcdDeviceHandleStateImpl is an invalid size"); + +// This is nn::hid::NpadLarkType +enum class NpadLarkType : u32 { + Invalid, + H1, + H2, + NL, + NR, +}; + +// This is nn::hid::NpadLuciaType +enum class NpadLuciaType : u32 { + Invalid, + J, + E, + U, +}; + +// This is nn::hid::NpadLagonType +enum class NpadLagonType : u32 { + Invalid, +}; + +// This is nn::hid::NpadLagerType +enum class NpadLagerType : u32 { + Invalid, + J, + E, + U, +}; + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/types/touch_types.h b/src/core/hle/service/hid/controllers/types/touch_types.h new file mode 100644 index 000000000..efeaa796d --- /dev/null +++ b/src/core/hle/service/hid/controllers/types/touch_types.h @@ -0,0 +1,90 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <array> + +#include <array> +#include "common/bit_field.h" +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "common/point.h" +#include "core/hid/hid_types.h" + +namespace Service::HID { +static constexpr std::size_t MAX_FINGERS = 16; +static constexpr size_t MAX_POINTS = 4; + +// This is nn::hid::GestureType +enum class GestureType : u32 { + Idle, // Nothing touching the screen + Complete, // Set at the end of a touch event + Cancel, // Set when the number of fingers change + Touch, // A finger just touched the screen + Press, // Set if last type is touch and the finger hasn't moved + Tap, // Fast press then release + Pan, // All points moving together across the screen + Swipe, // Fast press movement and release of a single point + Pinch, // All points moving away/closer to the midpoint + Rotate, // All points rotating from the midpoint +}; + +// This is nn::hid::GestureDirection +enum class GestureDirection : u32 { + None, + Left, + Up, + Right, + Down, +}; + +// This is nn::hid::GestureAttribute +struct GestureAttribute { + union { + u32 raw{}; + + BitField<4, 1, u32> is_new_touch; + BitField<8, 1, u32> is_double_tap; + }; +}; +static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); + +// This is nn::hid::GestureState +struct GestureState { + s64 sampling_number{}; + s64 detection_count{}; + GestureType type{GestureType::Idle}; + GestureDirection direction{GestureDirection::None}; + Common::Point<s32> pos{}; + Common::Point<s32> delta{}; + f32 vel_x{}; + f32 vel_y{}; + GestureAttribute attributes{}; + f32 scale{}; + f32 rotation_angle{}; + s32 point_count{}; + std::array<Common::Point<s32>, 4> points{}; +}; +static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); + +struct GestureProperties { + std::array<Common::Point<s32>, MAX_POINTS> points{}; + std::size_t active_points{}; + Common::Point<s32> mid_point{}; + s64 detection_count{}; + u64 delta_time{}; + f32 average_distance{}; + f32 angle{}; +}; + +// This is nn::hid::TouchScreenState +struct TouchScreenState { + s64 sampling_number{}; + s32 entry_count{}; + INSERT_PADDING_BYTES(4); // Reserved + std::array<Core::HID::TouchState, MAX_FINGERS> states{}; +}; +static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size"); + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp deleted file mode 100644 index 0aaed1fa7..000000000 --- a/src/core/hle/service/hid/controllers/xpad.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <cstring> -#include "common/common_types.h" -#include "core/core_timing.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/controllers/xpad.h" - -namespace Service::HID { -constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00; - -XPad::XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} { - static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size, - "XpadSharedMemory is bigger than the shared memory"); - shared_memory = std::construct_at( - reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); -} -XPad::~XPad() = default; - -void XPad::OnInit() {} - -void XPad::OnRelease() {} - -void XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - if (!IsControllerActivated()) { - shared_memory->basic_xpad_lifo.buffer_count = 0; - shared_memory->basic_xpad_lifo.buffer_tail = 0; - return; - } - - const auto& last_entry = shared_memory->basic_xpad_lifo.ReadCurrentEntry().state; - next_state.sampling_number = last_entry.sampling_number + 1; - // TODO(ogniK): Update xpad states - - shared_memory->basic_xpad_lifo.WriteNextEntry(next_state); -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h deleted file mode 100644 index 9e63a317a..000000000 --- a/src/core/hle/service/hid/controllers/xpad.h +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/bit_field.h" -#include "common/common_types.h" -#include "core/hid/hid_types.h" -#include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/hid/ring_lifo.h" - -namespace Service::HID { -class XPad final : public ControllerBase { -public: - explicit XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); - ~XPad() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - -private: - // This is nn::hid::BasicXpadAttributeSet - struct BasicXpadAttributeSet { - union { - u32 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(BasicXpadAttributeSet) == 4, "BasicXpadAttributeSet is an invalid size"); - - // This is nn::hid::BasicXpadButtonSet - struct BasicXpadButtonSet { - union { - u32 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(BasicXpadButtonSet) == 4, "BasicXpadButtonSet is an invalid size"); - - // This is nn::hid::detail::BasicXpadState - struct BasicXpadState { - s64 sampling_number{}; - BasicXpadAttributeSet attributes{}; - BasicXpadButtonSet pad_states{}; - Core::HID::AnalogStickState l_stick{}; - Core::HID::AnalogStickState r_stick{}; - }; - static_assert(sizeof(BasicXpadState) == 0x20, "BasicXpadState is an invalid size"); - - struct XpadSharedMemory { - // This is nn::hid::detail::BasicXpadLifo - Lifo<BasicXpadState, hid_entry_count> basic_xpad_lifo{}; - static_assert(sizeof(basic_xpad_lifo) == 0x2C8, "basic_xpad_lifo is an invalid size"); - INSERT_PADDING_WORDS(0x4E); - }; - static_assert(sizeof(XpadSharedMemory) == 0x400, "XpadSharedMemory is an invalid size"); - - BasicXpadState next_state{}; - XpadSharedMemory* shared_memory = nullptr; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp index b06ea467e..de24b0401 100644 --- a/src/core/hle/service/hid/hid_server.cpp +++ b/src/core/hle/service/hid/hid_server.cpp @@ -28,6 +28,7 @@ #include "core/hle/service/hid/controllers/seven_six_axis.h" #include "core/hle/service/hid/controllers/six_axis.h" #include "core/hle/service/hid/controllers/touchscreen.h" +#include "core/hle/service/hid/controllers/types/npad_types.h" namespace Service::HID { @@ -1099,7 +1100,7 @@ void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) { void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; struct Parameters { - NPad::NpadRevision revision; + NpadRevision revision; INSERT_PADDING_WORDS_NOINIT(1); u64 applet_resource_user_id; }; @@ -1122,7 +1123,7 @@ void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) { void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop<u64>()}; - const auto hold_type{rp.PopEnum<NPad::NpadJoyHoldType>()}; + const auto hold_type{rp.PopEnum<NpadJoyHoldType>()}; GetResourceManager()->GetNpad()->SetHoldType(hold_type); @@ -1157,8 +1158,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) Core::HID::NpadIdType new_npad_id{}; auto controller = GetResourceManager()->GetNpad(); - controller->SetNpadMode(new_npad_id, parameters.npad_id, NPad::NpadJoyDeviceType::Left, - NPad::NpadJoyAssignmentMode::Single); + controller->SetNpadMode(new_npad_id, parameters.npad_id, NpadJoyDeviceType::Left, + NpadJoyAssignmentMode::Single); LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, parameters.applet_resource_user_id); @@ -1173,7 +1174,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) { Core::HID::NpadIdType npad_id; INSERT_PADDING_WORDS_NOINIT(1); u64 applet_resource_user_id; - NPad::NpadJoyDeviceType npad_joy_device_type; + NpadJoyDeviceType npad_joy_device_type; }; static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); @@ -1182,7 +1183,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) { Core::HID::NpadIdType new_npad_id{}; auto controller = GetResourceManager()->GetNpad(); controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, - NPad::NpadJoyAssignmentMode::Single); + NpadJoyAssignmentMode::Single); LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", parameters.npad_id, parameters.applet_resource_user_id, @@ -1205,7 +1206,7 @@ void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) { Core::HID::NpadIdType new_npad_id{}; auto controller = GetResourceManager()->GetNpad(); - controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NPad::NpadJoyAssignmentMode::Dual); + controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NpadJoyAssignmentMode::Dual); LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, parameters.applet_resource_user_id); // Spams a lot when controller applet is open @@ -1257,7 +1258,7 @@ void IHidServer::StopLrAssignmentMode(HLERequestContext& ctx) { void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop<u64>()}; - const auto activation_mode{rp.PopEnum<NPad::NpadHandheldActivationMode>()}; + const auto activation_mode{rp.PopEnum<NpadHandheldActivationMode>()}; GetResourceManager()->GetNpad()->SetNpadHandheldActivationMode(activation_mode); @@ -1349,7 +1350,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext Core::HID::NpadIdType npad_id; INSERT_PADDING_WORDS_NOINIT(1); u64 applet_resource_user_id; - NPad::NpadJoyDeviceType npad_joy_device_type; + NpadJoyDeviceType npad_joy_device_type; }; static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); @@ -1359,7 +1360,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext auto controller = GetResourceManager()->GetNpad(); const auto is_reassigned = controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, - NPad::NpadJoyAssignmentMode::Single); + NpadJoyAssignmentMode::Single); LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", parameters.npad_id, parameters.applet_resource_user_id, @@ -2315,7 +2316,7 @@ void IHidServer::SetDisallowedPalmaConnection(HLERequestContext& ctx) { void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop<u64>()}; - const auto communication_mode{rp.PopEnum<NPad::NpadCommunicationMode>()}; + const auto communication_mode{rp.PopEnum<NpadCommunicationMode>()}; GetResourceManager()->GetNpad()->SetNpadCommunicationMode(communication_mode); diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp index 4d33456a3..5cc88c4a1 100644 --- a/src/core/hle/service/hid/hid_system_server.cpp +++ b/src/core/hle/service/hid/hid_system_server.cpp @@ -5,6 +5,7 @@ #include "core/hle/service/hid/controllers/npad.h" #include "core/hle/service/hid/controllers/palma.h" #include "core/hle/service/hid/controllers/touchscreen.h" +#include "core/hle/service/hid/controllers/types/npad_types.h" #include "core/hle/service/hid/errors.h" #include "core/hle/service/hid/hid_system_server.h" #include "core/hle/service/hid/resource_manager.h" @@ -328,7 +329,7 @@ void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) { LOG_DEBUG(Service_HID, "called, npad_id_type={}", npad_id_type); // Spams a lot when controller applet is running - const NPad::AppletDetailedUiType detailed_ui_type = + const AppletDetailedUiType detailed_ui_type = GetResourceManager()->GetNpad()->GetAppletDetailedUiType(npad_id_type); IPC::ResponseBuilder rb{ctx, 3}; diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp index 89cdc19cc..0cfe30fde 100644 --- a/src/core/hle/service/hid/resource_manager.cpp +++ b/src/core/hle/service/hid/resource_manager.cpp @@ -18,10 +18,10 @@ #include "core/hle/service/hid/controllers/npad.h" #include "core/hle/service/hid/controllers/palma.h" #include "core/hle/service/hid/controllers/seven_six_axis.h" +#include "core/hle/service/hid/controllers/shared_memory_format.h" #include "core/hle/service/hid/controllers/six_axis.h" #include "core/hle/service/hid/controllers/stubbed.h" #include "core/hle/service/hid/controllers/touchscreen.h" -#include "core/hle/service/hid/controllers/xpad.h" namespace Service::HID { @@ -45,40 +45,43 @@ void ResourceManager::Initialize() { return; } - u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer(); - debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory); - mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory); - debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory); - keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory); - unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory); - npad = std::make_shared<NPad>(system.HIDCore(), shared_memory, service_context); - gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory); - touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory); - xpad = std::make_shared<XPad>(system.HIDCore(), shared_memory); + system.HIDCore().ReloadInputDevices(); + is_initialized = true; +} + +void ResourceManager::InitializeController(u64 aruid) { + SharedMemoryFormat* shared_memory = nullptr; + const auto result = applet_resource->GetSharedMemoryFormat(&shared_memory, aruid); + if (result.IsError()) { + return; + } + + debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory->debug_pad); + mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory->mouse); + debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory->debug_mouse); + keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory->keyboard); + unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory->unique_pad.header); + npad = std::make_shared<NPad>(system.HIDCore(), shared_memory->npad, service_context); + gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory->gesture); + touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory->touch_screen); - palma = std::make_shared<Palma>(system.HIDCore(), shared_memory, service_context); + palma = std::make_shared<Palma>(system.HIDCore(), service_context); - home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory); - sleep_button = std::make_shared<SleepButton>(system.HIDCore(), shared_memory); - capture_button = std::make_shared<CaptureButton>(system.HIDCore(), shared_memory); + home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory->home_button.header); + sleep_button = + std::make_shared<SleepButton>(system.HIDCore(), shared_memory->sleep_button.header); + capture_button = + std::make_shared<CaptureButton>(system.HIDCore(), shared_memory->capture_button.header); + digitizer = std::make_shared<Digitizer>(system.HIDCore(), shared_memory->digitizer.header); six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad); - console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory); + console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory->console); seven_six_axis = std::make_shared<SevenSixAxis>(system); - home_button->SetCommonHeaderOffset(0x4C00); - sleep_button->SetCommonHeaderOffset(0x4E00); - capture_button->SetCommonHeaderOffset(0x5000); - unique_pad->SetCommonHeaderOffset(0x5A00); - debug_mouse->SetCommonHeaderOffset(0x3DC00); - // Homebrew doesn't try to activate some controllers, so we activate them by default npad->Activate(); six_axis->Activate(); touch_screen->Activate(); - - system.HIDCore().ReloadInputDevices(); - is_initialized = true; } std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const { @@ -101,6 +104,10 @@ std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() const { return debug_pad; } +std::shared_ptr<Digitizer> ResourceManager::GetDigitizer() const { + return digitizer; +} + std::shared_ptr<Gesture> ResourceManager::GetGesture() const { return gesture; } @@ -163,7 +170,11 @@ Result ResourceManager::CreateAppletResource(u64 aruid) { Result ResourceManager::CreateAppletResourceImpl(u64 aruid) { std::scoped_lock lock{shared_mutex}; - return applet_resource->CreateAppletResource(aruid); + const auto result = applet_resource->CreateAppletResource(aruid); + if (result.IsSuccess()) { + InitializeController(aruid); + } + return result; } Result ResourceManager::RegisterCoreAppletResource() { @@ -227,7 +238,6 @@ void ResourceManager::UpdateControllers(std::uintptr_t user_data, home_button->OnUpdate(core_timing); sleep_button->OnUpdate(core_timing); capture_button->OnUpdate(core_timing); - xpad->OnUpdate(core_timing); } void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h index 15c1beb1a..5ad7cb564 100644 --- a/src/core/hle/service/hid/resource_manager.h +++ b/src/core/hle/service/hid/resource_manager.h @@ -31,10 +31,10 @@ class Palma; class SevenSixAxis; class SixAxis; class TouchScreen; -class XPad; using CaptureButton = Controller_Stubbed; -using DebugMouse = Controller_Stubbed; +using DebugMouse = Mouse; +using Digitizer = Controller_Stubbed; using HomeButton = Controller_Stubbed; using SleepButton = Controller_Stubbed; using UniquePad = Controller_Stubbed; @@ -46,12 +46,14 @@ public: ~ResourceManager(); void Initialize(); + void InitializeController(u64 aruid); std::shared_ptr<AppletResource> GetAppletResource() const; std::shared_ptr<CaptureButton> GetCaptureButton() const; std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const; std::shared_ptr<DebugMouse> GetDebugMouse() const; std::shared_ptr<DebugPad> GetDebugPad() const; + std::shared_ptr<Digitizer> GetDigitizer() const; std::shared_ptr<Gesture> GetGesture() const; std::shared_ptr<HomeButton> GetHomeButton() const; std::shared_ptr<Keyboard> GetKeyboard() const; @@ -96,6 +98,7 @@ private: std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr; std::shared_ptr<DebugMouse> debug_mouse = nullptr; std::shared_ptr<DebugPad> debug_pad = nullptr; + std::shared_ptr<Digitizer> digitizer = nullptr; std::shared_ptr<Gesture> gesture = nullptr; std::shared_ptr<HomeButton> home_button = nullptr; std::shared_ptr<Keyboard> keyboard = nullptr; @@ -107,7 +110,6 @@ private: std::shared_ptr<SleepButton> sleep_button = nullptr; std::shared_ptr<TouchScreen> touch_screen = nullptr; std::shared_ptr<UniquePad> unique_pad = nullptr; - std::shared_ptr<XPad> xpad = nullptr; // TODO: Create these resources // std::shared_ptr<AudioControl> audio_control = nullptr; |