Skip to content
Snippets Groups Projects
Commit 072559de authored by german77's avatar german77 Committed by Narr the Reg
Browse files

service/hid: Update debug pad, xpad, stubbed and controller base to use ring...

service/hid: Update debug pad, xpad, stubbed and controller base to use ring lifo and the emulated controller
parent dbe03011
No related branches found
No related tags found
No related merge requests found
...@@ -35,9 +35,6 @@ public: ...@@ -35,9 +35,6 @@ public:
virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
std::size_t size) {} std::size_t size) {}
// Called when input devices should be loaded
virtual void OnLoadInputDevices() = 0;
void ActivateController(); void ActivateController();
void DeactivateController(); void DeactivateController();
...@@ -47,14 +44,6 @@ public: ...@@ -47,14 +44,6 @@ public:
protected: protected:
bool is_activated{false}; bool is_activated{false};
struct CommonHeader {
s64_le timestamp;
s64_le total_entry_count;
s64_le last_entry_index;
s64_le entry_count;
};
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
Core::System& system; Core::System& system;
}; };
} // namespace Service::HID } // namespace Service::HID
...@@ -5,7 +5,10 @@ ...@@ -5,7 +5,10 @@
#include <cstring> #include <cstring>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/settings.h" #include "common/settings.h"
#include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/hid/hid_core.h"
#include "core/hid/hid_types.h"
#include "core/hle/service/hid/controllers/debug_pad.h" #include "core/hle/service/hid/controllers/debug_pad.h"
namespace Service::HID { namespace Service::HID {
...@@ -14,7 +17,10 @@ constexpr s32 HID_JOYSTICK_MAX = 0x7fff; ...@@ -14,7 +17,10 @@ constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
[[maybe_unused]] constexpr s32 HID_JOYSTICK_MIN = -0x7fff; [[maybe_unused]] constexpr s32 HID_JOYSTICK_MIN = -0x7fff;
enum class JoystickId : std::size_t { Joystick_Left, Joystick_Right }; enum class JoystickId : std::size_t { Joystick_Left, Joystick_Right };
Controller_DebugPad::Controller_DebugPad(Core::System& system_) : ControllerBase{system_} {} Controller_DebugPad::Controller_DebugPad(Core::System& system_) : ControllerBase{system_} {
controller = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Other);
}
Controller_DebugPad::~Controller_DebugPad() = default; Controller_DebugPad::~Controller_DebugPad() = default;
void Controller_DebugPad::OnInit() {} void Controller_DebugPad::OnInit() {}
...@@ -23,63 +29,29 @@ void Controller_DebugPad::OnRelease() {} ...@@ -23,63 +29,29 @@ 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, u8* data,
std::size_t size) { std::size_t size) {
shared_memory.header.timestamp = core_timing.GetCPUTicks();
shared_memory.header.total_entry_count = 17;
if (!IsControllerActivated()) { if (!IsControllerActivated()) {
shared_memory.header.entry_count = 0; debug_pad_lifo.entry_count = 0;
shared_memory.header.last_entry_index = 0; debug_pad_lifo.last_entry_index = 0;
std::memcpy(data, &debug_pad_lifo, sizeof(debug_pad_lifo));
return; return;
} }
shared_memory.header.entry_count = 16;
const auto& last_entry = shared_memory.pad_states[shared_memory.header.last_entry_index]; const auto& last_entry = debug_pad_lifo.ReadCurrentEntry().state;
shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17; next_state.sampling_number = last_entry.sampling_number + 1;
auto& cur_entry = shared_memory.pad_states[shared_memory.header.last_entry_index];
cur_entry.sampling_number = last_entry.sampling_number + 1;
cur_entry.sampling_number2 = cur_entry.sampling_number;
if (Settings::values.debug_pad_enabled) { if (Settings::values.debug_pad_enabled) {
cur_entry.attribute.connected.Assign(1); next_state.attribute.connected.Assign(1);
auto& pad = cur_entry.pad_state;
using namespace Settings::NativeButton; const auto& button_state = controller->GetDebugPadButtons();
pad.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); const auto& stick_state = controller->GetSticks();
pad.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
pad.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
pad.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
pad.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
pad.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
pad.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
pad.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
pad.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
pad.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
pad.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
pad.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
pad.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
pad.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
const auto [stick_l_x_f, stick_l_y_f] = next_state.pad_state = button_state;
analogs[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus(); next_state.l_stick = stick_state.left;
const auto [stick_r_x_f, stick_r_y_f] = next_state.r_stick = stick_state.right;
analogs[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus();
cur_entry.l_stick.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX);
cur_entry.l_stick.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
cur_entry.r_stick.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX);
cur_entry.r_stick.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX);
} }
std::memcpy(data, &shared_memory, sizeof(SharedMemory)); debug_pad_lifo.WriteNextEntry(next_state);
std::memcpy(data, &debug_pad_lifo, sizeof(debug_pad_lifo));
} }
void Controller_DebugPad::OnLoadInputDevices() {
std::transform(Settings::values.debug_pad_buttons.begin(),
Settings::values.debug_pad_buttons.begin() +
Settings::NativeButton::NUM_BUTTONS_HID,
buttons.begin(), Input::CreateDevice<Input::ButtonDevice>);
std::transform(Settings::values.debug_pad_analogs.begin(),
Settings::values.debug_pad_analogs.end(), analogs.begin(),
Input::CreateDevice<Input::AnalogDevice>);
}
} // namespace Service::HID } // namespace Service::HID
...@@ -10,8 +10,14 @@ ...@@ -10,8 +10,14 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/swap.h" #include "common/swap.h"
#include "core/frontend/input.h"
#include "core/hle/service/hid/controllers/controller_base.h" #include "core/hle/service/hid/controllers/controller_base.h"
#include "core/hle/service/hid/ring_lifo.h"
namespace Core::HID {
class EmulatedController;
struct DebugPadButton;
struct AnalogStickState;
} // namespace Core::HID
namespace Service::HID { namespace Service::HID {
class Controller_DebugPad final : public ControllerBase { class Controller_DebugPad final : public ControllerBase {
...@@ -28,66 +34,31 @@ public: ...@@ -28,66 +34,31 @@ public:
// 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, u8* data, std::size_t size) override;
// Called when input devices should be loaded
void OnLoadInputDevices() override;
private: private:
struct AnalogStick { // This is nn::hid::DebugPadAttribute
s32_le x; struct DebugPadAttribute {
s32_le y;
};
static_assert(sizeof(AnalogStick) == 0x8);
struct PadState {
union {
u32_le raw{};
BitField<0, 1, u32> a;
BitField<1, 1, u32> b;
BitField<2, 1, u32> x;
BitField<3, 1, u32> y;
BitField<4, 1, u32> l;
BitField<5, 1, u32> r;
BitField<6, 1, u32> zl;
BitField<7, 1, u32> zr;
BitField<8, 1, u32> plus;
BitField<9, 1, u32> minus;
BitField<10, 1, u32> d_left;
BitField<11, 1, u32> d_up;
BitField<12, 1, u32> d_right;
BitField<13, 1, u32> d_down;
};
};
static_assert(sizeof(PadState) == 0x4, "PadState is an invalid size");
struct Attributes {
union { union {
u32_le raw{}; u32_le raw{};
BitField<0, 1, u32> connected; BitField<0, 1, u32> connected;
}; };
}; };
static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size"); static_assert(sizeof(DebugPadAttribute) == 0x4, "DebugPadAttribute is an invalid size");
struct PadStates { // This is nn::hid::DebugPadState
struct DebugPadState {
s64_le sampling_number; s64_le sampling_number;
s64_le sampling_number2; DebugPadAttribute attribute;
Attributes attribute; Core::HID::DebugPadButton pad_state;
PadState pad_state; Core::HID::AnalogStickState r_stick;
AnalogStick r_stick; Core::HID::AnalogStickState l_stick;
AnalogStick l_stick;
}; };
static_assert(sizeof(PadStates) == 0x28, "PadStates is an invalid state"); static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state");
struct SharedMemory { // This is nn::hid::detail::DebugPadLifo
CommonHeader header; Lifo<DebugPadState> debug_pad_lifo{};
std::array<PadStates, 17> pad_states; static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size");
INSERT_PADDING_BYTES(0x138); DebugPadState next_state{};
};
static_assert(sizeof(SharedMemory) == 0x400, "SharedMemory is an invalid size");
SharedMemory shared_memory{};
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID> Core::HID::EmulatedController* controller;
buttons;
std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NumAnalogs>
analogs;
}; };
} // namespace Service::HID } // namespace Service::HID
...@@ -31,10 +31,9 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u ...@@ -31,10 +31,9 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
std::memcpy(data + common_offset, &header, sizeof(CommonHeader)); std::memcpy(data + common_offset, &header, sizeof(CommonHeader));
} }
void Controller_Stubbed::OnLoadInputDevices() {}
void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) { void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) {
common_offset = off; common_offset = off;
smart_update = true; smart_update = true;
} }
} // namespace Service::HID } // namespace Service::HID
...@@ -22,12 +22,17 @@ public: ...@@ -22,12 +22,17 @@ public:
// 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, u8* data, std::size_t size) override;
// Called when input devices should be loaded
void OnLoadInputDevices() override;
void SetCommonHeaderOffset(std::size_t off); void SetCommonHeaderOffset(std::size_t off);
private: private:
struct CommonHeader {
s64_le timestamp;
s64_le total_entry_count;
s64_le last_entry_index;
s64_le entry_count;
};
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
bool smart_update{}; bool smart_update{};
std::size_t common_offset{}; std::size_t common_offset{};
}; };
......
...@@ -19,28 +19,19 @@ void Controller_XPad::OnRelease() {} ...@@ -19,28 +19,19 @@ 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, u8* data,
std::size_t size) { std::size_t size) {
for (auto& xpad_entry : shared_memory.shared_memory_entries) { if (!IsControllerActivated()) {
xpad_entry.header.timestamp = core_timing.GetCPUTicks(); basic_xpad_lifo.entry_count = 0;
xpad_entry.header.total_entry_count = 17; basic_xpad_lifo.last_entry_index = 0;
std::memcpy(data, &basic_xpad_lifo, sizeof(basic_xpad_lifo));
if (!IsControllerActivated()) { return;
xpad_entry.header.entry_count = 0;
xpad_entry.header.last_entry_index = 0;
return;
}
xpad_entry.header.entry_count = 16;
const auto& last_entry = xpad_entry.pad_states[xpad_entry.header.last_entry_index];
xpad_entry.header.last_entry_index = (xpad_entry.header.last_entry_index + 1) % 17;
auto& cur_entry = xpad_entry.pad_states[xpad_entry.header.last_entry_index];
cur_entry.sampling_number = last_entry.sampling_number + 1;
cur_entry.sampling_number2 = cur_entry.sampling_number;
} }
const auto& last_entry = basic_xpad_lifo.ReadCurrentEntry().state;
next_state.sampling_number = last_entry.sampling_number + 1;
// TODO(ogniK): Update xpad states // TODO(ogniK): Update xpad states
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); basic_xpad_lifo.WriteNextEntry(next_state);
std::memcpy(data + SHARED_MEMORY_OFFSET, &basic_xpad_lifo, sizeof(basic_xpad_lifo));
} }
void Controller_XPad::OnLoadInputDevices() {}
} // namespace Service::HID } // namespace Service::HID
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/swap.h" #include "common/swap.h"
#include "core/hid/hid_types.h"
#include "core/hle/service/hid/controllers/controller_base.h" #include "core/hle/service/hid/controllers/controller_base.h"
#include "core/hle/service/hid/ring_lifo.h"
namespace Service::HID { namespace Service::HID {
class Controller_XPad final : public ControllerBase { class Controller_XPad final : public ControllerBase {
...@@ -25,11 +27,9 @@ public: ...@@ -25,11 +27,9 @@ public:
// 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, u8* data, std::size_t size) override;
// Called when input devices should be loaded
void OnLoadInputDevices() override;
private: private:
struct Attributes { // This is nn::hid::BasicXpadAttributeSet
struct BasicXpadAttributeSet {
union { union {
u32_le raw{}; u32_le raw{};
BitField<0, 1, u32> is_connected; BitField<0, 1, u32> is_connected;
...@@ -40,9 +40,10 @@ private: ...@@ -40,9 +40,10 @@ private:
BitField<5, 1, u32> is_right_wired; BitField<5, 1, u32> is_right_wired;
}; };
}; };
static_assert(sizeof(Attributes) == 4, "Attributes is an invalid size"); static_assert(sizeof(BasicXpadAttributeSet) == 4, "BasicXpadAttributeSet is an invalid size");
struct Buttons { // This is nn::hid::BasicXpadButtonSet
struct BasicXpadButtonSet {
union { union {
u32_le raw{}; u32_le raw{};
// Button states // Button states
...@@ -88,35 +89,21 @@ private: ...@@ -88,35 +89,21 @@ private:
BitField<30, 1, u32> handheld_left_b; BitField<30, 1, u32> handheld_left_b;
}; };
}; };
static_assert(sizeof(Buttons) == 4, "Buttons is an invalid size"); static_assert(sizeof(BasicXpadButtonSet) == 4, "BasicXpadButtonSet is an invalid size");
struct AnalogStick {
s32_le x;
s32_le y;
};
static_assert(sizeof(AnalogStick) == 0x8, "AnalogStick is an invalid size");
struct XPadState { // This is nn::hid::detail::BasicXpadState
struct BasicXpadState {
s64_le sampling_number; s64_le sampling_number;
s64_le sampling_number2; BasicXpadAttributeSet attributes;
Attributes attributes; BasicXpadButtonSet pad_states;
Buttons pad_states; Core::HID::AnalogStickState l_stick;
AnalogStick l_stick; Core::HID::AnalogStickState r_stick;
AnalogStick r_stick;
}; };
static_assert(sizeof(XPadState) == 0x28, "XPadState is an invalid size"); static_assert(sizeof(BasicXpadState) == 0x20, "BasicXpadState is an invalid size");
struct XPadEntry { // This is nn::hid::detail::BasicXpadLifo
CommonHeader header; Lifo<BasicXpadState> basic_xpad_lifo{};
std::array<XPadState, 17> pad_states{}; static_assert(sizeof(basic_xpad_lifo) == 0x2C8, "basic_xpad_lifo is an invalid size");
INSERT_PADDING_BYTES(0x138); BasicXpadState next_state{};
};
static_assert(sizeof(XPadEntry) == 0x400, "XPadEntry is an invalid size");
struct SharedMemory {
std::array<XPadEntry, 4> shared_memory_entries{};
};
static_assert(sizeof(SharedMemory) == 0x1000, "SharedMemory is an invalid size");
SharedMemory shared_memory{};
}; };
} // namespace Service::HID } // namespace Service::HID
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment