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.l_stick = pad_state.l_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(),
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 {
const bool support_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 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 u32 IndexToNPad(std::size_t index);
@ -292,6 +296,8 @@ private:
bool is_connected;
};
u32 press_state{};
NPadType style{};
std::array<NPadEntry, 10> shared_memory_entries{};
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 gyroscope_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100;
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,
};
class IAppletResource final : public ServiceFramework<IAppletResource> {
public:
IAppletResource() : ServiceFramework("IAppletResource") {
IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") {
static const FunctionInfo functions[] = {
{0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
};
@ -90,9 +73,10 @@ public:
GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000);
// Register update callbacks
pad_update_event = CoreTiming::RegisterEvent(
"HID::UpdatePadCallback",
[this](u64 userdata, int cycles_late) { UpdateControllers(userdata, cycles_late); });
pad_update_event =
CoreTiming::RegisterEvent("HID::UpdatePadCallback", [this](u64 userdata, int cycles_late) {
UpdateControllers(userdata, cycles_late);
});
// TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
@ -101,30 +85,19 @@ public:
ReloadInputDevices();
}
void ActivateController(HidController controller) {
void IAppletResource::ActivateController(HidController controller) {
controllers[static_cast<size_t>(controller)]->ActivateController();
}
void DeactivateController(HidController controller) {
void IAppletResource::DeactivateController(HidController controller) {
controllers[static_cast<size_t>(controller)]->DeactivateController();
}
template <typename T>
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() {
IAppletResource ::~IAppletResource() {
CoreTiming::UnscheduleEvent(pad_update_event, 0);
}
private:
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
@ -132,7 +105,7 @@ private:
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);
for (const auto& controller : controllers) {
if (should_reload) {
@ -144,16 +117,6 @@ private:
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> {
public:
IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") {
@ -172,9 +135,11 @@ private:
}
};
class Hid final : public ServiceFramework<Hid> {
public:
Hid() : ServiceFramework("hid") {
std::shared_ptr<IAppletResource> Hid::GetAppletResource() {
return applet_resource;
}
Hid::Hid() : ServiceFramework("hid") {
// clang-format off
static const FunctionInfo functions[] = {
{0, &Hid::CreateAppletResource, "CreateAppletResource"},
@ -300,12 +265,10 @@ public:
RegisterHandlers(functions);
}
~Hid() = default;
private:
std::shared_ptr<IAppletResource> applet_resource;
Hid::~Hid() = default;
void CreateAppletResource(Kernel::HLERequestContext& ctx) {
void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -320,20 +283,20 @@ private:
rb.PushIpcInterface<IAppletResource>(applet_resource);
}
void ActivateXpad(Kernel::HLERequestContext& ctx) {
void Hid::ActivateXpad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto basic_xpad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}",
basic_xpad_id, applet_resource_user_id);
LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}", basic_xpad_id,
applet_resource_user_id);
applet_resource->ActivateController(HidController::XPad);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void ActivateDebugPad(Kernel::HLERequestContext& ctx) {
void Hid::ActivateDebugPad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -344,7 +307,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void ActivateTouchScreen(Kernel::HLERequestContext& ctx) {
void Hid::ActivateTouchScreen(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -355,7 +318,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void ActivateMouse(Kernel::HLERequestContext& ctx) {
void Hid::ActivateMouse(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -366,7 +329,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void ActivateKeyboard(Kernel::HLERequestContext& ctx) {
void Hid::ActivateKeyboard(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -377,7 +340,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void ActivateGesture(Kernel::HLERequestContext& ctx) {
void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto unknown{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -390,7 +353,7 @@ private:
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
IPC::RequestParser rp{ctx};
const auto unknown{rp.Pop<u32>()};
@ -404,7 +367,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -416,21 +379,21 @@ private:
rb.Push(RESULT_SUCCESS);
}
void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()};
const auto drift_mode{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_HID,
"(STUBBED) called, handle={}, drift_mode={}, applet_resource_user_id={}",
handle, drift_mode, applet_resource_user_id);
"(STUBBED) called, handle={}, drift_mode={}, applet_resource_user_id={}", handle,
drift_mode, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -444,7 +407,7 @@ private:
rb.Push(true);
}
void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
void Hid::SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto supported_styleset{rp.Pop<u32>()};
@ -457,7 +420,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
void Hid::GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -470,7 +433,7 @@ private:
rb.Push<u32>(controller.GetSupportedStyleSet().raw);
}
void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
void Hid::SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -482,7 +445,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void ActivateNpad(Kernel::HLERequestContext& ctx) {
void Hid::ActivateNpad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -493,14 +456,14 @@ private:
applet_resource->ActivateController(HidController::NPad);
}
void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) {
void Hid::AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto unknown{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}",
npad_id, applet_resource_user_id, unknown);
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}", npad_id,
applet_resource_user_id, unknown);
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
@ -508,7 +471,7 @@ private:
.GetStyleSetChangedEvent());
}
void DisconnectNpad(Kernel::HLERequestContext& ctx) {
void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()};
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,
applet_resource_user_id);
applet_resource->GetController<Controller_NPad>(HidController::NPad)
.DisconnectNPad(npad_id);
applet_resource->GetController<Controller_NPad>(HidController::NPad).DisconnectNPad(npad_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
void Hid::GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()};
@ -535,7 +497,7 @@ private:
.raw);
}
void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
void Hid::SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto hold_type{rp.Pop<u64>()};
@ -550,60 +512,57 @@ private:
rb.Push(RESULT_SUCCESS);
}
void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
void Hid::GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
const auto& controller =
applet_resource->GetController<Controller_NPad>(HidController::NPad);
const auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(static_cast<u64>(controller.GetHoldType()));
}
void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) {
void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
npad_id, applet_resource_user_id);
LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id,
applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
applet_resource->GetController<Controller_NPad>(HidController::NPad)
.SetVibrationEnabled(true);
applet_resource->GetController<Controller_NPad>(HidController::NPad).SetVibrationEnabled(true);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called");
applet_resource->GetController<Controller_NPad>(HidController::NPad)
.SetVibrationEnabled(false);
applet_resource->GetController<Controller_NPad>(HidController::NPad).SetVibrationEnabled(false);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void SendVibrationValue(Kernel::HLERequestContext& ctx) {
void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto controller_id{rp.Pop<u32>()};
const auto vibration_values{rp.PopRaw<Controller_NPad::Vibration>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}",
controller_id, applet_resource_user_id);
LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id,
applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@ -612,7 +571,7 @@ private:
.VibrateController({controller_id}, {vibration_values});
}
void SendVibrationValues(Kernel::HLERequestContext& ctx) {
void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -637,22 +596,21 @@ private:
rb.Push(RESULT_SUCCESS);
}
void GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto controller_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}",
controller_id, applet_resource_user_id);
LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id,
applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(RESULT_SUCCESS);
rb.PushRaw<Controller_NPad::Vibration>(
applet_resource->GetController<Controller_NPad>(HidController::NPad)
.GetLastVibration());
applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration());
}
void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -667,7 +625,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto unknown_1{rp.Pop<u32>()};
const auto unknown_2{rp.Pop<u32>()};
@ -681,7 +639,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto mode{rp.Pop<u64>()};
@ -693,7 +651,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called");
IPC::ResponseBuilder rb{ctx, 4};
@ -702,7 +660,7 @@ private:
rb.Push<u32>(0);
}
void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@ -710,7 +668,7 @@ private:
rb.PushIpcInterface<IActiveVibrationDeviceList>();
}
void ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -721,7 +679,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
void Hid::StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
@ -733,7 +691,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()};
@ -743,7 +701,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx) {
void Hid::SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto unknown{rp.Pop<u32>()};
@ -755,7 +713,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto unknown{rp.Pop<u32>()};
@ -764,7 +722,6 @@ private:
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
};
class HidDbg final : public ServiceFramework<HidDbg> {
public:

View file

@ -3,6 +3,15 @@
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace CoreTiming {
struct EventType;
}
namespace Kernel {
class SharedMemory;
}
namespace SM {
class ServiceManager;
@ -10,6 +19,107 @@ class ServiceManager;
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
void ReloadInputDevices();