Merge pull request #3304 from wwylele/hid-new-framework

HID: convert to ServiceFramework
This commit is contained in:
Weiyi Wang 2018-01-04 11:04:57 +02:00 committed by GitHub
commit a66e4585a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 260 additions and 258 deletions

View File

@ -3,15 +3,12 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <algorithm> #include <algorithm>
#include <atomic>
#include <cmath> #include <cmath>
#include <memory>
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/3ds.h" #include "core/3ds.h"
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/frontend/input.h" #include "core/hle/ipc_helpers.h"
#include "core/hle/ipc.h"
#include "core/hle/kernel/event.h" #include "core/hle/kernel/event.h"
#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/shared_memory.h" #include "core/hle/kernel/shared_memory.h"
@ -23,27 +20,7 @@
namespace Service { namespace Service {
namespace HID { namespace HID {
// Handle to shared memory region designated to HID_User service static std::weak_ptr<Module> current_module;
static Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
// Event handles
static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_1;
static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_2;
static Kernel::SharedPtr<Kernel::Event> event_accelerometer;
static Kernel::SharedPtr<Kernel::Event> event_gyroscope;
static Kernel::SharedPtr<Kernel::Event> event_debug_pad;
static u32 next_pad_index;
static u32 next_touch_index;
static u32 next_accelerometer_index;
static u32 next_gyroscope_index;
static int enable_accelerometer_count; // positive means enabled
static int enable_gyroscope_count; // positive means enabled
static CoreTiming::EventType* pad_update_event;
static CoreTiming::EventType* accelerometer_update_event;
static CoreTiming::EventType* gyroscope_update_event;
// Updating period for each HID device. These empirical values are measured from a 11.2 3DS. // Updating period for each HID device. These empirical values are measured from a 11.2 3DS.
constexpr u64 pad_update_ticks = BASE_CLOCK_RATE_ARM11 / 234; constexpr u64 pad_update_ticks = BASE_CLOCK_RATE_ARM11 / 234;
@ -53,13 +30,6 @@ constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE_ARM11 / 101;
constexpr float accelerometer_coef = 512.0f; // measured from hw test result constexpr float accelerometer_coef = 512.0f; // measured from hw test result
constexpr float gyroscope_coef = 14.375f; // got from hwtest GetGyroscopeLowRawToDpsCoefficient call constexpr float gyroscope_coef = 14.375f; // got from hwtest GetGyroscopeLowRawToDpsCoefficient call
static std::atomic<bool> is_device_reload_pending;
static std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>
buttons;
static std::unique_ptr<Input::AnalogDevice> circle_pad;
static std::unique_ptr<Input::MotionDevice> motion_device;
static std::unique_ptr<Input::TouchDevice> touch_device;
DirectionState GetStickDirectionState(s16 circle_pad_x, s16 circle_pad_y) { DirectionState GetStickDirectionState(s16 circle_pad_x, s16 circle_pad_y) {
// 30 degree and 60 degree are angular thresholds for directions // 30 degree and 60 degree are angular thresholds for directions
constexpr float TAN30 = 0.577350269f; constexpr float TAN30 = 0.577350269f;
@ -89,7 +59,7 @@ DirectionState GetStickDirectionState(s16 circle_pad_x, s16 circle_pad_y) {
return state; return state;
} }
static void LoadInputDevices() { void Module::LoadInputDevices() {
std::transform(Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN, std::transform(Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN,
Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_END, Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_END,
buttons.begin(), Input::CreateDevice<Input::ButtonDevice>); buttons.begin(), Input::CreateDevice<Input::ButtonDevice>);
@ -99,16 +69,7 @@ static void LoadInputDevices() {
touch_device = Input::CreateDevice<Input::TouchDevice>(Settings::values.touch_device); touch_device = Input::CreateDevice<Input::TouchDevice>(Settings::values.touch_device);
} }
static void UnloadInputDevices() { void Module::UpdatePadCallback(u64 userdata, int cycles_late) {
for (auto& button : buttons) {
button.reset();
}
circle_pad.reset();
motion_device.reset();
touch_device.reset();
}
static void UpdatePadCallback(u64 userdata, int cycles_late) {
SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer());
if (is_device_reload_pending.exchange(false)) if (is_device_reload_pending.exchange(false))
@ -198,7 +159,7 @@ static void UpdatePadCallback(u64 userdata, int cycles_late) {
CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event); CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
} }
static void UpdateAccelerometerCallback(u64 userdata, int cycles_late) { void Module::UpdateAccelerometerCallback(u64 userdata, int cycles_late) {
SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer());
mem->accelerometer.index = next_accelerometer_index; mem->accelerometer.index = next_accelerometer_index;
@ -240,7 +201,7 @@ static void UpdateAccelerometerCallback(u64 userdata, int cycles_late) {
CoreTiming::ScheduleEvent(accelerometer_update_ticks - cycles_late, accelerometer_update_event); CoreTiming::ScheduleEvent(accelerometer_update_ticks - cycles_late, accelerometer_update_event);
} }
static void UpdateGyroscopeCallback(u64 userdata, int cycles_late) { void Module::UpdateGyroscopeCallback(u64 userdata, int cycles_late) {
SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer());
mem->gyroscope.index = next_gyroscope_index; mem->gyroscope.index = next_gyroscope_index;
@ -273,134 +234,122 @@ static void UpdateGyroscopeCallback(u64 userdata, int cycles_late) {
CoreTiming::ScheduleEvent(gyroscope_update_ticks - cycles_late, gyroscope_update_event); CoreTiming::ScheduleEvent(gyroscope_update_ticks - cycles_late, gyroscope_update_event);
} }
void GetIPCHandles(Service::Interface* self) { void Module::Interface::GetIPCHandles(Kernel::HLERequestContext& ctx) {
u32* cmd_buff = Kernel::GetCommandBuffer(); IPC::RequestParser rp{ctx, 0xA, 0, 0};
IPC::RequestBuilder rb = rp.MakeBuilder(1, 7);
cmd_buff[1] = 0; // No error rb.Push(RESULT_SUCCESS);
cmd_buff[2] = 0x14000000; // IPC Command Structure translate-header rb.PushCopyObjects(hid->shared_mem, hid->event_pad_or_touch_1, hid->event_pad_or_touch_2,
// TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling) hid->event_accelerometer, hid->event_gyroscope, hid->event_debug_pad);
cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::shared_mem).Unwrap();
cmd_buff[4] = Kernel::g_handle_table.Create(Service::HID::event_pad_or_touch_1).Unwrap();
cmd_buff[5] = Kernel::g_handle_table.Create(Service::HID::event_pad_or_touch_2).Unwrap();
cmd_buff[6] = Kernel::g_handle_table.Create(Service::HID::event_accelerometer).Unwrap();
cmd_buff[7] = Kernel::g_handle_table.Create(Service::HID::event_gyroscope).Unwrap();
cmd_buff[8] = Kernel::g_handle_table.Create(Service::HID::event_debug_pad).Unwrap();
} }
void EnableAccelerometer(Service::Interface* self) { void Module::Interface::EnableAccelerometer(Kernel::HLERequestContext& ctx) {
u32* cmd_buff = Kernel::GetCommandBuffer(); IPC::RequestParser rp{ctx, 0x11, 0, 0};
++enable_accelerometer_count; ++hid->enable_accelerometer_count;
// Schedules the accelerometer update event if the accelerometer was just enabled // Schedules the accelerometer update event if the accelerometer was just enabled
if (enable_accelerometer_count == 1) { if (hid->enable_accelerometer_count == 1) {
CoreTiming::ScheduleEvent(accelerometer_update_ticks, accelerometer_update_event); CoreTiming::ScheduleEvent(accelerometer_update_ticks, hid->accelerometer_update_event);
} }
cmd_buff[1] = RESULT_SUCCESS.raw; IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_DEBUG(Service_HID, "called"); LOG_DEBUG(Service_HID, "called");
} }
void DisableAccelerometer(Service::Interface* self) { void Module::Interface::DisableAccelerometer(Kernel::HLERequestContext& ctx) {
u32* cmd_buff = Kernel::GetCommandBuffer(); IPC::RequestParser rp{ctx, 0x12, 0, 0};
--enable_accelerometer_count; --hid->enable_accelerometer_count;
// Unschedules the accelerometer update event if the accelerometer was just disabled // Unschedules the accelerometer update event if the accelerometer was just disabled
if (enable_accelerometer_count == 0) { if (hid->enable_accelerometer_count == 0) {
CoreTiming::UnscheduleEvent(accelerometer_update_event, 0); CoreTiming::UnscheduleEvent(hid->accelerometer_update_event, 0);
} }
cmd_buff[1] = RESULT_SUCCESS.raw; IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_DEBUG(Service_HID, "called"); LOG_DEBUG(Service_HID, "called");
} }
void EnableGyroscopeLow(Service::Interface* self) { void Module::Interface::EnableGyroscopeLow(Kernel::HLERequestContext& ctx) {
u32* cmd_buff = Kernel::GetCommandBuffer(); IPC::RequestParser rp{ctx, 0x13, 0, 0};
++enable_gyroscope_count; ++hid->enable_gyroscope_count;
// Schedules the gyroscope update event if the gyroscope was just enabled // Schedules the gyroscope update event if the gyroscope was just enabled
if (enable_gyroscope_count == 1) { if (hid->enable_gyroscope_count == 1) {
CoreTiming::ScheduleEvent(gyroscope_update_ticks, gyroscope_update_event); CoreTiming::ScheduleEvent(gyroscope_update_ticks, hid->gyroscope_update_event);
} }
cmd_buff[1] = RESULT_SUCCESS.raw; IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_DEBUG(Service_HID, "called"); LOG_DEBUG(Service_HID, "called");
} }
void DisableGyroscopeLow(Service::Interface* self) { void Module::Interface::DisableGyroscopeLow(Kernel::HLERequestContext& ctx) {
u32* cmd_buff = Kernel::GetCommandBuffer(); IPC::RequestParser rp{ctx, 0x14, 0, 0};
--enable_gyroscope_count; --hid->enable_gyroscope_count;
// Unschedules the gyroscope update event if the gyroscope was just disabled // Unschedules the gyroscope update event if the gyroscope was just disabled
if (enable_gyroscope_count == 0) { if (hid->enable_gyroscope_count == 0) {
CoreTiming::UnscheduleEvent(gyroscope_update_event, 0); CoreTiming::UnscheduleEvent(hid->gyroscope_update_event, 0);
} }
cmd_buff[1] = RESULT_SUCCESS.raw; IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_DEBUG(Service_HID, "called"); LOG_DEBUG(Service_HID, "called");
} }
void GetGyroscopeLowRawToDpsCoefficient(Service::Interface* self) { void Module::Interface::GetGyroscopeLowRawToDpsCoefficient(Kernel::HLERequestContext& ctx) {
u32* cmd_buff = Kernel::GetCommandBuffer(); IPC::RequestParser rp{ctx, 0x15, 0, 0};
cmd_buff[1] = RESULT_SUCCESS.raw; IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
rb.Push(RESULT_SUCCESS);
f32 coef = gyroscope_coef; rb.PushRaw<f32>(gyroscope_coef);
memcpy(&cmd_buff[2], &coef, 4);
} }
void GetGyroscopeLowCalibrateParam(Service::Interface* self) { void Module::Interface::GetGyroscopeLowCalibrateParam(Kernel::HLERequestContext& ctx) {
u32* cmd_buff = Kernel::GetCommandBuffer(); IPC::RequestParser rp{ctx, 0x16, 0, 0};
cmd_buff[1] = RESULT_SUCCESS.raw; IPC::RequestBuilder rb = rp.MakeBuilder(6, 0);
rb.Push(RESULT_SUCCESS);
const s16 param_unit = 6700; // an approximate value taken from hw const s16 param_unit = 6700; // an approximate value taken from hw
GyroscopeCalibrateParam param = { GyroscopeCalibrateParam param = {
{0, param_unit, -param_unit}, {0, param_unit, -param_unit}, {0, param_unit, -param_unit}, {0, param_unit, -param_unit}, {0, param_unit, -param_unit}, {0, param_unit, -param_unit},
}; };
memcpy(&cmd_buff[2], &param, sizeof(param)); rb.PushRaw(param);
LOG_WARNING(Service_HID, "(STUBBED) called"); LOG_WARNING(Service_HID, "(STUBBED) called");
} }
void GetSoundVolume(Service::Interface* self) { void Module::Interface::GetSoundVolume(Kernel::HLERequestContext& ctx) {
u32* cmd_buff = Kernel::GetCommandBuffer(); IPC::RequestParser rp{ctx, 0x17, 0, 0};
const u8 volume = 0x3F; // TODO(purpasmart): Find out if this is the max value for the volume const u8 volume = 0x3F; // TODO(purpasmart): Find out if this is the max value for the volume
cmd_buff[1] = RESULT_SUCCESS.raw; IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
cmd_buff[2] = volume; rb.Push(RESULT_SUCCESS);
rb.Push(volume);
LOG_WARNING(Service_HID, "(STUBBED) called"); LOG_WARNING(Service_HID, "(STUBBED) called");
} }
void Init() { Module::Interface::Interface(std::shared_ptr<Module> hid, const char* name, u32 max_session)
: ServiceFramework(name, max_session), hid(std::move(hid)) {}
Module::Module() {
using namespace Kernel; using namespace Kernel;
AddService(new HID_U_Interface);
AddService(new HID_SPVR_Interface);
is_device_reload_pending.store(true);
using Kernel::MemoryPermission;
shared_mem = shared_mem =
SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::Read, SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::Read,
0, Kernel::MemoryRegion::BASE, "HID:SharedMemory"); 0, MemoryRegion::BASE, "HID:SharedMemory");
next_pad_index = 0;
next_touch_index = 0;
next_accelerometer_index = 0;
next_gyroscope_index = 0;
enable_accelerometer_count = 0;
enable_gyroscope_count = 0;
// Create event handles // Create event handles
event_pad_or_touch_1 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch1"); event_pad_or_touch_1 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch1");
@ -410,27 +359,35 @@ void Init() {
event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad"); event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad");
// Register update callbacks // Register update callbacks
pad_update_event = CoreTiming::RegisterEvent("HID::UpdatePadCallback", UpdatePadCallback); pad_update_event =
accelerometer_update_event = CoreTiming::RegisterEvent("HID::UpdatePadCallback", [this](u64 userdata, int cycles_late) {
CoreTiming::RegisterEvent("HID::UpdateAccelerometerCallback", UpdateAccelerometerCallback); UpdatePadCallback(userdata, cycles_late);
gyroscope_update_event = });
CoreTiming::RegisterEvent("HID::UpdateGyroscopeCallback", UpdateGyroscopeCallback); accelerometer_update_event = CoreTiming::RegisterEvent(
"HID::UpdateAccelerometerCallback", [this](u64 userdata, int cycles_late) {
UpdateAccelerometerCallback(userdata, cycles_late);
});
gyroscope_update_event = CoreTiming::RegisterEvent(
"HID::UpdateGyroscopeCallback",
[this](u64 userdata, int cycles_late) { UpdateGyroscopeCallback(userdata, cycles_late); });
CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event); CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event);
} }
void Shutdown() { void Module::ReloadInputDevices() {
shared_mem = nullptr; is_device_reload_pending.store(true);
event_pad_or_touch_1 = nullptr;
event_pad_or_touch_2 = nullptr;
event_accelerometer = nullptr;
event_gyroscope = nullptr;
event_debug_pad = nullptr;
UnloadInputDevices();
} }
void ReloadInputDevices() { void ReloadInputDevices() {
is_device_reload_pending.store(true); if (auto hid = current_module.lock())
hid->ReloadInputDevices();
}
void InstallInterfaces(SM::ServiceManager& service_manager) {
auto hid = std::make_shared<Module>();
std::make_shared<User>(hid)->InstallAsService(service_manager);
std::make_shared<Spvr>(hid)->InstallAsService(service_manager);
current_module = hid;
} }
} // namespace HID } // namespace HID

View File

@ -5,17 +5,29 @@
#pragma once #pragma once
#include <array> #include <array>
#include <atomic>
#ifndef _MSC_VER #ifndef _MSC_VER
#include <cstddef> #include <cstddef>
#endif #endif
#include <memory>
#include "common/bit_field.h" #include "common/bit_field.h"
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "core/frontend/input.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/service.h"
#include "core/settings.h" #include "core/settings.h"
namespace Service { namespace Kernel {
class Event;
class SharedMemory;
}
class Interface; namespace CoreTiming {
class EventType;
};
namespace Service {
namespace HID { namespace HID {
@ -186,7 +198,16 @@ struct DirectionState {
/// Translates analog stick axes to directions. This is exposed for ir_rst module to use. /// Translates analog stick axes to directions. This is exposed for ir_rst module to use.
DirectionState GetStickDirectionState(s16 circle_pad_x, s16 circle_pad_y); DirectionState GetStickDirectionState(s16 circle_pad_x, s16 circle_pad_y);
/** class Module final {
public:
Module();
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> hid, const char* name, u32 max_session);
protected:
/**
* HID::GetIPCHandles service function * HID::GetIPCHandles service function
* Inputs: * Inputs:
* None * None
@ -200,45 +221,45 @@ DirectionState GetStickDirectionState(s16 circle_pad_x, s16 circle_pad_y);
* 7 : Gyroscope event * 7 : Gyroscope event
* 8 : Event signaled by HID * 8 : Event signaled by HID
*/ */
void GetIPCHandles(Interface* self); void GetIPCHandles(Kernel::HLERequestContext& ctx);
/** /**
* HID::EnableAccelerometer service function * HID::EnableAccelerometer service function
* Inputs: * Inputs:
* None * None
* Outputs: * Outputs:
* 1 : Result of function, 0 on success, otherwise error code * 1 : Result of function, 0 on success, otherwise error code
*/ */
void EnableAccelerometer(Interface* self); void EnableAccelerometer(Kernel::HLERequestContext& ctx);
/** /**
* HID::DisableAccelerometer service function * HID::DisableAccelerometer service function
* Inputs: * Inputs:
* None * None
* Outputs: * Outputs:
* 1 : Result of function, 0 on success, otherwise error code * 1 : Result of function, 0 on success, otherwise error code
*/ */
void DisableAccelerometer(Interface* self); void DisableAccelerometer(Kernel::HLERequestContext& ctx);
/** /**
* HID::EnableGyroscopeLow service function * HID::EnableGyroscopeLow service function
* Inputs: * Inputs:
* None * None
* Outputs: * Outputs:
* 1 : Result of function, 0 on success, otherwise error code * 1 : Result of function, 0 on success, otherwise error code
*/ */
void EnableGyroscopeLow(Interface* self); void EnableGyroscopeLow(Kernel::HLERequestContext& ctx);
/** /**
* HID::DisableGyroscopeLow service function * HID::DisableGyroscopeLow service function
* Inputs: * Inputs:
* None * None
* Outputs: * Outputs:
* 1 : Result of function, 0 on success, otherwise error code * 1 : Result of function, 0 on success, otherwise error code
*/ */
void DisableGyroscopeLow(Interface* self); void DisableGyroscopeLow(Kernel::HLERequestContext& ctx);
/** /**
* HID::GetSoundVolume service function * HID::GetSoundVolume service function
* Inputs: * Inputs:
* None * None
@ -246,9 +267,9 @@ void DisableGyroscopeLow(Interface* self);
* 1 : Result of function, 0 on success, otherwise error code * 1 : Result of function, 0 on success, otherwise error code
* 2 : u8 output value * 2 : u8 output value
*/ */
void GetSoundVolume(Interface* self); void GetSoundVolume(Kernel::HLERequestContext& ctx);
/** /**
* HID::GetGyroscopeLowRawToDpsCoefficient service function * HID::GetGyroscopeLowRawToDpsCoefficient service function
* Inputs: * Inputs:
* None * None
@ -256,9 +277,9 @@ void GetSoundVolume(Interface* self);
* 1 : Result of function, 0 on success, otherwise error code * 1 : Result of function, 0 on success, otherwise error code
* 2 : float output value * 2 : float output value
*/ */
void GetGyroscopeLowRawToDpsCoefficient(Service::Interface* self); void GetGyroscopeLowRawToDpsCoefficient(Kernel::HLERequestContext& ctx);
/** /**
* HID::GetGyroscopeLowCalibrateParam service function * HID::GetGyroscopeLowCalibrateParam service function
* Inputs: * Inputs:
* None * None
@ -266,13 +287,51 @@ void GetGyroscopeLowRawToDpsCoefficient(Service::Interface* self);
* 1 : Result of function, 0 on success, otherwise error code * 1 : Result of function, 0 on success, otherwise error code
* 2~6 (18 bytes) : struct GyroscopeCalibrateParam * 2~6 (18 bytes) : struct GyroscopeCalibrateParam
*/ */
void GetGyroscopeLowCalibrateParam(Service::Interface* self); void GetGyroscopeLowCalibrateParam(Kernel::HLERequestContext& ctx);
/// Initialize HID service private:
void Init(); std::shared_ptr<Module> hid;
};
/// Shutdown HID service void ReloadInputDevices();
void Shutdown();
private:
void LoadInputDevices();
void UpdatePadCallback(u64 userdata, int cycles_late);
void UpdateAccelerometerCallback(u64 userdata, int cycles_late);
void UpdateGyroscopeCallback(u64 userdata, int cycles_late);
// Handle to shared memory region designated to HID_User service
Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
// Event handles
Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_1;
Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_2;
Kernel::SharedPtr<Kernel::Event> event_accelerometer;
Kernel::SharedPtr<Kernel::Event> event_gyroscope;
Kernel::SharedPtr<Kernel::Event> event_debug_pad;
u32 next_pad_index = 0;
u32 next_touch_index = 0;
u32 next_accelerometer_index = 0;
u32 next_gyroscope_index = 0;
int enable_accelerometer_count = 0; // positive means enabled
int enable_gyroscope_count = 0; // positive means enabled
CoreTiming::EventType* pad_update_event;
CoreTiming::EventType* accelerometer_update_event;
CoreTiming::EventType* gyroscope_update_event;
std::atomic<bool> is_device_reload_pending{true};
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>
buttons;
std::unique_ptr<Input::AnalogDevice> circle_pad;
std::unique_ptr<Input::MotionDevice> motion_device;
std::unique_ptr<Input::TouchDevice> touch_device;
};
void InstallInterfaces(SM::ServiceManager& service_manager);
/// Reload input devices. Used when input configuration changed /// Reload input devices. Used when input configuration changed
void ReloadInputDevices(); void ReloadInputDevices();

View File

@ -2,27 +2,26 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/hid/hid_spvr.h" #include "core/hle/service/hid/hid_spvr.h"
namespace Service { namespace Service {
namespace HID { namespace HID {
const Interface::FunctionInfo FunctionTable[] = { Spvr::Spvr(std::shared_ptr<Module> hid) : Module::Interface(std::move(hid), "hid:SPVR", 6) {
{0x000A0000, GetIPCHandles, "GetIPCHandles"}, static const FunctionInfo functions[] = {
{0x000A0000, &Spvr::GetIPCHandles, "GetIPCHandles"},
{0x000B0000, nullptr, "StartAnalogStickCalibration"}, {0x000B0000, nullptr, "StartAnalogStickCalibration"},
{0x000E0000, nullptr, "GetAnalogStickCalibrateParam"}, {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"},
{0x00110000, EnableAccelerometer, "EnableAccelerometer"}, {0x00110000, &Spvr::EnableAccelerometer, "EnableAccelerometer"},
{0x00120000, DisableAccelerometer, "DisableAccelerometer"}, {0x00120000, &Spvr::DisableAccelerometer, "DisableAccelerometer"},
{0x00130000, EnableGyroscopeLow, "EnableGyroscopeLow"}, {0x00130000, &Spvr::EnableGyroscopeLow, "EnableGyroscopeLow"},
{0x00140000, DisableGyroscopeLow, "DisableGyroscopeLow"}, {0x00140000, &Spvr::DisableGyroscopeLow, "DisableGyroscopeLow"},
{0x00150000, GetGyroscopeLowRawToDpsCoefficient, "GetGyroscopeLowRawToDpsCoefficient"}, {0x00150000, &Spvr::GetGyroscopeLowRawToDpsCoefficient,
{0x00160000, GetGyroscopeLowCalibrateParam, "GetGyroscopeLowCalibrateParam"}, "GetGyroscopeLowRawToDpsCoefficient"},
{0x00170000, GetSoundVolume, "GetSoundVolume"}, {0x00160000, &Spvr::GetGyroscopeLowCalibrateParam, "GetGyroscopeLowCalibrateParam"},
}; {0x00170000, &Spvr::GetSoundVolume, "GetSoundVolume"},
};
HID_SPVR_Interface::HID_SPVR_Interface() { RegisterHandlers(functions);
Register(FunctionTable);
} }
} // namespace HID } // namespace HID

View File

@ -4,18 +4,14 @@
#pragma once #pragma once
#include "core/hle/service/service.h" #include "core/hle/service/hid/hid.h"
namespace Service { namespace Service {
namespace HID { namespace HID {
class HID_SPVR_Interface : public Service::Interface { class Spvr final : public Module::Interface {
public: public:
HID_SPVR_Interface(); explicit Spvr(std::shared_ptr<Module> hid);
std::string GetPortName() const override {
return "hid:SPVR";
}
}; };
} // namespace HID } // namespace HID

View File

@ -2,27 +2,26 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/hid/hid_user.h" #include "core/hle/service/hid/hid_user.h"
namespace Service { namespace Service {
namespace HID { namespace HID {
const Interface::FunctionInfo FunctionTable[] = { User::User(std::shared_ptr<Module> hid) : Module::Interface(std::move(hid), "hid:USER", 6) {
{0x000A0000, GetIPCHandles, "GetIPCHandles"}, static const FunctionInfo functions[] = {
{0x000A0000, &User::GetIPCHandles, "GetIPCHandles"},
{0x000B0000, nullptr, "StartAnalogStickCalibration"}, {0x000B0000, nullptr, "StartAnalogStickCalibration"},
{0x000E0000, nullptr, "GetAnalogStickCalibrateParam"}, {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"},
{0x00110000, EnableAccelerometer, "EnableAccelerometer"}, {0x00110000, &User::EnableAccelerometer, "EnableAccelerometer"},
{0x00120000, DisableAccelerometer, "DisableAccelerometer"}, {0x00120000, &User::DisableAccelerometer, "DisableAccelerometer"},
{0x00130000, EnableGyroscopeLow, "EnableGyroscopeLow"}, {0x00130000, &User::EnableGyroscopeLow, "EnableGyroscopeLow"},
{0x00140000, DisableGyroscopeLow, "DisableGyroscopeLow"}, {0x00140000, &User::DisableGyroscopeLow, "DisableGyroscopeLow"},
{0x00150000, GetGyroscopeLowRawToDpsCoefficient, "GetGyroscopeLowRawToDpsCoefficient"}, {0x00150000, &User::GetGyroscopeLowRawToDpsCoefficient,
{0x00160000, GetGyroscopeLowCalibrateParam, "GetGyroscopeLowCalibrateParam"}, "GetGyroscopeLowRawToDpsCoefficient"},
{0x00170000, GetSoundVolume, "GetSoundVolume"}, {0x00160000, &User::GetGyroscopeLowCalibrateParam, "GetGyroscopeLowCalibrateParam"},
}; {0x00170000, &User::GetSoundVolume, "GetSoundVolume"},
};
HID_U_Interface::HID_U_Interface() { RegisterHandlers(functions);
Register(FunctionTable);
} }
} // namespace HID } // namespace HID

View File

@ -4,7 +4,7 @@
#pragma once #pragma once
#include "core/hle/service/service.h" #include "core/hle/service/hid/hid.h"
// This service is used for interfacing to physical user controls. // This service is used for interfacing to physical user controls.
// Uses include game pad controls, touchscreen, accelerometers, gyroscopes, and debug pad. // Uses include game pad controls, touchscreen, accelerometers, gyroscopes, and debug pad.
@ -12,16 +12,9 @@
namespace Service { namespace Service {
namespace HID { namespace HID {
/** class User final : public Module::Interface {
* HID service interface.
*/
class HID_U_Interface : public Service::Interface {
public: public:
HID_U_Interface(); explicit User(std::shared_ptr<Module> hid);
std::string GetPortName() const override {
return "hid:USER";
}
}; };
} // namespace HID } // namespace HID

View File

@ -277,7 +277,7 @@ void Init() {
DLP::Init(); DLP::Init();
FRD::Init(); FRD::Init();
GSP::InstallInterfaces(*SM::g_service_manager); GSP::InstallInterfaces(*SM::g_service_manager);
HID::Init(); HID::InstallInterfaces(*SM::g_service_manager);
IR::InstallInterfaces(*SM::g_service_manager); IR::InstallInterfaces(*SM::g_service_manager);
MVD::Init(); MVD::Init();
NDM::Init(); NDM::Init();
@ -307,7 +307,6 @@ void Shutdown() {
NIM::Shutdown(); NIM::Shutdown();
NEWS::Shutdown(); NEWS::Shutdown();
NDM::Shutdown(); NDM::Shutdown();
HID::Shutdown();
FRD::Shutdown(); FRD::Shutdown();
DLP::Shutdown(); DLP::Shutdown();
CFG::Shutdown(); CFG::Shutdown();