From 64f68e96354df3afb9bb563c888793f98ecb5026 Mon Sep 17 00:00:00 2001
From: Narr the Reg <juangerman-13@hotmail.com>
Date: Wed, 13 Dec 2023 21:39:38 -0600
Subject: [PATCH] service: hid: Allow to create multiple instances of shared
 memory

---
 src/core/CMakeLists.txt                       |  10 +-
 src/core/hle/kernel/kernel.cpp                |  15 -
 src/core/hle/kernel/kernel.h                  |   6 -
 .../hid/controllers/applet_resource.cpp       |  39 ++-
 .../service/hid/controllers/applet_resource.h |   7 +-
 .../hid/controllers/console_six_axis.cpp      |  19 +-
 .../hid/controllers/console_six_axis.h        |  19 +-
 .../service/hid/controllers/controller_base.h |   3 -
 .../hle/service/hid/controllers/debug_pad.cpp |  19 +-
 .../hle/service/hid/controllers/debug_pad.h   |  47 +--
 .../hle/service/hid/controllers/gesture.cpp   |  33 +-
 .../hle/service/hid/controllers/gesture.h     |  85 +----
 .../hle/service/hid/controllers/keyboard.cpp  |  19 +-
 .../hle/service/hid/controllers/keyboard.h    |  31 +-
 .../hle/service/hid/controllers/mouse.cpp     |  17 +-
 src/core/hle/service/hid/controllers/mouse.h  |  14 +-
 src/core/hle/service/hid/controllers/npad.cpp |  28 +-
 src/core/hle/service/hid/controllers/npad.h   | 309 +-----------------
 .../hle/service/hid/controllers/palma.cpp     |   3 +-
 src/core/hle/service/hid/controllers/palma.h  |   3 +-
 .../hid/controllers/shared_memory_format.h    | 239 ++++++++++++++
 .../hid/controllers/shared_memory_holder.cpp  |  49 +++
 .../hid/controllers/shared_memory_holder.h    |  44 +++
 .../hle/service/hid/controllers/six_axis.cpp  |  25 +-
 .../hle/service/hid/controllers/stubbed.cpp   |  17 +-
 .../hle/service/hid/controllers/stubbed.h     |  17 +-
 .../service/hid/controllers/touchscreen.cpp   |  22 +-
 .../hle/service/hid/controllers/touchscreen.h |  30 +-
 .../hid/controllers/types/debug_pad_types.h   |  31 ++
 .../hid/controllers/types/gesture_types.h     |  77 +++++
 .../hid/controllers/types/keyboard_types.h    |  20 ++
 .../hid/controllers/types/mouse_types.h       |  12 +
 .../hid/controllers/types/npad_types.h        | 255 +++++++++++++++
 .../hid/controllers/types/touch_types.h       |  90 +++++
 src/core/hle/service/hid/controllers/xpad.cpp |  39 ---
 src/core/hle/service/hid/controllers/xpad.h   | 112 -------
 src/core/hle/service/hid/hid_server.cpp       |  23 +-
 .../hle/service/hid/hid_system_server.cpp     |   3 +-
 src/core/hle/service/hid/resource_manager.cpp |  64 ++--
 src/core/hle/service/hid/resource_manager.h   |   8 +-
 40 files changed, 1063 insertions(+), 840 deletions(-)
 create mode 100644 src/core/hle/service/hid/controllers/shared_memory_format.h
 create mode 100644 src/core/hle/service/hid/controllers/shared_memory_holder.cpp
 create mode 100644 src/core/hle/service/hid/controllers/shared_memory_holder.h
 create mode 100644 src/core/hle/service/hid/controllers/types/debug_pad_types.h
 create mode 100644 src/core/hle/service/hid/controllers/types/gesture_types.h
 create mode 100644 src/core/hle/service/hid/controllers/types/keyboard_types.h
 create mode 100644 src/core/hle/service/hid/controllers/types/mouse_types.h
 create mode 100644 src/core/hle/service/hid/controllers/types/npad_types.h
 create mode 100644 src/core/hle/service/hid/controllers/types/touch_types.h
 delete mode 100644 src/core/hle/service/hid/controllers/xpad.cpp
 delete mode 100644 src/core/hle/service/hid/controllers/xpad.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 7b9ed856f9..dced370798 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -549,6 +549,11 @@ add_library(core STATIC
     hle/service/hid/xcd.cpp
     hle/service/hid/xcd.h
     hle/service/hid/errors.h
+    hle/service/hid/controllers/types/debug_pad_types.h
+    hle/service/hid/controllers/types/keyboard_types.h
+    hle/service/hid/controllers/types/mouse_types.h
+    hle/service/hid/controllers/types/npad_types.h
+    hle/service/hid/controllers/types/touch_types.h
     hle/service/hid/controllers/applet_resource.cpp
     hle/service/hid/controllers/applet_resource.h
     hle/service/hid/controllers/console_six_axis.cpp
@@ -569,14 +574,15 @@ add_library(core STATIC
     hle/service/hid/controllers/palma.h
     hle/service/hid/controllers/seven_six_axis.cpp
     hle/service/hid/controllers/seven_six_axis.h
+    hle/service/hid/controllers/shared_memory_format.h
+    hle/service/hid/controllers/shared_memory_holder.cpp
+    hle/service/hid/controllers/shared_memory_holder.h
     hle/service/hid/controllers/six_axis.cpp
     hle/service/hid/controllers/six_axis.h
     hle/service/hid/controllers/stubbed.cpp
     hle/service/hid/controllers/stubbed.h
     hle/service/hid/controllers/touchscreen.cpp
     hle/service/hid/controllers/touchscreen.h
-    hle/service/hid/controllers/xpad.cpp
-    hle/service/hid/controllers/xpad.h
     hle/service/hid/hidbus/hidbus_base.cpp
     hle/service/hid/hidbus/hidbus_base.h
     hle/service/hid/hidbus/ringcon.cpp
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 8cb05ca0bb..e479dacde1 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -135,7 +135,6 @@ struct KernelCore::Impl {
                 obj = nullptr;
             }
         };
-        CleanupObject(hid_shared_mem);
         CleanupObject(font_shared_mem);
         CleanupObject(irs_shared_mem);
         CleanupObject(time_shared_mem);
@@ -744,22 +743,16 @@ struct KernelCore::Impl {
     void InitializeHackSharedMemory(KernelCore& kernel) {
         // Setup memory regions for emulated processes
         // TODO(bunnei): These should not be hardcoded regions initialized within the kernel
-        constexpr std::size_t hid_size{0x40000};
         constexpr std::size_t font_size{0x1100000};
         constexpr std::size_t irs_size{0x8000};
         constexpr std::size_t time_size{0x1000};
         constexpr std::size_t hidbus_size{0x1000};
 
-        hid_shared_mem = KSharedMemory::Create(system.Kernel());
         font_shared_mem = KSharedMemory::Create(system.Kernel());
         irs_shared_mem = KSharedMemory::Create(system.Kernel());
         time_shared_mem = KSharedMemory::Create(system.Kernel());
         hidbus_shared_mem = KSharedMemory::Create(system.Kernel());
 
-        hid_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
-                                   Svc::MemoryPermission::Read, hid_size);
-        KSharedMemory::Register(kernel, hid_shared_mem);
-
         font_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
                                     Svc::MemoryPermission::Read, font_size);
         KSharedMemory::Register(kernel, font_shared_mem);
@@ -1190,14 +1183,6 @@ const KSystemResource& KernelCore::GetSystemSystemResource() const {
     return *impl->sys_system_resource;
 }
 
-Kernel::KSharedMemory& KernelCore::GetHidSharedMem() {
-    return *impl->hid_shared_mem;
-}
-
-const Kernel::KSharedMemory& KernelCore::GetHidSharedMem() const {
-    return *impl->hid_shared_mem;
-}
-
 Kernel::KSharedMemory& KernelCore::GetFontSharedMem() {
     return *impl->font_shared_mem;
 }
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 69b5bbd6c8..78c88902cc 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -239,12 +239,6 @@ public:
     /// Gets the system resource manager.
     const KSystemResource& GetSystemSystemResource() const;
 
-    /// Gets the shared memory object for HID services.
-    Kernel::KSharedMemory& GetHidSharedMem();
-
-    /// Gets the shared memory object for HID services.
-    const Kernel::KSharedMemory& GetHidSharedMem() const;
-
     /// Gets the shared memory object for font services.
     Kernel::KSharedMemory& GetFontSharedMem();
 
diff --git a/src/core/hle/service/hid/controllers/applet_resource.cpp b/src/core/hle/service/hid/controllers/applet_resource.cpp
index 435b862336..c8e74c7643 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;
+        }
+    }
 
