1
0
Fork 0
forked from suyu/suyu

hid: Make Hid service accessible and add GetPressState

This commit is contained in:
Zach Hilman 2018-12-24 16:19:16 -05:00
parent abbcc8e61e
commit 621b25b6be
4 changed files with 573 additions and 492 deletions

View file

@ -410,6 +410,8 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw; libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw;
libnx_entry.pad.l_stick = pad_state.l_stick; libnx_entry.pad.l_stick = pad_state.l_stick;
libnx_entry.pad.r_stick = pad_state.r_stick; libnx_entry.pad.r_stick = pad_state.r_stick;
press_state |= static_cast<u32>(pad_state.pad_states.raw);
} }
std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
shared_memory_entries.size() * sizeof(NPadEntry)); shared_memory_entries.size() * sizeof(NPadEntry));
@ -636,6 +638,12 @@ void Controller_NPad::ClearAllControllers() {
}); });
} }
u32 Controller_NPad::GetPressState() {
const auto res = press_state;
press_state = 0;
return res;
}
bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const { bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const {
const bool support_handheld = const bool support_handheld =
std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), NPAD_HANDHELD) != std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), NPAD_HANDHELD) !=

View file

@ -124,6 +124,10 @@ public:
void ConnectAllDisconnectedControllers(); void ConnectAllDisconnectedControllers();
void ClearAllControllers(); void ClearAllControllers();
// Logical OR for all buttons presses on all controllers
// Specifically for cheat engine and other features.
u32 GetPressState();
static std::size_t NPadIdToIndex(u32 npad_id); static std::size_t NPadIdToIndex(u32 npad_id);
static u32 IndexToNPad(std::size_t index); static u32 IndexToNPad(std::size_t index);
@ -292,6 +296,8 @@ private:
bool is_connected; bool is_connected;
}; };
u32 press_state{};
NPadType style{}; NPadType style{};
std::array<NPadEntry, 10> shared_memory_entries{}; std::array<NPadEntry, 10> shared_memory_entries{};
std::array< std::array<

View file

