early-access version 2692
This commit is contained in:
parent
f893fd07de
commit
2767a169c9
23 changed files with 428 additions and 387 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 2691.
|
This is the source code for early-access 2692.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -317,27 +317,27 @@ static_assert(sizeof(TouchAttribute) == 0x4, "TouchAttribute is an invalid size"
|
||||||
|
|
||||||
// This is nn::hid::TouchState
|
// This is nn::hid::TouchState
|
||||||
struct TouchState {
|
struct TouchState {
|
||||||
u64 delta_time;
|
u64 delta_time{};
|
||||||
TouchAttribute attribute;
|
TouchAttribute attribute{};
|
||||||
u32 finger;
|
u32 finger{};
|
||||||
Common::Point<u32> position;
|
Common::Point<u32> position{};
|
||||||
u32 diameter_x;
|
u32 diameter_x{};
|
||||||
u32 diameter_y;
|
u32 diameter_y{};
|
||||||
u32 rotation_angle;
|
u32 rotation_angle{};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size");
|
static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size");
|
||||||
|
|
||||||
// This is nn::hid::NpadControllerColor
|
// This is nn::hid::NpadControllerColor
|
||||||
struct NpadControllerColor {
|
struct NpadControllerColor {
|
||||||
u32 body;
|
u32 body{};
|
||||||
u32 button;
|
u32 button{};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(NpadControllerColor) == 8, "NpadControllerColor is an invalid size");
|
static_assert(sizeof(NpadControllerColor) == 8, "NpadControllerColor is an invalid size");
|
||||||
|
|
||||||
// This is nn::hid::AnalogStickState
|
// This is nn::hid::AnalogStickState
|
||||||
struct AnalogStickState {
|
struct AnalogStickState {
|
||||||
s32 x;
|
s32 x{};
|
||||||
s32 y;
|
s32 y{};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(AnalogStickState) == 8, "AnalogStickState is an invalid size");
|
static_assert(sizeof(AnalogStickState) == 8, "AnalogStickState is an invalid size");
|
||||||
|
|
||||||
|
@ -355,10 +355,10 @@ static_assert(sizeof(NpadBatteryLevel) == 0x4, "NpadBatteryLevel is an invalid s
|
||||||
|
|
||||||
// This is nn::hid::system::NpadPowerInfo
|
// This is nn::hid::system::NpadPowerInfo
|
||||||
struct NpadPowerInfo {
|
struct NpadPowerInfo {
|
||||||
bool is_powered;
|
bool is_powered{};
|
||||||
bool is_charging;
|
bool is_charging{};
|
||||||
INSERT_PADDING_BYTES(0x6);
|
INSERT_PADDING_BYTES(0x6);
|
||||||
NpadBatteryLevel battery_level;
|
NpadBatteryLevel battery_level{8};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size");
|
static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size");
|
||||||
|
|
||||||
|
@ -475,8 +475,8 @@ static_assert(sizeof(DebugPadButton) == 0x4, "DebugPadButton is an invalid size"
|
||||||
|
|
||||||
// This is nn::hid::ConsoleSixAxisSensorHandle
|
// This is nn::hid::ConsoleSixAxisSensorHandle
|
||||||
struct ConsoleSixAxisSensorHandle {
|
struct ConsoleSixAxisSensorHandle {
|
||||||
u8 unknown_1;
|
u8 unknown_1{};
|
||||||
u8 unknown_2;
|
u8 unknown_2{};
|
||||||
INSERT_PADDING_BYTES_NOINIT(2);
|
INSERT_PADDING_BYTES_NOINIT(2);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(ConsoleSixAxisSensorHandle) == 4,
|
static_assert(sizeof(ConsoleSixAxisSensorHandle) == 4,
|
||||||
|
@ -484,9 +484,9 @@ static_assert(sizeof(ConsoleSixAxisSensorHandle) == 4,
|
||||||
|
|
||||||
// This is nn::hid::SixAxisSensorHandle
|
// This is nn::hid::SixAxisSensorHandle
|
||||||
struct SixAxisSensorHandle {
|
struct SixAxisSensorHandle {
|
||||||
NpadStyleIndex npad_type;
|
NpadStyleIndex npad_type{NpadStyleIndex::None};
|
||||||
u8 npad_id;
|
u8 npad_id{};
|
||||||
DeviceIndex device_index;
|
DeviceIndex device_index{DeviceIndex::None};
|
||||||
INSERT_PADDING_BYTES_NOINIT(1);
|
INSERT_PADDING_BYTES_NOINIT(1);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(SixAxisSensorHandle) == 4, "SixAxisSensorHandle is an invalid size");
|
static_assert(sizeof(SixAxisSensorHandle) == 4, "SixAxisSensorHandle is an invalid size");
|
||||||
|
@ -501,19 +501,19 @@ static_assert(sizeof(SixAxisSensorFusionParameters) == 8,
|
||||||
|
|
||||||
// This is nn::hid::VibrationDeviceHandle
|
// This is nn::hid::VibrationDeviceHandle
|
||||||
struct VibrationDeviceHandle {
|
struct VibrationDeviceHandle {
|
||||||
NpadStyleIndex npad_type;
|
NpadStyleIndex npad_type{NpadStyleIndex::None};
|
||||||
u8 npad_id;
|
u8 npad_id{};
|
||||||
DeviceIndex device_index;
|
DeviceIndex device_index{DeviceIndex::None};
|
||||||
INSERT_PADDING_BYTES_NOINIT(1);
|
INSERT_PADDING_BYTES_NOINIT(1);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(VibrationDeviceHandle) == 4, "SixAxisSensorHandle is an invalid size");
|
static_assert(sizeof(VibrationDeviceHandle) == 4, "SixAxisSensorHandle is an invalid size");
|
||||||
|
|
||||||
// This is nn::hid::VibrationValue
|
// This is nn::hid::VibrationValue
|
||||||
struct VibrationValue {
|
struct VibrationValue {
|
||||||
f32 low_amplitude;
|
f32 low_amplitude{};
|
||||||
f32 low_frequency;
|
f32 low_frequency{};
|
||||||
f32 high_amplitude;
|
f32 high_amplitude{};
|
||||||
f32 high_frequency;
|
f32 high_frequency{};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size.");
|
static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size.");
|
||||||
|
|
||||||
|
@ -562,7 +562,7 @@ static_assert(sizeof(KeyboardAttribute) == 0x4, "KeyboardAttribute is an invalid
|
||||||
// This is nn::hid::KeyboardKey
|
// This is nn::hid::KeyboardKey
|
||||||
struct KeyboardKey {
|
struct KeyboardKey {
|
||||||
// This should be a 256 bit flag
|
// 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");
|
static_assert(sizeof(KeyboardKey) == 0x20, "KeyboardKey is an invalid size");
|
||||||
|
|
||||||
|
@ -591,16 +591,16 @@ static_assert(sizeof(MouseAttribute) == 0x4, "MouseAttribute is an invalid size"
|
||||||
|
|
||||||
// This is nn::hid::detail::MouseState
|
// This is nn::hid::detail::MouseState
|
||||||
struct MouseState {
|
struct MouseState {
|
||||||
s64 sampling_number;
|
s64 sampling_number{};
|
||||||
s32 x;
|
s32 x{};
|
||||||
s32 y;
|
s32 y{};
|
||||||
s32 delta_x;
|
s32 delta_x{};
|
||||||
s32 delta_y;
|
s32 delta_y{};
|
||||||
// Axis Order in HW is switched for the wheel
|
// Axis Order in HW is switched for the wheel
|
||||||
s32 delta_wheel_y;
|
s32 delta_wheel_y{};
|
||||||
s32 delta_wheel_x;
|
s32 delta_wheel_x{};
|
||||||
MouseButton button;
|
MouseButton button{};
|
||||||
MouseAttribute attribute;
|
MouseAttribute attribute{};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(MouseState) == 0x28, "MouseState is an invalid size");
|
static_assert(sizeof(MouseState) == 0x28, "MouseState is an invalid size");
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,14 @@
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200;
|
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_} {
|
: ControllerBase{hid_core_} {
|
||||||
console = hid_core.GetEmulatedConsole();
|
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;
|
Controller_ConsoleSixAxis::~Controller_ConsoleSixAxis() = default;
|
||||||
|
@ -21,8 +26,7 @@ void Controller_ConsoleSixAxis::OnInit() {}
|
||||||
|
|
||||||
void Controller_ConsoleSixAxis::OnRelease() {}
|
void Controller_ConsoleSixAxis::OnRelease() {}
|
||||||
|
|
||||||
void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
std::size_t size) {
|
|
||||||
if (!IsControllerActivated() || !is_transfer_memory_set) {
|
if (!IsControllerActivated() || !is_transfer_memory_set) {
|
||||||
seven_sixaxis_lifo.buffer_count = 0;
|
seven_sixaxis_lifo.buffer_count = 0;
|
||||||
seven_sixaxis_lifo.buffer_tail = 0;
|
seven_sixaxis_lifo.buffer_tail = 0;
|
||||||
|
@ -49,13 +53,11 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti
|
||||||
-motion_status.quaternion.xyz.z,
|
-motion_status.quaternion.xyz.z,
|
||||||
};
|
};
|
||||||
|
|
||||||
console_six_axis.sampling_number++;
|
shared_memory->sampling_number++;
|
||||||
console_six_axis.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
|
shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
|
||||||
console_six_axis.verticalization_error = motion_status.verticalization_error;
|
shared_memory->verticalization_error = motion_status.verticalization_error;
|
||||||
console_six_axis.gyro_bias = motion_status.gyro_bias;
|
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
|
// Update seven six axis transfer memory
|
||||||
seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state);
|
seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state);
|
||||||
std::memcpy(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo));
|
std::memcpy(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo));
|
||||||
|
|
|
@ -18,7 +18,7 @@ class EmulatedConsole;
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
class Controller_ConsoleSixAxis final : public ControllerBase {
|
class Controller_ConsoleSixAxis final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_);
|
explicit Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
|
||||||
~Controller_ConsoleSixAxis() override;
|
~Controller_ConsoleSixAxis() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -28,7 +28,7 @@ public:
|
||||||
void OnRelease() override;
|
void OnRelease() override;
|
||||||
|
|
||||||
// When the controller is requesting an update for the shared memory
|
// 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
|
// Called on InitializeSevenSixAxisSensor
|
||||||
void SetTransferMemoryPointer(u8* t_mem);
|
void SetTransferMemoryPointer(u8* t_mem);
|
||||||
|
@ -62,12 +62,13 @@ private:
|
||||||
Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{};
|
Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{};
|
||||||
static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size");
|
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;
|
u8* transfer_memory = nullptr;
|
||||||
|
ConsoleSharedMemory* shared_memory = nullptr;
|
||||||
|
Core::HID::EmulatedConsole* console = nullptr;
|
||||||
|
|
||||||
bool is_transfer_memory_set = false;
|
bool is_transfer_memory_set = false;
|
||||||
u64 last_saved_timestamp{};
|
u64 last_saved_timestamp{};
|
||||||
u64 last_global_timestamp{};
|
u64 last_global_timestamp{};
|
||||||
ConsoleSharedMemory console_six_axis{};
|
|
||||||
SevenSixAxisState next_seven_sixaxis_state{};
|
|
||||||
};
|
};
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -27,12 +27,10 @@ public:
|
||||||
virtual void OnRelease() = 0;
|
virtual void OnRelease() = 0;
|
||||||
|
|
||||||
// When the controller is requesting an update for the shared memory
|
// When the controller is requesting an update for the shared memory
|
||||||
virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing) = 0;
|
||||||
std::size_t size) = 0;
|
|
||||||
|
|
||||||
// When the controller is requesting a motion update for the shared memory
|
// When the controller is requesting a motion update for the shared memory
|
||||||
virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {}
|
||||||
std::size_t size) {}
|
|
||||||
|
|
||||||
void ActivateController();
|
void ActivateController();
|
||||||
|
|
||||||
|
@ -41,6 +39,7 @@ public:
|
||||||
bool IsControllerActivated() const;
|
bool IsControllerActivated() const;
|
||||||
|
|
||||||
static const std::size_t hid_entry_count = 17;
|
static const std::size_t hid_entry_count = 17;
|
||||||
|
static const std::size_t shared_memory_size = 0x40000;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool is_activated{false};
|
bool is_activated{false};
|
||||||
|
|
|
@ -14,8 +14,12 @@
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000;
|
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_} {
|
: 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);
|
controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,16 +29,14 @@ void Controller_DebugPad::OnInit() {}
|
||||||
|
|
||||||
void Controller_DebugPad::OnRelease() {}
|
void Controller_DebugPad::OnRelease() {}
|
||||||
|
|
||||||
void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
std::size_t size) {
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
debug_pad_lifo.buffer_count = 0;
|
shared_memory->debug_pad_lifo.buffer_count = 0;
|
||||||
debug_pad_lifo.buffer_tail = 0;
|
shared_memory->debug_pad_lifo.buffer_tail = 0;
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &debug_pad_lifo, sizeof(debug_pad_lifo));
|
|
||||||
return;
|
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;
|
next_state.sampling_number = last_entry.sampling_number + 1;
|
||||||
|
|
||||||
if (Settings::values.debug_pad_enabled) {
|
if (Settings::values.debug_pad_enabled) {
|
||||||
|
@ -48,8 +50,7 @@ void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing,
|
||||||
next_state.r_stick = stick_state.right;
|
next_state.r_stick = stick_state.right;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_pad_lifo.WriteNextEntry(next_state);
|
shared_memory->debug_pad_lifo.WriteNextEntry(next_state);
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &debug_pad_lifo, sizeof(debug_pad_lifo));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -18,7 +18,7 @@ struct AnalogStickState;
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
class Controller_DebugPad final : public ControllerBase {
|
class Controller_DebugPad final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit Controller_DebugPad(Core::HID::HIDCore& hid_core_);
|
explicit Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
|
||||||
~Controller_DebugPad() override;
|
~Controller_DebugPad() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -28,7 +28,7 @@ public:
|
||||||
void OnRelease() override;
|
void OnRelease() override;
|
||||||
|
|
||||||
// When the controller is requesting an update for the shared memory
|
// 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:
|
private:
|
||||||
// This is nn::hid::DebugPadAttribute
|
// This is nn::hid::DebugPadAttribute
|
||||||
|
@ -42,19 +42,24 @@ private:
|
||||||
|
|
||||||
// This is nn::hid::DebugPadState
|
// This is nn::hid::DebugPadState
|
||||||
struct DebugPadState {
|
struct DebugPadState {
|
||||||
s64 sampling_number;
|
s64 sampling_number{};
|
||||||
DebugPadAttribute attribute;
|
DebugPadAttribute attribute{};
|
||||||
Core::HID::DebugPadButton pad_state;
|
Core::HID::DebugPadButton pad_state{};
|
||||||
Core::HID::AnalogStickState r_stick;
|
Core::HID::AnalogStickState r_stick{};
|
||||||
Core::HID::AnalogStickState l_stick;
|
Core::HID::AnalogStickState l_stick{};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state");
|
static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state");
|
||||||
|
|
||||||
|
struct DebugPadSharedMemory {
|
||||||
// This is nn::hid::detail::DebugPadLifo
|
// This is nn::hid::detail::DebugPadLifo
|
||||||
Lifo<DebugPadState, hid_entry_count> debug_pad_lifo{};
|
Lifo<DebugPadState, hid_entry_count> debug_pad_lifo{};
|
||||||
static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size");
|
static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size");
|
||||||
DebugPadState next_state{};
|
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
|
} // namespace Service::HID
|
||||||
|
|
|
@ -24,25 +24,28 @@ constexpr f32 Square(s32 num) {
|
||||||
return static_cast<f32>(num * 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();
|
console = hid_core.GetEmulatedConsole();
|
||||||
}
|
}
|
||||||
Controller_Gesture::~Controller_Gesture() = default;
|
Controller_Gesture::~Controller_Gesture() = default;
|
||||||
|
|
||||||
void Controller_Gesture::OnInit() {
|
void Controller_Gesture::OnInit() {
|
||||||
gesture_lifo.buffer_count = 0;
|
shared_memory->gesture_lifo.buffer_count = 0;
|
||||||
gesture_lifo.buffer_tail = 0;
|
shared_memory->gesture_lifo.buffer_tail = 0;
|
||||||
force_update = true;
|
force_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_Gesture::OnRelease() {}
|
void Controller_Gesture::OnRelease() {}
|
||||||
|
|
||||||
void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
std::size_t size) {
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
gesture_lifo.buffer_count = 0;
|
shared_memory->gesture_lifo.buffer_count = 0;
|
||||||
gesture_lifo.buffer_tail = 0;
|
shared_memory->gesture_lifo.buffer_tail = 0;
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &gesture_lifo, sizeof(gesture_lifo));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,15 +53,15 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
|
||||||
|
|
||||||
GestureProperties gesture = GetGestureProperties();
|
GestureProperties gesture = GetGestureProperties();
|
||||||
f32 time_difference =
|
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
|
// Only update if necesary
|
||||||
if (!ShouldUpdateGesture(gesture, time_difference)) {
|
if (!ShouldUpdateGesture(gesture, time_difference)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_update_timestamp = gesture_lifo.timestamp;
|
last_update_timestamp = shared_memory->gesture_lifo.timestamp;
|
||||||
UpdateGestureSharedMemory(data, size, gesture, time_difference);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_Gesture::ReadTouchInput() {
|
void Controller_Gesture::ReadTouchInput() {
|
||||||
|
@ -98,7 +101,7 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
|
||||||
GestureType type = GestureType::Idle;
|
GestureType type = GestureType::Idle;
|
||||||
GestureAttribute attributes{};
|
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
|
// Reset next state to default
|
||||||
next_state.sampling_number = last_entry.sampling_number + 1;
|
next_state.sampling_number = last_entry.sampling_number + 1;
|
||||||
|
@ -128,8 +131,7 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
|
||||||
next_state.points = gesture.points;
|
next_state.points = gesture.points;
|
||||||
last_gesture = gesture;
|
last_gesture = gesture;
|
||||||
|
|
||||||
gesture_lifo.WriteNextEntry(next_state);
|
shared_memory->gesture_lifo.WriteNextEntry(next_state);
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &gesture_lifo, sizeof(gesture_lifo));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
|
void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
|
||||||
|
@ -306,7 +308,7 @@ void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture,
|
||||||
}
|
}
|
||||||
|
|
||||||
const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const {
|
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() {
|
Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
class Controller_Gesture final : public ControllerBase {
|
class Controller_Gesture final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit Controller_Gesture(Core::HID::HIDCore& hid_core_);
|
explicit Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
|
||||||
~Controller_Gesture() override;
|
~Controller_Gesture() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -25,7 +25,7 @@ public:
|
||||||
void OnRelease() override;
|
void OnRelease() override;
|
||||||
|
|
||||||
// When the controller is requesting an update for the shared memory
|
// 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:
|
private:
|
||||||
static constexpr size_t MAX_FINGERS = 16;
|
static constexpr size_t MAX_FINGERS = 16;
|
||||||
|
@ -67,19 +67,19 @@ private:
|
||||||
|
|
||||||
// This is nn::hid::GestureState
|
// This is nn::hid::GestureState
|
||||||
struct GestureState {
|
struct GestureState {
|
||||||
s64 sampling_number;
|
s64 sampling_number{};
|
||||||
s64 detection_count;
|
s64 detection_count{};
|
||||||
GestureType type;
|
GestureType type{GestureType::Idle};
|
||||||
GestureDirection direction;
|
GestureDirection direction{GestureDirection::None};
|
||||||
Common::Point<s32> pos;
|
Common::Point<s32> pos{};
|
||||||
Common::Point<s32> delta;
|
Common::Point<s32> delta{};
|
||||||
f32 vel_x;
|
f32 vel_x{};
|
||||||
f32 vel_y;
|
f32 vel_y{};
|
||||||
GestureAttribute attributes;
|
GestureAttribute attributes{};
|
||||||
f32 scale;
|
f32 scale{};
|
||||||
f32 rotation_angle;
|
f32 rotation_angle{};
|
||||||
s32 point_count;
|
s32 point_count{};
|
||||||
std::array<Common::Point<s32>, 4> points;
|
std::array<Common::Point<s32>, 4> points{};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size");
|
static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size");
|
||||||
|
|
||||||
|
@ -93,6 +93,14 @@ private:
|
||||||
f32 angle{};
|
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
|
// Reads input from all available input engines
|
||||||
void ReadTouchInput();
|
void ReadTouchInput();
|
||||||
|
|
||||||
|
@ -135,12 +143,9 @@ private:
|
||||||
// Returns the average distance, angle and middle point of the active fingers
|
// Returns the average distance, angle and middle point of the active fingers
|
||||||
GestureProperties GetGestureProperties();
|
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{};
|
GestureState next_state{};
|
||||||
|
GestureSharedMemory* shared_memory = nullptr;
|
||||||
Core::HID::EmulatedConsole* console;
|
Core::HID::EmulatedConsole* console = nullptr;
|
||||||
|
|
||||||
std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{};
|
std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{};
|
||||||
GestureProperties last_gesture{};
|
GestureProperties last_gesture{};
|
||||||
|
|
|
@ -13,8 +13,12 @@
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800;
|
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_} {
|
: 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();
|
emulated_devices = hid_core.GetEmulatedDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,16 +28,14 @@ void Controller_Keyboard::OnInit() {}
|
||||||
|
|
||||||
void Controller_Keyboard::OnRelease() {}
|
void Controller_Keyboard::OnRelease() {}
|
||||||
|
|
||||||
void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
std::size_t size) {
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
keyboard_lifo.buffer_count = 0;
|
shared_memory->keyboard_lifo.buffer_count = 0;
|
||||||
keyboard_lifo.buffer_tail = 0;
|
shared_memory->keyboard_lifo.buffer_tail = 0;
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &keyboard_lifo, sizeof(keyboard_lifo));
|
|
||||||
return;
|
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;
|
next_state.sampling_number = last_entry.sampling_number + 1;
|
||||||
|
|
||||||
if (Settings::values.keyboard_enabled) {
|
if (Settings::values.keyboard_enabled) {
|
||||||
|
@ -45,8 +47,7 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
|
||||||
next_state.attribute.is_connected.Assign(1);
|
next_state.attribute.is_connected.Assign(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
keyboard_lifo.WriteNextEntry(next_state);
|
shared_memory->keyboard_lifo.WriteNextEntry(next_state);
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &keyboard_lifo, sizeof(keyboard_lifo));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct KeyboardKey;
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
class Controller_Keyboard final : public ControllerBase {
|
class Controller_Keyboard final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit Controller_Keyboard(Core::HID::HIDCore& hid_core_);
|
explicit Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
|
||||||
~Controller_Keyboard() override;
|
~Controller_Keyboard() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -27,23 +27,28 @@ public:
|
||||||
void OnRelease() override;
|
void OnRelease() override;
|
||||||
|
|
||||||
// When the controller is requesting an update for the shared memory
|
// 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:
|
private:
|
||||||
// This is nn::hid::detail::KeyboardState
|
// This is nn::hid::detail::KeyboardState
|
||||||
struct KeyboardState {
|
struct KeyboardState {
|
||||||
s64 sampling_number;
|
s64 sampling_number{};
|
||||||
Core::HID::KeyboardModifier modifier;
|
Core::HID::KeyboardModifier modifier{};
|
||||||
Core::HID::KeyboardAttribute attribute;
|
Core::HID::KeyboardAttribute attribute{};
|
||||||
Core::HID::KeyboardKey key;
|
Core::HID::KeyboardKey key{};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size");
|
static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size");
|
||||||
|
|
||||||
|
struct KeyboardSharedMemory {
|
||||||
// This is nn::hid::detail::KeyboardLifo
|
// This is nn::hid::detail::KeyboardLifo
|
||||||
Lifo<KeyboardState, hid_entry_count> keyboard_lifo{};
|
Lifo<KeyboardState, hid_entry_count> keyboard_lifo{};
|
||||||
static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size");
|
static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size");
|
||||||
KeyboardState next_state{};
|
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
|
} // namespace Service::HID
|
||||||
|
|
|
@ -13,7 +13,12 @@
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400;
|
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();
|
emulated_devices = hid_core.GetEmulatedDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,16 +27,14 @@ Controller_Mouse::~Controller_Mouse() = default;
|
||||||
void Controller_Mouse::OnInit() {}
|
void Controller_Mouse::OnInit() {}
|
||||||
void Controller_Mouse::OnRelease() {}
|
void Controller_Mouse::OnRelease() {}
|
||||||
|
|
||||||
void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
std::size_t size) {
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
mouse_lifo.buffer_count = 0;
|
shared_memory->mouse_lifo.buffer_count = 0;
|
||||||
mouse_lifo.buffer_tail = 0;
|
shared_memory->mouse_lifo.buffer_tail = 0;
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &mouse_lifo, sizeof(mouse_lifo));
|
|
||||||
return;
|
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.sampling_number = last_entry.sampling_number + 1;
|
||||||
|
|
||||||
next_state.attribute.raw = 0;
|
next_state.attribute.raw = 0;
|
||||||
|
@ -51,8 +54,7 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
next_state.button = mouse_button_state;
|
next_state.button = mouse_button_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
mouse_lifo.WriteNextEntry(next_state);
|
shared_memory->mouse_lifo.WriteNextEntry(next_state);
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &mouse_lifo, sizeof(mouse_lifo));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct AnalogStickState;
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
class Controller_Mouse final : public ControllerBase {
|
class Controller_Mouse final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit Controller_Mouse(Core::HID::HIDCore& hid_core_);
|
explicit Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
|
||||||
~Controller_Mouse() override;
|
~Controller_Mouse() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -27,15 +27,20 @@ public:
|
||||||
void OnRelease() override;
|
void OnRelease() override;
|
||||||
|
|
||||||
// When the controller is requesting an update for the shared memory
|
// 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:
|
private:
|
||||||
|
struct MouseSharedMemory {
|
||||||
// This is nn::hid::detail::MouseLifo
|
// This is nn::hid::detail::MouseLifo
|
||||||
Lifo<Core::HID::MouseState, hid_entry_count> mouse_lifo{};
|
Lifo<Core::HID::MouseState, hid_entry_count> mouse_lifo{};
|
||||||
static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size");
|
static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size");
|
||||||
Core::HID::MouseState next_state{};
|
INSERT_PADDING_WORDS(0x2C);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(MouseSharedMemory) == 0x400, "MouseSharedMemory is an invalid size");
|
||||||
|
|
||||||
Core::HID::AnalogStickState last_mouse_wheel_state;
|
Core::HID::MouseState next_state{};
|
||||||
Core::HID::EmulatedDevices* emulated_devices;
|
Core::HID::AnalogStickState last_mouse_wheel_state{};
|
||||||
|
MouseSharedMemory* shared_memory = nullptr;
|
||||||
|
Core::HID::EmulatedDevices* emulated_devices = nullptr;
|
||||||
};
|
};
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -62,11 +62,14 @@ bool Controller_NPad::IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle&
|
||||||
return npad_id && npad_type && device_index;
|
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_)
|
KernelHelpers::ServiceContext& service_context_)
|
||||||
: ControllerBase{hid_core_}, service_context{service_context_} {
|
: ControllerBase{hid_core_}, service_context{service_context_} {
|
||||||
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
||||||
|
assert(NPAD_OFFSET + ((i + 1) * sizeof(NpadInternalState)) < shared_memory_size);
|
||||||
auto& controller = controller_data[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.device = hid_core.GetEmulatedControllerByIndex(i);
|
||||||
controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
|
controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
|
||||||
Core::HID::DEFAULT_VIBRATION_VALUE;
|
Core::HID::DEFAULT_VIBRATION_VALUE;
|
||||||
|
@ -116,11 +119,11 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
|
||||||
if (!controller.device->IsConnected()) {
|
if (!controller.device->IsConnected()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto& shared_memory = controller.shared_memory_entry;
|
auto* shared_memory = controller.shared_memory;
|
||||||
const auto& battery_level = controller.device->GetBattery();
|
const auto& battery_level = controller.device->GetBattery();
|
||||||
shared_memory.battery_level_dual = battery_level.dual.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_left = battery_level.left.battery_level;
|
||||||
shared_memory.battery_level_right = battery_level.right.battery_level;
|
shared_memory->battery_level_right = battery_level.right.battery_level;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -135,99 +138,100 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
|
||||||
}
|
}
|
||||||
LOG_DEBUG(Service_HID, "Npad connected {}", npad_id);
|
LOG_DEBUG(Service_HID, "Npad connected {}", npad_id);
|
||||||
const auto controller_type = controller.device->GetNpadStyleIndex();
|
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) {
|
if (controller_type == Core::HID::NpadStyleIndex::None) {
|
||||||
controller.styleset_changed_event->GetWritableEvent().Signal();
|
controller.styleset_changed_event->GetWritableEvent().Signal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
shared_memory.style_tag.raw = Core::HID::NpadStyleSet::None;
|
shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None;
|
||||||
shared_memory.device_type.raw = 0;
|
shared_memory->device_type.raw = 0;
|
||||||
shared_memory.system_properties.raw = 0;
|
shared_memory->system_properties.raw = 0;
|
||||||
switch (controller_type) {
|
switch (controller_type) {
|
||||||
case Core::HID::NpadStyleIndex::None:
|
case Core::HID::NpadStyleIndex::None:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::ProController:
|
case Core::HID::NpadStyleIndex::ProController:
|
||||||
shared_memory.style_tag.fullkey.Assign(1);
|
shared_memory->style_tag.fullkey.Assign(1);
|
||||||
shared_memory.device_type.fullkey.Assign(1);
|
shared_memory->device_type.fullkey.Assign(1);
|
||||||
shared_memory.system_properties.is_vertical.Assign(1);
|
shared_memory->system_properties.is_vertical.Assign(1);
|
||||||
shared_memory.system_properties.use_plus.Assign(1);
|
shared_memory->system_properties.use_plus.Assign(1);
|
||||||
shared_memory.system_properties.use_minus.Assign(1);
|
shared_memory->system_properties.use_minus.Assign(1);
|
||||||
shared_memory.applet_footer.type = AppletFooterUiType::SwitchProController;
|
shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::SwitchProController;
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::Handheld:
|
case Core::HID::NpadStyleIndex::Handheld:
|
||||||
shared_memory.style_tag.handheld.Assign(1);
|
shared_memory->style_tag.handheld.Assign(1);
|
||||||
shared_memory.device_type.handheld_left.Assign(1);
|
shared_memory->device_type.handheld_left.Assign(1);
|
||||||
shared_memory.device_type.handheld_right.Assign(1);
|
shared_memory->device_type.handheld_right.Assign(1);
|
||||||
shared_memory.system_properties.is_vertical.Assign(1);
|
shared_memory->system_properties.is_vertical.Assign(1);
|
||||||
shared_memory.system_properties.use_plus.Assign(1);
|
shared_memory->system_properties.use_plus.Assign(1);
|
||||||
shared_memory.system_properties.use_minus.Assign(1);
|
shared_memory->system_properties.use_minus.Assign(1);
|
||||||
shared_memory.system_properties.use_directional_buttons.Assign(1);
|
shared_memory->system_properties.use_directional_buttons.Assign(1);
|
||||||
shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual;
|
shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual;
|
||||||
shared_memory.applet_footer.type = AppletFooterUiType::HandheldJoyConLeftJoyConRight;
|
shared_memory->applet_nfc_xcd.applet_footer.type =
|
||||||
|
AppletFooterUiType::HandheldJoyConLeftJoyConRight;
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::JoyconDual:
|
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) {
|
if (controller.is_dual_left_connected) {
|
||||||
shared_memory.device_type.joycon_left.Assign(1);
|
shared_memory->device_type.joycon_left.Assign(1);
|
||||||
shared_memory.system_properties.use_minus.Assign(1);
|
shared_memory->system_properties.use_minus.Assign(1);
|
||||||
}
|
}
|
||||||
if (controller.is_dual_right_connected) {
|
if (controller.is_dual_right_connected) {
|
||||||
shared_memory.device_type.joycon_right.Assign(1);
|
shared_memory->device_type.joycon_right.Assign(1);
|
||||||
shared_memory.system_properties.use_plus.Assign(1);
|
shared_memory->system_properties.use_plus.Assign(1);
|
||||||
}
|
}
|
||||||
shared_memory.system_properties.use_directional_buttons.Assign(1);
|
shared_memory->system_properties.use_directional_buttons.Assign(1);
|
||||||
shared_memory.system_properties.is_vertical.Assign(1);
|
shared_memory->system_properties.is_vertical.Assign(1);
|
||||||
shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual;
|
shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual;
|
||||||
if (controller.is_dual_left_connected && controller.is_dual_right_connected) {
|
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) {
|
} 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 {
|
} else {
|
||||||
shared_memory.applet_footer.type = AppletFooterUiType::JoyDualRightOnly;
|
shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualRightOnly;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::JoyconLeft:
|
case Core::HID::NpadStyleIndex::JoyconLeft:
|
||||||
shared_memory.style_tag.joycon_left.Assign(1);
|
shared_memory->style_tag.joycon_left.Assign(1);
|
||||||
shared_memory.device_type.joycon_left.Assign(1);
|
shared_memory->device_type.joycon_left.Assign(1);
|
||||||
shared_memory.system_properties.is_horizontal.Assign(1);
|
shared_memory->system_properties.is_horizontal.Assign(1);
|
||||||
shared_memory.system_properties.use_minus.Assign(1);
|
shared_memory->system_properties.use_minus.Assign(1);
|
||||||
shared_memory.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal;
|
shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal;
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::JoyconRight:
|
case Core::HID::NpadStyleIndex::JoyconRight:
|
||||||
shared_memory.style_tag.joycon_right.Assign(1);
|
shared_memory->style_tag.joycon_right.Assign(1);
|
||||||
shared_memory.device_type.joycon_right.Assign(1);
|
shared_memory->device_type.joycon_right.Assign(1);
|
||||||
shared_memory.system_properties.is_horizontal.Assign(1);
|
shared_memory->system_properties.is_horizontal.Assign(1);
|
||||||
shared_memory.system_properties.use_plus.Assign(1);
|
shared_memory->system_properties.use_plus.Assign(1);
|
||||||
shared_memory.applet_footer.type = AppletFooterUiType::JoyRightHorizontal;
|
shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyRightHorizontal;
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::GameCube:
|
case Core::HID::NpadStyleIndex::GameCube:
|
||||||
shared_memory.style_tag.gamecube.Assign(1);
|
shared_memory->style_tag.gamecube.Assign(1);
|
||||||
shared_memory.device_type.fullkey.Assign(1);
|
shared_memory->device_type.fullkey.Assign(1);
|
||||||
shared_memory.system_properties.is_vertical.Assign(1);
|
shared_memory->system_properties.is_vertical.Assign(1);
|
||||||
shared_memory.system_properties.use_plus.Assign(1);
|
shared_memory->system_properties.use_plus.Assign(1);
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::Pokeball:
|
case Core::HID::NpadStyleIndex::Pokeball:
|
||||||
shared_memory.style_tag.palma.Assign(1);
|
shared_memory->style_tag.palma.Assign(1);
|
||||||
shared_memory.device_type.palma.Assign(1);
|
shared_memory->device_type.palma.Assign(1);
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::NES:
|
case Core::HID::NpadStyleIndex::NES:
|
||||||
shared_memory.style_tag.lark.Assign(1);
|
shared_memory->style_tag.lark.Assign(1);
|
||||||
shared_memory.device_type.fullkey.Assign(1);
|
shared_memory->device_type.fullkey.Assign(1);
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::SNES:
|
case Core::HID::NpadStyleIndex::SNES:
|
||||||
shared_memory.style_tag.lucia.Assign(1);
|
shared_memory->style_tag.lucia.Assign(1);
|
||||||
shared_memory.device_type.fullkey.Assign(1);
|
shared_memory->device_type.fullkey.Assign(1);
|
||||||
shared_memory.applet_footer.type = AppletFooterUiType::Lucia;
|
shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::Lucia;
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::N64:
|
case Core::HID::NpadStyleIndex::N64:
|
||||||
shared_memory.style_tag.lagoon.Assign(1);
|
shared_memory->style_tag.lagoon.Assign(1);
|
||||||
shared_memory.device_type.fullkey.Assign(1);
|
shared_memory->device_type.fullkey.Assign(1);
|
||||||
shared_memory.applet_footer.type = AppletFooterUiType::Lagon;
|
shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::Lagon;
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::SegaGenesis:
|
case Core::HID::NpadStyleIndex::SegaGenesis:
|
||||||
shared_memory.style_tag.lager.Assign(1);
|
shared_memory->style_tag.lager.Assign(1);
|
||||||
shared_memory.device_type.fullkey.Assign(1);
|
shared_memory->device_type.fullkey.Assign(1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -235,23 +239,23 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
|
||||||
|
|
||||||
const auto& body_colors = controller.device->GetColors();
|
const auto& body_colors = controller.device->GetColors();
|
||||||
|
|
||||||
shared_memory.fullkey_color.attribute = ColorAttribute::Ok;
|
shared_memory->fullkey_color.attribute = ColorAttribute::Ok;
|
||||||
shared_memory.fullkey_color.fullkey = body_colors.fullkey;
|
shared_memory->fullkey_color.fullkey = body_colors.fullkey;
|
||||||
|
|
||||||
shared_memory.joycon_color.attribute = ColorAttribute::Ok;
|
shared_memory->joycon_color.attribute = ColorAttribute::Ok;
|
||||||
shared_memory.joycon_color.left = body_colors.left;
|
shared_memory->joycon_color.left = body_colors.left;
|
||||||
shared_memory.joycon_color.right = body_colors.right;
|
shared_memory->joycon_color.right = body_colors.right;
|
||||||
|
|
||||||
// TODO: Investigate when we should report all batery types
|
// TODO: Investigate when we should report all batery types
|
||||||
const auto& battery_level = controller.device->GetBattery();
|
const auto& battery_level = controller.device->GetBattery();
|
||||||
shared_memory.battery_level_dual = battery_level.dual.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_left = battery_level.left.battery_level;
|
||||||
shared_memory.battery_level_right = battery_level.right.battery_level;
|
shared_memory->battery_level_right = battery_level.right.battery_level;
|
||||||
|
|
||||||
controller.is_connected = true;
|
controller.is_connected = true;
|
||||||
controller.device->Connect();
|
controller.device->Connect();
|
||||||
SignalStyleSetChangedEvent(npad_id);
|
SignalStyleSetChangedEvent(npad_id);
|
||||||
WriteEmptyEntry(controller.shared_memory_entry);
|
WriteEmptyEntry(controller.shared_memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::OnInit() {
|
void Controller_NPad::OnInit() {
|
||||||
|
@ -271,12 +275,12 @@ void Controller_NPad::OnInit() {
|
||||||
|
|
||||||
// Prefill controller buffers
|
// Prefill controller buffers
|
||||||
for (auto& controller : controller_data) {
|
for (auto& controller : controller_data) {
|
||||||
auto& npad = controller.shared_memory_entry;
|
auto* npad = controller.shared_memory;
|
||||||
npad.fullkey_color = {
|
npad->fullkey_color = {
|
||||||
.attribute = ColorAttribute::NoController,
|
.attribute = ColorAttribute::NoController,
|
||||||
.fullkey = {},
|
.fullkey = {},
|
||||||
};
|
};
|
||||||
npad.joycon_color = {
|
npad->joycon_color = {
|
||||||
.attribute = ColorAttribute::NoController,
|
.attribute = ColorAttribute::NoController,
|
||||||
.left = {},
|
.left = {},
|
||||||
.right = {},
|
.right = {},
|
||||||
|
@ -288,25 +292,25 @@ void Controller_NPad::OnInit() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) {
|
void Controller_NPad::WriteEmptyEntry(NpadInternalState* npad) {
|
||||||
NPadGenericState dummy_pad_state{};
|
NPadGenericState dummy_pad_state{};
|
||||||
NpadGcTriggerState dummy_gc_state{};
|
NpadGcTriggerState dummy_gc_state{};
|
||||||
dummy_pad_state.sampling_number = npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
|
dummy_pad_state.sampling_number = npad->fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
|
||||||
npad.fullkey_lifo.WriteNextEntry(dummy_pad_state);
|
npad->fullkey_lifo.WriteNextEntry(dummy_pad_state);
|
||||||
dummy_pad_state.sampling_number = npad.handheld_lifo.ReadCurrentEntry().sampling_number + 1;
|
dummy_pad_state.sampling_number = npad->handheld_lifo.ReadCurrentEntry().sampling_number + 1;
|
||||||
npad.handheld_lifo.WriteNextEntry(dummy_pad_state);
|
npad->handheld_lifo.WriteNextEntry(dummy_pad_state);
|
||||||
dummy_pad_state.sampling_number = npad.joy_dual_lifo.ReadCurrentEntry().sampling_number + 1;
|
dummy_pad_state.sampling_number = npad->joy_dual_lifo.ReadCurrentEntry().sampling_number + 1;
|
||||||
npad.joy_dual_lifo.WriteNextEntry(dummy_pad_state);
|
npad->joy_dual_lifo.WriteNextEntry(dummy_pad_state);
|
||||||
dummy_pad_state.sampling_number = npad.joy_left_lifo.ReadCurrentEntry().sampling_number + 1;
|
dummy_pad_state.sampling_number = npad->joy_left_lifo.ReadCurrentEntry().sampling_number + 1;
|
||||||
npad.joy_left_lifo.WriteNextEntry(dummy_pad_state);
|
npad->joy_left_lifo.WriteNextEntry(dummy_pad_state);
|
||||||
dummy_pad_state.sampling_number = npad.joy_right_lifo.ReadCurrentEntry().sampling_number + 1;
|
dummy_pad_state.sampling_number = npad->joy_right_lifo.ReadCurrentEntry().sampling_number + 1;
|
||||||
npad.joy_right_lifo.WriteNextEntry(dummy_pad_state);
|
npad->joy_right_lifo.WriteNextEntry(dummy_pad_state);
|
||||||
dummy_pad_state.sampling_number = npad.palma_lifo.ReadCurrentEntry().sampling_number + 1;
|
dummy_pad_state.sampling_number = npad->palma_lifo.ReadCurrentEntry().sampling_number + 1;
|
||||||
npad.palma_lifo.WriteNextEntry(dummy_pad_state);
|
npad->palma_lifo.WriteNextEntry(dummy_pad_state);
|
||||||
dummy_pad_state.sampling_number = npad.system_ext_lifo.ReadCurrentEntry().sampling_number + 1;
|
dummy_pad_state.sampling_number = npad->system_ext_lifo.ReadCurrentEntry().sampling_number + 1;
|
||||||
npad.system_ext_lifo.WriteNextEntry(dummy_pad_state);
|
npad->system_ext_lifo.WriteNextEntry(dummy_pad_state);
|
||||||
dummy_gc_state.sampling_number = npad.gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1;
|
dummy_gc_state.sampling_number = npad->gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1;
|
||||||
npad.gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
|
npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::OnRelease() {
|
void Controller_NPad::OnRelease() {
|
||||||
|
@ -372,23 +376,19 @@ void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
std::size_t data_len) {
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
||||||
auto& controller = controller_data[i];
|
auto& controller = controller_data[i];
|
||||||
auto& npad = controller.shared_memory_entry;
|
auto* npad = controller.shared_memory;
|
||||||
|
|
||||||
const auto& controller_type = controller.device->GetNpadStyleIndex();
|
const auto& controller_type = controller.device->GetNpadStyleIndex();
|
||||||
|
|
||||||
if (controller_type == Core::HID::NpadStyleIndex::None ||
|
if (controller_type == Core::HID::NpadStyleIndex::None ||
|
||||||
!controller.device->IsConnected()) {
|
!controller.device->IsConnected()) {
|
||||||
// Refresh shared memory
|
|
||||||
std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
|
|
||||||
&controller.shared_memory_entry, sizeof(NpadInternalState));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,8 +416,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
|
|
||||||
libnx_state.connection_status.is_wired.Assign(1);
|
libnx_state.connection_status.is_wired.Assign(1);
|
||||||
pad_state.sampling_number =
|
pad_state.sampling_number =
|
||||||
npad.fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||||
npad.fullkey_lifo.WriteNextEntry(pad_state);
|
npad->fullkey_lifo.WriteNextEntry(pad_state);
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::Handheld:
|
case Core::HID::NpadStyleIndex::Handheld:
|
||||||
pad_state.connection_status.raw = 0;
|
pad_state.connection_status.raw = 0;
|
||||||
|
@ -434,8 +434,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_left_wired.Assign(1);
|
||||||
libnx_state.connection_status.is_right_wired.Assign(1);
|
libnx_state.connection_status.is_right_wired.Assign(1);
|
||||||
pad_state.sampling_number =
|
pad_state.sampling_number =
|
||||||
npad.handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
npad->handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||||
npad.handheld_lifo.WriteNextEntry(pad_state);
|
npad->handheld_lifo.WriteNextEntry(pad_state);
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::JoyconDual:
|
case Core::HID::NpadStyleIndex::JoyconDual:
|
||||||
pad_state.connection_status.raw = 0;
|
pad_state.connection_status.raw = 0;
|
||||||
|
@ -450,8 +450,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
}
|
}
|
||||||
|
|
||||||
pad_state.sampling_number =
|
pad_state.sampling_number =
|
||||||
npad.joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
npad->joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||||
npad.joy_dual_lifo.WriteNextEntry(pad_state);
|
npad->joy_dual_lifo.WriteNextEntry(pad_state);
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::JoyconLeft:
|
case Core::HID::NpadStyleIndex::JoyconLeft:
|
||||||
pad_state.connection_status.raw = 0;
|
pad_state.connection_status.raw = 0;
|
||||||
|
@ -460,8 +460,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
|
|
||||||
libnx_state.connection_status.is_left_connected.Assign(1);
|
libnx_state.connection_status.is_left_connected.Assign(1);
|
||||||
pad_state.sampling_number =
|
pad_state.sampling_number =
|
||||||
npad.joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
npad->joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||||
npad.joy_left_lifo.WriteNextEntry(pad_state);
|
npad->joy_left_lifo.WriteNextEntry(pad_state);
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::JoyconRight:
|
case Core::HID::NpadStyleIndex::JoyconRight:
|
||||||
pad_state.connection_status.raw = 0;
|
pad_state.connection_status.raw = 0;
|
||||||
|
@ -470,8 +470,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
|
|
||||||
libnx_state.connection_status.is_right_connected.Assign(1);
|
libnx_state.connection_status.is_right_connected.Assign(1);
|
||||||
pad_state.sampling_number =
|
pad_state.sampling_number =
|
||||||
npad.joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
npad->joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||||
npad.joy_right_lifo.WriteNextEntry(pad_state);
|
npad->joy_right_lifo.WriteNextEntry(pad_state);
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::GameCube:
|
case Core::HID::NpadStyleIndex::GameCube:
|
||||||
pad_state.connection_status.raw = 0;
|
pad_state.connection_status.raw = 0;
|
||||||
|
@ -480,18 +480,18 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
|
|
||||||
libnx_state.connection_status.is_wired.Assign(1);
|
libnx_state.connection_status.is_wired.Assign(1);
|
||||||
pad_state.sampling_number =
|
pad_state.sampling_number =
|
||||||
npad.fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||||
trigger_state.sampling_number =
|
trigger_state.sampling_number =
|
||||||
npad.gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
npad->gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||||
npad.fullkey_lifo.WriteNextEntry(pad_state);
|
npad->fullkey_lifo.WriteNextEntry(pad_state);
|
||||||
npad.gc_trigger_lifo.WriteNextEntry(trigger_state);
|
npad->gc_trigger_lifo.WriteNextEntry(trigger_state);
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::Pokeball:
|
case Core::HID::NpadStyleIndex::Pokeball:
|
||||||
pad_state.connection_status.raw = 0;
|
pad_state.connection_status.raw = 0;
|
||||||
pad_state.connection_status.is_connected.Assign(1);
|
pad_state.connection_status.is_connected.Assign(1);
|
||||||
pad_state.sampling_number =
|
pad_state.sampling_number =
|
||||||
npad.palma_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
npad->palma_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||||
npad.palma_lifo.WriteNextEntry(pad_state);
|
npad->palma_lifo.WriteNextEntry(pad_state);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -500,17 +500,13 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw;
|
libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw;
|
||||||
libnx_state.l_stick = pad_state.l_stick;
|
libnx_state.l_stick = pad_state.l_stick;
|
||||||
libnx_state.r_stick = pad_state.r_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);
|
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,
|
void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
std::size_t data_len) {
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -525,7 +521,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& npad = controller.shared_memory_entry;
|
auto* npad = controller.shared_memory;
|
||||||
const auto& motion_state = controller.device->GetMotions();
|
const auto& motion_state = controller.device->GetMotions();
|
||||||
auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
|
auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
|
||||||
auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
|
auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
|
||||||
|
@ -611,32 +607,30 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||||
}
|
}
|
||||||
|
|
||||||
sixaxis_fullkey_state.sampling_number =
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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) {
|
if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
|
||||||
// This buffer only is updated on handheld on HW
|
// 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 {
|
} else {
|
||||||
// Handheld doesn't update this buffer on HW
|
// 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_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
|
||||||
npad.sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
|
npad->sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
|
||||||
npad.sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
|
npad->sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
|
||||||
npad.sixaxis_right_lifo.WriteNextEntry(sixaxis_right_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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,8 +708,8 @@ void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceTy
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& controller = GetControllerFromNpadIdType(npad_id);
|
auto& controller = GetControllerFromNpadIdType(npad_id);
|
||||||
if (controller.shared_memory_entry.assignment_mode != assignment_mode) {
|
if (controller.shared_memory->assignment_mode != assignment_mode) {
|
||||||
controller.shared_memory_entry.assignment_mode = assignment_mode;
|
controller.shared_memory->assignment_mode = assignment_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!controller.device->IsConnected()) {
|
if (!controller.device->IsConnected()) {
|
||||||
|
@ -982,32 +976,32 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
|
||||||
controller.vibration[device_idx].device_mounted = false;
|
controller.vibration[device_idx].device_mounted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& shared_memory_entry = controller.shared_memory_entry;
|
auto* shared_memory = controller.shared_memory;
|
||||||
// Don't reset shared_memory_entry.assignment_mode this value is persistent
|
// Don't reset shared_memory->assignment_mode this value is persistent
|
||||||
shared_memory_entry.style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out
|
shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out
|
||||||
shared_memory_entry.device_type.raw = 0;
|
shared_memory->device_type.raw = 0;
|
||||||
shared_memory_entry.system_properties.raw = 0;
|
shared_memory->system_properties.raw = 0;
|
||||||
shared_memory_entry.button_properties.raw = 0;
|
shared_memory->button_properties.raw = 0;
|
||||||
shared_memory_entry.battery_level_dual = 0;
|
shared_memory->battery_level_dual = 0;
|
||||||
shared_memory_entry.battery_level_left = 0;
|
shared_memory->battery_level_left = 0;
|
||||||
shared_memory_entry.battery_level_right = 0;
|
shared_memory->battery_level_right = 0;
|
||||||
shared_memory_entry.fullkey_color = {
|
shared_memory->fullkey_color = {
|
||||||
.attribute = ColorAttribute::NoController,
|
.attribute = ColorAttribute::NoController,
|
||||||
.fullkey = {},
|
.fullkey = {},
|
||||||
};
|
};
|
||||||
shared_memory_entry.joycon_color = {
|
shared_memory->joycon_color = {
|
||||||
.attribute = ColorAttribute::NoController,
|
.attribute = ColorAttribute::NoController,
|
||||||
.left = {},
|
.left = {},
|
||||||
.right = {},
|
.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_left_connected = true;
|
||||||
controller.is_dual_right_connected = true;
|
controller.is_dual_right_connected = true;
|
||||||
controller.is_connected = false;
|
controller.is_connected = false;
|
||||||
controller.device->Disconnect();
|
controller.device->Disconnect();
|
||||||
SignalStyleSetChangedEvent(npad_id);
|
SignalStyleSetChangedEvent(npad_id);
|
||||||
WriteEmptyEntry(controller.shared_memory_entry);
|
WriteEmptyEntry(shared_memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
|
ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace Service::HID {
|
||||||
|
|
||||||
class Controller_NPad final : public ControllerBase {
|
class Controller_NPad final : public ControllerBase {
|
||||||
public:
|
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_);
|
KernelHelpers::ServiceContext& service_context_);
|
||||||
~Controller_NPad() override;
|
~Controller_NPad() override;
|
||||||
|
|
||||||
|
@ -47,11 +47,10 @@ public:
|
||||||
void OnRelease() override;
|
void OnRelease() override;
|
||||||
|
|
||||||
// When the controller is requesting an update for the shared memory
|
// 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
|
// When the controller is requesting a motion update for the shared memory
|
||||||
void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
||||||
std::size_t size) override;
|
|
||||||
|
|
||||||
// This is nn::hid::GyroscopeZeroDriftMode
|
// This is nn::hid::GyroscopeZeroDriftMode
|
||||||
enum class GyroscopeZeroDriftMode : u32 {
|
enum class GyroscopeZeroDriftMode : u32 {
|
||||||
|
@ -410,6 +409,13 @@ private:
|
||||||
U,
|
U,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AppletNfcXcd {
|
||||||
|
union {
|
||||||
|
AppletFooterUi applet_footer{};
|
||||||
|
Lifo<NfcXcdDeviceHandleStateImpl, 0x2> nfc_xcd_device_lifo;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// This is nn::hid::detail::NpadInternalState
|
// This is nn::hid::detail::NpadInternalState
|
||||||
struct NpadInternalState {
|
struct NpadInternalState {
|
||||||
Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None};
|
Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None};
|
||||||
|
@ -436,10 +442,7 @@ private:
|
||||||
Core::HID::NpadBatteryLevel battery_level_dual{};
|
Core::HID::NpadBatteryLevel battery_level_dual{};
|
||||||
Core::HID::NpadBatteryLevel battery_level_left{};
|
Core::HID::NpadBatteryLevel battery_level_left{};
|
||||||
Core::HID::NpadBatteryLevel battery_level_right{};
|
Core::HID::NpadBatteryLevel battery_level_right{};
|
||||||
union {
|
AppletNfcXcd applet_nfc_xcd{};
|
||||||
AppletFooterUi applet_footer{};
|
|
||||||
Lifo<NfcXcdDeviceHandleStateImpl, 0x2> nfc_xcd_device_lifo;
|
|
||||||
};
|
|
||||||
INSERT_PADDING_BYTES(0x20); // Unknown
|
INSERT_PADDING_BYTES(0x20); // Unknown
|
||||||
Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo{};
|
Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo{};
|
||||||
NpadLarkType lark_type_l_and_main{};
|
NpadLarkType lark_type_l_and_main{};
|
||||||
|
@ -466,9 +469,9 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NpadControllerData {
|
struct NpadControllerData {
|
||||||
Core::HID::EmulatedController* device;
|
|
||||||
Kernel::KEvent* styleset_changed_event{};
|
Kernel::KEvent* styleset_changed_event{};
|
||||||
NpadInternalState shared_memory_entry{};
|
NpadInternalState* shared_memory = nullptr;
|
||||||
|
Core::HID::EmulatedController* device = nullptr;
|
||||||
|
|
||||||
std::array<VibrationData, 2> vibration{};
|
std::array<VibrationData, 2> vibration{};
|
||||||
bool unintended_home_button_input_protection{};
|
bool unintended_home_button_input_protection{};
|
||||||
|
@ -498,15 +501,14 @@ private:
|
||||||
SixAxisSensorState sixaxis_dual_right_state{};
|
SixAxisSensorState sixaxis_dual_right_state{};
|
||||||
SixAxisSensorState sixaxis_left_lifo_state{};
|
SixAxisSensorState sixaxis_left_lifo_state{};
|
||||||
SixAxisSensorState sixaxis_right_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 ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx);
|
||||||
void InitNewlyAddedController(Core::HID::NpadIdType npad_id);
|
void InitNewlyAddedController(Core::HID::NpadIdType npad_id);
|
||||||
bool IsControllerSupported(Core::HID::NpadStyleIndex controller) const;
|
bool IsControllerSupported(Core::HID::NpadStyleIndex controller) const;
|
||||||
void RequestPadStateUpdate(Core::HID::NpadIdType npad_id);
|
void RequestPadStateUpdate(Core::HID::NpadIdType npad_id);
|
||||||
void WriteEmptyEntry(NpadInternalState& npad);
|
void WriteEmptyEntry(NpadInternalState* npad);
|
||||||
|
|
||||||
NpadControllerData& GetControllerFromHandle(
|
NpadControllerData& GetControllerFromHandle(
|
||||||
const Core::HID::SixAxisSensorHandle& device_handle);
|
const Core::HID::SixAxisSensorHandle& device_handle);
|
||||||
|
|
|
@ -10,15 +10,18 @@
|
||||||
|
|
||||||
namespace Service::HID {
|
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;
|
Controller_Stubbed::~Controller_Stubbed() = default;
|
||||||
|
|
||||||
void Controller_Stubbed::OnInit() {}
|
void Controller_Stubbed::OnInit() {}
|
||||||
|
|
||||||
void Controller_Stubbed::OnRelease() {}
|
void Controller_Stubbed::OnRelease() {}
|
||||||
|
|
||||||
void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
std::size_t size) {
|
|
||||||
if (!smart_update) {
|
if (!smart_update) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +32,7 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
|
||||||
header.entry_count = 0;
|
header.entry_count = 0;
|
||||||
header.last_entry_index = 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) {
|
void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
class Controller_Stubbed final : public ControllerBase {
|
class Controller_Stubbed final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_);
|
explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
|
||||||
~Controller_Stubbed() override;
|
~Controller_Stubbed() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -20,19 +20,20 @@ public:
|
||||||
void OnRelease() override;
|
void OnRelease() override;
|
||||||
|
|
||||||
// When the controller is requesting an update for the shared memory
|
// 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);
|
void SetCommonHeaderOffset(std::size_t off);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct CommonHeader {
|
struct CommonHeader {
|
||||||
s64 timestamp;
|
s64 timestamp{};
|
||||||
s64 total_entry_count;
|
s64 total_entry_count{};
|
||||||
s64 last_entry_index;
|
s64 last_entry_index{};
|
||||||
s64 entry_count;
|
s64 entry_count{};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
|
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
|
||||||
|
|
||||||
|
u8* raw_shared_memory = nullptr;
|
||||||
bool smart_update{};
|
bool smart_update{};
|
||||||
std::size_t common_offset{};
|
std::size_t common_offset{};
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,8 +16,13 @@
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400;
|
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_} {
|
: 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();
|
console = hid_core.GetEmulatedConsole();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,14 +32,12 @@ void Controller_Touchscreen::OnInit() {}
|
||||||
|
|
||||||
void Controller_Touchscreen::OnRelease() {}
|
void Controller_Touchscreen::OnRelease() {}
|
||||||
|
|
||||||
void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
std::size_t size) {
|
shared_memory->touch_screen_lifo.timestamp = core_timing.GetCPUTicks();
|
||||||
touch_screen_lifo.timestamp = core_timing.GetCPUTicks();
|
|
||||||
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
touch_screen_lifo.buffer_count = 0;
|
shared_memory->touch_screen_lifo.buffer_count = 0;
|
||||||
touch_screen_lifo.buffer_tail = 0;
|
shared_memory->touch_screen_lifo.buffer_tail = 0;
|
||||||
std::memcpy(data, &touch_screen_lifo, sizeof(touch_screen_lifo));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +78,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
|
||||||
static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter));
|
static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter));
|
||||||
|
|
||||||
const u64 tick = core_timing.GetCPUTicks();
|
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.sampling_number = last_entry.sampling_number + 1;
|
||||||
next_state.entry_count = static_cast<s32>(active_fingers_count);
|
next_state.entry_count = static_cast<s32>(active_fingers_count);
|
||||||
|
@ -107,8 +110,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
touch_screen_lifo.WriteNextEntry(next_state);
|
shared_memory->touch_screen_lifo.WriteNextEntry(next_state);
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &touch_screen_lifo, sizeof(touch_screen_lifo));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -26,14 +26,14 @@ public:
|
||||||
|
|
||||||
// This is nn::hid::TouchScreenConfigurationForNx
|
// This is nn::hid::TouchScreenConfigurationForNx
|
||||||
struct TouchScreenConfigurationForNx {
|
struct TouchScreenConfigurationForNx {
|
||||||
TouchScreenModeForNx mode;
|
TouchScreenModeForNx mode{TouchScreenModeForNx::UseSystemSetting};
|
||||||
INSERT_PADDING_BYTES_NOINIT(0x7);
|
INSERT_PADDING_BYTES_NOINIT(0x7);
|
||||||
INSERT_PADDING_BYTES_NOINIT(0xF); // Reserved
|
INSERT_PADDING_BYTES_NOINIT(0xF); // Reserved
|
||||||
};
|
};
|
||||||
static_assert(sizeof(TouchScreenConfigurationForNx) == 0x17,
|
static_assert(sizeof(TouchScreenConfigurationForNx) == 0x17,
|
||||||
"TouchScreenConfigurationForNx is an invalid size");
|
"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;
|
~Controller_Touchscreen() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -43,26 +43,32 @@ public:
|
||||||
void OnRelease() override;
|
void OnRelease() override;
|
||||||
|
|
||||||
// When the controller is requesting an update for the shared memory
|
// 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:
|
private:
|
||||||
static constexpr std::size_t MAX_FINGERS = 16;
|
static constexpr std::size_t MAX_FINGERS = 16;
|
||||||
|
|
||||||
// This is nn::hid::TouchScreenState
|
// This is nn::hid::TouchScreenState
|
||||||
struct TouchScreenState {
|
struct TouchScreenState {
|
||||||
s64 sampling_number;
|
s64 sampling_number{};
|
||||||
s32 entry_count;
|
s32 entry_count{};
|
||||||
INSERT_PADDING_BYTES(4); // Reserved
|
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");
|
static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size");
|
||||||
|
|
||||||
|
struct TouchSharedMemory {
|
||||||
// This is nn::hid::detail::TouchScreenLifo
|
// This is nn::hid::detail::TouchScreenLifo
|
||||||
Lifo<TouchScreenState, hid_entry_count> touch_screen_lifo{};
|
Lifo<TouchScreenState, hid_entry_count> touch_screen_lifo{};
|
||||||
static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size");
|
static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size");
|
||||||
TouchScreenState next_state{};
|
INSERT_PADDING_WORDS(0xF2);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(TouchSharedMemory) == 0x3000, "TouchSharedMemory is an invalid size");
|
||||||
|
|
||||||
std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers;
|
TouchScreenState next_state{};
|
||||||
Core::HID::EmulatedConsole* console;
|
TouchSharedMemory* shared_memory = nullptr;
|
||||||
|
Core::HID::EmulatedConsole* console = nullptr;
|
||||||
|
|
||||||
|
std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{};
|
||||||
};
|
};
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -11,28 +11,31 @@
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00;
|
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;
|
Controller_XPad::~Controller_XPad() = default;
|
||||||
|
|
||||||
void Controller_XPad::OnInit() {}
|
void Controller_XPad::OnInit() {}
|
||||||
|
|
||||||
void Controller_XPad::OnRelease() {}
|
void Controller_XPad::OnRelease() {}
|
||||||
|
|
||||||
void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
std::size_t size) {
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
basic_xpad_lifo.buffer_count = 0;
|
shared_memory->basic_xpad_lifo.buffer_count = 0;
|
||||||
basic_xpad_lifo.buffer_tail = 0;
|
shared_memory->basic_xpad_lifo.buffer_tail = 0;
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &basic_xpad_lifo, sizeof(basic_xpad_lifo));
|
|
||||||
return;
|
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;
|
next_state.sampling_number = last_entry.sampling_number + 1;
|
||||||
// TODO(ogniK): Update xpad states
|
// TODO(ogniK): Update xpad states
|
||||||
|
|
||||||
basic_xpad_lifo.WriteNextEntry(next_state);
|
shared_memory->basic_xpad_lifo.WriteNextEntry(next_state);
|
||||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &basic_xpad_lifo, sizeof(basic_xpad_lifo));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
class Controller_XPad final : public ControllerBase {
|
class Controller_XPad final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit Controller_XPad(Core::HID::HIDCore& hid_core_);
|
explicit Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
|
||||||
~Controller_XPad() override;
|
~Controller_XPad() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -23,7 +23,7 @@ public:
|
||||||
void OnRelease() override;
|
void OnRelease() override;
|
||||||
|
|
||||||
// When the controller is requesting an update for the shared memory
|
// 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:
|
private:
|
||||||
// This is nn::hid::BasicXpadAttributeSet
|
// This is nn::hid::BasicXpadAttributeSet
|
||||||
|
@ -91,17 +91,23 @@ private:
|
||||||
|
|
||||||
// This is nn::hid::detail::BasicXpadState
|
// This is nn::hid::detail::BasicXpadState
|
||||||
struct BasicXpadState {
|
struct BasicXpadState {
|
||||||
s64 sampling_number;
|
s64 sampling_number{};
|
||||||
BasicXpadAttributeSet attributes;
|
BasicXpadAttributeSet attributes{};
|
||||||
BasicXpadButtonSet pad_states;
|
BasicXpadButtonSet pad_states{};
|
||||||
Core::HID::AnalogStickState l_stick;
|
Core::HID::AnalogStickState l_stick{};
|
||||||
Core::HID::AnalogStickState r_stick;
|
Core::HID::AnalogStickState r_stick{};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(BasicXpadState) == 0x20, "BasicXpadState is an invalid size");
|
static_assert(sizeof(BasicXpadState) == 0x20, "BasicXpadState is an invalid size");
|
||||||
|
|
||||||
|
struct XpadSharedMemory {
|
||||||
// This is nn::hid::detail::BasicXpadLifo
|
// This is nn::hid::detail::BasicXpadLifo
|
||||||
Lifo<BasicXpadState, hid_entry_count> basic_xpad_lifo{};
|
Lifo<BasicXpadState, hid_entry_count> basic_xpad_lifo{};
|
||||||
static_assert(sizeof(basic_xpad_lifo) == 0x2C8, "basic_xpad_lifo is an invalid size");
|
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{};
|
BasicXpadState next_state{};
|
||||||
|
XpadSharedMemory* shared_memory = nullptr;
|
||||||
};
|
};
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -40,7 +40,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)
|
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
|
// 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 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_,
|
IAppletResource::IAppletResource(Core::System& system_,
|
||||||
KernelHelpers::ServiceContext& service_context_)
|
KernelHelpers::ServiceContext& service_context_)
|
||||||
|
@ -49,20 +48,20 @@ IAppletResource::IAppletResource(Core::System& system_,
|
||||||
{0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
|
{0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
|
||||||
};
|
};
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer();
|
||||||
MakeController<Controller_DebugPad>(HidController::DebugPad);
|
MakeController<Controller_DebugPad>(HidController::DebugPad, shared_memory);
|
||||||
MakeController<Controller_Touchscreen>(HidController::Touchscreen);
|
MakeController<Controller_Touchscreen>(HidController::Touchscreen, shared_memory);
|
||||||
MakeController<Controller_Mouse>(HidController::Mouse);
|
MakeController<Controller_Mouse>(HidController::Mouse, shared_memory);
|
||||||
MakeController<Controller_Keyboard>(HidController::Keyboard);
|
MakeController<Controller_Keyboard>(HidController::Keyboard, shared_memory);
|
||||||
MakeController<Controller_XPad>(HidController::XPad);
|
MakeController<Controller_XPad>(HidController::XPad, shared_memory);
|
||||||
MakeController<Controller_Stubbed>(HidController::HomeButton);
|
MakeController<Controller_Stubbed>(HidController::HomeButton, shared_memory);
|
||||||
MakeController<Controller_Stubbed>(HidController::SleepButton);
|
MakeController<Controller_Stubbed>(HidController::SleepButton, shared_memory);
|
||||||
MakeController<Controller_Stubbed>(HidController::CaptureButton);
|
MakeController<Controller_Stubbed>(HidController::CaptureButton, shared_memory);
|
||||||
MakeController<Controller_Stubbed>(HidController::InputDetector);
|
MakeController<Controller_Stubbed>(HidController::InputDetector, shared_memory);
|
||||||
MakeController<Controller_Stubbed>(HidController::UniquePad);
|
MakeController<Controller_Stubbed>(HidController::UniquePad, shared_memory);
|
||||||
MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad);
|
MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad, shared_memory);
|
||||||
MakeController<Controller_Gesture>(HidController::Gesture);
|
MakeController<Controller_Gesture>(HidController::Gesture, shared_memory);
|
||||||
MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor);
|
MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor, shared_memory);
|
||||||
|
|
||||||
// Homebrew doesn't try to activate some controllers, so we activate them by default
|
// Homebrew doesn't try to activate some controllers, so we activate them by default
|
||||||
GetController<Controller_NPad>(HidController::NPad).ActivateController();
|
GetController<Controller_NPad>(HidController::NPad).ActivateController();
|
||||||
|
@ -136,8 +135,7 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
|
||||||
if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) {
|
if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(),
|
controller->OnUpdate(core_timing);
|
||||||
SHARED_MEMORY_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If ns_late is higher than the update rate ignore the delay
|
// If ns_late is higher than the update rate ignore the delay
|
||||||
|
@ -152,10 +150,8 @@ void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
|
||||||
std::chrono::nanoseconds ns_late) {
|
std::chrono::nanoseconds ns_late) {
|
||||||
auto& core_timing = system.CoreTiming();
|
auto& core_timing = system.CoreTiming();
|
||||||
|
|
||||||
controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate(
|
controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate(core_timing);
|
||||||
core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE);
|
controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(core_timing);
|
||||||
controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(
|
|
||||||
core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE);
|
|
||||||
|
|
||||||
// If ns_late is higher than the update rate ignore the delay
|
// If ns_late is higher than the update rate ignore the delay
|
||||||
if (ns_late > mouse_keyboard_update_ns) {
|
if (ns_late > mouse_keyboard_update_ns) {
|
||||||
|
@ -168,8 +164,7 @@ void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
|
||||||
void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
|
void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
|
||||||
auto& core_timing = system.CoreTiming();
|
auto& core_timing = system.CoreTiming();
|
||||||
|
|
||||||
controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate(
|
controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate(core_timing);
|
||||||
core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE);
|
|
||||||
|
|
||||||
// If ns_late is higher than the update rate ignore the delay
|
// If ns_late is higher than the update rate ignore the delay
|
||||||
if (ns_late > motion_update_ns) {
|
if (ns_late > motion_update_ns) {
|
||||||
|
|
|
@ -59,13 +59,14 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void MakeController(HidController controller) {
|
void MakeController(HidController controller, u8* shared_memory) {
|
||||||
controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>(system.HIDCore());
|
controllers[static_cast<std::size_t>(controller)] =
|
||||||
|
std::make_unique<T>(system.HIDCore(), shared_memory);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void MakeControllerWithServiceContext(HidController controller) {
|
void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) {
|
||||||
controllers[static_cast<std::size_t>(controller)] =
|
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);
|
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
|
||||||
|
|
Loading…
Reference in a new issue