-    data[index].shared_memory_handle = &shared_memory;
+    auto* shared_memory_format = shared_memory.GetAddress();
+    if (shared_memory_format != nullptr) {
+        shared_memory_format->Initialize();
+    }
+
+    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 62137db131..e7991f93a0 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 b2bf1d78d2..084e995562 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 5b7c6a29ae..3d1c9ce23d 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 9a44ee41ea..4326c78219 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 9de19ebfc8..38fafe88fd 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 5566dba774..704d1fc98f 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 59b2ec73c4..0b6e9c4e59 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 4c6f8ee078..cee6b6c074 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 ddb1b0ba47..feab499bdf 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 172ec1309a..8abc8c5e97 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 6e5a04e341..cce6deb527 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 a80f3823f5..3107915d74 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 08ee9de9ca..53a737cf54 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 9167c93f0d..19e8becb4f 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 588ff9d620..aa0454b5ed 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 a6047f36af..73884230d5 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 0000000000..63fb46c11e
--- /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 0000000000..223487421b
--- /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 0000000000..260402712c
--- /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 3d24a5c048..36b72f9ea2 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 9e2f3ab212..26001e9146 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 1483a968ed..bdf35d84b0 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 fcd9734143..a98f1f85ef 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 79f026a81d..63513404b4 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 0000000000..a96171b622
--- /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 0000000000..b4f034cd33
--- /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 0000000000..f44a536b90
--- /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 0000000000..fb9c7703ab
--- /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 0000000000..9eb98ccef9
--- /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 0000000000..efeaa796d7
--- /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 0aaed1fa73..0000000000
--- 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 9e63a317af..0000000000
--- 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 b06ea467e3..de24b0401c 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 4d33456a32..5cc88c4a17 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 89cdc19cce..0cfe30fde4 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;
+}
 
-    palma = std::make_shared<Palma>(system.HIDCore(), shared_memory, service_context);
+void ResourceManager::InitializeController(u64 aruid) {
+    SharedMemoryFormat* shared_memory = nullptr;
+    const auto result = applet_resource->GetSharedMemoryFormat(&shared_memory, aruid);
+    if (result.IsError()) {
+        return;
+    }
 
-    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);
+    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(), service_context);
+
+    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 15c1beb1aa..5ad7cb5649 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;