@ -40,25 +40,8 @@ constexpr u64 pad_update_ticks = CoreTiming::BASE_CLOCK_RATE / 66;
constexpr u64 accelerometer_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; constexpr u64 accelerometer_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100;
constexpr u64 gyroscope_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; constexpr u64 gyroscope_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100;
constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
enum class HidController : std::size_t {
DebugPad,
Touchscreen,
Mouse,
Keyboard,
XPad,
Unknown1,
Unknown2,
Unknown3,
SixAxisSensor,
NPad,
Gesture,
MaxControllers, IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") {
};
class IAppletResource final : public ServiceFramework<IAppletResource> {
public:
IAppletResource() : ServiceFramework("IAppletResource") {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
}; };
@ -90,49 +73,39 @@ public:
GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000); GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000);
// Register update callbacks // Register update callbacks
pad_update_event = CoreTiming::RegisterEvent( pad_update_event =
"HID::UpdatePadCallback", CoreTiming::RegisterEvent("HID::UpdatePadCallback", [this](u64 userdata, int cycles_late) {
[this](u64 userdata, int cycles_late) { UpdateControllers(userdata, cycles_late); }); UpdateControllers(userdata, cycles_late);
});
// TODO(shinyquagsire23): Other update callbacks? (accel, gyro?) // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event); CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event);
ReloadInputDevices(); ReloadInputDevices();
} }
void ActivateController(HidController controller) { void IAppletResource::ActivateController(HidController controller) {
controllers[static_cast<size_t>(controller)]->ActivateController(); controllers[static_cast<size_t>(controller)]->ActivateController();
} }
void DeactivateController(HidController controller) { void IAppletResource::DeactivateController(HidController controller) {
controllers[static_cast<size_t>(controller)]->DeactivateController(); controllers[static_cast<size_t>(controller)]->DeactivateController();
} }
template <typename T> IAppletResource ::~IAppletResource() {
void MakeController(HidController controller) {
controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>();
}
template <typename T>
T& GetController(HidController controller) {
return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
}
~IAppletResource() {
CoreTiming::UnscheduleEvent(pad_update_event, 0); CoreTiming::UnscheduleEvent(pad_update_event, 0);
} }
private: void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called"); LOG_DEBUG(Service_HID, "called");
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(shared_mem); rb.PushCopyObjects(shared_mem);
} }
void UpdateControllers(u64 userdata, int cycles_late) { void IAppletResource::UpdateControllers(u64 userdata, int cycles_late) {
const bool should_reload = Settings::values.is_device_reload_pending.exchange(false); const bool should_reload = Settings::values.is_device_reload_pending.exchange(false);
for (const auto& controller : controllers) { for (const auto& controller : controllers) {
if (should_reload) { if (should_reload) {
@ -142,17 +115,7 @@ private:
} }
CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event); CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
} }
// Handle to shared memory region designated to HID service
Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
// CoreTiming update events
CoreTiming::EventType* pad_update_event;
std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
controllers{};
};
class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
public: public:
@ -172,9 +135,11 @@ private:
} }
}; };
class Hid final : public ServiceFramework<Hid> { std::shared_ptr<IAppletResource> Hid::GetAppletResource() {
public: return applet_resource;
Hid() : ServiceFramework("hid") { }
Hid::Hid() : ServiceFramework("hid") {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &Hid::CreateAppletResource, "CreateAppletResource"}, {0, &Hid::CreateAppletResource, "CreateAppletResource"},
@ -299,13 +264,11 @@ public:
// clang-format on // clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
} }
~Hid() = default;
private: Hid::~Hid() = default;
std::shared_ptr<IAppletResource> applet_resource;
void CreateAppletResource(Kernel::HLERequestContext& ctx) { void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -318,22 +281,22 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IAppletResource>(applet_resource); rb.PushIpcInterface<IAppletResource>(applet_resource);
} }
void ActivateXpad(Kernel::HLERequestContext& ctx) { void Hid::ActivateXpad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto basic_xpad_id{rp.Pop<u32>()}; const auto basic_xpad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}", LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}", basic_xpad_id,
basic_xpad_id, applet_resource_user_id); applet_resource_user_id);
applet_resource->ActivateController(HidController::XPad); applet_resource->ActivateController(HidController::XPad);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void ActivateDebugPad(Kernel::HLERequestContext& ctx) { void Hid::ActivateDebugPad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -342,9 +305,9 @@ private:
applet_resource->ActivateController(HidController::DebugPad); applet_resource->ActivateController(HidController::DebugPad);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void ActivateTouchScreen(Kernel::HLERequestContext& ctx) { void Hid::ActivateTouchScreen(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -353,9 +316,9 @@ private:
applet_resource->ActivateController(HidController::Touchscreen); applet_resource->ActivateController(HidController::Touchscreen);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void ActivateMouse(Kernel::HLERequestContext& ctx) { void Hid::ActivateMouse(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -364,9 +327,9 @@ private:
applet_resource->ActivateController(HidController::Mouse); applet_resource->ActivateController(HidController::Mouse);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void ActivateKeyboard(Kernel::HLERequestContext& ctx) { void Hid::ActivateKeyboard(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -375,9 +338,9 @@ private:
applet_resource->ActivateController(HidController::Keyboard); applet_resource->ActivateController(HidController::Keyboard);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void ActivateGesture(Kernel::HLERequestContext& ctx) { void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto unknown{rp.Pop<u32>()}; const auto unknown{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -388,9 +351,9 @@ private:
applet_resource->ActivateController(HidController::Gesture); applet_resource->ActivateController(HidController::Gesture);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) { void Hid::ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) {
// Should have no effect with how our npad sets up the data // Should have no effect with how our npad sets up the data
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto unknown{rp.Pop<u32>()}; const auto unknown{rp.Pop<u32>()};
@ -402,9 +365,9 @@ private:
applet_resource->ActivateController(HidController::NPad); applet_resource->ActivateController(HidController::NPad);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void StartSixAxisSensor(Kernel::HLERequestContext& ctx) { void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()}; const auto handle{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -414,23 +377,23 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()}; const auto handle{rp.Pop<u32>()};
const auto drift_mode{rp.Pop<u32>()}; const auto drift_mode{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_HID, LOG_WARNING(Service_HID,
"(STUBBED) called, handle={}, drift_mode={}, applet_resource_user_id={}", "(STUBBED) called, handle={}, drift_mode={}, applet_resource_user_id={}", handle,
handle, drift_mode, applet_resource_user_id); drift_mode, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) { void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()}; const auto handle{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -442,9 +405,9 @@ private:
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
// TODO (Hexagon12): Properly implement reading gyroscope values from controllers. // TODO (Hexagon12): Properly implement reading gyroscope values from controllers.
rb.Push(true); rb.Push(true);
} }
void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { void Hid::SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto supported_styleset{rp.Pop<u32>()}; const auto supported_styleset{rp.Pop<u32>()};
@ -455,9 +418,9 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { void Hid::GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -468,9 +431,9 @@ private:
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.Push<u32>(controller.GetSupportedStyleSet().raw); rb.Push<u32>(controller.GetSupportedStyleSet().raw);
} }
void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) { void Hid::SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -480,9 +443,9 @@ private:
.SetSupportedNPadIdTypes(ctx.ReadBuffer().data(), ctx.GetReadBufferSize()); .SetSupportedNPadIdTypes(ctx.ReadBuffer().data(), ctx.GetReadBufferSize());
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void ActivateNpad(Kernel::HLERequestContext& ctx) { void Hid::ActivateNpad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -491,24 +454,24 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
applet_resource->ActivateController(HidController::NPad); applet_resource->ActivateController(HidController::NPad);
} }
void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) { void Hid::AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()}; const auto npad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
const auto unknown{rp.Pop<u64>()}; const auto unknown{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}", LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}", npad_id,
npad_id, applet_resource_user_id, unknown); applet_resource_user_id, unknown);
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(applet_resource->GetController<Controller_NPad>(HidController::NPad) rb.PushCopyObjects(applet_resource->GetController<Controller_NPad>(HidController::NPad)
.GetStyleSetChangedEvent()); .GetStyleSetChangedEvent());
} }
void DisconnectNpad(Kernel::HLERequestContext& ctx) { void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()}; const auto npad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -516,13 +479,12 @@ private:
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id, LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
applet_resource_user_id); applet_resource_user_id);
applet_resource->GetController<Controller_NPad>(HidController::NPad) applet_resource->GetController<Controller_NPad>(HidController::NPad).DisconnectNPad(npad_id);
.DisconnectNPad(npad_id);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) { void Hid::GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()}; const auto npad_id{rp.Pop<u32>()};
@ -533,9 +495,9 @@ private:
rb.PushRaw<u64>(applet_resource->GetController<Controller_NPad>(HidController::NPad) rb.PushRaw<u64>(applet_resource->GetController<Controller_NPad>(HidController::NPad)
.GetLedPattern(npad_id) .GetLedPattern(npad_id)
.raw); .raw);
} }
void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { void Hid::SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
const auto hold_type{rp.Pop<u64>()}; const auto hold_type{rp.Pop<u64>()};
@ -548,71 +510,68 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { void Hid::GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
const auto& controller = const auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
applet_resource->GetController<Controller_NPad>(HidController::NPad);
IPC::ResponseBuilder rb{ctx, 4}; IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.Push<u64>(static_cast<u64>(controller.GetHoldType())); rb.Push<u64>(static_cast<u64>(controller.GetHoldType()));
} }
void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) { void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()}; const auto npad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id,
npad_id, applet_resource_user_id); applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
applet_resource->GetController<Controller_NPad>(HidController::NPad) applet_resource->GetController<Controller_NPad>(HidController::NPad).SetVibrationEnabled(true);
.SetVibrationEnabled(true);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void EndPermitVibrationSession(Kernel::HLERequestContext& ctx) { void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called"); LOG_DEBUG(Service_HID, "called");
applet_resource->GetController<Controller_NPad>(HidController::NPad) applet_resource->GetController<Controller_NPad>(HidController::NPad).SetVibrationEnabled(false);
.SetVibrationEnabled(false);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void SendVibrationValue(Kernel::HLERequestContext& ctx) { void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto controller_id{rp.Pop<u32>()}; const auto controller_id{rp.Pop<u32>()};
const auto vibration_values{rp.PopRaw<Controller_NPad::Vibration>()}; const auto vibration_values{rp.PopRaw<Controller_NPad::Vibration>()};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id,
controller_id, applet_resource_user_id); applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
applet_resource->GetController<Controller_NPad>(HidController::NPad) applet_resource->GetController<Controller_NPad>(HidController::NPad)
.VibrateController({controller_id}, {vibration_values}); .VibrateController({controller_id}, {vibration_values});
} }
void SendVibrationValues(Kernel::HLERequestContext& ctx) { void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -635,24 +594,23 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void GetActualVibrationValue(Kernel::HLERequestContext& ctx) { void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto controller_id{rp.Pop<u32>()}; const auto controller_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id,
controller_id, applet_resource_user_id); applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 6}; IPC::ResponseBuilder rb{ctx, 6};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushRaw<Controller_NPad::Vibration>( rb.PushRaw<Controller_NPad::Vibration>(
applet_resource->GetController<Controller_NPad>(HidController::NPad) applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration());
.GetLastVibration()); }
}
void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()}; const auto npad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -665,9 +623,9 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto unknown_1{rp.Pop<u32>()}; const auto unknown_1{rp.Pop<u32>()};
const auto unknown_2{rp.Pop<u32>()}; const auto unknown_2{rp.Pop<u32>()};
@ -679,9 +637,9 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
const auto mode{rp.Pop<u64>()}; const auto mode{rp.Pop<u64>()};
@ -691,26 +649,26 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called"); LOG_DEBUG(Service_HID, "called");
IPC::ResponseBuilder rb{ctx, 4}; IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.Push<u32>(1); rb.Push<u32>(1);
rb.Push<u32>(0); rb.Push<u32>(0);
} }
void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) { void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called"); LOG_DEBUG(Service_HID, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IActiveVibrationDeviceList>(); rb.PushIpcInterface<IActiveVibrationDeviceList>();
} }
void ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -719,9 +677,9 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { void Hid::StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()}; const auto handle{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
@ -731,9 +689,9 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void StopSixAxisSensor(Kernel::HLERequestContext& ctx) { void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()}; const auto handle{rp.Pop<u32>()};
@ -741,9 +699,9 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx) { void Hid::SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
const auto unknown{rp.Pop<u32>()}; const auto unknown{rp.Pop<u32>()};
@ -753,9 +711,9 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx) { void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto unknown{rp.Pop<u32>()}; const auto unknown{rp.Pop<u32>()};
@ -763,8 +721,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
};
class HidDbg final : public ServiceFramework<HidDbg> { class HidDbg final : public ServiceFramework<HidDbg> {
public: public:

View file

@ -3,6 +3,15 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#pragma once #pragma once
#include "core/hle/service/service.h"
namespace CoreTiming {
struct EventType;
}
namespace Kernel {
class SharedMemory;
}
namespace SM { namespace SM {
class ServiceManager; class ServiceManager;
@ -10,6 +19,107 @@ class ServiceManager;
namespace Service::HID { namespace Service::HID {
class ControllerBase;
enum class HidController : std::size_t {
DebugPad,
Touchscreen,
Mouse,
Keyboard,
XPad,
Unknown1,
Unknown2,
Unknown3,
SixAxisSensor,
NPad,
Gesture,
MaxControllers,
};
class IAppletResource final : public ServiceFramework<IAppletResource> {
public:
IAppletResource();
~IAppletResource() override;
void ActivateController(HidController controller);
void DeactivateController(HidController controller);
template <typename T>
T& GetController(HidController controller) {
return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
}
template <typename T>
const T& GetController(HidController controller) const {
return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
}
private:
template <typename T>
void MakeController(HidController controller) {
controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>();
}
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
void UpdateControllers(u64 userdata, int cycles_late);
Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
CoreTiming::EventType* pad_update_event;
std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
controllers{};
};
class Hid final : public ServiceFramework<Hid> {
public:
Hid();
~Hid() override;
std::shared_ptr<IAppletResource> GetAppletResource();
private:
void CreateAppletResource(Kernel::HLERequestContext& ctx);
void ActivateXpad(Kernel::HLERequestContext& ctx);
void ActivateDebugPad(Kernel::HLERequestContext& ctx);
void ActivateTouchScreen(Kernel::HLERequestContext& ctx);
void ActivateMouse(Kernel::HLERequestContext& ctx);
void ActivateKeyboard(Kernel::HLERequestContext& ctx);
void ActivateGesture(Kernel::HLERequestContext& ctx);
void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx);
void StartSixAxisSensor(Kernel::HLERequestContext& ctx);
void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx);
void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx);
void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx);
void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx);
void ActivateNpad(Kernel::HLERequestContext& ctx);
void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx);
void DisconnectNpad(Kernel::HLERequestContext& ctx);
void GetPlayerLedPattern(Kernel::HLERequestContext& ctx);
void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx);
void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx);
void EndPermitVibrationSession(Kernel::HLERequestContext& ctx);
void SendVibrationValue(Kernel::HLERequestContext& ctx);
void SendVibrationValues(Kernel::HLERequestContext& ctx);
void GetActualVibrationValue(Kernel::HLERequestContext& ctx);
void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx);
void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx);
void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx);
void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx);
void ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx);
void StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx);
void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
std::shared_ptr<IAppletResource> applet_resource;
};
/// Reload input devices. Used when input configuration changed /// Reload input devices. Used when input configuration changed
void ReloadInputDevices(); void ReloadInputDevices();