summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hid/hid_types.h72
-rw-r--r--src/core/hle/service/hid/controllers/console_sixaxis.cpp20
-rw-r--r--src/core/hle/service/hid/controllers/console_sixaxis.h11
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.h7
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.cpp19
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.h29
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp32
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h45
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp19
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.h27
-rw-r--r--src/core/hle/service/hid/controllers/mouse.cpp20
-rw-r--r--src/core/hle/service/hid/controllers/mouse.h21
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp290
-rw-r--r--src/core/hle/service/hid/controllers/npad.h32
-rw-r--r--src/core/hle/service/hid/controllers/stubbed.cpp11
-rw-r--r--src/core/hle/service/hid/controllers/stubbed.h13
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp22
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.h28
-rw-r--r--src/core/hle/service/hid/controllers/xpad.cpp21
-rw-r--r--src/core/hle/service/hid/controllers/xpad.h26
-rw-r--r--src/core/hle/service/hid/hid.cpp41
-rw-r--r--src/core/hle/service/hid/hid.h9
-rw-r--r--src/yuzu/configuration/configure_ui.cpp73
23 files changed, 496 insertions, 392 deletions
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index df2b1dfc5..26ec1091b 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -316,27 +316,27 @@ static_assert(sizeof(TouchAttribute) == 0x4, "TouchAttribute is an invalid size"
// This is nn::hid::TouchState
struct TouchState {
- u64 delta_time;
- TouchAttribute attribute;
- u32 finger;
- Common::Point<u32> position;
- u32 diameter_x;
- u32 diameter_y;
- u32 rotation_angle;
+ u64 delta_time{};
+ TouchAttribute attribute{};
+ u32 finger{};
+ Common::Point<u32> position{};
+ u32 diameter_x{};
+ u32 diameter_y{};
+ u32 rotation_angle{};
};
static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size");
// This is nn::hid::NpadControllerColor
struct NpadControllerColor {
- u32 body;
- u32 button;
+ u32 body{};
+ u32 button{};
};
static_assert(sizeof(NpadControllerColor) == 8, "NpadControllerColor is an invalid size");
// This is nn::hid::AnalogStickState
struct AnalogStickState {
- s32 x;
- s32 y;
+ s32 x{};
+ s32 y{};
};
static_assert(sizeof(AnalogStickState) == 8, "AnalogStickState is an invalid size");
@@ -354,10 +354,10 @@ static_assert(sizeof(NpadBatteryLevel) == 0x4, "NpadBatteryLevel is an invalid s
// This is nn::hid::system::NpadPowerInfo
struct NpadPowerInfo {
- bool is_powered;
- bool is_charging;
+ bool is_powered{};
+ bool is_charging{};
INSERT_PADDING_BYTES(0x6);
- NpadBatteryLevel battery_level;
+ NpadBatteryLevel battery_level{8};
};
static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size");
@@ -474,8 +474,8 @@ static_assert(sizeof(DebugPadButton) == 0x4, "DebugPadButton is an invalid size"
// This is nn::hid::ConsoleSixAxisSensorHandle
struct ConsoleSixAxisSensorHandle {
- u8 unknown_1;
- u8 unknown_2;
+ u8 unknown_1{};
+ u8 unknown_2{};
INSERT_PADDING_BYTES_NOINIT(2);
};
static_assert(sizeof(ConsoleSixAxisSensorHandle) == 4,
@@ -483,9 +483,9 @@ static_assert(sizeof(ConsoleSixAxisSensorHandle) == 4,
// This is nn::hid::SixAxisSensorHandle
struct SixAxisSensorHandle {
- NpadStyleIndex npad_type;
- u8 npad_id;
- DeviceIndex device_index;
+ NpadStyleIndex npad_type{NpadStyleIndex::None};
+ u8 npad_id{};
+ DeviceIndex device_index{DeviceIndex::None};
INSERT_PADDING_BYTES_NOINIT(1);
};
static_assert(sizeof(SixAxisSensorHandle) == 4, "SixAxisSensorHandle is an invalid size");
@@ -500,19 +500,19 @@ static_assert(sizeof(SixAxisSensorFusionParameters) == 8,
// This is nn::hid::VibrationDeviceHandle
struct VibrationDeviceHandle {
- NpadStyleIndex npad_type;
- u8 npad_id;
- DeviceIndex device_index;
+ NpadStyleIndex npad_type{NpadStyleIndex::None};
+ u8 npad_id{};
+ DeviceIndex device_index{DeviceIndex::None};
INSERT_PADDING_BYTES_NOINIT(1);
};
static_assert(sizeof(VibrationDeviceHandle) == 4, "SixAxisSensorHandle is an invalid size");
// This is nn::hid::VibrationValue
struct VibrationValue {
- f32 low_amplitude;
- f32 low_frequency;
- f32 high_amplitude;
- f32 high_frequency;
+ f32 low_amplitude{};
+ f32 low_frequency{};
+ f32 high_amplitude{};
+ f32 high_frequency{};
};
static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size.");
@@ -561,7 +561,7 @@ static_assert(sizeof(KeyboardAttribute) == 0x4, "KeyboardAttribute is an invalid
// This is nn::hid::KeyboardKey
struct KeyboardKey {
// This should be a 256 bit flag
- std::array<u8, 32> key;
+ std::array<u8, 32> key{};
};
static_assert(sizeof(KeyboardKey) == 0x20, "KeyboardKey is an invalid size");
@@ -590,16 +590,16 @@ static_assert(sizeof(MouseAttribute) == 0x4, "MouseAttribute is an invalid size"
// This is nn::hid::detail::MouseState
struct MouseState {
- s64 sampling_number;
- s32 x;
- s32 y;
- s32 delta_x;
- s32 delta_y;
+ s64 sampling_number{};
+ s32 x{};
+ s32 y{};
+ s32 delta_x{};
+ s32 delta_y{};
// Axis Order in HW is switched for the wheel
- s32 delta_wheel_y;
- s32 delta_wheel_x;
- MouseButton button;
- MouseAttribute attribute;
+ s32 delta_wheel_y{};
+ s32 delta_wheel_x{};
+ MouseButton button{};
+ MouseAttribute attribute{};
};
static_assert(sizeof(MouseState) == 0x28, "MouseState is an invalid size");
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp
index f5a0b94dd..bb3cba910 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp
+++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp
@@ -9,9 +9,14 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200;
-Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_)
+Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_,
+ u8* raw_shared_memory_)
: ControllerBase{hid_core_} {
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));
}
Controller_ConsoleSixAxis::~Controller_ConsoleSixAxis() = default;
@@ -20,8 +25,7 @@ void Controller_ConsoleSixAxis::OnInit() {}
void Controller_ConsoleSixAxis::OnRelease() {}
-void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t size) {
+void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated() || !is_transfer_memory_set) {
seven_sixaxis_lifo.buffer_count = 0;
seven_sixaxis_lifo.buffer_tail = 0;
@@ -48,13 +52,11 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti
-motion_status.quaternion.xyz.z,
};
- console_six_axis.sampling_number++;
- console_six_axis.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
- console_six_axis.verticalization_error = motion_status.verticalization_error;
- console_six_axis.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;
- // Update console six axis shared memory
- std::memcpy(data + SHARED_MEMORY_OFFSET, &console_six_axis, sizeof(console_six_axis));
// Update seven six axis transfer memory
seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state);
std::memcpy(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo));
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/console_sixaxis.h
index 6da5e9454..2fd11538f 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.h
+++ b/src/core/hle/service/hid/controllers/console_sixaxis.h
@@ -17,7 +17,7 @@ class EmulatedConsole;
namespace Service::HID {
class Controller_ConsoleSixAxis final : public ControllerBase {
public:
- explicit Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_);
+ explicit Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_ConsoleSixAxis() override;
// Called when the controller is initialized
@@ -27,7 +27,7 @@ public:
void OnRelease() override;
// When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, size_t size) override;
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
// Called on InitializeSevenSixAxisSensor
void SetTransferMemoryPointer(u8* t_mem);
@@ -61,12 +61,13 @@ private:
Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{};
static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size");
- Core::HID::EmulatedConsole* console;
+ SevenSixAxisState next_seven_sixaxis_state{};
u8* transfer_memory = nullptr;
+ ConsoleSharedMemory* shared_memory = nullptr;
+ Core::HID::EmulatedConsole* console = nullptr;
+
bool is_transfer_memory_set = false;
u64 last_saved_timestamp{};
u64 last_global_timestamp{};
- ConsoleSharedMemory console_six_axis{};
- SevenSixAxisState next_seven_sixaxis_state{};
};
} // 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 bb01ea643..d6f7a5073 100644
--- a/src/core/hle/service/hid/controllers/controller_base.h
+++ b/src/core/hle/service/hid/controllers/controller_base.h
@@ -26,12 +26,10 @@ public:
virtual void OnRelease() = 0;
// When the controller is requesting an update for the shared memory
- virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t size) = 0;
+ virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing) = 0;
// When the controller is requesting a motion update for the shared memory
- virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t size) {}
+ virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {}
void ActivateController();
@@ -40,6 +38,7 @@ 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 73309d64e..8ec9f4a95 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ b/src/core/hle/service/hid/controllers/debug_pad.cpp
@@ -13,8 +13,12 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000;
-Controller_DebugPad::Controller_DebugPad(Core::HID::HIDCore& hid_core_)
+Controller_DebugPad::Controller_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));
controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
}
@@ -24,16 +28,14 @@ void Controller_DebugPad::OnInit() {}
void Controller_DebugPad::OnRelease() {}
-void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t size) {
+void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
- debug_pad_lifo.buffer_count = 0;
- debug_pad_lifo.buffer_tail = 0;
- std::memcpy(data + SHARED_MEMORY_OFFSET, &debug_pad_lifo, sizeof(debug_pad_lifo));
+ shared_memory->debug_pad_lifo.buffer_count = 0;
+ shared_memory->debug_pad_lifo.buffer_tail = 0;
return;
}
- const auto& last_entry = 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) {
@@ -47,8 +49,7 @@ void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing,
next_state.r_stick = stick_state.right;
}
- debug_pad_lifo.WriteNextEntry(next_state);
- std::memcpy(data + SHARED_MEMORY_OFFSET, &debug_pad_lifo, sizeof(debug_pad_lifo));
+ 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 388d25b3c..68ff0ea79 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.h
+++ b/src/core/hle/service/hid/controllers/debug_pad.h
@@ -17,7 +17,7 @@ struct AnalogStickState;
namespace Service::HID {
class Controller_DebugPad final : public ControllerBase {
public:
- explicit Controller_DebugPad(Core::HID::HIDCore& hid_core_);
+ explicit Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_DebugPad() override;
// Called when the controller is initialized
@@ -27,7 +27,7 @@ public:
void OnRelease() override;
// When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
private:
// This is nn::hid::DebugPadAttribute
@@ -41,19 +41,24 @@ private:
// 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;
+ 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");
- // 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");
- DebugPadState next_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");
- Core::HID::EmulatedController* controller;
+ DebugPadState next_state{};
+ DebugPadSharedMemory* shared_memory = nullptr;
+ 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 c8dd131dd..3eae1ae35 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/core/hle/service/hid/controllers/gesture.cpp
@@ -23,25 +23,28 @@ constexpr f32 Square(s32 num) {
return static_cast<f32>(num * num);
}
-Controller_Gesture::Controller_Gesture(Core::HID::HIDCore& hid_core_) : ControllerBase(hid_core_) {
+Controller_Gesture::Controller_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));
console = hid_core.GetEmulatedConsole();
}
Controller_Gesture::~Controller_Gesture() = default;
void Controller_Gesture::OnInit() {
- gesture_lifo.buffer_count = 0;
- gesture_lifo.buffer_tail = 0;
+ shared_memory->gesture_lifo.buffer_count = 0;
+ shared_memory->gesture_lifo.buffer_tail = 0;
force_update = true;
}
void Controller_Gesture::OnRelease() {}
-void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t size) {
+void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
- gesture_lifo.buffer_count = 0;
- gesture_lifo.buffer_tail = 0;
- std::memcpy(data + SHARED_MEMORY_OFFSET, &gesture_lifo, sizeof(gesture_lifo));
+ shared_memory->gesture_lifo.buffer_count = 0;
+ shared_memory->gesture_lifo.buffer_tail = 0;
return;
}
@@ -49,15 +52,15 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
GestureProperties gesture = GetGestureProperties();
f32 time_difference =
- static_cast<f32>(gesture_lifo.timestamp - last_update_timestamp) / (1000 * 1000 * 1000);
+ static_cast<f32>(shared_memory->gesture_lifo.timestamp - last_update_timestamp) /
+ (1000 * 1000 * 1000);
// Only update if necesary
if (!ShouldUpdateGesture(gesture, time_difference)) {
return;
}
- last_update_timestamp = gesture_lifo.timestamp;
- UpdateGestureSharedMemory(data, size, gesture, time_difference);
+ last_update_timestamp = shared_memory->gesture_lifo.timestamp;
}
void Controller_Gesture::ReadTouchInput() {
@@ -97,7 +100,7 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
GestureType type = GestureType::Idle;
GestureAttribute attributes{};
- const auto& last_entry = 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;
@@ -127,8 +130,7 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
next_state.points = gesture.points;
last_gesture = gesture;
- gesture_lifo.WriteNextEntry(next_state);
- std::memcpy(data + SHARED_MEMORY_OFFSET, &gesture_lifo, sizeof(gesture_lifo));
+ shared_memory->gesture_lifo.WriteNextEntry(next_state);
}
void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
@@ -305,7 +307,7 @@ void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture,
}
const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const {
- return gesture_lifo.ReadCurrentEntry().state;
+ return shared_memory->gesture_lifo.ReadCurrentEntry().state;
}
Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() {
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h
index 7a9d28dc6..c62a341bf 100644
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ b/src/core/hle/service/hid/controllers/gesture.h
@@ -14,7 +14,7 @@
namespace Service::HID {
class Controller_Gesture final : public ControllerBase {
public:
- explicit Controller_Gesture(Core::HID::HIDCore& hid_core_);
+ explicit Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_Gesture() override;
// Called when the controller is initialized
@@ -24,7 +24,7 @@ public:
void OnRelease() override;
// When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, size_t size) override;
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
private:
static constexpr size_t MAX_FINGERS = 16;
@@ -66,19 +66,19 @@ private:
// This is nn::hid::GestureState
struct GestureState {
- s64 sampling_number;
- s64 detection_count;
- GestureType type;
- GestureDirection direction;
- 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;
+ 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");
@@ -92,6 +92,14 @@ private:
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();
@@ -134,12 +142,9 @@ private:
// Returns the average distance, angle and middle point of the active fingers
GestureProperties GetGestureProperties();
- // 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");
GestureState next_state{};
-
- Core::HID::EmulatedConsole* console;
+ GestureSharedMemory* shared_memory = nullptr;
+ Core::HID::EmulatedConsole* console = nullptr;
std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{};
GestureProperties last_gesture{};
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index 8dc67757b..117d87433 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -12,8 +12,12 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800;
-Controller_Keyboard::Controller_Keyboard(Core::HID::HIDCore& hid_core_)
+Controller_Keyboard::Controller_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));
emulated_devices = hid_core.GetEmulatedDevices();
}
@@ -23,16 +27,14 @@ void Controller_Keyboard::OnInit() {}
void Controller_Keyboard::OnRelease() {}
-void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t size) {
+void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
- keyboard_lifo.buffer_count = 0;
- keyboard_lifo.buffer_tail = 0;
- std::memcpy(data + SHARED_MEMORY_OFFSET, &keyboard_lifo, sizeof(keyboard_lifo));
+ shared_memory->keyboard_lifo.buffer_count = 0;
+ shared_memory->keyboard_lifo.buffer_tail = 0;
return;
}
- const auto& last_entry = 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) {
@@ -44,8 +46,7 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
next_state.attribute.is_connected.Assign(1);
}
- keyboard_lifo.WriteNextEntry(next_state);
- std::memcpy(data + SHARED_MEMORY_OFFSET, &keyboard_lifo, sizeof(keyboard_lifo));
+ 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 39c6085f1..7532f53c6 100644
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ b/src/core/hle/service/hid/controllers/keyboard.h
@@ -16,7 +16,7 @@ struct KeyboardKey;
namespace Service::HID {
class Controller_Keyboard final : public ControllerBase {
public:
- explicit Controller_Keyboard(Core::HID::HIDCore& hid_core_);
+ explicit Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_Keyboard() override;
// Called when the controller is initialized
@@ -26,23 +26,28 @@ public:
void OnRelease() override;
// When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
+ 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;
+ 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");
- // 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");
- KeyboardState next_state{};
+ 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");
- Core::HID::EmulatedDevices* emulated_devices;
+ KeyboardState next_state{};
+ KeyboardSharedMemory* shared_memory = nullptr;
+ 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 a0292f586..b11cb438d 100644
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ b/src/core/hle/service/hid/controllers/mouse.cpp
@@ -12,7 +12,12 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400;
-Controller_Mouse::Controller_Mouse(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
+Controller_Mouse::Controller_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));
emulated_devices = hid_core.GetEmulatedDevices();
}
@@ -21,16 +26,14 @@ Controller_Mouse::~Controller_Mouse() = default;
void Controller_Mouse::OnInit() {}
void Controller_Mouse::OnRelease() {}
-void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t size) {
+void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
- mouse_lifo.buffer_count = 0;
- mouse_lifo.buffer_tail = 0;
- std::memcpy(data + SHARED_MEMORY_OFFSET, &mouse_lifo, sizeof(mouse_lifo));
+ shared_memory->mouse_lifo.buffer_count = 0;
+ shared_memory->mouse_lifo.buffer_tail = 0;
return;
}
- const auto& last_entry = mouse_lifo.ReadCurrentEntry().state;
+ const auto& last_entry = shared_memory->mouse_lifo.ReadCurrentEntry().state;
next_state.sampling_number = last_entry.sampling_number + 1;
next_state.attribute.raw = 0;
@@ -50,8 +53,7 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
next_state.button = mouse_button_state;
}
- mouse_lifo.WriteNextEntry(next_state);
- std::memcpy(data + SHARED_MEMORY_OFFSET, &mouse_lifo, sizeof(mouse_lifo));
+ 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 62acdfb77..733d00577 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/core/hle/service/hid/controllers/mouse.h
@@ -16,7 +16,7 @@ struct AnalogStickState;
namespace Service::HID {
class Controller_Mouse final : public ControllerBase {
public:
- explicit Controller_Mouse(Core::HID::HIDCore& hid_core_);
+ explicit Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_Mouse() override;
// Called when the controller is initialized
@@ -26,15 +26,20 @@ public:
void OnRelease() override;
// When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
private:
- // 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");
- Core::HID::MouseState next_state{};
+ 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::AnalogStickState last_mouse_wheel_state;
- Core::HID::EmulatedDevices* emulated_devices;
+ Core::HID::MouseState next_state{};
+ Core::HID::AnalogStickState last_mouse_wheel_state{};
+ MouseSharedMemory* shared_memory = nullptr;
+ 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 16e973b25..17f71beaf 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -61,11 +61,14 @@ bool Controller_NPad::IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle&
return npad_id && npad_type && device_index;
}
-Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_,
+Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
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.device = hid_core.GetEmulatedControllerByIndex(i);
controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
Core::HID::DEFAULT_VIBRATION_VALUE;
@@ -115,11 +118,11 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
if (!controller.device->IsConnected()) {
return;
}
- auto& shared_memory = controller.shared_memory_entry;
+ auto* shared_memory = controller.shared_memory;
const auto& battery_level = controller.device->GetBattery();
- shared_memory.battery_level_dual = battery_level.dual.battery_level;
- shared_memory.battery_level_left = battery_level.left.battery_level;
- shared_memory.battery_level_right = battery_level.right.battery_level;
+ shared_memory->battery_level_dual = battery_level.dual.battery_level;
+ shared_memory->battery_level_left = battery_level.left.battery_level;
+ shared_memory->battery_level_right = battery_level.right.battery_level;
break;
}
default:
@@ -134,99 +137,100 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
}
LOG_DEBUG(Service_HID, "Npad connected {}", npad_id);
const auto controller_type = controller.device->GetNpadStyleIndex();
- auto& shared_memory = controller.shared_memory_entry;
+ auto* shared_memory = controller.shared_memory;
if (controller_type == Core::HID::NpadStyleIndex::None) {
controller.styleset_changed_event->GetWritableEvent().Signal();
return;
}
- shared_memory.style_tag.raw = Core::HID::NpadStyleSet::None;
- shared_memory.device_type.raw = 0;
- shared_memory.system_properties.raw = 0;
+ shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None;
+ shared_memory->device_type.raw = 0;
+ shared_memory->system_properties.raw = 0;
switch (controller_type) {
case Core::HID::NpadStyleIndex::None:
UNREACHABLE();
break;
case Core::HID::NpadStyleIndex::ProController:
- shared_memory.style_tag.fullkey.Assign(1);
- shared_memory.device_type.fullkey.Assign(1);
- shared_memory.system_properties.is_vertical.Assign(1);
- shared_memory.system_properties.use_plus.Assign(1);
- shared_memory.system_properties.use_minus.Assign(1);
- shared_memory.applet_footer.type = AppletFooterUiType::SwitchProController;
+ shared_memory->style_tag.fullkey.Assign(1);
+ shared_memory->device_type.fullkey.Assign(1);
+ shared_memory->system_properties.is_vertical.Assign(1);
+ shared_memory->system_properties.use_plus.Assign(1);
+ shared_memory->system_properties.use_minus.Assign(1);
+ shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::SwitchProController;
break;
case Core::HID::NpadStyleIndex::Handheld:
- shared_memory.style_tag.handheld.Assign(1);
- shared_memory.device_type.handheld_left.Assign(1);
- shared_memory.device_type.handheld_right.Assign(1);
- shared_memory.system_properties.is_vertical.Assign(1);
- shared_memory.system_properties.use_plus.Assign(1);
- shared_memory.system_properties.use_minus.Assign(1);
- shared_memory.system_properties.use_directional_buttons.Assign(1);
- shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual;
- shared_memory.applet_footer.type = AppletFooterUiType::HandheldJoyConLeftJoyConRight;
+ shared_memory->style_tag.handheld.Assign(1);
+ shared_memory->device_type.handheld_left.Assign(1);
+ shared_memory->device_type.handheld_right.Assign(1);
+ shared_memory->system_properties.is_vertical.Assign(1);
+ shared_memory->system_properties.use_plus.Assign(1);
+ shared_memory->system_properties.use_minus.Assign(1);
+ shared_memory->system_properties.use_directional_buttons.Assign(1);
+ shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual;
+ shared_memory->applet_nfc_xcd.applet_footer.type =
+ AppletFooterUiType::HandheldJoyConLeftJoyConRight;
break;
case Core::HID::NpadStyleIndex::JoyconDual:
- shared_memory.style_tag.joycon_dual.Assign(1);
+ shared_memory->style_tag.joycon_dual.Assign(1);
if (controller.is_dual_left_connected) {
- shared_memory.device_type.joycon_left.Assign(1);
- shared_memory.system_properties.use_minus.Assign(1);
+ shared_memory->device_type.joycon_left.Assign(1);
+ shared_memory->system_properties.use_minus.Assign(1);
}
if (controller.is_dual_right_connected) {
- shared_memory.device_type.joycon_right.Assign(1);
- shared_memory.system_properties.use_plus.Assign(1);
+ shared_memory->device_type.joycon_right.Assign(1);
+ shared_memory->system_properties.use_plus.Assign(1);
}
- shared_memory.system_properties.use_directional_buttons.Assign(1);
- shared_memory.system_properties.is_vertical.Assign(1);
- shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual;
+ shared_memory->system_properties.use_directional_buttons.Assign(1);
+ shared_memory->system_properties.is_vertical.Assign(1);
+ shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual;
if (controller.is_dual_left_connected && controller.is_dual_right_connected) {
- shared_memory.applet_footer.type = AppletFooterUiType::JoyDual;
+ shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDual;
} else if (controller.is_dual_left_connected) {
- shared_memory.applet_footer.type = AppletFooterUiType::JoyDualLeftOnly;
+ shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualLeftOnly;
} else {
- shared_memory.applet_footer.type = AppletFooterUiType::JoyDualRightOnly;
+ shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualRightOnly;
}
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
- shared_memory.style_tag.joycon_left.Assign(1);
- shared_memory.device_type.joycon_left.Assign(1);
- shared_memory.system_properties.is_horizontal.Assign(1);
- shared_memory.system_properties.use_minus.Assign(1);
- shared_memory.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal;
+ shared_memory->style_tag.joycon_left.Assign(1);
+ shared_memory->device_type.joycon_left.Assign(1);
+ shared_memory->system_properties.is_horizontal.Assign(1);
+ shared_memory->system_properties.use_minus.Assign(1);
+ shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal;
break;
case Core::HID::NpadStyleIndex::JoyconRight:
- shared_memory.style_tag.joycon_right.Assign(1);
- shared_memory.device_type.joycon_right.Assign(1);
- shared_memory.system_properties.is_horizontal.Assign(1);
- shared_memory.system_properties.use_plus.Assign(1);
- shared_memory.applet_footer.type = AppletFooterUiType::JoyRightHorizontal;
+ shared_memory->style_tag.joycon_right.Assign(1);
+ shared_memory->device_type.joycon_right.Assign(1);
+ shared_memory->system_properties.is_horizontal.Assign(1);
+ shared_memory->system_properties.use_plus.Assign(1);
+ shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyRightHorizontal;
break;
case Core::HID::NpadStyleIndex::GameCube:
- shared_memory.style_tag.gamecube.Assign(1);
- shared_memory.device_type.fullkey.Assign(1);
- shared_memory.system_properties.is_vertical.Assign(1);
- shared_memory.system_properties.use_plus.Assign(1);
+ shared_memory->style_tag.gamecube.Assign(1);
+ shared_memory->device_type.fullkey.Assign(1);
+ shared_memory->system_properties.is_vertical.Assign(1);
+ shared_memory->system_properties.use_plus.Assign(1);
break;
case Core::HID::NpadStyleIndex::Pokeball:
- shared_memory.style_tag.palma.Assign(1);
- shared_memory.device_type.palma.Assign(1);
+ shared_memory->style_tag.palma.Assign(1);
+ shared_memory->device_type.palma.Assign(1);
break;
case Core::HID::NpadStyleIndex::NES:
- shared_memory.style_tag.lark.Assign(1);
- shared_memory.device_type.fullkey.Assign(1);
+ shared_memory->style_tag.lark.Assign(1);
+ shared_memory->device_type.fullkey.Assign(1);
break;
case Core::HID::NpadStyleIndex::SNES:
- shared_memory.style_tag.lucia.Assign(1);
- shared_memory.device_type.fullkey.Assign(1);
- shared_memory.applet_footer.type = AppletFooterUiType::Lucia;
+ shared_memory->style_tag.lucia.Assign(1);
+ shared_memory->device_type.fullkey.Assign(1);
+ shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::Lucia;
break;
case Core::HID::NpadStyleIndex::N64:
- shared_memory.style_tag.lagoon.Assign(1);
- shared_memory.device_type.fullkey.Assign(1);
- shared_memory.applet_footer.type = AppletFooterUiType::Lagon;
+ shared_memory->style_tag.lagoon.Assign(1);
+ shared_memory->device_type.fullkey.Assign(1);
+ shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::Lagon;
break;
case Core::HID::NpadStyleIndex::SegaGenesis:
- shared_memory.style_tag.lager.Assign(1);
- shared_memory.device_type.fullkey.Assign(1);
+ shared_memory->style_tag.lager.Assign(1);
+ shared_memory->device_type.fullkey.Assign(1);
break;
default:
break;
@@ -234,23 +238,23 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
const auto& body_colors = controller.device->GetColors();
- shared_memory.fullkey_color.attribute = ColorAttribute::Ok;
- shared_memory.fullkey_color.fullkey = body_colors.fullkey;
+ shared_memory->fullkey_color.attribute = ColorAttribute::Ok;
+ shared_memory->fullkey_color.fullkey = body_colors.fullkey;
- shared_memory.joycon_color.attribute = ColorAttribute::Ok;
- shared_memory.joycon_color.left = body_colors.left;
- shared_memory.joycon_color.right = body_colors.right;
+ shared_memory->joycon_color.attribute = ColorAttribute::Ok;
+ shared_memory->joycon_color.left = body_colors.left;
+ shared_memory->joycon_color.right = body_colors.right;
// TODO: Investigate when we should report all batery types
const auto& battery_level = controller.device->GetBattery();
- shared_memory.battery_level_dual = battery_level.dual.battery_level;
- shared_memory.battery_level_left = battery_level.left.battery_level;
- shared_memory.battery_level_right = battery_level.right.battery_level;
+ shared_memory->battery_level_dual = battery_level.dual.battery_level;
+ shared_memory->battery_level_left = battery_level.left.battery_level;
+ shared_memory->battery_level_right = battery_level.right.battery_level;
controller.is_connected = true;
controller.device->Connect();
SignalStyleSetChangedEvent(npad_id);
- WriteEmptyEntry(controller.shared_memory_entry);
+ WriteEmptyEntry(controller.shared_memory);
}
void Controller_NPad::OnInit() {
@@ -270,12 +274,12 @@ void Controller_NPad::OnInit() {
// Prefill controller buffers
for (auto& controller : controller_data) {
- auto& npad = controller.shared_memory_entry;
- npad.fullkey_color = {
+ auto* npad = controller.shared_memory;
+ npad->fullkey_color = {
.attribute = ColorAttribute::NoController,
.fullkey = {},
};
- npad.joycon_color = {
+ npad->joycon_color = {
.attribute = ColorAttribute::NoController,
.left = {},
.right = {},
@@ -287,25 +291,25 @@ void Controller_NPad::OnInit() {
}
}
-void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) {
+void Controller_NPad::WriteEmptyEntry(NpadInternalState* npad) {
NPadGenericState dummy_pad_state{};
NpadGcTriggerState dummy_gc_state{};
- dummy_pad_state.sampling_number = npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
- npad.fullkey_lifo.WriteNextEntry(dummy_pad_state);
- dummy_pad_state.sampling_number = npad.handheld_lifo.ReadCurrentEntry().sampling_number + 1;
- npad.handheld_lifo.WriteNextEntry(dummy_pad_state);
- dummy_pad_state.sampling_number = npad.joy_dual_lifo.ReadCurrentEntry().sampling_number + 1;
- npad.joy_dual_lifo.WriteNextEntry(dummy_pad_state);
- dummy_pad_state.sampling_number = npad.joy_left_lifo.ReadCurrentEntry().sampling_number + 1;
- npad.joy_left_lifo.WriteNextEntry(dummy_pad_state);
- dummy_pad_state.sampling_number = npad.joy_right_lifo.ReadCurrentEntry().sampling_number + 1;
- npad.joy_right_lifo.WriteNextEntry(dummy_pad_state);
- dummy_pad_state.sampling_number = npad.palma_lifo.ReadCurrentEntry().sampling_number + 1;
- npad.palma_lifo.WriteNextEntry(dummy_pad_state);
- dummy_pad_state.sampling_number = npad.system_ext_lifo.ReadCurrentEntry().sampling_number + 1;
- npad.system_ext_lifo.WriteNextEntry(dummy_pad_state);
- dummy_gc_state.sampling_number = npad.gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1;
- npad.gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
+ dummy_pad_state.sampling_number = npad->fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad->fullkey_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_pad_state.sampling_number = npad->handheld_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad->handheld_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_pad_state.sampling_number = npad->joy_dual_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad->joy_dual_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_pad_state.sampling_number = npad->joy_left_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad->joy_left_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_pad_state.sampling_number = npad->joy_right_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad->joy_right_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_pad_state.sampling_number = npad->palma_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad->palma_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_pad_state.sampling_number = npad->system_ext_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad->system_ext_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_gc_state.sampling_number = npad->gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
}
void Controller_NPad::OnRelease() {
@@ -371,23 +375,19 @@ void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
}
}
-void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t data_len) {
+void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
return;
}
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
- auto& npad = controller.shared_memory_entry;
+ auto* npad = controller.shared_memory;
const auto& controller_type = controller.device->GetNpadStyleIndex();
if (controller_type == Core::HID::NpadStyleIndex::None ||
!controller.device->IsConnected()) {
- // Refresh shared memory
- std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
- &controller.shared_memory_entry, sizeof(NpadInternalState));
continue;
}
@@ -415,8 +415,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
libnx_state.connection_status.is_wired.Assign(1);
pad_state.sampling_number =
- npad.fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad.fullkey_lifo.WriteNextEntry(pad_state);
+ npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->fullkey_lifo.WriteNextEntry(pad_state);
break;
case Core::HID::NpadStyleIndex::Handheld:
pad_state.connection_status.raw = 0;
@@ -433,8 +433,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
libnx_state.connection_status.is_left_wired.Assign(1);
libnx_state.connection_status.is_right_wired.Assign(1);
pad_state.sampling_number =
- npad.handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad.handheld_lifo.WriteNextEntry(pad_state);
+ npad->handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->handheld_lifo.WriteNextEntry(pad_state);
break;
case Core::HID::NpadStyleIndex::JoyconDual:
pad_state.connection_status.raw = 0;
@@ -449,8 +449,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
}
pad_state.sampling_number =
- npad.joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad.joy_dual_lifo.WriteNextEntry(pad_state);
+ npad->joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->joy_dual_lifo.WriteNextEntry(pad_state);
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
pad_state.connection_status.raw = 0;
@@ -459,8 +459,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
libnx_state.connection_status.is_left_connected.Assign(1);
pad_state.sampling_number =
- npad.joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad.joy_left_lifo.WriteNextEntry(pad_state);
+ npad->joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->joy_left_lifo.WriteNextEntry(pad_state);
break;
case Core::HID::NpadStyleIndex::JoyconRight:
pad_state.connection_status.raw = 0;
@@ -469,8 +469,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
libnx_state.connection_status.is_right_connected.Assign(1);
pad_state.sampling_number =
- npad.joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad.joy_right_lifo.WriteNextEntry(pad_state);
+ npad->joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->joy_right_lifo.WriteNextEntry(pad_state);
break;
case Core::HID::NpadStyleIndex::GameCube:
pad_state.connection_status.raw = 0;
@@ -479,18 +479,18 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
libnx_state.connection_status.is_wired.Assign(1);
pad_state.sampling_number =
- npad.fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
trigger_state.sampling_number =
- npad.gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad.fullkey_lifo.WriteNextEntry(pad_state);
- npad.gc_trigger_lifo.WriteNextEntry(trigger_state);
+ npad->gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->fullkey_lifo.WriteNextEntry(pad_state);
+ npad->gc_trigger_lifo.WriteNextEntry(trigger_state);
break;
case Core::HID::NpadStyleIndex::Pokeball:
pad_state.connection_status.raw = 0;
pad_state.connection_status.is_connected.Assign(1);
pad_state.sampling_number =
- npad.palma_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad.palma_lifo.WriteNextEntry(pad_state);
+ npad->palma_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->palma_lifo.WriteNextEntry(pad_state);
break;
default:
break;
@@ -499,17 +499,13 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw;
libnx_state.l_stick = pad_state.l_stick;
libnx_state.r_stick = pad_state.r_stick;
- npad.system_ext_lifo.WriteNextEntry(pad_state);
+ npad->system_ext_lifo.WriteNextEntry(pad_state);
press_state |= static_cast<u64>(pad_state.npad_buttons.raw);
-
- std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
- &controller.shared_memory_entry, sizeof(NpadInternalState));
}
}
-void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t data_len) {
+void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
return;
}
@@ -524,7 +520,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
continue;
}
- auto& npad = controller.shared_memory_entry;
+ auto* npad = controller.shared_memory;
const auto& motion_state = controller.device->GetMotions();
auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
@@ -610,32 +606,30 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
}
sixaxis_fullkey_state.sampling_number =
- npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_handheld_state.sampling_number =
- npad.sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_dual_left_state.sampling_number =
- npad.sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_dual_right_state.sampling_number =
- npad.sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_left_lifo_state.sampling_number =
- npad.sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_right_lifo_state.sampling_number =
- npad.sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ npad->sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
// This buffer only is updated on handheld on HW
- npad.sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
+ npad->sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
} else {
// Handheld doesn't update this buffer on HW
- npad.sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
+ npad->sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
}
- npad.sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
- npad.sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
- npad.sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
- npad.sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state);
- std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
- &controller.shared_memory_entry, sizeof(NpadInternalState));
+ npad->sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
+ npad->sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
+ npad->sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
+ npad->sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state);
}
}
@@ -713,8 +707,8 @@ void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceTy
}
auto& controller = GetControllerFromNpadIdType(npad_id);
- if (controller.shared_memory_entry.assignment_mode != assignment_mode) {
- controller.shared_memory_entry.assignment_mode = assignment_mode;
+ if (controller.shared_memory->assignment_mode != assignment_mode) {
+ controller.shared_memory->assignment_mode = assignment_mode;
}
if (!controller.device->IsConnected()) {
@@ -981,32 +975,32 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
controller.vibration[device_idx].device_mounted = false;
}
- auto& shared_memory_entry = controller.shared_memory_entry;
- // Don't reset shared_memory_entry.assignment_mode this value is persistent
- shared_memory_entry.style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out
- shared_memory_entry.device_type.raw = 0;
- shared_memory_entry.system_properties.raw = 0;
- shared_memory_entry.button_properties.raw = 0;
- shared_memory_entry.battery_level_dual = 0;
- shared_memory_entry.battery_level_left = 0;
- shared_memory_entry.battery_level_right = 0;
- shared_memory_entry.fullkey_color = {
+ auto* shared_memory = controller.shared_memory;
+ // Don't reset shared_memory->assignment_mode this value is persistent
+ shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out
+ shared_memory->device_type.raw = 0;
+ shared_memory->system_properties.raw = 0;
+ shared_memory->button_properties.raw = 0;
+ shared_memory->battery_level_dual = 0;
+ shared_memory->battery_level_left = 0;
+ shared_memory->battery_level_right = 0;
+ shared_memory->fullkey_color = {
.attribute = ColorAttribute::NoController,
.fullkey = {},
};
- shared_memory_entry.joycon_color = {
+ shared_memory->joycon_color = {
.attribute = ColorAttribute::NoController,
.left = {},
.right = {},
};
- shared_memory_entry.applet_footer.type = AppletFooterUiType::None;
+ shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::None;
controller.is_dual_left_connected = true;
controller.is_dual_right_connected = true;
controller.is_connected = false;
controller.device->Disconnect();
SignalStyleSetChangedEvent(npad_id);
- WriteEmptyEntry(controller.shared_memory_entry);
+ WriteEmptyEntry(shared_memory);
}
ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index b42532b68..0a96825a5 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -35,7 +35,7 @@ namespace Service::HID {
class Controller_NPad final : public ControllerBase {
public:
- explicit Controller_NPad(Core::HID::HIDCore& hid_core_,
+ explicit Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
KernelHelpers::ServiceContext& service_context_);
~Controller_NPad() override;
@@ -46,11 +46,10 @@ public:
void OnRelease() override;
// When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
// When the controller is requesting a motion update for the shared memory
- void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t size) override;
+ void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override;
// This is nn::hid::GyroscopeZeroDriftMode
enum class GyroscopeZeroDriftMode : u32 {
@@ -188,6 +187,8 @@ public:
static bool IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
private:
+ static constexpr std::size_t NPAD_COUNT = 10;
+
// This is nn::hid::detail::ColorAttribute
enum class ColorAttribute : u32 {
Ok = 0,
@@ -409,6 +410,13 @@ private:
U,
};
+ struct AppletNfcXcd {
+ union {
+ AppletFooterUi applet_footer{};
+ Lifo<NfcXcdDeviceHandleStateImpl, 0x2> nfc_xcd_device_lifo;
+ };
+ };
+
// This is nn::hid::detail::NpadInternalState
struct NpadInternalState {
Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None};
@@ -435,10 +443,7 @@ private:
Core::HID::NpadBatteryLevel battery_level_dual{};
Core::HID::NpadBatteryLevel battery_level_left{};
Core::HID::NpadBatteryLevel battery_level_right{};
- union {
- AppletFooterUi applet_footer{};
- Lifo<NfcXcdDeviceHandleStateImpl, 0x2> nfc_xcd_device_lifo;
- };
+ AppletNfcXcd applet_nfc_xcd{};
INSERT_PADDING_BYTES(0x20); // Unknown
Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo{};
NpadLarkType lark_type_l_and_main{};
@@ -465,9 +470,9 @@ private:
};
struct NpadControllerData {
- Core::HID::EmulatedController* device;
Kernel::KEvent* styleset_changed_event{};
- NpadInternalState shared_memory_entry{};
+ NpadInternalState* shared_memory = nullptr;
+ Core::HID::EmulatedController* device = nullptr;
std::array<VibrationData, 2> vibration{};
bool unintended_home_button_input_protection{};
@@ -497,15 +502,14 @@ private:
SixAxisSensorState sixaxis_dual_right_state{};
SixAxisSensorState sixaxis_left_lifo_state{};
SixAxisSensorState sixaxis_right_lifo_state{};
-
- int callback_key;
+ int callback_key{};
};
void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx);
void InitNewlyAddedController(Core::HID::NpadIdType npad_id);
bool IsControllerSupported(Core::HID::NpadStyleIndex controller) const;
void RequestPadStateUpdate(Core::HID::NpadIdType npad_id);
- void WriteEmptyEntry(NpadInternalState& npad);
+ void WriteEmptyEntry(NpadInternalState* npad);
NpadControllerData& GetControllerFromHandle(
const Core::HID::SixAxisSensorHandle& device_handle);
@@ -520,7 +524,7 @@ private:
std::atomic<u64> press_state{};
- std::array<NpadControllerData, 10> controller_data{};
+ std::array<NpadControllerData, NPAD_COUNT> controller_data{};
KernelHelpers::ServiceContext& service_context;
std::mutex mutex;
std::vector<Core::HID::NpadIdType> supported_npad_id_types{};
diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp
index 4d3b9d2be..df9ee0c3f 100644
--- a/src/core/hle/service/hid/controllers/stubbed.cpp
+++ b/src/core/hle/service/hid/controllers/stubbed.cpp
@@ -9,15 +9,18 @@
namespace Service::HID {
-Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
+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() = default;
void Controller_Stubbed::OnInit() {}
void Controller_Stubbed::OnRelease() {}
-void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t size) {
+void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!smart_update) {
return;
}
@@ -28,7 +31,7 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
header.entry_count = 0;
header.last_entry_index = 0;
- std::memcpy(data + common_offset, &header, sizeof(CommonHeader));
+ std::memcpy(raw_shared_memory + common_offset, &header, sizeof(CommonHeader));
}
void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) {
diff --git a/src/core/hle/service/hid/controllers/stubbed.h b/src/core/hle/service/hid/controllers/stubbed.h
index 512066eb3..1483a968e 100644
--- a/src/core/hle/service/hid/controllers/stubbed.h
+++ b/src/core/hle/service/hid/controllers/stubbed.h
@@ -9,7 +9,7 @@
namespace Service::HID {
class Controller_Stubbed final : public ControllerBase {
public:
- explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_);
+ explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_Stubbed() override;
// Called when the controller is initialized
@@ -19,19 +19,20 @@ public:
void OnRelease() override;
// When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
+ 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;
+ 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;
bool smart_update{};
std::size_t common_offset{};
};
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index 5b4b51a69..108ce5a41 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -15,8 +15,13 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400;
-Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_)
+Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_,
+ u8* raw_shared_memory_)
: ControllerBase{hid_core_} {
+ 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();
}
@@ -26,14 +31,12 @@ void Controller_Touchscreen::OnInit() {}
void Controller_Touchscreen::OnRelease() {}
-void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t size) {
- touch_screen_lifo.timestamp = core_timing.GetCPUTicks();
+void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ shared_memory->touch_screen_lifo.timestamp = core_timing.GetCPUTicks();
if (!IsControllerActivated()) {
- touch_screen_lifo.buffer_count = 0;
- touch_screen_lifo.buffer_tail = 0;
- std::memcpy(data, &touch_screen_lifo, sizeof(touch_screen_lifo));
+ shared_memory->touch_screen_lifo.buffer_count = 0;
+ shared_memory->touch_screen_lifo.buffer_tail = 0;
return;
}
@@ -74,7 +77,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter));
const u64 tick = core_timing.GetCPUTicks();
- const auto& last_entry = 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);
@@ -106,8 +109,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
}
}
- touch_screen_lifo.WriteNextEntry(next_state);
- std::memcpy(data + SHARED_MEMORY_OFFSET, &touch_screen_lifo, sizeof(touch_screen_lifo));
+ shared_memory->touch_screen_lifo.WriteNextEntry(next_state);
}
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h
index 424973b38..e57a3a80e 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.h
+++ b/src/core/hle/service/hid/controllers/touchscreen.h
@@ -25,14 +25,14 @@ public:
// This is nn::hid::TouchScreenConfigurationForNx
struct TouchScreenConfigurationForNx {
- TouchScreenModeForNx mode;
+ TouchScreenModeForNx mode{TouchScreenModeForNx::UseSystemSetting};
INSERT_PADDING_BYTES_NOINIT(0x7);
INSERT_PADDING_BYTES_NOINIT(0xF); // Reserved
};
static_assert(sizeof(TouchScreenConfigurationForNx) == 0x17,
"TouchScreenConfigurationForNx is an invalid size");
- explicit Controller_Touchscreen(Core::HID::HIDCore& hid_core_);
+ explicit Controller_Touchscreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_Touchscreen() override;
// Called when the controller is initialized
@@ -42,26 +42,32 @@ public:
void OnRelease() override;
// When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
private:
static constexpr std::size_t MAX_FINGERS = 16;
// This is nn::hid::TouchScreenState
struct TouchScreenState {
- s64 sampling_number;
- s32 entry_count;
+ s64 sampling_number{};
+ s32 entry_count{};
INSERT_PADDING_BYTES(4); // Reserved
- std::array<Core::HID::TouchState, MAX_FINGERS> states;
+ std::array<Core::HID::TouchState, MAX_FINGERS> states{};
};
static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size");
- // 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");
+ 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;
+ Core::HID::EmulatedConsole* console = nullptr;
- std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers;
- Core::HID::EmulatedConsole* console;
+ std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{};
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp
index fc6ac6457..62119e2c5 100644
--- a/src/core/hle/service/hid/controllers/xpad.cpp
+++ b/src/core/hle/service/hid/controllers/xpad.cpp
@@ -10,28 +10,31 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00;
-Controller_XPad::Controller_XPad(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
+Controller_XPad::Controller_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));
+}
Controller_XPad::~Controller_XPad() = default;
void Controller_XPad::OnInit() {}
void Controller_XPad::OnRelease() {}
-void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
- std::size_t size) {
+void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
- basic_xpad_lifo.buffer_count = 0;
- basic_xpad_lifo.buffer_tail = 0;
- std::memcpy(data + SHARED_MEMORY_OFFSET, &basic_xpad_lifo, sizeof(basic_xpad_lifo));
+ shared_memory->basic_xpad_lifo.buffer_count = 0;
+ shared_memory->basic_xpad_lifo.buffer_tail = 0;
return;
}
- const auto& last_entry = basic_xpad_lifo.ReadCurrentEntry().state;
+ 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
- basic_xpad_lifo.WriteNextEntry(next_state);
- std::memcpy(data + SHARED_MEMORY_OFFSET, &basic_xpad_lifo, sizeof(basic_xpad_lifo));
+ 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
index 8211b6ee3..d01dee5fc 100644
--- a/src/core/hle/service/hid/controllers/xpad.h
+++ b/src/core/hle/service/hid/controllers/xpad.h
@@ -12,7 +12,7 @@
namespace Service::HID {
class Controller_XPad final : public ControllerBase {
public:
- explicit Controller_XPad(Core::HID::HIDCore& hid_core_);
+ explicit Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_XPad() override;
// Called when the controller is initialized
@@ -22,7 +22,7 @@ public:
void OnRelease() override;
// When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
private:
// This is nn::hid::BasicXpadAttributeSet
@@ -90,17 +90,23 @@ private:
// 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;
+ 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");
- // 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");
+ 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.cpp b/src/core/hle/service/hid/hid.cpp
index fb1ec52b2..36162ac97 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -39,7 +39,6 @@ constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000};
constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
// TODO: Correct update rate for motion is 5ms. Check why some games don't behave at that speed
constexpr auto motion_update_ns = std::chrono::nanoseconds{10 * 1000 * 1000}; // (10ms, 100Hz)
-constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
IAppletResource::IAppletResource(Core::System& system_,
KernelHelpers::ServiceContext& service_context_)
@@ -48,20 +47,20 @@ IAppletResource::IAppletResource(Core::System& system_,
{0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
};
RegisterHandlers(functions);
-
- MakeController<Controller_DebugPad>(HidController::DebugPad);
- MakeController<Controller_Touchscreen>(HidController::Touchscreen);
- MakeController<Controller_Mouse>(HidController::Mouse);
- MakeController<Controller_Keyboard>(HidController::Keyboard);
- MakeController<Controller_XPad>(HidController::XPad);
- MakeController<Controller_Stubbed>(HidController::HomeButton);
- MakeController<Controller_Stubbed>(HidController::SleepButton);
- MakeController<Controller_Stubbed>(HidController::CaptureButton);
- MakeController<Controller_Stubbed>(HidController::InputDetector);
- MakeController<Controller_Stubbed>(HidController::UniquePad);
- MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad);
- MakeController<Controller_Gesture>(HidController::Gesture);
- MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor);
+ u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer();
+ MakeController<Controller_DebugPad>(HidController::DebugPad, shared_memory);
+ MakeController<Controller_Touchscreen>(HidController::Touchscreen, shared_memory);
+ MakeController<Controller_Mouse>(HidController::Mouse, shared_memory);
+ MakeController<Controller_Keyboard>(HidController::Keyboard, shared_memory);
+ MakeController<Controller_XPad>(HidController::XPad, shared_memory);
+ MakeController<Controller_Stubbed>(HidController::HomeButton, shared_memory);
+ MakeController<Controller_Stubbed>(HidController::SleepButton, shared_memory);
+ MakeController<Controller_Stubbed>(HidController::CaptureButton, shared_memory);
+ MakeController<Controller_Stubbed>(HidController::InputDetector, shared_memory);
+ MakeController<Controller_Stubbed>(HidController::UniquePad, shared_memory);
+ MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad, shared_memory);
+ MakeController<Controller_Gesture>(HidController::Gesture, shared_memory);
+ MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor, shared_memory);
// Homebrew doesn't try to activate some controllers, so we activate them by default
GetController<Controller_NPad>(HidController::NPad).ActivateController();
@@ -135,8 +134,7 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) {
continue;
}
- controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(),
- SHARED_MEMORY_SIZE);
+ controller->OnUpdate(core_timing);
}
// If ns_late is higher than the update rate ignore the delay
@@ -151,10 +149,8 @@ void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
- controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate(
- core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE);
- controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(
- core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE);
+ controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate(core_timing);
+ controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(core_timing);
// If ns_late is higher than the update rate ignore the delay
if (ns_late > mouse_keyboard_update_ns) {
@@ -167,8 +163,7 @@ void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
- controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate(
- core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE);
+ controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate(core_timing);
// If ns_late is higher than the update rate ignore the delay
if (ns_late > motion_update_ns) {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 95778e673..e61f8ed08 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -58,13 +58,14 @@ public:
private:
template <typename T>
- void MakeController(HidController controller) {
- controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>(system.HIDCore());
+ void MakeController(HidController controller, u8* shared_memory) {
+ controllers[static_cast<std::size_t>(controller)] =
+ std::make_unique<T>(system.HIDCore(), shared_memory);
}
template <typename T>
- void MakeControllerWithServiceContext(HidController controller) {
+ void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) {
controllers[static_cast<std::size_t>(controller)] =
- std::make_unique<T>(system.HIDCore(), service_context);
+ std::make_unique<T>(system.HIDCore(), shared_memory, service_context);
}
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp
index 46e5409db..d3a60cdd1 100644
--- a/src/yuzu/configuration/configure_ui.cpp
+++ b/src/yuzu/configuration/configure_ui.cpp
@@ -9,6 +9,7 @@
#include <QDirIterator>
#include "common/common_types.h"
#include "common/fs/path_util.h"
+#include "common/logging/log.h"
#include "common/settings.h"
#include "core/core.h"
#include "ui_configure_ui.h"
@@ -170,14 +171,74 @@ void ConfigureUi::RetranslateUI() {
}
void ConfigureUi::InitializeLanguageComboBox() {
+ // This is a list of lexicographically sorted languages, only the available translations are
+ // shown to the user.
+ static const struct {
+ const QString name;
+ const char* id;
+ } languages[] = {
+ // clang-format off
+ {QStringLiteral(u"Bahasa Indonesia"), "id"}, // Indonesian
+ {QStringLiteral(u"Bahasa Melayu"), "ms"}, // Malay
+ {QStringLiteral(u"Catal\u00E0"), "ca"}, // Catalan
+ {QStringLiteral(u"\u010Ce\u0161tina"), "cs"}, // Czech
+ {QStringLiteral(u"Dansk"), "da"}, // Danish
+ {QStringLiteral(u"Deutsch"), "de"}, // German
+ {QStringLiteral(u"English"), "en"}, // English
+ {QStringLiteral(u"Espa\u00F1ol"), "es"}, // Spanish
+ {QStringLiteral(u"Fran\u00E7ais"), "fr"}, // French
+ {QStringLiteral(u"Hrvatski"), "hr"}, // Croatian
+ {QStringLiteral(u"Italiano"), "it"}, // Italian
+ {QStringLiteral(u"Magyar"), "hu"}, // Hungarian
+ {QStringLiteral(u"Nederlands"), "nl"}, // Dutch
+ {QStringLiteral(u"Norsk bokm\u00E5l"), "nb"}, // Norwegian
+ {QStringLiteral(u"Polski"), "pl"}, // Polish
+ {QStringLiteral(u"Portugu\u00EAs"), "pt_PT"}, // Portuguese
+ {QStringLiteral(u"Portugu\u00EAs (Brasil)"), "pt_BR"}, // Portuguese (Brazil)
+ {QStringLiteral(u"Rom\u00E2n\u0103"), "ro"}, // Romanian
+ {QStringLiteral(u"Srpski"), "sr"}, // Serbian
+ {QStringLiteral(u"Suomi"), "fi"}, // Finnish
+ {QStringLiteral(u"Svenska"), "sv"}, // Swedish
+ {QStringLiteral(u"Ti\u1EBFng Vi\u1EC7t"), "vi"}, // Vietnamese
+ {QStringLiteral(u"Ti\u1EBFng Vi\u1EC7t (Vi\u1EC7t Nam)"), "vi_VN"}, // Vietnamese
+ {QStringLiteral(u"T\u00FCrk\u00E7e"), "tr_TR"}, // Turkish
+ {QStringLiteral(u"\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC"), "el"}, // Greek
+ {QStringLiteral(u"\u0420\u0443\u0441\u0441\u043A\u0438\u0439"), "ru_RU"}, // Russian
+ {QStringLiteral(u"\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430"),
+ "uk"}, // Ukrainian
+ {QStringLiteral(u"\u0627\u0644\u0639\u0631\u0628\u064A\u0629"), "ar"}, // Arabic
+ {QStringLiteral(u"\u0641\u0627\u0631\u0633\u06CC"), "fa"}, // Farsi
+ {QStringLiteral(u"\uD55C\uAD6D\uC5B4"), "ko_KR"}, // Korean
+ {QStringLiteral(u"\u65E5\u672C\u8A9E"), "ja_JP"}, // Japanese
+ {QStringLiteral(u"\u7B80\u4F53\u4E2D\u6587"), "zh_CN"}, // Simplified Chinese
+ {QStringLiteral(u"\u7E41\u9AD4\u4E2D\u6587"), "zh_TW"}, // Traditional Chinese
+ // clang-format on
+ };
ui->language_combobox->addItem(tr("<System>"), QString{});
- ui->language_combobox->addItem(tr("English"), QStringLiteral("en"));
- QDirIterator it(QStringLiteral(":/languages"), QDirIterator::NoIteratorFlags);
- while (it.hasNext()) {
- QString locale = it.next();
+ QDir languages_dir{QStringLiteral(":/languages")};
+ QStringList language_files = languages_dir.entryList();
+ for (const auto& lang : languages) {
+ if (QString::fromLatin1(lang.id) == QStringLiteral("en")) {
+ ui->language_combobox->addItem(lang.name, QStringLiteral("en"));
+ continue;
+ }
+ for (int i = 0; i < language_files.size(); ++i) {
+ QString locale = language_files[i];
+ locale.truncate(locale.lastIndexOf(QLatin1Char{'.'}));
+ if (QString::fromLatin1(lang.id) == locale) {
+ ui->language_combobox->addItem(lang.name, locale);
+ language_files.removeAt(i);
+ break;
+ }
+ }
+ }
+ // Anything remaining will be at the bottom
+ for (const QString& file : language_files) {
+ LOG_CRITICAL(Frontend, "Unexpected Language File: {}", file.toStdString());
+ QString locale = file;
locale.truncate(locale.lastIndexOf(QLatin1Char{'.'}));
- locale.remove(0, locale.lastIndexOf(QLatin1Char{'/'}) + 1);
- const QString lang = QLocale::languageToString(QLocale(locale).language());
+ const QString language_name = QLocale::languageToString(QLocale(locale).language());
+ const QString lang = QStringLiteral("%1 [%2]").arg(language_name, locale);
ui->language_combobox->addItem(lang, locale);
}